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:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With