Jump to content

  • Log In with Google      Sign In   
  • Create Account


problem with buffer objects and glDrawArray


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
7 replies to this topic

#1 TheSeb   Members   -  Reputation: 144

Like
0Likes
Like

Posted 30 January 2006 - 01:17 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, &myLoader->myObjects[i].vertexBufferName );
				
		glBindBuffer( GL_ARRAY_BUFFER, myLoader->myObjects[i].vertexBufferName );

		glBufferData( GL_ARRAY_BUFFER, sizeof(float)*3*myLoader->myObjects[i].nbVertices, &myLoader->myObjects[i].myVertices, GL_STATIC_DRAW );
		
		glGenBuffers(1, &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, &myLoader->myObjects[i].myIndices, GL_STATIC_DRAW );

		glGenBuffers(1, &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, &myLoader->myObjects[i].myMapping, GL_STATIC_DRAW_ARB );
	
		glGenBuffers(1, &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, &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, &(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 (&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 ;
}




Sponsor:

#2 songho   Members   -  Reputation: 268

Like
0Likes
Like

Posted 30 January 2006 - 03:41 AM

Are you using same vertex arrays for glDrawArrays() and glDrawElements() ?

They cannot be same because glDrawElements() allows hopping around arrays with indices, but glDrawArrays() does not.

You have to repeat the shared vertices once per face with glDrawArrays().


#3 TheSeb   Members   -  Reputation: 144

Like
0Likes
Like

Posted 02 February 2006 - 12:15 AM

Hi,
I would try with both, what is the best for performances ?
i have added glNormalPointer in the display function but it still doesn't work. Do you have an idea ?

#4 TheSeb   Members   -  Reputation: 144

Like
0Likes
Like

Posted 02 February 2006 - 11:08 PM

up

#5 Enigma   Members   -  Reputation: 1402

Like
0Likes
Like

Posted 03 February 2006 - 12:48 AM

void  loader3ds::buildBOs()
{
for (i=0 ; i<=myLoader->getCounterObj() ; i++)
I really hope that you've cut this down for the sake of posting or incorrectly copied it. You don't really have a global/member loop variable, do you?
glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short int)*myLoader->myObjects[i].nbVertices, &myLoader->myObjects[i].myIndices, GL_STATIC_DRAW );
Presumably that first should be nbIndices or equivalent, although since you're clearly using C++ I would strongly recommend using std::vector instead of doing manual memory management. Strongly recommend it.
glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
glMapBuffer is used for updating the contets of a buffer. It maps the buffer into application memory so that it can be written to. You should not be using it here. When mapped the buffer must be unmapped before being used as a rendering source.
glEnableClientState (GL_INDEX_ARRAY);
This enables the colour index array for use in indexed colour modes, not the element index array. Remove this line.
glBindBuffer( GL_ARRAY_BUFFER, myLoader->myObjects[i].indexBufferName );
glIndexPointer (GL_SHORT, 0, (char *) NULL );
You generated it as an element index buffer, now you're trying to use it as a colour index buffer. Replace with:
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, myLoader->myObjects[i].indexBufferName );
glBindBuffer( GL_ARRAY_BUFFER, myLoader->myObjects[i].normalsBufferName );
As you noted, you will need a glNormalPointer call too.
//glDrawElements (GL_TRIANGLES, (myLoader->myObjects[i].nbPoly*3), GL_UNSIGNED_SHORT, &(myLoader->myObjects[i].myIndices[0][0]));
Should be:
glDrawElements (GL_TRIANGLES, (myLoader->myObjects[i].nbPoly*3), GL_UNSIGNED_SHORT, static_cast< void * >(0));
to use the GL_ELEMENT_ARRAY_BUFFER.
glDrawArrays( GL_TRIANGLES, 0, myLoader->myObjects[i].nbVertices);
Don't use glDrawArrays - you have indices.

Σnigma

#6 TheSeb   Members   -  Reputation: 144

Like
0Likes
Like

Posted 03 February 2006 - 03:00 AM

Hi,
Thanks for your answer !
About it :

for (i=0 ; i<=myLoader->getCounterObj() ; i++)

i use it to count the number of models which i have in the scene. I shouldn't do like this ? if no, how ?

#7 Enigma   Members   -  Reputation: 1402

Like
0Likes
Like

Posted 03 February 2006 - 03:06 AM

I was commenting on the fact that you don't have a local definition of i, suggesting that you must have a global or member variable named i. I would have expected to see:

for (int i = 0; i <= myLoader->getCounterObj(); i++)

(and having just noticed it, did you really mean <= and not just <?)

At any rate, a better encapsulation would probably be just:

myLoader->buildBOs();.

and delegate the work to the object that owns the various variables.

Σnigma

#8 TheSeb   Members   -  Reputation: 144

Like
0Likes
Like

Posted 03 February 2006 - 03:20 AM

Quote:
Original post by Enigma
I was commenting on the fact that you don't have a local definition of i, suggesting that you must have a global or member variable named i. I would have expected to see:

for (int i = 0; i <= myLoader->getCounterObj(); i++)

(and having just noticed it, did you really mean <= and not just <?)

At any rate, a better encapsulation would probably be just:

myLoader->buildBOs();.

and delegate the work to the object that owns the various variables.

Σnigma


ok thanks for your help.
I do " <= " because getCounterObj() start at 0




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS