Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

invalid operation on glEnd without cause?

Tags:

c++

opengl

I have been working on a GL program for some time now and suddenly it began to give errors. After trying to resolve these for a while I wrote a short test program that generates the same behavior:

#include <GL/glut.h>
#include <iostream>

#define CHECK_GL_ERR() printError(__LINE__)

void printError(int line)
{
        GLenum err = glGetError();
        if(err != GL_NO_ERROR)
        {
                std::cerr << "GL error on line " << line << ": " << gluErrorString(err) << std::endl;
        }
}

void displayFunc()
{
        CHECK_GL_ERR();
        glBegin(GL_POINTS);
        CHECK_GL_ERR();
        glVertex3f(0, 0, 0);
        CHECK_GL_ERR();
        glEnd();
        CHECK_GL_ERR(); //line 23
        exit(0);
}

int main(int argc, char **argv)
{
        glutInit(&argc, argv);
        glutInitWindowSize(300, 300);
        glutCreateWindow("Test");

        glutDisplayFunc(displayFunc);

        glutMainLoop();
}

When I run this program it gives the output:

GL error on line 23: invalid operation

So it seems that glEnd(); causes the error. The docs say:

GL_INVALID_OPERATION is generated if glEnd is executed without being preceded by a glBegin.

Which is not the case in my code. So does anyone see, why this code gives an error message?

PS: Of course I know that glBegin/End has been deprecated/removed for a long time but it is very convenient to hack together some small amounts of code. Also the program worked without errors until GL decided to be grumpy.

EDIT

I just did a trace with glslDevil which gave:

W! Program Start
|  glXQueryExtension(0x1ab03f0, (nil), (nil))
|  glXChooseFBConfig(0x1ab03f0, 0, 0x7fffb8fcf8b0, 0x7fffb8fcf8a4)
|  glXGetVisualFromFBConfig(0x1ab03f0, 0x111)
|  glXGetProcAddressARB(0x7f93c37526e5)
|  glXCreateNewContext(0x1ab03f0, 0x111, 32788, (nil), 1)
|  glXIsDirect(0x1ab03f0, 0x1ac8de8)
|  glXMakeContextCurrent(0x1ab03f0, 123731970, 123731970, 0x1ac8de8)
|  glXMakeContextCurrent(0x1ab03f0, 123731970, 123731970, 0x1ac8de8)
|  glDrawBuffer(GL_FRONT)
|  glReadBuffer(GL_FRONT)
|  glXMakeContextCurrent(0x1ab03f0, 123731970, 123731970, 0x1ac8de8)
|  glViewport(0, 0, 300, 300)
|  glXMakeContextCurrent(0x1ab03f0, 123731970, 123731970, 0x1ac8de8)
|  glXMakeContextCurrent(0x1ab03f0, 123731970, 123731970, 0x1ac8de8)
|  glGetError()
|  glBegin(GL_POINTS)
|  glGetError()
|  glVertex3f(0,000000, 0,000000, 0,000000)
|  glGetError()
|  glEnd()
W! OpenGL error GL_INVALID_OPERATION detected
|  glGetError()
|  glXMakeContextCurrent(0x1ab03f0, 123731970, 123731970, 0x1ac8de8)
|  glXDestroyContext(0x1ab03f0, 0x1ac8de8)
E! Child process exited
W! Program termination forced!
like image 570
Nobody moving away from SE Avatar asked Nov 18 '12 13:11

Nobody moving away from SE


1 Answers

After some testing, I found your program have two simple issues:

  1. You must not use glGetError inside a glBegin/glEnd block. The API is strict about that. But the error only happens after glEnd. If you read the API, you'll find that the error might propagate: it only happens after the glEnd.
  2. A segmentation fault occurs when you use exit(0) inside the display function(that only happens with the Intel driver.) That happens because the GL context hasn't been freed yet, and a driver bug comes along. So you should avoid exit inside the display function.
like image 62
Charles Welton Avatar answered Oct 13 '22 16:10

Charles Welton