Cant draw multiple objects in opengl - c++

I cant work out why the following code doesn't work, I am attempting to draw 2 shapes, a triangle that is coloured red and a cube that is multi coloured, by themselves they draw perfectly but if I try to draw both at once it gives weird bugs, I have tried changing lines around changing variable's modifying my shaders and I cant seem to get anywhere near the result I want, the current code ends up drawing 2 identical triangles that use the cubes colours.
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
GLuint MatrixID = glGetUniformLocation(shader->id(), "MVP");
glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
glm::mat4 View = glm::lookAt(
glm::vec3(4,2,2), // Camera location
glm::vec3(0,0,0), // and looks at the origin
glm::vec3(0,1,0) // Head is up (set to 0,-1,0 to look upside-down)
);
glm::mat4 myMatrix = glm::translate(-2.f,0.f,0.f);
glm::mat4 Model = glm::mat4(1.f);
Model= myMatrix * Model;
glm::mat4 MVP = Projection * View * Model;
glm::mat4 myMatrix2 = glm::translate(2.f,0.f,0.f);
glm::mat4 Model2 = glm::mat4(1.f);
Model2= myMatrix2 * Model2;
glm::mat4 MVP2 = Projection * View * Model2;
glViewport(0, 0, windowWidth, windowHeight); // set viewport to the size of the window
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
shader->bind();
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, colourBuffer);
glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,0,(void*)0);
glDrawArrays(GL_TRIANGLES,0,12*3);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP2[0][0]);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer2);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, colourBuffer2);
glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,0,(void*)0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
SwapBuffers(hdc);
glDeleteBuffers(1, &vertexBuffer);
glDeleteBuffers(1, &vertexBuffer2);
glDeleteBuffers(1, &colourBuffer);
glDeleteBuffers(1, &colourBuffer2);
shader->unbind();
glDeleteVertexArrays(1, &VertexArrayID);
that's the main code. I create all the buffers in a similar way by basically using variations of the following 3 lines to insert the different buffer names and data,
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER,sizeof(Cube), Cube, GL_STATIC_DRAW);
fragment shader
#version 330 core
in vec3 fragmentColour;
out vec3 colour;
void main(){
colour = fragmentColour;
}
vertex shader
#version 330 core
uniform mat4 MVP;
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec3 vertexColour;
out vec3 fragmentColour;
void main(){
gl_Position = MVP * vec4(vertexPosition_modelspace,1);
fragmentColour = vertexColour;
}

I see you are trying to use VAOs but you create only one.Also why do you prepare:
glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER,
vertexBuffer);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0);
glEnableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER,
colourBuffer);
glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,0,(void*)0);
and delete:
glDeleteBuffers(1, &vertexBuffer); glDeleteBuffers(1, &vertexBuffer2);
glDeleteBuffers(1, &colourBuffer); glDeleteBuffers(1, &colourBuffer2);
your VAOs on each render call?The whole purpose of VAOs is to init all the needed buffers and attributes once and then bind only the VAO itself for the actual rendering.Do it on the initialization setup and delete only when you don't need those objects anymore.Here is a good example how it is done properly .
What you should do is this:
Initiate your VAOs in some init method only once.Then in render loop :
glBindVertexArray(m_VAO1);
///draw geometry here
glBindVertexArray(0);
Do this for each geometry you want to render.
After deeper review of your code I see you do this :
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
So you do bind VAO.But you create and bind only one!You need to create one per renderable object,Attach to it all required buffers and then use them in the render loop as I explained above.

Related

Rendering a model in openGL

I'm trying to render this model in openGL:
model in image viewer
this is my attempt so far:
model rendered by my code
I only gave it the verticies so far, no normals or faces. I'm wondering why it doesn't look full like the first one. Is it because of lack of normals? I'm pretty sure I got the number of verticies/triangles right but I'm not sure if I've made mistakes. What is the next step to fully render the model like the first image?
buffer creation:
//Vertex buffer
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
//color buffer
GLuint colorbuffer;
glGenBuffers(1, &colorbuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data), g_color_buffer_data, GL_STATIC_DRAW);
//create shaders and attach them to a program object
GLuint program = rigShadersToProgram();
GLuint matrixID = glGetUniformLocation(program, "MVP");
rendering loop:
// Rendering loop
while (!glfwWindowShouldClose(window))
{
//clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
////////////////////////////matrix operations/////////////////////////////////////////
//projection matrix 45 degree FoV, 4:3 ratio, display range 0.1 - 100
glm::mat4 projection = glm::perspective(99.0f, 4.0f/3.0f, 0.1f, 100.0f);
//camera matrix
glm::mat4 view = glm::lookAt(
glm::vec3(2, 1, -1), //camera is at (2,1,-1)
glm::vec3(0, 0 , 0), //looks at origin
glm::vec3(0,1, 0) //head is up
);
//model matrix identity matrix
glm::mat4 model = glm::mat4(1.0f);
//rotate
model = glm::rotate(model, e, glm::vec3(1,2,3));
//model-view-projection
glm::mat4 MVP = projection * view * model;
//////////////////////////////////////////////////////////////////////////////////////
//use the compiled shaders
glUseProgram(program);
//send transformation matrix to currently bound shader
glUniformMatrix4fv(matrixID, 1, GL_FALSE, &MVP[0][0]);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
//vertex buffer
glVertexAttribPointer(
0, //index
3, //size
GL_FLOAT, //type
GL_FALSE, //normalized?
0, //stride
0 //array buffer offset
);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
//color buffer
glVertexAttribPointer(
1, //index
3, //size
GL_FLOAT, //type
GL_FALSE, //normalized?
0, //stride
0 //array buffer offset
);
//draw triangle
glDrawArrays(GL_TRIANGLES, 0, 12722*3);
std::cout << glfwGetTime() << "\n";
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glfwSwapBuffers(window);
glfwPollEvents();
the model data is stored in an array:
static const GLfloat g_vertex_buffer_data[] = {
-1.557376f, 0.094970f, 0.171995f,
-1.565967f, 0.098142f, 0.171995f,
-1.557376f, 0.094970f, -0.048469f,
-1.565967f, 0.098142f, -0.048469f,
-1.532660f, 0.162907f, -0.048469f,
-1.541251f, 0.166079f, -0.048469f,
-1.444236f, 0.405840f, 0.171996f,
-1.452827f, 0.409013f, 0.171996f,
-1.463533f, 0.352575f, 0.171995f,
-1.472257f, 0.355747f, 0.171995f,
-1.528166f, 0.175331f, 0.011009f,
-1.536757f, 0.178371f, 0.011009f,
-1.538475f, 0.146781f, 0.025019f, ... etc
vertex shader:
#version 430 core
layout(location =0) in vec3 vpos;
layout(location =1) in vec3 vertexColor;
out vec3 fragmentColor;
uniform mat4 MVP;
void main(void)
{
//output position of the vertex in clip space MVP*position
gl_Position = MVP * vec4(vpos,1);
fragmentColor = vertexColor;
};
fragment shader:
#version 430 core
in vec3 fragmentColor;
out vec3 color;
void main()
{
color = fragmentColor;
};
You don't show the actual model loading or rendering code. But what's clear from the screenshot of your program is, that your vertex indexing order is totally messed up. There are vertices connected with each other in your program's drawing that definitely are not connected in the model. Time to recheck the model loader code.
BTW: why did you hardcode the number of vertices to draw in the glDrawArrays call? That doesn't make sense at all.

C++ openGL static window with VBOs and shaders

So I've been building a pretty simple piece of code that renders .OBJ files and lets the user look around using VBOs and the most simple GLSL shaders immaginable, but when run the window is just a static image (looks like the object seen from 0,0,0). Without the shader program it still renders normally, just without color. Any idea what I colud be doing wrong?
VBO & shader stuff:
//Create buffer for vertex data (x,y,z)
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(vector3f), &vertices[0], GL_STATIC_DRAW);
//Create buffer for color data (r,g,b)
glGenBuffers(1, &colorBuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glBufferData(GL_ARRAY_BUFFER, temp.size() * sizeof(vector3f), &temp[0], GL_STATIC_DRAW);
//Create and compile shaders
GLuint vertShader = 0, fragShader = 0, program = 0;
createShader("vertex.glsl", GL_VERTEX_SHADER, vertShader);
createShader("fragment.glsl", GL_FRAGMENT_SHADER, fragShader);
program = glCreateProgram();
glAttachShader(program, vertShader);
glAttachShader(program, fragShader);
glBindAttribLocation(program, vertexAttribIndex, "vertex_position");
glBindAttribLocation(program, colorAttribIndex, "vertex_colour");
glLinkProgram(program);
printShaderInfoLog(vertShader);
printProgramInfoLog(program);
//Set attribute pointers for GLSL
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(vertexAttribIndex, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(vertexAttribIndex);
glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glVertexAttribPointer(colorAttribIndex, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(colorAttribIndex);
Render loop:
while (!glfwWindowShouldClose(window)) {
glClearColor(0.0F, 0.0F, 0.0F, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glUseProgram(program);
glViewport(0, 0, width, height);
gluPerspective(70.0, width / height, 1.0, 30.0);
glMatrixMode(GL_MODELVIEW);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glDrawArrays(GL_TRIANGLES, 0, vertBufferSize);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glfwSwapBuffers(window);
glfwPollEvents();
}
Vertex shader:
#version 420
layout(location = 0) in vec3 vertex_position;
layout(location = 1) in vec3 vertex_colour;
out vec3 colour;
out vec4 gl_Position;
void main () {
colour = vertex_colour;
gl_Position = vec4 (vertex_position, 1.0);
}
Fragment shader:
#version 420
in vec3 colour;
out vec4 colorOut;
void main () {
colorOut = vec4(colour, 1.0);
}
Sorry if I've missed out anything obvious, I've been fighting this for hours.

Initialize GLSL layout with glEnableVertexAttribArray

I want to pass arrays of vertices, UV's and normals to the shader and transform them using MVP matrix, so I wrote a simple shader program:
#version 330 core
//Vertex shader
layout(location=0)in vec3 vertexPosition_modelspace;
layout(location=1)in vec2 vertexUV;
out vec2 UV;
uniform mat4 MVP;
void main(){
gl_Position = MVP * vec4(vertexPosition_modelspace,1);
UV = vertexUV;
}
#version 330
//Fragment Shader
in vec2 UV;
out vec3 color;
uniform sampler2D color_texture;
void main(void) {
color = texture(color_texture, UV).rgb;
}
Then I needed to pass an array of vertices, which is being initialized like that:
glGenBuffers(1, &vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], model_usage);
Same with UV's and normals, the type is still GL_ARRAY_BUFFER for them.
Then a draw loop:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
for (Model* mdl : baseShader->getModels()) {
glUseProgram(baseShader->getShaderProgram());
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, mdl->getTextureBuffer());
glUniform1i(texture_location, 0);
glm::mat4 mvp = RootEngine->projection_matrix * RootEngine->view_matrix * mdl->getModelMatrix();
glUniformMatrix4fv(baseShader->getMVPlocation(), 1, GL_FALSE, &mvp[0][0]);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, mdl->getVertexBuffer());
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(1); // Matches layout (location = 1)
glBindBuffer(GL_ARRAY_BUFFER, mdl->getUVsBuffer());
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
glDrawArrays(GL_TRIANGLES, 0, mdl->getVertices()->size());
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
}
SDL_GL_SwapWindow(RootEngine->getMainWindow());
BaseShader and Model are my own classes which do a simple initialization and VBO handling.
The problem is nothing actually being rendered. I tried to add glEnableClientState(GL_VERTEX_ARRAY);
and
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
...
glDeleteVertexArrays(1, &VertexArrayID);
But still nothing. When I don't use layout and pass the data with glVertexPointer everything seems to work fine.
UPDATE 1: I found out what prevents vertices from being rendered. It's uniform variable in the VertexShader. If it's being removed the vertices are being rendered, but then there is no way to pass a matrix to the shader.
I've just passed the wrong texture, so the model was colored black and thus invisible. Thanks everybody for your answers.

Multiple objects drawing (OpenGL)

The issue is that I can't figure out how to properly draw two objects, because my another object isn't being drawn.
Here's the main code:
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
GLuint VertexArrayID2;
glGenVertexArrays(1, &VertexArrayID2);
glBindVertexArray(VertexArrayID2);
GLuint programID = LoadShaders( "SimpleVertexShader.vertexshader", "SimpleFragmentShader.fragmentshader" );
GLuint MatrixID = glGetUniformLocation(programID, "MVP");
GLuint MatrixID2 = glGetUniformLocation(programID, "MVP2");
glm::mat4 Projection = glm::perspective(45.0f, 5.0f / 4.0f, 0.1f, 100.0f);
glm::mat4 View = glm::lookAt(
glm::vec3(4*2,3*2,8*2),
glm::vec3(0,0,0),
glm::vec3(0,1,0)
);
glm::mat4 Model = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 0.0f));
glm::mat4 MVP = Projection * View * Model;
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
glm::mat4 Model2 = glm::translate(glm::mat4(1.0f), glm::vec3(-5.0f, 0.0f, 0.0f));
glm::mat4 MVP2 = Projection * View * Model2;
glUniformMatrix4fv(MatrixID2, 1, GL_FALSE, &MVP2[0][0]);
static const GLfloat g_vertex_buffer_data[] = {
-1.0f,-1.0f,-1.0f,
-1.0f,-1.0f, 1.0f,
(plenty of floats)
1.0f,-1.0f, 1.0f
};
static const GLfloat g_vertex_buffer_data2[] = {
-1.0f, -1.0f, 3.0f,
(plenty of floats)
0.0f, 1.0f, 2.0f,
};
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
GLuint vertexbuffer2;
glGenBuffers(1, &vertexbuffer2);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer2);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data2), g_vertex_buffer_data2, GL_STATIC_DRAW);
do{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(programID);
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
glUniformMatrix4fv(MatrixID2, 1, GL_FALSE, &MVP2[0][0]);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0);
glDrawArrays(GL_TRIANGLES, 0, 12*3);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer2);
glVertexAttribPointer(2,3,GL_FLOAT,GL_FALSE,0,(void*)0);
glDrawArrays(GL_TRIANGLES, 0, 4*3);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(2);
glfwSwapBuffers(window);
glfwPollEvents();
}
And shader:
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 2) in vec3 vertexPosition_modelspace2;
uniform mat4 MVP;
uniform mat4 MVP2;
void main(){
gl_Position = MVP * vec4(vertexPosition_modelspace,1);
gl_Position = MVP2 * vec4(vertexPosition_modelspace2,1);
}
I have noticed that only last object is being drawn, so the issue is that 'gl_Position' overwrites it's values, but how should I figure it out?
gl_Position = MVP * vec4(vertexPosition_modelspace,1);
gl_Position = MVP2 * vec4(vertexPosition_modelspace2,1);
That is not how the graphics pipeline work. You can not draw two objects at the same time. Just the last write to gl_Position will be effective, and your first object will be completely ignored. In the most basic variant, you want to draw two completely independent objects, and you will need two draw calls for that - as you do in your code.
However, when doing so, you do not need two different vertex attributes. Your shader just processes vertices, which in your case only have the verexPosition_modelspace attribute. So you can use that attribute for all the objects you want to draw. There is no point in using different attributes for different objects if the attribute means the same thing.
Let's have a look at your drawing code:
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0);
Here, you set up vertex attribute 0 to point to the vertex data of the first buffer, and you enable the attribute array. So the data will not be used as source for vertexPosition_modelspace.
glDrawArrays(GL_TRIANGLES, 0, 12*3);
Now you draw the object. But as we already have seen, your shader does only really use vertexPosition_modelspace2, for which you did not have set an pointer, or enabled the array. Since the array is disabled, the GL will use the current value of attribute 2 - for all vertices. So in the case of triangles, you create triangles with all points being the same - getting triangles with a surface area of 0 and are invisible anyways, no matter what actual value attribute 2 currently has.
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer2);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0);
Now you do a strange thing: you enable attribute 2 array, but do not set a pointer for it! You should re-specify the pointer for attribute 0 to point to your second model.
glDrawArrays(GL_TRIANGLES, 0, 4*3);
Now you draw with both attribute 0 and 2 enabled. Attribute 0 will contain the data you want, but is ignored by the shader. Attribute 2 is just point somewhere, and you get undefined behavior - it might just crash, but It might also display strange stuff, or nothing at all.
To make this work, just remove vertexPosition_modelspace2 completely from the shader. Use just one MVP matrix also.
When drawing any object, you have to:
Set the MVP uniform matrix for the object
Set the attribute pointer for attribute 0
Enable the attribute array for attribute 0 (or make sure it is already enabled)
Issue the draw call
You can do this with as many objects as you want.

Drawing Multiple Models in OpenGL 3.x/4.x

I'm working on a rendering engine and so far it's been coming great, but I can not figure out why when I make two drawing calls to render different models, only 1 will show up.
I'm using wxWidgets to handle the window system, the code in question is pasted below. Any suggestions?
Main Rendering Loop
TestShader.Activate();
glUseProgram(TestShader.Program);
ProjectionMatrix = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
int projectionMatrixLocation = glGetUniformLocation(TestShader.Program, "ProjectionMatrix");
glUniformMatrix4fv(projectionMatrixLocation, 1, GL_FALSE, glm::value_ptr(ProjectionMatrix));
glm::mat4 ViewMatrix = glm::lookAt(
glm::vec3(position),
glm::vec3(position+direction),
glm::vec3(up)
);
int viewMatrixLocation = glGetUniformLocation(TestShader.Program, "ViewMatrix");
glUniformMatrix4fv(viewMatrixLocation, 1, GL_FALSE, glm::value_ptr(ViewMatrix));
TestModel[1].Draw(TestShader, glm::vec3(0,0,-11));
TestModel[0].Draw(TestShader, glm::vec3(0,0,-1));
Refresh(false);
Model Drawing Function
void E_MODEL::Draw(EShader Shader, glm::vec3 Location)
{
if (!Registered) glGenVertexArrays(1, &VAO[0]);
glBindVertexArray(VAO[0]);
if (!Registered) glGenBuffers(1, &VBO[0]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
if (!Registered) glBufferData(GL_ARRAY_BUFFER, Vertices.size() * sizeof(glm::vec3), &Vertices[0], GL_STATIC_DRAW);
if (!Registered) glGenBuffers(1, &VBO[1]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
if (!Registered) glBufferData(GL_ARRAY_BUFFER, Normals.size() * sizeof(glm::vec3), &Normals[0], GL_STATIC_DRAW);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glm::mat4 modelMatrix = glm::translate(glm::mat4(1.0f), Location);
int modelMatrixLocation = glGetUniformLocation(Shader.Program, "modelMatrix");
glUniformMatrix4fv(modelMatrixLocation, 1, GL_FALSE, glm::value_ptr(modelMatrix));
glDrawArrays( GL_TRIANGLES, 0, Vertices.size() );
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
Registered = true;
}
Vertex Shader
#version 330 core
// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec3 vertexColor;
// Output data ; will be interpolated for each fragment.
out vec3 fragmentColor;
// Values that stay constant for the whole mesh.
uniform mat4 ProjectionMatrix;
uniform mat4 ViewMatrix;
uniform mat4 modelMatrix;
void main(){
gl_Position = ProjectionMatrix * ViewMatrix * modelMatrix * vec4(vertexPosition_modelspace,1);
// The color of each vertex will be interpolated
// to produce the color of each fragment
fragmentColor = vertexColor;
}
Fragment Shader
#version 330 core
// Interpolated values from the vertex shaders
in vec3 fragmentColor;
// Ouput data
out vec3 color;
void main(){
// Output color = color specified in the vertex shader,
// interpolated between all 3 surrounding vertices
color = fragmentColor;
}
glClear clears a buffer. With the GL_COLOR_BUFFER_BIT flag, you are clearing the color buffer. With the GL_DEPTH_BUFFER_BIT flag, you are clearing the depth buffer. By doing this each time you draw a model, the color and depth information written previously is cleared. This means you are erasing the image every time you draw a model.
You typically clear the buffers once per "paint" or "present". That is, you clear once, you draw N times, you present once. What you are doing now is clear, draw, clear, draw... present.
TL;DR: Call glClear once, before all of your drawing, not before each draw.
is it the glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); inside the draw function? maybe move that out to before you make the calls the draw functions?