feat(rendering): ttf font rendering
This commit is contained in:
parent
82c0a86235
commit
19f048b52a
24 changed files with 381 additions and 42 deletions
16
assets/font/AUTHORS
Normal file
16
assets/font/AUTHORS
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
AUTHORS
|
||||||
|
|
||||||
|
Current Contributors (sorted alphabetically):
|
||||||
|
|
||||||
|
- Vishal Vijayraghavan <vishalvvr at fedoraproject dot org>
|
||||||
|
Project Owner/ Maintainer (Current)
|
||||||
|
Red Hat, Inc.
|
||||||
|
|
||||||
|
Previous Contributors
|
||||||
|
- Pravin Satpute <psatpute at redhat dot com>
|
||||||
|
Project Owner/ Maintainer
|
||||||
|
Red Hat, Inc.
|
||||||
|
|
||||||
|
- Steve Matteson
|
||||||
|
Original Designer
|
||||||
|
Ascender, Inc.
|
102
assets/font/LICENSE
Normal file
102
assets/font/LICENSE
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
Digitized data copyright (c) 2010 Google Corporation
|
||||||
|
with Reserved Font Arimo, Tinos and Cousine.
|
||||||
|
Copyright (c) 2012 Red Hat, Inc.
|
||||||
|
with Reserved Font Name Liberation.
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License,
|
||||||
|
Version 1.1.
|
||||||
|
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
http://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
|
||||||
|
PREAMBLE The goals of the Open Font License (OFL) are to stimulate
|
||||||
|
worldwide development of collaborative font projects, to support the font
|
||||||
|
creation efforts of academic and linguistic communities, and to provide
|
||||||
|
a free and open framework in which fonts may be shared and improved in
|
||||||
|
partnership with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves.
|
||||||
|
The fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply to
|
||||||
|
any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such.
|
||||||
|
This may include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components
|
||||||
|
as distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting ? in part or in whole ?
|
||||||
|
any of the components of the Original Version, by changing formats or
|
||||||
|
by porting the Font Software to a new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical writer
|
||||||
|
or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,in
|
||||||
|
Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the
|
||||||
|
corresponding Copyright Holder. This restriction only applies to the
|
||||||
|
primary font name as presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole, must
|
||||||
|
be distributed entirely under this license, and must not be distributed
|
||||||
|
under any other license. The requirement for fonts to remain under
|
||||||
|
this license does not apply to any document created using the Font
|
||||||
|
Software.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are not met.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER
|
||||||
|
DEALINGS IN THE FONT SOFTWARE.
|
||||||
|
|
BIN
assets/font/LiberationMono-Bold.ttf
Normal file
BIN
assets/font/LiberationMono-Bold.ttf
Normal file
Binary file not shown.
BIN
assets/font/LiberationMono-BoldItalic.ttf
Normal file
BIN
assets/font/LiberationMono-BoldItalic.ttf
Normal file
Binary file not shown.
BIN
assets/font/LiberationMono-Italic.ttf
Normal file
BIN
assets/font/LiberationMono-Italic.ttf
Normal file
Binary file not shown.
BIN
assets/font/LiberationMono-Regular.ttf
Normal file
BIN
assets/font/LiberationMono-Regular.ttf
Normal file
Binary file not shown.
BIN
assets/font/LiberationSans-Bold.ttf
Normal file
BIN
assets/font/LiberationSans-Bold.ttf
Normal file
Binary file not shown.
BIN
assets/font/LiberationSans-BoldItalic.ttf
Normal file
BIN
assets/font/LiberationSans-BoldItalic.ttf
Normal file
Binary file not shown.
BIN
assets/font/LiberationSans-Italic.ttf
Normal file
BIN
assets/font/LiberationSans-Italic.ttf
Normal file
Binary file not shown.
BIN
assets/font/LiberationSans-Regular.ttf
Normal file
BIN
assets/font/LiberationSans-Regular.ttf
Normal file
Binary file not shown.
BIN
assets/font/LiberationSerif-Bold.ttf
Normal file
BIN
assets/font/LiberationSerif-Bold.ttf
Normal file
Binary file not shown.
BIN
assets/font/LiberationSerif-BoldItalic.ttf
Normal file
BIN
assets/font/LiberationSerif-BoldItalic.ttf
Normal file
Binary file not shown.
BIN
assets/font/LiberationSerif-Italic.ttf
Normal file
BIN
assets/font/LiberationSerif-Italic.ttf
Normal file
Binary file not shown.
BIN
assets/font/LiberationSerif-Regular.ttf
Normal file
BIN
assets/font/LiberationSerif-Regular.ttf
Normal file
Binary file not shown.
22
assets/shaders/debug/debugfont.fs
Normal file
22
assets/shaders/debug/debugfont.fs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
out vec4 FragColor;
|
||||||
|
in vec3 vPos;
|
||||||
|
in vec2 vTexCoord;
|
||||||
|
|
||||||
|
uniform sampler2D fontTex;
|
||||||
|
uniform int charIndex;
|
||||||
|
|
||||||
|
// Main
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
int x = (charIndex-32) % 16;
|
||||||
|
int y = (charIndex-32) / 16;
|
||||||
|
|
||||||
|
float fx = float(x) / 16;
|
||||||
|
float fy = float(y) / 8;
|
||||||
|
|
||||||
|
vec4 color = texture(fontTex, vec2(fx, fy) + vTexCoord * vec2(1.f/32, 1.f/16));
|
||||||
|
FragColor = vec3(color) == vec3(0, 0, 0) ? vec4(0, 0, 0, 0) : color;
|
||||||
|
// FragColor = color;
|
||||||
|
}
|
12
assets/shaders/debug/debugfont.vs
Normal file
12
assets/shaders/debug/debugfont.vs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#version 330 core
|
||||||
|
in vec3 aPos;
|
||||||
|
in vec2 aTexCoord;
|
||||||
|
|
||||||
|
out vec3 vPos;
|
||||||
|
out vec2 vTexCoord;
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = vec4(aPos, 1.0);
|
||||||
|
vPos = aPos;
|
||||||
|
vTexCoord = aTexCoord;
|
||||||
|
}
|
|
@ -1,22 +1,14 @@
|
||||||
|
// https://learnopengl.com/In-Practice/Text-Rendering
|
||||||
|
|
||||||
#version 330 core
|
#version 330 core
|
||||||
|
in vec2 TexCoords;
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
out vec4 FragColor;
|
uniform sampler2D text;
|
||||||
in vec3 vPos;
|
uniform vec3 textColor;
|
||||||
in vec2 vTexCoord;
|
|
||||||
|
|
||||||
uniform sampler2D fontTex;
|
void main()
|
||||||
uniform int charIndex;
|
{
|
||||||
|
vec4 sampled = vec4(1.0, 1.0, 1.0, texture(text, TexCoords).r);
|
||||||
// Main
|
color = vec4(textColor, 1.0) * sampled;
|
||||||
|
|
||||||
void main() {
|
|
||||||
int x = (charIndex-32) % 16;
|
|
||||||
int y = (charIndex-32) / 16;
|
|
||||||
|
|
||||||
float fx = float(x) / 16;
|
|
||||||
float fy = float(y) / 8;
|
|
||||||
|
|
||||||
vec4 color = texture(fontTex, vec2(fx, fy) + vTexCoord * vec2(1.f/32, 1.f/16));
|
|
||||||
FragColor = vec3(color) == vec3(0, 0, 0) ? vec4(0, 0, 0, 0) : color;
|
|
||||||
// FragColor = color;
|
|
||||||
}
|
}
|
|
@ -1,12 +1,13 @@
|
||||||
#version 330 core
|
// https://learnopengl.com/In-Practice/Text-Rendering
|
||||||
in vec3 aPos;
|
|
||||||
in vec2 aTexCoord;
|
#version 330 core
|
||||||
|
layout (location = 0) in vec4 vertex; // <vec2 pos, vec2 tex>
|
||||||
|
out vec2 TexCoords;
|
||||||
|
|
||||||
|
uniform mat4 projection;
|
||||||
|
|
||||||
out vec3 vPos;
|
|
||||||
out vec2 vTexCoord;
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = vec4(aPos, 1.0);
|
gl_Position = projection * vec4(vertex.xy, 0.0, 1.0);
|
||||||
vPos = aPos;
|
TexCoords = vertex.zw;
|
||||||
vTexCoord = aTexCoord;
|
|
||||||
}
|
}
|
|
@ -7,6 +7,7 @@ find_package(OpenGL)
|
||||||
find_package(glm CONFIG REQUIRED)
|
find_package(glm CONFIG REQUIRED)
|
||||||
find_package(ReactPhysics3D REQUIRED)
|
find_package(ReactPhysics3D REQUIRED)
|
||||||
find_package(pugixml 1.15 REQUIRED)
|
find_package(pugixml 1.15 REQUIRED)
|
||||||
|
find_package(Freetype)
|
||||||
|
|
||||||
find_package(Stb REQUIRED)
|
find_package(Stb REQUIRED)
|
||||||
include_directories(${Stb_INCLUDE_DIR})
|
include_directories(${Stb_INCLUDE_DIR})
|
||||||
|
@ -44,7 +45,7 @@ list(APPEND SOURCES ${AUTOGEN_OUTS})
|
||||||
add_library(openblocks STATIC ${SOURCES})
|
add_library(openblocks STATIC ${SOURCES})
|
||||||
set_target_properties(openblocks PROPERTIES OUTPUT_NAME "openblocks")
|
set_target_properties(openblocks PROPERTIES OUTPUT_NAME "openblocks")
|
||||||
target_link_directories(openblocks PUBLIC ${LUAJIT_LIBRARY_DIRS})
|
target_link_directories(openblocks PUBLIC ${LUAJIT_LIBRARY_DIRS})
|
||||||
target_link_libraries(openblocks ${GLEW_LIBRARIES} ${LUAJIT_LIBRARIES} OpenGL::GL ReactPhysics3D::ReactPhysics3D pugixml::pugixml)
|
target_link_libraries(openblocks ${GLEW_LIBRARIES} ${LUAJIT_LIBRARIES} OpenGL::GL ReactPhysics3D::ReactPhysics3D pugixml::pugixml Freetype::Freetype)
|
||||||
target_include_directories(openblocks PUBLIC "src" "../include" ${LUAJIT_INCLUDE_DIRS})
|
target_include_directories(openblocks PUBLIC "src" "../include" ${LUAJIT_INCLUDE_DIRS})
|
||||||
add_dependencies(openblocks autogen_build autogen)
|
add_dependencies(openblocks autogen_build autogen)
|
||||||
|
|
||||||
|
|
|
@ -7,19 +7,19 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
extern int viewportWidth, viewportHeight;
|
extern int viewportWidth, viewportHeight;
|
||||||
extern Texture* fontTexture;
|
extern Texture* debugFontTexture;
|
||||||
extern Shader* fontShader;
|
extern Shader* debugFontShader;
|
||||||
extern Shader* identityShader;
|
extern Shader* identityShader;
|
||||||
|
|
||||||
void drawChar(char c, int x, int y, float scale=1.f) {
|
void drawChar(char c, int x, int y, float scale=1.f) {
|
||||||
fontShader->use();
|
debugFontShader->use();
|
||||||
fontTexture->activate(1);
|
debugFontTexture->activate(1);
|
||||||
fontShader->set("fontTex", 1);
|
debugFontShader->set("fontTex", 1);
|
||||||
|
|
||||||
fontShader->set("charIndex", (int)c);
|
debugFontShader->set("charIndex", (int)c);
|
||||||
|
|
||||||
// https://stackoverflow.com/a/10631263
|
// https://stackoverflow.com/a/10631263
|
||||||
int tex = fontShader->getAttribute("aTexCoord");
|
int tex = debugFontShader->getAttribute("aTexCoord");
|
||||||
|
|
||||||
y = viewportHeight - y - 16*scale;
|
y = viewportHeight - y - 16*scale;
|
||||||
float x0 = float(x)/viewportWidth, y0 = float(y)/viewportHeight, x1 = ((float)x + 8*scale)/viewportWidth, y1 = ((float)y + 16*scale)/viewportHeight;
|
float x0 = float(x)/viewportWidth, y0 = float(y)/viewportHeight, x1 = ((float)x + 8*scale)/viewportWidth, y1 = ((float)y + 16*scale)/viewportHeight;
|
||||||
|
|
162
core/src/rendering/font.cpp
Normal file
162
core/src/rendering/font.cpp
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
#include "font.h"
|
||||||
|
#include "logger.h"
|
||||||
|
#include "panic.h"
|
||||||
|
#include "rendering/shader.h"
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <GL/gl.h>
|
||||||
|
#include <glm/ext/matrix_clip_space.hpp>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
|
||||||
|
// https://learnopengl.com/In-Practice/Text-Rendering
|
||||||
|
|
||||||
|
FT_Library freetype;
|
||||||
|
Shader* fontShader;
|
||||||
|
|
||||||
|
extern int viewportWidth, viewportHeight;
|
||||||
|
|
||||||
|
unsigned int textVAO, textVBO;
|
||||||
|
|
||||||
|
void fontInit() {
|
||||||
|
if (FT_Error err = FT_Init_FreeType(&freetype)) {
|
||||||
|
Logger::fatalErrorf("Failed to initialize Freetype: [%d]", err);
|
||||||
|
panic();
|
||||||
|
}
|
||||||
|
|
||||||
|
fontShader = new Shader("assets/shaders/font.vs", "assets/shaders/font.fs");
|
||||||
|
|
||||||
|
// Set up buffer
|
||||||
|
glGenVertexArrays(1, &textVAO);
|
||||||
|
glBindVertexArray(textVAO);
|
||||||
|
|
||||||
|
glGenBuffers(1, &textVBO);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, textVBO);
|
||||||
|
|
||||||
|
// Dynamic, because we update the vertices often V~~~~~~~~~~~~~~
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6 * 4, NULL, GL_DYNAMIC_DRAW);
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
|
||||||
|
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fontFinish() {
|
||||||
|
if (FT_Error err = FT_Done_FreeType(freetype)) {
|
||||||
|
Logger::fatalErrorf("Failed to free Freetype: [%d]", err);
|
||||||
|
panic();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Font> loadFont(std::string fontName) {
|
||||||
|
std::string fontPath = "assets/font/" + fontName;
|
||||||
|
|
||||||
|
FT_Face face;
|
||||||
|
if (FT_Error err = FT_New_Face(freetype, fontPath.c_str(), 0, &face)) {
|
||||||
|
Logger::fatalErrorf("Failed to create font '%s': [%d]", fontName.c_str(), err);
|
||||||
|
panic();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Font> font = std::make_shared<Font>();
|
||||||
|
|
||||||
|
FT_Set_Pixel_Sizes(face, 0, 48);
|
||||||
|
|
||||||
|
// Load each glyph
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
for (unsigned char c = 0; c < 128; c++) {
|
||||||
|
// load character glyph
|
||||||
|
if (FT_Error err = FT_Load_Char(face, c, FT_LOAD_RENDER)) {
|
||||||
|
Logger::errorf("Failed to load glyph %d in font '%s': [%d]", c, fontName.c_str(), err);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate texture
|
||||||
|
unsigned int texture;
|
||||||
|
glGenTextures(1, &texture);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture);
|
||||||
|
glTexImage2D(
|
||||||
|
GL_TEXTURE_2D,
|
||||||
|
0,
|
||||||
|
GL_RED,
|
||||||
|
face->glyph->bitmap.width,
|
||||||
|
face->glyph->bitmap.rows,
|
||||||
|
0,
|
||||||
|
GL_RED,
|
||||||
|
GL_UNSIGNED_BYTE,
|
||||||
|
face->glyph->bitmap.buffer
|
||||||
|
);
|
||||||
|
// set texture options
|
||||||
|
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_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
// now store character for later use
|
||||||
|
Character character;
|
||||||
|
character.ID = texture;
|
||||||
|
character.size = glm::ivec2(face->glyph->bitmap.width, face->glyph->bitmap.rows);
|
||||||
|
character.bearing = glm::ivec2(face->glyph->bitmap_left, face->glyph->bitmap_top);
|
||||||
|
character.advance = (unsigned int)face->glyph->advance.x;
|
||||||
|
font->characters[c] = character;
|
||||||
|
}
|
||||||
|
|
||||||
|
FT_Done_Face(face);
|
||||||
|
|
||||||
|
return font;
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawText(std::shared_ptr<Font> font, std::string text, float x, float y, float scale, glm::vec3 color) {
|
||||||
|
// activate corresponding render state
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
fontShader->use();
|
||||||
|
fontShader->set("textColor", color);
|
||||||
|
fontShader->set("text", 0);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
|
glm::mat4 projection = glm::ortho(0.0f, (float)viewportWidth, 0.0f, (float)viewportHeight);
|
||||||
|
fontShader->set("projection", projection);
|
||||||
|
|
||||||
|
// This is not in the learnopengl guide but it is VERY important
|
||||||
|
// I'm surprised I missed it but honestly... not so much. I'm an idiot
|
||||||
|
glBindVertexArray(textVAO);
|
||||||
|
|
||||||
|
// iterate through all characters
|
||||||
|
for (size_t i = 0; i < text.size(); i++) {
|
||||||
|
unsigned char c = text[i];
|
||||||
|
Character ch = font->characters[c];
|
||||||
|
|
||||||
|
float xpos = x + ch.bearing.x * scale;
|
||||||
|
float ypos = y - (ch.size.y - ch.bearing.y) * scale;
|
||||||
|
|
||||||
|
float w = ch.size.x * scale;
|
||||||
|
float h = ch.size.y * scale;
|
||||||
|
// render glyph texture over quad
|
||||||
|
glBindTexture(GL_TEXTURE_2D, ch.ID);
|
||||||
|
|
||||||
|
float vertices[6][4] = {
|
||||||
|
{ xpos, ypos + h, 0.0f, 0.0f },
|
||||||
|
{ xpos, ypos, 0.0f, 1.0f },
|
||||||
|
{ xpos + w, ypos, 1.0f, 1.0f },
|
||||||
|
|
||||||
|
{ xpos, ypos + h, 0.0f, 0.0f },
|
||||||
|
{ xpos + w, ypos, 1.0f, 1.0f },
|
||||||
|
{ xpos + w, ypos + h, 1.0f, 0.0f }
|
||||||
|
};
|
||||||
|
// render glyph texture over quad
|
||||||
|
glBindTexture(GL_TEXTURE_2D, ch.ID);
|
||||||
|
// update content of VBO memory
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, textVBO);
|
||||||
|
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
// render quad
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||||
|
// now advance cursors for next glyph (note that advance is number of 1/64 pixels)
|
||||||
|
x += (ch.advance >> 6) * scale; // bitshift by 6 to get value in pixels (2^6 = 64)
|
||||||
|
}
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
23
core/src/rendering/font.h
Normal file
23
core/src/rendering/font.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
// https://learnopengl.com/In-Practice/Text-Rendering
|
||||||
|
|
||||||
|
struct Character {
|
||||||
|
unsigned int ID; // ID handle of the glyph texture
|
||||||
|
glm::ivec2 size; // Size of glyph
|
||||||
|
glm::ivec2 bearing; // Offset from baseline to left/top of glyph
|
||||||
|
unsigned int advance; // Offset to advance to next glyph
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Font {
|
||||||
|
Character characters[128];
|
||||||
|
};
|
||||||
|
|
||||||
|
void fontInit();
|
||||||
|
void fontFinish();
|
||||||
|
std::shared_ptr<Font> loadFont(std::string fontName);
|
||||||
|
void drawText(std::shared_ptr<Font> font, std::string text, float x, float y, float scale=1.f, glm::vec3 color = glm::vec3(1,1,1));
|
|
@ -23,6 +23,7 @@
|
||||||
#include "math_helper.h"
|
#include "math_helper.h"
|
||||||
#include "objects/service/selection.h"
|
#include "objects/service/selection.h"
|
||||||
#include "partassembly.h"
|
#include "partassembly.h"
|
||||||
|
#include "rendering/font.h"
|
||||||
#include "rendering/mesh2d.h"
|
#include "rendering/mesh2d.h"
|
||||||
#include "rendering/texture.h"
|
#include "rendering/texture.h"
|
||||||
#include "rendering/torus.h"
|
#include "rendering/torus.h"
|
||||||
|
@ -46,14 +47,16 @@ Shader* identityShader = NULL;
|
||||||
Shader* ghostShader = NULL;
|
Shader* ghostShader = NULL;
|
||||||
Shader* wireframeShader = NULL;
|
Shader* wireframeShader = NULL;
|
||||||
Shader* outlineShader = NULL;
|
Shader* outlineShader = NULL;
|
||||||
Shader* fontShader = NULL;
|
Shader* debugFontShader = NULL;
|
||||||
Shader* generic2dShader = NULL;
|
Shader* generic2dShader = NULL;
|
||||||
extern Camera camera;
|
extern Camera camera;
|
||||||
Skybox* skyboxTexture = NULL;
|
Skybox* skyboxTexture = NULL;
|
||||||
Texture3D* studsTexture = NULL;
|
Texture3D* studsTexture = NULL;
|
||||||
Texture* fontTexture = NULL;
|
Texture* debugFontTexture = NULL;
|
||||||
Mesh2D* rect2DMesh = NULL;
|
Mesh2D* rect2DMesh = NULL;
|
||||||
|
|
||||||
|
std::shared_ptr<Font> sansSerif;
|
||||||
|
|
||||||
bool debugRendererEnabled = false;
|
bool debugRendererEnabled = false;
|
||||||
bool wireframeRendering = false;
|
bool wireframeRendering = false;
|
||||||
|
|
||||||
|
@ -74,7 +77,7 @@ void renderInit(GLFWwindow* window, int width, int height) {
|
||||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
fontTexture = new Texture("assets/textures/debugfnt.bmp", GL_RGB);
|
debugFontTexture = new Texture("assets/textures/debugfnt.bmp", GL_RGB);
|
||||||
|
|
||||||
skyboxTexture = new Skybox({
|
skyboxTexture = new Skybox({
|
||||||
"assets/textures/skybox/null_plainsky512_lf.jpg",
|
"assets/textures/skybox/null_plainsky512_lf.jpg",
|
||||||
|
@ -95,7 +98,7 @@ void renderInit(GLFWwindow* window, int width, int height) {
|
||||||
ghostShader = new Shader("assets/shaders/ghost.vs", "assets/shaders/ghost.fs");
|
ghostShader = new Shader("assets/shaders/ghost.vs", "assets/shaders/ghost.fs");
|
||||||
wireframeShader = new Shader("assets/shaders/wireframe.vs", "assets/shaders/wireframe.fs");
|
wireframeShader = new Shader("assets/shaders/wireframe.vs", "assets/shaders/wireframe.fs");
|
||||||
outlineShader = new Shader("assets/shaders/outline.vs", "assets/shaders/outline.fs");
|
outlineShader = new Shader("assets/shaders/outline.vs", "assets/shaders/outline.fs");
|
||||||
fontShader = new Shader("assets/shaders/font.vs", "assets/shaders/font.fs");
|
debugFontShader = new Shader("assets/shaders/debug/debugfont.vs", "assets/shaders/debug/debugfont.fs");
|
||||||
generic2dShader = new Shader("assets/shaders/generic2d.vs", "assets/shaders/generic2d.fs");
|
generic2dShader = new Shader("assets/shaders/generic2d.vs", "assets/shaders/generic2d.fs");
|
||||||
|
|
||||||
// Create mesh for 2d rectangle
|
// Create mesh for 2d rectangle
|
||||||
|
@ -110,6 +113,10 @@ void renderInit(GLFWwindow* window, int width, int height) {
|
||||||
};
|
};
|
||||||
|
|
||||||
rect2DMesh = new Mesh2D(6, rectVerts);
|
rect2DMesh = new Mesh2D(6, rectVerts);
|
||||||
|
|
||||||
|
// Initialize fonts
|
||||||
|
fontInit();
|
||||||
|
sansSerif = loadFont("LiberationSans-Regular.ttf");
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderParts() {
|
void renderParts() {
|
||||||
|
@ -356,7 +363,6 @@ void renderHandles() {
|
||||||
glm::vec4 screenPos = projection * view * glm::vec4((glm::vec3)cframe.Position(), 1.0f);
|
glm::vec4 screenPos = projection * view * glm::vec4((glm::vec3)cframe.Position(), 1.0f);
|
||||||
screenPos /= screenPos.w;
|
screenPos /= screenPos.w;
|
||||||
screenPos += 1; screenPos /= 2; screenPos.y = 1 - screenPos.y; screenPos *= glm::vec4(glm::vec2(viewportWidth, viewportHeight), 1, 1);
|
screenPos += 1; screenPos /= 2; screenPos.y = 1 - screenPos.y; screenPos *= glm::vec4(glm::vec2(viewportWidth, viewportHeight), 1, 1);
|
||||||
printVec((glm::vec3)screenPos);
|
|
||||||
|
|
||||||
drawRect(screenPos.x - 3, screenPos.y - 3, 6, 6, glm::vec3(0, 1, 1));
|
drawRect(screenPos.x - 3, screenPos.y - 3, 6, 6, glm::vec3(0, 1, 1));
|
||||||
}
|
}
|
||||||
|
@ -664,6 +670,7 @@ void render(GLFWwindow* window) {
|
||||||
renderDebugInfo();
|
renderDebugInfo();
|
||||||
// TODO: Make this a debug flag
|
// TODO: Make this a debug flag
|
||||||
// renderAABB();
|
// renderAABB();
|
||||||
|
|
||||||
renderTime = tu_clock_micros() - startTime;
|
renderTime = tu_clock_micros() - startTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
1
deps.txt
1
deps.txt
|
@ -9,3 +9,4 @@ reactphysics3d
|
||||||
pugixml
|
pugixml
|
||||||
luajit
|
luajit
|
||||||
qscintilla
|
qscintilla
|
||||||
|
freetype2
|
Loading…
Add table
Reference in a new issue