diff --git a/text_rendering/atlas.png b/text_rendering/atlas.png index a0cfd30..496c515 100644 Binary files a/text_rendering/atlas.png and b/text_rendering/atlas.png differ diff --git a/text_rendering/font_fragshader.glsl b/text_rendering/font_fragshader.glsl index 51ba398..1230f6f 100644 --- a/text_rendering/font_fragshader.glsl +++ b/text_rendering/font_fragshader.glsl @@ -1,14 +1,15 @@ -#version 330 +#version 330 core // viewsize.x = viewport width in pixels; viewsize.y = viewport height in pixels -uniform vec2 viewsize; -// texture uv coordinate in texture space -in vec2 texture_coord; -uniform sampler2D texture_sampler; +uniform ivec2 viewsize; +uniform ivec2 texturesize; -out vec4 color; +// texture uv coordinate in texture space +in vec2 uv; +uniform sampler2D ts; void main() { - color = mix(vec4(0.0f,0.0f,0.0f,1.0f), vec4(1.0f,1.0f,1.0f,1.0f), texture(texture_sampler, texture_coord)) + vec4(1.0f,0.0f,0.0f,1.0f); + //gl_FragColor = vec4(1.0f,0.0f,0.0f,1.0f); + gl_FragColor = texture(ts, uv); } diff --git a/text_rendering/font_vertshader.glsl b/text_rendering/font_vertshader.glsl index 240063f..e18ab9a 100644 --- a/text_rendering/font_vertshader.glsl +++ b/text_rendering/font_vertshader.glsl @@ -1,20 +1,23 @@ #version 330 core // viewsize.x = viewport width in pixels; viewsize.y = viewport height in pixels -uniform vec2 viewsize; +uniform ivec2 viewsize; +uniform ivec2 texturesize; -// both position and and uv are in pixels +// both position and and uv are in pixels, they where converted to floats when +// passed to the shader layout(location = 0) in vec2 position; -layout(location = 1) in vec2 uv; +layout(location = 1) in vec2 txcoord; -out vec2 texture_coord; +out vec2 uv; void main() { vec4 pos = vec4(position.x, position.y, 0.0f, 1.0f); - vec2 v = viewsize / 2; - pos.xy = (pos.xy - v) / v; + vec2 hsize = vec2(float(viewsize.x)/2.0f, float(viewsize.y)/2.0f); + + pos.xy = (pos.xy - hsize) / hsize; gl_Position = pos; - texture_coord = uv / viewsize; + uv = txcoord / float(texturesize); } diff --git a/text_rendering/main.c b/text_rendering/main.c index 13130e9..56a7fc0 100644 --- a/text_rendering/main.c +++ b/text_rendering/main.c @@ -21,7 +21,7 @@ int main(void) return 1; } - ren_render_text("ciao mamma", 100, 100, 100, 100, 12); + ren_render_text("ciao mamma", 0, 0, 100, 100, 12); SDL_GL_SwapWindow(win); SDL_Event e; diff --git a/text_rendering/ren.c b/text_rendering/ren.c index f6cc19c..1e5d957 100644 --- a/text_rendering/ren.c +++ b/text_rendering/ren.c @@ -46,6 +46,16 @@ const char * ren_err_msg[] = { [REN_UNIFORM] = "Failed to get uniform location", }; + +#define ELEM(x) [x] = #x, +const char *glerr[] = { + ELEM(GL_INVALID_ENUM) + ELEM(GL_INVALID_VALUE) + ELEM(GL_INVALID_OPERATION) +}; +#undef ELEM + + // different stacks #include "stack.h" STACK_DECL(vtstack, struct v_text) @@ -60,8 +70,11 @@ struct { GLuint box_prog; GLuint font_buffer; GLint viewsize_loc; + GLint texturesize_loc; struct vtstack font_stack; struct vcstack box_stack; + int width, height; + int s_x, s_y, s_w, s_h; } ren = {0}; @@ -292,7 +305,7 @@ int ren_init(SDL_Window *w) ren.font = font_init(); if (!ren.font) REN_RET(-1, REN_FONT) - if (font_load(ren.font, FONT_PATH, 12)) REN_RET(-1, REN_FONT) + if (font_load(ren.font, FONT_PATH, 20)) REN_RET(-1, REN_FONT) font_dump(ren.font, "./atlas.png"); ren.font_texture = ren_texturer_2d( @@ -311,29 +324,12 @@ int ren_init(SDL_Window *w) // generate the font buffer object glGenBuffers(1, &ren.font_buffer); if (!ren.font_buffer) REN_RET(-1, REN_BUFFER) - glBindBuffer(GL_ARRAY_BUFFER, ren.font_buffer); - glEnableVertexAttribArray(REN_VERTEX_IDX); - glVertexAttribPointer( - REN_VERTEX_IDX, - 2, - GL_INT, - GL_FALSE, - sizeof(struct v_text), - 0); - glEnableVertexAttribArray(REN_UV_IDX); - glVertexAttribPointer( - REN_UV_IDX, - 2, - GL_INT, - GL_FALSE, - sizeof(struct v_text), - (void*)sizeof(vec2_i)); - - glBindBuffer(GL_ARRAY_BUFFER, 0); // create the uniforms ren.viewsize_loc = glGetUniformLocation(ren.font_prog, "viewsize"); if (ren.viewsize_loc == -1) REN_RET(-1, REN_UNIFORM) + ren.texturesize_loc = glGetUniformLocation(ren.font_prog, "texturesize"); + if (ren.texturesize_loc == -1) REN_RET(-1, REN_UNIFORM) int width, height; SDL_GetWindowSize(w, &width, &height); @@ -344,12 +340,38 @@ int ren_init(SDL_Window *w) return 0; } - +#define GLERR() {int a = glGetError(); if (a != GL_NO_ERROR) printf("glError: %d %s\n", a, glerr[a]);} static int ren_draw_font_stack(void) { glUseProgram(ren.font_prog); glBindBuffer(GL_ARRAY_BUFFER, ren.font_buffer); + glViewport(0, 0, ren.width, ren.height); + glScissor(ren.s_x, ren.s_y, ren.s_w, ren.s_h); + glUniform2i(ren.viewsize_loc, ren.width, ren.height); + glUniform2i(ren.texturesize_loc, ren.font->width, ren.font->height); + GLERR(); + + glEnableVertexAttribArray(REN_VERTEX_IDX); + glEnableVertexAttribArray(REN_UV_IDX); + // when passing ints to glVertexAttribPointer they are automatically + // converted to floats + glVertexAttribPointer( + REN_VERTEX_IDX, + 2, + GL_INT, + GL_FALSE, + sizeof(struct v_text), + 0); + GLERR(); + glVertexAttribPointer( + REN_UV_IDX, + 2, + GL_INT, + GL_FALSE, + sizeof(struct v_text), + (void*)sizeof(vec2_i)); + GLERR(); // TODO: implement size and damage tracking on stacks glBufferData( GL_ARRAY_BUFFER, @@ -357,7 +379,10 @@ static int ren_draw_font_stack(void) ren.font_stack.items, GL_DYNAMIC_DRAW); glDrawArrays(GL_TRIANGLES, 0, ren.font_stack.idx); + GLERR(); + glDisableVertexAttribArray(REN_VERTEX_IDX); + glDisableVertexAttribArray(REN_UV_IDX); glBindBuffer(GL_ARRAY_BUFFER, 0); glUseProgram(0); return 0; @@ -366,12 +391,24 @@ static int ren_draw_font_stack(void) int ren_update_viewport(int w, int h) { - glViewport(0, 0, w, h); - glUniform2i(ren.viewsize_loc, w, h); + ren.width = w; + ren.height = h; return 0; } +// TODO: add a scissor array in order to do less render calls +int ren_set_scissor(int x, int y, int w, int h) +{ + ren.s_x = x; + ren.s_y = y; + ren.s_w = w; + ren.s_h = h; + return 0; +} + + + // TODO: implement font size int ren_render_text(const char *str, int x, int y, int w, int h, int size) { @@ -420,15 +457,24 @@ int ren_render_text(const char *str, int x, int y, int w, int h, int size) .uv = { .u = g->u+g->w, .v = g->v }, }; vtstack_push(&ren.font_stack, &v); + vtstack_push(&ren.font_stack, &v); // x4,y4 v = (struct v_text){ .pos = { .x = gx+g->x, .y = gy+g->y }, .uv = { .u = g->u, .v = g->v }, }; vtstack_push(&ren.font_stack, &v); + // x1,y1 + v = (struct v_text){ + .pos = { .x = gx+g->x, .y = gy+g->y+g->h }, + .uv = { .u = g->u, .v = g->v+g->h }, + }; + vtstack_push(&ren.font_stack, &v); // TODO: possible kerning needs to be applied here - gx += g->w + g->a; + // FIXME: advance is too large + //gx += g->w + g->a; + gx += g->w + g->x + 1; if (cp == '\n') gy += ren.font->glyph_max_h; // TODO: encode and/or store line height @@ -436,7 +482,7 @@ int ren_render_text(const char *str, int x, int y, int w, int h, int size) // FIXME: here we are doing one draw call for string of text which is // inefficient but is simpler and allows for individual scissors - glScissor(x, y, w, h); + ren_set_scissor(x, y, w, h); ren_draw_font_stack(); vtstack_clear(&ren.font_stack); diff --git a/text_rendering/test b/text_rendering/test index 484c873..585c5e6 100755 Binary files a/text_rendering/test and b/text_rendering/test differ