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:
parent
aa3cab87d2
commit
7e409fc14a
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user