separate the rest of general drawing code
This commit is contained in:
parent
472a0657f3
commit
4f2b8ccd01
@ -68,7 +68,9 @@ TWN_API void draw_triangle(char const *texture,
|
|||||||
|
|
||||||
TWN_API void draw_billboard(const char *path,
|
TWN_API void draw_billboard(const char *path,
|
||||||
Vec3 position,
|
Vec3 position,
|
||||||
Vec2 size);
|
Vec2 size,
|
||||||
|
Color color, /* optional, default: all 255 */
|
||||||
|
bool cylindrical); /* optional, default: false */
|
||||||
|
|
||||||
/* sets a perspective 3d camera to be used for all 3d commands */
|
/* sets a perspective 3d camera to be used for all 3d commands */
|
||||||
TWN_API void draw_camera(Vec3 position, float fov, Vec3 up, Vec3 direction);
|
TWN_API void draw_camera(Vec3 position, float fov, Vec3 up, Vec3 direction);
|
||||||
|
@ -49,7 +49,7 @@ typedef struct Rect {
|
|||||||
float h;
|
float h;
|
||||||
} Rect;
|
} Rect;
|
||||||
|
|
||||||
|
/* TODO: remove from here? */
|
||||||
typedef struct Matrix4 {
|
typedef struct Matrix4 {
|
||||||
Vec4 row[4];
|
Vec4 row[4];
|
||||||
} Matrix4;
|
} Matrix4;
|
||||||
|
@ -574,3 +574,310 @@ void render_circle(const CirclePrimitive *circle) {
|
|||||||
|
|
||||||
arrpush(deferred_commands, final_command);
|
arrpush(deferred_commands, final_command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void finally_render_quads(const Primitive2D primitives[],
|
||||||
|
const struct QuadBatch batch,
|
||||||
|
const VertexBuffer buffer)
|
||||||
|
{
|
||||||
|
DeferredCommandDraw command = {0};
|
||||||
|
|
||||||
|
GLsizei off = 0, voff = 0, uvoff = 0, coff = 0;
|
||||||
|
|
||||||
|
if (!batch.constant_colored && batch.textured) {
|
||||||
|
off = offsetof(ElementIndexedQuad, v1);
|
||||||
|
voff = offsetof(ElementIndexedQuad, v0);
|
||||||
|
uvoff = offsetof(ElementIndexedQuad, uv0);
|
||||||
|
coff = offsetof(ElementIndexedQuad, c0);
|
||||||
|
} else if (batch.constant_colored && batch.textured) {
|
||||||
|
off = offsetof(ElementIndexedQuadWithoutColor, v1);
|
||||||
|
voff = offsetof(ElementIndexedQuadWithoutColor, v0);
|
||||||
|
uvoff = offsetof(ElementIndexedQuadWithoutColor, uv0);
|
||||||
|
} else if (!batch.constant_colored && !batch.textured) {
|
||||||
|
off = offsetof(ElementIndexedQuadWithoutTexture, v1);
|
||||||
|
voff = offsetof(ElementIndexedQuadWithoutTexture, v0);
|
||||||
|
coff = offsetof(ElementIndexedQuad, c0);
|
||||||
|
} else if (batch.constant_colored && !batch.textured) {
|
||||||
|
off = offsetof(ElementIndexedQuadWithoutColorWithoutTexture, v1);
|
||||||
|
voff = offsetof(ElementIndexedQuadWithoutColorWithoutTexture, v0);
|
||||||
|
}
|
||||||
|
|
||||||
|
command.vertices = (AttributeArrayPointer) {
|
||||||
|
.arity = 2,
|
||||||
|
.type = GL_FLOAT,
|
||||||
|
.stride = off,
|
||||||
|
.offset = voff,
|
||||||
|
.buffer = buffer
|
||||||
|
};
|
||||||
|
|
||||||
|
if (batch.textured)
|
||||||
|
command.texcoords = (AttributeArrayPointer) {
|
||||||
|
.arity = 2,
|
||||||
|
.type = GL_FLOAT,
|
||||||
|
.stride = off,
|
||||||
|
.offset = uvoff,
|
||||||
|
.buffer = buffer
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!batch.constant_colored) {
|
||||||
|
command.colors = (AttributeArrayPointer) {
|
||||||
|
.arity = 4,
|
||||||
|
.type = GL_UNSIGNED_BYTE,
|
||||||
|
.stride = off,
|
||||||
|
.offset = coff,
|
||||||
|
.buffer = buffer
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
command.constant_colored = true;
|
||||||
|
command.color = primitives[0].sprite.color;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (batch.textured) {
|
||||||
|
command.textured = true;
|
||||||
|
command.texture_key = batch.texture_key;
|
||||||
|
command.texture_repeat = batch.repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
command.element_buffer = get_quad_element_buffer();
|
||||||
|
command.element_count = 6 * (GLsizei)batch.size;
|
||||||
|
command.range_end = 6 * (GLsizei)batch.size;
|
||||||
|
|
||||||
|
use_texture_mode(batch.mode);
|
||||||
|
|
||||||
|
DeferredCommand final_command = {
|
||||||
|
.type = DEFERRED_COMMAND_TYPE_DRAW,
|
||||||
|
.draw = command
|
||||||
|
};
|
||||||
|
|
||||||
|
arrpush(deferred_commands, final_command);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t get_quad_payload_size(struct QuadBatch batch) {
|
||||||
|
if (batch.constant_colored && batch.textured)
|
||||||
|
return sizeof (ElementIndexedQuadWithoutColor);
|
||||||
|
else if (!batch.constant_colored && batch.textured)
|
||||||
|
return sizeof (ElementIndexedQuad);
|
||||||
|
else if (batch.constant_colored && !batch.textured)
|
||||||
|
return sizeof (ElementIndexedQuadWithoutColorWithoutTexture);
|
||||||
|
else if (!batch.constant_colored && !batch.textured)
|
||||||
|
return sizeof (ElementIndexedQuadWithoutTexture);
|
||||||
|
|
||||||
|
SDL_assert(false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool push_quad_payload_to_vertex_buffer_builder(struct QuadBatch batch,
|
||||||
|
VertexBufferBuilder *builder,
|
||||||
|
Vec2 v0, Vec2 v1, Vec2 v2, Vec2 v3,
|
||||||
|
Vec2 uv0, Vec2 uv1, Vec2 uv2, Vec2 uv3,
|
||||||
|
Color color)
|
||||||
|
{
|
||||||
|
if (!batch.constant_colored && batch.textured) {
|
||||||
|
ElementIndexedQuad const buffer_element = {
|
||||||
|
.v0 = v0,
|
||||||
|
.v1 = v1,
|
||||||
|
.v2 = v2,
|
||||||
|
.v3 = v3,
|
||||||
|
|
||||||
|
.uv0 = uv0,
|
||||||
|
.uv1 = uv1,
|
||||||
|
.uv2 = uv2,
|
||||||
|
.uv3 = uv3,
|
||||||
|
|
||||||
|
/* equal for all (flat shaded) */
|
||||||
|
.c0 = color,
|
||||||
|
// .c1 = color,
|
||||||
|
.c2 = color,
|
||||||
|
// .c3 = color,
|
||||||
|
};
|
||||||
|
|
||||||
|
return push_to_vertex_buffer_builder(builder, &buffer_element, sizeof buffer_element);
|
||||||
|
|
||||||
|
} else if (batch.constant_colored && batch.textured) {
|
||||||
|
ElementIndexedQuadWithoutColor const buffer_element = {
|
||||||
|
.v0 = v0,
|
||||||
|
.v1 = v1,
|
||||||
|
.v2 = v2,
|
||||||
|
.v3 = v3,
|
||||||
|
|
||||||
|
.uv0 = uv0,
|
||||||
|
.uv1 = uv1,
|
||||||
|
.uv2 = uv2,
|
||||||
|
.uv3 = uv3,
|
||||||
|
};
|
||||||
|
|
||||||
|
return push_to_vertex_buffer_builder(builder, &buffer_element, sizeof buffer_element);
|
||||||
|
|
||||||
|
} else if (!batch.constant_colored && !batch.textured) {
|
||||||
|
ElementIndexedQuadWithoutTexture const buffer_element = {
|
||||||
|
.v0 = v0,
|
||||||
|
.v1 = v1,
|
||||||
|
.v2 = v2,
|
||||||
|
.v3 = v3,
|
||||||
|
|
||||||
|
/* equal for all (flat shaded) */
|
||||||
|
.c0 = color,
|
||||||
|
// .c1 = color,
|
||||||
|
.c2 = color,
|
||||||
|
// .c3 = color,
|
||||||
|
};
|
||||||
|
|
||||||
|
return push_to_vertex_buffer_builder(builder, &buffer_element, sizeof buffer_element);
|
||||||
|
|
||||||
|
} else if (batch.constant_colored && !batch.textured) {
|
||||||
|
ElementIndexedQuadWithoutColorWithoutTexture const buffer_element = {
|
||||||
|
.v0 = v0,
|
||||||
|
.v1 = v1,
|
||||||
|
.v2 = v2,
|
||||||
|
.v3 = v3,
|
||||||
|
};
|
||||||
|
|
||||||
|
return push_to_vertex_buffer_builder(builder, &buffer_element, sizeof buffer_element);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_assert(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void finally_draw_uncolored_space_traingle_batch(const MeshBatch *batch,
|
||||||
|
const TextureKey texture_key,
|
||||||
|
const VertexBuffer buffer)
|
||||||
|
{
|
||||||
|
const size_t primitives_len = arrlenu(batch->primitives);
|
||||||
|
|
||||||
|
/* nothing to do */
|
||||||
|
if (primitives_len == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const Rect srcrect = textures_get_srcrect(&ctx.texture_cache, texture_key);
|
||||||
|
const Rect dims = textures_get_dims(&ctx.texture_cache, texture_key);
|
||||||
|
|
||||||
|
const float wr = srcrect.w / dims.w;
|
||||||
|
const float hr = srcrect.h / dims.h;
|
||||||
|
const float xr = srcrect.x / dims.w;
|
||||||
|
const float yr = srcrect.y / dims.h;
|
||||||
|
|
||||||
|
/* update pixel-based uvs to correspond with texture atlases */
|
||||||
|
for (size_t i = 0; i < primitives_len; ++i) {
|
||||||
|
UncoloredSpaceTriangle *payload =
|
||||||
|
&((UncoloredSpaceTriangle *)(void *)batch->primitives)[i];
|
||||||
|
|
||||||
|
payload->uv0.x = xr + ((float)payload->uv0.x / srcrect.w) * wr;
|
||||||
|
payload->uv0.y = yr + ((float)payload->uv0.y / srcrect.h) * hr;
|
||||||
|
payload->uv1.x = xr + ((float)payload->uv1.x / srcrect.w) * wr;
|
||||||
|
payload->uv1.y = yr + ((float)payload->uv1.y / srcrect.h) * hr;
|
||||||
|
payload->uv2.x = xr + ((float)payload->uv2.x / srcrect.w) * wr;
|
||||||
|
payload->uv2.y = yr + ((float)payload->uv2.y / srcrect.h) * hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
specify_vertex_buffer(buffer, batch->primitives, primitives_len * sizeof (UncoloredSpaceTriangle));
|
||||||
|
|
||||||
|
DeferredCommandDraw command = {0};
|
||||||
|
|
||||||
|
command.vertices = (AttributeArrayPointer) {
|
||||||
|
.arity = 3,
|
||||||
|
.type = GL_FLOAT,
|
||||||
|
.stride = offsetof(UncoloredSpaceTriangle, v1),
|
||||||
|
.offset = offsetof(UncoloredSpaceTriangle, v0),
|
||||||
|
.buffer = buffer
|
||||||
|
};
|
||||||
|
|
||||||
|
command.texcoords = (AttributeArrayPointer) {
|
||||||
|
.arity = 2,
|
||||||
|
.type = GL_FLOAT,
|
||||||
|
.stride = offsetof(UncoloredSpaceTriangle, v1),
|
||||||
|
.offset = offsetof(UncoloredSpaceTriangle, uv0),
|
||||||
|
.buffer = buffer
|
||||||
|
};
|
||||||
|
|
||||||
|
command.textured = true;
|
||||||
|
command.texture_key = texture_key;
|
||||||
|
|
||||||
|
command.primitive_count = (GLsizei)(3 * primitives_len);
|
||||||
|
|
||||||
|
DeferredCommand final_command = {
|
||||||
|
.type = DEFERRED_COMMAND_TYPE_DRAW,
|
||||||
|
.draw = command
|
||||||
|
};
|
||||||
|
|
||||||
|
arrpush(deferred_commands, final_command);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool push_text_payload_to_vertex_buffer_builder(FontData const *font_data,
|
||||||
|
VertexBufferBuilder *builder,
|
||||||
|
stbtt_aligned_quad quad)
|
||||||
|
{
|
||||||
|
(void)font_data;
|
||||||
|
|
||||||
|
ElementIndexedQuadWithoutColor buffer_element = {
|
||||||
|
.v0 = (Vec2){ quad.x0, quad.y0 },
|
||||||
|
.v1 = (Vec2){ quad.x1, quad.y0 },
|
||||||
|
.v2 = (Vec2){ quad.x1, quad.y1 },
|
||||||
|
.v3 = (Vec2){ quad.x0, quad.y1 },
|
||||||
|
|
||||||
|
.uv0 = (Vec2){ quad.s0, quad.t0 },
|
||||||
|
.uv1 = (Vec2){ quad.s1, quad.t0 },
|
||||||
|
.uv2 = (Vec2){ quad.s1, quad.t1 },
|
||||||
|
.uv3 = (Vec2){ quad.s0, quad.t1 },
|
||||||
|
};
|
||||||
|
|
||||||
|
return push_to_vertex_buffer_builder(builder, &buffer_element, sizeof buffer_element);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void finally_draw_text(FontData const *font_data,
|
||||||
|
size_t len,
|
||||||
|
Color color,
|
||||||
|
VertexBuffer buffer)
|
||||||
|
{
|
||||||
|
DeferredCommandDraw command = {0};
|
||||||
|
|
||||||
|
command.vertices = (AttributeArrayPointer) {
|
||||||
|
.arity = 2,
|
||||||
|
.type = GL_FLOAT,
|
||||||
|
.stride = offsetof(ElementIndexedQuadWithoutColor, v1),
|
||||||
|
.offset = offsetof(ElementIndexedQuadWithoutColor, v0),
|
||||||
|
.buffer = buffer
|
||||||
|
};
|
||||||
|
|
||||||
|
command.texcoords = (AttributeArrayPointer) {
|
||||||
|
.arity = 2,
|
||||||
|
.type = GL_FLOAT,
|
||||||
|
.stride = offsetof(ElementIndexedQuadWithoutColor, v1),
|
||||||
|
.offset = offsetof(ElementIndexedQuadWithoutColor, uv0),
|
||||||
|
.buffer = 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);
|
||||||
|
|
||||||
|
DeferredCommand final_command = {
|
||||||
|
.type = DEFERRED_COMMAND_TYPE_DRAW,
|
||||||
|
.draw = command
|
||||||
|
};
|
||||||
|
|
||||||
|
arrpush(deferred_commands, final_command);
|
||||||
|
|
||||||
|
/* TODO: why doesn't it get restored if not placed here? */
|
||||||
|
// glDepthMask(GL_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t get_text_payload_size(void) {
|
||||||
|
return sizeof (ElementIndexedQuadWithoutColor);
|
||||||
|
}
|
||||||
|
@ -113,6 +113,73 @@ typedef struct TextCache {
|
|||||||
} TextCache;
|
} TextCache;
|
||||||
|
|
||||||
|
|
||||||
|
/* TODO: try using the fact we utilize edge coloring and step virtual color attributes to bogus points */
|
||||||
|
/* this is only doable is we take out color attribute to separate array or a portion of it */
|
||||||
|
/* interleaved vertex array data */
|
||||||
|
typedef struct ElementIndexedQuad {
|
||||||
|
/* upper-left */
|
||||||
|
Vec2 v0;
|
||||||
|
Vec2 uv0;
|
||||||
|
Color c0;
|
||||||
|
/* bottom-left */
|
||||||
|
Vec2 v1;
|
||||||
|
Vec2 uv1;
|
||||||
|
Color c1;
|
||||||
|
/* bottom-right */
|
||||||
|
Vec2 v2;
|
||||||
|
Vec2 uv2;
|
||||||
|
Color c2;
|
||||||
|
/* upper-right */
|
||||||
|
Vec2 v3;
|
||||||
|
Vec2 uv3;
|
||||||
|
Color c3;
|
||||||
|
} ElementIndexedQuad;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct ElementIndexedQuadWithoutColor {
|
||||||
|
/* upper-left */
|
||||||
|
Vec2 v0;
|
||||||
|
Vec2 uv0;
|
||||||
|
/* bottom-left */
|
||||||
|
Vec2 v1;
|
||||||
|
Vec2 uv1;
|
||||||
|
/* bottom-right */
|
||||||
|
Vec2 v2;
|
||||||
|
Vec2 uv2;
|
||||||
|
/* upper-right */
|
||||||
|
Vec2 v3;
|
||||||
|
Vec2 uv3;
|
||||||
|
} ElementIndexedQuadWithoutColor;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct ElementIndexedQuadWithoutTexture {
|
||||||
|
/* upper-left */
|
||||||
|
Vec2 v0;
|
||||||
|
Color c0;
|
||||||
|
/* bottom-left */
|
||||||
|
Vec2 v1;
|
||||||
|
Color c1;
|
||||||
|
/* bottom-right */
|
||||||
|
Vec2 v2;
|
||||||
|
Color c2;
|
||||||
|
/* upper-right */
|
||||||
|
Vec2 v3;
|
||||||
|
Color c3;
|
||||||
|
} ElementIndexedQuadWithoutTexture;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct ElementIndexedQuadWithoutColorWithoutTexture {
|
||||||
|
/* upper-left */
|
||||||
|
Vec2 v0;
|
||||||
|
/* bottom-left */
|
||||||
|
Vec2 v1;
|
||||||
|
/* bottom-right */
|
||||||
|
Vec2 v2;
|
||||||
|
/* upper-right */
|
||||||
|
Vec2 v3;
|
||||||
|
} ElementIndexedQuadWithoutColorWithoutTexture;
|
||||||
|
|
||||||
|
|
||||||
/* renders the background, then the primitives in all render queues */
|
/* renders the background, then the primitives in all render queues */
|
||||||
void render(void);
|
void render(void);
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#include "twn_util.h"
|
#include "twn_util.h"
|
||||||
#include "twn_util_c.h"
|
#include "twn_util_c.h"
|
||||||
#include "twn_engine_context_c.h"
|
#include "twn_engine_context_c.h"
|
||||||
#include "twn_text_c.h"
|
|
||||||
#include "twn_types.h"
|
#include "twn_types.h"
|
||||||
#include "twn_deferred_commands.h"
|
#include "twn_deferred_commands.h"
|
||||||
#include "twn_gl_any_rendering_c.h"
|
#include "twn_gl_any_rendering_c.h"
|
||||||
@ -11,73 +10,6 @@
|
|||||||
#include <stb_ds.h>
|
#include <stb_ds.h>
|
||||||
|
|
||||||
|
|
||||||
/* TODO: try using the fact we utilize edge coloring and step virtual color attributes to bogus points */
|
|
||||||
/* this is only doable is we take out color attribute to separate array or a portion of it */
|
|
||||||
/* interleaved vertex array data */
|
|
||||||
typedef struct ElementIndexedQuad {
|
|
||||||
/* upper-left */
|
|
||||||
Vec2 v0;
|
|
||||||
Vec2 uv0;
|
|
||||||
Color c0;
|
|
||||||
/* bottom-left */
|
|
||||||
Vec2 v1;
|
|
||||||
Vec2 uv1;
|
|
||||||
Color c1;
|
|
||||||
/* bottom-right */
|
|
||||||
Vec2 v2;
|
|
||||||
Vec2 uv2;
|
|
||||||
Color c2;
|
|
||||||
/* upper-right */
|
|
||||||
Vec2 v3;
|
|
||||||
Vec2 uv3;
|
|
||||||
Color c3;
|
|
||||||
} ElementIndexedQuad;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct ElementIndexedQuadWithoutColor {
|
|
||||||
/* upper-left */
|
|
||||||
Vec2 v0;
|
|
||||||
Vec2 uv0;
|
|
||||||
/* bottom-left */
|
|
||||||
Vec2 v1;
|
|
||||||
Vec2 uv1;
|
|
||||||
/* bottom-right */
|
|
||||||
Vec2 v2;
|
|
||||||
Vec2 uv2;
|
|
||||||
/* upper-right */
|
|
||||||
Vec2 v3;
|
|
||||||
Vec2 uv3;
|
|
||||||
} ElementIndexedQuadWithoutColor;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct ElementIndexedQuadWithoutTexture {
|
|
||||||
/* upper-left */
|
|
||||||
Vec2 v0;
|
|
||||||
Color c0;
|
|
||||||
/* bottom-left */
|
|
||||||
Vec2 v1;
|
|
||||||
Color c1;
|
|
||||||
/* bottom-right */
|
|
||||||
Vec2 v2;
|
|
||||||
Color c2;
|
|
||||||
/* upper-right */
|
|
||||||
Vec2 v3;
|
|
||||||
Color c3;
|
|
||||||
} ElementIndexedQuadWithoutTexture;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct ElementIndexedQuadWithoutColorWithoutTexture {
|
|
||||||
/* upper-left */
|
|
||||||
Vec2 v0;
|
|
||||||
/* bottom-left */
|
|
||||||
Vec2 v1;
|
|
||||||
/* bottom-right */
|
|
||||||
Vec2 v2;
|
|
||||||
/* upper-right */
|
|
||||||
Vec2 v3;
|
|
||||||
} ElementIndexedQuadWithoutColorWithoutTexture;
|
|
||||||
|
|
||||||
|
|
||||||
static TextureMode texture_mode_last_used = TEXTURE_MODE_UNKNOWN;
|
static TextureMode texture_mode_last_used = TEXTURE_MODE_UNKNOWN;
|
||||||
static Pipeline pipeline_last_used = PIPELINE_NO;
|
static Pipeline pipeline_last_used = PIPELINE_NO;
|
||||||
|
|
||||||
@ -268,312 +200,6 @@ bool push_to_vertex_buffer_builder(VertexBufferBuilder *builder,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void finally_render_quads(const Primitive2D primitives[],
|
|
||||||
const struct QuadBatch batch,
|
|
||||||
const VertexBuffer buffer)
|
|
||||||
{
|
|
||||||
DeferredCommandDraw command = {0};
|
|
||||||
|
|
||||||
GLsizei off = 0, voff = 0, uvoff = 0, coff = 0;
|
|
||||||
|
|
||||||
if (!batch.constant_colored && batch.textured) {
|
|
||||||
off = offsetof(ElementIndexedQuad, v1);
|
|
||||||
voff = offsetof(ElementIndexedQuad, v0);
|
|
||||||
uvoff = offsetof(ElementIndexedQuad, uv0);
|
|
||||||
coff = offsetof(ElementIndexedQuad, c0);
|
|
||||||
} else if (batch.constant_colored && batch.textured) {
|
|
||||||
off = offsetof(ElementIndexedQuadWithoutColor, v1);
|
|
||||||
voff = offsetof(ElementIndexedQuadWithoutColor, v0);
|
|
||||||
uvoff = offsetof(ElementIndexedQuadWithoutColor, uv0);
|
|
||||||
} else if (!batch.constant_colored && !batch.textured) {
|
|
||||||
off = offsetof(ElementIndexedQuadWithoutTexture, v1);
|
|
||||||
voff = offsetof(ElementIndexedQuadWithoutTexture, v0);
|
|
||||||
coff = offsetof(ElementIndexedQuad, c0);
|
|
||||||
} else if (batch.constant_colored && !batch.textured) {
|
|
||||||
off = offsetof(ElementIndexedQuadWithoutColorWithoutTexture, v1);
|
|
||||||
voff = offsetof(ElementIndexedQuadWithoutColorWithoutTexture, v0);
|
|
||||||
}
|
|
||||||
|
|
||||||
command.vertices = (AttributeArrayPointer) {
|
|
||||||
.arity = 2,
|
|
||||||
.type = GL_FLOAT,
|
|
||||||
.stride = off,
|
|
||||||
.offset = voff,
|
|
||||||
.buffer = buffer
|
|
||||||
};
|
|
||||||
|
|
||||||
if (batch.textured)
|
|
||||||
command.texcoords = (AttributeArrayPointer) {
|
|
||||||
.arity = 2,
|
|
||||||
.type = GL_FLOAT,
|
|
||||||
.stride = off,
|
|
||||||
.offset = uvoff,
|
|
||||||
.buffer = buffer
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!batch.constant_colored) {
|
|
||||||
command.colors = (AttributeArrayPointer) {
|
|
||||||
.arity = 4,
|
|
||||||
.type = GL_UNSIGNED_BYTE,
|
|
||||||
.stride = off,
|
|
||||||
.offset = coff,
|
|
||||||
.buffer = buffer
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
command.constant_colored = true;
|
|
||||||
command.color = primitives[0].sprite.color;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (batch.textured) {
|
|
||||||
command.textured = true;
|
|
||||||
command.texture_key = batch.texture_key;
|
|
||||||
command.texture_repeat = batch.repeat;
|
|
||||||
}
|
|
||||||
|
|
||||||
command.element_buffer = get_quad_element_buffer();
|
|
||||||
command.element_count = 6 * (GLsizei)batch.size;
|
|
||||||
command.range_end = 6 * (GLsizei)batch.size;
|
|
||||||
|
|
||||||
use_texture_mode(batch.mode);
|
|
||||||
|
|
||||||
DeferredCommand final_command = {
|
|
||||||
.type = DEFERRED_COMMAND_TYPE_DRAW,
|
|
||||||
.draw = command
|
|
||||||
};
|
|
||||||
|
|
||||||
arrpush(deferred_commands, final_command);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t get_quad_payload_size(struct QuadBatch batch) {
|
|
||||||
if (batch.constant_colored && batch.textured)
|
|
||||||
return sizeof (ElementIndexedQuadWithoutColor);
|
|
||||||
else if (!batch.constant_colored && batch.textured)
|
|
||||||
return sizeof (ElementIndexedQuad);
|
|
||||||
else if (batch.constant_colored && !batch.textured)
|
|
||||||
return sizeof (ElementIndexedQuadWithoutColorWithoutTexture);
|
|
||||||
else if (!batch.constant_colored && !batch.textured)
|
|
||||||
return sizeof (ElementIndexedQuadWithoutTexture);
|
|
||||||
|
|
||||||
SDL_assert(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool push_quad_payload_to_vertex_buffer_builder(struct QuadBatch batch,
|
|
||||||
VertexBufferBuilder *builder,
|
|
||||||
Vec2 v0, Vec2 v1, Vec2 v2, Vec2 v3,
|
|
||||||
Vec2 uv0, Vec2 uv1, Vec2 uv2, Vec2 uv3,
|
|
||||||
Color color)
|
|
||||||
{
|
|
||||||
if (!batch.constant_colored && batch.textured) {
|
|
||||||
ElementIndexedQuad const buffer_element = {
|
|
||||||
.v0 = v0,
|
|
||||||
.v1 = v1,
|
|
||||||
.v2 = v2,
|
|
||||||
.v3 = v3,
|
|
||||||
|
|
||||||
.uv0 = uv0,
|
|
||||||
.uv1 = uv1,
|
|
||||||
.uv2 = uv2,
|
|
||||||
.uv3 = uv3,
|
|
||||||
|
|
||||||
/* equal for all (flat shaded) */
|
|
||||||
.c0 = color,
|
|
||||||
// .c1 = color,
|
|
||||||
.c2 = color,
|
|
||||||
// .c3 = color,
|
|
||||||
};
|
|
||||||
|
|
||||||
return push_to_vertex_buffer_builder(builder, &buffer_element, sizeof buffer_element);
|
|
||||||
|
|
||||||
} else if (batch.constant_colored && batch.textured) {
|
|
||||||
ElementIndexedQuadWithoutColor const buffer_element = {
|
|
||||||
.v0 = v0,
|
|
||||||
.v1 = v1,
|
|
||||||
.v2 = v2,
|
|
||||||
.v3 = v3,
|
|
||||||
|
|
||||||
.uv0 = uv0,
|
|
||||||
.uv1 = uv1,
|
|
||||||
.uv2 = uv2,
|
|
||||||
.uv3 = uv3,
|
|
||||||
};
|
|
||||||
|
|
||||||
return push_to_vertex_buffer_builder(builder, &buffer_element, sizeof buffer_element);
|
|
||||||
|
|
||||||
} else if (!batch.constant_colored && !batch.textured) {
|
|
||||||
ElementIndexedQuadWithoutTexture const buffer_element = {
|
|
||||||
.v0 = v0,
|
|
||||||
.v1 = v1,
|
|
||||||
.v2 = v2,
|
|
||||||
.v3 = v3,
|
|
||||||
|
|
||||||
/* equal for all (flat shaded) */
|
|
||||||
.c0 = color,
|
|
||||||
// .c1 = color,
|
|
||||||
.c2 = color,
|
|
||||||
// .c3 = color,
|
|
||||||
};
|
|
||||||
|
|
||||||
return push_to_vertex_buffer_builder(builder, &buffer_element, sizeof buffer_element);
|
|
||||||
|
|
||||||
} else if (batch.constant_colored && !batch.textured) {
|
|
||||||
ElementIndexedQuadWithoutColorWithoutTexture const buffer_element = {
|
|
||||||
.v0 = v0,
|
|
||||||
.v1 = v1,
|
|
||||||
.v2 = v2,
|
|
||||||
.v3 = v3,
|
|
||||||
};
|
|
||||||
|
|
||||||
return push_to_vertex_buffer_builder(builder, &buffer_element, sizeof buffer_element);
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_assert(false);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void finally_draw_uncolored_space_traingle_batch(const MeshBatch *batch,
|
|
||||||
const TextureKey texture_key,
|
|
||||||
const VertexBuffer buffer)
|
|
||||||
{
|
|
||||||
const size_t primitives_len = arrlenu(batch->primitives);
|
|
||||||
|
|
||||||
/* nothing to do */
|
|
||||||
if (primitives_len == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const Rect srcrect = textures_get_srcrect(&ctx.texture_cache, texture_key);
|
|
||||||
const Rect dims = textures_get_dims(&ctx.texture_cache, texture_key);
|
|
||||||
|
|
||||||
const float wr = srcrect.w / dims.w;
|
|
||||||
const float hr = srcrect.h / dims.h;
|
|
||||||
const float xr = srcrect.x / dims.w;
|
|
||||||
const float yr = srcrect.y / dims.h;
|
|
||||||
|
|
||||||
/* update pixel-based uvs to correspond with texture atlases */
|
|
||||||
for (size_t i = 0; i < primitives_len; ++i) {
|
|
||||||
UncoloredSpaceTriangle *payload =
|
|
||||||
&((UncoloredSpaceTriangle *)(void *)batch->primitives)[i];
|
|
||||||
|
|
||||||
payload->uv0.x = xr + ((float)payload->uv0.x / srcrect.w) * wr;
|
|
||||||
payload->uv0.y = yr + ((float)payload->uv0.y / srcrect.h) * hr;
|
|
||||||
payload->uv1.x = xr + ((float)payload->uv1.x / srcrect.w) * wr;
|
|
||||||
payload->uv1.y = yr + ((float)payload->uv1.y / srcrect.h) * hr;
|
|
||||||
payload->uv2.x = xr + ((float)payload->uv2.x / srcrect.w) * wr;
|
|
||||||
payload->uv2.y = yr + ((float)payload->uv2.y / srcrect.h) * hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
specify_vertex_buffer(buffer, batch->primitives, primitives_len * sizeof (UncoloredSpaceTriangle));
|
|
||||||
|
|
||||||
DeferredCommandDraw command = {0};
|
|
||||||
|
|
||||||
command.vertices = (AttributeArrayPointer) {
|
|
||||||
.arity = 3,
|
|
||||||
.type = GL_FLOAT,
|
|
||||||
.stride = offsetof(UncoloredSpaceTriangle, v1),
|
|
||||||
.offset = offsetof(UncoloredSpaceTriangle, v0),
|
|
||||||
.buffer = buffer
|
|
||||||
};
|
|
||||||
|
|
||||||
command.texcoords = (AttributeArrayPointer) {
|
|
||||||
.arity = 2,
|
|
||||||
.type = GL_FLOAT,
|
|
||||||
.stride = offsetof(UncoloredSpaceTriangle, v1),
|
|
||||||
.offset = offsetof(UncoloredSpaceTriangle, uv0),
|
|
||||||
.buffer = buffer
|
|
||||||
};
|
|
||||||
|
|
||||||
command.textured = true;
|
|
||||||
command.texture_key = texture_key;
|
|
||||||
|
|
||||||
command.primitive_count = (GLsizei)(3 * primitives_len);
|
|
||||||
|
|
||||||
DeferredCommand final_command = {
|
|
||||||
.type = DEFERRED_COMMAND_TYPE_DRAW,
|
|
||||||
.draw = command
|
|
||||||
};
|
|
||||||
|
|
||||||
arrpush(deferred_commands, final_command);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool push_text_payload_to_vertex_buffer_builder(FontData const *font_data,
|
|
||||||
VertexBufferBuilder *builder,
|
|
||||||
stbtt_aligned_quad quad)
|
|
||||||
{
|
|
||||||
(void)font_data;
|
|
||||||
|
|
||||||
ElementIndexedQuadWithoutColor buffer_element = {
|
|
||||||
.v0 = (Vec2){ quad.x0, quad.y0 },
|
|
||||||
.v1 = (Vec2){ quad.x1, quad.y0 },
|
|
||||||
.v2 = (Vec2){ quad.x1, quad.y1 },
|
|
||||||
.v3 = (Vec2){ quad.x0, quad.y1 },
|
|
||||||
|
|
||||||
.uv0 = (Vec2){ quad.s0, quad.t0 },
|
|
||||||
.uv1 = (Vec2){ quad.s1, quad.t0 },
|
|
||||||
.uv2 = (Vec2){ quad.s1, quad.t1 },
|
|
||||||
.uv3 = (Vec2){ quad.s0, quad.t1 },
|
|
||||||
};
|
|
||||||
|
|
||||||
return push_to_vertex_buffer_builder(builder, &buffer_element, sizeof buffer_element);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void finally_draw_text(FontData const *font_data,
|
|
||||||
size_t len,
|
|
||||||
Color color,
|
|
||||||
VertexBuffer buffer)
|
|
||||||
{
|
|
||||||
DeferredCommandDraw command = {0};
|
|
||||||
|
|
||||||
command.vertices = (AttributeArrayPointer) {
|
|
||||||
.arity = 2,
|
|
||||||
.type = GL_FLOAT,
|
|
||||||
.stride = offsetof(ElementIndexedQuadWithoutColor, v1),
|
|
||||||
.offset = offsetof(ElementIndexedQuadWithoutColor, v0),
|
|
||||||
.buffer = buffer
|
|
||||||
};
|
|
||||||
|
|
||||||
command.texcoords = (AttributeArrayPointer) {
|
|
||||||
.arity = 2,
|
|
||||||
.type = GL_FLOAT,
|
|
||||||
.stride = offsetof(ElementIndexedQuadWithoutColor, v1),
|
|
||||||
.offset = offsetof(ElementIndexedQuadWithoutColor, uv0),
|
|
||||||
.buffer = 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);
|
|
||||||
|
|
||||||
DeferredCommand final_command = {
|
|
||||||
.type = DEFERRED_COMMAND_TYPE_DRAW,
|
|
||||||
.draw = command
|
|
||||||
};
|
|
||||||
|
|
||||||
arrpush(deferred_commands, final_command);
|
|
||||||
|
|
||||||
/* TODO: why doesn't it get restored if not placed here? */
|
|
||||||
// glDepthMask(GL_TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t get_text_payload_size(void) {
|
|
||||||
return sizeof (ElementIndexedQuadWithoutColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void load_cubemap_side(const char *path, GLenum target) {
|
static void load_cubemap_side(const char *path, GLenum target) {
|
||||||
SDL_Surface *surface = textures_load_surface(path);
|
SDL_Surface *surface = textures_load_surface(path);
|
||||||
/* TODO: sanity check whether all of them have same dimensions? */
|
/* TODO: sanity check whether all of them have same dimensions? */
|
||||||
|
Loading…
Reference in New Issue
Block a user