Added UITexture and font caching

This commit is contained in:
grayson committed 2021-09-02 02:21:27 -05:00
1 parent 2af54c4d9e
commit dff0d86558
26 files changed
+252 -60

No files matched your search

+2 -2
View File
@@ -30,7 +30,7 @@ namespace nf {
size_t ibCount = 0;
std::vector<float> tc;
parseOBJ(obj, vb, ib, ibCount, tc);
m_model->create(&vb[0], vb.size() * sizeof(float), &ib[0], ibCount, &tc[0], tc.size() * sizeof(float), texture.data, texture.size);
m_model->create(&vb[0], vb.size() * sizeof(float), &ib[0], ibCount, &tc[0], tc.size() * sizeof(float), &texture);
model.alreadyLoaded = true;
model.loadedModel = m_model;
}
@@ -52,7 +52,7 @@ namespace nf {
}
void Entity::setScale(double x) {
m_rotation = { x, x, x };
m_scale = { x, x, x };
}
void Entity::setScale(double x, double y, double z) {
+11 -6
View File
@@ -13,17 +13,22 @@ namespace nf {
}
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) {
void Model::create(const void* vertexBufferData, const size_t vertexBufferSize, const void* indexBufferData, size_t indexBufferCount, const void* textureCoordinatesBufferData, size_t textureCoordinatesBufferSize, ATexture* texture) {
m_vao = new VertexArray;
m_vao->addBuffer(vertexBufferData, vertexBufferSize);
m_vao->push<float>(3);
m_vao->finishBufferLayout();
if (textureCoordinatesBufferData && textureCoordinatesBufferSize && textureData) {
m_vao->addBuffer(textureCoordinatesBufferData, textureCoordinatesBufferSize);
m_vao->push<float>(2);
m_vao->finishBufferLayout();
m_vao->addBuffer(textureCoordinatesBufferData, textureCoordinatesBufferSize);
m_vao->push<float>(2);
m_vao->finishBufferLayout();
if (texture->alreadyLoaded) {
m_texture = texture->loadedTexture;
}
else {
m_texture = new Texture;
m_texture->create(textureData, textureSize);
m_texture->create(texture->data, texture->size);
texture->alreadyLoaded = true;
texture->loadedTexture = m_texture;
}
m_ib = new IndexBuffer(indexBufferData, indexBufferCount);
}
+35 -27
View File
@@ -8,9 +8,7 @@
#include "Shader.h"
namespace nf {
Text::Text() :
m_centered(false)
{
Text::Text() {
}
@@ -23,24 +21,32 @@ namespace nf {
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;
if (newFont.alreadyLoaded) {
m_font = newFont.loadedFont;
}
else {
m_font = new 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->m_characters[c] = ch;
}
FT_Done_Face(face);
FT_Done_FreeType(ft);
newFont.alreadyLoaded = true;
newFont.loadedFont = m_font;
}
FT_Done_Face(face);
FT_Done_FreeType(ft);
m_vao = new VertexArray;
m_vao->addBuffer(nullptr, 0);
m_vao->push<float>(2);
@@ -50,8 +56,8 @@ namespace nf {
m_vao->finishBufferLayout();
}
void Text::centered(bool centered) {
m_centered = centered;
void Text::setText(const std::string& string) {
m_string = string;
}
const char* Text::identity() {
@@ -63,22 +69,24 @@ namespace nf {
m_vao->bind();
std::string::const_iterator si;
float currX = (float)m_position.x * windowWidth, currY = (float)m_position.y * windowHeight;
if (m_centered) {
if (m_centeredX || m_centeredY) {
float textWidth = 0.0f;
float textHeight = 0.0f;
for (si = m_string.begin(); si != m_string.end(); si++) {
Character& c = m_font[*si];
Character& c = m_font->m_characters[*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;
if (m_centeredX)
currX = ((float)windowWidth - textWidth) / 2;
if (m_centeredY)
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];
Character& c = m_font->m_characters[*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;
@@ -1,7 +1,10 @@
#include "UIElement.h"
namespace nf {
UIElement::UIElement() {
UIElement::UIElement() :
m_centeredX(false),
m_centeredY(false)
{
}
@@ -9,6 +12,18 @@ namespace nf {
return "none";
}
void UIElement::setPosition(float x, float y) {
m_position = Vec2(x, y);
}
void UIElement::setPosition(const Vec2& position) {
m_position = position;
}
void UIElement::centered(bool x, bool y) {
m_centeredX = x;
m_centeredY = y;
}
void UIElement::render(Shader* shader, unsigned int windowWidth, unsigned int windowHeight) {
}
@@ -0,0 +1,76 @@
#include "UITexture.h"
#include "GL/glew.h"
#include "Assets.h"
#include "Texture.h"
namespace nf {
UITexture::UITexture() :
m_texture(0)
{
}
void UITexture::create(Asset* texture, const Vec2& position, double scale) {
ATexture* tex = (ATexture*)texture;
m_position = position;
m_scale = (float)scale;
if (tex->alreadyLoaded) {
m_texture = tex->loadedTexture;
}
else {
m_texture = new Texture;
m_texture->create(tex->data, tex->size);
}
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();
}
const char* UITexture::identity() {
return "texture";
}
void UITexture::render(Shader* shader, unsigned int windowWidth, unsigned int windowHeight) {
float posX = (float)m_position.x * windowWidth, posY = (float)m_position.y * windowHeight;
float scale = windowWidth / 5.0f;
Vec2 texDim = m_texture->getDimensions();
float height = scale * m_scale;
float width = ((float)texDim.x / (float)texDim.y) * scale * m_scale;
if (m_centeredX)
posX = ((float)windowWidth - width) / 2;
if (m_centeredY)
posY = ((float)windowHeight - height) / 2;
float vb[3][4] = {
posX, posY + height,
posX, posY,
posX + width, posY,
posX, posY + height,
posX + width, posY,
posX + width, posY + height
};
float tc[3][4] = {
0.0, 1.0,
0.0, 0.0,
1.0, 0.0,
0.0, 1.0,
1.0, 0.0,
1.0, 1.0
};
m_texture->bind();
m_vao->setBufferData(0, vb, sizeof(vb));
m_vao->setBufferData(1, tc, sizeof(tc));
glDrawArrays(GL_TRIANGLES, 0, 6);
}
UITexture::~UITexture() {
}
}
+13 -2
View File
@@ -49,7 +49,6 @@ namespace nf {
wglMakeCurrent(m_hdc, m_hglrc);
wglSwapIntervalEXT(0);
Log("OpenGL version: " + std::string((char*)glGetString(GL_VERSION)));
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -64,6 +63,9 @@ namespace nf {
const char* textVertex = baseAP["textVertex.shader"]->data;
const char* textFragment = baseAP["textFragment.shader"]->data;
m_textShader = new Shader(textVertex, textFragment);
const char* uiTextureVertex = baseAP["uiTextureVertex.shader"]->data;
const char* uiTextureFragment = baseAP["uiTextureFragment.shader"]->data;
m_uiTextureShader = new Shader(uiTextureVertex, uiTextureFragment);
BaseAssets::cube = (AModel*)baseAP["cube.obj"];
BaseAssets::plane = (AModel*)baseAP["plane.obj"];
@@ -91,6 +93,7 @@ namespace nf {
glViewport(0, 0, m_app->getConfig().width, m_app->getConfig().height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
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;
@@ -102,6 +105,7 @@ namespace nf {
}
m_lGame.clear();
glDisable(GL_DEPTH_TEST);
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;
@@ -111,7 +115,11 @@ namespace nf {
curr.render(m_textShader, m_app->getConfig().width, m_app->getConfig().height);
continue;
}
//TODO: Add else if for UI texture
if (curr.identity() == "texture") {
m_uiTextureShader->bind();
m_uiTextureShader->setUniform("proj", proj);
curr.render(m_uiTextureShader, m_app->getConfig().width, m_app->getConfig().height);
}
}
m_lUI.clear();
@@ -123,6 +131,9 @@ namespace nf {
}
Renderer::~Renderer() {
delete m_entityShader;
delete m_textShader;
delete m_uiTextureShader;
ReleaseDC(m_app->getWindow(), m_hdc);
wglMakeCurrent(NULL, NULL);
wglDeleteContext(m_hglrc);
+7 -3
View File
@@ -12,15 +12,15 @@ namespace nf {
}
void Texture::create(const char* textureData, size_t textureSize) {
int width, height, nChannels;
int nChannels;
stbi_set_flip_vertically_on_load(true);
unsigned char* texture = stbi_load_from_memory((unsigned char*)textureData, textureSize, &width, &height, &nChannels, 0);
unsigned char* texture = stbi_load_from_memory((unsigned char*)textureData, textureSize, &m_x, &m_y, &nChannels, 0);
if (!texture)
Error("Texture failed to load from memory!");
glBindTexture(GL_TEXTURE_2D, m_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_x, m_y, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
glGenerateMipmap(GL_TEXTURE_2D);
stbi_image_free(texture);
}
@@ -29,6 +29,10 @@ namespace nf {
glBindTexture(GL_TEXTURE_2D, m_id);
}
Vec2 Texture::getDimensions() {
return { (float)m_x, (float)m_y };
}
Texture::~Texture() {
glDeleteTextures(1, &m_id);
}