133 lines
3.8 KiB
C
133 lines
3.8 KiB
C
/* a rendering.c mixin */
|
|
#ifndef CIRCLES_H
|
|
#define CIRCLES_H
|
|
|
|
#include "../util.h"
|
|
#include "../private/rendering.h"
|
|
#include "../context.h"
|
|
|
|
#include <SDL2/SDL.h>
|
|
#include <stb_ds.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
void push_circle(t_fvec2 position, float radius, t_color color) {
|
|
struct circle_primitive circle = {
|
|
.radius = radius,
|
|
.color = color,
|
|
.position = position,
|
|
};
|
|
|
|
struct primitive_2d primitive = {
|
|
.type = PRIMITIVE_2D_CIRCLE,
|
|
.circle = circle,
|
|
};
|
|
|
|
arrput(ctx.render_queue_2d, primitive);
|
|
}
|
|
|
|
/* TODO: caching and reuse scheme */
|
|
/* vertices_out and indices_out MUST BE FREED */
|
|
static void create_circle_geometry(t_fvec2 position,
|
|
t_color color,
|
|
float radius,
|
|
size_t num_vertices,
|
|
SDL_Vertex **vertices_out,
|
|
int **indices_out)
|
|
{
|
|
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 */
|
|
float seg_rotation_angle = (360.0f / (float)num_vertices) * ((float)M_PI / 180);
|
|
|
|
vertices[0].position.x = (float)position.x;
|
|
vertices[0].position.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 */
|
|
float start_x = 0.0f - radius;
|
|
float start_y = 0.0f;
|
|
|
|
for (size_t i = 1; i < num_vertices + 1; ++i) {
|
|
float final_seg_rotation_angle = (float)i * seg_rotation_angle;
|
|
|
|
vertices[i].position.x =
|
|
cosf(final_seg_rotation_angle) * start_x -
|
|
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].position.y += position.y;
|
|
|
|
vertices[i].color.r = color.r;
|
|
vertices[i].color.g = color.g;
|
|
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;
|
|
}
|
|
|
|
*vertices_out = vertices;
|
|
*indices_out = indices;
|
|
}
|
|
|
|
|
|
static void render_circle(const struct circle_primitive *circle) {
|
|
SDL_Vertex *vertices = NULL;
|
|
int *indices = NULL;
|
|
int num_vertices = (int)circle->radius;
|
|
|
|
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);
|
|
|
|
free(vertices);
|
|
free(indices);
|
|
}
|
|
|
|
#endif
|