More GPGPU Woes

I have a VBO containing an array of contiguous pairs, each of type GLuint, representing a location on a flat grid. I am trying to send this list of pairs to my shader, but I get a crash on the glDrawElements() call. Note that I’m not trying to “render” anything in a graphical sense. I just want this list to be fed to the shader and received as…


in uvec2  GridLocation;

Initializing the VBO…


    // Initialize grid location pairs...

        // Calculate required storage space for all location pairs...
        GLuint const Storage = m_Width * m_Height * sizeof(GLuint) * 2;

        // Allocate...
        GLuint *pGridLocations = (GLuint *) malloc(Storage);
        
        // Initialize vertex ordinals across the grid...
        for(GLuint CurrentY = 0; CurrentY < m_Height; ++CurrentY)
            for(GLuint CurrentX = 0; CurrentX < m_Width; ++CurrentX)
            {
                // Calculate current location...
                GLuint *pCurrentLocation = 
                    pGridLocations + (2 * ((CurrentY * m_Width) + CurrentX));

                // Store grid index...
                pCurrentLocation[0] = CurrentX;
                pCurrentLocation[1] = CurrentY;
            }

        // Initialize vertex buffer object with vertex pairs...
        
            // Allocate...
            glGenBuffers(1, &m_VBO_GridLocations);
            
            // Select...
            glBindBuffer(GL_ARRAY_BUFFER, m_VBO_GridLocations);
            
            // Commit grid indices to card...
            glBufferData(GL_ARRAY_BUFFER, Storage, pGridLocations, GL_STATIC_DRAW);
            
            // Associate data with generic vertex attribute...
            glVertexAttribPointer(m_GVA_GridLocations, 2, GL_UNSIGNED_INT, GL_FALSE, 0, BufferOffset(0));

Routine to pass data to shader to do some fancy calculations and store in FBO’s attached texture.


// Re-evaluate the waves, but must be called at constant interval...
void Fluid::EvaluateWaves()
{
    // Variables...
    GLint   Viewport[4] = { 0, 0, 0, 0 };

    // Setup viewport for one to one pixel = texel = geometry mapping...
    
        // Projection should not transform...
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluOrtho2D(0.0, m_Width, 0.0, m_Height);
        
        // There should be no modelview transformations either...
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        // Lastly, backup viewport size, and resize to the size of grid maps...
        glGetIntegerv(GL_VIEWPORT, Viewport);
        glViewport(0, 0, m_Width, m_Height);

    // Redirect rendering through our framebuffer object...
    glBindFramebuffer(GL_FRAMEBUFFER, m_FrameBufferObject);

        // Check for OpenGL errors...
        PrintOpenGLErrors();

    // Make sure data written to texture replaces and doesn't just modulate...
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

    // Send grid location data to program...

        // Install program...
        glUseProgram(m_PO_EvaluateWaves);

        // Select the Z map texture...
        glBindTexture(GL_TEXTURE_2D, m_ZMaps_TextureID[0]);

        // Enable required vertex arrays...
        glEnableVertexAttribArray(m_GVA_GridLocations);

        // Select the grid indices...
        glBindBuffer(GL_ARRAY_BUFFER, m_VBO_GridLocations);

/****** Crashes on next line ******/
        // Commit data to shader...
        glDrawElements(GL_POINTS, m_Width * m_Height, GL_UNSIGNED_INT, BufferOffset(0));

        // Disable required vertex arrays...
        glDisableVertexAttribArray(m_GVA_GridLocations);

        // Check for OpenGL errors...
        PrintOpenGLErrors();

    // Restore state...
    
        // Default framebuffer...
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
    
        // Viewport back to original dimensions...
        glViewport(Viewport[0], Viewport[1], Viewport[2], Viewport[3]);
        
        // Check for OpenGL errors...
        PrintOpenGLErrors();
}

I’ve been trying to get this to work for two days now and of no luck. =(

Kip

There are several things wrong with this. But I can tell you why this crashes:

glDrawElements(GL_POINTS, m_Width * m_Height, GL_UNSIGNED_INT, BufferOffset(0));

glDrawElements does indexed rendering. This means you need an array of indices, which is what the last argument should refer to.

Since there is no buffer object bound to GL_ELEMENT_ARRAY_BUFFER, the last argument is a pointer. You passed in NULL. So the first thing this will doe is reference NULL.

So you either forgot to bind something to GL_ELEMENT_ARRAY_BUFFER, or you should be using glDrawArrays instead of glDrawElements.

Thanks Alfonse. I passed in NULL because I thought it would dereference from the currently bound VBO, but since I never bound one of the GL_ELEMENT_ARRAY_BUFFER, it makes sense that it would crash.

I used glDrawElements instead of glDrawArrays because the latter is apparently deprecated?

Can you think of a more sensible solution I should have pursued to just pass that list of pairs of GLuint into my shader?

I appreciate your spotting that error.

I used glDrawElements instead of glDrawArrays because the latter is apparently deprecated?

Says who?

Sorry, my bad, got it confused with glArrayElement. So you recommend glDrawArrays() API instead? I imagine I would allocate an element array buffer which is just the list of numbers from 0 to n-1 pairs. Correct?

OK, seriously, read this wiki page.

Thanks Alfonse. I’ve read it and it wasn’t helpful.

I’ve changed the call to initialize the array with


glVertexAttribIPointer(m_GVA_GridLocations, 2, GL_UNSIGNED_INT, 0, BufferOffset(0));

Instead of the glVertexAttribPointer call.

I’m trying to send the list to the shader via


glDrawArrays(GL_POINTS, 0, m_Width * m_Height);

When I use glReadPixels to examine the output, it’s the same junk as if I had never called glDrawArrays. My shader, as a test, should just be writing 0.0f for each pair sent.

I don’t know what I’ve done wrong. I appreciate the links, but I’ve gone through over a thousand pages of material in the red book and the orange book, and sometimes we aren’t perfect and miss something and someone more experienced pointing out a solution can be very helpful.