Java-Gaming.org    
Featured games (91)
games approved by the League of Dukes
Games in Showcase (578)
games submitted by our members
Games in WIP (498)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
   Home   Help   Search   Login   Register   
  Show Posts
Pages: [1]
1  Java Game APIs & Engines / JOGL Development / Re: Texture Packing, is there any point in doing it manually? on: 2009-01-11 22:07:26
Here's a screenshot and a description to give an idea of what I'm doing.
In the following shot I get ~50 fps with about 1400 vegetation sprites rendered.
The computer is a Precision M90, so it's a fairly recent laptop.

My rendering method looks like this
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
public void drawPackedTexture(float x, float y, float w, float h, PackedTexture texture, 
         Alignment align, BlendMode mode, float[] rgb, TransformMatrix pMatrix) {
      y = height - y;
      float[][] c = getAlignmentOffset(align);
      Rectangle2D.Float bounds = texture.getBounds();

      bindTexture(texture.packedTextureId);
      setBlendMode(mode);
     
      gl.glPushMatrix();
      gl.glTranslatef(x, y, 0.0f);
      gl.glScalef(w, h, 1.0f);
      // gl.glRotatef(0, 0.0f, 0.0f, 1.0f);
     
      if (pMatrix != null) {
         gl.glMultMatrixf(pMatrix.getMatrix(), 0);
      }
     
      gl.glBegin(GL.GL_POLYGON);
      gl.glColor4f(rgb[0], rgb[1], rgb[2], rgb[3]);
      gl.glTexCoord2f(bounds.x, bounds.y);
      gl.glVertex2f(c[0][0], c[1][0]);
      gl.glTexCoord2f(bounds.x + bounds.width, bounds.y);
      gl.glVertex2f(c[0][1], c[1][0]);
      gl.glTexCoord2f(bounds.x + bounds.width, bounds.y + bounds.height);
      gl.glVertex2f(c[0][1], c[1][1]);
      gl.glTexCoord2f(bounds.x, bounds.y + bounds.height);
      gl.glVertex2f(c[0][0], c[1][1]);
      gl.glEnd();
     
      gl.glPopMatrix();
   }


Where bindtexture avoids binding already present textureIds. Transform matrix is used to shear the top of the grass, so that it moves in the wind.
Right now, it only needs to bind one texture for all the vegetation.

Anyway, that's about what I can think of.

Thank you for reading.



2  Java Game APIs & Engines / JOGL Development / Texture Packing, is there any point in doing it manually? on: 2009-01-11 21:19:16
Edit: Disclaimer - I just tried running the test on my year old gaming rig, and it performs at 280 fps. Even with 8000 items, it runs smooth. This is the kind of performance I like Smiley
So I suppose there's much blame to be passed to mobile graphics cards, or drivers, or vista, or what have you. But still, if you have any advice to give, shoot! I'd really like this to run well on any decent computer.


Hello,

I just spent much of my Sunday implementing a seamless (somewhat) texture-packing utility into my texture-manager and renderer,
thinking it could improve performance significantly since I'm doing 2D graphics, and draw thousands of small billboards while binding textures continuously.

The idea is of course to stuff many images into the same 1024x1024 texture and point to different coordinates at render.

But putting it to work, I don't notice any difference in performance at all. Is this a legacy idea that binding is expensive? Or is it already taken care of by the JOGL API?

I'm using com.sun.opengl.util.texture.Texture by the way which does say "For best performance, try to avoid calling enable() / bind() / disable() any more than necessary." in the API.. perhaps it's still insignificant compared to matrix-operating on RGBA images over and over. Who knows Smiley

Slightly disappointing, but this is how it goes sometimes,

0gleth0rpe.
3  Java Game APIs & Engines / JOGL Development / Re: Suggestions on optimizing render on: 2008-08-11 18:42:04
Thank you for that suggestion!

I did a quick test now with a refactoring of enable/disable multi-texturing and binding textures only when necessary and voila!
A sudden leap from 9 down to 3 ms Smiley

1  
2  
3  
4  
5  
6  
[DEBUG] 18:38:11 :: TestVegetation - ----- Frame -----
[DEBUG] 18:38:11 :: TestVegetation - LightSources took 0.6 ms
[DEBUG] 18:38:11 :: TestVegetation - Terrain: 468 tiles
[DEBUG] 18:38:11 :: TestVegetation - Terrain took 2 ms
[DEBUG] 18:38:11 :: TestVegetation - Vegetation: 1403 items
[DEBUG] 18:38:11 :: TestVegetation - Vegetation took 1 ms
4  Java Game APIs & Engines / JOGL Development / Suggestions on optimizing render on: 2008-08-11 13:44:39
Hello,

I've been getting to know JOGL over some time and has been putting together some reuseable components.
I am however not experiencing the performance that I would expect.

I this example, I am rendering a multitextured terrain (2 texture units)  and some basic textures. This is crudely done per terrain tile and sprite through a helper class.

On this rather recent laptop I am achieving ~60 fps with around 500 tiles and 200 vegetation sprites.

I think I recall great optimization to be available through vertex arrays or something similar. Could someone please assist me with general pointers to how to reach more potential from openGL?

In my first example, 60 fps is stable



[DEBUG] 13:19:45 :: TestVegetation - ----- Frame -----
[DEBUG] 13:19:45 :: TestVegetation - LightSources took 0.1 ms
[DEBUG] 13:19:45 :: TestVegetation - Terrain: 468 tiles
[DEBUG] 13:19:45 :: TestVegetation - Terrain took 4 ms
[DEBUG] 13:19:45 :: TestVegetation - Vegetation: 155 items
[DEBUG] 13:19:45 :: TestVegetation - Vegetation took 0.9 ms

In my second example, I am not achieving 60 fps.



[DEBUG] 13:17:48 :: TestVegetation - ----- Frame -----
[DEBUG] 13:17:48 :: TestVegetation - LightSources took 0.1 ms
[DEBUG] 13:17:48 :: TestVegetation - Terrain: 468 tiles
[DEBUG] 13:17:48 :: TestVegetation - Terrain took 4 ms
[DEBUG] 13:17:48 :: TestVegetation - Vegetation: 1557 items
[DEBUG] 13:17:48 :: TestVegetation - Vegetation took 5 ms

Obviously vegetation is the cause here.

I have plenty of references here to custom stuff but hopefully it can be of assistance somehow.
I am not asking for a step to step guide or source code, just hints and ideas.. anything off the top of your heads Smiley

Known probably sources;
* I am using 24 bit transparent PNG which could perhaps be a problem (as compared to non-alpha channel ones)
* Turning on and off texturing units for each tile ?
* Low performance logic surrounding the render

Thank you for reading.

[size=12pt]Related code snippets[/size]

Rendering tiles:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
for (int iy = vTileOffsetY; iy < vTileOffsetY + vScreenTileHeight + 2; iy++) {
   for (int ix = vTileOffsetX; ix < vTileOffsetX + vScreenTileWidth
         + 2; ix++) {
      // Fetch tile

      TerrainTile tile = mTerrainMap.get(ix, iy);

      if (tile == null) {
         continue;
      }

      // Calculate window coordinates

      float x = ((float) ix * sTILE_WIDTH - mScrollX) - sTILE_WIDTH
            / 2;
      float y = ((float) iy * sTILE_HEIGHT - mScrollY) - sTILE_HEIGHT
            / 2;

      // Calculate texture coordinates

      float tx = ix * tw;
      float ty = iy * th;

      g.drawMultiTexture(x, y, sTILE_WIDTH, sTILE_HEIGHT, tile
            .getTextureId1(), tile.getTextureId2(), tile
            .isPrimary(), new float[] { tx, ty, tw, th },
            new float[][] { mLightMap.get(ix - 1, iy - 1).getRGB(),
                  mLightMap.get(ix, iy - 1).getRGB(),
                  mLightMap.get(ix - 1, iy).getRGB(),
                  mLightMap.get(ix, iy).getRGB() });
   }
}


Rendering Vegetation:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
for (Vegetation v : mVegetation) {
   float x = toScreenCoord(v.getX(), Orientation.HORIZONTAL);
   float y = toScreenCoord(v.getY(), Orientation.VERTICAL);

   if (!g.inView(x, y, sFRAME_LIGHTMAP_MARGIN)) {
      continue;
   }

   RGB rgb = mLightMap.get((int) v.getX(), (int) v.getY());

   g.drawFrames(x, y + 16, v.getFrames(), Alignment.LOWER_MIDDLE,
         (float) v.getScale(), rgb.getRGB(), BlendMode.ALPHA);
}


Render multitextured tile
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
public void drawMultiTexture(float x, float y, float w, float h,
      Long textureId1, Long textureId2, boolean[] isPrimary,
      float textureOffset[], float[][] color) {

   y = height - y;

   /* Enable Multitexturing */

   Texture tex1 = textureManager.getTexture(textureId1);
   Texture tex2 = textureManager.getTexture(textureId2);

   // Set up the first texture unit to interpolate using crossbar extension

   gl.glActiveTexture(GL.GL_TEXTURE0);
   gl.glEnable(GL.GL_TEXTURE_2D);
   gl.glBindTexture(GL.GL_TEXTURE_2D, tex1.getTextureObject());
   gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_COMBINE);
   gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_COMBINE_RGB, GL.GL_INTERPOLATE);
   gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_SOURCE0_RGB, GL.GL_TEXTURE1);
   gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_SOURCE1_RGB, GL.GL_TEXTURE0);
   gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_SOURCE2_RGB, GL.GL_PRIMARY_COLOR);
   gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_OPERAND2_RGB, GL.GL_SRC_ALPHA);
   gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_COMBINE_ALPHA, GL.GL_INTERPOLATE);
   gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_SOURCE0_ALPHA, GL.GL_TEXTURE1);
   gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_SOURCE1_ALPHA, GL.GL_TEXTURE0);
   gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_SOURCE2_ALPHA,
         GL.GL_PRIMARY_COLOR);
   gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_OPERAND2_ALPHA, GL.GL_SRC_ALPHA);

   // Set up the second texture unit for primary color tinting
  gl.glActiveTexture(GL.GL_TEXTURE1);
   gl.glEnable(GL.GL_TEXTURE_2D);
   gl.glBindTexture(GL.GL_TEXTURE_2D, tex2.getTextureObject());
   gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_COMBINE);
   gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_COMBINE_RGB, GL.GL_MODULATE);
   gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_SOURCE0_RGB, GL.GL_PRIMARY_COLOR);
   float[] constant = { 1, 1, 1, 1 };
   gl.glTexEnvfv(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_COLOR, constant, 0);
   gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_COMBINE_ALPHA, GL.GL_REPLACE);
   gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_SOURCE0_ALPHA, GL.GL_CONSTANT);

   /*
    * Triangle Fan Rendering
    *
    * Center, Lower Left, Upper Left, Upper Right, Lower Right
    */


   float tx1 = textureOffset[0];
   float tx2 = textureOffset[0] + textureOffset[2];
   float ty1 = textureOffset[1];
   float ty2 = textureOffset[1] + textureOffset[3];

   // Calculate blending of the center vertex

   float p = 0.0f;

   for (int i = 0; i < isPrimary.length; i++) {
      if (!isPrimary[i])
         p += 0.25f;
   }

   // Calculate color of the center vertex

   float midColor[] = new float[] {
         (color[0][0] + color[1][0] + color[2][0] + color[3][0]) / 4,
         (color[0][1] + color[1][1] + color[2][1] + color[3][1]) / 4,
         (color[0][2] + color[1][2] + color[2][2] + color[3][2]) / 4 };

   gl.glBegin(GL.GL_TRIANGLE_FAN);
   {
      gl.glColor4f(midColor[0], midColor[1], midColor[2], p);
      gl.glMultiTexCoord2f(GL.GL_TEXTURE0, (tx2 + tx1) / 2,
            (ty2 + ty1) / 2);
      gl.glMultiTexCoord2f(GL.GL_TEXTURE1, (tx2 + tx1) / 2,
            (ty2 + ty1) / 2);
      gl.glVertex2f(x + w / 2, y - h / 2);

      gl.glColor4f(color[2][0], color[2][1], color[2][2],
            isPrimary[2] ? 0.0f : 1.0f);
      gl.glMultiTexCoord2f(GL.GL_TEXTURE0, tx1, ty2);
      gl.glMultiTexCoord2f(GL.GL_TEXTURE1, tx1, ty2);
      gl.glVertex2f(x, y - h);

      gl.glColor4f(color[0][0], color[0][1], color[0][2],
            isPrimary[0] ? 0.0f : 1.0f);
      gl.glMultiTexCoord2f(GL.GL_TEXTURE0, tx1, ty1);
      gl.glMultiTexCoord2f(GL.GL_TEXTURE1, tx1, ty1);
      gl.glVertex2f(x, y);

      gl.glColor4f(color[1][0], color[1][1], color[1][2],
            isPrimary[1] ? 0.0f : 1.0f);
      gl.glMultiTexCoord2f(GL.GL_TEXTURE0, tx2, ty1);
      gl.glMultiTexCoord2f(GL.GL_TEXTURE1, tx2, ty1);
      gl.glVertex2f(x + w, y);

      gl.glColor4f(color[3][0], color[3][1], color[3][2],
            isPrimary[3] ? 0.0f : 1.0f);
      gl.glMultiTexCoord2f(GL.GL_TEXTURE0, tx2, ty2);
      gl.glMultiTexCoord2f(GL.GL_TEXTURE1, tx2, ty2);
      gl.glVertex2f(x + w, y - h);

      gl.glColor4f(color[2][0], color[2][1], color[2][2],
            isPrimary[2] ? 0.0f : 1.0f);
      gl.glMultiTexCoord2f(GL.GL_TEXTURE0, tx1, ty2);
      gl.glMultiTexCoord2f(GL.GL_TEXTURE1, tx1, ty2);
      gl.glVertex2f(x, y - h);
   }
   gl.glEnd();

   // Turn the second multitexture pass off
  gl.glActiveTexture(GL.GL_TEXTURE1);
   gl.glDisable(GL.GL_TEXTURE_2D);

   // Turn the first multitexture pass off
  gl.glActiveTexture(GL.GL_TEXTURE0);
   gl.glDisable(GL.GL_TEXTURE_2D);

   gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE);
}


Render sprite ("frame")
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
public void drawFrames(float x, float y, Frames frames, Alignment align,
      float scale, float[] rgb, BlendMode mode) {
   long textureId = frames.getNextFrame();

   Texture tex = textureManager.getTexture(textureId);

   float w = tex.getImageWidth() * scale;

   float h = tex.getImageHeight() * scale;

   x = applyHorizontalAlignment(x, w, align);

   y = applyVerticalAlignment(y, h, align);

   drawTexture(x, y, w, h, frames.getNextFrame(), mode, rgb);
}


Draw Texture (used in above)
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
public void drawTexture(float x, float y, float w, float h, Long textureId,
   BlendMode mode, float[] rgb) {
   Texture tex = textureManager.getTexture(textureId);
   tex.enable();
   tex.bind();

   y = height - y;

   setBlendMode(mode);
   gl.glBegin(GL.GL_POLYGON);
   gl.glColor4f(rgb[0], rgb[1], rgb[2], rgb[3]);
   gl.glTexCoord2f(0f, 0f);
   gl.glVertex2f(x, y);
   gl.glTexCoord2f(1f, 0f);
   gl.glVertex2f(x + w, y);
   gl.glTexCoord2f(1f, 1f);
   gl.glVertex2f(x + w, y - h);
   gl.glTexCoord2f(0f, 1f);
   gl.glVertex2f(x, y - h);
   gl.glEnd();

   tex.disable();
}
Pages: [1]
 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

xsi3rr4x (26 views)
2014-04-15 18:08:23

BurntPizza (21 views)
2014-04-15 03:46:01

UprightPath (37 views)
2014-04-14 17:39:50

UprightPath (19 views)
2014-04-14 17:35:47

Porlus (35 views)
2014-04-14 15:48:38

tom_mai78101 (61 views)
2014-04-10 04:04:31

BurntPizza (119 views)
2014-04-08 23:06:04

tom_mai78101 (219 views)
2014-04-05 13:34:39

trollwarrior1 (186 views)
2014-04-04 12:06:45

CJLetsGame (193 views)
2014-04-01 02:16:10
List of Learning Resources
by Longarmx
2014-04-08 03:14:44

Good Examples
by matheus23
2014-04-05 13:51:37

Good Examples
by Grunnt
2014-04-03 15:48:46

Good Examples
by Grunnt
2014-04-03 15:48:37

Good Examples
by matheus23
2014-04-01 18:40:51

Good Examples
by matheus23
2014-04-01 18:40:34

Anonymous/Local/Inner class gotchas
by Roquen
2014-03-11 15:22:30

Anonymous/Local/Inner class gotchas
by Roquen
2014-03-11 15:05:20
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!