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;
}