Vertex Array & Interleaved Array troubles

Sage
Posts: 1,199
Joined: 2004.10
Post: #1
I'm implementing something I read about in a paper a long time ago. It's called projected-grid water, and it works by projecting an eye-space grid to a water plane and perturbing that to make waves. So far, it's working really well.

Usually I start with simple immediate mode rendering, and when I know geometry's being processed and submitted correctly I move on to faster paths.

The trouble here is that my immediate mode rendering works quite well, but using vertex arrays doesn't work, nor do interleaved arrays. I'm using an array of a struct with several members in it and I thought I was striding it correctly, but clearly something's wrong.

Here's my code.
Code:
struct water_vertex
{          
    gfs::vec4 c; // color
    sgf::vec3 n; // normal
    sgf::vec3 v; // vertex
    
    // everything below is strided
    sgf::vec2 screenVertex;
    bool projected;
};

static const GLenum water_vertex_format = GL_C4F_N3F_V3F;
static const unsigned int water_vertex_stride = sizeof( water_vertex ) - ( sizeof( sgf::vec4 ) + sizeof( sgf::vec3 ) + sizeof( sgf::vec3 ) );

enum render_approach
{
    interleaved_arrays,
    vertex_arrays,
    immediate_mode
};

void
Ocean::renderSolid( void )
{
    const render_approach renderMode = immediate_mode;

    glError();
    switch( renderMode )
    {
        case interleaved_arrays:
        {
            glInterleavedArrays( water_vertex_format, water_vertex_stride, &(_vertices.front()));  
            glDrawElements( GL_TRIANGLES, _indices.size(), GL_UNSIGNED_INT, &(_indices.front()));
            break;
        }

        case vertex_arrays:
        {
            water_vertex *verticesPtr = &(_vertices.front());

            glEnableClientState( GL_COLOR_ARRAY );
            glColorPointer( 4,  GL_FLOAT, sizeof( water_vertex ), verticesPtr );

            glEnableClientState( GL_NORMAL_ARRAY );
            glNormalPointer( GL_FLOAT, sizeof( water_vertex ), verticesPtr + sizeof( vec4 ));

            glEnableClientState( GL_VERTEX_ARRAY );
            glVertexPointer( 3, GL_FLOAT, sizeof( water_vertex ), verticesPtr + sizeof( vec4 ) + sizeof( vec3 ));
            
            glDrawElements( GL_TRIANGLES, _indices.size(), GL_UNSIGNED_INT, &(_indices.front()));


            glDisableClientState( GL_VERTEX_ARRAY );
            glDisableClientState( GL_NORMAL_ARRAY );
            glDisableClientState( GL_COLOR_ARRAY );

            break;
        }

        case immediate_mode:
        {
            glBegin( GL_TRIANGLES );
            for ( unsigned int i = 0, N = _indices.size(); i < N; i += 3 )
            {
                unsigned int a( _indices[i + 0] ),
                             b( _indices[i + 1] ),
                             c( _indices[i + 2] );
                
                if ( _vertices[a].projected || _vertices[b].projected || _vertices[c].projected )
                {
                    glColor4fv( _vertices[a].c );
                    glNormal3fv( _vertices[a].n );
                    glVertex3fv( _vertices[a].v );

                    glColor4fv( _vertices[b].c );
                    glNormal3fv( _vertices[b].n );
                    glVertex3fv( _vertices[b].v );

                    glColor4fv( _vertices[c].c );
                    glNormal3fv( _vertices[c].n );
                    glVertex3fv( _vertices[c].v );
                }

            }
            glEnd();

            break;
        }
    }
    
    glError();  
}

The immediate mode path works great, so I know my data's correct. Clearly I'm striding it incorrectly, or something to that effect. Can anybody see anything obvious here?

One thing I should note here is that my original implementation used several different std::vectors, one for each type of data. One for color, one for normal, one for vertices, etc etc. That one rendered correctly with vertex arrays. I went from that one to my packed vertex approach you see above because when I profiled it I saw I was spending a lot of time in std::vector's array access operator, since I had to use numerical indexing and couldn't take advantage of iterators. Packing them all into once struct has saved a few CPU % points, and has allowed for some other optimization, but has apparently blown up my rendering pipeline. Sad
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #2
The stride should be sizeof(water_vertex)
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #3
Great Scott!

You did it, thanks, OSC! For some reason I was thinking of the stride as being the bytes of the struct which weren't being rendered. But, of course, sizeof( water_vertex ) makes perfect sense.

I'll go hide in a cave, now.

PS: Your desudesudesu.net is one of the stranger things I've seen in a long time. Baffling.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #4
In a lot of ways, your definition of stride would make sense (because then the default 0 wouldn't be a special case). That's not the way it works, though.
Quote this message in a reply
Moderator
Posts: 770
Joined: 2003.04
Post: #5
You know, this thread is very boring without cool pictures of projected-grid water... Wink
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #6
Screenshots! Well, they're not very exciting, because I haven't implemented any shaders yet. This is pure fixed-function for verifying that the geometry is working.

[Image: ProjectionGridWater_0.png]

[Image: ProjectionGridWater_1.png]

The colors are being calculated on CPU right now but will be offloaded to a vertex shader soon. They are a dynamic normalmap -- so I'll get accurate reflection/refraction distortion. It should look pretty sweet.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  (Offered) Voice Artist With Vast Array of Voices RoskoPeeko 0 3,206 Apr 5, 2011 06:06 AM
Last Post: RoskoPeeko
  OpenAL install troubles m3the01 3 3,198 Feb 20, 2009 12:46 PM
Last Post: DaveJ
  Particle Vertex Array bonanza 9 4,276 Jun 27, 2008 07:46 AM
Last Post: bonanza
  reading wavefront-file in array bonanza 6 4,891 Sep 6, 2007 05:43 AM
Last Post: bonanza
  Vertex Array Range bonanza 3 3,625 Jun 19, 2007 12:42 PM
Last Post: OneSadCookie