0
\$\begingroup\$

I'm making a collage of lots 16x16 renders on a 512x512 texture, of the same scene, from various viewing positions and angles, preferably lots of times per second. I've profiled my program (which contained a glDrawElements call per mesh), and the multiple glDrawElements calls seemed to slow it down a lot. In order to optimize, I've resorted to instanced rendering. However, the main problem I'm having is changing the viewport between, say, every 3 instance renderings, or so. I was thinking of adding a fourth matrix, which would scale the perspectively-projected vertices of a would-be 16x16 picture, translate them so that the little images don't overlap, and based on the little picture's position and size (16x16 pixels) on screen, use the `discard' command in the pixel shader.

How do I scale the projected vertices from the current large viewport into a 16x16 smaller version of it and translate them inside the former at a certain position?

Or, more clearly, how do I change the viewport during a glDrawElementsInstanced call, every N instances?

EDIT Here's a visualization of what I'm trying to achieve:visualization

Keep in mind, I can't change the viewport as I want to do this during a call to glDrawEleemntsInstanced, every 3 instances, or so.

How do I compute a matrix or what do I have to do to get the post-projection vertices scaled and translated so that I'll have the full image scaled in a 16x16 portion of the screen?

\$\endgroup\$
5
  • \$\begingroup\$ You can't change the viewport during a draw, it's state is separate from the vertex data. It does sound like you may be achieve what you're going for, though, although I'm having trouble visualizing it based on your write-up. Can you provide a picture or sketch for clarification? \$\endgroup\$ – user1430 Jan 16 '15 at 19:39
  • \$\begingroup\$ @toby I have problems visualizing it as well. Although, if your goal is just to use a different matrix every other instance of the draw call, there are two common techniques of doing it: Uploading all matrices to a uniform buffer and indexing it somehow based on the gl_InstanceID, or using glVertexAttribDivisor to make multiple instances use the same vertex attribute "index" (the following instancing tutorial uses it ogldev.atspace.co.uk/www/tutorial33/tutorial33.html) \$\endgroup\$ – TravisG Jan 16 '15 at 20:13
  • \$\begingroup\$ @JoshPetrie, thank you for your answer, I have added a visualization made of two figures side-by side. \$\endgroup\$ – toby Jan 17 '15 at 10:30
  • \$\begingroup\$ @TravisG, thank you for your answer, I have the part about using a matrix for every other instance of the draw call. It's just the post-projective scaling and translation I have problems with. \$\endgroup\$ – toby Jan 17 '15 at 10:31
  • \$\begingroup\$ Avoid using discard as much as you can, it has a huge performance impact gamedev.stackexchange.com/questions/40301/… \$\endgroup\$ – Khlorghaal Jan 18 '15 at 18:45
1
\$\begingroup\$

From what I understand you are trying to render a scene many times from many views into a tilemap.

To do that I would make each tile a layer of a Texture_2D_Array, and bind to a 3D framebuffer.
In the first phase, render your scene instanced with view per instance, then in geometry shader (only place you can set it) set gl_Layer = instance.
In the second phase simply render all layers of the array onto the tile atlas.

By using a framebuffer you eliminate the need to cull using discard, which would have a severe performance impact. It will also make the code much more readable than doing all of this in vertex stage.

\$\endgroup\$

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.