summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2010-10-13 22:55:14 -0700
committerEric Anholt <eric@anholt.net>2010-10-13 23:50:06 -0700
commit68fe4c3e53835d511ed63f573e4da510fabe1fe8 (patch)
treecb80400a98f0b985e4522156c4418089d82ac625
parentadd362dbc3456150c5be7dcc0c6a0337af73c5e3 (diff)
Switch from MultiDrawElements to the extra-vert-at-the-end stips hack.HEADmaster
-rw-r--r--ground.c50
-rw-r--r--rings.c48
2 files changed, 39 insertions, 59 deletions
diff --git a/ground.c b/ground.c
index 4979a36..55a369f 100644
--- a/ground.c
+++ b/ground.c
@@ -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);
diff --git a/rings.c b/rings.c
index 83b9120..7e1935a 100644
--- a/rings.c
+++ b/rings.c
@@ -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;