static void * lp_setup_map_vertices(struct vbuf_render *vbr) { struct lp_setup_context *setup = lp_setup_context(vbr); return setup->vertex_buffer; }
static void lp_setup_set_primitive(struct vbuf_render *vbr, unsigned prim) { lp_setup_context(vbr)->prim = prim; }
/** * This function is hit when the draw module is working in pass-through mode. * It's up to us to convert the vertex array into point/line/tri prims. */ static void lp_setup_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) { struct lp_setup_context *setup = lp_setup_context(vbr); const unsigned stride = setup->vertex_info->size * sizeof(float); const void *vertex_buffer = (void *) get_vert(setup->vertex_buffer, start, stride); const boolean flatshade_first = setup->flatshade_first; unsigned i; if (!lp_setup_update_state(setup, TRUE)) return; switch (setup->prim) { case PIPE_PRIM_POINTS: for (i = 0; i < nr; i++) { setup->point( setup, get_vert(vertex_buffer, i-0, stride) ); } break; case PIPE_PRIM_LINES: for (i = 1; i < nr; i += 2) { setup->line( setup, get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride) ); } break; case PIPE_PRIM_LINE_STRIP: for (i = 1; i < nr; i ++) { setup->line( setup, get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride) ); } break; case PIPE_PRIM_LINE_LOOP: for (i = 1; i < nr; i ++) { setup->line( setup, get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride) ); } if (nr) { setup->line( setup, get_vert(vertex_buffer, nr-1, stride), get_vert(vertex_buffer, 0, stride) ); } break; case PIPE_PRIM_TRIANGLES: for (i = 2; i < nr; i += 3) { setup->triangle( setup, get_vert(vertex_buffer, i-2, stride), get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride) ); } break; case PIPE_PRIM_TRIANGLE_STRIP: if (flatshade_first) { for (i = 2; i < nr; i++) { /* emit first triangle vertex as first triangle vertex */ setup->triangle( setup, get_vert(vertex_buffer, i-2, stride), get_vert(vertex_buffer, i+(i&1)-1, stride), get_vert(vertex_buffer, i-(i&1), stride) ); } } else { for (i = 2; i < nr; i++) { /* emit last triangle vertex as last triangle vertex */ setup->triangle( setup, get_vert(vertex_buffer, i+(i&1)-2, stride), get_vert(vertex_buffer, i-(i&1)-1, stride), get_vert(vertex_buffer, i-0, stride) ); } } break; case PIPE_PRIM_TRIANGLE_FAN: if (flatshade_first) { for (i = 2; i < nr; i += 1) { /* emit first non-spoke vertex as first vertex */ setup->triangle( setup, get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride), get_vert(vertex_buffer, 0, stride) ); } } else { for (i = 2; i < nr; i += 1) { /* emit last non-spoke vertex as last vertex */ setup->triangle( setup, get_vert(vertex_buffer, 0, stride), get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride) ); } } break; case PIPE_PRIM_QUADS: /* GL quads don't follow provoking vertex convention */ if (flatshade_first) { /* emit last quad vertex as first triangle vertex */ for (i = 3; i < nr; i += 4) { setup->triangle( setup, get_vert(vertex_buffer, i-0, stride), get_vert(vertex_buffer, i-3, stride), get_vert(vertex_buffer, i-2, stride) ); setup->triangle( setup, get_vert(vertex_buffer, i-0, stride), get_vert(vertex_buffer, i-2, stride), get_vert(vertex_buffer, i-1, stride) ); } } else { /* emit last quad vertex as last triangle vertex */ for (i = 3; i < nr; i += 4) { setup->triangle( setup, get_vert(vertex_buffer, i-3, stride), get_vert(vertex_buffer, i-2, stride), get_vert(vertex_buffer, i-0, stride) ); setup->triangle( setup, get_vert(vertex_buffer, i-2, stride), get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride) ); } } break; case PIPE_PRIM_QUAD_STRIP: /* GL quad strips don't follow provoking vertex convention */ if (flatshade_first) { /* emit last quad vertex as first triangle vertex */ for (i = 3; i < nr; i += 2) { setup->triangle( setup, get_vert(vertex_buffer, i-0, stride), get_vert(vertex_buffer, i-3, stride), get_vert(vertex_buffer, i-2, stride) ); setup->triangle( setup, get_vert(vertex_buffer, i-0, stride), get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-3, stride) ); } } else { /* emit last quad vertex as last triangle vertex */ for (i = 3; i < nr; i += 2) { setup->triangle( setup, get_vert(vertex_buffer, i-3, stride), get_vert(vertex_buffer, i-2, stride), get_vert(vertex_buffer, i-0, stride) ); setup->triangle( setup, get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-3, stride), get_vert(vertex_buffer, i-0, stride) ); } } break; case PIPE_PRIM_POLYGON: /* Almost same as tri fan but the _first_ vertex specifies the flat * shading color. */ if (flatshade_first) { /* emit first polygon vertex as first triangle vertex */ for (i = 2; i < nr; i += 1) { setup->triangle( setup, get_vert(vertex_buffer, 0, stride), get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride) ); } } else { /* emit first polygon vertex as last triangle vertex */ for (i = 2; i < nr; i += 1) { setup->triangle( setup, get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride), get_vert(vertex_buffer, 0, stride) ); } } break; default: assert(0); } }
static boolean lp_setup_set_primitive(struct vbuf_render *vbr, unsigned prim) { lp_setup_context(vbr)->prim = prim; return TRUE; }