コード例 #1
0
/**
 * Test glDrawElements() with glPrimitiveRestartIndexNV().
 */
static bool
test_draw_by_index(VBO_CFG vbo_cfg, bool one_by_one, GLenum primMode, GLenum indexType)
{
#define NUM_VERTS 48
#define NUM_ELEMS (NUM_VERTS * 5 / 4)
   GLfloat verts[NUM_VERTS+2][2];
   GLubyte indices[sizeof(GLuint) * NUM_ELEMS];
   GLfloat x, dx;
   GLuint restart_index;
   GLuint num_elems;
   bool pass = true;
   const char *typeStr = NULL, *primStr = NULL;
   GLuint vbo1, vbo2;
   bool create_vbo1 = false;
   bool create_vbo2 = false;
   uintptr_t index_offset = 0;
   uintptr_t vbo_data_size = sizeof(verts) + sizeof(indices);
   GLuint i, j;

   if ((vbo_cfg != DISABLE_VBO) && (vbo_cfg != VBO_INDEX_ONLY)) {
      create_vbo1 = true;
   }

   if ((vbo_cfg == VBO_INDEX_ONLY) || (vbo_cfg == VBO_SEPARATE_VERTEX_AND_INDEX)) {
      create_vbo2 = true;
   }

   if ((vbo_cfg == DISABLE_VBO) || (vbo_cfg == VBO_VERTEX_ONLY)) {
      index_offset = (uintptr_t) indices;
   } else if (vbo_cfg == VBO_COMBINED_VERTEX_AND_INDEX) {
      index_offset = sizeof(verts);
   } else {
      index_offset = 0;
   }

   switch (indexType) {
   case GL_UNSIGNED_BYTE:
      restart_index = 255;
      typeStr = "GL_UNSIGNED_BYTE";
      break;
   case GL_UNSIGNED_SHORT:
      restart_index = 1000;
      typeStr = "GL_UNSIGNED_SHORT";
      break;
   case GL_UNSIGNED_INT:
      restart_index = 1000 * 1000;
      typeStr = "GL_UNSIGNED_INT";
      break;
   default:
      assert(0);
      restart_index = 0;
   }

   x = 0.0;
   dx = 20.0;

   if (primMode == GL_TRIANGLE_STRIP) {
      const GLfloat y = 0.5 * piglit_height - 10.0, dy = 20.0;
      for (i = 0; i < NUM_VERTS / 2; i++) {
         verts[i*2+0][0] = x;
         verts[i*2+0][1] = y;
         verts[i*2+1][0] = x;
         verts[i*2+1][1] = y + dy;
         x += dx;
      }

      /* setup elements to draw series of squares w/ tri strip */
      for (i = j = 0; i < NUM_VERTS; i++) {
         write_index_value(indices, indexType, j, i);
         j++;
         if (i > 0 && i % 4 == 3) {
            write_index_value(indices, indexType, j, restart_index);
            j++;
         }
      }

      num_elems = j;
      primStr = "GL_TRIANGLE_STRIP";
   }
   else {
      const GLfloat y = 0.5 * piglit_height;

      assert(primMode == GL_LINE_STRIP);

      glLineWidth(5.0);

      for (i = 0; i < NUM_VERTS; i++) {
         verts[i][0] = x;
         verts[i][1] = y;
         x += dx;
      }

      /* setup elements to draw series of disjoint lines w/ line strip */
      for (i = j = 0; i < NUM_VERTS / 2; i++) {
         write_index_value(indices, indexType, j, i);
         j++;
         if (i > 0 && i % 2 == 1) {
            write_index_value(indices, indexType, j, restart_index);
            j++;
         }
      }

      num_elems = j;
      primStr = "GL_LINE_STRIP";
   }

   assert(num_elems <= NUM_ELEMS);

   /* debug */
   if (0) {
      for (i = 0; i < num_elems; i++)
         printf("%2d: %d\n", i, read_index_value(indices, indexType, i));
   }

   piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);

   glClear(GL_COLOR_BUFFER_BIT);

   glColor4fv(green);

   if (create_vbo1) {
      glGenBuffers(1, &vbo1);
      glBindBuffer(GL_ARRAY_BUFFER, vbo1);
      glBufferData(GL_ARRAY_BUFFER, vbo_data_size, NULL, GL_STATIC_DRAW);
   }

   if (create_vbo2) {
      glGenBuffers(1, &vbo2);
      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo2);
      glBufferData(GL_ELEMENT_ARRAY_BUFFER, vbo_data_size, NULL, GL_STATIC_DRAW);
   } else {
      vbo2 = vbo1;
   }

   if (create_vbo1) {
      /* Load vertex data into VBO */
      glBindBuffer(GL_ARRAY_BUFFER, vbo1);
      glBufferSubData(GL_ARRAY_BUFFER,
                      0, sizeof(verts),
                      verts);
      glVertexPointer(2, GL_FLOAT, 0, (void *)0);
   } else {
      glVertexPointer(2, GL_FLOAT, 0, (void *)verts);
   }

   if ((vbo_cfg != DISABLE_VBO) && (vbo_cfg != VBO_VERTEX_ONLY)) {
      /* Load index data into VBO */
      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo2);
      glBufferSubData(GL_ELEMENT_ARRAY_BUFFER,
                      index_offset, type_array_size(indexType, num_elems),
                      indices);
   }

   glEnableClientState(GL_VERTEX_ARRAY);
   pass = piglit_check_gl_error(GL_NO_ERROR) && pass;

   enable_restart(restart_index);

   /* Draw */
   if (one_by_one) {
      do_ArrayElement(primMode, num_elems, indexType, indices);
   } else {
      glDrawElements(primMode, num_elems, indexType, (void*) index_offset);
   }

   disable_restart();

   glDisableClientState(GL_VERTEX_ARRAY);

   if (vbo_cfg != DISABLE_VBO) {
      glBindBuffer(GL_ARRAY_BUFFER, 0);
      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
   }

   if (create_vbo1) {
      glDeleteBuffers(1, &vbo1);
   }

   if (create_vbo2) {
      glDeleteBuffers(1, &vbo2);
   }

   if (!check_rendering()) {
      fprintf(stderr, "%s: failure drawing with %s(%s, %s), %s\n",
              TestName,
              one_by_one ? "glArrayElement" : "glDrawElements",
              primStr, typeStr,
              vbo_cfg_names[vbo_cfg]);
      pass = false;
   }

   piglit_present_results();

   return pass;
#undef NUM_VERTS
}
コード例 #2
0
ファイル: primitive-restart.c プロジェクト: blaztinn/piglit
/**
 * Test glDrawArrayss() with glPrimitiveRestartIndexNV().
 * We only test a line strip.
 */
static GLboolean
test_draw_arrays(VBO_CFG vbo_cfg)
{
#define NUM_VERTS 12
   GLfloat verts[NUM_VERTS+2][2];
   const GLfloat dx = 20.0;
   GLfloat x;
   GLuint restart_index;
   GLboolean pass = GL_TRUE;
   const char *primStr = "GL_LINE_STRIP";
   GLuint test;
   const GLenum primMode = GL_LINE_STRIP;
   GLuint vbo = 0;

   x = 0.0;

   /* setup vertices */
   {
      GLuint i;
      const GLfloat y = 0.5 * piglit_height;

      glLineWidth(5.0);

      for (i = 0; i < NUM_VERTS; i++) {
         verts[i][0] = x;
         verts[i][1] = y;
         x += dx;
      }
   }

   piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);

   glColor4fv(green);

   if ((vbo_cfg != DISABLE_VBO) && (vbo_cfg != VBO_INDEX_ONLY)) {
      glGenBuffers(1, &vbo);
      glBindBuffer(GL_ARRAY_BUFFER, vbo);
      glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
      glVertexPointer(2, GL_FLOAT, 0, (void *)0);
   } else {
      glVertexPointer(2, GL_FLOAT, 2*sizeof(GLfloat), verts);
   }

   glEnableClientState(GL_VERTEX_ARRAY);

   assert(glGetError()==0);

   /*
    * Render and do checks.
    * Try three different restart indexes at start, end, middle.
    */
   for (test = 0; test < 3 && pass; test++) {
      /* choose the restart index */
      if (test == 0)
         restart_index = 0;
      else if (test == 1)
         restart_index = NUM_VERTS - 1;
      else
         restart_index = NUM_VERTS / 2;

      /* draw */
      glClear(GL_COLOR_BUFFER_BIT);
      enable_restart(restart_index);
      glDrawArrays(primMode, 0, NUM_VERTS);
      disable_restart();

      /* check */
      {
         const GLfloat x0 = 0.0;
         const GLint iy = piglit_height / 2;
         GLint i;

         /* probe at midpoint of each line segment */
         for (i = 0; i < NUM_VERTS - 1 && pass; i++) {
            /* test midpoint of line to see if it was drawn */
            const float fx = x0 + 0.5 * dx + i * dx;
            const int ix = (int) fx;

            /* read pixel */
            if (restart_index == i || restart_index == i + 1) {
               /* pixel should NOT be drawn here */
               if (!piglit_probe_pixel_rgb(ix, iy, black)) {
                  if (0)
                     fprintf(stderr, "bad pixel drawn\n");
                  pass = GL_FALSE;
               }
            }
            else {
               /* pixel should be drawn here */
               if (!piglit_probe_pixel_rgb(ix, iy, green)) {
                  if (0)
                     fprintf(stderr, "bad pixel drawn\n");
                  pass = GL_FALSE;
               }
            }
         }
      }
   }

   piglit_present_results();

   if (vbo != 0) {
      glBindBuffer(GL_ARRAY_BUFFER, 0);
   }

   if (!pass) {
      fprintf(stderr, "%s: failure drawing with glDrawArrays(%s), "
              "restart index = %u\n",
              TestName, primStr, restart_index);
   }

   return pass;
}