3
\$\begingroup\$

I'm currently rendering a large proportion of the graphics of my game using custom OpenGL primitive functions (e.g. DrawCircleFilled(), DrawPolygonFilled(), etc) drawing procedurally generated objects (e.g. trees). Typically the core of these functions is a glBegin and glEnd loop, and use GL_TRIANGLE_FAN, GL_LINE_LOOP, GL_LINES, or GL_POLYGON. While this generally works, I'm seeing some performance issues if I have too many objects using these functions on screen at once.

For instance, I could render a brick wall by drawing 128 small brick-coloured rectangles with an outline. Alternatively I could render a single OpenGL texture with these bricks pre-drawn, which takes up more video memory but seems to be less processor intensive.

With this in mind, my question is: how do I take the output of the primitive functions and store them in an OpenGL texture at runtime? I'm aware of how to do with with an SDL_Surface, but I don't have access to the primitive drawing functions in SDL and SDL primitive drawing is very slow (one of the reasons why I switched to raw OpenGL in the first place).

Advice appreciated.

Thanks, Nathan

\$\endgroup\$
  • 1
    \$\begingroup\$ Turning output into a texture at runtime often referred to as "render to texture;" see this SO post details. However, before trying that, I suspect you'd get a signifigant performance improvement by changing your openGL code from immediate mode to the more modern approach of using VBOs. \$\endgroup\$ – Pikalek Apr 24 '17 at 22:31
  • \$\begingroup\$ Are you still using SDL_Texture for textures or GLuints? (And which version of SDL are you using)? \$\endgroup\$ – Pharap Apr 25 '17 at 7:07
  • 1
    \$\begingroup\$ @Pikalek Thanks for this information - I had a terrible feeling the answer might be to move to the modern approach, which I struggle to get my head around. Before I dive into this side of things, is there a rough order of magnitude of likely performance improvement for VBOs compared to immediate mode? \$\endgroup\$ – nathanburns Apr 25 '17 at 11:39
  • 1
    \$\begingroup\$ @Pharap - Solely GLuints. I'm using SDL2, was previously using an SDL primitives drawing library but it wasn't able to handle the particle effects and complex polygons I'm looking to use, so I moved to OpenGL \$\endgroup\$ – nathanburns Apr 25 '17 at 11:40
2
\$\begingroup\$

@Pikalek's suggestion in the comments is spot-on. You can render to a texture using a texture-backed FBO. Using retained mode will allow you to keep some of your geometry on the video card and not upload it on every frame (which is what happens when you call glBegin()/glEnd()).

There's another way that may also be useful. You can render some of your shapes using a shader. For example, a brick wall can be rendered as a single quad with an appropriate shader that divides it up into smaller rectangles that you shade as desired. It's too much to describe the process in a single answer here, but if you look up some introductions to glsl, that should get you going.

\$\endgroup\$
  • \$\begingroup\$ Immediate mode is the one with glBegin, glVertex<2,3,4><d,f> and glEnd \$\endgroup\$ – Bálint Apr 25 '17 at 5:59
  • \$\begingroup\$ Thanks @user1118321 - modern OpenGL stretches my brain capacity enough, GLSL is a whole other level. I think I'll stick with the basic fragment shader I have now and try the VBO approach, and report back here with progress \$\endgroup\$ – nathanburns Apr 25 '17 at 11:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.