OpenGL 3.2 Texturing Issue - c++

I'm working on a 2D engine in C++ at the moment.
I've run into a problem which I seem to believe I've come up against once before, but have since forgotten how I fixed it.
The engine is cross platform ( Win, OSX, Linux ) and to accomplish this I am using GLFW as a base.
When doing the normal texturing thing I end up with this :
As you can see the texturing isn't right ( as the image is supposed to be a simple Image of me ).
Using geDebugger I can confirm that the image being buffered to the GPU is correct, but some how it is ending up as you see in the Image.
I'll include some cuts of relevant code below, but should you want more info feel free to ask.
-Buffer Generation Code
glGenVertexArrays( 1, &_vao );
// Generate Buffers and so on.
glBindVertexArray( _vao );
glGenBuffers( 1, &_vboVertices );
glBindBuffer( GL_ARRAY_BUFFER, _vboVertices );
glBufferData( GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * _numVertices, _vertices, GL_STATIC_DRAW );
glGenBuffers( 1, &_vboTexCoords );
glBindBuffer( GL_ARRAY_BUFFER, _vboTexCoords );
glBufferData( GL_ARRAY_BUFFER, sizeof(GLfloat) * 2 * _numVertices, _texCoords, GL_STATIC_DRAW );
glGenBuffers( 1, &_vboIndices );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, _vboIndices );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof(GLint) * _numIndices, _indices, GL_STATIC_DRAW );
-Render Code
glm::mat4 modelViewProjMatrix = projMatrix * viewMatrix * modelMatrix;
ShaderResource * shader = ShaderManager::GetInstance()->GetShader( _shaderName.c_str() );
TextureResource * texture = TextureManager::GetInstance()->GetTexture( _textureName.c_str() );
shader->BindShader();
// Bind VAO
glBindVertexArray( _vao );
// Bind all VBO's
glBindBuffer( GL_ARRAY_BUFFER, _vboVertices );
GLint posLocation = shader->GetAttribLocation("in_position");
glVertexAttribPointer( posLocation, 3, GL_FLOAT, GL_FALSE, 0, (void*)0 );
GLint texCoordLocation = shader->GetAttribLocation("in_texCoord");
glVertexAttribPointer( texCoordLocation, 2, GL_FLOAT, GL_FALSE, 0, (void*)0 );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, _vboIndices );
// Enable VBO Pointers
glEnableVertexAttribArray( posLocation );
glEnableVertexAttribArray( texCoordLocation );
// Find and assign Uniforms
GLint MVPMatrixLocation = shader->GetUniformLocation("in_MVPMatrix");
GLint colourLocation = shader->GetUniformLocation("in_colour");
GLint textureLocation = shader->GetUniformLocation("texMap");
glUniformMatrix4fv( MVPMatrixLocation, 1, GL_FALSE, glm::value_ptr( modelViewProjMatrix ) );
glUniform4fv( colourLocation, 1, glm::value_ptr( _colour ) );
// Texture Uniform
if( texture != 0 )
{
glActiveTexture( GL_TEXTURE0 );
glUniform1i( textureLocation, 0 );
glBindTexture( GL_TEXTURE_2D, texture->GetTextureId() );
}
glDrawElements( GL_TRIANGLES, _numIndices, GL_UNSIGNED_INT, (void*) 0 );
glDisableVertexAttribArray( posLocation );
glDisableVertexAttribArray( texCoordLocation );
shader->UnbindShader();
glBindVertexArray( 0 );
-Vert Shader
#version 150
in vec3 in_position;
in vec2 in_texCoord;
out vec4 out_colour;
smooth out vec2 out_texCoord;
uniform vec4 in_colour;
uniform mat4 in_MVPMatrix;
void main()
{
out_colour = in_colour;
out_texCoord = in_texCoord;
gl_Position = in_MVPMatrix * vec4( in_position, 1.0 );
}
-Frag Shader
#version 150
in vec4 out_colour;
smooth in vec2 out_texCoord;
out vec4 fragColor;
uniform sampler2D texMap;
void main()
{
vec4 diffuseTexel = texture2D( texMap, out_texCoord );
fragColor = out_colour * diffuseTexel;
}

glVertexAttribPointer( posLocation, 3, GL_FLOAT, GL_FALSE, 0, (void*)0 );
glVertexAttribPointer( texCoordLocation, 2, GL_FLOAT, GL_FALSE, 0, (void*)0 );
This means that both the positions and texture coordinates come from the same locations in the buffer. That they overlap.
You seem to want them to come from different buffer objects. That means you have to bind a new buffer to GL_ARRAY_BUFFER between your first and second glVertexAttribPointer calls.

// Bind all VBO's
glBindBuffer( GL_ARRAY_BUFFER, _vboVertices );
GLint posLocation = shader->GetAttribLocation("in_position");
glVertexAttribPointer( posLocation, 3, GL_FLOAT, GL_FALSE, 0, (void*)0 );
GLint texCoordLocation = shader->GetAttribLocation("in_texCoord");
glVertexAttribPointer( texCoordLocation, 2, GL_FLOAT, GL_FALSE, 0, (void*)0 );
VertexAttribPointer for texcoords should be set after binding _vboTexCoord, not _vboVertices.

Related

vertex buffer object and data buffers [opengl]

I'm trying to figure out how to use multiple buffers associated to a single vertex array object on the basis of one buffer per "object model" (e.g. verticies, normal, textures). To make it very simple in the sample code that follows I have couple objects composed of just one triangles (3 vertices) and associated colors. Buffer element indexed by ArrayBuffer1 receive the vertex coords (homogeneous coords) and an RGBA color vectors. Same for Buffer element indexed by ArrayBuffer2.
The vertex shader is a passthrough as following
#version 400 core
layout( location = 0 ) in vec4 vPosition;
layout( location = 1 ) in vec4 vColor;
out vec4 color;
void
main()
{
color= vColor;
gl_Position = vPosition;
}
The fragment shader is a passthroug has well
#version 450 core
in vec4 color;
out vec4 fColor;
void main()
{
fColor = color;
}
I d like to pass on data with one buffer per object grouping vertex attributes in the same buffer.
I can't figure how to raw these 2 objects.
Here is the client code (init part)
enum VertexDim { xDim, yDim, zDim, wDim, NumDim};
enum VAO_IDs { Triangles, NumVAOs };
enum Buffer_IDs { ArrayBuffer1, ArrayBuffer2, NumBuffers };
enum Attrib_IDs { vPosition = 0, vColor=1 };
GLuint VAOs[NumVAOs];
GLuint Buffers[NumBuffers];
const GLuint NumVertices = 6;
const GLuint curDim= NumDim;
// first triangle
GLfloat static_vertices1[NumVertices/2][NumDim] = {
{ -0.90f, -0.90f, 0.5f, 1}, { 0.85f, -0.90f, 0.3f, 1 }, { -0.90f, 0.85f, 0.0f, 1 } // Triangle 1
};
// second triangle
GLfloat static_vertices2[NumVertices/2][NumDim] = {
{ 0.90f, -0.85f, -0.1f, 1 }, { 0.90f, 0.90f, -0.5f, 1 }, { -0.85f, 0.90f, -0.8f, 1 } // Triangle 2
};
// a base color from which to compute different vertex colors
GLfloat infColor_value[4]= {0.9f, 0.7f, 0.5f, 1.0f};
//----------------------------------------------------------------------------
//
// init
//
void
init( void )
{
const unsigned int n=NumVertices/2;
GLfloat infColor_values1[n][curDim];
GLfloat infColor_values2[n][curDim];
// compute different vertex colors from base color infColor_value
// .. loop over infColor_values1 and infColor_values2
ShaderInfo shaders[] =
{
{ GL_VERTEX_SHADER, "media/shaders/triangles/triangles2.vert" },
{ GL_FRAGMENT_SHADER, "media/shaders/triangles/triangles2.frag" },
{ GL_NONE, NULL }
};
// LoadShaders is a wrapper to load, compile code and link shaders
GLuint program = LoadShaders( shaders );
if( program == 0) { std::cerr<<"shader program failed to build" << std::endl; }
glUseProgram( program );
glGenVertexArrays( NumVAOs, VAOs );
glBindVertexArray( VAOs[Triangles] );
glCreateBuffers( NumBuffers, Buffers );
// vertex 1
glBindBuffer( GL_ARRAY_BUFFER, Buffers[ArrayBuffer1] );
glNamedBufferData( Buffers[ArrayBuffer1], sizeof(static_vertices1)+sizeof(infColor_values1) , NULL, GL_STATIC_DRAW);
glNamedBufferSubData( Buffers[ArrayBuffer1], 0, sizeof(static_vertices1), static_vertices1);
glNamedBufferSubData( Buffers[ArrayBuffer1], sizeof(static_vertices1), sizeof(infColor_values1), infColor_values1);
GLuint64 offset = 0;
glVertexAttribPointer( vPosition, NumDim, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
glEnableVertexAttribArray( vPosition );
offset = sizeof(static_vertices1);
glVertexAttribPointer( vColor, 4, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)offset );
glEnableVertexAttribArray( vColor );
// vertex 2
glBindBuffer( GL_ARRAY_BUFFER, Buffers[ArrayBuffer2] );
glNamedBufferData( Buffers[ArrayBuffer2], sizeof(static_vertices2)+sizeof(infColor_values2) , NULL, GL_STATIC_DRAW);
glNamedBufferSubData( Buffers[ArrayBuffer2], 0, sizeof(static_vertices2), static_vertices1);
glNamedBufferSubData( Buffers[ArrayBuffer2], sizeof(static_vertices2), sizeof(infColor_values2), infColor_values2);
offset = 0;
glVertexAttribPointer( vPosition, NumDim, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
glEnableVertexAttribArray( vPosition );
offset = sizeof(static_vertices2);
glVertexAttribPointer( vColor, 4, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)offset );
glEnableVertexAttribArray( vColor );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
glBindVertexArray(0);
}
and here follows the code to render
void
display( void )
{
static const float black[] = { 0.0f, 0.0f, 0.0f, 0.0f };
glClearBufferfv(GL_COLOR, 0, black);
glBindVertexArray( VAOs[Triangles] );
glDrawArrays( GL_TRIANGLES, 0, NumVertices );
glBindVertexArray(0);
}
to sum it up : how to store an object vertices attributes in a single buffer and still display multiple objects ?
I could fetch verything in the same sub buffers (one for vertex coord, one for vetex colors) but I can't come up wit ha solution where I would sparate the obejcts to render.
I ve read close answers ( Architecture to draw many different objects in OpenGL What are Vertex Array Objects? ) related to this question yet it does not answer my question.
Defining a VAO for each object made it following #Rabbid76 advice
change for the init code
enum Buffer_IDs { Mesh, NumBuffers };
//....
// triangle 1
glBindBuffer( GL_ARRAY_BUFFER, Buffers1[Mesh] );
glNamedBufferData( Buffers1[Mesh], sizeof(static_vertices1)+sizeof(infColor_values1) , NULL, GL_STATIC_DRAW);
glNamedBufferSubData( Buffers1[Mesh], 0, sizeof(static_vertices1), static_vertices1);
glNamedBufferSubData( Buffers1[Mesh], sizeof(static_vertices1), sizeof(infColor_values1), infColor_values1);
GLuint64 offset = 0;
glVertexAttribPointer( vPosition, NumDim, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
glEnableVertexAttribArray( vPosition );
offset = sizeof(static_vertices1);
glVertexAttribPointer( vColor, 4, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)offset );
glEnableVertexAttribArray( vColor );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
glBindVertexArray(0);
// triangle 2
glBindVertexArray( VAOs[Triangle2] );
glCreateBuffers( NumBuffers, Buffers2 );
glBindBuffer( GL_ARRAY_BUFFER, Buffers2[Mesh] );
glNamedBufferData( Buffers2[Mesh], sizeof(static_vertices2)+sizeof(infColor_values2) , NULL, GL_STATIC_DRAW);
glNamedBufferSubData( Buffers2[Mesh], 0, sizeof(static_vertices2), static_vertices2);
glNamedBufferSubData( Buffers2[Mesh], sizeof(static_vertices2), sizeof(infColor_values2), infColor_values2);
offset = 0;
glVertexAttribPointer( vPosition, NumDim, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
glEnableVertexAttribArray( vPosition );
offset = sizeof(static_vertices2);
glVertexAttribPointer( vColor, 4, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)offset );
glEnableVertexAttribArray( vColor );
change for the render code
void
display( void )
{
static const float black[] = { 0.0f, 0.0f, 0.0f, 0.0f };
glClearBufferfv(GL_COLOR, 0, black);
glBindVertexArray( VAOs[Triangle1] );
glDrawArrays( GL_TRIANGLES, 0, NumVertices/2 );
glBindVertexArray( VAOs[Triangle2] );
glDrawArrays( GL_TRIANGLES, 0, NumVertices/2 );
glBindVertexArray(0);
}

glDrawElements using the wrong VBO?

I'm trying to render two different objects on screen. The problem I as far as I can tell is OpenGL is using the wrong Vertex Buffer but the correct Index Buffer, but I'm not too sure about anything I'm currently doing as I've pretty much started learning OpenGL again.
This is what currently gets displayed: http://puu.sh/ekhd7/cca60981ab.jpg
If its a bad idea having classes for objects, or how it should be done, please tell me - I'm going off nothing.
struct point4{
vec4 vertex;
vec4 color;
};
class Pyramid
{
public:
//Variables and Contructor here
void init(){
glGenBuffers( 1, &Arraybufferx );
glBindBuffer( GL_ARRAY_BUFFER, Arraybufferx );
glBufferData( GL_ARRAY_BUFFER, sizeof(point4)*16, NULL, GL_STATIC_DRAW );
glBufferSubData( GL_ARRAY_BUFFER, 0, sizeof(left), left );
glBufferSubData( GL_ARRAY_BUFFER, sizeof(left) , sizeof(right), right );
glBufferSubData( GL_ARRAY_BUFFER, sizeof(left)*2, sizeof(back), back );
glBufferSubData( GL_ARRAY_BUFFER, sizeof(left)*3, sizeof(front), front );
glBufferSubData( GL_ARRAY_BUFFER, sizeof(left)*4, sizeof(bottom), bottom );
glGenBuffers( 1, &IndexBuffer );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, IndexBuffer );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof(gIndices), gIndices, GL_STATIC_DRAW );
}
void display(GLint tr,GLint theta, GLfloat rt1[], GLfloat Theta1[]){
glBindBuffer( GL_ARRAY_BUFFER, Arraybufferx );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, IndexBuffer );
glUniform3fv( tr, 1, rt1 );
glUniform3fv( theta, 1, Theta1 );
glDrawElements( GL_TRIANGLES, sizeof(gIndices), GL_UNSIGNED_INT, 0 );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
}
};
class cube{
public:
//Variables and Contructor here
void init(){
glGenBuffers( 1, &Arraybuffer );
glBindBuffer( GL_ARRAY_BUFFER, Arraybuffer );
glBufferData( GL_ARRAY_BUFFER, sizeof(left)*6, NULL, GL_STATIC_DRAW );
glBufferSubData( GL_ARRAY_BUFFER, 0, sizeof(left), left );
glBufferSubData( GL_ARRAY_BUFFER, sizeof(point4)*4, sizeof(right), right );
glBufferSubData( GL_ARRAY_BUFFER, sizeof(point4)*8, sizeof(top), top );
glBufferSubData( GL_ARRAY_BUFFER, sizeof(point4)*12, sizeof(bottom), bottom );
glBufferSubData( GL_ARRAY_BUFFER, sizeof(point4)*16, sizeof(back), back );
glBufferSubData( GL_ARRAY_BUFFER, sizeof(point4)*20, sizeof(front), front );
glGenBuffers( 1, &IndexBuffer );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, IndexBuffer );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof(gIndices), gIndices, GL_STATIC_DRAW );
}
void display(GLint tr,GLint theta, GLfloat rt1[], GLfloat Theta1[]){
glBindBuffer( GL_ARRAY_BUFFER, Arraybuffer );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, IndexBuffer );
glUniform3fv( tr, 1, rt1 );
glUniform3fv( theta, 1, Theta1 );
glDrawElements( GL_TRIANGLES, sizeof(gIndices), GL_UNSIGNED_INT, 0 );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
}
};
void init()
{
// Create a vertex array object
GLuint vao;
glGenVertexArrays( 1, &vao );
glBindVertexArray( vao );
pyramid.init();
Cube.init();
GLuint program = InitShader( "vshader36.glsl", "fshader36.glsl" );
glUseProgram( program );
GLuint vPosition = glGetAttribLocation( program, "vPosition" );
glEnableVertexAttribArray( vPosition );
GLuint vColor = glGetAttribLocation( program, "vColor" );
glEnableVertexAttribArray( vColor );
model_view = glGetUniformLocation(program, "model_view");
GLuint projection = glGetUniformLocation(program, "projection");
glVertexAttribPointer( vPosition, 4, GL_FLOAT, GL_FALSE, sizeof(point4), 0 );
glVertexAttribPointer(vColor,4,GL_FLOAT,GL_FALSE,sizeof(point4),(void*)sizeof(vec4));
// Create and send the model view matrix
mat4 mv = LookAt(eye, at, up);
glUniformMatrix4fv(model_view, 1, GL_TRUE, mv);
theta = glGetUniformLocation( program, "theta" );
tr = glGetUniformLocation( program, "tr" );
glEnableClientState (GL_VERTEX_ARRAY);
mat4 p = Frustum(-1.0, 1.0, -1.0, 1.0, 10.0, -20.0);
glUniformMatrix4fv(projection, 1, GL_TRUE, p);
glEnable( GL_DEPTH_TEST );
glClearColor( 1.0, 1.0, 1.0, 1.0 );
}
//----------------------------------------------------------------------------
void display( void )
{
mat4 mv = LookAt(eye, at, up);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glUniformMatrix4fv(model_view, 1, GL_TRUE, mv);
Cube.display(tr,theta,Translate1,Theta);
pyramid.display(tr,theta,Translate2,Theta);
glutSwapBuffers();
}
You misunderstood how Vertex Array Pointers (and VAOs) work. glDraw*() commands never care about the current GL_ARRAY_BUFFER binding. That binding is relevant at the time of the glVertexAtrrib*Pointer() calls - a reference to the currently bound GL_ARRARY_BUFFER becomes part of the attribute pointer. This also means that you can set up each attribute to be fetched from a different buffer.
Consequently, your code will only use the VBO of the cube object, as this is the one that is bound at the time you set vertex attrib pointers.
When you want to draw your different objects, you have to switch
the vertex attrib pointers, so it will look like this:
drawObject() {
glBindBuffer(GL_ARRAY_BUFFER,vbo_for_attr0);
glVertexAttribPointer(0,...);
glBindBuffer(GL_ARRAY_BUFFER,vbo_for_attr1);
glVertexAttribPointer(1,...);
[...]
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glDrawElements(...);
(This is assuming you are using the same attribs for all objects. If this is not the case, you may also have to enable/disable the attrib arrays in this function).
This is where VAOs enter the picture. VAOs are container objects stroing the complete vertex array pointer states for each attribute (including the buffer binding and enable/disable state), and the GL_ELEMENT_ARRAY buffer binding. Conceptually, you can create a VAO per object, and move the vertex pointer setup to yout init() function, reducing the draw code to
drawObject() {
glBindVertexArray(vao);
glDrawElements(...);
So conceptually, it looks like this:

OpenGl object not displaying, shader related

I'm trying to render in opengl using shaders, the background colour generates and no error messages appear but the object I'm trying to render doesn't show. I've been trying all day to solve this but have come to nothing. I'm reading vertices and indices in from a .txt file but that doesn't seem to be the problem as all the numbers are exactly what they should be. Here is my init:
void init() {
readFile("pendulum.txt", pVert, pIndices, pCols);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable( GL_DEPTH_TEST );
glClearColor(0.5,0.5,0.5,1.0);
program = InitShader( "aVertexShader64.glsl", "aFragShader63.glsl" );
glUseProgram( program );
modelView = glGetUniformLocation( program, "model_view" );
projection = glGetUniformLocation( program, "projection" );
glGenVertexArrays( 1, &vao );
glBindVertexArray( vao );
// Create and initialize two buffer objects
glGenBuffers( 2, buffers);
//one buffer for the vertexPositions and colours
glBindBuffer( GL_ARRAY_BUFFER, buffers[0]);
glBufferData( GL_ARRAY_BUFFER, numVertexPositionBytes + numVertexColourBytes,NULL, GL_STATIC_DRAW );
glBufferSubData( GL_ARRAY_BUFFER, 0, numVertexPositionBytes, vertexPositions );
glBufferSubData( GL_ARRAY_BUFFER, numVertexPositionBytes, numVertexColourBytes, vertexColours);
//one buffer for the indices
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
glBufferData( GL_ELEMENT_ARRAY_BUFFER, numVertexIndexBytes,vertexIndices, GL_STATIC_DRAW );
// set up vertex arrays
GLuint vPosition = glGetAttribLocation( program, "vPosition" );
glEnableVertexAttribArray( vPosition );
glVertexAttribPointer( vPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
GLuint vColor = glGetAttribLocation( program, "vColor" );
glEnableVertexAttribArray( vColor );
glVertexAttribPointer( vColor, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(numVertexPositionBytes) );
}
Main:
int main( int argc, char **argv ){
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH );
glutInitWindowSize(winWidth, winHeight);
glutCreateWindow( "pendulum" );
glewInit();
init();
//initialiseBoxCoordinates();
//glutTimerFunc(1,timer,0);
glutReshapeFunc(reshape);
glutDisplayFunc( display );
glutKeyboardFunc( keyboard );
glutIdleFunc( idle );
glutMainLoop();
return 0;
}
And Display:
void display( void ) {
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
pStack.pushMatrix();
pStack.loadIdentity();
pStack.rotated(theta,0.0,1.0,0.0);
pStack.translated(0.0,0.0,-1.0);
for(int i = 0; i<NumPVerts; i++){
pStack.transformd(&pVert[i*4],&pVertActual[i*4]);
}
glBindVertexArray(lineVao);
glDrawArrays(GL_LINES,0, lineVertSize/3);
glBindVertexArray(pVao);
glBindBuffer(GL_ARRAY_BUFFER, pBuffers[0]);
glBufferSubData(GL_ARRAY_BUFFER, 0, numPVertexBytes, pVertActual);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pBuffers[1]);
glDrawElements(GL_TRIANGLES, NumPIndices, GL_UNSIGNED_BYTE, 0);
pStack.popMatrix();
//switch buffers
glutSwapBuffers();
}
After the matrix transformations the vertices are all where they should be and I have used the same matrix class before with no problems so I don't think it's that. I think it has something to do with the shaders but I'm still new to opengl and am really not sure. Here are the vertex shader:
in vec4 vPosition;
in vec4 vColor;
out vec4 color;
uniform mat4 model_view;
uniform mat4 projection;
void main() {
gl_Position = projection*model_view*vPosition/vPosition.w;
color = vColor;
}
And the fragment shader:
in vec4 color;
out vec4 fColor;
void main() {
fColor = color;
}
As far as i can see, your shaders are kinda fine. But you don't use #version tag there, which could lead to some problems, like shader compilation errors.
I don't understand why you have the division vPosition/vPosition.w in your vertex shader. This is still done automatically by opengl pipeline, you don't need to do this.
There are some rucial bits in your sources left out. For example, i don't know what InitShader(...) does, and i don't see any calls to glUniform(..) (i suppose, they are hidden in pStack object?). And i don't see initialization code of some important variables like numVertexPositionBytes, or what BUFFER_OFFSET(numVertexPositionBytes) is supposed even to mean.

opengl flickering while rendering multiple objects

I'm pretty new to opengl and I don't really understand what's going on here. I'm trying to use two VAOs to create multiple objects and am using a custom matrix to rotate/translate them. The image is fine when I load up one, but when I load up two they both flicker. My init is this, where I have a different array for each buffer, vertex position, vertex indices and vertex colours.
void init()
{
readFile();
//glEnable(GL_DEPTH);
glEnable( GL_DEPTH_TEST );
//make background yerpul in colour
glClearColor( 0.235, 0.194, 0.314, 1.0 );
// Load shaders and use the resulting shader program
program = InitShader( "aVertexShader61.glsl", "aFragShader61.glsl" );
glUseProgram( program );
// Create a vertex array object
glGenVertexArrays( 1, &vao );
glBindVertexArray( vao );
// Create and initialize two buffer objects
glGenBuffers( 2, buffers);
//one buffer for the vertexPositions and colours
glBindBuffer( GL_ARRAY_BUFFER, buffers[0]);
glBufferData( GL_ARRAY_BUFFER, numVertexPositionBytes + numVertexColourBytes,NULL, GL_STATIC_DRAW );
glBufferSubData( GL_ARRAY_BUFFER, 0, numVertexPositionBytes, vertexPositions );
glBufferSubData( GL_ARRAY_BUFFER, numVertexPositionBytes, numVertexColourBytes, vertexColours);
//one buffer for the indices
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
glBufferData( GL_ELEMENT_ARRAY_BUFFER, numVertexIndexBytes,vertexIndicies, GL_STATIC_DRAW );
// set up vertex arrays
GLuint vPosition = glGetAttribLocation( program, "vPosition" );
glEnableVertexAttribArray( vPosition );
glVertexAttribPointer( vPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
GLuint vColor = glGetAttribLocation( program, "vColor" );
glEnableVertexAttribArray( vColor );
glVertexAttribPointer( vColor, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(numVertexPositionBytes) );
// Second object
glGenVertexArrays( 1, &vao2 );
glBindVertexArray( vao2 );
glGenBuffers( 2, buffers2);
//one buffer for the vertexPositions and colours
glBindBuffer( GL_ARRAY_BUFFER, buffers2[0]);
glBufferData( GL_ARRAY_BUFFER, numVertexPositionBytes + numVertexColourBytes,NULL, GL_STATIC_DRAW );
glBufferSubData( GL_ARRAY_BUFFER, 0, numVertexPositionBytes, vertexPositions2 );
glBufferSubData( GL_ARRAY_BUFFER, numVertexPositionBytes, numVertexColourBytes, vertexColours2);
//one buffer for the indices
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, buffers2[1]);
glBufferData( GL_ELEMENT_ARRAY_BUFFER, numVertexIndexBytes,vertexIndicies2, GL_STATIC_DRAW );
// set up vertex arrays
GLuint vPosition2 = glGetAttribLocation( program, "vPosition" );
glEnableVertexAttribArray( vPosition2 );
glVertexAttribPointer( vPosition2, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
GLuint vColor2 = glGetAttribLocation( program, "vColor" );
glEnableVertexAttribArray( vColor2 );
glVertexAttribPointer( vColor2, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(numVertexPositionBytes) );
glBindVertexArray(0);
}
This is my display that gets called with glutPostRedisplay(); in my idle function, no other calls to anything are made from the idle. mStack is a matrix stack object created from an external file
void
display( void )
{
//clear for first object, generate matrix and apply to object
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
mStack.loadIdentity();
mStack.translatef(0,yDisplace,0);
mStack.rotatef(Theta[Yaxis], 0.0,1.0,0.0);
for (unsigned char i=0; i<NumVertices; i++){
mStack.transformf(&vertexPositionsInit[i*4],&vertexPositions[i*4]);
}
//Apply to second object
for (unsigned char i=0; i<NumVertices; i++){
mStack.transformf(&vertexPositionsInit2[i*4],&vertexPositions2[i*4]);
}
//Draw first object
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
glBufferSubData(GL_ARRAY_BUFFER, 0, numVertexPositionBytes, vertexPositions );
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
//Indexing into vertices we need to use glDrawElements
glDrawElements(GL_TRIANGLES, NumIndicies, GL_UNSIGNED_BYTE, 0);
glutSwapBuffers();
//Clear and draw second object
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glutSwapBuffers();
glBindVertexArray(vao2);
glBindBuffer(GL_ARRAY_BUFFER, buffers2[0]);
glBufferSubData(GL_ARRAY_BUFFER, 0, numVertexPositionBytes, vertexPositions2 );
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers2[1]);
//Indexing into vertices we need to use glDrawElements
glDrawElements(GL_TRIANGLES, NumIndicies, GL_UNSIGNED_BYTE, 0);
glutSwapBuffers();
}
I'm using simple vertex and fragment shaders.
The vertex shader,
in vec4 vPosition;
in vec4 vColor;
out vec4 color;
void main()
{
gl_Position = vPosition;
color = vColor;
}
And fragment shader,
in vec4 color;
out vec4 fColor;
void main()
{
fColor = color;
}
Any help would be appreciated, and I can post the Matrix file if need be.
Thanks
Don't call glutSwapBuffers() or glClear() in between objects. Swapping buffers is a way to tell GLUT "Okay, I'm done with this frame, let's start with the next one."
Usually you'll want to split out the code that sets up and completes each frame (like the calls to glClear() and glutSwapBuffers()) from the code that renders each object, because OpenGL is basically a gigantic box of global variables and it's hard to write good OpenGL code without breaking your methods up into small pieces.

Can a VBO be bound to multiple VAOs?

I'm trying to render a model's UV map by treating its texture coordinates as an array of vertex positions. I set up a VAO for the model which renders perfectly, then tried adding a second VAO and binding the texture coordinate buffer to it. Unfortunately it doesn't render anything.
I've written a second set of vertex and fragment shaders for the UV map which compile just fine. The buffer is bound in the same way as with the model VAO and the vertex attributes set. The only difference I can see is I'm not re-specifying the buffer data.
This is my code for setting up the model VAO:
// Create model VAO
glGenVertexArrays( 1, &modelVAO );
glBindVertexArray( modelVAO );
// Create position buffer
glGenBuffers( 1, &positionBuffer );
glBindBuffer( GL_ARRAY_BUFFER, positionBuffer );
glBufferData( GL_ARRAY_BUFFER, sizeof( GLfloat ) * vertexCount * 4, positions, GL_STATIC_DRAW );
glVertexAttribPointer( 0, 4, GL_FLOAT, GL_FALSE, 0, 0 );
glEnableVertexAttribArray( 0 );
// Create normal buffer
glGenBuffers( 1, &normalBuffer );
glBindBuffer( GL_ARRAY_BUFFER, normalBuffer );
glBufferData( GL_ARRAY_BUFFER, sizeof( GLfloat ) * vertexCount * 3, normals, GL_STATIC_DRAW );
glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 0, 0 );
glEnableVertexAttribArray( 1 );
// Create texture coordinate buffer
glGenBuffers( 1, &textureCoordinateBuffer );
glBindBuffer( GL_ARRAY_BUFFER, textureCoordinateBuffer );
glBufferData( GL_ARRAY_BUFFER, sizeof( GLfloat ) * vertexCount * 2, textureCoordinates, GL_DYNAMIC_DRAW );
glVertexAttribPointer( 2, 2, GL_FLOAT, GL_FALSE, 0, 0 );
glEnableVertexAttribArray( 2 );
// Unbind model VAO
glBindVertexArray( 0 );
Then I set up the UV map VAO like this:
// Create new UV map VAO
glGenVertexArrays( 1, &uvMapVAO );
glBindVertexArray( uvMapVAO );
// Bind texture coordinate buffer
glBindBuffer( GL_ARRAY_BUFFER, textureCoordinateBuffer );
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 0, 0 );
glEnableVertexAttribArray( 0 );
// Unbind UV map VAO
glBindVertexArray( 0 );
Is it possible to use the same VBO with more than one VAO like this?
Yes. VAOs just store references to VBOs, with the associated data for format, offsets, etc., as specified by glVertexAttribPointer. Index VBOs have slightly different semantics.