diff options
author | Mike Erwin <significant.bit@gmail.com> | 2016-08-11 01:01:04 +0300 |
---|---|---|
committer | Mike Erwin <significant.bit@gmail.com> | 2016-08-11 01:01:04 +0300 |
commit | 4aadf7331e108e7257af07d01384ce67de5e0391 (patch) | |
tree | 8d43e958cfa3c9af71e9fa03aa34b35738c217d1 | |
parent | f537d96286654ba370ffdbfd7701a409d9e0c493 (diff) |
Gawain: tweak immediate mode API
Should be simpler to use now.
Made vertex format structure private. New immVertexFormat() function
clears and returns the format. Devs can start with add_attrib(format...)
and not have to clear it first.
immBindProgram automatically packs the vertex format if needed.
Updated 3D cursor drawing to use new API.
-rw-r--r-- | source/blender/editors/space_view3d/view3d_draw.c | 12 | ||||
-rw-r--r-- | source/blender/gpu/GPU_immediate.h | 4 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_immediate.c | 53 |
3 files changed, 40 insertions, 29 deletions
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 3903e4e1fe8..42780774e22 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -555,10 +555,9 @@ static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d) glLineWidth(1); - clear_VertexFormat(&immVertexFormat); - unsigned color = add_attrib(&immVertexFormat, "color", GL_UNSIGNED_BYTE, 3, NORMALIZE_INT_TO_FLOAT); - unsigned pos = add_attrib(&immVertexFormat, "pos", GL_FLOAT, 2, KEEP_FLOAT); - pack(&immVertexFormat); + VertexFormat* format = immVertexFormat(); + unsigned pos = add_attrib(format, "pos", GL_FLOAT, 2, KEEP_FLOAT); + unsigned color = add_attrib(format, "color", GL_UNSIGNED_BYTE, 3, NORMALIZE_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); @@ -582,9 +581,8 @@ static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d) immUnbindProgram(); - clear_VertexFormat(&immVertexFormat); - pos = add_attrib(&immVertexFormat, "pos", GL_FLOAT, 2, KEEP_FLOAT); - pack(&immVertexFormat); + clear_VertexFormat(format); + pos = add_attrib(format, "pos", GL_FLOAT, 2, KEEP_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); diff --git a/source/blender/gpu/GPU_immediate.h b/source/blender/gpu/GPU_immediate.h index 1373faa236b..0ee97349970 100644 --- a/source/blender/gpu/GPU_immediate.h +++ b/source/blender/gpu/GPU_immediate.h @@ -53,11 +53,13 @@ void pack(VertexFormat*); // unsigned attrib_idx(const VertexFormat*, const char* name); void bind_attrib_locations(const VertexFormat*, GLuint program); -extern PER_THREAD VertexFormat immVertexFormat; // so we don't have to copy or pass around +// --- immediate mode work-alike -------------------------------- void immInit(void); void immDestroy(void); +VertexFormat* immVertexFormat(void); // returns a cleared vertex format, ready for add_attrib + void immBindProgram(GLuint program); void immUnbindProgram(void); diff --git a/source/blender/gpu/intern/gpu_immediate.c b/source/blender/gpu/intern/gpu_immediate.c index 57f1cc53a67..628c8d1c30d 100644 --- a/source/blender/gpu/intern/gpu_immediate.c +++ b/source/blender/gpu/intern/gpu_immediate.c @@ -233,6 +233,8 @@ void get_attrib_locations(const VertexFormat* format, AttribBinding* binding, GL // --- immediate mode work-alike -------------------------------- typedef struct { + // TODO: organize this struct by frequency of change (run-time) + // current draw call GLubyte* buffer_data; unsigned buffer_offset; @@ -240,6 +242,8 @@ typedef struct { unsigned vertex_ct; GLenum primitive; + VertexFormat vertex_format; + // current vertex unsigned vertex_idx; GLubyte* vertex_data; @@ -259,7 +263,6 @@ typedef struct { static PER_THREAD bool initialized = false; static PER_THREAD Immediate imm; -PER_THREAD VertexFormat immVertexFormat; void immInit() { @@ -267,7 +270,6 @@ void immInit() assert(!initialized); #endif - clear_VertexFormat(&immVertexFormat); memset(&imm, 0, sizeof(Immediate)); glGenVertexArrays(1, &imm.vao_id); @@ -295,20 +297,29 @@ void immDestroy() assert(imm.primitive == GL_NONE); // make sure we're not between a Begin/End pair #endif - clear_VertexFormat(&immVertexFormat); + clear_VertexFormat(&imm.vertex_format); glDeleteVertexArrays(1, &imm.vao_id); glDeleteBuffers(1, &imm.vbo_id); initialized = false; } +VertexFormat* immVertexFormat() + { + clear_VertexFormat(&imm.vertex_format); + return &imm.vertex_format; + } + void immBindProgram(GLuint program) { #if TRUST_NO_ONE assert(imm.bound_program == 0); #endif + if (!imm.vertex_format.packed) + pack(&imm.vertex_format); + glUseProgram(program); - get_attrib_locations(&immVertexFormat, &imm.attrib_binding, program); + get_attrib_locations(&imm.vertex_format, &imm.attrib_binding, program); imm.bound_program = program; } @@ -360,7 +371,7 @@ void immBegin(GLenum primitive, unsigned vertex_ct) imm.attrib_value_bits = 0; // how many bytes do we need for this draw call? - const unsigned bytes_needed = vertex_buffer_size(&immVertexFormat, vertex_ct); + const unsigned bytes_needed = vertex_buffer_size(&imm.vertex_format, vertex_ct); #if TRUST_NO_ONE assert(bytes_needed <= IMM_BUFFER_SIZE); @@ -371,7 +382,7 @@ void immBegin(GLenum primitive, unsigned vertex_ct) // does the current buffer have enough room? const unsigned available_bytes = IMM_BUFFER_SIZE - imm.buffer_offset; // ensure vertex data is aligned - const unsigned pre_padding = padding(imm.buffer_offset, immVertexFormat.stride); // might waste a little space, but it's safe + const unsigned pre_padding = padding(imm.buffer_offset, imm.vertex_format.stride); // might waste a little space, but it's safe if ((bytes_needed + pre_padding) <= available_bytes) imm.buffer_offset += pre_padding; else @@ -445,11 +456,11 @@ void immEnd() imm.prev_enabled_attrib_bits = imm.attrib_binding.enabled_bits; } - const unsigned stride = immVertexFormat.stride; + const unsigned stride = imm.vertex_format.stride; - for (unsigned a_idx = 0; a_idx < immVertexFormat.attrib_ct; ++a_idx) + for (unsigned a_idx = 0; a_idx < imm.vertex_format.attrib_ct; ++a_idx) { - const Attrib* a = immVertexFormat.attribs + a_idx; + const Attrib* a = imm.vertex_format.attribs + a_idx; const unsigned offset = imm.buffer_offset + a->offset; const GLvoid* pointer = (const GLubyte*)0 + offset; @@ -500,10 +511,10 @@ static void setAttribValueBit(unsigned attrib_id) void immAttrib1f(unsigned attrib_id, float x) { - Attrib* attrib = immVertexFormat.attribs + attrib_id; + Attrib* attrib = imm.vertex_format.attribs + attrib_id; #if TRUST_NO_ONE - assert(attrib_id < immVertexFormat.attrib_ct); + assert(attrib_id < imm.vertex_format.attrib_ct); assert(attrib->comp_type == GL_FLOAT); assert(attrib->comp_ct == 1); assert(imm.vertex_idx < imm.vertex_ct); @@ -520,10 +531,10 @@ void immAttrib1f(unsigned attrib_id, float x) void immAttrib2f(unsigned attrib_id, float x, float y) { - Attrib* attrib = immVertexFormat.attribs + attrib_id; + Attrib* attrib = imm.vertex_format.attribs + attrib_id; #if TRUST_NO_ONE - assert(attrib_id < immVertexFormat.attrib_ct); + assert(attrib_id < imm.vertex_format.attrib_ct); assert(attrib->comp_type == GL_FLOAT); assert(attrib->comp_ct == 2); assert(imm.vertex_idx < imm.vertex_ct); @@ -541,10 +552,10 @@ void immAttrib2f(unsigned attrib_id, float x, float y) void immAttrib3f(unsigned attrib_id, float x, float y, float z) { - Attrib* attrib = immVertexFormat.attribs + attrib_id; + Attrib* attrib = imm.vertex_format.attribs + attrib_id; #if TRUST_NO_ONE - assert(attrib_id < immVertexFormat.attrib_ct); + assert(attrib_id < imm.vertex_format.attrib_ct); assert(attrib->comp_type == GL_FLOAT); assert(attrib->comp_ct == 3); assert(imm.vertex_idx < imm.vertex_ct); @@ -563,10 +574,10 @@ void immAttrib3f(unsigned attrib_id, float x, float y, float z) void immAttrib3ub(unsigned attrib_id, unsigned char r, unsigned char g, unsigned char b) { - Attrib* attrib = immVertexFormat.attribs + attrib_id; + Attrib* attrib = imm.vertex_format.attribs + attrib_id; #if TRUST_NO_ONE - assert(attrib_id < immVertexFormat.attrib_ct); + assert(attrib_id < imm.vertex_format.attrib_ct); assert(attrib->comp_type == GL_UNSIGNED_BYTE); assert(attrib->comp_ct == 3); assert(imm.vertex_idx < imm.vertex_ct); @@ -585,10 +596,10 @@ void immAttrib3ub(unsigned attrib_id, unsigned char r, unsigned char g, unsigned void immAttrib4ub(unsigned attrib_id, unsigned char r, unsigned char g, unsigned char b, unsigned char a) { - Attrib* attrib = immVertexFormat.attribs + attrib_id; + Attrib* attrib = imm.vertex_format.attribs + attrib_id; #if TRUST_NO_ONE - assert(attrib_id < immVertexFormat.attrib_ct); + assert(attrib_id < imm.vertex_format.attrib_ct); assert(attrib->comp_type == GL_UNSIGNED_BYTE); assert(attrib->comp_ct == 4); assert(imm.vertex_idx < imm.vertex_ct); @@ -612,14 +623,14 @@ void immEndVertex() assert(imm.primitive != GL_NONE); // make sure we're between a Begin/End pair // have all attribs been assigned values? - const unsigned short all_bits = ~(0xFFFFU << immVertexFormat.attrib_ct); + const unsigned short all_bits = ~(0xFFFFU << imm.vertex_format.attrib_ct); assert(imm.attrib_value_bits == all_bits); assert(imm.vertex_idx < imm.vertex_ct); #endif imm.vertex_idx++; - imm.vertex_data += immVertexFormat.stride; + imm.vertex_data += imm.vertex_format.stride; imm.attrib_value_bits = 0; } |