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