z

  • Follow


In OpenGL, as Z decreases, does this usually go into the screen or out of the screen?  I always forget this.  Any trick to memorizing this?


0
Reply bob3904 (233) 6/27/2012 11:05:03 PM

On Wednesday, June 27, 2012 7:05:03 PM UTC-4, b...@coolfone.comze.com wrote:
> In OpenGL, as Z decreases, does this usually go into the screen or out of the screen?  I always forget this.  Any trick to memorizing this?

It can be either way, depending on what you want to do.

The default z test is GL_LESS.
--
Andy V
0
Reply vesper.spamonly.andy53 (38) 6/27/2012 11:16:02 PM


On Thursday, June 28, 2012 1:05:03 AM UTC+2, b...@coolfone.comze.com wrote:
> In OpenGL, as Z decreases, does this usually go into the screen or out of the screen?  I always forget this.  Any trick to memorizing this?

Call it "depth" instead of "Z".

All the documentation says "depth buffer". Only old
textbooks and DIRECT3D say "Z-buffer" these days.
0
Reply tooby (65) 6/28/2012 1:18:52 PM

Ok, so as Z increases, you usually go into the screen.

On Wednesday, June 27, 2012 6:16:02 PM UTC-5, Andy V wrote:
> On Wednesday, June 27, 2012 7:05:03 PM UTC-4, b...@coolfone.comze.com wrote:
> > In OpenGL, as Z decreases, does this usually go into the screen or out of the screen?  I always forget this.  Any trick to memorizing this?
> 
> It can be either way, depending on what you want to do.
> 
> The default z test is GL_LESS.
> --
> Andy V
0
Reply bob3904 (233) 6/28/2012 2:01:15 PM

On Thu, 28 Jun 2012 07:01:15 -0700 (PDT)
bob@coolfone.comze.com wrote:

> Ok, so as Z increases, you usually go into the screen.

No. In its default state OpenGL assumes a ortho view with a identity
transformation from model over view to projection, with the positive Z
coming out of the screen.


Wolfgang

0
Reply Wolfgang.Draxinger (58) 6/28/2012 2:07:38 PM

On Thursday, June 28, 2012 4:07:38 PM UTC+2, Wolfgang.Draxinger wrote:
> 
> No. In its default state OpenGL assumes a ortho view with a identity
> transformation from model over view to projection, with the positive Z
> coming out of the screen.
> 

Also known as "Harold Space" - after King
Harold II.

http://www.xrv.org.uk/photopost/data/500/Harold.jpg

0
Reply tooby (65) 6/28/2012 3:10:00 PM

On Wed, 27 Jun 2012 16:05:03 -0700, bob wrote:

> In OpenGL, as Z decreases, does this usually go into the screen or out of
> the screen?  I always forget this.

The positive Z axis points out of the screen, so decreasing Z goes into
the screen.

> Any trick to memorizing this?

The coordinate system is the logical one for modelling environments:

	X = East
	Y = North
	Z = Up

0
Reply nobody (4805) 6/28/2012 6:58:04 PM

On Thursday, June 28, 2012 8:58:08 PM UTC+2, Nobody wrote:
> On Wed, 27 Jun 2012 16:05:03 -0700, bob wrote:
> 
> > In OpenGL, as Z decreases, does this usually go into the screen or out of
> > the screen?  I always forget this.
> 
> The positive Z axis points out of the screen, so decreasing Z goes into
> the screen.
> 

It's pointless to think this way, because...


> > Any trick to memorizing this?
> 
> The coordinate system is the logical one for modelling environments:
> 
> 	X = East
> 	Y = North
> 	Z = Up

....'Z' can be anything you want it to be.

If you want Z pointing in, you can do that.
If you want Z pointing out, you can do that.
If you want Z pointing up, you can do that too.
0
Reply tooby (65) 6/28/2012 7:50:48 PM

On Thu, 28 Jun 2012 12:50:48 -0700, fungus wrote:

> If you want Z pointing in, you can do that. If you want Z pointing out,
> you can do that. If you want Z pointing up, you can do that too.

With the appropriate matrices you can use any coordinate system you like
for modelling, but the coordinate system in which gl_Position is
interpreted has X to the right, Y up, and Z out of the screen.

0
Reply nobody (4805) 6/29/2012 5:03:53 AM

On Fri, 29 Jun 2012 06:04:00 +0100
Nobody <nobody@nowhere.com> wrote:

> With the appropriate matrices you can use any coordinate system you
> like for modelling, but the coordinate system in which gl_Position is
> interpreted has X to the right, Y up, and Z out of the screen.

Not quite. You can simply call

glDepthRange(1, -1);
glDepthFunc(GL_GREATER);

and have the depth mapping reversed. Same goes for glViewport if I'm
not mistaken, i.e.

glViewport(width, height, -width, -height); 

should flip the viewport accordingly. Though I admit I still have to
check the specification if this is actually valid.

OpenGL is all you want it to be.


Wolfgang

0
Reply Wolfgang.Draxinger (58) 6/29/2012 11:05:02 AM

On Fri, 29 Jun 2012 13:05:02 +0200, Wolfgang.Draxinger wrote:

>> With the appropriate matrices you can use any coordinate system you like
>> for modelling, but the coordinate system in which gl_Position is
>> interpreted has X to the right, Y up, and Z out of the screen.
> 
> Not quite. You can simply call
> 
> glDepthRange(1, -1);

This should be glDepthRange(1, 0), although the above is equivalent
(argument values outside the range [0,1] are clamped to this range).

> glDepthFunc(GL_GREATER);
> 
> and have the depth mapping reversed.

The original question was asking about Z, which isn't the same thing
as depth (it's not unocmmon to conflate the two, so he might have meant
depth, or he might have actually meant Z).

Initially (i.e. unless changed with glDepthRange), depth ranges from 0 at
the near plane to 1 at the far plane.

Normalised device coordinates (post-clip coordinates) always have Z equal
to -1 at the near plane and 1 at the far plane.

The GL and GLU functions commonly used for defining projection matrices
will result in a negative scale factor for the Z coordinate if nearVal and
farVal are both positive and farVal > nearVal, meaning that the coordinate
system prior to projection has Z equal to -1 at the far plane and 1 at the
near plane.

> Same goes for glViewport if I'm not mistaken, i.e.
> 
> glViewport(width, height, -width, -height);
> 
> should flip the viewport accordingly. Though I admit I still have to check
> the specification if this is actually valid.

"INVALID_VALUE is generated if either w or h is negative" (2.14.1).

> OpenGL is all you want it to be.

You can transform vertex coordinates and map depth values, but ultimately
you have to know what the reference points are.

0
Reply nobody (4805) 6/29/2012 4:12:58 PM

Hi folks, I'm rendering thousands of quads that are rotated towards the 
camera about the vertical axis. For grass texturing.
I'm using a structure like this.
struct Grass
{
     vec3    vertex;
     vec2    texST;
     vec2    sizeWH;
};

And using glDrawArrays(GL_QUADS, 0, numGrass) to render them.

I was wondering if I would be better off rendering just one quad and 
instancing it thousands of times. It'll use the same amount of data 
apart from the vertex, which will be one per quad, rather than every 
point on the quad.

Does anyone know which way would be faster, or is there not much in it?

Thanks
Dave.




0
Reply turn1 (48) 6/29/2012 7:28:03 PM

http://www.opengl.org/registry/specs/ARB/point_sprite.txt
0
Reply klammerj (94) 6/30/2012 4:18:32 AM

On Sat, 30 Jun 2012 06:18:32 +0200, Johann Klammer wrote:

> http://www.opengl.org/registry/specs/ARB/point_sprite.txt

point_sprite still hasn't made it into the standard, and it relies upon
glTexEnv which is deprecated in later versions.

The same effect can be achieved using a geometry shader to convert points
to screen-aligned triangle-pairs.

The dimensions and texture coordinates can be passed as uniforms or as an
attribute with a vertex divisor of 1.

0
Reply nobody (4805) 6/30/2012 7:05:52 PM

On 30/06/2012 05:18, Johann Klammer wrote:
> http://www.opengl.org/registry/specs/ARB/point_sprite.txt

Thanks, but I don't want the sprites to always be facing the camera, 
like I said they are only rotated about the vertical. This is to stop 
the grass looking up at you when you look down. Also with point sprites 
you can't mirror them, or make them non-square for variation, as far as 
I know.

My question was-  is instancing one quad a thousand times, quicker than 
doing a thousand quads on their own? I was wonder whether instancing was 
the best option for speed/memory, because I'm only sending position and 
size data per quad rather than per vertex. There's not much in it 
though, I guess.
Cheers,
Dave


0
Reply turn1 (48) 6/30/2012 7:18:46 PM

On Sat, 30 Jun 2012 20:18:48 +0100, VelociChicken wrote:

> Thanks, but I don't want the sprites to always be facing the camera, 
> like I said they are only rotated about the vertical. This is to stop 
> the grass looking up at you when you look down. Also with point sprites 
> you can't mirror them, or make them non-square for variation, as far as 
> I know.
> 
> My question was-  is instancing one quad a thousand times, quicker than 
> doing a thousand quads on their own? I was wonder whether instancing was 
> the best option for speed/memory, because I'm only sending position and 
> size data per quad rather than per vertex. There's not much in it 
> though, I guess.

Instancing can save memory and thus memory bandwidth, but if you don't
have a lot of geometry, that isn't going to significantly affect speed.

In any case, you can get what you want without instancing. IIUC, each
blade needs a position and a size, so you can render as GL_POINTS and
generate a pair of suitably sized and aligned triangles in the geometry
shader.


0
Reply nobody (4805) 6/30/2012 9:49:42 PM

On 30/06/2012 22:49, Nobody wrote:
> On Sat, 30 Jun 2012 20:18:48 +0100, VelociChicken wrote:
>
>> Thanks, but I don't want the sprites to always be facing the camera,
>> like I said they are only rotated about the vertical. This is to stop
>> the grass looking up at you when you look down. Also with point sprites
>> you can't mirror them, or make them non-square for variation, as far as
>> I know.
>>
>> My question was-  is instancing one quad a thousand times, quicker than
>> doing a thousand quads on their own? I was wonder whether instancing was
>> the best option for speed/memory, because I'm only sending position and
>> size data per quad rather than per vertex. There's not much in it
>> though, I guess.
> Instancing can save memory and thus memory bandwidth, but if you don't
> have a lot of geometry, that isn't going to significantly affect speed.
>
> In any case, you can get what you want without instancing. IIUC, each
> blade needs a position and a size, so you can render as GL_POINTS and
> generate a pair of suitably sized and aligned triangles in the geometry
> shader.
>
Thanks, I didn't want to go with the geometry shader path, as I'm not 
sure of the compatibility percentage of graphic cards out there that can 
do it. But I guess using the latest technology is very exciting and gets 
cool results.

I just wanted to know if instancing has a penalty over just quads!? Does 
it have extra internal processing that would slow it down over thousands 
of grass polygons?

I'll do try and stick with saving memory bandwidth in general like you 
said, it's probably the best route in all things GL.
Cheers,
Dave.

0
Reply turn1 (48) 7/1/2012 2:57:12 PM

On Sun, 01 Jul 2012 15:57:12 +0100, VelociChicken wrote:

> Thanks, I didn't want to go with the geometry shader path, as I'm not 
> sure of the compatibility percentage of graphic cards out there that can 
> do it. But I guess using the latest technology is very exciting and gets 
> cool results.

I suspect that the set of cards which support instancing but which don't
support geometry shaders is likely to be quite small. 2.0 has neither, 3.0
has both; that leaves 2.0 implementations which have ARB_draw_instanced
but not ARB_geometry_shader4 (or vendor-specific equivalents).

> I just wanted to know if instancing has a penalty over just quads!? Does 
> it have extra internal processing that would slow it down over thousands 
> of grass polygons?

I suppose that a naive implementation could result in per-batch setup
overheads being multiplied. The only way you can get a definitive answer
to such questions is to just try it on many different implementations; the
vendors don't make a habit of publishing this kind of information.


0
Reply nobody (4805) 7/1/2012 3:42:27 PM

On Sunday, July 1, 2012 4:57:12 PM UTC+2, VelociChicken wrote:
> 
> I just wanted to know if instancing has a penalty over just quads!? Does 
> it have extra internal processing that would slow it down over thousands 
> of grass polygons?
> 

You can try it and see but I doubt it.

I use double-buffered quads. Make two
vertex buffers and use the main CPU to
fill them up with quad data, swapping
buffers as needed.

0
Reply tooby (65) 7/1/2012 4:14:45 PM

Hi guys, I've been trying to figure out what's going on here for hours, 
and I've got to the end of my tether for now.

I'm having problems with a second colour attachment to an FBO.
What happens is that I get just one frame of the WORLD POSITION data 
instead of the TEXTURE COORDINATES, then I get nothing at all, it just 
freezes and doesn't change again (not a crash, just not updating). The 
world position display also seems to be offset and wrapped around the 
screen somehow. But it's not supposed to be there at all!
Has anybody seen this weird problem before, any hints would be a great help.

Thanks,
Dave


Here is the relavent code:-

// Used to store the world coordinates...
     glGenTextures(1, &positionsTex);
     glBindTexture(GL_TEXTURE_2D, positionsTex);
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB,  width, height, 0, 
GL_RGBA, GL_FLOAT, NULL);
     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

// Used to store the texture coordinates...this one doesn't work...
     glGenTextures(1, &textCoordsTex);
     glBindTexture(GL_TEXTURE_2D, textCoordsTex);
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB,  width, height, 0, 
GL_RGBA, GL_FLOAT, NULL);
     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

// Depth buffer...
     glGenTextures(1, &depthTex);
     glBindTexture(GL_TEXTURE_2D, depthTex);
     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24,  width, 
height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

// Make frame buffer...
     glGenFramebuffersEXT(1, &fbo);
     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);

// Attach the textures to FBO attachment point...
     glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, 
GL_COLOR_ATTACHMENT0_EXT,    GL_TEXTURE_2D, positionsTex, 0);
     glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, 
GL_COLOR_ATTACHMENT1_EXT,    GL_TEXTURE_2D, textCoordsTex, 0);
     glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, 
GL_DEPTH_ATTACHMENT_EXT,    GL_TEXTURE_2D, depthTex, 0);

     GLenum fboStatus = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
     if (fboStatus != GL_FRAMEBUFFER_COMPLETE)
     {
// If the frame buffer does not report back as complete...
exit(0); // Exit the application
     }


====================================
//FBO pixel shader...

varying vec4 worldCoord;

void main(void)
{
     gl_FragData[0] = vec4(worldCoord.xyz, 1.0);
     gl_FragData[1] = vec4(1.0, 0.0, 0.0, 1.0);    // Just some red to 
test it's going though.
}

====================================
//Deferred pixel shader for screen quad...

uniform sampler2D positionsTex;
uniform sampler2D textCoordsTex;

void main(void)
{
// 'gl_TexCoord[0].st' is of course from the screen quad...
     vec4 deferredPos = texture2D(positionsTex, gl_TexCoord[0].st).xyzw;
     vec4 textCoords  = vec4(texture2D(textCoordsTex, 
gl_TexCoord[0].st).xy, 0.0, 0.0);

// Just render the texture coordinate values to see some result that 
it's working...
     gl_FragColor  = vec4(textCoords);
     return;
}
====================================
Before rendering the screen quad...
(The 'shaders' code works for getting the uniform postion and it works fine)

// Render landscape etc...rough code outline...

     glUseProgram(terrain);
.... call all triangle buffer fills...
     GLenum buffers[3] = {GL_COLOR_ATTACHMENT0_EXT, 
GL_COLOR_ATTACHMENT1_EXT, GL_DEPTH_ATTACHMENT_EXT};
     glDrawBuffers(3, buffers);

....and then...
     glUseProgram(deferred);
     glUniform1i(shaders->progDeferred.GetUniform("positionsTex"), 0);
glUniform1i(shaders->progDeferred.GetUniform("textCoordsTex"), 1);

     glActiveTexture(GL_TEXTURE0);
     glBindTexture( GL_TEXTURE_2D, positionsTex);

     glActiveTexture(GL_TEXTURE1);
     glBindTexture( GL_TEXTURE_2D, textCoordsTex);
...do screen quad...


====================================

So it's not getting the red colour in gl_FragData[1] at all!
Swapping the FragData indices over shows the red coming through to the 
deferred shader just fine.
The positionsTex data works fine and everything is copied for the 
textCoordsTex setting up, so I don't understand the difference or what 
is wrong.

My card is a GTX 260 and in can run 8 attachments according to 
glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &num) plus I found other 
executables demonstrating it works on my computer.

Thanks again.

















0
Reply turn1 (48) 7/3/2012 6:57:33 PM

OK, I think I finally understood I should NOT include the depth buffer 
in glDrawBuffers(..)

So this...

GLenum buffers[3] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, 
GL_DEPTH_ATTACHMENT_EXT};
glDrawBuffers(3, buffers);

Should be...

GLenum buffers[2] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT};
glDrawBuffers(2, buffers);

So the depth attachment is not meant to be part of the rendering, which 
kind of makes sense, but it's not that obvious as it is still an 
attached buffer.

I was surprised when by rendering went down from 75 to 68 fps when 
enabling the second attachment though! :(

Cheers,
Dave.


On 03/07/2012 19:58, VelociChicken wrote:
> Hi guys, I've been trying to figure out what's going on here for 
> hours, and I've got to the end of my tether for now.
>
> I'm having problems with a second colour attachment to an FBO.
> What happens is that I get just one frame of the WORLD POSITION data 
> instead of the TEXTURE COORDINATES, then I get nothing at all, it just 
> freezes and doesn't change again (not a crash, just not updating). The 
> world position display also seems to be offset and wrapped around the 
> screen somehow. But it's not supposed to be there at all!
> Has anybody seen this weird problem before, any hints would be a great 
> help.
>
> Thanks,
> Dave
>
>
> Here is the relavent code:-
>
> // Used to store the world coordinates...
>     glGenTextures(1, &positionsTex);
>     glBindTexture(GL_TEXTURE_2D, positionsTex);
>     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB,  width, height, 0, 
> GL_RGBA, GL_FLOAT, NULL);
>     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
>     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
>     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
>     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
>     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
>
> // Used to store the texture coordinates...this one doesn't work...
>     glGenTextures(1, &textCoordsTex);
>     glBindTexture(GL_TEXTURE_2D, textCoordsTex);
>     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB,  width, height, 0, 
> GL_RGBA, GL_FLOAT, NULL);
>     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
>     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
>     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
>     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
>     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
>
> // Depth buffer...
>     glGenTextures(1, &depthTex);
>     glBindTexture(GL_TEXTURE_2D, depthTex);
>     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24,  width, 
> height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
>     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
>     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
>     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
>     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
>     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
>
> // Make frame buffer...
>     glGenFramebuffersEXT(1, &fbo);
>     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
>
> // Attach the textures to FBO attachment point...
>     glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, 
> GL_COLOR_ATTACHMENT0_EXT,    GL_TEXTURE_2D, positionsTex, 0);
>     glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, 
> GL_COLOR_ATTACHMENT1_EXT,    GL_TEXTURE_2D, textCoordsTex, 0);
>     glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, 
> GL_DEPTH_ATTACHMENT_EXT,    GL_TEXTURE_2D, depthTex, 0);
>
>     GLenum fboStatus = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
>     if (fboStatus != GL_FRAMEBUFFER_COMPLETE)
>     {
> // If the frame buffer does not report back as complete...
> exit(0); // Exit the application
>     }
>
>
> ====================================
> //FBO pixel shader...
>
> varying vec4 worldCoord;
>
> void main(void)
> {
>     gl_FragData[0] = vec4(worldCoord.xyz, 1.0);
>     gl_FragData[1] = vec4(1.0, 0.0, 0.0, 1.0);    // Just some red to 
> test it's going though.
> }
>
> ====================================
> //Deferred pixel shader for screen quad...
>
> uniform sampler2D positionsTex;
> uniform sampler2D textCoordsTex;
>
> void main(void)
> {
> // 'gl_TexCoord[0].st' is of course from the screen quad...
>     vec4 deferredPos = texture2D(positionsTex, gl_TexCoord[0].st).xyzw;
>     vec4 textCoords  = vec4(texture2D(textCoordsTex, 
> gl_TexCoord[0].st).xy, 0.0, 0.0);
>
> // Just render the texture coordinate values to see some result that 
> it's working...
>     gl_FragColor  = vec4(textCoords);
>     return;
> }
> ====================================
> Before rendering the screen quad...
> (The 'shaders' code works for getting the uniform postion and it works 
> fine)
>
> // Render landscape etc...rough code outline...
>
>     glUseProgram(terrain);
> ... call all triangle buffer fills...
>     GLenum buffers[3] = {GL_COLOR_ATTACHMENT0_EXT, 
> GL_COLOR_ATTACHMENT1_EXT, GL_DEPTH_ATTACHMENT_EXT};
>     glDrawBuffers(3, buffers);
>
> ...and then...
>     glUseProgram(deferred);
> glUniform1i(shaders->progDeferred.GetUniform("positionsTex"), 0);
> glUniform1i(shaders->progDeferred.GetUniform("textCoordsTex"), 1);
>
>     glActiveTexture(GL_TEXTURE0);
>     glBindTexture( GL_TEXTURE_2D, positionsTex);
>
>     glActiveTexture(GL_TEXTURE1);
>     glBindTexture( GL_TEXTURE_2D, textCoordsTex);
> ..do screen quad...
>
>
> ====================================
>
> So it's not getting the red colour in gl_FragData[1] at all!
> Swapping the FragData indices over shows the red coming through to the 
> deferred shader just fine.
> The positionsTex data works fine and everything is copied for the 
> textCoordsTex setting up, so I don't understand the difference or what 
> is wrong.
>
> My card is a GTX 260 and in can run 8 attachments according to 
> glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &num) plus I found other 
> executables demonstrating it works on my computer.
>
> Thanks again.
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


0
Reply turn1 (48) 7/3/2012 9:19:44 PM

OK I've had a look at instancing the quads, but it was about the same 
rendering time, with much less main memory overhead. So I guess some GFX 
cards will be better than others in sending the data, my card didn't 
seem to care all that much.

One reason a for slow down area, I suppose was the following:

There's a maximum number of elements in the vertex uniform for 
instances, 512 I think, so I had to do the following:-

     // Do the grass in 512 instance chunks at a time...
     for (int i = 0; i < numGrass; i+=512)
     {
         int num = numGrass-i;
         if (num > 512) num = 512;

         glUniform3fv(instanceGrassLocation, num, (float*)&grassInst[i]);
         glDrawArraysInstancedEXT(GL_QUADS, 0, 4, num);
     }

Is this the standard way of doing it? I can't find a proper example 
using Google etc.
I was wondering if when the number of grass panels goes up to 30,000 
then I will start to see the difference in speeds.


Thanks again,
Dave



On 01/07/2012 17:14, fungus wrote:
> On Sunday, July 1, 2012 4:57:12 PM UTC+2, VelociChicken wrote:
>> I just wanted to know if instancing has a penalty over just quads!? Does
>> it have extra internal processing that would slow it down over thousands
>> of grass polygons?
>>
> You can try it and see but I doubt it.
>
> I use double-buffered quads. Make two
> vertex buffers and use the main CPU to
> fill them up with quad data, swapping
> buffers as needed.
>


0
Reply turn1 (48) 7/4/2012 4:51:57 PM

On 04/07/2012 17:51, VelociChicken wrote:
> OK I've had a look at instancing the quads, but it was about the same 
> rendering time, with much less main memory overhead. So I guess some 
> GFX cards will be better than others in sending the data, my card 
> didn't seem to care all that much.
>
> One reason a for slow down area, I suppose was the following:
>
> There's a maximum number of elements in the vertex uniform for 
> instances, 512 I think, so I had to do the following:-
>
>     // Do the grass in 512 instance chunks at a time...
>     for (int i = 0; i < numGrass; i+=512)
>     {
>         int num = numGrass-i;
>         if (num > 512) num = 512;
>
>         glUniform3fv(instanceGrassLocation, num, (float*)&grassInst[i]);
>         glDrawArraysInstancedEXT(GL_QUADS, 0, 4, num);
>     }
>
> Is this the standard way of doing it? I can't find a proper example 
> using Google etc.
> I was wondering if when the number of grass panels goes up to 30,000 
> then I will start to see the difference in speeds.

So, is this the correct way of doing many instances please? I'm learning 
all this on my own, and it would be nice to have maybe a nod or a "don't 
be silly" from someone here.
Thanks,
Dave.






0
Reply turn1 (48) 7/5/2012 3:15:33 PM

On Wed, 04 Jul 2012 17:51:57 +0100, VelociChicken wrote:

> There's a maximum number of elements in the vertex uniform for 
> instances, 512 I think, so I had to do the following:-
> 
>      // Do the grass in 512 instance chunks at a time...
>      for (int i = 0; i < numGrass; i+=512)
>      {
>          int num = numGrass-i;
>          if (num > 512) num = 512;
> 
>          glUniform3fv(instanceGrassLocation, num, (float*)&grassInst[i]);
>          glDrawArraysInstancedEXT(GL_QUADS, 0, 4, num);
>      }
> 
> Is this the standard way of doing it?

No; using a uniform array is the wrong approach here. Make the location an
attribute and use glVertexAttribDivisor(index, 1) so that it uses one
element per instance rather than one per vertex.

In cases where that won't work (e.g. because you need non-sequential
access), use a texture instead. With shaders, it's common to use textures
for large arrays of data. Buffer textures (aka texture buffers) are ideal,
as you don't need filters or mipmaps, and they're guaranteed to hold at
least 64k elements, versus 1k for a 1D texture. For larger arrays, you can
use a 2D texture and flatten it, i.e. access element "i" with:

	texelFetch(ivec2(i % width,i / width))

The space available for uniforms is inevitably limited, because each core
has a local copy of all uniform data. Think of uniforms (even arrays) as
registers rather than memory.

0
Reply nobody (4805) 7/5/2012 3:55:54 PM

On 05/07/2012 16:55, Nobody wrote:
> On Wed, 04 Jul 2012 17:51:57 +0100, VelociChicken wrote:
>
>> There's a maximum number of elements in the vertex uniform for
>> instances, 512 I think, so I had to do the following:-
>>
>>       // Do the grass in 512 instance chunks at a time...
>>       for (int i = 0; i < numGrass; i+=512)
>>       {
>>           int num = numGrass-i;
>>           if (num > 512) num = 512;
>>
>>           glUniform3fv(instanceGrassLocation, num, (float*)&grassInst[i]);
>>           glDrawArraysInstancedEXT(GL_QUADS, 0, 4, num);
>>       }
>>
>> Is this the standard way of doing it?
> No; using a uniform array is the wrong approach here. Make the location an
> attribute and use glVertexAttribDivisor(index, 1) so that it uses one
> element per instance rather than one per vertex.

OK, that's OpenGL 3.3 by the look of it, and I'm finding it difficult to 
understand it from internet sources, but I'll get there.
My quad grass instances already have just one vertex change per 
instance, I'm not sure what you're saying there.

>
> In cases where that won't work (e.g. because you need non-sequential
> access), use a texture instead. With shaders, it's common to use textures
> for large arrays of data. Buffer textures (aka texture buffers) are ideal,
> as you don't need filters or mipmaps, and they're guaranteed to hold at
> least 64k elements, versus 1k for a 1D texture. For larger arrays, you can
> use a 2D texture and flatten it, i.e. access element "i" with:

This idea sounds more compatible to me (well at least I understand it 
too!), thanks, I've used textures for random number fetches and it 
simple didn't occur to me to use textures for storing vertices, thanks 
for the nudge in that direction.
Each of my ground patches has up to 4096 different grasses, so I can 
store the vertices simply in one 64x64 RGB texture per patch. With 4096 
patches in total which makes it 192Mb, I guess that's OK.

	texelFetch(ivec2(i % width,i / width))

The space available for uniforms is inevitably limited, because each core
has a local copy of all uniform data. Think of uniforms (even arrays) as
registers rather than memory.

"Think of uniforms (even arrays) as registers rather than memory."

That's a good way of looking at them.
Thanks again for the help,
Dave






0
Reply turn1 (48) 7/5/2012 6:20:15 PM

On Thu, 05 Jul 2012 19:20:40 +0100, VelociChicken wrote:

>>>           glUniform3fv(instanceGrassLocation, num, (float*)&grassInst[i]);
>>>           glDrawArraysInstancedEXT(GL_QUADS, 0, 4, num);

>>> Is this the standard way of doing it?
>> No; using a uniform array is the wrong approach here. Make the location an
>> attribute and use glVertexAttribDivisor(index, 1) so that it uses one
>> element per instance rather than one per vertex.
> 
> OK, that's OpenGL 3.3 by the look of it, and I'm finding it difficult to 
> understand it from internet sources, but I'll get there.
> My quad grass instances already have just one vertex change per 
> instance, I'm not sure what you're saying there.

The call:

	glDrawArraysInstancedEXT(GL_QUADS, 0, 4, num)

will draw "num" instance, each consisting of a single quad, each
consisting of 4 vertices.

For any attribute for which you don't specify a divisor, each vertex will
use a separate element from the array specified with glVertexAttribPointer();
the index will reset to the value of the "first" parameter between each
instance. If you specify a divisor for an attribute, all vertices from a
given instance will get the same value for that attribute.

So if you were to call glDrawArraysInstanced(..., 0, 3, 4), where
attribute 0 has no divisor while attribute 1 has a divisor of 1 and
attribute 2 has a divisor of 2, the indices used for each attribute
would be:

	0	0 1 2 0 1 2 0 1 2 0 1 2
	1	0 0 0 1 1 1 2 2 2 3 3 3
	2	0 0 0 0 0 0 1 1 1 1 1 1

>> In cases where that won't work (e.g. because you need non-sequential
>> access), use a texture instead. With shaders, it's common to use textures
>> for large arrays of data. Buffer textures (aka texture buffers) are ideal,
>> as you don't need filters or mipmaps, and they're guaranteed to hold at
>> least 64k elements, versus 1k for a 1D texture. For larger arrays, you can
>> use a 2D texture and flatten it, i.e. access element "i" with:
> 
> This idea sounds more compatible to me (well at least I understand it 
> too!), thanks, I've used textures for random number fetches and it 
> simple didn't occur to me to use textures for storing vertices, thanks 
> for the nudge in that direction.

In the case of sequential access, using an attribute is preferable, as the
value can be pre-fetched. A texture lookup is dependent upon the shader
computing the index, even if the computation is simply the value of
gl_PrimitiveID.

0
Reply nobody (4805) 7/6/2012 9:42:55 PM

On 06/07/2012 22:43, Nobody wrote:
> On Thu, 05 Jul 2012 19:20:40 +0100, VelociChicken wrote:
>
>>>>            glUniform3fv(instanceGrassLocation, num, (float*)&grassInst[i]);
>>>>            glDrawArraysInstancedEXT(GL_QUADS, 0, 4, num);
>>>> Is this the standard way of doing it?
>>> No; using a uniform array is the wrong approach here. Make the location an
>>> attribute and use glVertexAttribDivisor(index, 1) so that it uses one
>>> element per instance rather than one per vertex.
>> OK, that's OpenGL 3.3 by the look of it, and I'm finding it difficult to
>> understand it from internet sources, but I'll get there.
>> My quad grass instances already have just one vertex change per
>> instance, I'm not sure what you're saying there.
> The call:
>
> 	glDrawArraysInstancedEXT(GL_QUADS, 0, 4, num)
>
> will draw "num" instance, each consisting of a single quad, each
> consisting of 4 vertices.
>
> For any attribute for which you don't specify a divisor, each vertex will
> use a separate element from the array specified with glVertexAttribPointer();
> the index will reset to the value of the "first" parameter between each
> instance. If you specify a divisor for an attribute, all vertices from a
> given instance will get the same value for that attribute.
>
> So if you were to call glDrawArraysInstanced(..., 0, 3, 4), where
> attribute 0 has no divisor while attribute 1 has a divisor of 1 and
> attribute 2 has a divisor of 2, the indices used for each attribute
> would be:
>
> 	0	0 1 2 0 1 2 0 1 2 0 1 2
> 	1	0 0 0 1 1 1 2 2 2 3 3 3
> 	2	0 0 0 0 0 0 1 1 1 1 1 1
>
>>> In cases where that won't work (e.g. because you need non-sequential
>>> access), use a texture instead. With shaders, it's common to use textures
>>> for large arrays of data. Buffer textures (aka texture buffers) are ideal,
>>> as you don't need filters or mipmaps, and they're guaranteed to hold at
>>> least 64k elements, versus 1k for a 1D texture. For larger arrays, you can
>>> use a 2D texture and flatten it, i.e. access element "i" with:
>> This idea sounds more compatible to me (well at least I understand it
>> too!), thanks, I've used textures for random number fetches and it
>> simple didn't occur to me to use textures for storing vertices, thanks
>> for the nudge in that direction.
> In the case of sequential access, using an attribute is preferable, as the
> value can be pre-fetched. A texture lookup is dependent upon the shader
> computing the index, even if the computation is simply the value of
> gl_PrimitiveID.
>
OK thanks, I understand what the divisor does now. It's a very useful 
function.

I can only bind one buffer at a time, so how do I get it to know where 
the instance attributes are located?
Here the vertexGrassBuffer only has one quad in it, and I'm guess this 
is wrong because the instance in not in that buffer.


     glBindBuffer(GL_ARRAY_BUFFER, vertexGrassBuffer);

     glEnableVertexAttribArray(texCoordsGrassLocation);
     glEnableVertexAttribArray(sizeGrassLocation);
     glEnableVertexAttribArray(instanceGrassLocation);

     glVertexAttribPointer(texCoordsGrassLocation, 2, GL_FLOAT, 
GL_FALSE, sizeof(Grass), (char*)offsetof(Grass, texST));
     glVertexAttribPointer(sizeGrassLocation, 2, GL_FLOAT, GL_FALSE, 
sizeof(Grass), (char*)offsetof(Grass, sizeWH));
     glVertexAttribPointer(instanceGrassLocation, 3, GL_FLOAT, GL_FALSE, 
sizeof(GrassInstance), 0);
     glVertexAttribDivisor(instanceGrassLocation, 4);

     glDrawArraysInstancedARB(GL_QUADS, 0, 4, numGrass);
     // Clear up...

Cheers,
Dave.







0
Reply turn1 (48) 7/7/2012 9:27:48 PM

On Sat, 07 Jul 2012 22:28:11 +0100, VelociChicken wrote:

> I can only bind one buffer at a time, so how do I get it to know where 
> the instance attributes are located?

glDrawArrays will obtain attribute values using the buffer which was bound
at the time of the glVertexAttribPointer call, the bindings at the time
of the glDrawArrays call aren't relevant. The buffer can be re-bound or
unbound immediately after glVertexAttribPointer returns.

So if you have multiple attributes in separate buffers, just call
glBindBuffer(GL_ARRAY_BUFFER, ...) before each glVertexAttribPointer
call.

0
Reply nobody (4805) 7/8/2012 1:43:33 AM

On 08/07/2012 02:43, Nobody wrote:
> On Sat, 07 Jul 2012 22:28:11 +0100, VelociChicken wrote:
>
>> I can only bind one buffer at a time, so how do I get it to know where
>> the instance attributes are located?
> glDrawArrays will obtain attribute values using the buffer which was bound
> at the time of the glVertexAttribPointer call, the bindings at the time
> of the glDrawArrays call aren't relevant. The buffer can be re-bound or
> unbound immediately after glVertexAttribPointer returns.
>
> So if you have multiple attributes in separate buffers, just call
> glBindBuffer(GL_ARRAY_BUFFER, ...) before each glVertexAttribPointer
> call.
Working thanks, BUT it's really slow at rendering compared to the way I 
was using 'uniform' batching. Amazingly so.
I was getting about 60 FPS with loads of grass, now I'm get 16 FPS!
So I don't know what to do now, this is really bad.

Perhaps I'm doing something wrong, when I render the quads I do need to 
multiply the number of instances by the divisor don't I? -

glVertexAttribDivisor(instanceGrassLocation, 4);
glDrawArraysInstancedARB(GL_QUADS, 0, 4, numGrass*4);

I did this because it was the only way to render all the grass, as it 
missed a load out without it.
Anyway, I want to go back to using 'uniform' batching like before, 
because if the above is correct, I'm stuffed.
Dave.



0
Reply turn1 (48) 7/8/2012 11:58:27 AM

On 08/07/2012 12:58, VelociChicken wrote:
> On 08/07/2012 02:43, Nobody wrote:
>> On Sat, 07 Jul 2012 22:28:11 +0100, VelociChicken wrote:
>>
>>> I can only bind one buffer at a time, so how do I get it to know where
>>> the instance attributes are located?
>> glDrawArrays will obtain attribute values using the buffer which was 
>> bound
>> at the time of the glVertexAttribPointer call, the bindings at the time
>> of the glDrawArrays call aren't relevant. The buffer can be re-bound or
>> unbound immediately after glVertexAttribPointer returns.
>>
>> So if you have multiple attributes in separate buffers, just call
>> glBindBuffer(GL_ARRAY_BUFFER, ...) before each glVertexAttribPointer
>> call.
> Working thanks, BUT it's really slow at rendering compared to the way 
> I was using 'uniform' batching. Amazingly so.
> I was getting about 60 FPS with loads of grass, now I'm get 16 FPS!
> So I don't know what to do now, this is really bad.
>
> Perhaps I'm doing something wrong, when I render the quads I do need 
> to multiply the number of instances by the divisor don't I? -
>
> glVertexAttribDivisor(instanceGrassLocation, 4);
> glDrawArraysInstancedARB(GL_QUADS, 0, 4, numGrass*4);
>
> I did this because it was the only way to render all the grass, as it 
> missed a load out without it.
> Anyway, I want to go back to using 'uniform' batching like before, 
> because if the above is correct, I'm stuffed.
> Dave.
>
I've just set the divisor to 1, which is a little confusing, I guess I 
didn't understand it after all:
glVertexAttribDivisor(instanceGrassLocation, 1);
glDrawArraysInstancedARB(GL_QUADS, 0, 4, numGrass);

This seems to work just as before with the 'uniform' batching, and at 
the same speed thankfully.
Dave.







0
Reply turn1 (48) 7/8/2012 12:03:19 PM

Le 08/07/2012 07:58, VelociChicken a écrit :
> On 08/07/2012 02:43, Nobody wrote:
>> On Sat, 07 Jul 2012 22:28:11 +0100, VelociChicken wrote:
>>
>>> I can only bind one buffer at a time, so how do I get it to know where
>>> the instance attributes are located?
>> glDrawArrays will obtain attribute values using the buffer which was
>> bound
>> at the time of the glVertexAttribPointer call, the bindings at the time
>> of the glDrawArrays call aren't relevant. The buffer can be re-bound or
>> unbound immediately after glVertexAttribPointer returns.
>>
>> So if you have multiple attributes in separate buffers, just call
>> glBindBuffer(GL_ARRAY_BUFFER, ...) before each glVertexAttribPointer
>> call.
> Working thanks, BUT it's really slow at rendering compared to the way I
> was using 'uniform' batching. Amazingly so.
> I was getting about 60 FPS with loads of grass, now I'm get 16 FPS!
> So I don't know what to do now, this is really bad.
>
> Perhaps I'm doing something wrong, when I render the quads I do need to
> multiply the number of instances by the divisor don't I? -
>
> glVertexAttribDivisor(instanceGrassLocation, 4);
> glDrawArraysInstancedARB(GL_QUADS, 0, 4, numGrass*4);
>
> I did this because it was the only way to render all the grass, as it
> missed a load out without it.
> Anyway, I want to go back to using 'uniform' batching like before,
> because if the above is correct, I'm stuffed.
> Dave.
>

Hi,
at some point the fill rate might be the bottleneck rather than the 
geometry if you're drawing zillions of overlapping rectangles. You might 
want to sort your rectangles, perform occlusion queries, etc. so as to 
minimize the number of quads being rendered.
The best way to check whether this is true, just try different 
viewpoints (top-view, front views etc.) : if there is a significant 
difference in rendering time, then changing the way you handle geometry 
won't influence much.

Cheers,

-- 
Nicolas Bonneel
http://people.seas.harvard.edu/~nbonneel/



0
Reply nicolas.bonneel1 (27) 7/9/2012 12:40:49 AM

On Sun, 08 Jul 2012 12:58:27 +0100, VelociChicken wrote:

> Perhaps I'm doing something wrong, when I render the quads I do need to 
> multiply the number of instances by the divisor don't I? -
> 
> glVertexAttribDivisor(instanceGrassLocation, 4);
> glDrawArraysInstancedARB(GL_QUADS, 0, 4, numGrass*4);

For your case:
- The per-vertex data should be an array of 4 elements.
- The per-vertex attributes should have a divisor of 0.
- the "count" parameter should be 4.
- The per-instance data should be an array of numGrass elements.
- The per-instance attributes should have a divisor of 1.
- the "primcount" parameter should be numGrass.

The reason for the slowdown is that you're now drawing 4 times as many
instances as you were before.

If an attribute has a divisor of zero, each vertex uses the next element
from the associated array. The index resets to the "first" parameter after
each instance.

If an attribute has a divisor of N (N>0), all vertices in a group of N
consecutive instances have the same value for that attribute. The index
increments by one after each group of N consecutive instances.

IOW, a divisor of zero indicates that the attribute is per-vertex, a
divisor of one indicates that the attribute is per-instance, a divisor of
N indicates that the attribute is per-N-instances.

0
Reply nobody (4805) 7/9/2012 6:52:04 AM

This is a multi-part message in MIME format.
--------------030300010907030203050209
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit

On 09/07/2012 07:52, Nobody wrote:
> On Sun, 08 Jul 2012 12:58:27 +0100, VelociChicken wrote:
>
>> Perhaps I'm doing something wrong, when I render the quads I do need to
>> multiply the number of instances by the divisor don't I? -
>>
>> glVertexAttribDivisor(instanceGrassLocation, 4);
>> glDrawArraysInstancedARB(GL_QUADS, 0, 4, numGrass*4);
> For your case:
> - The per-vertex data should be an array of 4 elements.
> - The per-vertex attributes should have a divisor of 0.
> - the "count" parameter should be 4.
> - The per-instance data should be an array of numGrass elements.
> - The per-instance attributes should have a divisor of 1.
> - the "primcount" parameter should be numGrass.
>
> The reason for the slowdown is that you're now drawing 4 times as many
> instances as you were before.
>
> If an attribute has a divisor of zero, each vertex uses the next element
> from the associated array. The index resets to the "first" parameter after
> each instance.
>
> If an attribute has a divisor of N (N>0), all vertices in a group of N
> consecutive instances have the same value for that attribute. The index
> increments by one after each group of N consecutive instances.
>
> IOW, a divisor of zero indicates that the attribute is per-vertex, a
> divisor of one indicates that the attribute is per-instance, a divisor of
> N indicates that the attribute is per-N-instances.
>

Yeah, I've already replied I got it worked out - I thought a divisor of 
two would be every other vertex as I'm applying it to the vertex array, 
but no, I see it's all to do with the quad that's being rendered instead.
I'm just happy with it working now at least. Thanks for the clarification.

Dave.



--------------030300010907030203050209
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: 7bit

<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">On 09/07/2012 07:52, Nobody wrote:<br>
    </div>
    <blockquote cite="mid:pan.2012.07.09.06.52.04.478000@nowhere.com"
      type="cite">
      <pre wrap="">On Sun, 08 Jul 2012 12:58:27 +0100, VelociChicken wrote:

</pre>
      <blockquote type="cite">
        <pre wrap="">Perhaps I'm doing something wrong, when I render the quads I do need to 
multiply the number of instances by the divisor don't I? -

glVertexAttribDivisor(instanceGrassLocation, 4);
glDrawArraysInstancedARB(GL_QUADS, 0, 4, numGrass*4);
</pre>
      </blockquote>
      <pre wrap="">
For your case:
- The per-vertex data should be an array of 4 elements.
- The per-vertex attributes should have a divisor of 0.
- the "count" parameter should be 4.
- The per-instance data should be an array of numGrass elements.
- The per-instance attributes should have a divisor of 1.
- the "primcount" parameter should be numGrass.

The reason for the slowdown is that you're now drawing 4 times as many
instances as you were before.

If an attribute has a divisor of zero, each vertex uses the next element
from the associated array. The index resets to the "first" parameter after
each instance.

If an attribute has a divisor of N (N&gt;0), all vertices in a group of N
consecutive instances have the same value for that attribute. The index
increments by one after each group of N consecutive instances.

IOW, a divisor of zero indicates that the attribute is per-vertex, a
divisor of one indicates that the attribute is per-instance, a divisor of
N indicates that the attribute is per-N-instances.

</pre>
    </blockquote>
    <font face="Verdana"><br>
      Yeah, I've already replied I got it worked out - I thought a
      divisor of two would be every other vertex as I'm applying it to
      the vertex array, but no, I see it's all to do with the quad
      that's being rendered instead.<br>
      I'm just happy with it working now at least. Thanks for the
      clarification.<br>
      <br>
      Dave.<br>
      <br>
    </font><br>
  </body>
</html>

--------------030300010907030203050209--
0
Reply turn1 (48) 7/9/2012 8:11:56 PM

32 Replies
84 Views

(page loaded in 0.84 seconds)

Similiar Articles:


















7/23/2012 9:26:45 AM


Reply: