I'm trying to pass a structure to a simple GLSL vetrex shader. Here's how the structure look like on the C++ side:
struct Vertex
{
float position[3];
char boneIndex[4];
float weights[4];
float normals[3];
float textureCords[2];
};
Is it possible to pass array of this vertex to the vertex shader without creating a separate array for each component?
Can I do something like this:
#version 330 core
uniform mat4 MVP;
layout(location = 0) in struct Vertex
{
vec3 position;
uint boneIndex;
vec4 weights;
vec3 normals;
vec2 textureCords;
} vertex;
out vec2 UV;
void main()
{
gl_Position = MVP * vec4(vertex.position, 1.0f);
UV = vertex.textureCords;
}
(Dont mind that not all of the components are in use, it's just for the example.)
And if I can, how can I pass the data to it from the C++ side using the glVertexAttribPointer() function? (According to my understanding you can pass only 1,2,3,4 to the size parameter).
Is it the even the right way to do things? I'm a beginner in OpenGL programming so if you have an answer please don't hesitate to include obvious details.
Edit:
I ended up doing something like this:
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(4);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); //float position[3]
glVertexAttribPointer(1, 1, GL_INT, GL_FALSE, 12, (void*)0); //char boneIndex[4]
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 16, (void*)0); //float weights[4]
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 32, (void*)0); //float normals[3]
glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, 44, (void*)0); //float textureCords[2]
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indiceBuffer);
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, (void*)0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glDisableVertexAttribArray(3);
glDisableVertexAttribArray(4);
On the C++ size, and on the GLSL vertex shader:
#version 330 core
uniform mat4 MVP;
layout(location = 0) in vec3 position;
layout(location = 1) in int boneIndex;
layout(location = 2) in vec4 weight;
layout(location = 3) in vec3 normal;
layout(location = 4) in vec2 UVCords;
out vec2 UV;
void main()
{
gl_Position = MVP * vec4(position, 1.0f);
UV = UVCords;
}
But it still won't work, the model wont render correctly
vec4or smaller uses a single attribute location, things likemat4use 4 locations (it might help to think of them as an array of 4vec4s). So assigning withglVertexAttribPointer (...)should be pretty straight forward.glVertexAttribIPointer (...)because it is an integer field whereas all of your other vertex data are floating-point.n, first will have offset0and stride2n, and the second offsetnand the very same stride. Once you get that it'll be easy to do it for more than 2 attributes.