diff options
-rw-r--r-- | ground.c | 50 | ||||
-rw-r--r-- | rings.c | 48 |
2 files changed, 39 insertions, 59 deletions
@@ -41,6 +41,7 @@ static const int ground_size = 256; static GLuint ground_obj; static int elements_offset; +static int num_ground_elements; extern int no_multi_draw_arrays; extern GLUvec4 eye_world; @@ -68,10 +69,6 @@ install_ground_transform(void) void draw_ground(void) { - GLvoid *indices[ground_size]; - GLsizei count[ground_size]; - int v; - if (ground_prog == 0) return; @@ -85,29 +82,10 @@ draw_ground(void) glEnable(GL_TEXTURE_2D); glBindVertexArray(ground_obj); - - for (v = 0; v < ground_size - 1; v++) { - indices[v] = (void *)(uintptr_t)(elements_offset + - v * sizeof(uint32_t) * 2 * - ground_size); - count[v] = 2 * ground_size; - } - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, ground_vbo); - if (GLEW_EXT_multi_draw_arrays && !no_multi_draw_arrays) { - glMultiDrawElements(GL_TRIANGLE_STRIP, - count, - GL_UNSIGNED_INT, - (const GLvoid **)indices, - ground_size - 1); - } else { - for (v = 0; v < ground_size - 1; v++) { - glDrawElements(GL_TRIANGLE_STRIP, - ground_size * 2, - GL_UNSIGNED_INT, - indices[v]); - } - } + glDrawElements(GL_TRIANGLE_STRIP, num_ground_elements, + GL_UNSIGNED_INT, + (void *)(uintptr_t)elements_offset); glDisable(GL_TEXTURE_2D); } @@ -128,8 +106,8 @@ setup_ground(void) elements_offset = pos_offset + sizeof(float) * ground_size * ground_size * 3; - vbo_size = elements_offset + - 2 * sizeof(uint32_t) * (ground_size - 1) * ground_size; + num_ground_elements = (2 * ground_size + 1) * (ground_size - 1); + vbo_size = elements_offset + num_ground_elements * sizeof(uint32_t); glGenBuffers(1, &ground_vbo); glBindBuffer(GL_ARRAY_BUFFER_ARB, ground_vbo); @@ -152,10 +130,22 @@ setup_ground(void) uint32_t *next_element = elements; for (y = 0; y < ground_size - 1; y++) { for (x = 0; x < ground_size; x++) { - *next_element++ = (y + 1) * ground_size + x; - *next_element++ = y * ground_size + x; + int y0 = y * ground_size; + int y1 = (y + 1) * ground_size; + + if (!(y & 1)) { + *next_element++ = y1 + x; + *next_element++ = y0 + x; + } else { + *next_element++ = y1 + ground_size - 1 - x; + *next_element++ = y0 + ground_size - 1 - x; + } } + *next_element = *(next_element - 1); + next_element++; } + assert((next_element - (uint32_t *)(base + elements_offset)) == + num_ground_elements); glUnmapBuffer(GL_ARRAY_BUFFER_ARB); @@ -65,30 +65,10 @@ install_transform(int instance) void do_ring_drawelements(void) { - GLvoid *indices[ring.num_verts]; - GLsizei count[ring.num_verts]; - int v; - - for (v = 0; v < ring.num_verts; v++) { - indices[v] = (void *)(uintptr_t)(ring.elements_offset + - ring.elements_vert_stride * v); - count[v] = ring.num_steps * 2 + 2; - } - - if (GLEW_EXT_multi_draw_arrays && !no_multi_draw_arrays) { - glMultiDrawElements(GL_TRIANGLE_STRIP, - count, - GL_UNSIGNED_INT, - (const GLvoid **)indices, - ring.num_verts); - } else { - for (v = 0; v < ring.num_verts; v++) { - glDrawElements(GL_TRIANGLE_STRIP, - ring.num_steps * 2 + 2, - GL_UNSIGNED_INT, - indices[v]); - } - } + glDrawElements(GL_TRIANGLE_STRIP, + ring.num_verts * (ring.num_steps * 2 + 2), + GL_UNSIGNED_INT, + (void *)(uintptr_t)ring.elements_offset); } void @@ -434,17 +414,27 @@ revolve(const float *verts, unsigned int num_verts, } } - /* Calculate the element data (indices). We'll emit num_verts strips - * going around the revolved object. + /* Calculate the element data (indices). We emit strips going + * around the ring (steps), where at the end of each strip we + * dupe the vert so we can keep the strip going back the other + * way without restarting the primitives. */ i = 0; for (v = 0; v < num_verts; v++) { + int v0 = v; int v1 = (v + 1) % num_verts; for (s = 0; s <= steps; s++) { - elements[i++] = num_verts * s + v1; - elements[i++] = num_verts * s + v; + if (!(v & 1)) { + elements[i++] = num_verts * s + v1; + elements[i++] = num_verts * s + v0; + } else { + elements[i++] = num_verts * (s + 1) - 1 - v1; + elements[i++] = num_verts * (s + 1) - 1 - v0; + } } + elements[i] = elements[i - 1]; + i++; } glBindVertexArray(ring.array_obj); @@ -503,7 +493,7 @@ setup_rings(void) ring.tangent_offset = ring.norm_offset + 3 * 4 * sv; ring.texcoord_offset = ring.tangent_offset + 3 * 4 * sv; ring.elements_offset = ring.texcoord_offset + 2 * 4 * sv; - ring.elements_vert_stride = (num_steps + 1) * 2 * 4; + ring.elements_vert_stride = ((num_steps + 1) * 2 + 1) * 4; size = ring.elements_offset + ring.elements_vert_stride * ring.num_verts; |