glBinding/GLFW "Error after macro substitution"

1.2k views Asked by At

I am trying to learn OpenGL with GLFW/glBinding and I if i want to create and use a vertexbuffer, I get the Compilingerror

error: cannot convert ‘int’ to ‘gl::GLenum’ for argument ‘1’ to ‘void gl::glBindBuffer(gl::GLenum, gl::GLuint)’
 gl::glBindBuffer(GL_ARRAY_BUFFER, VBO);

My IDE (Clion) tells me, that there is a param mismatch (obviously) after a Macro substitution. So my Question is: what did I wrong? Because if it was the macros fault, there would be more hits on google for this topic :)

Code:

GLuint VBO;
gl::glGenBuffers(1, &VBO);
gl::glBindBuffer(GL_ARRAY_BUFFER, VBO);    

My Tutorial is this and it it says not to use the namespace gl:: but if I don't I can't access the functions, so i guess this is not the problem.

thanks

2

There are 2 answers

5
Quentin On BEST ANSWER

First step: according to glBinding's documentation, the argument should be something like gl::GL_ARRAY_BUFFER. Still, this won't solve the whole problem.

This is because your OpenGL implementation used #define's to expose constants such as GL_ARRAY_BUFFER, in the following manner:

#define GL_ARRAY_BUFFER 1

This means that your code is actually preprocessed to:

gl::glBindBuffer(1, VBO);

And that, before the compiler has had a chance to see your code and use glBinding's GL_ARRAY_BUFFER. Hence the error.

The solution is, as stated in the documentation, to remove and replace the standard GL.h include with the include from glBinding.

0
curious student On

I know I'm late to the party, but this might help those that Google this, as I did. First of all, there are 2 ways of solving this, a future-proof method and a quick-and-dirty method.

The quick and dirty method, as stated above by Steelbean, is:

#define GLFW_INCLUDE_NONE
#include <glbinding/gl/gl.h>
#include <GLFW/glfw3.h>

The order is CRITICAL.

The elegant and future-proof method is to create a special header file where all of your conditional #include s are added. As an example, here is mine. Note that I use exclusively 1 out of the 2 libraries that are specified in the header file, but you can use them both(or even add more):

#pragma once // OR THE OLD-STYLE HEADER GUARD, IF THAT'S WHAT YOU'RE INTO
// This is where you specify what window manager you want to use
#define __WML_GLFW3__ 1
#define __glLOADER_glBINDINGS__ 1





#ifdef __glLOADER_glBINDINGS__

#include <glbinding/gl/gl.h>
#include <glbinding/Binding.h>
//This is here for readability.
namespace gl
{
    using VAO_t = GLuint;
    using program_t = GLuint;
    using shader_t = GLuint;
    using shader_source_t = GLchar*;
    using buffer_t = GLuint;
};

#else

#error "No available GL Loader.\n"

#endif

// If you want to use SFML
#ifdef __WML_SFML__

static const EWindowLib WINDOW_LIB = EWindowLib::sfml;

#elif defined __WML_GLFW3__
#ifdef __glLOADER_glBINDINGS__
#define GLFW_INCLUDE_NONE 1
#endif
#include <GLFW/glfw3.h>

static const EWindowLib WINDOW_LIB = EWindowLib::glfw;

#else

#error "No available window manager library.\n"

#endif

static int initEnvironment()
{

    #ifdef __glLOADER_glBINDINGS__
    glbinding::Binding::initialize();
    #else
    #error "No available GL Loader.\n"
    #endif

    switch(WINDOW_LIB)
    {
        case EWindowLib::sfml:
            break;

        case EWindowLib::glfw:
            if(glfwInit() != GLFW_TRUE)
                return GLFW_FALSE;
            glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
            glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
            glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
            glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
            break;

        default:
            break;
    }
}

static int terminateEnvironment()
{
    #ifdef __WML_GLFW3__
    glfwTerminate();
    #endif

    //TODO: change this into a fancy error-checking method. 
    return (1);
}

Note that the order here is also critical. To be more precise, you need to define GLFW_INCLUDE_NONE before you include GLFW. Now that I have this header file(let's call it DEFS.hpp) I can use SMFL and GLFW for window management interchangeably just by removing one define and adding another. Now DEFS.hpp will be included in the source file that defines the program's entry point; that is, include DEFS.hpp in the source file with int main(/*int argc, char** argv*/). Hope this saves you some development time.