I have an application displaying some 3D rendering.
I encounter some graphical problems with VBO, when integrating my application on different user's laptops. Vertex Buffer Object work perfectly fine in out development stations
First laptop embeds a AMD Radeon HD 6470M -> OpenGL 4.1
On this laptop, I've got some :
old fashion way opengl code, working fine.
vbo implemented : No data of the VBO is displayed
Here the code responsible of the drawing of my VBO :
// Compute this on the client side to attempt compute it for each vertex
Matrix4 modelview = view * model;
// Links matrix values to entry shader matrices for the specified shader
glUniformMatrix4fv(glGetUniformLocation(shaderID, "projection"), 1, GL_TRUE, projection.getValues());
glUniformMatrix4fv(glGetUniformLocation(shaderID, "modelview"), 1, GL_TRUE, modelview.getValues());
GLfloat color[4] = {material_->getDiffuse()[0], material_->getDiffuse()[1], material_->getDiffuse()[2], lgc3d::alphaFromSelection(selected)};
glUniform4fv(glGetUniformLocation(shaderID, "color"), 1, color);
// Get the positions in the shader for data
glEnableVertexAttribArray(VPos_index);
glEnableVertexAttribArray(VNor_index);
glEnableVertexAttribArray(VTex_index);
// Bind the buffers we want access
glBindBuffer(GL_ARRAY_BUFFER, VBO_index_vertices);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBO_index_indices3);
glBindTexture(GL_TEXTURE_2D, material_->getTexture().getID());
{
// Precise how the data have to be read by OpenGL (defining offset), for triangles
glVertexAttribPointer(VPos_index, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(0));
glVertexAttribPointer(VNor_index, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(offsetof(Vertex, normals)));
glVertexAttribPointer(VTex_index, 2, GL_FLOAT, GL_TRUE, sizeof(Vertex), BUFFER_OFFSET(offsetof(Vertex, textcoords)));
glDrawElements(GL_TRIANGLES, nb_tri_ * 3, GL_UNSIGNED_INT, 0);
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBO_index_indices4);
{
// Precise how the data have to be read by OpenGL (defining offset), for quads
glVertexAttribPointer(VPos_index, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(0));
glVertexAttribPointer(VNor_index, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(offsetof(Vertex, normals)));
glVertexAttribPointer(VTex_index, 2, GL_FLOAT, GL_TRUE, sizeof(Vertex), BUFFER_OFFSET(offsetof(Vertex, textcoords)));
glDrawElements(GL_QUADS, nb_qua_ * 4, GL_UNSIGNED_INT, 0);
}
// Unbind everything
glDisableVertexAttribArray(VPos_index);
glDisableVertexAttribArray(VNor_index);
glDisableVertexAttribArray(VTex_index);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
Do I use any too recent function ? I really don't have this feeling.
The non-VBO objects are displayed perfectly:
{
// defines an array of generic vertex attribute data, of index 0
glEnableVertexAttribArray(0);
// Get eye position
Vector3D eyev(cam->getEyePosition());
float eyet[3] = {(float)eyev.X, (float)eyev.Y, (float)eyev.Z};
// Specify data location for OpenGL
glVertexAttribPointer(0, 3, GL_DOUBLE, GL_FALSE, 0, vertices_);
// Links matrix values to entry shader matrices for the specified shader
glUniformMatrix4fv(glGetUniformLocation(shaderID, "projection"), 1, GL_TRUE, projection.getValues());
glUniformMatrix4fv(glGetUniformLocation(shaderID, "modelview"), 1, GL_TRUE, modelview.getValues());
glUniform3fv(glGetUniformLocation(shaderID, "cameraEye"), 1, eyet);
glLineWidth(1);
// Order OpenGL to draw
glDrawArrays(GL_LINES, 0, nb_coord_ / 3);
// Inactivates the generic vertex attribute data of index 0
glDisableVertexAttribArray(0);
}
Second laptop embeds a Intel Graphic 3000 -> OpenGL 3.0
Here, if I only drop the mouse over the OpenGL canevas, it crashes. Nothing is never displayed... even the background clearing color.
I spent attention do not to use deprecated functions and I really thought that everything would be compatible with a huge bunch a computers/laptops. Does anyone have any idea ?
Everything is displayed in a QGLWidget, with Qt5.8. Problems happens on 64bits platforms, tested on Windows 7 Professional.
Related
I am currently using this: http://www.opengl-tutorial.org/beginners-tutorials/tutorial-7-model-loading/
All I've done so far is replace the model, changed up the camera so that it is isometric, and made the cursor show up again. So nothing major.
My new model shows up perfectly along with its textures. I was wondering how I can make it so that by pressing W, A, S, & D, I can move my model around?
I'm planning on making a very simple "game" where I just move my model around, and collide with other objects scattered around the map.
Any help is appreciated! Thanks everyone!
// Clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Use our shader
glUseProgram(programID);
// Send our transformation to the currently bound shader,
// in the "MVP" uniform
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
// Bind our texture in Texture Unit 0
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, Texture);
// Set our "myTextureSampler" sampler to user Texture Unit 0
glUniform1i(TextureID, 0);
// 1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0, // attribute
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// 2nd attribute buffer : UVs
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glVertexAttribPointer(
1, // attribute
2, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// Draw the triangle !
glDrawArrays(GL_TRIANGLES, 0, vertices.size() );
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
// Swap buffers
glfwSwapBuffers(window);
glfwPollEvents();
the MVP matricies encode the translation, rotation and scaling of the model. It is the product of the Projection * View * Modelmatrix. If you apply the translation the the Modelmatrix and recalculate mvp, then you should see the object moving.
I have a VBO with a IBO and I want to render for example the second triangle and in the next render step I want to render the third triangle.
I think the correct way to render the second triangle ist to call
glDrawArrays(GL_TRIANGLES,
3, // indexArray[3] is start
3); // take 3 indices (from index 3..5 --> second triangle)
It works fine with the first triangle. But when I want to render another triangle the parameters of the VBO will be interpreted not correctly.
The definition of my VAO looks like this
glGenVertexArrays(1, out VAO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO.V_ID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBO.E_ID);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, false, 12 * sizeof(float), 0);
glBindAttribLocation(shaderID, 0, "InUV");
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, true, 12 * sizeof(float), 2 * sizeof(float));
glBindAttribLocation(shaderID, 1, "InColor");
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 3, GL_FLOAT, true, 12 * sizeof(float), 6 * sizeof(float));
glBindAttribLocation(shaderID, 2, "InNormal");
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 3, GL_FLOAT, false, 12 * sizeof(float), 9 * sizeof(float));
glBindAttribLocation(shaderID, 3, "InVertex");
glBindVertexArray(0);
When I call
glDrawElements(GL_TRIANGLES, VBO.length, GL_UNSIGNED_INT, 0);
The object will render correctly.
Does I use glDrawArrays in a wrong way or is there another way to render one special triangle of a VBO???
glDrawElements and glDrawArrays are different, glDrawArrays will ignore the index buffer
instead you should do:
usigned int *NULLptr=0;
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, (void*)(NULLptr+3));
note the offset specified, you can also do this in place with (void*)(3*sizeof(unsigned int))
I'm drawing my points like that :
TAB_PAS = 2;
glVertexPointer(TAB_PAS,GL_FLOAT,0,test[0].send_terrain());
glDrawElements( GL_LINES, indice_degra_de.size(), GL_UNSIGNED_INT, indice_degra_de.constData());
glVertexPointer(TAB_PAS,GL_FLOAT,0,test[1].send_terrain());
glDrawElements( GL_LINES, indice_degra.size(), GL_UNSIGNED_INT, indice_degra.constData());
glVertexPointer(TAB_PAS,GL_FLOAT,0,test[2].send_terrain());
glDrawElements( GL_LINES, indice_degra_de.size(), GL_UNSIGNED_INT, indice_degra_de.constData());
glVertexPointer(TAB_PAS,GL_FLOAT,0,test[3].send_terrain());
It draws a big terrain.
So now, I want for exemple applique a floor texture. I saw a function glTexCoordPointer but I don't know how to use it:
glTexCoordPointer(2, GL_FLOAT, 0, test[0].send_terrain());
// Something like that ?
I already uploaded my picture.tga, so now the problem is to applique it.
You use glTextCoordPointer in the same way as glVertexPointer :
glVertexPointer(TAB_PAS, GL_FLOAT, 0, test[0].send_terrain());
glTexCoordPointer(2, GL_FLOAT, 0, test[0].send_texCoords());
glDrawElements(GL_LINES, indice_degra_de.size(), GL_UNSIGNED_INT, indice_degra_de.constData());
You need to specify the texture coordinates in another array, where every pair of texture coordinates correspond to one vertex in your terrain data.
To have OpenGL actually use your Texture Coordinates:
glEnableClientState(GL_TEXTURE_COORD_ARRAY); // Before calling DrawElements
And of course you must have the texture bound and enabled. Complete example, assuming you generate texture coordinates and have your .tga texture uploaded to OpenGL:
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textureHandle);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(TAB_PAS,GL_FLOAT,0,test[0].send_terrain());
glTexCoordPointer(2, GL_FLOAT, 0, text[0].send_texCoord());
glDrawElements( GL_LINES, indice_degra_de.size(), GL_UNSIGNED_INT, indice_degra_de.constData());
glVertexPointer(TAB_PAS,GL_FLOAT,0,test[1].send_terrain());
glTexCoordPointer(2, GL_FLOAT, 0, text[1].send_texCoord());
glDrawElements( GL_LINES, indice_degra.size(), GL_UNSIGNED_INT, indice_degra.constData());
glVertexPointer(TAB_PAS,GL_FLOAT,0,test[2].send_terrain());
glTexCoordPointer(2, GL_FLOAT, 0, text[2].send_texCoord());
glDrawElements( GL_LINES, indice_degra_de.size(), GL_UNSIGNED_INT, indice_degra_de.constData());
glVertexPointer(TAB_PAS,GL_FLOAT,0,test[3].send_terrain());
glTexCoordPointer(2, GL_FLOAT, 0, text[3].send_texCoord());
// and so on...
I hope this is what you need
I'm currently trying to get my head around VBOs and I'm running into some problems.
I'm using an interleaved array with position, colors, and normals. However, when I go to draw, the display is just white.
This is the structure of my array:
GLfloat position[3];
GLfloat normal[3];
GLfloat color[4];
Here's the code:
Initialization:
glGenBuffers(1, &arrays[0]);
glBindBuffer(GL_ARRAY_BUFFER, arrays[0]);
glBufferData(GL_ARRAY_BUFFER, 125*10*36*sizeof(GLfloat), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glGenVertexArrays(1, &vaoID[1]);
glBindVertexArray(vaoID[1]);
glBindBuffer(GL_ARRAY_BUFFER, vaoID[1]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 40, ((void*)0));
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 40, ((void*)12));
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, 40, ((void*)24));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glBindVertexArray(0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
Draw:
glPushMatrix();
glBindVertexArray(vaoID[1]);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 125*36);
glPopMatrix();
I'm making a 5x5 cube of cubes that spectrum in color from black to white. However, on draw, this is all I'm getting:
I see a problem with what you've posted above. You've defined your colors as being floats in the struct, but you're telling glVertexAttribPointer() that your colors are unsigned bytes. It should probably be something like this:
glVertexAttribPointer(2, 4, GL_FLOAT, GL_TRUE, 40, ((void*)24));
And that assumes that you're actually putting floats into those memory locations. How are you setting them?
I have some code that loops through a set of objects and renders instances of those objects. The list of objects that needs to be rendered is stored as a std::map<MeshResource*, std::vector<MeshRendererer*>>, where an object of class MeshResource contains the vertices and indices with the actual data, and an object of classMeshRenderer defines the point in space the mesh is to be rendered at.
My rendering code is as follows:
glDisable(GL_BLEND);
glEnable(GL_CULL_FACE);
glDepthMask(GL_TRUE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
for (std::map<MeshResource*, std::vector<MeshRenderer*> >::iterator it = renderables.begin(); it != renderables.end(); it++)
{
it->first->setupBeforeRendering();
cout << "<";
for (unsigned long i =0; i < it->second.size(); i++)
{
//Pass in an identity matrix to the vertex shader- used here only for debugging purposes; the real code correctly inputs any matrix.
uniformizeModelMatrix(Matrix4::IDENTITY);
/**
* StartHere fix rendering problem.
* Ruled out:
* Vertex buffers correctly.
* Index buffers correctly.
* Matrices correct?
*/
it->first->render();
}
it->first->cleanupAfterRendering();
}
geometryPassShader->disable();
glDepthMask(GL_FALSE);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
The function in MeshResource that handles setting up the uniforms is as follows:
void MeshResource::setupBeforeRendering()
{
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(4);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iboID);
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0); // Vertex position
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*) 12); // Vertex normal
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*) 24); // UV layer 0
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*) 32); // Vertex color
glVertexAttribPointer(4, 1, GL_UNSIGNED_SHORT, GL_FALSE, sizeof(Vertex), (const GLvoid*) 44); //Material index
}
The code that renders the object is this:
void MeshResource::render()
{
glDrawElements(GL_TRIANGLES, geometry->numIndices, GL_UNSIGNED_SHORT, 0);
}
And the code that cleans up is this:
void MeshResource::cleanupAfterRendering()
{
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glDisableVertexAttribArray(3);
glDisableVertexAttribArray(4);
}
The end result of this is that I get a black screen, although the end of my rendering pipeline after the rendering code (essentially just drawing axes and lines on the screen) works properly, so I'm fairly sure it's not an issue with the passing of uniforms. If, however, I change the code slightly so that the rendering code calls the setup immediately before rendering, like so:
void MeshResource::render()
{
setupBeforeRendering();
glDrawElements(GL_TRIANGLES, geometry->numIndices, GL_UNSIGNED_SHORT, 0);
}
The program works as desired. I don't want to have to do this, though, as my aim is to set up vertex, material, etc. data once per object type and then render each instance updating only the transformation information.
The uniformizeModelMatrix works as follows:
void RenderManager::uniformizeModelMatrix(Matrix4 matrix)
{
glBindBuffer(GL_UNIFORM_BUFFER, globalMatrixUBOID);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(Matrix4), matrix.ptr());
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}