commit 8d68d0c9765c67fdae6c3c993169eaeabbb8c12b
parent 757e64e16f8e643dc90ea4faedc2f9709b6a7dd7
Author: rexim <reximkut@gmail.com>
Date: Tue, 6 Jul 2021 21:35:50 +0700
Implement proper tile renderer
Diffstat:
5 files changed, 111 insertions(+), 41 deletions(-)
diff --git a/shaders/font.frag b/shaders/font.frag
@@ -16,11 +16,11 @@ uniform sampler2D font;
uniform float time;
in vec2 uv;
-in float glyph_ch;
+flat in int glyph_ch;
in vec4 glyph_color;
void main() {
- int ch = int(glyph_ch);
+ int ch = glyph_ch;
if (!(ASCII_DISPLAY_LOW <= ch && ch <= ASCII_DISPLAY_HIGH)) {
ch = 63;
}
@@ -32,5 +32,5 @@ void main() {
vec2 size = vec2(FONT_CHAR_WIDTH_UV, -FONT_CHAR_HEIGHT_UV);
vec2 t = pos + size * uv;
- gl_FragColor = texture(font, t)* glyph_color;
+ gl_FragColor = texture(font, t) * glyph_color;
}
diff --git a/shaders/font.vert b/shaders/font.vert
@@ -8,14 +8,14 @@
#define FONT_CHAR_HEIGHT (FONT_HEIGHT / FONT_ROWS)
uniform vec2 resolution;
+uniform vec2 scale;
-layout(location = 0) in vec2 pos;
-layout(location = 1) in float scale;
-layout(location = 2) in float ch;
-layout(location = 3) in vec4 color;
+layout(location = 0) in ivec2 tile;
+layout(location = 1) in int ch;
+layout(location = 2) in vec4 color;
out vec2 uv;
-out float glyph_ch;
+flat out int glyph_ch;
out vec4 glyph_color;
vec2 project_point(vec2 point)
@@ -26,6 +26,7 @@ vec2 project_point(vec2 point)
void main() {
uv = vec2(float(gl_VertexID & 1), float((gl_VertexID >> 1) & 1));
vec2 char_size = vec2(float(FONT_CHAR_WIDTH), float(FONT_CHAR_HEIGHT));
+ vec2 pos = tile * char_size * scale;
gl_Position = vec4(project_point(uv * char_size * scale + pos), 0.0, 1.0);
glyph_ch = ch;
glyph_color = color;
diff --git a/src/la.c b/src/la.c
@@ -38,6 +38,48 @@ Vec2f vec2f_div(Vec2f a, Vec2f b)
return vec2f(a.x / b.x, a.y / b.y);
}
+//////////////////////////////
+
+Vec2i vec2i(int x, int y)
+{
+ return (Vec2i) {
+ .x = x,
+ .y = y,
+ };
+}
+
+Vec2i vec2is(int x)
+{
+ return vec2i(x, x);
+}
+
+Vec2i vec2i_add(Vec2i a, Vec2i b)
+{
+ return vec2i(a.x + b.x, a.y + b.y);
+}
+
+Vec2i vec2i_sub(Vec2i a, Vec2i b)
+{
+ return vec2i(a.x - b.x, a.y - b.y);
+}
+
+Vec2i vec2i_mul(Vec2i a, Vec2i b)
+{
+ return vec2i(a.x * b.x, a.y * b.y);
+}
+
+Vec2i vec2i_mul3(Vec2i a, Vec2i b, Vec2i c)
+{
+ return vec2i_mul(vec2i_mul(a, b), c);
+}
+
+Vec2i vec2i_div(Vec2i a, Vec2i b)
+{
+ return vec2i(a.x / b.x, a.y / b.y);
+}
+
+//////////////////////////////
+
Vec4f vec4f(float x, float y, float z, float w)
{
return (Vec4f) {
diff --git a/src/la.h b/src/la.h
@@ -14,6 +14,18 @@ Vec2f vec2f_mul3(Vec2f a, Vec2f b, Vec2f c);
Vec2f vec2f_div(Vec2f a, Vec2f b);
typedef struct {
+ int x, y;
+} Vec2i;
+
+Vec2i vec2i(int x, int y);
+Vec2i vec2is(int x);
+Vec2i vec2i_add(Vec2i a, Vec2i b);
+Vec2i vec2i_sub(Vec2i a, Vec2i b);
+Vec2i vec2i_mul(Vec2i a, Vec2i b);
+Vec2i vec2i_mul3(Vec2i a, Vec2i b, Vec2i c);
+Vec2i vec2i_div(Vec2i a, Vec2i b);
+
+typedef struct {
float x, y, z, w;
} Vec4f;
diff --git a/src/main.c b/src/main.c
@@ -75,7 +75,7 @@ void usage(FILE *stream)
// TODO: Delete line
// TODO: Split the line on Enter
-#define OPENGL_RENDERER
+// #define OPENGL_RENDERER
#ifdef OPENGL_RENDERER
void MessageCallback(GLenum source,
@@ -96,15 +96,13 @@ void MessageCallback(GLenum source,
}
typedef struct {
- Vec2f pos;
- float scale;
- float ch;
+ Vec2i tile;
+ int ch;
Vec4f color;
} Glyph;
typedef enum {
- GLYPH_ATTR_POS = 0,
- GLYPH_ATTR_SCALE,
+ GLYPH_ATTR_TILE = 0,
GLYPH_ATTR_CH,
GLYPH_ATTR_COLOR,
COUNT_GLYPH_ATTRS,
@@ -113,27 +111,27 @@ typedef enum {
typedef struct {
size_t offset;
size_t comps;
+ GLenum type;
} Glyph_Attr_Def;
static const Glyph_Attr_Def glyph_attr_defs[COUNT_GLYPH_ATTRS] = {
- [GLYPH_ATTR_POS] = {
- .offset = offsetof(Glyph, pos),
+ [GLYPH_ATTR_TILE] = {
+ .offset = offsetof(Glyph, tile),
.comps = 2,
- },
- [GLYPH_ATTR_SCALE] = {
- .offset = offsetof(Glyph, scale),
- .comps = 1,
+ .type = GL_INT
},
[GLYPH_ATTR_CH] = {
.offset = offsetof(Glyph, ch),
.comps = 1,
+ .type = GL_INT
},
[GLYPH_ATTR_COLOR] = {
.offset = offsetof(Glyph, color),
.comps = 4,
+ .type = GL_FLOAT
},
};
-static_assert(COUNT_GLYPH_ATTRS == 4, "The amount of glyph vertex attributes have changed");
+static_assert(COUNT_GLYPH_ATTRS == 3, "The amount of glyph vertex attributes have changed");
#define GLYPH_BUFFER_CAP 1024
@@ -154,20 +152,14 @@ void glyph_buffer_sync(void)
glyph_buffer);
}
-void gl_render_text(const char *text, size_t text_size,
- Vec2f pos, float scale, Vec4f color)
+void gl_render_text(const char *text, size_t text_size, Vec2i tile, Vec4f color)
{
for (size_t i = 0; i < text_size; ++i) {
- const Vec2f char_size = vec2f(FONT_CHAR_WIDTH, FONT_CHAR_HEIGHT);
- const Glyph glyph = {
- .pos = vec2f_add(pos, vec2f_mul3(char_size,
- vec2f((float) i, 0.0f),
- vec2fs(scale))),
- .scale = scale,
- .ch = (float) text[i],
+ glyph_buffer_push((Glyph) {
+ .tile = vec2i_add(tile, vec2i(i, 0)),
+ .ch = text[i],
.color = color
- };
- glyph_buffer_push(glyph);
+ });
}
}
@@ -225,6 +217,7 @@ int main(int argc, char **argv)
GLint time_uniform;
GLint resolution_uniform;
+ GLint scale_uniform;
// Initialize Shaders
{
@@ -246,6 +239,9 @@ int main(int argc, char **argv)
time_uniform = glGetUniformLocation(program, "time");
resolution_uniform = glGetUniformLocation(program, "resolution");
+ scale_uniform = glGetUniformLocation(program, "scale");
+
+ glUniform2f(scale_uniform, 5.0f, 5.0f);
}
// Init Font Texture
@@ -297,20 +293,38 @@ int main(int argc, char **argv)
for (Glyph_Attr attr = 0; attr < COUNT_GLYPH_ATTRS; ++attr) {
glEnableVertexAttribArray(attr);
- glVertexAttribPointer(
- attr,
- glyph_attr_defs[attr].comps,
- GL_FLOAT,
- GL_FALSE,
- sizeof(Glyph),
- (void*) glyph_attr_defs[attr].offset);
+ switch (glyph_attr_defs[attr].type) {
+ case GL_FLOAT:
+ glVertexAttribPointer(
+ attr,
+ glyph_attr_defs[attr].comps,
+ glyph_attr_defs[attr].type,
+ GL_FALSE,
+ sizeof(Glyph),
+ (void*) glyph_attr_defs[attr].offset);
+ break;
+
+ case GL_INT:
+ glVertexAttribIPointer(
+ attr,
+ glyph_attr_defs[attr].comps,
+ glyph_attr_defs[attr].type,
+ sizeof(Glyph),
+ (void*) glyph_attr_defs[attr].offset);
+ break;
+
+ default:
+ assert(false && "unreachable");
+ exit(1);
+ }
glVertexAttribDivisor(attr, 1);
}
}
const char *text = "Hello, World";
- Vec4f color = vec4f(1.0f, 0.0f, 0.0f, 1.0f);
- gl_render_text(text, strlen(text), vec2fs(0.0f), 5.0f, color);
+ const char *foobar = "Foo Bar";
+ gl_render_text(text, strlen(text), vec2is(0), vec4f(1.0f, 0.0f, 0.0f, 1.0f));
+ gl_render_text(foobar, strlen(foobar), vec2i(0, -1), vec4f(0.0f, 1.0f, 0.0f, 1.0f));
glyph_buffer_sync();
bool quit = false;
@@ -328,6 +342,7 @@ int main(int argc, char **argv)
{
int w, h;
SDL_GetWindowSize(window, &w, &h);
+ // TODO: update the viewport and the resolution only on actual window change
glViewport(0, 0, w, h);
glUniform2f(resolution_uniform, (float) w, (float) h);
}