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
    Commented Jan 16, 2015 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
    Commented Jan 16, 2015 at 20:13
  • \$\begingroup\$ @JoshPetrie, thank you for your answer, I have added a visualization made of two figures side-by side. \$\endgroup\$
    – toby
    Commented Jan 17, 2015 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
    Commented Jan 17, 2015 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
    Commented Jan 18, 2015 at 18:45

1 Answer 1

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\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .