Added UIElement and Text; Custom fonts are supported

This commit is contained in:
grayson committed 2021-09-01 19:17:24 -05:00
1 parent c0f7634b5f
commit 65fd8e89bb
30 files changed
+346 -35

No files matched your search

-2
View File
@@ -24,8 +24,6 @@ namespace nf {
m_app->trackMouse(true);
else
m_app->trackMouse(false);
m_yaw = -90.0f;
m_pitch = 0.0f;
}
}
@@ -2,6 +2,8 @@
#include<vector>
#include "Shader.h"
namespace nf {
Entity::Entity() :
m_model(nullptr),
+4 -1
View File
@@ -7,7 +7,10 @@
#include "Texture.h"
namespace nf {
Model::Model() {
Model::Model() :
m_texture(nullptr)
{
}
void Model::create(const void* vertexBufferData, const size_t vertexBufferSize, const void* indexBufferData, size_t indexBufferCount, const void* textureCoordinatesBufferData, size_t textureCoordinatesBufferSize, const char* textureData, size_t textureSize) {
+113
View File
@@ -0,0 +1,113 @@
#include "Text.h"
#include "GL/glew.h"
#include "ft2build.h"
#include FT_FREETYPE_H
#include "UIElement.h"
#include "Shader.h"
namespace nf {
Text::Text() :
m_centered(false)
{
}
void Text::create(const std::string& string, const Vec2& position, const Vec3& color, unsigned int size, Asset* font) {
m_string = string;
m_position = position;
m_color = color;
FT_Library ft;
if (FT_Init_FreeType(&ft))
Error("Could not initialize FreeType!");
FT_Face face;
AFont& newFont = *(AFont*)font;
if (FT_New_Memory_Face(ft, (const unsigned char*)newFont.data, newFont.size, 0, &face))
Error("Could not load font!");
FT_Set_Pixel_Sizes(face, 0, size);
for (unsigned char c = 0; c < 128; c++) {
FT_Load_Char(face, c, FT_LOAD_RENDER);
unsigned int tex;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
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);
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);
Character ch = { tex, Vec2((float)face->glyph->bitmap.width, (float)face->glyph->bitmap.rows), Vec2(face->glyph->bitmap_left, face->glyph->bitmap_top), (unsigned int)face->glyph->advance.x };
m_font[c] = ch;
}
FT_Done_Face(face);
FT_Done_FreeType(ft);
m_vao = new VertexArray;
m_vao->addBuffer(nullptr, 0);
m_vao->push<float>(2);
m_vao->finishBufferLayout();
m_vao->addBuffer(nullptr, 0);
m_vao->push<float>(2);
m_vao->finishBufferLayout();
}
void Text::centered(bool centered) {
m_centered = centered;
}
const char* Text::identity() {
return "text";
}
void Text::render(Shader* shader, unsigned int windowWidth, unsigned int windowHeight) {
float scale = windowWidth / 4000.0f;
m_vao->bind();
std::string::const_iterator si;
float currX = (float)m_position.x * windowWidth, currY = (float)m_position.y * windowHeight;
if (m_centered) {
float textWidth = 0.0f;
float textHeight = 0.0f;
for (si = m_string.begin(); si != m_string.end(); si++) {
Character& c = m_font[*si];
textWidth += (c.advance >> 6) * scale;
if (c.size.y >= textHeight)
textHeight = (float)c.size.y * scale;
}
currX = ((float)windowWidth - textWidth) / 2;
currY = ((float)windowHeight - textHeight) / 2;
}
glm::vec3 color = { m_color.x, m_color.y, m_color.z };
shader->setUniform("textColor", color);
for (si = m_string.begin(); si != m_string.end(); si++) {
Character& c = m_font[*si];
float x = currX + (float)c.bearing.x * scale;
float y = currY - float(c.size.y - c.bearing.y) * scale;
float w = (float)c.size.x * scale;
float h = (float)c.size.y * scale;
float vb[3][4] = {
x, y + h,
x, y,
x + w, y,
x, y + h,
x + w, y,
x + w, y + h
};
float tc[3][4] = {
0.0, 0.0,
0.0, 1.0,
1.0, 1.0,
0.0, 0.0,
1.0, 1.0,
1.0, 0.0
};
glBindTexture(GL_TEXTURE_2D, c.texID);
m_vao->setBufferData(0, vb, sizeof(vb));
m_vao->setBufferData(1, tc, sizeof(tc));
glDrawArrays(GL_TRIANGLES, 0, 6);
currX += (c.advance >> 6) * scale;
}
}
Text::~Text() {
}
}
@@ -0,0 +1,19 @@
#include "UIElement.h"
namespace nf {
UIElement::UIElement() {
}
const char* UIElement::identity() {
return "none";
}
void UIElement::render(Shader* shader, unsigned int windowWidth, unsigned int windowHeight) {
}
UIElement::~UIElement() {
}
}
+30 -10
View File
@@ -5,6 +5,8 @@
#include "glm/glm.hpp"
#include "Application.h"
#include "Shader.h"
#include "UIElement.h"
#include "Utility.h"
namespace nf {
@@ -52,12 +54,16 @@ namespace nf {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_CULL_FACE);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
baseAP.load("base.nfpack");
const char* defaultVertex = baseAP["defaultVertex.shader"]->data;
const char* defaultFragment = baseAP["defaultFragment.shader"]->data;
m_defaultShader = new Shader(defaultVertex, defaultFragment);
const char* entityVertex = baseAP["entityVertex.shader"]->data;
const char* entityFragment = baseAP["entityFragment.shader"]->data;
m_entityShader = new Shader(entityVertex, entityFragment);
const char* textVertex = baseAP["textVertex.shader"]->data;
const char* textFragment = baseAP["textFragment.shader"]->data;
m_textShader = new Shader(textVertex, textFragment);
BaseAssets::cube = (AModel*)baseAP["cube.obj"];
BaseAssets::plane = (AModel*)baseAP["plane.obj"];
@@ -65,6 +71,7 @@ namespace nf {
BaseAssets::cone = (AModel*)baseAP["cone.obj"];
BaseAssets::cylinder = (AModel*)baseAP["cylinder.obj"];
BaseAssets::torus = (AModel*)baseAP["torus.obj"];
BaseAssets::defaultFont = (AFont*)baseAP["default.ttf"];
}
void Renderer::render(Entity& in) {
@@ -73,25 +80,38 @@ namespace nf {
m_lGame.push_back(&in);
//TODO: Sort transparent objects by distance; Farthest first
}
void Renderer::render(UIElement& in) {
if (&in == nullptr)
Error("Tried to render Entity before being created!");
m_lUI.push_back(&in);
//TODO: Sort transparent objects by distance; Farthest first
}
void Renderer::doFrame(Camera* camera) {
glViewport(0, 0, m_app->getConfig().width, m_app->getConfig().height);
glm::mat4 proj = glm::perspective(glm::radians(45.0f), (float)m_app->getConfig().width / (float)m_app->getConfig().height, 0.1f, 100000.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glm::mat4 proj = glm::perspective(glm::radians(45.0f), (float)m_app->getConfig().width / (float)m_app->getConfig().height, 0.1f, 100000.0f);
for (Entity* draw : m_lGame) {
Entity& curr = *draw;
curr.bind(m_defaultShader);
m_defaultShader->setUniform("proj", proj);
camera->bind(m_defaultShader);
curr.bind(m_entityShader);
m_entityShader->setUniform("proj", proj);
camera->bind(m_entityShader);
//TODO: Clean this up a bit
glDrawElements(GL_TRIANGLES, curr.getModel()->getIndexCount(), GL_UNSIGNED_INT, nullptr);
}
m_lGame.clear();
for (Drawable* draw : m_lUI) {
Drawable& curr = *draw;
proj = glm::ortho(0.0f, (float)m_app->getConfig().width, 0.0f, (float)m_app->getConfig().height);
for (UIElement* draw : m_lUI) {
UIElement& curr = *draw;
if (curr.identity() == "text") {
m_textShader->bind();
m_textShader->setUniform("proj", proj);
curr.render(m_textShader, m_app->getConfig().width, m_app->getConfig().height);
continue;
}
//TODO: Add else if for UI texture
}
m_lUI.clear();
+5
View File
@@ -52,6 +52,11 @@ namespace nf {
getUniformLocation(name);
glUniformMatrix4fv(m_uniformLocations[name], 1, GL_FALSE, glm::value_ptr(data));
}
void Shader::setUniform(const char* name, glm::vec3& data) {
if (m_uniformLocations.find(name) == m_uniformLocations.end())
getUniformLocation(name);
glUniform3fv(m_uniformLocations[name], 1, glm::value_ptr(data));
}
void Shader::getUniformLocation(const char* uniformName) {
unsigned int loc = glGetUniformLocation(m_id, uniformName);
+6
View File
@@ -50,6 +50,12 @@ namespace nf {
glBindVertexArray(m_id);
}
void VertexArray::setBufferData(unsigned int buffer, const void* data, const size_t dataSize) {
bind();
m_buffers[buffer]->bind();
glBufferData(GL_ARRAY_BUFFER, dataSize, data, GL_STATIC_DRAW);
}
VertexArray::~VertexArray() {
for (VertexBuffer* curr : m_buffers) {
delete curr;