[RELEASE] u22-v04
This version is submitted for U22 final presentation. (squashed 158 commits)
This commit is contained in:
@@ -27,7 +27,7 @@ target_link_libraries(glyphas
|
||||
if (BUILD_TESTING)
|
||||
add_executable(glyphas-test test.c)
|
||||
target_link_libraries(glyphas-test
|
||||
SDL2::SDL2
|
||||
${SDL2_TARGET}
|
||||
|
||||
glyphas)
|
||||
endif()
|
||||
|
@@ -9,31 +9,20 @@
|
||||
#include "util/gleasy/texture.h"
|
||||
#include "util/gleasy/program.h"
|
||||
#include "util/math/vector.h"
|
||||
#include "util/memory/memory.h"
|
||||
|
||||
#include "./block.h"
|
||||
|
||||
/* resources */
|
||||
#include "anysrc/drawer.vshader.h"
|
||||
#include "anysrc/drawer.fshader.h"
|
||||
#include "util/glyphas/anysrc/drawer.vshader.h"
|
||||
#include "util/glyphas/anysrc/drawer.fshader.h"
|
||||
|
||||
#define GLYPHAS_DRAWER_UNIFORM_TEX 0
|
||||
#define UNIFORM_TEX_ 0
|
||||
|
||||
#define GLYPHAS_DRAWER_VSHADER_IN_POS 0
|
||||
#define GLYPHAS_DRAWER_VSHADER_IN_SIZE 1
|
||||
#define GLYPHAS_DRAWER_VSHADER_IN_UV_POS 2
|
||||
#define GLYPHAS_DRAWER_VSHADER_IN_UV_SIZE 3
|
||||
#define GLYPHAS_DRAWER_VSHADER_IN_COLOR 4
|
||||
|
||||
struct glyphas_drawer_t {
|
||||
gleasy_texture_2d_t tex;
|
||||
|
||||
GLuint vao;
|
||||
|
||||
gleasy_buffer_array_t instances;
|
||||
size_t instances_reserved;
|
||||
size_t instances_length;
|
||||
};
|
||||
#define VSHADER_IN_POS_ 0
|
||||
#define VSHADER_IN_SIZE_ 1
|
||||
#define VSHADER_IN_UV_POS_ 2
|
||||
#define VSHADER_IN_UV_SIZE_ 3
|
||||
#define VSHADER_IN_COLOR_ 4
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
@@ -45,73 +34,60 @@ typedef struct {
|
||||
} glyphas_drawer_instance_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
static void glyphas_drawer_setup_vao_(
|
||||
gleasy_buffer_array_t instances) {
|
||||
assert(instances != 0);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instances);
|
||||
|
||||
# define enable_attrib_(NAME, name, dim, type) do { \
|
||||
glEnableVertexAttribArray(GLYPHAS_DRAWER_VSHADER_IN_##NAME); \
|
||||
glVertexAttribPointer( \
|
||||
GLYPHAS_DRAWER_VSHADER_IN_##NAME, dim, type, GL_FALSE, \
|
||||
sizeof(glyphas_drawer_instance_t), \
|
||||
NULL + offsetof(glyphas_drawer_instance_t, name)); \
|
||||
glVertexAttribDivisor(GLYPHAS_DRAWER_VSHADER_IN_##NAME, 1); \
|
||||
} while (0)
|
||||
|
||||
enable_attrib_(POS, pos, 2, GL_FLOAT);
|
||||
enable_attrib_(SIZE, size, 2, GL_FLOAT);
|
||||
enable_attrib_(UV_POS, uv_pos, 2, GL_FLOAT);
|
||||
enable_attrib_(UV_SIZE, uv_size, 2, GL_FLOAT);
|
||||
enable_attrib_(COLOR, color, 4, GL_FLOAT);
|
||||
|
||||
# undef enable_attrib_
|
||||
}
|
||||
|
||||
gleasy_program_t glyphas_drawer_create_default_program(void) {
|
||||
return gleasy_program_new("", 0,
|
||||
glyphas_drawer_vshader_, sizeof(glyphas_drawer_vshader_),
|
||||
glyphas_drawer_fshader_, sizeof(glyphas_drawer_fshader_));
|
||||
}
|
||||
|
||||
glyphas_drawer_t* glyphas_drawer_new(void) {
|
||||
glyphas_drawer_t* drawer = memory_new(sizeof(*drawer));
|
||||
*drawer = (typeof(*drawer)) {0};
|
||||
void glyphas_drawer_initialize(
|
||||
glyphas_drawer_t* drawer, gleasy_texture_2d_t tex) {
|
||||
assert(drawer != NULL);
|
||||
|
||||
*drawer = (typeof(*drawer)) {
|
||||
.tex = tex,
|
||||
};
|
||||
|
||||
glCreateVertexArrays(1, &drawer->vao);
|
||||
glBindVertexArray(drawer->vao);
|
||||
|
||||
glGenBuffers(1, &drawer->instances);
|
||||
glyphas_drawer_setup_vao_(drawer->instances);
|
||||
|
||||
return drawer;
|
||||
glBindVertexArray(drawer->vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, drawer->instances);
|
||||
|
||||
# define enable_(index, var, dim, type) do { \
|
||||
glEnableVertexAttribArray(index); \
|
||||
glVertexAttribPointer( \
|
||||
index, dim, type, GL_FALSE, \
|
||||
sizeof(glyphas_drawer_instance_t), \
|
||||
NULL + offsetof(glyphas_drawer_instance_t, var)); \
|
||||
glVertexAttribDivisor(index, 1); \
|
||||
} while (0)
|
||||
|
||||
enable_(VSHADER_IN_POS_, pos, 2, GL_FLOAT);
|
||||
enable_(VSHADER_IN_SIZE_, size, 2, GL_FLOAT);
|
||||
enable_(VSHADER_IN_UV_POS_, uv_pos, 2, GL_FLOAT);
|
||||
enable_(VSHADER_IN_UV_SIZE_, uv_size, 2, GL_FLOAT);
|
||||
enable_(VSHADER_IN_COLOR_, color, 4, GL_FLOAT);
|
||||
|
||||
# undef enable_attrib_
|
||||
}
|
||||
|
||||
void glyphas_drawer_delete(glyphas_drawer_t* drawer) {
|
||||
if (drawer == NULL) return;
|
||||
void glyphas_drawer_deinitialize(glyphas_drawer_t* drawer) {
|
||||
assert(drawer != NULL);
|
||||
|
||||
glDeleteBuffers(1, &drawer->instances);
|
||||
|
||||
glDeleteVertexArrays(1, &drawer->vao);
|
||||
|
||||
memory_delete(drawer);
|
||||
}
|
||||
|
||||
void glyphas_drawer_clear(
|
||||
glyphas_drawer_t* drawer, gleasy_texture_2d_t tex, size_t reserve) {
|
||||
void glyphas_drawer_clear(glyphas_drawer_t* drawer, size_t reserve) {
|
||||
assert(drawer != NULL);
|
||||
assert(tex != 0);
|
||||
assert(reserve > 0);
|
||||
|
||||
drawer->tex = tex;
|
||||
|
||||
drawer->instances_length = 0;
|
||||
if (drawer->instances_reserved < reserve) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, drawer->instances);
|
||||
glBufferData(GL_ARRAY_BUFFER,
|
||||
reserve * sizeof(glyphas_drawer_instance_t),
|
||||
NULL, GL_DYNAMIC_DRAW);
|
||||
reserve*sizeof(glyphas_drawer_instance_t), NULL, GL_DYNAMIC_DRAW);
|
||||
drawer->instances_reserved = reserve;
|
||||
}
|
||||
}
|
||||
@@ -158,7 +134,7 @@ void glyphas_drawer_draw(const glyphas_drawer_t* drawer) {
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, drawer->tex);
|
||||
glUniform1i(GLYPHAS_DRAWER_UNIFORM_TEX, 0);
|
||||
glUniform1i(UNIFORM_TEX_, 0);
|
||||
|
||||
glDrawArraysInstanced(GL_TRIANGLES, 0, 6, drawer->instances_length);
|
||||
}
|
||||
|
@@ -1,33 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include "util/gleasy/buffer.h"
|
||||
#include "util/gleasy/texture.h"
|
||||
#include "util/gleasy/program.h"
|
||||
|
||||
#include "./block.h"
|
||||
|
||||
struct glyphas_drawer_t;
|
||||
typedef struct glyphas_drawer_t glyphas_drawer_t;
|
||||
typedef struct {
|
||||
gleasy_texture_2d_t tex;
|
||||
|
||||
GLuint vao;
|
||||
|
||||
gleasy_buffer_array_t instances;
|
||||
size_t instances_reserved;
|
||||
size_t instances_length;
|
||||
} glyphas_drawer_t;
|
||||
|
||||
gleasy_program_t
|
||||
glyphas_drawer_create_default_program(
|
||||
void
|
||||
);
|
||||
|
||||
glyphas_drawer_t*
|
||||
glyphas_drawer_new(
|
||||
void
|
||||
void
|
||||
glyphas_drawer_initialize(
|
||||
glyphas_drawer_t* drawer,
|
||||
gleasy_texture_2d_t tex
|
||||
);
|
||||
|
||||
void
|
||||
glyphas_drawer_delete(
|
||||
glyphas_drawer_deinitialize(
|
||||
glyphas_drawer_t* drawer
|
||||
);
|
||||
|
||||
void
|
||||
glyphas_drawer_clear(
|
||||
glyphas_drawer_t* drawer,
|
||||
gleasy_texture_2d_t tex,
|
||||
size_t reserve
|
||||
glyphas_drawer_t* drawer,
|
||||
size_t reserve
|
||||
);
|
||||
|
||||
void
|
||||
@@ -44,7 +52,7 @@ glyphas_drawer_add_block_item(
|
||||
/* The drawer doesn't hold the reference. */
|
||||
);
|
||||
|
||||
/* bind the program before drawing */
|
||||
/* call glUseProgram before calling */
|
||||
void
|
||||
glyphas_drawer_draw(
|
||||
const glyphas_drawer_t* drawer
|
||||
|
@@ -11,6 +11,16 @@
|
||||
|
||||
#include "./context.h"
|
||||
|
||||
static const char* glyphas_face_get_ft_error_str_(FT_Error err) {
|
||||
/* what a fucking trick lol.
|
||||
* https://stackoverflow.com/questions/61641364/gcc-cant-find-ft-error-string-when-trying-to-compile */
|
||||
# undef FTERRORS_H_
|
||||
# define FT_ERRORDEF(code, val, str) case code: return str;
|
||||
# define FT_ERROR_START_LIST switch(err) {
|
||||
# define FT_ERROR_END_LIST default: return "unknown"; }
|
||||
# include FT_ERRORS_H
|
||||
}
|
||||
|
||||
void glyphas_face_initialize_from_file(
|
||||
glyphas_face_t* face,
|
||||
const glyphas_context_t* ctx,
|
||||
@@ -23,8 +33,8 @@ void glyphas_face_initialize_from_file(
|
||||
|
||||
const FT_Error err = FT_New_Face(ctx->ft, path, index, &face->ft);
|
||||
if (err != FT_Err_Ok) {
|
||||
fprintf(stderr,
|
||||
"failed to load font file '%s': %s\n", path, FT_Error_String(err));
|
||||
fprintf(stderr, "failed to load font file '%s': %s\n",
|
||||
path, glyphas_face_get_ft_error_str_(err));
|
||||
abort();
|
||||
}
|
||||
}
|
||||
@@ -43,8 +53,8 @@ void glyphas_face_initialize_from_buffer(
|
||||
const FT_Error err =
|
||||
FT_New_Memory_Face(ctx->ft, data, length, index, &face->ft);
|
||||
if (err != FT_Err_Ok) {
|
||||
fprintf(stderr,
|
||||
"failed to load font on memory: %s\n", FT_Error_String(err));
|
||||
fprintf(stderr, "failed to load font on memory: %s\n",
|
||||
glyphas_face_get_ft_error_str_(err));
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
@@ -28,8 +28,8 @@ typedef struct {
|
||||
gleasy_atlas_t* atlas;
|
||||
glyphas_cache_t* cache;
|
||||
|
||||
gleasy_program_t prog;
|
||||
glyphas_drawer_t* drawer;
|
||||
gleasy_program_t prog;
|
||||
glyphas_drawer_t drawer;
|
||||
} context_t;
|
||||
|
||||
#define SCALE 0.01f
|
||||
@@ -56,8 +56,8 @@ static void align_text_(context_t* ctx, const char* str) {
|
||||
static const vec2_t origin = vec2(.5f, -.5f);
|
||||
glyphas_block_set_origin(block, &origin);
|
||||
|
||||
glyphas_drawer_clear(ctx->drawer, gleasy_atlas_get_texture(ctx->atlas), len);
|
||||
glyphas_drawer_add_block(ctx->drawer, block);
|
||||
glyphas_drawer_clear(&ctx->drawer, len);
|
||||
glyphas_drawer_add_block(&ctx->drawer, block);
|
||||
glyphas_block_delete(block);
|
||||
}
|
||||
|
||||
@@ -72,8 +72,8 @@ static void initialize_(context_t* ctx, const char* path, const char* str) {
|
||||
ctx->atlas = gleasy_atlas_new(GL_RED, 256, 256, false /* anti-alias */);
|
||||
ctx->cache = glyphas_cache_new(ctx->atlas, &ctx->face, 16, 16);
|
||||
|
||||
ctx->prog = glyphas_drawer_create_default_program();
|
||||
ctx->drawer = glyphas_drawer_new();
|
||||
ctx->prog = glyphas_drawer_create_default_program();
|
||||
glyphas_drawer_initialize(&ctx->drawer, gleasy_atlas_get_texture(ctx->atlas));
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
|
||||
align_text_(ctx, str);
|
||||
@@ -87,13 +87,13 @@ static void draw_(const context_t* ctx) {
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glUseProgram(ctx->prog);
|
||||
glyphas_drawer_draw(ctx->drawer);
|
||||
glyphas_drawer_draw(&ctx->drawer);
|
||||
}
|
||||
|
||||
static void deinitialize_(context_t* ctx) {
|
||||
assert(ctx != NULL);
|
||||
|
||||
glyphas_drawer_delete(ctx->drawer);
|
||||
glyphas_drawer_deinitialize(&ctx->drawer);
|
||||
glDeleteProgram(ctx->prog);
|
||||
|
||||
glyphas_cache_delete(ctx->cache);
|
||||
|
Reference in New Issue
Block a user