Optimizing rendering.

jorgemonti
Unregistered
 
Post: #1
Hi,

Sorry for this lengthy and first thread!

I'm developing an opengl/SDL 2D game. I'm trying to optimize
the rendering process. I've read that the immediate mode is
the slowest, but it's the easiest to implement and it's the
mode i'm using.

I'm renderering only GL_QUADS. My textures comes from bitmapped
files with different size. For instance, my app window is
1024x768, then i have 12 256x256 textures. To render the app
background i've to paint 12 textured quads for every frame.
For the rendering code I only have:

Code:
for( unsigned int i = 0; i < m_textures.size(); i++ )
  {
    // Bind texture.
    glBindTexture( GL_TEXTURE_2D, m_textures[i].id );

    // Paint polygon.
    glBegin( GL_QUADS );

      glTexCoord2f( 0.0f,
                    m_textures[i].height );
      glVertex3f( m_textures[i].rect.x,
                  m_textures[i].rect.y + m_textures[i].rect.h,
                  0.0f );

      glTexCoord2f( m_textures[i].width,
                    m_textures[i].height );
      glVertex3f( m_textures[i].rect.x + m_textures[i].rect.w,
                  m_textures[i].rect.y + m_textures[i].rect.h,
                  0.0f );
                  
      glTexCoord2f( m_textures[i].width,
                    0.0f );
      glVertex3f( m_textures[i].rect.x + m_textures[i].rect.w,
                  m_textures[i].rect.y,
                  0.0f );

      glTexCoord2f( 0.0f,
                    0.0f );
      glVertex3f( m_textures[i].rect.x,
                  m_textures[i].rect.y,
                  0.0f );
    glEnd();
  }

So, what's the best way to try to optimize this code? Using display
lists, vertex arrays, vertex buffer objects, using GL_TRIANGLE instead
of GL_QUADS, use STRIPS,... ??

And, if I change the rendering code to dinamically multiply the
vertex with a scale constant, like the next one, but method can i
still use?

Code:
for( unsigned int i = 0; i < m_textures.size(); i++ )
  {
    // Bind texture.
    glBindTexture( GL_TEXTURE_2D, m_textures[i].id );

    // Paint polygon.
    glBegin( GL_QUADS );

      glTexCoord2f( 0.0f,
                    m_textures[i].height );
      glVertex3f( m_textures[i].rect.x * scale_x,
                  (m_textures[i].rect.y + m_textures[i].rect.h) * scale_y,
                  0.0f );

      glTexCoord2f( m_textures[i].width,
                    m_textures[i].height );
      glVertex3f( (m_textures[i].rect.x + m_textures[i].rect.w) * scale_x,
                  (m_textures[i].rect.y + m_textures[i].rect.h) * scale_y,
                  0.0f );
                  
      glTexCoord2f( m_textures[i].width,
                    0.0f );
      glVertex3f( (m_textures[i].rect.x + m_textures[i].rect.w) * scale_x,
                  m_textures[i].rect.y * scale_y,
                  0.0f );

      glTexCoord2f( 0.0f,
                    0.0f );
      glVertex3f( m_textures[i].rect.x * scale_x,
                  m_textures[i].rect.y * scale_y,
                  0.0f );
    glEnd();
  }

Any suggestion is welcome!
Thanks,

Jorge
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #2
Immediate mode is slow, but it isn't going to cause problems with 12 quads per frame. If you have performance issues, they're elsewhere.

Use Shark, and perhaps Sampler, OpenGL Profiler or OpenGL Driver Monitor to find where your performance problems really are.
Quote this message in a reply
jorgemonti
Unregistered
 
Post: #3
The 12 textured quads only was an example! I have only represented
the process to render all the graphic objects. Every graphic object is
composed by different sized textured quads. And i have a lot of graphic
objects Smile
Quote this message in a reply
Member
Posts: 144
Joined: 2004.07
Post: #4
jorgemonti Wrote:The 12 textured quads only was an example! I have only represented
the process to render all the graphic objects. Every graphic object is
composed by different sized textured quads. And i have a lot of graphic
objects Smile

In that case Immediate mode is suicide Rasp
Quote this message in a reply
Member
Posts: 153
Joined: 2004.12
Post: #5
Vertex arrays are a nice option, there extremely easy to implement and usually give you a good performance gain. Plus if you decide they don't help 'enough' its REALLY easy to change them to Buffer arrays/Indexed vertex arrays/etc...

There was a long silence...
'I claim them all,' said the Savage at last.
Quote this message in a reply
Member
Posts: 144
Joined: 2004.07
Post: #6
The general rule of thumb is to get the best performance use glDrawArrays()/glDrawElements() (with or without VBOs) for dynamic data (changed vertices/colors/etc each frame) or use display lists for static data.

Immediate mode is always a bad idea unless we're dealing with just a few vertices (total).
Quote this message in a reply
jorgemonti
Unregistered
 
Post: #7
And how many vertex are enough to try to optimize? I've been
checking and I have an average of 1500 vertex per frame because
I don't have any 3d model, etc only textured quads.

Thanks for your comments.
Quote this message in a reply
Member
Posts: 156
Joined: 2002.11
Post: #8
Each display list should have more than 16 elements on it for you to start noticing an improvement in performance, according to an (old) document by Apple. You should also try to group all the quads, then the triangles, on your list, to optimize rendering.
Quote this message in a reply
jorgemonti
Unregistered
 
Post: #9
Lets me explain a little my 2D engine because, maybe, I've to improve the way i render the
frames before trying to improve the openGL calls.

I organize the scene using a tree. The root is a static background 1024x768 image from 12
256x256 textures. All the graphics have arbitrary size. Then I divide the graphic file in NxM
different textures with power of 2 size (<= 256), to cover all the graphic. When I've to paint
the object I paint all their textures. Every object has his z coord to give deep, a visibility flag,
etc. To render the frame I only have to paint all the nodes of the tree.

Then, maybe, i have to group different kind of objects, because, for instance, i have a lot of
snow flakes rendered independently, with their glBind, glBegin...glEnd and maybe it could
be better to only do one glBind and have all the vertex and texture coords in arrays and paint
all the flakes in one call. Now every object has his Update method who made the texture
bind and the glBegin(GL_QUADS) ... glEnd() with no knowledge of the other objects.

I hope this helps ! :-)
Quote this message in a reply
Moderator
Posts: 1,560
Joined: 2003.10
Post: #10
jorgemonti Wrote:Then, maybe, i have to group different kind of objects, because, for instance, i have a lot of snow flakes rendered independently, with their glBind, glBegin...glEnd and maybe it could be better to only do one glBind and have all the vertex and texture coords in arrays and paint all the flakes in one call.

Yes indeed. If it's architecturally possible to sort by texture and render everything that uses that texture in one pass, go for it.

- Alex Diener
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #11
Consider using rectangle textures.
Quote this message in a reply
Member
Posts: 78
Joined: 2002.06
Post: #12
arekkusu Wrote:Consider using rectangle textures.
Pleaes -- you'll save yourself so much hassle. And AFAIK they are supported on most hardware > Rage128 (which was a long time ago).

If you don't; then think about just using a portion of larger square textures.
Quote this message in a reply
Puzzler183
Unregistered
 
Post: #13
This will cause some evil fill rate issues in theory....
Quote this message in a reply
jorgemonti
Unregistered
 
Post: #14
arekkusu Wrote:Consider using rectangle textures.

What extension are you talking about ? I'm developing with an Intel i865
(extreme 2) where the maximum texture size is 1024. Then to load the background
image i needed a 1024x1024 texture! with a very high impact in the fillrate
because I render all the scene every frame. Now I'm using textures with maximum
size of 256x256 with a very good performance.
Quote this message in a reply
Moderator
Posts: 771
Joined: 2003.04
Post: #15
If you have lots of overdrawing, and you are not using semi-transparent objects, you can draw front-to-back to reduce fillrate issues.

BTW, "Intel i865 (extreme 2)" == integrated graphics == PC (Win/Linux)
This is a Mac forum Wink

Check this page for some benchmarks of the i865 extreme 2.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Optimizing CGLFlushDrawable Nick 3 3,831 Nov 27, 2006 06:48 PM
Last Post: OneSadCookie
  Optimizing for OpenGL on OS X aaronsullivan 3 3,405 Mar 22, 2005 02:36 PM
Last Post: Puzzler183
  Optimizing Terrain Drawing? Blake 10 4,431 Jan 25, 2004 03:44 PM
Last Post: Blake
  optimizing dynamic geometry arekkusu 15 7,142 Nov 27, 2003 12:29 PM
Last Post: OneSadCookie
  optimizing OpenGL ghettotek 20 7,966 Feb 25, 2003 05:47 PM
Last Post: henryj