diff --git a/fontReader.cpp b/fontReader.cpp index f0611e2..d498e9f 100644 --- a/fontReader.cpp +++ b/fontReader.cpp @@ -58,7 +58,7 @@ namespace vb01{ -1, -1 ); - root->initTextureDataOnGpu(glyph.data, pixelHeight, pixelHeight, glyph.bufferId, glyph.layerId, false, glyph.size.x, glyph.size.y); + root->initTextureDataOnGpu(glyph.data, pixelHeight, pixelHeight, glyph.bufferId, glyph.layerId, false, true, glyph.size.x, glyph.size.y); glyphs.push_back(glyph); } diff --git a/gui.frag b/gui.frag index 1697255..f15db47 100755 --- a/gui.frag +++ b/gui.frag @@ -6,7 +6,7 @@ in flat int ID; out vec4 FragColor; struct GuiObjectData{ - float pos[3], scale[3]; + float pos[3], scale[3], size[2]; bool texturingEnabled; int glyphTexture[2], pastTexture[2], nextTexture[2]; float diffuseColor[4]; diff --git a/gui.vert b/gui.vert index 5904066..6d6eb43 100755 --- a/gui.vert +++ b/gui.vert @@ -9,7 +9,7 @@ out int ID; uniform vec2 screen; struct GuiObjectData{ - float pos[3], scale[3]; + float pos[3], scale[3], size[2]; bool texturingEnabled; int glyphTexture[2], pastTexture[2], nextTexture[2]; float diffuseColor[4]; @@ -22,14 +22,15 @@ layout(std430, binding = 0) readonly restrict buffer objSSBO { void main(){ int id = gl_InstanceID; vec3 scale = vec3(guiObjData[id].scale[0], guiObjData[id].scale[1], guiObjData[id].scale[2]); - vec3 pos = vec3(guiObjData[id].pos[0], guiObjData[id].pos[1], guiObjData[id].pos[2]); - pos *= scale; + vec3 pos = vec3(guiObjData[id].pos[0], guiObjData[id].pos[1], guiObjData[id].pos[2]) * scale; + vec2 size = vec2(guiObjData[id].size[0], guiObjData[id].size[1]); + vec3 vertPos = vec3(aVert.xy * scale.xy * size.xy, aVert.z); float x, y; - x = (aVert.x * scale.x + pos.x - screen.x * .5) / (screen.x * .5); - y = (screen.y * .5 - (aVert.y * scale.y + pos.y)) / (screen.y * .5); - gl_Position = vec4(x, y, -(pos.z + aVert.z), 1); - texCoords = vec2(aTexCoords.x, 1.0 - aTexCoords.y); + x = (vertPos.x + pos.x - screen.x * .5) / (screen.x * .5); + y = (screen.y * .5 - (vertPos.y + pos.y)) / (screen.y * .5); + gl_Position = vec4(x, y, -(pos.z + vertPos.z), 1); + texCoords = vec2(aTexCoords.x * size.x, (1.0 - aTexCoords.y) * size.y); ID = id; } diff --git a/root.cpp b/root.cpp index ef507d5..206693f 100755 --- a/root.cpp +++ b/root.cpp @@ -140,7 +140,7 @@ namespace vb01{ } //TODO check loading of textures with different dimensions - void Root::initTextureDataOnGpu(u8 *data, int width, int height, int &bufferId, int &layerId, bool scene, int w, int h){ + void Root::initTextureDataOnGpu(u8 *data, int width, int height, int &bufferId, int &layerId, bool scene, bool singleChannel, int w, int h){ int textureUnitId = -1; vector &textureData = (scene ? meshTextureData : guiTextureData); @@ -156,6 +156,8 @@ namespace vb01{ glGenTextures(1, &textureData[textureUnitId].buffer); } + GLint texelFormat = (singleChannel ? GL_RED : GL_RGB); + for(int i = 0; i < textureData.size(); i++){ TextureUnitGpuData &texData = textureData[i]; @@ -163,7 +165,7 @@ namespace vb01{ u8 background[numPixels]{0}; glBindTexture(GL_TEXTURE_2D_ARRAY, texData.buffer); - glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RED, texData.width, texData.height, texData.imageData.size() + 1, 0, GL_RED, GL_UNSIGNED_BYTE, NULL); + glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, texelFormat, texData.width, texData.height, texData.imageData.size() + 1, 0, texelFormat, GL_UNSIGNED_BYTE, NULL); int dims[]{texData.width, texData.height}; @@ -171,10 +173,10 @@ namespace vb01{ if(!(texData.subDims[j].first == 0 && texData.subDims[j].second == 0)){ dims[0] = texData.subDims[j].first; dims[1] = texData.subDims[j].second; + glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, j, texData.width, texData.height, 1, texelFormat, GL_UNSIGNED_BYTE, background); } - glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, j, texData.width, texData.height, 1, GL_RED, GL_UNSIGNED_BYTE, background); - glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, j, dims[0], dims[1], 1, GL_RED, GL_UNSIGNED_BYTE, texData.imageData[j]); + glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, j, dims[0], dims[1], 1, texelFormat, GL_UNSIGNED_BYTE, texData.imageData[j]); } if(textureUnitId == i){ @@ -187,10 +189,12 @@ namespace vb01{ texData.imageData.push_back(data); texData.subDims.push_back(make_pair(w, h)); - if(!(w == 0 && h == 0)) dims[0] = w, dims[1] = h; + if(!(w == 0 && h == 0)){ + dims[0] = w, dims[1] = h; + glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, layerId, texData.width, texData.height, 1, texelFormat, GL_UNSIGNED_BYTE, background); + } - glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, layerId, texData.width, texData.height, 1, GL_RED, GL_UNSIGNED_BYTE, background); - glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, layerId, dims[0], dims[1], 1, GL_RED, GL_UNSIGNED_BYTE, data); + glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, layerId, dims[0], dims[1], 1, texelFormat, GL_UNSIGNED_BYTE, data); } glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, scene ? GL_REPEAT : GL_CLAMP_TO_EDGE); @@ -288,6 +292,8 @@ namespace vb01{ gui.scale[0] = scale.x; gui.scale[1] = scale.y; gui.scale[2] = scale.z; + gui.size[0] = glyph.size.x / size.x; + gui.size[1] = glyph.size.y / size.y; const Texture::Frame &frame = ((Material::TextureUniform*)charac.material->getUniform("glyphTexture"))->value->getFrame(0); gui.glyphTexture[0] = frame.bufferId; @@ -395,6 +401,8 @@ namespace vb01{ gui.pos[0] = pos.x; gui.pos[1] = pos.y; gui.pos[2] = pos.z; + gui.size[0] = 1; + gui.size[1] = 1; gui.glyphTexture[0] = -1; gui.glyphTexture[1] = -1; gui.texturingEnabled = texturingEnabled; diff --git a/root.h b/root.h index 71e60d7..bcf2c3b 100755 --- a/root.h +++ b/root.h @@ -42,7 +42,7 @@ namespace vb01{ void removeSkybox(); void initVertexDataOnGpu(MeshData&, u32&, u32&, u32&, bool); void initTextureDataOnGpu(int, int); - void initTextureDataOnGpu(u8*, int, int, int&, int&, bool, int = 0, int = 0); + void initTextureDataOnGpu(u8*, int, int, int&, int&, bool, bool = false, int = 0, int = 0); void updateRenderNodeData(Node*); void createCubemap(bool, bool, std::string[6], int); inline Shader* getPhongShader(){return phongShader;} @@ -104,7 +104,7 @@ namespace vb01{ float a, b, c, near, far, radius; }; struct GuiData { - float pos[3], scale[3]; + float pos[3], scale[3], size[2]; int texturingEnabled, glyphTexture[2], pastTexture[2], nextTexture[2]; float diffuseColor[4]; }; diff --git a/text.cpp b/text.cpp index 6933dc7..af5a552 100755 --- a/text.cpp +++ b/text.cpp @@ -1,46 +1,16 @@ #include "root.h" #include "text.h" -#include "shader.h" #include "texture.h" #include "node.h" #include "material.h" #include "assetManager.h" -#include "glad.h" -#include -#include -#include -#include -#include FT_FREETYPE_H - using namespace std; namespace vb01{ Text::Text(string fontPath, wstring e, u16 firstChar, u16 lastChar){ font = (FontAsset*)AssetManager::getSingleton()->getAsset(fontPath); setEntry(e); - //init(); - //applyFont(fontPath, firstChar, lastChar); - } - - Text::~Text(){ - //glDeleteVertexArrays(1, &VAO); - //glDeleteBuffers(1, &VBO); - } - - void Text::init(){ - //glGenVertexArrays(1, &VAO); - //glGenBuffers(1, &VBO); - - //glBindVertexArray(VAO); - //glBindBuffer(GL_ARRAY_BUFFER, VBO); - - //glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6 * 4, NULL, GL_DYNAMIC_DRAW); - //glEnableVertexAttribArray(0); - //glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0); - - //glBindBuffer(GL_ARRAY_BUFFER, 0); - //glBindVertexArray(0); } wstring Text::getEntry(){ @@ -57,126 +27,28 @@ namespace vb01{ delete ch.material; characters.clear(); - Vector3 scale = Vector3::VEC_IJK; for(wchar_t ch : entry){ Material *mat = new Material(Root::getSingleton()->getGuiShader()); mat->addTexUniform("glyphTexture", new Texture(font->path, ch), false, false); - - Character charac = Character(ch, mat); - int numChars = characters.size(); - - if(numChars > 0){ - const FontAsset::Glyph &glyph = font->getGlyph(ch); - Vector2 currOffset = Vector2::VEC_ZERO; - - if(horizontal) - currOffset = Vector2::VEC_I * (leftToRight ? 1 : -1) * glyph.size.x * scale.x; - else - currOffset = Vector2::VEC_J * glyph.size.y * scale.y; - - charac.offset = characters[numChars - 1].offset + currOffset; - } - - characters.push_back(charac); - } - } - - //TODO ensure destruction of textures when unloading the asset - void Text::applyFont(string fontPath, u16 firstChar, u16 lastChar){ - characters.clear(); - - font = (FontAsset*)AssetManager::getSingleton()->getAsset(fontPath); - - for(u16 i = firstChar; i < lastChar; i++){ - - /* - Glyph c; - c.ch = i; - c.size = Vector2(face->glyph->bitmap.width, face->glyph->bitmap.rows); - c.bearing = Vector2(face->glyph->bitmap_left, face->glyph->bitmap_top); - c.advance = face->glyph->advance.x; - c.texId = i; - - */ - //characters.push_back(c); + characters.push_back(Character(ch, mat)); } } void Text::update(){ - //Root *root = Root::getSingleton(); - //int width = root->getWidth(), height = root->getHeight(); + Vector2 advanceOffset = Vector2::VEC_ZERO; + Vector3 scale = node->getScale(); + int numShifts = 6, startId = (leftToRight ? 0 : getLength() - 1); - //material->update(); - //Shader *shader = material->getShader(); - //shader->setVec2(Vector2(width, height), "screen"); - //shader->setVec3(node->getPosition(), "pos"); + for(int i = startId; (leftToRight ? (i < getLength()) : (i >= 0)); (leftToRight ? i++ : i--)){ + Character &charac = characters[i]; + const FontAsset::Glyph &currGlyph = font->getGlyph(charac.ch); + charac.offset = Vector2( (currGlyph.bearing.x + advanceOffset.x), (advanceOffset.y - currGlyph.bearing.y)); - //Vector2 advanceOffset = Vector2::VEC_ZERO; - - //for(int i = (leftToRight ? 0 : entry.length() - 1); (leftToRight ? (i < entry.length()) : (i >= 0)); (leftToRight ? i++ : i--)){ - // Glyph *glyphPtr = getGlyph(entry[i]); - - // if(!glyphPtr) continue; - - // int glyphTexId = -1; - - // for(int j = 0; j < font->glyphTextures.size(); j++) - // if(font->glyphTextures[j].first == glyphPtr->texId){ - // glyphTexId = j; - // break; - // } - - // Glyph glyph = *glyphPtr; - // prepareGlyphs(glyph, glyphTexId, advanceOffset); - // Vector2 size = glyph.size, bearing = glyph.bearing; - - // if(horizontal) - // advanceOffset.x += node->getScale().x * (size.x + bearing.x); - // else - // advanceOffset.y += node->getScale().y * size.y; - //} + if(horizontal) + advanceOffset.x += (currGlyph.advance >> numShifts); + else + advanceOffset.y += currGlyph.size.y + (currGlyph.size.y - currGlyph.bearing.y); + } } - - /* - void Text::prepareGlyphs(Glyph glyph, int glyphTexId, Vector2 advanceOffset){ - //Vector3 nodePos = node->getPosition(), scale = node->getScale(); - //Vector2 origin = Vector2(nodePos.x, nodePos.y) + (advanceOffset * scale); - - //Vector2 size = Vector2(glyph.size.x * scale.x, glyph.size.y * scale.y); - //Vector2 bearing = Vector2(glyph.bearing.x * scale.x, glyph.bearing.y * scale.y); - - //float data[] = { - // origin.x + bearing.x, origin.y - bearing.y, 0, 0, - // origin.x + bearing.x + size.x, origin.y - bearing.y, 1, 0, - // origin.x + bearing.x + size.x, origin.y - bearing.y + size.y, 1, 1, - - // origin.x + bearing.x + size.x, origin.y - bearing.y + size.y, 1, 1, - // origin.x + bearing.x, origin.y - bearing.y + size.y, 0, 1, - // origin.x + bearing.x, origin.y - bearing.y, 0, 0 - //}; - - ////glBindVertexArray(VAO); - ////glBindBuffer(GL_ARRAY_BUFFER, VBO); - ////glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(data), data); - - //int id = 2; - //material->getShader()->setInt(id, "textures[1].pastTexture"); - //font->glyphTextures[glyphTexId].second->select(id); - - ////glDrawArrays(GL_TRIANGLES, 0, 6); - } - */ - - /* - Text::Glyph* Text::getGlyph(u16 ch){ - Glyph *glyph = nullptr; - - for(Glyph &g : characters) - if(g.ch == ch) - glyph = &g; - - return glyph; - } - */ } diff --git a/text.h b/text.h index 67b5f38..5b3b335 100755 --- a/text.h +++ b/text.h @@ -25,7 +25,7 @@ namespace vb01{ }; Text(std::string, std::wstring, u16 = 0, u16 = 256); - ~Text(); + ~Text(){} void update(); std::wstring getEntry(); void setEntry(std::wstring); @@ -38,13 +38,7 @@ namespace vb01{ inline Material* getMaterial(){return material;} inline void setMaterial(Material *mat){this->material = mat;} inline const std::vector& getCharacters(){return characters;} - //Glyph* getGlyph(u16); private: - void init(); - void applyFont(std::string, u16, u16 = 256); - void clearFont(); - //void prepareGlyphs(Glyph, int, Vector2); - FontAsset *font = nullptr; Material *material = nullptr; std::vector characters;