work towards DeferredCommandDraw being universal, support for DeferredCommandDepthRange, rework of cirlce mesh (has a bug still), get_quad_element_buffer() now more general, as it should be with gl_any
This commit is contained in:
		| @@ -1,4 +1,3 @@ | |||||||
| #include "twn_util.h" |  | ||||||
| #include "twn_engine_context_c.h" | #include "twn_engine_context_c.h" | ||||||
| #include "twn_draw_c.h" | #include "twn_draw_c.h" | ||||||
| #include "twn_draw.h" | #include "twn_draw.h" | ||||||
| @@ -24,22 +23,15 @@ void draw_circle(Vec2 position, float radius, Color color) { | |||||||
|  |  | ||||||
|  |  | ||||||
| void create_circle_geometry(Vec2 position, | void create_circle_geometry(Vec2 position, | ||||||
|                             Color color, |  | ||||||
|                             float radius, |                             float radius, | ||||||
|                             size_t num_vertices, |                             size_t num_vertices, | ||||||
|                             SDL_Vertex vertices[], |                             Vec2 vertices[]) | ||||||
|                             int indices[]) |  | ||||||
| { | { | ||||||
|     /* the angle (in radians) to rotate by on each iteration */ |     /* the angle (in radians) to rotate by on each iteration */ | ||||||
|     float seg_rotation_angle = (360.0f / (float)num_vertices) * ((float)M_PI / 180); |     float seg_rotation_angle = (360.0f / (float)num_vertices) * ((float)M_PI / 180); | ||||||
|  |  | ||||||
|     vertices[0].position.x = (float)position.x; |     vertices[0].x = (float)position.x; | ||||||
|     vertices[0].position.y = (float)position.y; |     vertices[0].y = (float)position.y; | ||||||
|     vertices[0].color.r = color.r; |  | ||||||
|     vertices[0].color.g = color.g; |  | ||||||
|     vertices[0].color.b = color.b; |  | ||||||
|     vertices[0].color.a = color.a; |  | ||||||
|     vertices[0].tex_coord = (SDL_FPoint){ 0, 0 }; |  | ||||||
|  |  | ||||||
|     /* this point will rotate around the center */ |     /* this point will rotate around the center */ | ||||||
|     float start_x = 0.0f - radius; |     float start_x = 0.0f - radius; | ||||||
| @@ -48,34 +40,13 @@ void create_circle_geometry(Vec2 position, | |||||||
|     for (size_t i = 1; i < num_vertices + 1; ++i) { |     for (size_t i = 1; i < num_vertices + 1; ++i) { | ||||||
|         float final_seg_rotation_angle = (float)i * seg_rotation_angle; |         float final_seg_rotation_angle = (float)i * seg_rotation_angle; | ||||||
|  |  | ||||||
|         vertices[i].position.x = |         float c, s; | ||||||
|             cosf(final_seg_rotation_angle) * start_x - |         sincosf(final_seg_rotation_angle, &s, &c); | ||||||
|             sinf(final_seg_rotation_angle) * start_y; |  | ||||||
|         vertices[i].position.y = |  | ||||||
|             cosf(final_seg_rotation_angle) * start_y + |  | ||||||
|             sinf(final_seg_rotation_angle) * start_x; |  | ||||||
|  |  | ||||||
|         vertices[i].position.x += position.x; |         vertices[i].x = c * start_x - s * start_y; | ||||||
|         vertices[i].position.y += position.y; |         vertices[i].y = c * start_y + s * start_x; | ||||||
|  |  | ||||||
|         vertices[i].color.r = color.r; |         vertices[i].x += position.x; | ||||||
|         vertices[i].color.g = color.g; |         vertices[i].y += position.y; | ||||||
|         vertices[i].color.b = color.b; |  | ||||||
|         vertices[i].color.a = color.a; |  | ||||||
|  |  | ||||||
|         vertices[i].tex_coord = (SDL_FPoint){ 0, 0 }; |  | ||||||
|  |  | ||||||
|  |  | ||||||
|         size_t triangle_offset = 3 * (i - 1); |  | ||||||
|  |  | ||||||
|         /* center point index */ |  | ||||||
|         indices[triangle_offset] = 0; |  | ||||||
|         /* generated point index */ |  | ||||||
|         indices[triangle_offset + 1] = (int)i; |  | ||||||
|  |  | ||||||
|         size_t index = (i + 1) % num_vertices; |  | ||||||
|         if (index == 0) |  | ||||||
|             index = num_vertices; |  | ||||||
|         indices[triangle_offset + 2] = (int)index; |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -20,7 +20,10 @@ | |||||||
| extern Matrix4 camera_projection_matrix; | extern Matrix4 camera_projection_matrix; | ||||||
| extern Matrix4 camera_look_at_matrix; | extern Matrix4 camera_look_at_matrix; | ||||||
|  |  | ||||||
|  |  | ||||||
| #define QUAD_ELEMENT_BUFFER_LENGTH (65536 / 6) | #define QUAD_ELEMENT_BUFFER_LENGTH (65536 / 6) | ||||||
|  | #define CIRCLE_VERTICES_MAX 2048 | ||||||
|  | #define CIRCLE_ELEMENT_BUFFER_LENGTH (CIRCLE_VERTICES_MAX * 3) | ||||||
|  |  | ||||||
|  |  | ||||||
| typedef GLuint VertexBuffer; | typedef GLuint VertexBuffer; | ||||||
| @@ -129,11 +132,9 @@ void render_queue_clear(void); | |||||||
| /* fills two existing arrays with the geometry data of a circle */ | /* fills two existing arrays with the geometry data of a circle */ | ||||||
| /* the size of indices must be at least 3 times the number of vertices */ | /* the size of indices must be at least 3 times the number of vertices */ | ||||||
| void create_circle_geometry(Vec2 position, | void create_circle_geometry(Vec2 position, | ||||||
|                             Color color, |  | ||||||
|                             float radius, |                             float radius, | ||||||
|                             size_t num_vertices, |                             size_t num_vertices, | ||||||
|                             SDL_Vertex vertices[], |                             Vec2 vertices[]); | ||||||
|                             int indices[]); |  | ||||||
|  |  | ||||||
| struct QuadBatch { | struct QuadBatch { | ||||||
|     size_t size;             /* how many primitives are in current batch */ |     size_t size;             /* how many primitives are in current batch */ | ||||||
| @@ -191,6 +192,8 @@ void set_depth_range(double low, double high); | |||||||
|  |  | ||||||
| VertexBuffer get_quad_element_buffer(void); | VertexBuffer get_quad_element_buffer(void); | ||||||
|  |  | ||||||
|  | VertexBuffer get_circle_element_buffer(void); | ||||||
|  |  | ||||||
| void render_circle(const CirclePrimitive *circle); | void render_circle(const CirclePrimitive *circle); | ||||||
|  |  | ||||||
| void render_rectangle(const RectPrimitive *rectangle); | void render_rectangle(const RectPrimitive *rectangle); | ||||||
|   | |||||||
| @@ -96,13 +96,16 @@ typedef struct { | |||||||
|         Color color; |         Color color; | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     bool textured, texture_repeat; |     bool textured, texture_repeat, uses_gpu_key; | ||||||
|     TextureKey texture; |     TextureKey texture_key; | ||||||
|  |     GPUTexture gpu_texture; | ||||||
|  |  | ||||||
|     GLuint element_buffer; |     GLuint element_buffer; | ||||||
|     GLsizei element_count; |     GLsizei element_count; | ||||||
|     GLsizei range_start, range_end; |     GLsizei range_start, range_end; | ||||||
| } DeferredCommandDrawElements; |  | ||||||
|  |     double depth_range_low, depth_range_high; | ||||||
|  | } DeferredCommandDraw; | ||||||
|  |  | ||||||
|  |  | ||||||
| typedef struct { | typedef struct { | ||||||
| @@ -130,19 +133,26 @@ typedef struct { | |||||||
| } DeferredCommandUseTextureMode; | } DeferredCommandUseTextureMode; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | typedef struct { | ||||||
|  |     double low, high; | ||||||
|  | } DeferredCommandDepthRange; | ||||||
|  |  | ||||||
|  |  | ||||||
| typedef struct { | typedef struct { | ||||||
|     enum DeferredCommandType { |     enum DeferredCommandType { | ||||||
|         DEFERRED_COMMAND_TYPE_DRAW_ELEMENTS, |         DEFERRED_COMMAND_TYPE_DRAW, | ||||||
|         DEFERRED_COMMAND_TYPE_CLEAR, |         DEFERRED_COMMAND_TYPE_CLEAR, | ||||||
|         DEFERRED_COMMAND_TYPE_USE_PIPIELINE, |         DEFERRED_COMMAND_TYPE_USE_PIPIELINE, | ||||||
|         DEFERRED_COMMAND_TYPE_USE_TEXTURE_MODE, |         DEFERRED_COMMAND_TYPE_USE_TEXTURE_MODE, | ||||||
|  |         DEFERRED_COMMAND_TYPE_DEPTH_RANGE, | ||||||
|     } type; |     } type; | ||||||
|  |  | ||||||
|     union { |     union { | ||||||
|         DeferredCommandDrawElements draw_elements; |         DeferredCommandDraw draw; | ||||||
|         DeferredCommandClear clear; |         DeferredCommandClear clear; | ||||||
|         DeferredCommandUsePipeline use_pipeline; |         DeferredCommandUsePipeline use_pipeline; | ||||||
|         DeferredCommandUseTextureMode use_texture_mode; |         DeferredCommandUseTextureMode use_texture_mode; | ||||||
|  |         DeferredCommandDepthRange depth_range; | ||||||
|     }; |     }; | ||||||
| } DeferredCommand; | } DeferredCommand; | ||||||
|  |  | ||||||
| @@ -151,9 +161,6 @@ static TextureMode texture_mode_last_used = -1; | |||||||
| static Pipeline pipeline_last_used = PIPELINE_NO; | static Pipeline pipeline_last_used = PIPELINE_NO; | ||||||
|  |  | ||||||
|  |  | ||||||
| #define CIRCLE_VERTICES_MAX 2048 |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /* potentially double buffered array of vertex array handles */ | /* potentially double buffered array of vertex array handles */ | ||||||
| /* we assume they will be refilled fully each frame */ | /* we assume they will be refilled fully each frame */ | ||||||
| static size_t scratch_va_front_used, scratch_va_back_used; | static size_t scratch_va_front_used, scratch_va_back_used; | ||||||
| @@ -195,6 +202,10 @@ static DeferredCommand *deferred_commands; | |||||||
| static void issue_deferred_draw_commands(void) { | static void issue_deferred_draw_commands(void) { | ||||||
|     for (size_t i = 0; i < arrlenu(deferred_commands); ++i) { |     for (size_t i = 0; i < arrlenu(deferred_commands); ++i) { | ||||||
|         switch (deferred_commands[i].type) { |         switch (deferred_commands[i].type) { | ||||||
|  |             case DEFERRED_COMMAND_TYPE_DEPTH_RANGE: { | ||||||
|  |                 glDepthRange(deferred_commands[i].depth_range.low, deferred_commands[i].depth_range.high); | ||||||
|  |                 break;    | ||||||
|  |             } | ||||||
|             case DEFERRED_COMMAND_TYPE_CLEAR: { |             case DEFERRED_COMMAND_TYPE_CLEAR: { | ||||||
|                 glClearColor((1.0f / 255) * deferred_commands[i].clear.color.r, |                 glClearColor((1.0f / 255) * deferred_commands[i].clear.color.r, | ||||||
|                              (1.0f / 255) * deferred_commands[i].clear.color.g, |                              (1.0f / 255) * deferred_commands[i].clear.color.g, | ||||||
| @@ -211,8 +222,8 @@ static void issue_deferred_draw_commands(void) { | |||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             case DEFERRED_COMMAND_TYPE_DRAW_ELEMENTS: { |             case DEFERRED_COMMAND_TYPE_DRAW: { | ||||||
|                 DeferredCommandDrawElements const command = deferred_commands[i].draw_elements; |                 DeferredCommandDraw const command = deferred_commands[i].draw; | ||||||
|  |  | ||||||
|                 /* TODO: don't assume a single vertex array ? */ |                 /* TODO: don't assume a single vertex array ? */ | ||||||
|                 SDL_assert(command.vertices.arity != 0); |                 SDL_assert(command.vertices.arity != 0); | ||||||
| @@ -255,10 +266,12 @@ static void issue_deferred_draw_commands(void) { | |||||||
|                                command.color.a); |                                command.color.a); | ||||||
|  |  | ||||||
|                 if (command.textured) { |                 if (command.textured) { | ||||||
|                     if (command.texture_repeat) |                     if (command.uses_gpu_key) | ||||||
|                         textures_bind_repeating(&ctx.texture_cache, command.texture); |                         glBindTexture(GL_TEXTURE_2D, command.gpu_texture); | ||||||
|  |                     else if (command.texture_repeat) | ||||||
|  |                         textures_bind_repeating(&ctx.texture_cache, command.texture_key); | ||||||
|                     else |                     else | ||||||
|                         textures_bind(&ctx.texture_cache, command.texture); |                         textures_bind(&ctx.texture_cache, command.texture_key); | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 if (command.range_start == command.range_end) |                 if (command.range_start == command.range_end) | ||||||
| @@ -459,40 +472,6 @@ static void finally_use_2d_pipeline(void) { | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| void render_circle(const CirclePrimitive *circle) { |  | ||||||
|     static SDL_Vertex vertices[CIRCLE_VERTICES_MAX]; |  | ||||||
|     static int indices[CIRCLE_VERTICES_MAX * 3]; |  | ||||||
|     int num_vertices = MIN((int)circle->radius, CIRCLE_VERTICES_MAX-1); |  | ||||||
|  |  | ||||||
|     create_circle_geometry(circle->position, |  | ||||||
|                            circle->color, |  | ||||||
|                            circle->radius, |  | ||||||
|                            num_vertices, |  | ||||||
|                            vertices, |  | ||||||
|                            indices); |  | ||||||
|  |  | ||||||
|     glEnableClientState(GL_VERTEX_ARRAY); |  | ||||||
|     glVertexPointer(2, |  | ||||||
|                     GL_FLOAT, |  | ||||||
|                     sizeof (SDL_Vertex), |  | ||||||
|                     &vertices->position); |  | ||||||
|  |  | ||||||
|     glEnableClientState(GL_COLOR_ARRAY); |  | ||||||
|     glColorPointer(4, |  | ||||||
|                    GL_UNSIGNED_BYTE, |  | ||||||
|                    sizeof (SDL_Vertex), |  | ||||||
|                    &vertices->color); |  | ||||||
|  |  | ||||||
|     glDrawElements(GL_TRIANGLES, |  | ||||||
|                    num_vertices * 3, |  | ||||||
|                    GL_UNSIGNED_INT, |  | ||||||
|                    indices); |  | ||||||
|  |  | ||||||
|     glDisableClientState(GL_COLOR_ARRAY); |  | ||||||
|     glDisableClientState(GL_VERTEX_ARRAY); |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| void use_texture_mode(TextureMode mode) { | void use_texture_mode(TextureMode mode) { | ||||||
|     DeferredCommand const command = { |     DeferredCommand const command = { | ||||||
|         .type = DEFERRED_COMMAND_TYPE_USE_TEXTURE_MODE, |         .type = DEFERRED_COMMAND_TYPE_USE_TEXTURE_MODE, | ||||||
| @@ -589,7 +568,7 @@ void finally_render_quads(const Primitive2D primitives[], | |||||||
|                           const struct QuadBatch batch, |                           const struct QuadBatch batch, | ||||||
|                           const VertexBuffer buffer) |                           const VertexBuffer buffer) | ||||||
| { | { | ||||||
|     DeferredCommandDrawElements command = {0}; |     DeferredCommandDraw command = {0}; | ||||||
|  |  | ||||||
|     GLsizei off = 0, voff = 0, uvoff = 0, coff = 0; |     GLsizei off = 0, voff = 0, uvoff = 0, coff = 0; | ||||||
|  |  | ||||||
| @@ -644,7 +623,7 @@ void finally_render_quads(const Primitive2D primitives[], | |||||||
|     if (batch.textured) { |     if (batch.textured) { | ||||||
|         /* TODO: bad, don't */ |         /* TODO: bad, don't */ | ||||||
|         command.textured = true; |         command.textured = true; | ||||||
|         command.texture = primitives->sprite.texture_key; |         command.texture_key = primitives->sprite.texture_key; | ||||||
|         command.texture_repeat = batch.repeat; |         command.texture_repeat = batch.repeat; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -655,8 +634,8 @@ void finally_render_quads(const Primitive2D primitives[], | |||||||
|     use_texture_mode(batch.mode); |     use_texture_mode(batch.mode); | ||||||
|  |  | ||||||
|     DeferredCommand final_command = { |     DeferredCommand final_command = { | ||||||
|         .type = DEFERRED_COMMAND_TYPE_DRAW_ELEMENTS, |         .type = DEFERRED_COMMAND_TYPE_DRAW, | ||||||
|         .draw_elements = command |         .draw = command | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     arrpush(deferred_commands, final_command); |     arrpush(deferred_commands, final_command); | ||||||
| @@ -817,44 +796,46 @@ void finally_draw_text(FontData const *font_data, | |||||||
|                        Color color, |                        Color color, | ||||||
|                        VertexBuffer buffer) |                        VertexBuffer buffer) | ||||||
| { | { | ||||||
|     (void)buffer; |     DeferredCommandDraw command = {0}; | ||||||
|  |  | ||||||
|     /* vertex specification */ |     command.vertices = (AttributeArrayPointer) { | ||||||
|     glEnableClientState(GL_VERTEX_ARRAY); |         .arity = 2, | ||||||
|     glVertexPointer(2, |         .type = GL_FLOAT, | ||||||
|                     GL_FLOAT, |         .stride = offsetof(ElementIndexedQuadWithoutColor, v1), | ||||||
|                     offsetof(ElementIndexedQuadWithoutColor, v1), |         .offset = offsetof(ElementIndexedQuadWithoutColor, v0), | ||||||
|                     (void *)(size_t)offsetof(ElementIndexedQuadWithoutColor, v0)); |         .buffer = buffer | ||||||
|  |     }; | ||||||
|  |  | ||||||
|     glEnableClientState(GL_TEXTURE_COORD_ARRAY); |     command.texcoords = (AttributeArrayPointer) { | ||||||
|     glClientActiveTexture(GL_TEXTURE0); |         .arity = 2, | ||||||
|     glTexCoordPointer(2, |         .type = GL_FLOAT, | ||||||
|                       GL_FLOAT, |         .stride = offsetof(ElementIndexedQuadWithoutColor, v1), | ||||||
|                       offsetof(ElementIndexedQuadWithoutColor, v1), |         .offset = offsetof(ElementIndexedQuadWithoutColor, uv0), | ||||||
|                       (void *)(size_t)offsetof(ElementIndexedQuadWithoutColor, uv0)); |         .buffer = buffer | ||||||
|  |     }; | ||||||
|  |  | ||||||
|     get_quad_element_buffer(); |     command.constant_colored = true; | ||||||
|  |     command.color = color; | ||||||
|  |  | ||||||
|  |     command.gpu_texture = font_data->texture; | ||||||
|  |     command.uses_gpu_key = true; | ||||||
|  |     command.textured = true; | ||||||
|  |  | ||||||
|  |     command.element_buffer = get_quad_element_buffer(); | ||||||
|  |     command.element_count = 6 * (GLsizei)len; | ||||||
|  |     command.range_end = 6 * (GLsizei)len; | ||||||
|  |  | ||||||
|     use_texture_mode(TEXTURE_MODE_GHOSTLY); |     use_texture_mode(TEXTURE_MODE_GHOSTLY); | ||||||
|  |  | ||||||
|     glBindTexture(GL_TEXTURE_2D, font_data->texture); |     DeferredCommand final_command = { | ||||||
|  |         .type = DEFERRED_COMMAND_TYPE_DRAW, | ||||||
|  |         .draw = command | ||||||
|  |     }; | ||||||
|  |  | ||||||
|     glColor4ub(color.r, color.g, color.b, color.a); |     arrpush(deferred_commands, final_command); | ||||||
|  |  | ||||||
|     glDrawElements(GL_TRIANGLES, 6 * (GLsizei)len, GL_UNSIGNED_SHORT, NULL); |  | ||||||
|  |  | ||||||
|     /* clear the state */ |  | ||||||
|     glBufferData(GL_ARRAY_BUFFER, 0, NULL, GL_STREAM_DRAW); |  | ||||||
|     glBindBuffer(GL_ARRAY_BUFFER, 0); |  | ||||||
|  |  | ||||||
|     glDisableClientState(GL_TEXTURE_COORD_ARRAY); |  | ||||||
|     glDisableClientState(GL_VERTEX_ARRAY); |  | ||||||
|  |  | ||||||
|     glBindTexture(GL_TEXTURE_2D, 0); |  | ||||||
|     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); |  | ||||||
|  |  | ||||||
|     /* TODO: why doesn't it get restored if not placed here? */ |     /* TODO: why doesn't it get restored if not placed here? */ | ||||||
|     glDepthMask(GL_TRUE); |     // glDepthMask(GL_TRUE); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -883,6 +864,47 @@ static void load_cubemap_side(const char *path, GLenum target) { | |||||||
|     SDL_FreeSurface(surface); |     SDL_FreeSurface(surface); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void render_circle(const CirclePrimitive *circle) { | ||||||
|  |     static Vec2 vertices[CIRCLE_VERTICES_MAX]; | ||||||
|  |     int num_vertices = CIRCLE_VERTICES_MAX - 1; | ||||||
|  |  | ||||||
|  |     create_circle_geometry(circle->position, | ||||||
|  |                            circle->radius, | ||||||
|  |                            num_vertices, | ||||||
|  |                            vertices); | ||||||
|  |  | ||||||
|  |     VertexBuffer buffer = get_scratch_vertex_array(); | ||||||
|  |     specify_vertex_buffer(buffer, vertices, sizeof (Vec2) * num_vertices); | ||||||
|  |  | ||||||
|  |     DeferredCommandDraw command = {0}; | ||||||
|  |  | ||||||
|  |     command.vertices = (AttributeArrayPointer) { | ||||||
|  |         .arity = 2, | ||||||
|  |         .type = GL_FLOAT, | ||||||
|  |         .stride = sizeof (Vec2), | ||||||
|  |         .offset = 0, | ||||||
|  |         .buffer = buffer | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     command.constant_colored = true; | ||||||
|  |     command.color = circle->color; | ||||||
|  |  | ||||||
|  |     command.element_buffer = get_circle_element_buffer(); | ||||||
|  |     command.element_count = num_vertices * 3; | ||||||
|  |     command.range_end = num_vertices * 3; | ||||||
|  |  | ||||||
|  |     use_texture_mode(circle->color.a == 255 ? TEXTURE_MODE_OPAQUE : TEXTURE_MODE_GHOSTLY); | ||||||
|  |  | ||||||
|  |     DeferredCommand final_command = { | ||||||
|  |         .type = DEFERRED_COMMAND_TYPE_DRAW, | ||||||
|  |         .draw = command | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     arrpush(deferred_commands, final_command); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| void finally_render_skybox(char *paths) { | void finally_render_skybox(char *paths) { | ||||||
|     static GLuint cubemap = 0; |     static GLuint cubemap = 0; | ||||||
|     static char *paths_cache = NULL; |     static char *paths_cache = NULL; | ||||||
| @@ -1049,3 +1071,16 @@ void finally_apply_fog(float start, float end, float density, Color color) { | |||||||
| void finally_pop_fog(void) { | void finally_pop_fog(void) { | ||||||
|     glDisable(GL_FOG); |     glDisable(GL_FOG); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void set_depth_range(double low, double high) { | ||||||
|  |     DeferredCommand const command = { | ||||||
|  |         .type = DEFERRED_COMMAND_TYPE_DEPTH_RANGE, | ||||||
|  |         .depth_range = { | ||||||
|  |             .low = low, | ||||||
|  |             .high = high | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     arrpush(deferred_commands, command); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -33,40 +33,59 @@ void specify_vertex_buffer(VertexBuffer buffer, void const *data, size_t bytes) | |||||||
|  |  | ||||||
|  |  | ||||||
| VertexBuffer get_quad_element_buffer(void) { | VertexBuffer get_quad_element_buffer(void) { | ||||||
|     static GLuint buffer = 0; |     static VertexBuffer buffer = 0; | ||||||
|  |  | ||||||
|     /* it's only generated once at runtime */ |     /* it's only generated once at runtime */ | ||||||
|  |     /* TODO: use builder interface, not direct calls (glMapBuffer isn't portable) */ | ||||||
|     if (buffer == 0) { |     if (buffer == 0) { | ||||||
|         glGenBuffers(1, &buffer); |         buffer = create_vertex_buffer(); | ||||||
|         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer); |         VertexBufferBuilder builder = build_vertex_buffer(buffer, sizeof (GLshort) * QUAD_ELEMENT_BUFFER_LENGTH * 6 ); | ||||||
|         glBufferData(GL_ELEMENT_ARRAY_BUFFER, |  | ||||||
|                      QUAD_ELEMENT_BUFFER_LENGTH * 6 * sizeof(uint16_t), |  | ||||||
|                      NULL, |  | ||||||
|                      GL_STATIC_DRAW); |  | ||||||
|  |  | ||||||
|         uint16_t *const indices = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, |         for (size_t i = 0; i < QUAD_ELEMENT_BUFFER_LENGTH; ++i) { | ||||||
|                                               GL_WRITE_ONLY); |             GLshort indices[6]; | ||||||
|         if (!indices) |             indices[0] = (GLshort)(i * 4 + 0); | ||||||
|             CRY("Quad indices generation", "glMapBuffer() failed"); |             indices[1] = (GLshort)(i * 4 + 1); | ||||||
|  |             indices[2] = (GLshort)(i * 4 + 2); | ||||||
|  |             indices[3] = (GLshort)(i * 4 + 2); | ||||||
|  |             indices[4] = (GLshort)(i * 4 + 3); | ||||||
|  |             indices[5] = (GLshort)(i * 4 + 0); | ||||||
|  |  | ||||||
|         for (uint16_t i = 0; i < QUAD_ELEMENT_BUFFER_LENGTH; ++i) { |             push_to_vertex_buffer_builder(&builder, indices, sizeof indices); | ||||||
|             indices[i * 6 + 0] = (uint16_t)(i * 4 + 0); |         } | ||||||
|             indices[i * 6 + 1] = (uint16_t)(i * 4 + 1); |  | ||||||
|             indices[i * 6 + 2] = (uint16_t)(i * 4 + 2); |  | ||||||
|             indices[i * 6 + 3] = (uint16_t)(i * 4 + 2); |  | ||||||
|             indices[i * 6 + 4] = (uint16_t)(i * 4 + 3); |  | ||||||
|             indices[i * 6 + 5] = (uint16_t)(i * 4 + 0); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|         glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); |     SDL_assert_always(buffer); | ||||||
|  |  | ||||||
|     } else |  | ||||||
|         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer); |  | ||||||
|  |  | ||||||
|     return buffer; |     return buffer; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| void set_depth_range(double low, double high) { | VertexBuffer get_circle_element_buffer(void) { | ||||||
|     glDepthRange(low, high); |     static VertexBuffer buffer = 0; | ||||||
|  |  | ||||||
|  |     if (buffer == 0) { | ||||||
|  |         buffer = create_vertex_buffer(); | ||||||
|  |         VertexBufferBuilder builder = build_vertex_buffer(buffer, sizeof (GLshort) * CIRCLE_ELEMENT_BUFFER_LENGTH); | ||||||
|  |  | ||||||
|  |         for (size_t i = 1; i < CIRCLE_VERTICES_MAX; ++i) { | ||||||
|  |             /* first one is center point index, always zero */ | ||||||
|  |             GLshort indices[3]; | ||||||
|  |  | ||||||
|  |             indices[0] = 0; | ||||||
|  |  | ||||||
|  |             /* generated point index */ | ||||||
|  |             indices[1] = (GLshort)i; | ||||||
|  |  | ||||||
|  |             size_t index = (i + 1) % (CIRCLE_VERTICES_MAX - 1); | ||||||
|  |             if (index == 0) /* don't use center for outer ring */ | ||||||
|  |                 index = (CIRCLE_VERTICES_MAX - 1); | ||||||
|  |             indices[2] = (GLshort)index; | ||||||
|  |  | ||||||
|  |             push_to_vertex_buffer_builder(&builder, indices, sizeof indices); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     SDL_assert_always(buffer); | ||||||
|  |  | ||||||
|  |     return buffer; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -39,7 +39,7 @@ static inline float fast_sqrt(float x) | |||||||
|  |  | ||||||
|  |  | ||||||
| static inline Vec2 fast_cossine(float a) { | static inline Vec2 fast_cossine(float a) { | ||||||
|     const float s = SDL_sinf(a); |     const float s = sinf(a); | ||||||
|     return (Vec2){ |     return (Vec2){ | ||||||
|         .x = fast_sqrt(1.0f - s * s) * (a >= (float)M_PI_2 && a < (float)(M_PI + M_PI_2) ? -1 : 1), |         .x = fast_sqrt(1.0f - s * s) * (a >= (float)M_PI_2 && a < (float)(M_PI + M_PI_2) ? -1 : 1), | ||||||
|         .y = s |         .y = s | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user