static void gl_render_msg(gl_t *gl, const char *msg) { if (!gl->font) return; GLfloat font_vertex[8]; GLfloat font_vertex_dark[8]; GLfloat font_tex_coords[8]; // Deactivate custom shaders. Enable the font texture. gl_shader_use(0); set_viewport(gl, gl->win_width, gl->win_height, false, false); glBindTexture(GL_TEXTURE_2D, gl->font_tex); glTexCoordPointer(2, GL_FLOAT, 0, font_tex_coords); // Need blending. // Using fixed function pipeline here since we cannot guarantee presence of shaders (would be kinda overkill anyways). glEnable(GL_BLEND); struct font_output_list out; // If we get the same message, there's obviously no need to render fonts again ... if (strcmp(gl->font_last_msg, msg) != 0) { font_renderer_msg(gl->font, msg, &out); struct font_output *head = out.head; struct font_rect geom; calculate_msg_geometry(head, &geom); adjust_power_of_two(gl, &geom); blit_fonts(gl, head, &geom); font_renderer_free_output(&out); strlcpy(gl->font_last_msg, msg, sizeof(gl->font_last_msg)); gl->font_last_width = geom.width; gl->font_last_height = geom.height; } calculate_font_coords(gl, font_vertex, font_vertex_dark, font_tex_coords); glVertexPointer(2, GL_FLOAT, 0, font_vertex_dark); glColorPointer(4, GL_FLOAT, 0, gl->font_color_dark); glDrawArrays(GL_QUADS, 0, 4); glVertexPointer(2, GL_FLOAT, 0, font_vertex); glColorPointer(4, GL_FLOAT, 0, gl->font_color); glDrawArrays(GL_QUADS, 0, 4); // Go back to old rendering path. glTexCoordPointer(2, GL_FLOAT, 0, gl->tex_coords); glVertexPointer(2, GL_FLOAT, 0, vertexes_flipped); glColorPointer(4, GL_FLOAT, 0, white_color); glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]); glDisable(GL_BLEND); set_projection(gl, true); }
static void rpi_render_message(rpi_t *rpi, const char *msg) { free(rpi->mLastMsg); rpi->mLastMsg = strdup(msg); if (rpi->mMsgLength) { while (--rpi->mMsgLength) vgClearGlyph(rpi->mFont, rpi->mMsgLength); vgClearGlyph(rpi->mFont, 0); } struct font_output_list out; font_renderer_msg(rpi->mFontRenderer, msg, &out); struct font_output *head = out.head; while (head) { if (rpi->mMsgLength >= 1024) break; VGfloat origin[2], escapement[2]; VGImage img; escapement[0] = head->advance_x; escapement[1] = head->advance_y; origin[0] = -head->char_off_x; origin[1] = -head->char_off_y; img = vgCreateImage(VG_A_8, head->width, head->height, VG_IMAGE_QUALITY_NONANTIALIASED); // flip it for (unsigned i = 0; i < head->height; i++) vgImageSubData(img, head->output + head->pitch * i, head->pitch, VG_A_8, 0, head->height - i - 1, head->width, 1); vgSetGlyphToImage(rpi->mFont, rpi->mMsgLength, img, origin, escapement); vgDestroyImage(img); rpi->mMsgLength++; head = head->next; } font_renderer_free_output(&out); for (unsigned i = 0; i < rpi->mMsgLength; i++) rpi->mGlyphIndices[i] = i; }