Debugging OpenGL code

I’m writing a Batcher currently and having nothing displayed on the screen. I haven’t understood what’s the problem, I’ve rewritten the class more than a 20 times and still the same result. So I’ve tried using [icode]glGetError()[/icode] and put calls to it after every call to a opengl function and set break-points on those instances. The output said that there are errors when I’m updating the VBOs, so here is my code where I update my VBOs.


glBindBuffer(GL_ARRAY_BUFFER, vboVertID);
checkForErrors();
glBufferSubData(GL_ARRAY_BUFFER, 0, vBuffer);
checkForErrors();// Unacceptable value, Specified operation is not allowed in current state
        
glBindBuffer(GL_ARRAY_BUFFER, vboNormID);
checkForErrors();// Numeric argument is out of range
glBufferSubData(GL_ARRAY_BUFFER, 0, nBuffer);
checkForErrors();
        
glBindBuffer(GL_ARRAY_BUFFER, vboColID);
checkForErrors();// Numeric argument is out of range
glBufferSubData(GL_ARRAY_BUFFER, 0, cBuffer);
checkForErrors();
        
glBindBuffer(GL_ARRAY_BUFFER, vboTexID);
checkForErrors();// Numeric argument is out of range
glBufferSubData(GL_ARRAY_BUFFER, 0, tBuffer);
checkForErrors();

And my method to print the error messages is


public void checkForErrors()
{
    int error = GL_NO_ERROR;
        
    while ((error = glGetError()) != GL_NO_ERROR)
    {
        switch (error)
        {
            case GL_INVALID_ENUM:
                System.err.println("An unacceptable value is specified for an enumerated argument.");
                break;
            case GL_INVALID_VALUE:
                System.err.println("A numeric argument is out of range.");
                break;
            case GL_INVALID_OPERATION:
                System.err.println("The specified operation is not allowed in the current state.");
                break;
            default:
                System.err.println("Unknown OpenGL Error");
        }
    }
}

I’m now confused on where the error is. The complete class is here.

Thanks.

What is the precise output you get?

Also, you may get better error descriptions using the following method (borrowed from ra4king):

public static void checkGLError(String event) {
		int error;
		if((error = glGetError()) != GL_NO_ERROR)
			throw new RuntimeException("OpenGL Error during " + event + ": " + gluErrorString(error));
	}

Here is the output from it.


glBindBuffer(GL_ARRAY_BUFFER, vboVertID);
checkForErrors("L120"); // Invalid enum, Invalid operation
glBufferSubData(GL_ARRAY_BUFFER, 0, vBuffer);
checkForErrors("L122"); // Invalid value

glBindBuffer(GL_ARRAY_BUFFER, vboNormID);
checkForErrors("L125");
glBufferSubData(GL_ARRAY_BUFFER, 0, nBuffer);
checkForErrors("L127"); // Invalid value

glBindBuffer(GL_ARRAY_BUFFER, vboColID);
checkForErrors("L130");
glBufferSubData(GL_ARRAY_BUFFER, 0, cBuffer);
checkForErrors("L132"); // Invalid value

glBindBuffer(GL_ARRAY_BUFFER, vboTexID);
checkForErrors("L135");
glBufferSubData(GL_ARRAY_BUFFER, 0, tBuffer);
checkForErrors("L137"); // Invalid value

Dunno why does my [icode]glBindBuffer()[/icode] call returns [icode]GL_INVALID_ENUM[/icode] or [icode]GL_INVALID_OPERATION[/icode]

That is source code, right? Or am I missing something? I sure does not look like any output.

Enable OpenGL debug mode.


            Display.create(new PixelFormat(), new ContextAttribs().withDebug(true));
            glDebugMessageCallbackARB(new ARBDebugOutputCallback());

@Grunnt
Sorry for not mentioning that I’ve commented the errors on the line in the source based on the output. Here is the actual output.


L120: Invalid enum
L122: Invalid value
L127: Invalid value
L132: Invalid value
L137: Invalid value
L120: Invalid operation
L122: Invalid value
L127: Invalid value
L132: Invalid value
L137: Invalid value
L120: Invalid operation
L122: Invalid value
L127: Invalid value
L132: Invalid value
L137: Invalid value
... same being repeated ...

@theagentd

That didn’t work out. It said that “the function is not supported” on the glDebugMessageCallbackARB line.

It’s impossible to say what the problem is with just this code.

  1. Look at the official documentation pages for the functions you’re calling and you’ll see what the different errors mean. From http://www.opengl.org/sdk/docs/man2/xhtml/glBufferSubData.xml:

[quote]GL_INVALID_VALUE is generated if offset or size is negative, or if together they define a region of memory that extends beyond the buffer object’s allocated data store.
[/quote]
2. You should always call glGetError() BEFORE what you’re trying to debug as well as after to ensure that no error was already present when the function was called. Remember that if an error occurs, glGetError() will be locked to that error code until you clear it with glGetError(). I suspect this is why you’re detecting a “Invalid enum” error on glBindBuffer() since GL_ARRAY_BUFFER is a valid enum.

Either you’re developing on an Intel card or you have really outdated drivers for your Nvidia/AMD card. It’s a good idea to get this working as it gives much more detailed information about errors.

@theagentd

Yes I’ve added calls to [icode]checkForErrors()[/icode] before and after each opengl call. I’ve added them even before creation of buffers too. The errors only start to appear when the [icode]end()[/icode] method is called on the batcher where I update the buffers and render them.

My card is NVIDIA GeForce 210 (I know it’s old, saving my pocket money for a new card) and I’m using a hackintosh so I’m limited to compatibility mode (OpenGL 2.1 but supports 95% of OpenGL 3.3 functions as well). The driver version is 310.84, is old too, but there isn’t a new release for mac. Any ideas on what to do?

why is drawarrays (something, something, vertexamount*9)
I thought it needed (something, something, vertexmount)

I copied it from a previous one where [icode]vertexamount[/icode] was [icode]model.getFaces()[/icode]. Didn’t work with [icode]vertexamount[/icode] either.

hmmmmmmmm
The only last suggestion I have from my experience is look at the very basics. Most of my errors are really small things at lowest level of my program. Sometimes I spend whole day trying to solve a bug and at the end of the day I go check basic constructor which is supposed to set things, but it doesn’t.

What I mean is try using quads, they are not ‘best’ but for 2d game they don’t make any difference.
Also try not using any things like shaders, framebuffers and all the other stuff that isn’t necessary for rendering basic shapes.
You might just wanna try to write a basic spritebatcher which only handles vertices.

The only thing left then is to look at the documentation of each of your failing methods and see what those errors are caused by. I’m pretty sure debug mode doesn’t work on Macs regardless of profile.

Found this on the docs of [icode]glBindBuffer()[/icode]

I can’t understand it properly. Can you please explain what it means to me?

It means that all relevant buffer operations will affect the bound buffer. Binding 0 is the same as binding nothing or null (same as having nothing bound). If 0 is bound then any operations will throw a GL_INVALID_OPERATION error. Initially 0 is bound.

So, it means that 0 is the currently bound vbo. I’ve been passing [icode]vboVertID[/icode] to the call, dunno why 0 is bound still. I’ve also ensured that the value of the vbo is not 0, it’s 1 in the debugger and I’ve also generated the buffer.