use static, fixed arrays for circle geometry data instead of allocating for each one
This commit is contained in:
		@@ -20,9 +20,9 @@ static void title_tick(State *state) {
 | 
				
			|||||||
            ((float)ctx.resolution.x / 2) - ((float)320 / 2), 64, 320, 128 }));
 | 
					            ((float)ctx.resolution.x / 2) - ((float)320 / 2), 64, 320, 128 }));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* draw the tick count as an example of dynamic text */
 | 
					    /* draw the tick count as an example of dynamic text */
 | 
				
			||||||
    size_t text_str_len = snprintf(NULL, 0, "%lu", state->ctx->frame_number) + 1;
 | 
					    size_t text_str_len = snprintf(NULL, 0, "%llu", state->ctx->frame_number) + 1;
 | 
				
			||||||
    char *text_str = cmalloc(text_str_len);
 | 
					    char *text_str = cmalloc(text_str_len);
 | 
				
			||||||
    snprintf(text_str, text_str_len, "%lu", state->ctx->frame_number);
 | 
					    snprintf(text_str, text_str_len, "%llu", state->ctx->frame_number);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const char *font = "/fonts/kenney-pixel.ttf";
 | 
					    const char *font = "/fonts/kenney-pixel.ttf";
 | 
				
			||||||
    int text_h = 32;
 | 
					    int text_h = 32;
 | 
				
			||||||
@@ -39,7 +39,6 @@ static void title_tick(State *state) {
 | 
				
			|||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    draw_text(text_str, (Vec2){ 0, 0 }, text_h, (Color) { 255, 255, 255, 255 }, font);
 | 
					    draw_text(text_str, (Vec2){ 0, 0 }, text_h, (Color) { 255, 255, 255, 255 }, font);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    free(text_str);
 | 
					    free(text_str);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,6 +22,7 @@ TWN_API void draw_sprite(char const *path,
 | 
				
			|||||||
TWN_API void draw_rectangle(Rect rect, Color color);
 | 
					TWN_API void draw_rectangle(Rect rect, Color color);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* pushes a filled circle onto the circle render queue */
 | 
					/* pushes a filled circle onto the circle render queue */
 | 
				
			||||||
 | 
					/* note that its edges may look jagged with a radius larger than 2048 */
 | 
				
			||||||
TWN_API void draw_circle(Vec2 position, float radius, Color color);
 | 
					TWN_API void draw_circle(Vec2 position, float radius, Color color);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* TODO: have font optional, with something minimal coming embedded */
 | 
					/* TODO: have font optional, with something minimal coming embedded */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,18 +22,14 @@ void draw_circle(Vec2 position, float radius, Color color) {
 | 
				
			|||||||
    arrput(ctx.render_queue_2d, primitive);
 | 
					    arrput(ctx.render_queue_2d, primitive);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* TODO: caching and reuse scheme */
 | 
					
 | 
				
			||||||
/* vertices_out and indices_out MUST BE FREED */
 | 
					 | 
				
			||||||
void create_circle_geometry(Vec2 position,
 | 
					void create_circle_geometry(Vec2 position,
 | 
				
			||||||
                            Color color,
 | 
					                            Color color,
 | 
				
			||||||
                            float radius,
 | 
					                            float radius,
 | 
				
			||||||
                            size_t num_vertices,
 | 
					                            size_t num_vertices,
 | 
				
			||||||
                            SDL_Vertex **vertices_out,
 | 
					                            SDL_Vertex vertices[],
 | 
				
			||||||
                            int **indices_out)
 | 
					                            int indices[])
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    SDL_Vertex *vertices = cmalloc(sizeof *vertices * (num_vertices + 1));
 | 
					 | 
				
			||||||
    int *indices = cmalloc(sizeof *indices * (num_vertices * 3));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* 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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -82,7 +78,4 @@ void create_circle_geometry(Vec2 position,
 | 
				
			|||||||
            index = num_vertices;
 | 
					            index = num_vertices;
 | 
				
			||||||
        indices[triangle_offset + 2] = (int)index;
 | 
					        indices[triangle_offset + 2] = (int)index;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    *vertices_out = vertices;
 | 
					 | 
				
			||||||
    *indices_out = indices;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -126,12 +126,14 @@ void render(void);
 | 
				
			|||||||
/* clears all render queues */
 | 
					/* clears all render queues */
 | 
				
			||||||
void render_queue_clear(void);
 | 
					void render_queue_clear(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 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 */
 | 
				
			||||||
void create_circle_geometry(Vec2 position,
 | 
					void create_circle_geometry(Vec2 position,
 | 
				
			||||||
                            Color color,
 | 
					                            Color color,
 | 
				
			||||||
                            float radius,
 | 
					                            float radius,
 | 
				
			||||||
                            size_t num_vertices,
 | 
					                            size_t num_vertices,
 | 
				
			||||||
                            SDL_Vertex **vertices_out,
 | 
					                            SDL_Vertex vertices[],
 | 
				
			||||||
                            int **indices_out);
 | 
					                            int indices[]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct SpriteBatch {
 | 
					struct SpriteBatch {
 | 
				
			||||||
    size_t size;             /* how many primitives are in current batch */
 | 
					    size_t size;             /* how many primitives are in current batch */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -58,6 +58,9 @@ typedef enum {
 | 
				
			|||||||
static Pipeline pipeline_last_used = PIPELINE_NO;
 | 
					static Pipeline pipeline_last_used = PIPELINE_NO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CIRCLE_VERTICES_MAX 2048
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void use_space_pipeline(void) {
 | 
					void use_space_pipeline(void) {
 | 
				
			||||||
    if (pipeline_last_used == PIPELINE_SPACE)
 | 
					    if (pipeline_last_used == PIPELINE_SPACE)
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
@@ -164,16 +167,16 @@ void render_rectangle(const RectPrimitive *rectangle) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void render_circle(const CirclePrimitive *circle) {
 | 
					void render_circle(const CirclePrimitive *circle) {
 | 
				
			||||||
    SDL_Vertex *vertices = NULL;
 | 
					    static SDL_Vertex vertices[CIRCLE_VERTICES_MAX];
 | 
				
			||||||
    int *indices = NULL;
 | 
					    static int indices[CIRCLE_VERTICES_MAX * 3];
 | 
				
			||||||
    int num_vertices = (int)circle->radius;
 | 
					    int num_vertices = MIN((int)circle->radius, CIRCLE_VERTICES_MAX-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    create_circle_geometry(circle->position,
 | 
					    create_circle_geometry(circle->position,
 | 
				
			||||||
                           circle->color,
 | 
					                           circle->color,
 | 
				
			||||||
                           circle->radius,
 | 
					                           circle->radius,
 | 
				
			||||||
                           num_vertices,
 | 
					                           num_vertices,
 | 
				
			||||||
                           &vertices,
 | 
					                           vertices,
 | 
				
			||||||
                           &indices);
 | 
					                           indices);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    glEnableClientState(GL_VERTEX_ARRAY);
 | 
					    glEnableClientState(GL_VERTEX_ARRAY);
 | 
				
			||||||
    glVertexPointer(2,
 | 
					    glVertexPointer(2,
 | 
				
			||||||
@@ -194,9 +197,6 @@ void render_circle(const CirclePrimitive *circle) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    glDisableClientState(GL_COLOR_ARRAY);
 | 
					    glDisableClientState(GL_COLOR_ARRAY);
 | 
				
			||||||
    glDisableClientState(GL_VERTEX_ARRAY);
 | 
					    glDisableClientState(GL_VERTEX_ARRAY);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    SDL_free(vertices);
 | 
					 | 
				
			||||||
    SDL_free(indices);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user