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

Reply via email to