PDA

View Full Version : separate problems with buffer objects and glDrawArray



airseb
01-30-2006, 04:12 AM
Hi !
i have two problems :
1. my implementation of VBOs don't work with glDrawElement or glDrawArray (my program works with glDrawElement without VBOs)
2. with or without VBOs, glDrawArray don't works : i have strange rendering

I put my code here for both :

void loader3ds::buildBOs()
{
for (i=0 ; i<=myLoader->getCounterObj() ; i++)
{

glGenBuffers(1, &amp;myLoader->myObjects[i].vertexBufferName );

glBindBuffer( GL_ARRAY_BUFFER, myLoader->myObjects[i].vertexBufferName );

glBufferData( GL_ARRAY_BUFFER, sizeof(float)*3*myLoader->myObjects[i].nbVertices, &amp;myLoader->myObjects[i].myVertices, GL_STATIC_DRAW );

glGenBuffers(1, &amp;myLoader->myObjects[i].indexBufferName );

glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, myLoader->myObjects[i].indexBufferName );

glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short int)*myLoader->myObjects[i].nbVertices, &amp;myLoader->myObjects[i].myIndices, GL_STATIC_DRAW );

glGenBuffers(1, &amp;myLoader->myObjects[i].texCoordName );
// Get A Valid Name
glBindBufferARB( GL_ARRAY_BUFFER_ARB, myLoader->myObjects[i].texCoordName ); // Bind The Buffer
// Load The Data
glBufferData( GL_ARRAY_BUFFER_ARB, sizeof(float)*2*myLoader->myObjects[i].nbVertices, &amp;myLoader->myObjects[i].myMapping, GL_STATIC_DRAW_ARB );

glGenBuffers(1, &amp;myLoader->myObjects[i].normalsBufferName );

glBindBuffer( GL_ARRAY_BUFFER, myLoader->myObjects[i].normalsBufferName ); // Bind The Buffer

glBufferData( GL_ARRAY_BUFFER, sizeof(float)*3*myLoader->myObjects[i].nbVertices, &amp;myLoader->myObjects[i].perVertexNormals, GL_STATIC_DRAW );
// Our Copy Of The Data Is No Longer Necessary, It Is Safe In The Graphics Card
glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
delete [] myLoader->myObjects[i].perVertexNormals ;
delete [] myLoader->myObjects[i].myVertices ;
}
}
void display ()
{

glClear (GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT ) ;

glEnableClientState (GL_VERTEX_ARRAY);
glEnableClientState (GL_INDEX_ARRAY);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
glEnableClientState (GL_NORMAL_ARRAY);

glFrontFace(GL_CCW) ;

glEnable (GL_CULL_FACE) ;
glCullFace(GL_BACK) ;

int i ;
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL) ;
glRotatef(c, 0.0, 1.0, 0.0) ;
for (i=0 ; i<=myLoader->getCounterObj() ; i++)
{

glBindBuffer( GL_ARRAY_BUFFER, myLoader->myObjects[i].vertexBufferName );
glVertexPointer (3, GL_FLOAT, 0, (char *) NULL );

glBindBuffer( GL_ARRAY_BUFFER, myLoader->myObjects[i].indexBufferName );
glIndexPointer (GL_SHORT, 0, (char *) NULL );

glBindTexture (GL_TEXTURE_2D, texname[i]) ;
glBindBuffer( GL_ARRAY_BUFFER_ARB, myLoader->myObjects[i].texCoordName );
glTexCoordPointer (2, GL_FLOAT, 0, (char *) NULL );

glBindBuffer( GL_ARRAY_BUFFER, myLoader->myObjects[i].normalsBufferName );


//glDrawElements (GL_TRIANGLES, (myLoader->myObjects[i].nbPoly*3), GL_UNSIGNED_SHORT, &amp;(myLoader->myObjects[i].myIndices[0][0])) ;

glDrawArrays( GL_TRIANGLES, 0, myLoader->myObjects[i].nbVertices);

glutSwapBuffers() ;
}

int main(int argc, char *argv[])
{
myLoader= new loader3ds() ;
//cout<<"pos cam "<<myLoader->getCamPosX()<<" "<<myLoader->getCamPosY()<<" "<<myLoader->getCamPosZ()<<endl ;
//cout<<"target cam "<<myLoader->getCamTargetX()<<" "<<myLoader->getCamTargetY()<<" "<<myLoader->getCamTargetZ()<<endl ;



glutInit (&amp;argc, argv) ;
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH) ;
glutInitWindowSize (640, 480) ;
glutInitWindowPosition (250,250) ;
glutCreateWindow (argv [0]) ;
glewInit();

glEnable( GL_DEPTH_TEST );
glClearColor(0, 0, 1, 0);

myLoader->buildBOs();
myLoader->loadTextures() ;
myLoader->lighting() ;

glutReshapeFunc (reshape) ;
glutKeyboardFunc (keyboard) ;
glutDisplayFunc (display) ;
glutIdleFunc(display);

glutMainLoop () ;
return 0 ;
}

Relic
01-30-2006, 07:04 AM
You have not called glNormalPointer after binding it.

You're confused. The following array has nothing to to with the indices of glDrawElements:

glEnableClientState (GL_INDEX_ARRAY);
glBindBuffer( GL_ARRAY_BUFFER, myLoader->myObjects[i].indexBufferName );
glIndexPointer (GL_SHORT, 0, (char *) NULL );

This enables and sets the color index and does nothing in RGB color rendering pixelformats except setting state and wasting time.

What indexed vertex array rendering with DrawElement needs is a GL_ELEMENT_ARRAY_BUFFER (you have set that up) and a decent byte offset in the DrawElements call.

Read the spec examples:
http://oss.sgi.com/projects/ogl-sample/registry/ARB/vertex_buffer_object.txt

airseb
02-02-2006, 03:15 AM
thanks i'll try it, but can you tell me what is a "mapped buffer object" ?

Relic
02-02-2006, 03:44 AM
"Mapping" is the general computer term used if some data/address/port etc. not otherwise directly accessible is mapped into a memory region which _can_ be accessed.
On motherboards for example the Memory Management Unit (MMU) maps virtual adress space (e.g. 32 bit = 4 GB) to available physical memory (e.g. 1GB system RAM) by swapping in and out small memory blocks (with help of the OS).

In context of vertex buffer objects, the memory management is solely left to the OpenGL implementation. If you generate a buffer with a specific size but no data, you can call glMapBuffer to get a memory pointer from the OpenGL implementation which points to a user mode accessible virtual address so that you can copy data there. Unmap the object again and OpenGL does whatever it needs to manage the new data.
Those mapping calls are often called lock and unlock in various APIs.

If you do this a lot, the vertex buffer is basically a stream buffer.
Map and unmap is not necessary if the vertex buffer is static and you fill it at creation time.

airseb
02-03-2006, 02:22 AM
thanks, otherwise i have add glNormalPointer and removed glIndexPointer (i believed it was something else that it is really), i have put GL_ELEMENT_ARRAY_BUFFER in all glBindBuffer except for vertices(because it crashes when i do it), and with glDrawElement i have an empty window, do you see what's wrong ?

Relic
02-03-2006, 06:27 AM
have put GL_ELEMENT_ARRAY_BUFFER in all glBindBuffer except for vertices(because it crashes when i do it) You lost me. :confused:
Sorry, no new source, no better advice.

songho
02-03-2006, 08:24 AM
airseb,
Because of bad implementation on driver side, it may be crashed if you define wrong "target" for vertex arrays. For example, GL_ARRAY_BUFFER_ARB for index array.

VBO Spec says that the driver silently ignores the incorrect target param, but it does not in my experience.

This is my note for VBO.
VBO (http://www.songho.ca/opengl/gl_vbo.html)
I am not sure it can help you. Regards.
==song==