2

I have a problem where the code above intermittently runs incorrectly. In most runs it will correctly print "Successfully initialized OpenGL Device.". However, sometimes I only get "L"Successfully initialized GLEW." and then the application stops/hangs/deadlocks. I don't understand what could cause this, are any of the OpenGL calls blocking in any situation?

    if (glewInit() != GLEW_OK)
        BOOST_THROW_EXCEPTION(ogl_exception() << msg_info("Failed to initialize GLEW."));

    if(!GLEW_VERSION_3_0)
        LOG(warning) << "Missing OpenGL 3.0 support.";

    LOG(info) << L"Successfully initialized GLEW.";

    GL(glGenFramebuffers(1, &fbo_));        
    GL(glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo_));
    GL(glReadBuffer(GL_COLOR_ATTACHMENT0_EXT));
    GL(glDisable(GL_MULTISAMPLE_ARB));

    LOG(info) << L"Successfully initialized OpenGL Device.";

GL is just a macro that calls and checks glGetError().

void GLCheckError(const std::string& expr, const std::string& File, unsigned int Line);

#define GL_EXPR_STR(expr) #expr

#define GL(expr) \
    if(false){}else \
    { \
        (expr);  \
        GLCheckError(GL_EXPR_STR(expr), __FILE__, __LINE__);\
    }

void GLCheckError(const std::string& expr, const std::string& file, unsigned int line)
{
    // Get the last error
    GLenum ErrorCode = glGetError();

    if (ErrorCode != GL_NO_ERROR)
    {
        // Decode the error code
        switch (ErrorCode)
        {
            case GL_INVALID_ENUM :
                BOOST_THROW_EXCEPTION(ogl_invalid_enum()
                    << msg_info("an unacceptable value has been specified for an enumerated argument")
                    << errorstr("GL_INVALID_ENUM")
                    << line_info(line)
                    << source_info(file));

            case GL_INVALID_VALUE :
                BOOST_THROW_EXCEPTION(ogl_invalid_value()
                    << msg_info("a numeric argument is out of range")
                    << errorstr("GL_INVALID_VALUE")
                    << line_info(line)
                    << source_info(file));

            case GL_INVALID_OPERATION :
                BOOST_THROW_EXCEPTION(ogl_invalid_operation()
                    << msg_info("the specified operation is not allowed in the current state")
                    << errorstr("GL_INVALID_OPERATION")
                    << line_info(line)
                    << source_info(file));

            case GL_STACK_OVERFLOW :
                BOOST_THROW_EXCEPTION(ogl_stack_overflow()
                    << msg_info("this command would cause a stack overflow")
                    << errorstr("GL_STACK_OVERFLOW")
                    << line_info(line)
                    << source_info(file));

            case GL_STACK_UNDERFLOW :
                BOOST_THROW_EXCEPTION(ogl_stack_underflow()
                    << msg_info("this command would cause a stack underflow")
                    << errorstr("GL_STACK_UNDERFLOW")
                    << line_info(line)
                    << source_info(file));

            case GL_OUT_OF_MEMORY :
                BOOST_THROW_EXCEPTION(ogl_out_of_memory()
                    << msg_info("there is not enough memory left to execute the command")
                    << errorstr("GL_OUT_OF_MEMORY")
                    << line_info(line)
                    << source_info(file));

            case GL_INVALID_FRAMEBUFFER_OPERATION_EXT :
                BOOST_THROW_EXCEPTION(ogl_stack_underflow()
                    << msg_info("the object bound to FRAMEBUFFER_BINDING_EXT is not \"framebuffer complete\"")
                    << errorstr("GL_INVALID_FRAMEBUFFER_OPERATION_EXT")
                    << line_info(line)
                    << source_info(file));
        }
    }
}
Bohemian
  • 412,405
  • 93
  • 575
  • 722
ronag
  • 49,529
  • 25
  • 126
  • 221
  • Could you please give us the definition of the GL macro? glGetError is a bit tricky to use correct. – datenwolf Nov 16 '11 at 16:37
  • I'm using GL in a lot of other places with no issues. – ronag Nov 16 '11 at 17:03
  • 2
    @ronad: Yep, you're using it wrong. OpenGL accumulates errors. glGetError must be called in a loop until it returns GL_NO_ERROR. This error accumulation doesn't play well with your "one exception class for each OpenGL error" model. – datenwolf Nov 16 '11 at 17:23
  • Are you sure? "glGetError returns the value of the error flag. When an error occurs, the error flag is set to the appropriate error code value. No other errors are recorded until glGetError is called, the error code is returned, and the flag is reset to GL_NO_ERROR. If a call to glGetError returns GL_NO_ERROR, there has been no detectable error since the last call to glGetError, or since the GL was initialized.". Even if that is the case, why would that cause the application to block? – ronag Nov 16 '11 at 17:27
  • Yes, I am sure. If you'd read a bit further: "To allow for distributed implementations, there may be several error flags. If any single error flag has recorded an error, the value of that flag is returned and that flag is reset to GL_NO_ERROR when glGetError is called. If more than one flag has recorded an error, glGetError returns and clears an arbitrary error flag value. Thus, glGetError should always be called in a loop, until it returns GL_NO_ERROR, if all error flags are to be reset." – datenwolf Nov 16 '11 at 17:37
  • Ok, but still how can this cause a block? – ronag Nov 16 '11 at 17:50
  • I'm not saying it's responsible for the block, I just indicate, that I think it was a good idea to not use exceptions in that way. I think your problem is more related to exceptions, than to OpenGL. Did you try a debugger, interrupt the blocked process and looked, at which point in the code the process blocked? – datenwolf Nov 16 '11 at 17:52
  • datenwolf: Unfortunately this problem only occurs when run outside of visual studio on a test machine. The only help I have is the log messages, I will try to put a log message when an error occurs and before he exception is thrown. – ronag Nov 16 '11 at 17:54

0 Answers0