There is a bug with "DrawArrays": When an application first uses DrawArrays and then switch to DrawElements or Begin/ArrayElement/End nothing is drawn for some frames - may be until the VB overflows...? I have attached a small test program: It starts with "DrawArrays". Hit ´1´ to switch to DrawElements, nothing is drawn for 1 frame (hit arrow keys for next frame). Now switch back to "DrawArrays" with ´0´, and switch to "ArrayElement" with ´2´: nothing is drawn for a couple of frames... Bug found in mesa_3_2_dev branch, I did not test 3.3... With GLX drivers it is even worse since clientside DrawElements gets translated to serverside DrawArrays too... Andree
/* Keys: * ===== * - Arrow keys to rotate * - 'I' and 'i' zoom in and out * * - '0' = DrawArrays * - '1' = DrawElements * - '2' = ArrayElements */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <string.h> #include <math.h> #include "GL/glut.h" static GLfloat xrot; static GLfloat yrot; static GLfloat dist = -10; static GLint state = 0; static GLboolean doubleBuffer = GL_TRUE; static GLdouble plane[4] = {1.0, 0.0, -1.0, 0.0}; static GLuint surf1; GLfloat vertexarray[][3] = {{1,1,1}, {1,-1,1}, {-1,1,1}, {-1,1,1}, {1,-1,1}, {-1 ,-1,1}}; GLuint drawelementarray[] = {0,1,2,3,4,5 }; static void draw_surface( int with_state ) { switch(with_state) { case 2: { int i; glBegin(GL_TRIANGLES); for(i=0;i<6;i++) { glArrayElement(drawelementarray[i]); } glEnd(); } puts("glArrayElement"); break; case 1: glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, drawelementarray); puts("glDrawElements"); break; case 0: glDrawArrays(GL_TRIANGLES,0,6); puts("glDrawArrays"); break; } } static void Display(void) { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); draw_surface( state ); glFlush(); if (doubleBuffer) glutSwapBuffers(); } /* KW: only do this when necessary, so CVA can re-use results. */ static void set_matrix( void ) { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef( 0.0, 0.0, dist ); glRotatef( yrot, 0.0, 1.0, 0.0 ); glRotatef( xrot, 1.0, 0.0, 0.0 ); } static void InitMaterials(void) { static float ambient[] = {0.1, 0.1, 0.1, 1.0}; static float diffuse[] = {0.5, 1.0, 1.0, 1.0}; static float position0[] = {0.0, 0.0, 20.0, 0.0}; static float position1[] = {0.0, 0.0, -20.0, 0.0}; static float front_mat_shininess[] = {60.0}; static float front_mat_specular[] = {0.2, 0.2, 0.2, 1.0}; static float front_mat_diffuse[] = {0.5, 0.28, 0.38, 1.0}; /* static float back_mat_shininess[] = {60.0}; static float back_mat_specular[] = {0.5, 0.5, 0.2, 1.0}; static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0}; */ static float lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0}; static float lmodel_twoside[] = {GL_FALSE}; glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); glLightfv(GL_LIGHT0, GL_POSITION, position0); glEnable(GL_LIGHT0); glLightfv(GL_LIGHT1, GL_AMBIENT, ambient); glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse); glLightfv(GL_LIGHT1, GL_POSITION, position1); glEnable(GL_LIGHT1); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside); glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_mat_shininess); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_mat_specular); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, front_mat_diffuse); } static void Init(int argc, char *argv[]) { GLfloat fogColor[4] = {0.5,1.0,0.5,1.0}; glClearColor(0.0, 0.5, 0.0, 0.0); glEnable( GL_DEPTH_TEST ); glEnableClientState( GL_VERTEX_ARRAY ); glEnable(GL_TEXTURE_2D); glVertexPointer(3, GL_FLOAT, 0, vertexarray); InitMaterials(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum( -1.0, 1.0, -1.0, 1.0, 5, 25 ); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glClipPlane(GL_CLIP_PLANE0, plane); set_matrix(); } static void Reshape(int width, int height) { glViewport(0, 0, (GLint)width, (GLint)height); } static void Key( unsigned char key, int x, int y ) { (void) x; (void) y; switch (key) { case 27: exit(0); case 'i': dist += .25; set_matrix(); glutPostRedisplay(); break; case 'I': dist -= .25; set_matrix(); glutPostRedisplay(); break; case '0': state = 0; printf("state: %d\n", state); glutPostRedisplay(); break; case '1': state = 1; printf("state: %d\n", state); glutPostRedisplay(); break; case '2': state = 2; printf("state: %d\n", state); glutPostRedisplay(); break; } } static void SpecialKey( int key, int x, int y ) { (void) x; (void) y; switch (key) { case GLUT_KEY_LEFT: yrot -= 15.0; break; case GLUT_KEY_RIGHT: yrot += 15.0; break; case GLUT_KEY_UP: xrot += 15.0; break; case GLUT_KEY_DOWN: xrot -= 15.0; break; default: return; } set_matrix(); glutPostRedisplay(); } int main(int argc, char **argv) { GLenum type; glutInitWindowPosition(0, 0); glutInitWindowSize(400, 400); type = GLUT_DEPTH; type |= GLUT_RGB; type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE; glutInitDisplayMode(type); if (glutCreateWindow("ab_test") <= 0) { exit(0); } Init(argc, argv); glutReshapeFunc(Reshape); glutKeyboardFunc(Key); glutSpecialFunc(SpecialKey); glutDisplayFunc(Display); glutMainLoop(); return 0; }