+
+static void destroy_quadmesh(QuadMesh *m)
+{
+ glDeleteBuffers(1, &m->vbo_v);
+ glDeleteBuffers(1, &m->vbo_uv);
+ glDeleteBuffers(1, &m->ibo);
+
+ delete [] m->v;
+ delete [] m->uv;
+ delete [] m->idx;
+}
+
+static void draw_quadmesh(const QuadMesh *m, unsigned int prim)
+{
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ glBindBuffer(GL_ARRAY_BUFFER, m->vbo_v);
+ glVertexPointer(3, GL_FLOAT, 0, 0);
+
+ glBindBuffer(GL_ARRAY_BUFFER, m->vbo_uv);
+ glTexCoordPointer(2, GL_FLOAT, 0, 0);
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->ibo);
+ glDrawElements(prim, m->num_idx, GL_UNSIGNED_SHORT, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+}
+
+static void gen_quad_plane(QuadMesh *m, float width, float height, int usub, int vsub)
+{
+ Vec3 *vptr;
+ Vec2 *uvptr;
+ uint16_t *iptr;
+
+ if(usub < 1) usub = 1;
+ if(vsub < 1) vsub = 1;
+
+ int uverts = usub + 1;
+ int vverts = vsub + 1;
+ m->num_verts = uverts * vverts;
+ m->num_quads = usub * vsub;
+ m->num_idx = m->num_quads * 4;
+
+ vptr = m->v = new Vec3[m->num_verts];
+ uvptr = m->uv = new Vec2[m->num_verts];
+ iptr = m->idx = new uint16_t[m->num_idx];
+
+ float du = 1.0f / (float)usub;
+ float dv = 1.0f / (float)vsub;
+
+ float u = 0.0f;
+ for(int i=0; i<uverts; i++) {
+ float x = (u - 0.5f) * width;
+ float v = 0.0f;
+ for(int j=0; j<vverts; j++) {
+ float y = (v - 0.5f) * height;
+
+ *vptr++ = Vec3(x, 0, y);
+ *uvptr++ = Vec2(u, v);
+
+ if(i < usub && j < vsub) {
+ int idx = i * vverts + j;
+
+ *iptr++ = idx;
+ *iptr++ = idx + vverts;
+ *iptr++ = idx + vverts + 1;
+ *iptr++ = idx + 1;
+ }
+
+ v += dv;
+ }
+ u += du;
+ }
+
+ glGenBuffers(1, &m->vbo_v);
+ glBindBuffer(GL_ARRAY_BUFFER, m->vbo_v);
+ glBufferData(GL_ARRAY_BUFFER, m->num_verts * 3 * sizeof(float), m->v, GL_STATIC_DRAW);
+
+ glGenBuffers(1, &m->vbo_uv);
+ glBindBuffer(GL_ARRAY_BUFFER, m->vbo_uv);
+ glBufferData(GL_ARRAY_BUFFER, m->num_verts * 2 * sizeof(float), m->uv, GL_STATIC_DRAW);
+
+ glGenBuffers(1, &m->ibo);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->ibo);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, m->num_idx * sizeof(uint16_t), m->idx, GL_STATIC_DRAW);
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+}