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:
@ -96,13 +96,16 @@ typedef struct {
|
||||
Color color;
|
||||
};
|
||||
|
||||
bool textured, texture_repeat;
|
||||
TextureKey texture;
|
||||
bool textured, texture_repeat, uses_gpu_key;
|
||||
TextureKey texture_key;
|
||||
GPUTexture gpu_texture;
|
||||
|
||||
GLuint element_buffer;
|
||||
GLsizei element_count;
|
||||
GLsizei range_start, range_end;
|
||||
} DeferredCommandDrawElements;
|
||||
|
||||
double depth_range_low, depth_range_high;
|
||||
} DeferredCommandDraw;
|
||||
|
||||
|
||||
typedef struct {
|
||||
@ -130,19 +133,26 @@ typedef struct {
|
||||
} DeferredCommandUseTextureMode;
|
||||
|
||||
|
||||
typedef struct {
|
||||
double low, high;
|
||||
} DeferredCommandDepthRange;
|
||||
|
||||
|
||||
typedef struct {
|
||||
enum DeferredCommandType {
|
||||
DEFERRED_COMMAND_TYPE_DRAW_ELEMENTS,
|
||||
DEFERRED_COMMAND_TYPE_DRAW,
|
||||
DEFERRED_COMMAND_TYPE_CLEAR,
|
||||
DEFERRED_COMMAND_TYPE_USE_PIPIELINE,
|
||||
DEFERRED_COMMAND_TYPE_USE_TEXTURE_MODE,
|
||||
DEFERRED_COMMAND_TYPE_DEPTH_RANGE,
|
||||
} type;
|
||||
|
||||
union {
|
||||
DeferredCommandDrawElements draw_elements;
|
||||
DeferredCommandDraw draw;
|
||||
DeferredCommandClear clear;
|
||||
DeferredCommandUsePipeline use_pipeline;
|
||||
DeferredCommandUseTextureMode use_texture_mode;
|
||||
DeferredCommandDepthRange depth_range;
|
||||
};
|
||||
} DeferredCommand;
|
||||
|
||||
@ -151,9 +161,6 @@ static TextureMode texture_mode_last_used = -1;
|
||||
static Pipeline pipeline_last_used = PIPELINE_NO;
|
||||
|
||||
|
||||
#define CIRCLE_VERTICES_MAX 2048
|
||||
|
||||
|
||||
/* potentially double buffered array of vertex array handles */
|
||||
/* we assume they will be refilled fully each frame */
|
||||
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) {
|
||||
for (size_t i = 0; i < arrlenu(deferred_commands); ++i) {
|
||||
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: {
|
||||
glClearColor((1.0f / 255) * deferred_commands[i].clear.color.r,
|
||||
(1.0f / 255) * deferred_commands[i].clear.color.g,
|
||||
@ -211,8 +222,8 @@ static void issue_deferred_draw_commands(void) {
|
||||
break;
|
||||
}
|
||||
|
||||
case DEFERRED_COMMAND_TYPE_DRAW_ELEMENTS: {
|
||||
DeferredCommandDrawElements const command = deferred_commands[i].draw_elements;
|
||||
case DEFERRED_COMMAND_TYPE_DRAW: {
|
||||
DeferredCommandDraw const command = deferred_commands[i].draw;
|
||||
|
||||
/* TODO: don't assume a single vertex array ? */
|
||||
SDL_assert(command.vertices.arity != 0);
|
||||
@ -255,10 +266,12 @@ static void issue_deferred_draw_commands(void) {
|
||||
command.color.a);
|
||||
|
||||
if (command.textured) {
|
||||
if (command.texture_repeat)
|
||||
textures_bind_repeating(&ctx.texture_cache, command.texture);
|
||||
if (command.uses_gpu_key)
|
||||
glBindTexture(GL_TEXTURE_2D, command.gpu_texture);
|
||||
else if (command.texture_repeat)
|
||||
textures_bind_repeating(&ctx.texture_cache, command.texture_key);
|
||||
else
|
||||
textures_bind(&ctx.texture_cache, command.texture);
|
||||
textures_bind(&ctx.texture_cache, command.texture_key);
|
||||
}
|
||||
|
||||
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) {
|
||||
DeferredCommand const command = {
|
||||
.type = DEFERRED_COMMAND_TYPE_USE_TEXTURE_MODE,
|
||||
@ -589,7 +568,7 @@ void finally_render_quads(const Primitive2D primitives[],
|
||||
const struct QuadBatch batch,
|
||||
const VertexBuffer buffer)
|
||||
{
|
||||
DeferredCommandDrawElements command = {0};
|
||||
DeferredCommandDraw command = {0};
|
||||
|
||||
GLsizei off = 0, voff = 0, uvoff = 0, coff = 0;
|
||||
|
||||
@ -644,7 +623,7 @@ void finally_render_quads(const Primitive2D primitives[],
|
||||
if (batch.textured) {
|
||||
/* TODO: bad, don't */
|
||||
command.textured = true;
|
||||
command.texture = primitives->sprite.texture_key;
|
||||
command.texture_key = primitives->sprite.texture_key;
|
||||
command.texture_repeat = batch.repeat;
|
||||
}
|
||||
|
||||
@ -655,8 +634,8 @@ void finally_render_quads(const Primitive2D primitives[],
|
||||
use_texture_mode(batch.mode);
|
||||
|
||||
DeferredCommand final_command = {
|
||||
.type = DEFERRED_COMMAND_TYPE_DRAW_ELEMENTS,
|
||||
.draw_elements = command
|
||||
.type = DEFERRED_COMMAND_TYPE_DRAW,
|
||||
.draw = command
|
||||
};
|
||||
|
||||
arrpush(deferred_commands, final_command);
|
||||
@ -817,44 +796,46 @@ void finally_draw_text(FontData const *font_data,
|
||||
Color color,
|
||||
VertexBuffer buffer)
|
||||
{
|
||||
(void)buffer;
|
||||
DeferredCommandDraw command = {0};
|
||||
|
||||
/* vertex specification */
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(2,
|
||||
GL_FLOAT,
|
||||
offsetof(ElementIndexedQuadWithoutColor, v1),
|
||||
(void *)(size_t)offsetof(ElementIndexedQuadWithoutColor, v0));
|
||||
command.vertices = (AttributeArrayPointer) {
|
||||
.arity = 2,
|
||||
.type = GL_FLOAT,
|
||||
.stride = offsetof(ElementIndexedQuadWithoutColor, v1),
|
||||
.offset = offsetof(ElementIndexedQuadWithoutColor, v0),
|
||||
.buffer = buffer
|
||||
};
|
||||
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glClientActiveTexture(GL_TEXTURE0);
|
||||
glTexCoordPointer(2,
|
||||
GL_FLOAT,
|
||||
offsetof(ElementIndexedQuadWithoutColor, v1),
|
||||
(void *)(size_t)offsetof(ElementIndexedQuadWithoutColor, uv0));
|
||||
command.texcoords = (AttributeArrayPointer) {
|
||||
.arity = 2,
|
||||
.type = GL_FLOAT,
|
||||
.stride = offsetof(ElementIndexedQuadWithoutColor, v1),
|
||||
.offset = 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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
arrpush(deferred_commands, final_command);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
|
||||
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) {
|
||||
static GLuint cubemap = 0;
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user