I am trying to send a single unsigned int to vbo, but when I test its value in the vertex shader (which should be 1), the value is different from the one expected.
The variable that contains my unsigned ints is textureIds
The code that load the vbo :
std::vector<unsigned int> textureIds;
glGenBuffers(1, &vboID_m);
glBindBuffer(GL_ARRAY_BUFFER, vboID_m);
{
glBufferData(GL_ARRAY_BUFFER,
(vertices.size() + texture.size() + normals.size())
* sizeof(float) + textureIds.size() * sizeof(unsigned int), 0,
GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size() * sizeof(float),
vertices.data());
glBufferSubData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float),
texture.size() * sizeof(float), texture.data());
glBufferSubData(GL_ARRAY_BUFFER,
(vertices.size() + texture.size()) * sizeof(float),
normals.size() * sizeof(float), normals.data());
glBufferSubData(GL_ARRAY_BUFFER,
(vertices.size() + texture.size() + normals.size()) * sizeof(float),
textureIds.size() * sizeof(unsigned int), textureIds.data());
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
The code that draw the vbo:
void Chunck::draw() const {
glBindBuffer(GL_ARRAY_BUFFER, vboID_m);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float),
BUFFER_OFFSET(0));
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float),
BUFFER_OFFSET(verticeSize_m * sizeof(float)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float),
BUFFER_OFFSET(
(verticeSize_m + textureSize_m) * sizeof(float)));
glEnableVertexAttribArray(2);
glVertexAttribPointer(3, 1, GL_UNSIGNED_INT, GL_FALSE, sizeof(unsigned int),
BUFFER_OFFSET(
(verticeSize_m + textureSize_m + normalSize_m) * sizeof(float)));
glEnableVertexAttribArray(3);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, grassTexture_m.getID());
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, dirtTexture_m.getID());
glDrawArrays(GL_TRIANGLES, 0, verticeSize_m / 3);
glBindTexture(GL_TEXTURE_2D, 0);
glDisableVertexAttribArray(2);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
The vertex shader:
#version 330 core
in vec3 in_Vertex;
in vec2 in_TexCoord0;
in vec3 in_normal;
in int in_textureId;
uniform mat4 projection;
uniform mat4 model;
uniform mat4 view;
out vec2 coordTexture;
out vec3 normal;
out vec3 FragPos;
out vec3 rayDir;
out float grassAmount;
out float dirtAmount;
void main()
{
vec4 pos = model * vec4(in_Vertex, 1.0);
vec2 mu = vec2(0., 0.);
//pos.y = max(pos.y, 10 * exp(-((pos.x - mu.x) * (pos.x - mu.x) + (pos.z - mu.y) * (pos.z - mu.y)) / 100.));
gl_Position = projection * view * pos;
FragPos = vec3(pos);
coordTexture = in_TexCoord0;
normal = in_normal;
rayDir = (view * model * vec4(FragPos, 1.)).xyz;
grassAmount = 0;
dirtAmount = 0;
if (in_textureId == 0)
grassAmount = 1;
else if (in_textureId == 1)
dirtAmount = 1;
}
I should enter into the second if, but it doesn't :\
You have to use glVertexAttribIPointer (focus on I), when defining the array of generic vertex attribute data, for the vertex attribute in int in_textureId;.
Vertex attribute data defined by glVertexAttribPointer will be converted to floating point.
See OpenGL 4.6 API Core Profile Specification; 10.2. CURRENT VERTEX ATTRIBUTE VALUES; page 344
The VertexAttribI* commands specify signed or unsigned fixed-point values
that are stored as signed or unsigned integers, respectively. Such values are referred to as pure integers.
...
All other VertexAttrib* commands specify values that are converted directly to the internal floating-point representation.
Note, you should use either Layout Qualifier to specify the attribute index in the vertex shader:
layout(location = 0) in vec3 in_Vertex;
layout(location = 1) in vec2 in_TexCoord0;
layout(location = 2) in vec3 in_normal;
layout(location = 3) in int in_textureId;
or you should ask for the attribute index by glGetAttribLocation aftet the program has been linked:
e.g.:
GLuint progObj = ...;
glLinkProgram( progObj );
GLint texIdInx = glGetAttribLocation( progObj, "in_textureId" );
glVertexAttribIPointer(
texIdInx, 1, GL_UNSIGNED_INT, GL_FALSE, sizeof(unsigned int),
BUFFER_OFFSET((verticeSize_m + textureSize_m + normalSize_m) * sizeof(float)));
glEnableVertexAttribArray(texIdInx );
Edit:
Of course, glBindAttribLocation is a proper solution too.
Related
I have this tesselation evaluation shader:
\\ vertex
#version 410 core
#define SIZE 6
layout (location = 0) in vec2 x;
layout (location = 1) in vec2 h;
layout (location = 2) in float f[SIZE];
out TC_DATA
{
vec2 x;
vec2 h;
float f[SIZE];
} tc_out;
void main()
{
tc_out.x = x;
tc_out.h = h;
tc_out.f = f;
}
\\ tess control
#version 410
layout (vertices = 1) out;
#define SIZE 6
uniform int outer0;
uniform int outer1;
uniform int outer2;
uniform int inner;
in TC_DATA
{
vec2 x;
vec2 h;
float f[SIZE];
} tc_in[];
out TE_DATA
{
vec2 x;
vec2 h;
float f[SIZE];
} te_out[];
void main()
{
if (gl_InvocationID == 0)
{
gl_TessLevelInner[0] = inner;
gl_TessLevelOuter[0] = outer0;
gl_TessLevelOuter[1] = outer1;
gl_TessLevelOuter[2] = outer2;
}
te_out[gl_InvocationID].x = tc_in[gl_InvocationID].x;
te_out[gl_InvocationID].h = tc_in[gl_InvocationID].h;
// te_out[gl_InvocationID].f = tc_in[gl_InvocationID].f; // <---- uncommenting this line crashes the app
}
\\ tess evaluation
#version 410
layout (triangles) in;
out vec4 fColor;
void main()
{
gl_Position = vec4(1.0);
fColor = vec4(1.0);
}
\\ fragment
#version 410 core
in vec4 fColor;
out vec4 oColor;
void main()
{
oColor = fColor;
}
The vertex specification:
struct Vertex
{
glm::vec2 x;
glm::vec2 h;
std::array<float, 6> f;
};
std::vector<Vertex> vertices;
// ....
glGenVertexArrays(1, &vertex_array);
glBindVertexArray(vertex_array);
glGenBuffers(1, &vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, x));
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, h));
glVertexAttribPointer(2, 6, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, f));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
The render part:
glPatchParameteri(GL_PATCH_VERTICES, 1);
glBindVertexArray(vertex_array);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(decltype(vertices)::value_type), vertices.data(), GL_DYNAMIC_DRAW);
glDrawArrays(GL_PATCHES, 0, vertices.size());
I am trying to pass an array float f[6] and I crash my app if I don't comment the line indicated in the tesselation control shader. I don't understand what I'm doing wrong. I know for sure it is not the c++ part of the code. There are no errors when compiling the shaders or linking the program (opengl program).
The size argument of glVertexAttribPointer must be 1, 2, 3 or 4. Passing 6 to the size argument generates a GL_INVALID_VALUE error.
If the type of the vertex shader attribute is an array, each element of the array has a separate attribute index. The attribute layout (location = 2) in float f[SIZE]; has the attribute indices from 2 to 7:
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE,
sizeof(Vertex), (void*)offsetof(Vertex, f));
glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE,
sizeof(Vertex), (void*)(offsetof(Vertex, f) + 4));
glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE,
sizeof(Vertex), (void*)(offsetof(Vertex, f) + 8));
// [...]
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(4);
// [...]
My model looks stretched because of corrupted data in vertex shader attribute location
Here's the vertex shader code:
#version 330 core
layout (location = 0) in vec3 vertPos;
layout (location = 1) in vec3 vertNormal;
layout (location = 2) in vec2 texCoord;
layout (location = 3) in vec4 boneWeigths;
layout (location = 4) in ivec4 boneIDs;
out vec3 vNormal;
out vec3 fragPos;
out vec2 fragTexCoord;
const int MAX_BONES = 100;
uniform mat4 MVP;
uniform mat4 M;
uniform mat4 boneTransforms[MAX_BONES];
void main()
{
mat4 boneTx = boneTransforms[boneIDs[0]] * boneWeigths[0]
+ boneTransforms[boneIDs[1]] * boneWeigths[1]
+ boneTransforms[boneIDs[2]] * boneWeigths[2]
+ boneTransforms[boneIDs[3]] * boneWeigths[3];
vec4 pos = boneTx * vec4(vertPos, 1.0f);
gl_Position = MVP * pos;
vec4 normal = boneTx * vec4(vertNormal, 0.0f);
vNormal = normalize(vec3(M * normal));
fragPos = vec3(M * pos);
fragTexCoord = vec2(texCoord.x, texCoord.y);
}
The problem seems to be corrupted data in boneIDs (boneIDs data is fine on CPU, but getting corrupted data in shader). I tried hard-coding boneIDs data in shader, and that works fine.
Here's the code for VAO:
// create buffers/arrays
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
// load data into vertex buffers
glBindBuffer(GL_ARRAY_BUFFER, VBO);
unsigned int sz = sizeof(BoneVertex);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(BoneVertex), &vertices[0], GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
// set the vertex attribute pointers
// vertex Positions
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(BoneVertex), (void*)0);
// vertex normals
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(BoneVertex), (void*)(3 * sizeof(float)));
// vertex texture coords
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(BoneVertex), (void*)(6 * sizeof(float)));
// bone weights
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(BoneVertex), (void*)(8 * sizeof(float)));
// bone ids
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 4, GL_INT, GL_FALSE, sizeof(BoneVertex), (void*)(12 * sizeof(float)));
glBindVertexArray(0);
BoneVertex structure:
struct BoneVertex
{
glm::vec3 position;
glm::vec3 normal;
glm::vec2 textureCoords;
glm::vec4 boneWeights;
glm::ivec4 boneIDs;
}
This is weird, because the first 3 attributes data seems fine. The problem is with boneIDs and boneWeights
Is this somehow related to padding, and how data is arranged in a structure? Or am I missing something else?
Thanks
boneIDs is a vertex shader input with an integral data type:
layout (location = 4) in ivec4 boneIDs;
If you want to specify the generic vertex attribute data for an integral attribute, then you have to use glVertexAttribIPointer (focus on I) rather than glVertexAttribPointer (see glVertexAttribPointer).
Note, the type argument doesn't specify the type of the target attribute, it specifies the element type of the source data array. glVertexAttribPointer converts the source data array to floating point values, but glVertexAttribIPointer specifies the array for integral target attributes.
glVertexAttribPointer(4, 4, GL_INT, GL_FALSE, sizeof(BoneVertex), (void*)(12 * sizeof(float)));
glVertexAttribIPointer(4, 4, GL_INT, sizeof(BoneVertex), (void*)(12 * sizeof(float)));
I am trying to draw a grid of velocity vectors, I expect the velocity at each grid point to be a line with a slop of 1. A slanting line, but I always end up with a vertical line. I'm not sure what I'm doing wrong. Is there something I'm overlooking?
Here is how my vertex buffer looks :
float vel_pos[6*(N+2)*(N+2)];
int index1 = 0;
for (int i=0;i<N+2;i++)
{
for (int j=0;j<N+2;j++)
{
vel_pos[index1] = float(i);
vel_pos[index1+1] = float(j);
vel_pos[index1+2] = 0.0f;
vel_pos[index1+3] = float(i) +0.5f;
vel_pos[index1+4] = float(j) + 0.5f;
vel_pos[index1+5] = 0.0f;
index1 += 6;
}
}
Here is how I am creating my VBO and VAO :
unsigned int VBO, VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
// Bind vertex array object first and then bind the vertex buffer objects
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vel_pos), vel_pos, GL_STREAM_DRAW);
GLint velAttrib = glGetAttribLocation(ourShader.ID, "aPos");
// iterpreting data from buffer
glVertexAttribPointer(velAttrib, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
Here is my vertex shader :
out vec4 vertexColor;
layout (location = 0) in vec3 aPos;
layout (location = 1) in float densitySource; /* source of density */
uniform mat4 transform;
uniform mat4 projection;
void main()
{
gl_Position = projection*transform * vec4(aPos, 1.0);
vertexColor = vec4(1, 0.0, 0.0, 1.0);
}
And here's my drawing code :
ourShader.use();
glm::mat4 trans = glm::mat4(1.0f);
trans = glm::translate(trans, glm::vec3(-0.5f, -0.5f, 0.0f));
unsigned int transformMatrixLocation = glGetUniformLocation(ourShader.ID, "transform");
glUniformMatrix4fv(transformMatrixLocation, 1, GL_FALSE, glm::value_ptr(trans));
glm::mat4 projection = glm::ortho(-10.0f, 110.0f, -1.0f, 110.0f, -1.0f, 100.0f);
unsigned int projectionMatrixLocation = glGetUniformLocation(ourShader.ID, "projection");
glUniformMatrix4fv(projectionMatrixLocation, 1, GL_FALSE, glm::value_ptr(projection));
glBindVertexArray(VAO);
glLineWidth(1.0f);
glDrawArrays(GL_LINES, 0, (N+2)*(N+2));
This is the image I get :
resulting image
The 5th parameter (stride) of glVertexAttribPointer is the offset between two vertex coordinates and not between to primitives. Since your vertex coordinates have 3 components of type float, the offset has to be 3 * sizeof(float):
glVertexAttribPointer(velAttrib, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
Because you set an offset of 6 * sizeof(float), you have skipped every 2 coordinate and have drawn lines between the points of the grid.
But note, if stride is 0, the generic vertex attributes are understood to be tightly packed in the array. This is the case, so you ca use an offset of 0:
glVertexAttribPointer(velAttrib, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
I've got some problem with sending data to my vertex shader :
#version 450 core
layout (location = 5) in vec3 in_Vertex;
layout (location = 6) in vec3 in_Color;
in int gl_InstanceID;
layout (location = 0) uniform mat4 projection;
layout (location = 1) uniform mat4 modelview;
layout (location = 2) uniform float posX;
layout (location = 3) uniform float posY;
layout (location = 4) uniform uint posZ;
out vec4 v_color;
void main()
{
float tmpX = posX;
float tmpY = posY;
uint tmpZ = posZ;
gl_Position = projection * modelview * vec4(in_Vertex.x + tmpX*2, in_Vertex.y + tmpY*2, in_Vertex.z + tmpZ, 1.0) + vec4(in_Color, 0.0);
v_color = vec4(in_Color,1.0);
}
The in_Vertex is working fine but the in_Color seems to have bad values, I send the data as :
glUseProgram(m_shaderPerso.getID());
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glEnableVertexAttribArray(5);
glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(m_offsetColor));
glEnableVertexAttribArray(6);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);
glUniformMatrix4fv(0, 1, GL_FALSE, glm::value_ptr(projection));
glUniformMatrix4fv(1, 1, GL_FALSE, glm::value_ptr(modelview));
for( auto &x : m_mapPos)
{
glUniform1f(2, x.second.getX());
glUniform1f(3, x.second.getY());
glUniform1ui(4, s_map->getHauteur(x.second.getXint(),x.second.getYint()));
glDrawElements(GL_TRIANGLES, m_tailleI, GL_UNSIGNED_BYTE, 0);
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(6);
glDisableVertexAttribArray(5);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glUseProgram(m_shaderPerso.getID());
And I initialize the VBO with :
glGenBuffers(1, &m_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo); //Verrouillage VBO
glBufferData(GL_ARRAY_BUFFER, (tailleV * sizeof(float)) + (m_tailleI*3 * sizeof(float)), 0, GL_STATIC_DRAW); //Allocation memoire
glBufferSubData(GL_ARRAY_BUFFER, 0, tailleV * sizeof(float), m_vertices); //Transfert données vertices
glBufferSubData(GL_ARRAY_BUFFER, tailleV * sizeof(float), m_tailleI*3 * sizeof(float), m_color); //Transfert données couleurs
glBindBuffer(GL_ARRAY_BUFFER, 0);
glGenBuffers(1, &m_ibo); //Generation IBO (indices)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo); //Verrouillage IBO
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_tailleI * sizeof(GLubyte), 0, GL_STATIC_DRAW); //Allocation memoire
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, m_tailleI * sizeof(GLubyte), m_indices); //Transfert données
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
I really don't know where my mistake is, so I gave you all the code that could be usefull. I do know that the arrays m_vertices, m_color and m_indices are correctly initialized, and the vertices are correctly display, so the VBO for the vertices and the indices are good in the VRAM. I probably done a mistake when I sended the data but I can't find it for 2 days, and I think that a new look could help me.
Thanks for reading and probably helping :)
Besides what #HolyBlackCat said, you are mixing interleaved mode with batch mode. When your are filling your buffer, you are using batch mode:
glBindBuffer(GL_ARRAY_BUFFER, m_vbo); //Verrouillage VBO
glBufferData(GL_ARRAY_BUFFER, (tailleV * sizeof(float)) + (m_tailleI*3 * sizeof(float)), 0, GL_STATIC_DRAW); //Allocation memoire
glBufferSubData(GL_ARRAY_BUFFER, 0, tailleV * sizeof(float), m_vertices); //Transfert données vertices
glBufferSubData(GL_ARRAY_BUFFER, tailleV * sizeof(float), m_tailleI*3 * sizeof(float), m_color); //Transfert données couleurs
First you fill with vertices points, and, at the end of the buffer, with color attributes.
But when you are using the buffer, you are using it in interleaved mode*:
glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(m_offsetColor));
Choose one and stick with it.
*in glVertexAttribPointer function, stride can have an incorrect value.
Probably, you can solve your problem by changing:
glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(m_offsetColor))
to:
glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), BUFFER_OFFSET(tailleV * sizeof(float)))
I've uploaded vertices, colors, normals, and texture coordinates into a single VBO, which is associated with a VAO. I also have an EBO associated with the same VAO that stores indices. I am also using SDL and OpenGL 3.3 (Core Profile context, which is set using SDL).
At first, my model seems to render fine. Then after maybe 8 or so seconds, it looks like the data gets corrupted.
Here is a video: https://youtu.be/eEiH3EFTPFk
Every frame I am pulling the data out of OpenGL (using glGetNamedBufferSubData) and comparing to what it should be, and everything seems to check out.
Does anyone have any idea what might be happening here? I appreciate any insight you guys might be able to provide.
Here is my code for loading the model data:
struct Vbo
{
GLuint id;
};
struct Ebo
{
GLuint id;
GLenum mode;
GLsizei count;
GLenum type;
};
struct Vao
{
GLuint id;
Vbo vbo[4];
Ebo ebo;
};
// ...
MeshId GraphicsEngine::createStaticMesh(
std::vector<glm::vec3> vertices,
std::vector<glm::detail::uint32> indices,
std::vector<glm::vec4> colors,
std::vector<glm::vec3> normals,
std::vector<glm::vec2> textureCoordinates
)
{
Vao vao;
glGenVertexArrays(1, &vao.id);
glGenBuffers(1, &vao.vbo[0].id);
glGenBuffers(1, &vao.ebo.id);
auto size = vertices.size() * sizeof(glm::vec3);
size += colors.size() * sizeof(glm::vec4);
size += normals.size() * sizeof(glm::vec3);
size += textureCoordinates.size() * sizeof(glm::vec2);
glBindVertexArray(vao.id);
glBindBuffer(GL_ARRAY_BUFFER, vao.vbo[0].id);
glBufferData(GL_ARRAY_BUFFER, size, nullptr, GL_STATIC_DRAW);
auto offset = 0;
glBufferSubData(GL_ARRAY_BUFFER, offset, vertices.size() * sizeof(glm::vec3), &vertices[0]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
offset += vertices.size() * sizeof(glm::vec3);
glBufferSubData(GL_ARRAY_BUFFER, offset, colors.size() * sizeof(glm::vec4), &colors[0]);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(offset));
glEnableVertexAttribArray(1);
offset += colors.size() * sizeof(glm::vec4);
glBufferSubData(GL_ARRAY_BUFFER, offset, normals.size() * sizeof(glm::vec3), &normals[0]);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(offset));
glEnableVertexAttribArray(2);
offset += normals.size() * sizeof(glm::vec3);
glBufferSubData(GL_ARRAY_BUFFER, offset, textureCoordinates.size() * sizeof(glm::vec2), &textureCoordinates[0]);
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(offset));
glEnableVertexAttribArray(3);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vao.ebo.id);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(glm::detail::uint32), &indices[0], GL_STATIC_DRAW);
glBindVertexArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
vao.ebo.count = indices.size();
vao.ebo.mode = GL_TRIANGLES;
vao.ebo.type = GL_UNSIGNED_INT;
vertexArrayObjects_.push_back(vao);
auto index = vertexArrayObjects_.size() - 1;
return MeshId(index);
}
Here is my code that does the rendering:
// Setup camera
const glm::quat temp = glm::conjugate(camera_.orientation);
view_ = glm::mat4_cast(temp);
view_ = glm::translate(view_, glm::vec3(-camera_.position.x, -camera_.position.y, -camera_.position.z));
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shaderProgram_);
const int modelMatrixLocation = glGetUniformLocation(shaderProgram_, "modelMatrix");
const int pvmMatrixLocation = glGetUniformLocation(shaderProgram_, "pvmMatrix");
const int normalMatrixLocation = glGetUniformLocation(shaderProgram_, "normalMatrix");
glm::detail::uint32 i = 0;
for ( const auto& r : renderables_ )
{
const auto& graphicsData = graphicsData_[i];
glm::mat4 newModel = glm::translate(model_, graphicsData.position);
newModel = newModel * glm::mat4_cast( graphicsData.orientation );
newModel = glm::scale(newModel, graphicsData.scale);
// Send uniform variable values to the shader
const glm::mat4 pvmMatrix(projection_ * view_ * newModel);
glUniformMatrix4fv(pvmMatrixLocation, 1, GL_FALSE, &pvmMatrix[0][0]);
glm::mat3 normalMatrix = glm::inverse(glm::transpose(glm::mat3(view_ * newModel)));
glUniformMatrix3fv(normalMatrixLocation, 1, GL_FALSE, &normalMatrix[0][0]);
glUniformMatrix4fv(modelMatrixLocation, 1, GL_FALSE, &newModel[0][0]);
glBindTexture(GL_TEXTURE_2D, r.texture.id);
glBindVertexArray(r.vao.id);
glDrawElements(r.vao.ebo.mode, r.vao.ebo.count, r.vao.ebo.type, 0);
glBindVertexArray(0);
i++;
}
Fragment shader:
#version 330 core
in vec4 ourColor;
in vec2 texCoord;
out vec4 color;
uniform sampler2D ourTexture;
void main()
{
color = texture(ourTexture, texCoord);
}
Vertex shader:
#version 330 core
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
uniform mat4 pvmMatrix;
uniform mat3 normalMatrix;
layout (location = 0) in vec3 position;
layout (location = 1) in vec4 color;
layout (location = 2) in vec3 normal;
layout (location = 3) in vec2 textureCoordinate;
out vec4 ourColor;
out vec2 texCoord;
void main()
{
//gl_Position = vec4(position, 1.0);
gl_Position = pvmMatrix * vec4(position, 1.0);
ourColor = color;
texCoord = textureCoordinate;
}
As per #MichaelNastenkos comment about, I added glEnable(GL_DEPTH_TEST); before my rendering code and it seems to fix it.