Text rendering culling
This commit is contained in:
parent
76273e1c54
commit
0bdfa9e814
|
@ -14,12 +14,12 @@
|
||||||
|
|
||||||
#include <stb_truetype.h>
|
#include <stb_truetype.h>
|
||||||
#include "stb_rect_pack.h"
|
#include "stb_rect_pack.h"
|
||||||
|
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||||
|
#include "stb_image_write.h"
|
||||||
|
|
||||||
static uint32_t VBO = 0;
|
static uint32_t VBO = 0;
|
||||||
static uint32_t VAO = 0;
|
|
||||||
|
|
||||||
unsigned char ttf_buffer[1<<25];
|
unsigned char ttf_buffer[1<<25];
|
||||||
unsigned char temp_bitmap[512 * 512];
|
|
||||||
|
|
||||||
struct sFont *font;
|
struct sFont *font;
|
||||||
static struct shader *shader;
|
static struct shader *shader;
|
||||||
|
@ -29,22 +29,16 @@ void font_init(struct shader *textshader) {
|
||||||
|
|
||||||
shader_use(shader);
|
shader_use(shader);
|
||||||
|
|
||||||
// configure VAO/VBO for texture quads
|
|
||||||
glGenVertexArrays(1, &VAO);
|
|
||||||
glGenBuffers(1, &VBO);
|
glGenBuffers(1, &VBO);
|
||||||
glBindVertexArray(VAO);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||||
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 4 * 4, NULL, GL_DYNAMIC_DRAW);
|
|
||||||
|
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
|
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glBindVertexArray(0);
|
|
||||||
|
|
||||||
|
|
||||||
// Default font
|
// Default font
|
||||||
font = MakeFont("teenytinypixels.ttf", 16);
|
//font = MakeFont("teenytinypixels.ttf", 30);
|
||||||
|
font = MakeFont("LessPerfectDOSVGA.ttf", 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
void font_frame(struct window *w) {
|
void font_frame(struct window *w) {
|
||||||
|
@ -55,6 +49,8 @@ struct sFont *MakeFont(const char *fontfile, int height)
|
||||||
{
|
{
|
||||||
shader_use(shader);
|
shader_use(shader);
|
||||||
|
|
||||||
|
int packsize = 128;
|
||||||
|
|
||||||
struct sFont *newfont = calloc(1, sizeof(struct sFont));
|
struct sFont *newfont = calloc(1, sizeof(struct sFont));
|
||||||
newfont->height = height;
|
newfont->height = height;
|
||||||
|
|
||||||
|
@ -62,18 +58,17 @@ struct sFont *MakeFont(const char *fontfile, int height)
|
||||||
snprintf(fontpath, 256, "fonts/%s", fontfile);
|
snprintf(fontpath, 256, "fonts/%s", fontfile);
|
||||||
fread(ttf_buffer, 1, 1<<25, fopen(fontpath, "rb"));
|
fread(ttf_buffer, 1, 1<<25, fopen(fontpath, "rb"));
|
||||||
|
|
||||||
unsigned char *bitmap = malloc(1024*1024);
|
unsigned char *bitmap = malloc(packsize*packsize);
|
||||||
|
|
||||||
stbtt_packedchar glyphs[95];
|
stbtt_packedchar glyphs[95];
|
||||||
|
|
||||||
stbtt_pack_context pc;
|
stbtt_pack_context pc;
|
||||||
|
|
||||||
stbtt_PackBegin(&pc, bitmap, 1024, 1024, 0, 1, NULL);
|
stbtt_PackBegin(&pc, bitmap, packsize, packsize, 0, 1, NULL);
|
||||||
stbtt_PackSetOversampling(&pc, 1, 1);
|
|
||||||
stbtt_PackFontRange(&pc, ttf_buffer, 0, height, 32, 95, glyphs);
|
stbtt_PackFontRange(&pc, ttf_buffer, 0, height, 32, 95, glyphs);
|
||||||
stbtt_PackEnd(&pc);
|
stbtt_PackEnd(&pc);
|
||||||
|
|
||||||
|
stbi_write_png("packedfont.png", packsize, packsize, 1, bitmap, sizeof(char)*packsize);
|
||||||
|
|
||||||
stbtt_fontinfo fontinfo;
|
stbtt_fontinfo fontinfo;
|
||||||
if (!stbtt_InitFont(&fontinfo, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0))) {
|
if (!stbtt_InitFont(&fontinfo, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0))) {
|
||||||
|
@ -81,11 +76,11 @@ struct sFont *MakeFont(const char *fontfile, int height)
|
||||||
}
|
}
|
||||||
|
|
||||||
float scale = stbtt_ScaleForPixelHeight(&fontinfo, height);
|
float scale = stbtt_ScaleForPixelHeight(&fontinfo, height);
|
||||||
//glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
glGenTextures(1, &newfont->texID);
|
glGenTextures(1, &newfont->texID);
|
||||||
glBindTexture(GL_TEXTURE_2D, newfont->texID);
|
glBindTexture(GL_TEXTURE_2D, newfont->texID);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 1024, 1024, 0, GL_RED, GL_UNSIGNED_BYTE, bitmap);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, packsize, packsize, 0, GL_RED, GL_UNSIGNED_BYTE, bitmap);
|
||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
//glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
@ -94,24 +89,23 @@ struct sFont *MakeFont(const char *fontfile, int height)
|
||||||
|
|
||||||
|
|
||||||
for (unsigned char c = 32; c < 127; c++) {
|
for (unsigned char c = 32; c < 127; c++) {
|
||||||
//unsigned char *bitmap;
|
|
||||||
int advance, lsb, w, h, x0, y0;
|
|
||||||
stbtt_GetCodepointHMetrics(&fontinfo, c, &advance, &lsb);
|
|
||||||
stbtt_packedchar glyph = glyphs[c-32];
|
stbtt_packedchar glyph = glyphs[c-32];
|
||||||
|
|
||||||
YughInfo("Packed char is at %d, %d, %d, %d", glyphs[c-32].x0, glyphs[c-32].y0, glyphs[c-32].x1, glyphs[c-32].y1);
|
YughInfo("Packed char %c is at %d, %d, %d, %d", c, glyphs[c-32].x0, glyphs[c-32].y0, glyphs[c-32].x1, glyphs[c-32].y1);
|
||||||
|
|
||||||
|
YughInfo("Offsets are %f %f %f %f", glyph.xoff, glyph.yoff, glyph.xoff2, glyph.yoff2);
|
||||||
|
|
||||||
struct glrect r;
|
struct glrect r;
|
||||||
r.s0 = glyph.x0 / (float)1024;
|
r.s0 = glyph.x0 / (float) packsize;
|
||||||
r.s1 = glyph.x1 / (float) 1024;
|
r.s1 = glyph.x1 / (float) packsize;
|
||||||
r.t0 = glyph.y0 / (float) 1024;
|
r.t0 = glyph.y0 / (float) packsize;
|
||||||
r.t1 = glyph.y1 / (float) 1024;
|
r.t1 = glyph.y1 / (float) packsize;
|
||||||
YughInfo("That is %f %f %f %f", r.s0, r.t0, r.s1, r.t1);
|
|
||||||
newfont->Characters[c].Advance = advance * scale;
|
newfont->Characters[c].Advance = glyph.xadvance;
|
||||||
newfont->Characters[c].Size[0] = glyphs[c-32].x1 - glyphs[c-32].x0;
|
newfont->Characters[c].Size[0] = glyph.x1 - glyph.x0;
|
||||||
newfont->Characters[c].Size[1] = glyphs[c-32].y1 - glyphs[c-32].y0;
|
newfont->Characters[c].Size[1] = glyph.y1 - glyph.y0;
|
||||||
newfont->Characters[c].Bearing[0] = x0;
|
newfont->Characters[c].Bearing[0] = glyph.xoff;
|
||||||
newfont->Characters[c].Bearing[1] = y0*-1;
|
newfont->Characters[c].Bearing[1] = glyph.yoff2;
|
||||||
newfont->Characters[c].rect = r;
|
newfont->Characters[c].rect = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +120,7 @@ void sdrawCharacter(struct Character c, mfloat_t cursor[2], float scale, struct
|
||||||
float h = c.Size[1] * scale;
|
float h = c.Size[1] * scale;
|
||||||
|
|
||||||
float xpos = cursor[0] + c.Bearing[0] * scale;
|
float xpos = cursor[0] + c.Bearing[0] * scale;
|
||||||
float ypos = cursor[1] + (c.Bearing[1] * scale) - h;
|
float ypos = cursor[1] - c.Bearing[1] * scale;
|
||||||
|
|
||||||
float verts[4 * 4] = {
|
float verts[4 * 4] = {
|
||||||
xpos, ypos, c.rect.s0, c.rect.t1,
|
xpos, ypos, c.rect.s0, c.rect.t1,
|
||||||
|
@ -135,6 +129,9 @@ void sdrawCharacter(struct Character c, mfloat_t cursor[2], float scale, struct
|
||||||
xpos + w, ypos + h, c.rect.s1, c.rect.t0
|
xpos + w, ypos + h, c.rect.s1, c.rect.t0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (verts[5] < 0 || verts[10] < 0 || verts[0] > window_i(0)->width || verts[1] > window_i(0)->height)
|
||||||
|
return;
|
||||||
|
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, curchar*sizeof(verts), sizeof(verts), verts);
|
glBufferSubData(GL_ARRAY_BUFFER, curchar*sizeof(verts), sizeof(verts), verts);
|
||||||
|
|
||||||
curchar++;
|
curchar++;
|
||||||
|
@ -158,9 +155,10 @@ void renderText(const char *text, mfloat_t pos[2], float scale, mfloat_t color[3
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, font->texID);
|
glBindTexture(GL_TEXTURE_2D, font->texID);
|
||||||
glBindVertexArray(VAO);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||||
glBufferData(GL_ARRAY_BUFFER, len*16*sizeof(float), NULL, GL_STREAM_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, len*16*sizeof(float), NULL, GL_STREAM_DRAW);
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
|
||||||
|
|
||||||
const unsigned char *line, *wordstart;
|
const unsigned char *line, *wordstart;
|
||||||
line = (unsigned char*)text;
|
line = (unsigned char*)text;
|
||||||
|
|
|
@ -77,7 +77,7 @@ s7_pointer s7_gui_text(s7_scheme *sc, s7_pointer args) {
|
||||||
float size = s7_real(s7_caddr(args));
|
float size = s7_real(s7_caddr(args));
|
||||||
const float white[3] = {1.f, 1.f, 1.f};
|
const float white[3] = {1.f, 1.f, 1.f};
|
||||||
|
|
||||||
renderText(s, fpos, size, white, 200);
|
renderText(s, fpos, size, white, 1800);
|
||||||
|
|
||||||
return s7_car(args);
|
return s7_car(args);
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,8 @@ s7_pointer s7_log(s7_scheme *sc, s7_pointer args) {
|
||||||
s7_pointer s7_ui_rendertext(s7_scheme *sc, s7_pointer args) {
|
s7_pointer s7_ui_rendertext(s7_scheme *sc, s7_pointer args) {
|
||||||
const char *s = s7_string(s7_car(args));
|
const char *s = s7_string(s7_car(args));
|
||||||
s7_pointer s7pos = s7_cadr(args);
|
s7_pointer s7pos = s7_cadr(args);
|
||||||
double pos[2] = { s7_vector_ref(sc, s7pos, 0), s7_vector_ref(sc, s7pos, 1) };
|
cpVect cpos = s7tovec2(sc, s7_cadr(args));
|
||||||
|
double pos[2] = { cpos.x, cpos.y };
|
||||||
double size = s7_real(s7_caddr(args));
|
double size = s7_real(s7_caddr(args));
|
||||||
double white[3] = {1.f, 1.f, 1.f};
|
double white[3] = {1.f, 1.f, 1.f};
|
||||||
|
|
||||||
|
@ -247,6 +248,9 @@ s7_pointer s7_sys_cmd(s7_scheme *sc, s7_pointer args) {
|
||||||
case 7:
|
case 7:
|
||||||
return s7_make_integer(sc, MakeGameobject());
|
return s7_make_integer(sc, MakeGameobject());
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
return s7_make_integer(sc, frame_fps());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
|
@ -346,7 +350,7 @@ s7_pointer s7_phys_cmd(s7_scheme *sc, s7_pointer args) {
|
||||||
int cmd = s7_integer(s7_cadr(args));
|
int cmd = s7_integer(s7_cadr(args));
|
||||||
s7_pointer env = s7_caddr(args);
|
s7_pointer env = s7_caddr(args);
|
||||||
|
|
||||||
if (go == -1) return;
|
if (go == -1) return s7_nil(sc);
|
||||||
|
|
||||||
phys2d_add_handler_type(cmd, get_gameobject_from_id(go), env);
|
phys2d_add_handler_type(cmd, get_gameobject_from_id(go), env);
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,6 +94,8 @@ void openglInit()
|
||||||
glClearColor(editorClearColor[0], editorClearColor[1], editorClearColor[2], editorClearColor[3]);
|
glClearColor(editorClearColor[0], editorClearColor[1], editorClearColor[2], editorClearColor[3]);
|
||||||
|
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
|
glCullFace(GL_BACK);
|
||||||
|
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,10 @@ static double lastTick;
|
||||||
|
|
||||||
static float timescale = 1.f;
|
static float timescale = 1.f;
|
||||||
|
|
||||||
static double framems;
|
#define FPSBUF 10
|
||||||
|
static double framems[FPSBUF];
|
||||||
|
int framei = 0;
|
||||||
|
int fps;
|
||||||
|
|
||||||
void seghandle(int sig) {
|
void seghandle(int sig) {
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
@ -172,7 +175,12 @@ int main(int argc, char **args) {
|
||||||
double elapsed = glfwGetTime() - lastTick;
|
double elapsed = glfwGetTime() - lastTick;
|
||||||
deltaT = elapsed;
|
deltaT = elapsed;
|
||||||
lastTick = glfwGetTime();
|
lastTick = glfwGetTime();
|
||||||
|
double wait = fmax(0, renderMS-elapsed);
|
||||||
|
input_poll(wait);
|
||||||
|
window_all_handle_events();
|
||||||
|
|
||||||
|
framems[framei++] = elapsed;
|
||||||
|
if (framei == FPSBUF) framei = 0;
|
||||||
|
|
||||||
timer_update(elapsed);
|
timer_update(elapsed);
|
||||||
|
|
||||||
|
@ -194,14 +202,21 @@ int main(int argc, char **args) {
|
||||||
window_renderall();
|
window_renderall();
|
||||||
}
|
}
|
||||||
|
|
||||||
double wait = fmax(0, renderMS-elapsed);
|
|
||||||
input_poll(wait);
|
|
||||||
window_all_handle_events();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int frame_fps()
|
||||||
|
{
|
||||||
|
double fpsms = 0;
|
||||||
|
for (int i = 0; i < FPSBUF; i++) {
|
||||||
|
fpsms += framems[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return floor((float)FPSBUF / fpsms);
|
||||||
|
}
|
||||||
|
|
||||||
int sim_playing() { return sim_play; }
|
int sim_playing() { return sim_play; }
|
||||||
int sim_paused() { return (!sim_play && gameobjects_saved()); }
|
int sim_paused() { return (!sim_play && gameobjects_saved()); }
|
||||||
|
|
||||||
|
|
|
@ -9,5 +9,7 @@ void sim_stop();
|
||||||
void sim_step();
|
void sim_step();
|
||||||
void set_timescale(float val);
|
void set_timescale(float val);
|
||||||
|
|
||||||
|
int frame_fps();
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -49,6 +49,7 @@
|
||||||
(define (load_level s) (gen_cmd 0 s))
|
(define (load_level s) (gen_cmd 0 s))
|
||||||
(define (load_prefab s) (gen_cmd 1 s))
|
(define (load_prefab s) (gen_cmd 1 s))
|
||||||
(define (newobject) (sys_cmd 7))
|
(define (newobject) (sys_cmd 7))
|
||||||
|
(define (fps) (sys_cmd 8))
|
||||||
(define (quit) (sys_cmd 0))
|
(define (quit) (sys_cmd 0))
|
||||||
(define (exit) (quit))
|
(define (exit) (quit))
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,9 @@ uniform vec3 textColor;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec4 sampled = vec4(1.0, 1.0, 1.0, texture(text, TexCoords).r);
|
//vec4 sampled = vec4(1.0, 1.0, 1.0, texture(text, TexCoords).r);
|
||||||
color = vec4(textColor, 1.0) * sampled;
|
//color = vec4(textColor, 1.0) * sampled;
|
||||||
|
color = vec4(1.0, 1.0, 1.0, texture(text, TexCoords).r);
|
||||||
if (color.a <= 0.1f)
|
//if (color.a <= 0.1f)
|
||||||
discard;
|
//discard;
|
||||||
}
|
}
|
Loading…
Reference in a new issue