Jump to content
  • Advertisement
Sign in to follow this  
sothro

OpenGL Drawing multiple objects

This topic is 2073 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi,

 

Im' currently trying to draw multiple objects with opengl but when i'm trying to create my second model the program crashes with following errors: Error: 0:4: 'GL_ARB_explicit_attrib_location' : extension is disabled and then the same error with just 0:6 as difference.

 

I call the code below for every model in my vector of Model_3D objects, the GLuint programid variable isn't used.

 

My code is as follow:

void CreateObject(Model_3D *model,GLuint programid)
{
    //models->at(0)->SetShaderId(LoadShader("C:\\Users\\Sander\\Documents\\RTS idee\\idee\\engine\\GameEngine\\Debug\\SimpleShader.fragment.glsl", GL_FRAGMENT_SHADER));
    model->SetShaderIdFragment(LoadShader("C:\\Users\\Sander\\Documents\\RTS idee\\idee\\engine\\GameEngine\\Debug\\SimpleShader.fragment.glsl", GL_FRAGMENT_SHADER));
    model->SetShaderIdVertex( LoadShader("C:\\Users\\Sander\\Documents\\RTS idee\\idee\\engine\\GameEngine\\Debug\\SimpleShader.vertex.glsl", GL_VERTEX_SHADER));
    
        model->SetShaderIdProgram(glCreateProgram());
    //ShaderIds[0] = glCreateProgram();
    ExitOnGLError("ERROR: Could not create the shader program");

    
    glAttachShader(model->GetShaderIdProgram(), model->GetShaderIdFragment());
    glAttachShader(model->GetShaderIdProgram(), model->GetShaderIdVertex());
 


    glLinkProgram(model->GetShaderIdProgram());
    ExitOnGLError("ERROR: Could not link the shader program");

    ModelMatrixUniformLocation = glGetUniformLocation(model->GetShaderIdProgram(), "ModelMatrix");
    ExitOnGLError("ERROR: Could not get the shader uniform locations for modelmatrix");
    ViewMatrixUniformLocation = glGetUniformLocation(model->GetShaderIdProgram(), "ViewMatrix");
    ExitOnGLError("ERROR: Could not get the shader uniform locations for viewmatrix");
    ProjectionMatrixUniformLocation = glGetUniformLocation(model->GetShaderIdProgram(), "ProjectionMatrix");
    ExitOnGLError("ERROR: Could not get the shader uniform locations for projectionMatrix");

    glGenVertexArrays(1, &BufferIds[0]);
    ExitOnGLError("ERROR: Could not generate the VAO");
    glBindVertexArray(BufferIds[0]);
    ExitOnGLError("ERROR: Could not bind the VAO");

    //cube 1
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    ExitOnGLError("ERROR: Could not enable vertex attributes");

    glGenBuffers(2, &BufferIds[1]);
    ExitOnGLError("ERROR: Could not generate the buffer objects");
    
    int sizeVertex=sizeof(model->GetVertices().front());
    int vertexEllements=(model)->GetVertices().size();
    int sizeVertexes=sizeVertex*vertexEllements;
    glBindBuffer(GL_ARRAY_BUFFER, BufferIds[1]);
    //glBufferData(GL_ARRAY_BUFFER, sizeof(VERTICES), VERTICES, GL_STATIC_DRAW);
    glBufferData(GL_ARRAY_BUFFER, sizeVertexes, &model->GetVertices().front(), GL_STATIC_DRAW);

    ExitOnGLError("ERROR: Could not bind the VBO to the VAO");

    //glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(VERTICES[0]), (GLvoid*)0);
    //glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(VERTICES[0]), (GLvoid*)sizeof(VERTICES[0].Position));
        glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(model->GetVertices().front()), (GLvoid*)0);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(model->GetVertices().front()), (GLvoid*)sizeof(model->GetVertices().front().Position));
    ExitOnGLError("ERROR: Could not set VAO attributes");

    
    int size=sizeof(model->GetIndices().front());
    int ellements=model->GetIndices().size();
    int sizeIndices=size*ellements;
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, BufferIds[2]);
    //glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(INDICES), INDICES, GL_STATIC_DRAW);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeIndices,&model->GetIndices().front(), GL_STATIC_DRAW);

    ExitOnGLError("ERROR: Could not bind the IBO to the VAO");
 
    glBindVertexArray(0);
}

I'm probably understanding the use of the shaders and bufferIds wrong, i think i need to create seperate bufferIds for all my models, is this so?

And the glCreateProgram() is this unique for every model or the same?

 

Thanks for all the responses

 

 

Share this post


Link to post
Share on other sites
Advertisement

What version of GL context are you getting?

Could you post your vertex shader code?

 

There are functions that separate vertex format from the buffers being used, but for GL ~3.3 a vertex array per unique model is the norm. It's also perfectly normal for a great many objects to use the same shader program and to sort by shader. That error sounds like a GLSL compile error, but if you were successfully rendering one object with the same shader before your attempt to render more, I'm at a loss to solve the problem with just the information provided.

 

It's probably not relevant, but the second parameter to glVertexAttribPointer is the number of elements (floats here), not sizeof(float), if that helps. I don't know what your vertex format is so no idea if there's really 8 floats per vertex.

Share this post


Link to post
Share on other sites

I'm getting version 3.3.0.

 

I could draw 1 objects but when i try to create a second one i get the error that you can read in my first post.

 

As requested my vertex shader code:

#version 330


layout(location=0) in vec4 in_Position;

layout(location=1) in vec4 in_Color;

out vec4 ex_Color;

uniform mat4 ModelMatrix;

uniform mat4 ViewMatrix;

uniform mat4 ProjectionMatrix;


void main(void)
{

    gl_Position = (ProjectionMatrix * ViewMatrix * ModelMatrix) * in_Position;

    ex_Color = in_Color;
}

Thanks for the response allready :D

Share this post


Link to post
Share on other sites

Hi again,

 

i'm getting these errors when i'm loading my shaders for the second time for a new model:

 

ERROR: 0:4: 'GL_ARB_explicit_attrib_location' : extension is disabled
ERROR: 0:6: 'GL_ARB_explicit_attrib_location' : extension is disabled
 

If googled it but can't get wise out of it.

 

The code to load my shaders is this:

GLuint LoadShader(const char* filename, GLenum shader_type)
{
    GLuint shader_id = 0;
    FILE* file;
    long file_size = -1;
      GLchar* glsl_source;
      //added by me
     const GLchar* glsl_source_gl;
    
    if (NULL != (file = fopen(filename, "rb")) &&
        0 == fseek(file, 0, SEEK_END) &&
        -1 != (file_size = ftell(file)))
    {
        rewind(file);
        
        if (NULL != (glsl_source = (char*)malloc(file_size + 1)))
        {
            if (file_size == (long)fread(glsl_source, sizeof(char), file_size, file))
            {
                //added by me
                glsl_source_gl=glsl_source;

                glsl_source[file_size] = '\0';

                if (0 != (shader_id = glCreateShader(shader_type)))
                {


                    glShaderSource(shader_id, 1, (&glsl_source_gl), NULL);
                    
                    glCompileShader(shader_id);
                    ExitOnGLError("Could not compile a shader");

                    GLint status=1;
                     glGetShaderiv(shader_id, GL_COMPILE_STATUS, &status);
                    if(status==GL_FALSE)
                    {
                        ExitOnGLError("ERROR: Could not compile shader");
                    }

                    int infologLength = 0;
    int maxLength;
 
    
        glGetShaderiv(shader_id,GL_INFO_LOG_LENGTH,&maxLength);

 
    char infoLog[256];

        glGetShaderInfoLog(shader_id, maxLength, &infologLength, infoLog);

 
    if (infologLength > 0)
        printf("%s\n",infoLog);

                }
                else
                    fprintf(stderr, "ERROR: Could not create a shader.\n");
            }
            else
                fprintf(stderr, "ERROR: Could not read file %s\n", filename);
            
            free(glsl_source);
        }
        else
            fprintf(stderr, "ERROR: Could not allocate %i bytes.\n", file_size);

        fclose(file);
    }
    else
        fprintf(stderr, "ERROR: Could not open file %s\n", filename);

    return shader_id;

If anyone can point me in the right direction i would be very grateful.

Share this post


Link to post
Share on other sites

Sorry for the long delay between replies.

 

It's very strange that you would only get the error the second time through.

One thing to try would be to explicitly enable that extension using:

#extension GL_ARB_explicit_attrib_location : enable

after the version line.

 

Might be worthwhile to attempt to update your drivers.

Share this post


Link to post
Share on other sites

Hmmm.... Did you tried printing out the char array after loading to see if its exactly what you want to send to the GPU?

Share this post


Link to post
Share on other sites

Hi,

 

The char array is exactly the same as the first object that is created without any problem.

 

I have added the line :

#extension GL_ARB_explicit_attrib_location : enable

To my vertex shader as suggested by beans222, and now i'm not getting any error when trying to create the second object.

 

What does this line do exactly? Is it a problem with nvidia cards?

 

Thanks for all the help guys ;)

Share this post


Link to post
Share on other sites

Are you familiar with the extension system in OpenGL?

 

OpenGL has releases, like 2.0, 3.2, 3.3, 4.1, and so on. Which each release there are "core" features, things that should be available and working when you create a context of that version.

 

Often vendors release their own extensions, that is, features that are outside what OpenGL considers "core". These features have to be enabled explicitly, they don't just work once you create a context, unlike "core extensions".

 

You can also enable features that one OpenGL version considers "core features" and other doesn't.

 

Say that you want to use Uniform Buffers Objects (UBOs), but you are working on an OpenGL 3.0 context. UBOs are "core" but only from OpenGL 3.1 and above, so you have to explicitly enable ARB_uniform_buffer_object (name of the extension) to use them, and it will work if the card supports it (since they're not core for OpenGL 3.0 context, it might or might not be available).

 

There are also extensions that work inside the shaders, so you have to enable them in the shader source instead.

 

In your particular case, GL_ARB_explicit_attrib_location isn't enabled for some reason (which is weird since it is inside what OpenGL considers "core features" for OpenGL 3.2 contexts and above), so you're enabling it explicitly from the shader.

 

Its the extension that allows you to do this

layout(location=0) in vec4 in_Position;

That is, explicitly state the location of each vertex attribute (in this case, location of the attribute position is specified to be 0, and you can specify whatever location you want).

 

It makes easier to use vertex attributes with that since you don't have to query which location OpenGL assigned to your attribute each time you make one, you just have to say from the CPU code "this attribute position goes in location 0", then in the GLSL code "the attribute position will be coming from location 0" and it works.

Edited by TheChubu

Share this post


Link to post
Share on other sites

Thanks for the explanation :D

 

Now i can finally try to draw more then one object one my screen, just need to find out how to position them seperatly ;)

 

Thanks guys, really i didn't understand why it wouldn't work :D

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!