Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have some code that loops through a set of objects and renders instances of those objects. The list of objects that needs to be rendered is stored as a std::map>, where an object of class MeshResource contains the vertices and indices with the actual data, and an object of classMeshRenderer defines the point in space the mesh is to be rendered at.

My rendering code is as follows:

glDisable(GL_BLEND);
    glEnable(GL_CULL_FACE);
    glDepthMask(GL_TRUE);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);

    for (std::map<MeshResource*, std::vector<MeshRenderer*> >::iterator it = renderables.begin(); it != renderables.end(); it++)
    {
        it->first->setupBeforeRendering();
        cout << "<";
        for (unsigned long i =0; i < it->second.size(); i++)
        {
            //Pass in an identity matrix to the vertex shader- used here only for debugging purposes; the real code correctly inputs any matrix.
            uniformizeModelMatrix(Matrix4::IDENTITY);
            /**
             * StartHere fix rendering problem.
             * Ruled out:
             *  Vertex buffers correctly.
             *  Index buffers correctly.
             *  Matrices correct?
             */
            it->first->render();
        }
        it->first->cleanupAfterRendering();
    }

    geometryPassShader->disable();
    glDepthMask(GL_FALSE);
    glDisable(GL_CULL_FACE);
    glDisable(GL_DEPTH_TEST);

The function in MeshResource that handles setting up the uniforms is as follows:

void MeshResource::setupBeforeRendering()
{
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glEnableVertexAttribArray(2);
    glEnableVertexAttribArray(3);
    glEnableVertexAttribArray(4);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iboID);
    glBindBuffer(GL_ARRAY_BUFFER, vboID);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0); // Vertex position
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*) 12); // Vertex normal
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*) 24); // UV layer 0
    glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*) 32); // Vertex color
    glVertexAttribPointer(4, 1, GL_UNSIGNED_SHORT, GL_FALSE, sizeof(Vertex), (const GLvoid*) 44); //Material index
}

The code that renders the object is this:

void MeshResource::render()
{
    glDrawElements(GL_TRIANGLES, geometry->numIndices, GL_UNSIGNED_SHORT, 0);
}

And the code that cleans up is this:

void MeshResource::cleanupAfterRendering()
{
    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(2);
    glDisableVertexAttribArray(3);
    glDisableVertexAttribArray(4);
}

The end result of this is that I get a black screen, although the end of my rendering pipeline after the rendering code (essentially just drawing axes and lines on the screen) works properly, so I'm fairly sure it's not an issue with the passing of uniforms. If, however, I change the code slightly so that the rendering code calls the setup immediately before rendering, like so:

void MeshResource::render()
{
    setupBeforeRendering();
    glDrawElements(GL_TRIANGLES, geometry->numIndices, GL_UNSIGNED_SHORT, 0);
}

The program works as desired. I don't want to have to do this, though, as my aim is to set up vertex, material, etc. data once per object type and then render each instance updating only the transformation information.

The uniformizeModelMatrix works as follows:

void RenderManager::uniformizeModelMatrix(Matrix4 matrix)
{
    glBindBuffer(GL_UNIFORM_BUFFER, globalMatrixUBOID);
    glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(Matrix4), matrix.ptr());
    glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
share|improve this question
    
I have a nearly identical setup for rendering my models. Except my render call binds the buffer and sets the attribute pointers each time. Are you running into performance issues with this? It runs very fast for me. –  Byte56 Oct 11 '12 at 21:51
    
I haven't run into performance problems unless I have hundreds of identical objects on-screen, but still, I cannot figure out what's going wrong here, and it'd be great to learn why the code isn't working as expected. –  HJ Media Studios Oct 12 '12 at 0:21
1  
We just need to get the attention of @NicolBolas he's the resident openGL expert. –  Byte56 Oct 12 '12 at 16:49
add comment

1 Answer

First of all, OpenGL is full of weird things so a driver bug, however unlikely it may be, is still an option - consider testing the app on different setups (nVidia vs. AMD, older drivers) and other tiny modifications of code. For example, you could start with removing the "glBindBuffer(GL_UNIFORM_BUFFER, 0);" line - it appears to be doing nothing useful anyway.

Since everything here appears to be correct, the problem is most probably not here. There are two options: gDEBugger and stepping through the code in the C++ debugger. It appears that something is being reset just before drawing. In gDEBugger, there's a "call history" feature which could help you see which calls were made before the draw call and in what order.

By the way, I strongly suggest you to wrap every error-returning call with a macro that checks for all possible errors and throws them. It has to be a macro to support extended debugging (printing file, line and the faulty line of code itself) that can be disabled in release builds. If some secret rule is broken, such setup should warn you of that immediately.

share|improve this answer
4  
I would avoid linking to the Gremedy site. That version of gDEBugger is ancient and unsupported and very buggy. developer.amd.com/tools/heterogeneous-computing/amd-gdebugger is the up-to-date AMD supported version, with Windows and Linux support (no OS X, unfortunately). There are also some other fantastic GL debugging/perf tools on AMD's site, not to mention the tools that NVIDIA and Intel offer. –  Sean Middleditch Nov 11 '12 at 20:46
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.