4
$\begingroup$

I'm trying to switch between the rendering of two different scenes as fast as possible using OpenGL.

For all my OpenGL related stuff I wrote a wrapper-class which provides a quite easy way of adding and updating data. Based on the added data it automatically creates the variable naming for the shader. In the past I always used just one instance of this OpenGL class but now I'm trying to use two of them. (Each instance has its own shader program.)

When I do something like:

OpenGLInstance1.AssignModel(*MyModel1);

it automatically adds data and writes into the shader code:

// per vertex attributes 
layout (location = 0) in vec3   position;
layout (location = 1) in vec3   normals;
layout (location = 2) in uvec4  BoneIDs;
layout (location = 3) in vec4   Weights;

// per instance attributes
layout (location = 4) in mat4   CameraMatrix;           //dynamic
layout (location = 8) in mat4   ProjectionMatrix;       //dynamic

When I try to do this a second time with an other OpenGL-Class instance and Model:

OpenGLInstance2.AssignModel(*MyModel2);

I get:

// per vertex attributes 
layout (location = 12) in vec3  position;
layout (location = 13) in vec3  normals;
layout (location = 14) in uvec4 BoneIDs;
layout (location = 15) in vec4  Weights;

// per instance attributes
layout (location = 16) in mat4  CameraMatrix;           //dynamic
layout (location = 20) in mat4  ProjectionMatrix;       //dynamic

But since the GL_MAX_VERTEX_ATTRIBS gives a maximum number of attributes of 16, this is not possible.

Question 1

Each VAO (vertex array object) has some VBO (vertex buffer object) assigned. Is the location indexing of the VBO just in the scope of each VAO (starting again from zero for each VAO) or is it independent of the VAO?

Question 2

Do you have a suggestion how to work around this problem while keeping the implementation as generic, reusable and scalable as possible? (Just some general hints, I don't want to bother you with details.)

$\endgroup$
1
  • $\begingroup$ I would suggest using uniforms for most of these parameters, such as transformation matrices. You can use uniform buffers to quickly switch uniforms when rendering. Also, the vao just stores the attribute bindings and not the vbo itself. $\endgroup$
    – vgs
    Commented Nov 1, 2016 at 15:04

1 Answer 1

3
$\begingroup$

Each VAO, and shader for that matter, has a separate space of attribute locations. It's perfectly fine to have multiple shaders use the same attribute locations. Indeed, it's a good idea to do so if those attributes conceptually mean the same thing to both shaders.

A VAO can be used with a shader if that VAO's attribute locations match those the program expects. Well, technically they don't have to match. It's OK if the VAO provides an attribute that a shader doesn't use. It's more complicated if a VAO doesn't provide an attribute for a location that the shader expects.

So whatever it is that generates your shader prefix strings and VAOs should not be based on what has been generated for other shaders/VAOs. So if you're going to have attributes increase numerically starting from 0, then this should be the case for each independent shader. It should not be based on some constantly increasing global.

$\endgroup$
2
  • $\begingroup$ Thanks! And you are right, the OpenGL-Class has a static member static GLuint NumberAddedAttributes which is increased every time an attribute is added. And if each VAO really has its own attribute space, this would mean that i only have to make this member non-static and everything should work. But when i tried this yesterday, i ran into some problems. But now since I read your answer I'll check it again. $\endgroup$ Commented Nov 2, 2016 at 9:41
  • $\begingroup$ I would like to extent the question to SSBO (shader storage buffer object): I also use them and create the shader preamble automatically. I guess in case of SSBO binding points the counter has to be global for all shader? $\endgroup$ Commented Nov 2, 2016 at 10:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.