From e448f7003e6153bd70e6b20e704dc255c2bff413 Mon Sep 17 00:00:00 2001 From: devZoGok Date: Mon, 6 Jul 2026 13:01:31 +0300 Subject: [PATCH] GUI quad rendering improved font and image readers different mesh VAOs for spatial and GUI quads --- fontAsset.cpp | 9 ++ fontAsset.h | 19 ++- fontReader.cpp | 75 ++++++++---- fontReader.h | 30 ++--- gui.frag | 44 +++---- gui.vert | 20 ++- imageReader.cpp | 7 +- imageReader.h | 4 +- phong4.frag | 62 +++++----- phong4.vert | 6 +- quad.cpp | 6 +- root.cpp | 320 ++++++++++++++++++++++++++++++------------------ root.h | 33 +++-- texture.cpp | 38 ++---- texture.h | 2 +- 15 files changed, 406 insertions(+), 269 deletions(-) create mode 100644 fontAsset.cpp diff --git a/fontAsset.cpp b/fontAsset.cpp new file mode 100644 index 0000000..63df4b3 --- /dev/null +++ b/fontAsset.cpp @@ -0,0 +1,9 @@ +#include "fontAsset.h" + +namespace vb01{ + const FontAsset::Glyph& FontAsset::getGlyph(int id){ + for(Glyph &glyph : glyphs) + if(glyph.id == id) + return (const Glyph&) glyph; + } +} diff --git a/fontAsset.h b/fontAsset.h index 19ae3b2..2de54ff 100644 --- a/fontAsset.h +++ b/fontAsset.h @@ -2,9 +2,12 @@ #define FONT_ASSET_H #include "asset.h" +#include "util.h" #include + #include + #include #include FT_FREETYPE_H @@ -12,8 +15,20 @@ namespace vb01{ class Texture; struct FontAsset : public Asset{ - FT_Face face; - std::vector> glyphTextures; + struct Glyph{ + int id; + u8 *data; + Vector2 size, bearing; + u32 advance; + int layerId; + + Glyph(int i, u8 *d, Vector2 s, Vector2 b, u32 adv, int lid) : id(i), data(d), size(s), bearing(b), advance(adv), layerId(lid){} + }; + + const Glyph& getGlyph(int); + + FT_Face face; + std::vector glyphs; }; } diff --git a/fontReader.cpp b/fontReader.cpp index f4ec840..1e79d33 100644 --- a/fontReader.cpp +++ b/fontReader.cpp @@ -1,40 +1,67 @@ #include "fontReader.h" #include "fontAsset.h" +#include "root.h" + +#include "stb_image.h" #include -#include "glad.h" +#include + #include using namespace std; namespace vb01{ - FontReader *fontReader = nullptr; + FontReader *fontReader = nullptr; - FontReader* FontReader::getSingleton(){ - if(!fontReader) - fontReader = new FontReader(); + FontReader* FontReader::getSingleton(){ + if(!fontReader) + fontReader = new FontReader(); - return fontReader; + return fontReader; + } + + FontReader::FontReader() : AbstractAssetReader(){ + if(FT_Init_FreeType(&ft)) + cout << "Couldn't init Freetype\n"; + } + + Asset* FontReader::readAsset(string path){ + if(FT_New_Face(ft, path.c_str(), 0, &face)) + cout << "Could not load font\n"; + + FT_Set_Pixel_Sizes(face, pixelWidth, pixelHeight); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + vector glyphs; + Root *root = Root::getSingleton(); + u32 *buffer = root->getGuiTextureBuffer(); + + for(u16 i = firstChar; i < lastChar; i++){ + if(FT_Load_Char(face, i, FT_LOAD_RENDER)){ + cout << "Could not load glyph\n"; + continue; + } + + FontAsset::Glyph glyph = FontAsset::Glyph( + i, + face->glyph->bitmap.buffer, + Vector2(face->glyph->bitmap.width, face->glyph->bitmap.rows), + Vector2(face->glyph->bitmap_left, face->glyph->bitmap_top), + face->glyph->advance.x, + -1 + ); + root->initTextureDataOnGpu(buffer, glyph.data, glyph.size.x, glyph.size.y, glyph.layerId); + + glyphs.push_back(glyph); } - FontReader::FontReader() : AbstractAssetReader(){ - if(FT_Init_FreeType(&ft)) - cout << "Couldn't init Freetype\n"; - } + FontAsset *font = new FontAsset; + font->path = path; + font->face = face; + font->glyphs = glyphs; - Asset* FontReader::readAsset(string path){ - if(FT_New_Face(ft, path.c_str(), 0, &face)) - cout << "Could not load font\n"; - - FT_Set_Pixel_Sizes(face, pixelWidth, pixelHeight); - - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - FontAsset *font = new FontAsset; - font->path = path; - font->face = face; - - return font; - } + return font; + } } diff --git a/fontReader.h b/fontReader.h index 71071e9..31e8190 100644 --- a/fontReader.h +++ b/fontReader.h @@ -8,22 +8,22 @@ #include FT_FREETYPE_H namespace vb01{ - class FontReader : public AbstractAssetReader{ - public: - static FontReader* getSingleton(); - Asset* readAsset(std::string); - inline void setPixelWidth(int w){this->pixelWidth = w;} - inline void setPixelHeight(int h){this->pixelHeight = h;} - inline int getPixelWidth(){return pixelWidth;} - inline int getPixelHeight(){return pixelHeight;} - inline FT_Library& getFT(){return ft;} - private: - FontReader(); + class FontReader : public AbstractAssetReader{ + public: + static FontReader* getSingleton(); + Asset* readAsset(std::string); + inline void setPixelWidth(int w){this->pixelWidth = w;} + inline void setPixelHeight(int h){this->pixelHeight = h;} + inline int getPixelWidth(){return pixelWidth;} + inline int getPixelHeight(){return pixelHeight;} + inline FT_Library& getFT(){return ft;} + private: + FontReader(); - int pixelWidth = 0, pixelHeight = 100; - FT_Library ft; - FT_Face face; - }; + int pixelWidth = 0, pixelHeight = 100, firstChar = 0, lastChar = 256; + FT_Library ft; + FT_Face face; + }; } #endif diff --git a/gui.frag b/gui.frag index f977c2e..a96787b 100755 --- a/gui.frag +++ b/gui.frag @@ -1,39 +1,31 @@ -#version 330 core +#version 460 core in vec2 texCoords; +in flat int ID; out vec4 FragColor; -struct Texture{ - float mixRatio; - sampler2D pastTexture, nextTexture; - bool animated; +struct GuiObjectData{ + float pos[3]; + bool texturingEnabled; + int pastTexture[2], nextTexture[2]; + float diffuseColor[4]; }; -uniform bool texturingEnabled; -uniform bool diffuseColorEnabled; -uniform bool guiPlane; -uniform vec4 diffuseColor; -uniform Texture diffuseMap; +layout(std430, binding = 0) readonly restrict buffer objSSBO { + GuiObjectData guiObjData[]; +}; + +uniform sampler2DArray textureSamplers[256]; void main(){ - vec4 c = (texturingEnabled ? texture(diffuseMap.pastTexture, texCoords) : diffuseColor); - if(diffuseColorEnabled){ - float alpha = texture(diffuseMap.pastTexture, texCoords).w; - c = vec4(diffuseColor.xyz, alpha); - } + int id = ID; + vec4 c; - if(guiPlane){ - float gamma = 1, exposure = 1; - - //Reinhardt - //c.rgb = c.rgb / (c.rgb + vec3(1.)); - - //Exp - c.rgb = vec3(1.) - exp(-c.rgb * exposure); - - c.rgb = pow(c.rgb, vec3(1 / gamma)); - } + if(guiObjData[id].texturingEnabled) + c = texture(textureSamplers[guiObjData[id].pastTexture[0]], vec3(texCoords.xy, guiObjData[id].pastTexture[1])); + else + c = vec4(guiObjData[id].diffuseColor[0], guiObjData[id].diffuseColor[1], guiObjData[id].diffuseColor[2], guiObjData[id].diffuseColor[3]); FragColor = c; } diff --git a/gui.vert b/gui.vert index 836761c..2835284 100755 --- a/gui.vert +++ b/gui.vert @@ -1,17 +1,33 @@ -#version 330 core +#version 460 core layout (location = 0) in vec3 aVert; layout (location = 2) in vec2 aTexCoords; out vec2 texCoords; +out int ID; uniform vec2 screen; -uniform vec3 pos; + +struct GuiObjectData{ + float pos[3]; + bool texturingEnabled; + int pastTexture[2], nextTexture[2]; + float diffuseColor[4]; +}; + +layout(std430, binding = 0) readonly restrict buffer objSSBO { + GuiObjectData guiObjData[]; +}; void main(){ + int id = gl_InstanceID; + vec3 pos = vec3(guiObjData[id].pos[0], guiObjData[id].pos[1], guiObjData[id].pos[2]); + float x, y; x = (aVert.x + pos.x - screen.x * .5) / (screen.x * .5); y = (screen.y * .5 - (aVert.y + pos.y)) / (screen.y * .5); gl_Position = vec4(x, y, -(pos.z + aVert.z), 1); texCoords = aTexCoords; + + ID = id; } diff --git a/imageReader.cpp b/imageReader.cpp index 6d3deae..62c9762 100644 --- a/imageReader.cpp +++ b/imageReader.cpp @@ -20,8 +20,11 @@ namespace vb01{ int width, height, numChannels, layerId; u8 *data = stbi_load(path.c_str(), &width, &height, &numChannels, 0); - if(loadToGpu) - Root::getSingleton()->initTextureDataOnGpu(Root::getSingleton()->getMeshTextureBuffer(), data, width, height, layerId); + if(loadToGpu){ + Root *root = Root::getSingleton(); + u32 *texBuffer = (sceneImage ? root->getMeshTextureBuffer() : root->getGuiTextureBuffer()); + root->initTextureDataOnGpu(texBuffer, data, width, height, layerId); + } return new ImageAsset(path, data, width, height, numChannels, layerId); } diff --git a/imageReader.h b/imageReader.h index 202e067..d96d044 100644 --- a/imageReader.h +++ b/imageReader.h @@ -13,11 +13,13 @@ namespace vb01{ inline bool isFlip(){return flip;} inline void setLoadToGpu(bool ltg){this->loadToGpu = ltg;} inline bool isLoadToGpu(){return loadToGpu;} + inline void setSceneImage(bool si){this->sceneImage = si;} + inline bool isSceneImage(){return sceneImage;} Asset* readAsset(std::string); private: ImageReader(){} - bool flip = true, loadToGpu = true; + bool flip = true, loadToGpu = true, sceneImage = true; }; } diff --git a/phong4.frag b/phong4.frag index 56e393f..9f22047 100755 --- a/phong4.frag +++ b/phong4.frag @@ -1,8 +1,7 @@ #version 460 core -const int numLights=1; const bool checkLights=false; -in flat int drawId, instanceId; +in flat int ID; in vec3 fragPos; in vec3 tan; in vec3 biTan; @@ -15,40 +14,35 @@ layout (location = 1) out vec4 BrightColor; //0-POINT,1-DIRECTIONAL,2-SPOT -struct Light{ - bool useAngle, additive, render; - int type, attenuation; - vec3 pos, color, direction; - float innerAngle, outerAngle; - float a, b, c, near, far, radius; - //sampler2D depthMap; - //samplerCube depthMapCube; - mat4 lightMat; +struct ObjectFragData{ + float mixRatio; + int pastTexture[2], nextTexture[2]; + bool animated; + float diffuseColor[4], specularColor[4]; + float shinyness, specularStrength; + bool lightingEnabled, constLightingEnabled, texturingEnabled, normalMapEnabled, specularMapEnabled, castShadow, environmentMapEnabled; }; -struct Texture{ - float mixRatio; - sampler2D pastTexture, nextTexture; - bool animated; +layout(std430, binding = 1) buffer objFragSSBO { + ObjectFragData objData[]; +}; + +struct Light{ + int useAngle, additive, render; + int type, attenuation; + float pos[3], color[3], direction[3]; + float innerAngle, outerAngle; + float a, b, c, near, far, radius; + //mat4 lightMat; }; layout(std430, binding = 2) readonly buffer lightsSSBO { Light lights[]; }; -struct ObjectFragData{ - bool lightingEnabled, constLightingEnabled, texturingEnabled, normalMapEnabled, specularMapEnabled, castShadow, environmentMapEnabled; - vec4 diffuseColor, specularColor; - float shinyness, specularStrength; -}; - -layout(std430, binding = 1) buffer objFragSSBO { - //vec3 camPos; - ObjectFragData objData[]; -}; - -uniform Texture textures[4]; -uniform samplerCube environmentMap; +const int numLights = 0; +uniform vec3 camPos; +uniform sampler2DArray textureSamplers[256]; float linDepth(float depth, int i){ float z = depth * 2 - 1, near = lights[i].near, far = lights[i].far; @@ -87,8 +81,11 @@ float getShadow(int id){ } void main(){ - vec4 finalColor = objData[drawId + instanceId].diffuseColor; + int id = ID; + vec4 diffuseColor = vec4(objData[id].diffuseColor[0], objData[id].diffuseColor[1], objData[id].diffuseColor[2], objData[id].diffuseColor[3]); + vec4 finalColor = diffuseColor; + finalColor = texture(textureSamplers[objData[id].pastTexture[0]], vec3(texCoords.xy, objData[id].pastTexture[1])); /* if(texturingEnabled){ vec4 textureColor = texture(textures[0].pastTexture, texCoords); @@ -176,8 +173,7 @@ void main(){ specularCol += specularStrength * spec * specularSample * lights[i].color; } - if(castShadow) - diffuseCol *= (1.0 - getShadow(i)); + //if(castShadow) diffuseCol *= (1.0 - getShadow(i)); } } @@ -190,7 +186,5 @@ void main(){ if(brightness > 1) BrightColor = vec4(finalColor.rgb, 1); - //FragColor = vec4(fragPos,1); - FragColor = vec4(1,1,0,1); - //FragColor = finalColor; + FragColor = finalColor; } diff --git a/phong4.vert b/phong4.vert index c7f6a9f..c3fcf9e 100755 --- a/phong4.vert +++ b/phong4.vert @@ -19,7 +19,7 @@ layout (location = 6) in ivec4 aBoneIndices; out vec3 fragPos, norm, tan, biTan; out vec2 texCoords; -out int drawId, instanceId; +out int ID; struct Bone{ float angle; @@ -83,7 +83,6 @@ void main(){ vec4 vertPos = vec4(aPos, 1); bool anyWeights = false; - //int id = 0; int id = gl_DrawID + gl_InstanceID; mat4 model = objData[id].model; mat3 normalMat = mat3(transpose(inverse(model))); @@ -148,6 +147,5 @@ void main(){ gl_Position = viewProj * model * vertPos; fragPos = vec3(model * vertPos); texCoords = aTexCoords; - drawId = gl_DrawID; - instanceId = gl_InstanceID; + ID = id; } diff --git a/quad.cpp b/quad.cpp index 89bd543..8dfc485 100755 --- a/quad.cpp +++ b/quad.cpp @@ -11,7 +11,11 @@ namespace vb01{ if(renderMesh){ Root *root = Root::getSingleton(); - root->initVertexDataOnGpu(meshBase, root->getMeshVAO(), root->getMeshVBO(), root->getMeshEBO(), true); + + if(sp) + root->initVertexDataOnGpu(meshBase, root->getMeshVAO(), root->getMeshVBO(), root->getMeshEBO(), true); + else + root->initVertexDataOnGpu(meshBase, root->getGuiVAO(), root->getGuiVBO(), root->getGuiEBO(), false); } } diff --git a/root.cpp b/root.cpp index 1c3db93..aef4b85 100755 --- a/root.cpp +++ b/root.cpp @@ -1,6 +1,6 @@ -#include "stb_image.h" #include "root.h" #include "node.h" +#include "text.h" #include "shader.h" #include "box.h" #include "quad.h" @@ -11,7 +11,9 @@ #include "imageAsset.h" #include "animationController.h" -#include "glad.h" +#include "stb_image.h" + +#include #include @@ -76,12 +78,15 @@ namespace vb01{ meshTextureBuffer = new u32[NUM_MAX_TEXTURE_UNITS]; glGenTextures(NUM_MAX_TEXTURE_UNITS, meshTextureBuffer); - glBindTexture(GL_TEXTURE_2D_ARRAY, meshTextureBuffer[0]); + + guiTextureBuffer = new u32[NUM_MAX_TEXTURE_UNITS]; + glGenTextures(NUM_MAX_TEXTURE_UNITS, guiTextureBuffer); phongShader = new Shader(libPath + "phong4"); - + guiShader = new Shader(libPath + "gui"); initMeshRendering(meshVAO, meshVBO, meshEBO); + initMeshRendering(guiVAO, guiVBO, guiEBO); initParticleRendering(); initGuiRendering(); initPostProcessing(); @@ -186,131 +191,191 @@ namespace vb01{ } void Root::updateRenderNodeData(Node *node){ - Quaternion orient = Quaternion::QUAT_W; - Vector3 pos = Vector3::VEC_ZERO, scale = Vector3::VEC_IJK; - bool gui = false; + vector ancestors = node->getAncestors(); + Node *topAncestor = ancestors[ancestors.size() - 1]; + bool scene = (topAncestor == rootNode); + + Vector3 pos = node->getPosition(), scale = node->getScale(); + mat4 model = mat4(1.); + + if(scene){ + Quaternion orient = Quaternion::QUAT_W; - if(!gui){ pos = node->localToGlobalPosition(Vector3::VEC_ZERO); orient = node->localToGlobalOrientation(Quaternion::QUAT_W); scale = node->getScale(); + + Vector3 rotAxis = orient.getAxis(); + + if(rotAxis == Vector3::VEC_ZERO) + rotAxis = Vector3::VEC_I; + + model = translate(model, vec3(pos.x, pos.y, pos.z)); + model = rotate(model, orient.getAngle(), vec3(rotAxis.x, rotAxis.y, rotAxis.z)); + model = glm::scale(model, vec3(scale.x, scale.y, scale.z)); + + Vector3 direction = node->getGlobalAxis(2); + + for(Light *light : node->getLights()){ + LightData data; + Light::Type type = light->getLightType(); + data.type = (int)type; + data.color[0] = light->getColor().x; + data.color[1] = light->getColor().y; + data.color[1] = light->getColor().z; + + switch(type){ + case Light::Type::POINT: + data.pos[0] = pos.x; + data.pos[1] = pos.y; + data.pos[2] = pos.z; + data.a = light->getAttenuationValues().x; + data.b = light->getAttenuationValues().y; + data.c = light->getAttenuationValues().z; + data.radius = light->getRadius(); + data.useAngle = light->isUseAngle(); + break; + case Light::Type::DIRECTIONAL: + //shader->setMat4(proj * view, "lights[" + to_string(thisId) + "].lightMat"); + data.direction[0] = direction.x; + data.direction[1] = direction.y; + data.direction[2] = direction.z; + break; + case Light::Type::SPOT: + //shader->setMat4(proj * view, "lights[" + to_string(thisId) + "].lightMat"); + data.pos[0] = pos.x; + data.pos[1] = pos.y; + data.pos[2] = pos.z; + data.direction[0] = direction.x; + data.direction[1] = direction.y; + data.direction[2] = direction.z; + data.a = light->getAttenuationValues().x; + data.b = light->getAttenuationValues().y; + data.c = light->getAttenuationValues().z; + data.innerAngle = light->getInnerAngle(); + data.outerAngle = light->getOuterAngle(); + } + + lightData.push_back(data); + } } + else + for(Text *text : node->getTexts()){ + Material *mat = text->getMaterial(); + bool texturingEnabled = ((Material::BoolUniform*)mat->getUniform("texturingEnabled"))->value; - Vector3 rotAxis = orient.getAxis(); + GuiData gui; + gui.pos[0] = pos.x; + gui.pos[1] = pos.y; + gui.pos[2] = pos.z; + gui.texturingEnabled = texturingEnabled; - if(rotAxis == Vector3::VEC_ZERO) - rotAxis = Vector3::VEC_I; + if(gui.texturingEnabled){ + gui.pastTexture[0] = 0; + gui.pastTexture[1] = 0; + gui.nextTexture[0] = 0; + gui.nextTexture[1] = 0; + } + else{ + Vector4 diffCol = ((Material::Vector4Uniform*)mat->getUniform("diffuseColor"))->value; + gui.diffuseColor[0] = diffCol.x; + gui.diffuseColor[1] = diffCol.y; + gui.diffuseColor[2] = diffCol.z; + gui.diffuseColor[3] = diffCol.w; + } - mat4 model = mat4(1.); - model = translate(model, vec3(pos.x, pos.y, pos.z)); - model = rotate(model, orient.getAngle(), vec3(rotAxis.x, rotAxis.y, rotAxis.z)); - model = glm::scale(model, vec3(scale.x, scale.y, scale.z)); + guiData.push_back(gui); + } for(Mesh *mesh : node->getMeshes()){ MeshData &meshData = mesh->getMeshBase(); - - for(int i = 0; i < drawCmdMeshes.size(); i++) - if(*(drawCmdMeshes[i]) == meshData) - drawCmds[i].instanceCount++; - - ObjectVertexData ovd; - ovd.viewProj = projView; - ovd.model = model; - //ovd.animated = 0; - //ovd.bones[0]; - - /* - for(int i = 0; i < meshData.numShapeKeys; i++) - ovd.shapeKeyFactors[i] = meshData.shapeKeys[i].value; - */ - - objVertData.push_back(ovd); - Material *mat = mesh->getMaterial(); + bool texturingEnabled = ((Material::BoolUniform*)mat->getUniform("texturingEnabled"))->value; - ObjectFragmentData ofd; - ofd.texturingEnabled = true; + if(scene){ + bool lightingEnabled = ((Material::BoolUniform*)mat->getUniform("lightingEnabled"))->value; - if(ofd.texturingEnabled){ - ofd.pastTexture[0] = 0; - ofd.pastTexture[1] = 0; + for(int i = 0; i < drawCmdMeshes.size(); i++) + if(*(drawCmdMeshes[i]) == meshData) + drawCmds[i].instanceCount++; + + ObjectVertexData ovd; + ovd.viewProj = projView; + ovd.model = model; + //ovd.animated = 0; + //ovd.bones[0]; + + /* + for(int i = 0; i < meshData.numShapeKeys; i++) + ovd.shapeKeyFactors[i] = meshData.shapeKeys[i].value; + */ + + objVertData.push_back(ovd); + + Material *mat = mesh->getMaterial(); + + ObjectFragmentData ofd; + ofd.texturingEnabled = texturingEnabled; + + if(ofd.texturingEnabled){ + ofd.pastTexture[0] = 0; + ofd.pastTexture[1] = 0; + } + else{ + Vector4 diffuseColor = ((Material::Vector4Uniform*)mat->getUniform("diffuseColor"))->value; + + ofd.diffuseColor[0] = diffuseColor.x; + ofd.diffuseColor[1] = diffuseColor.y; + ofd.diffuseColor[2] = diffuseColor.z; + ofd.diffuseColor[3] = diffuseColor.w; + } + + ofd.lightingEnabled = lightingEnabled; + + if(ofd.lightingEnabled){ + ofd.constLightingEnabled = false; + ofd.normalMapEnabled = false; + ofd.castShadow = false; + ofd.environmentMapEnabled = false; + ofd.specularMapEnabled = false; + + if(!ofd.specularMapEnabled){ + Vector4 specularColor = ((Material::Vector4Uniform*)mat->getUniform("specularColor"))->value; + + ofd.specularColor[0] = specularColor.x; + ofd.specularColor[1] = specularColor.y; + ofd.specularColor[2] = specularColor.z; + ofd.specularColor[3] = specularColor.w; + ofd.shinyness; + ofd.specularStrength; + } + } + + objFragData.push_back(ofd); } else{ - Vector4 diffuseColor = ((Material::Vector4Uniform*)mat->getUniform("diffuseColor"))->value; + GuiData gui; + gui.pos[0] = pos.x; + gui.pos[1] = pos.y; + gui.pos[2] = pos.z; + gui.texturingEnabled = texturingEnabled; - ofd.diffuseColor[0] = diffuseColor.x; - ofd.diffuseColor[1] = diffuseColor.y; - ofd.diffuseColor[2] = diffuseColor.z; - ofd.diffuseColor[3] = diffuseColor.w; - } - - ofd.lightingEnabled = false; - - if(ofd.lightingEnabled){ - ofd.constLightingEnabled = false; - ofd.normalMapEnabled = false; - ofd.castShadow = false; - ofd.environmentMapEnabled = false; - ofd.specularMapEnabled = false; - - if(!ofd.specularMapEnabled){ - Vector4 specularColor = ((Material::Vector4Uniform*)mat->getUniform("specularColor"))->value; - - ofd.specularColor[0] = specularColor.x; - ofd.specularColor[1] = specularColor.y; - ofd.specularColor[2] = specularColor.z; - ofd.specularColor[3] = specularColor.w; - ofd.shinyness; - ofd.specularStrength; + if(gui.texturingEnabled){ + gui.pastTexture[0] = 0; + gui.pastTexture[1] = 0; + gui.nextTexture[0] = 0; + gui.nextTexture[1] = 0; } + else{ + Vector4 diffCol = ((Material::Vector4Uniform*)mat->getUniform("diffuseColor"))->value; + gui.diffuseColor[0] = diffCol.x; + gui.diffuseColor[1] = diffCol.y; + gui.diffuseColor[2] = diffCol.z; + gui.diffuseColor[3] = diffCol.w; + } + + guiData.push_back(gui); } - - objFragData.push_back(ofd); - } - - Vector3 direction = node->getGlobalAxis(2); - - for(Light *light : node->getLights()){ - LightData data; - Light::Type type = light->getLightType(); - data.type = (int)type; - data.color[0] = light->getColor().x; - data.color[1] = light->getColor().y; - data.color[1] = light->getColor().z; - - switch(type){ - case Light::Type::POINT: - data.pos[0] = pos.x; - data.pos[1] = pos.y; - data.pos[2] = pos.z; - data.a = light->getAttenuationValues().x; - data.b = light->getAttenuationValues().y; - data.c = light->getAttenuationValues().z; - data.radius = light->getRadius(); - data.useAngle = light->isUseAngle(); - break; - case Light::Type::DIRECTIONAL: - //shader->setMat4(proj * view, "lights[" + to_string(thisId) + "].lightMat"); - data.direction[0] = direction.x; - data.direction[1] = direction.y; - data.direction[2] = direction.z; - break; - case Light::Type::SPOT: - //shader->setMat4(proj * view, "lights[" + to_string(thisId) + "].lightMat"); - data.pos[0] = pos.x; - data.pos[1] = pos.y; - data.pos[2] = pos.z; - data.direction[0] = direction.x; - data.direction[1] = direction.y; - data.direction[2] = direction.z; - data.a = light->getAttenuationValues().x; - data.b = light->getAttenuationValues().y; - data.c = light->getAttenuationValues().z; - data.innerAngle = light->getInnerAngle(); - data.outerAngle = light->getOuterAngle(); - } - - lightData.push_back(data); } } @@ -555,8 +620,9 @@ namespace vb01{ updateGuiPlane(); glEnable(GL_DEPTH_TEST); - //updateNodeTree(guiShader, true); - //updateNodeTree(guiNode, true); + updateNodeTree(guiShader, true); + guiNode->update(); + renderGui(); glfwSwapBuffers(window); glfwPollEvents(); @@ -603,7 +669,19 @@ namespace vb01{ void Root::renderParticles(vector &particleEmitters){ } - void Root::renderGui(vector &meshes){ + void Root::renderGui(){ + glBindBuffer(GL_SHADER_STORAGE_BUFFER, guiDataBuffer); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GuiData) * guiData.size(), guiData.data(), GL_DYNAMIC_DRAW); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, guiDataBuffer); + + for(int i = 0; i < currTextureDims.size(); i++){ + glActiveTexture(GL_TEXTURE0 + i); + glBindTexture(GL_TEXTURE_2D_ARRAY, guiTextureBuffer[i]); + } + + glBindVertexArray(guiVAO); + glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0, guiData.size()); + glBindVertexArray(0); } mat4 Root::calculateProjView(Vector3 camPos){ @@ -622,16 +700,20 @@ namespace vb01{ shader->use(); if(!gui){ + objVertData.clear(); + objFragData.clear(); + + for(DrawElementsIndirectCommand &cmd : drawCmds) + cmd.instanceCount = 0; + Vector3 camPos = camera->getPosition(); shader->setVec3(camPos, "camPos"); projView = calculateProjView(camPos); } - - objVertData.clear(); - objFragData.clear(); - - for(DrawElementsIndirectCommand &cmd : drawCmds) - cmd.instanceCount = 0; + else{ + guiData.clear(); + shader->setVec2(Vector2(width, height), "screen"); + } for(int i = 0; i < currTextureDims.size(); i++) shader->setInt(i, "textureSamplers[" + to_string(i) + "]"); diff --git a/root.h b/root.h index a3b3ee1..4def3af 100755 --- a/root.h +++ b/root.h @@ -47,10 +47,15 @@ namespace vb01{ void updateRenderNodeData(Node*); void createCubemap(bool, bool, std::string[6], int); inline Shader* getPhongShader(){return phongShader;} + inline Shader* getGuiShader(){return guiShader;} inline u32& getMeshVAO(){return meshVAO;} inline u32& getMeshVBO(){return meshVBO;} inline u32& getMeshEBO(){return meshEBO;} + inline u32& getGuiVAO(){return guiVAO;} + inline u32& getGuiVBO(){return guiVBO;} + inline u32& getGuiEBO(){return guiEBO;} inline u32* getMeshTextureBuffer(){return meshTextureBuffer;} + inline u32* getGuiTextureBuffer(){return guiTextureBuffer;} inline u32* getGuiPlaneTextureBuffer(){return guiPlaneTextureBuffer;} inline const int getMaxNumShapeKeys(){return MAX_NUM_SHAPE_KEYS;} inline Camera* getCamera(){return camera;} @@ -98,22 +103,27 @@ namespace vb01{ float innerAngle, outerAngle; float a, b, c, near, far, radius; }; - struct TextureGpuData { + struct GuiData { + float pos[3]; + int texturingEnabled, pastTexture[2], nextTexture[2]; + float diffuseColor[4]; + }; + struct TextureUnitGpuData { u32 *buffer = nullptr; - int unitId = 0, layerId = 0, width = 0, height = 0; + int numLayers = 0, width = 0, height = 0; - TextureGpuData(u32 *b, int u, int l, int w, int h) : buffer(b), unitId(u), layerId(l), width(w), height(h){} + TextureUnitGpuData(u32 *b, int l, int w, int h) : buffer(b), numLayers(l), width(w), height(h){} }; glm::mat4 projView; const int MAX_NUM_SHAPE_KEYS = 5; int NUM_MAX_TEXTURE_UNITS = 0, NUM_MAX_TEXTURE_ARRAY_SIZE = 0, numLights = 0, width, height, blurLevel = 10, currNumVerts = 0, currNumIndexes = 0, depthmapSize = 512, currNumLayers = 0; - u32 meshVAO, meshVBO, meshEBO, *meshTextureBuffer = nullptr, *depthmapBuffer = nullptr; - u32 particleVAO, particleVBO; - u32 guiVAO, guiVBO, guiEBO, *guiTextureBuffer = nullptr; - u32 guiPlaneVAO, guiPlaneVBO, guiPlaneEBO, *guiPlaneTextureBuffer = nullptr; + u32 meshVAO = -1, meshVBO = -1, meshEBO = -1, *meshTextureBuffer = nullptr, *depthmapBuffer = nullptr; + u32 particleVAO = -1, particleVBO = -1; + u32 guiVAO = -1, guiVBO = -1, guiEBO = -1, *guiTextureBuffer = nullptr; + u32 guiPlaneVAO = -1, guiPlaneVBO = -1, guiPlaneEBO = -1, *guiPlaneTextureBuffer = nullptr; u32 skyboxVAO = -1, skyboxVBO = -1, skyboxEBO = -1, skyboxBuffer = -1; - u32 FBO, RBO, pingpongBuffers[2], drawCmdBuffer = -1, objVertBuffer = -1, objFragBuffer = -1, objLightBuffer = -1; + u32 FBO = -1, RBO = -1, pingpongBuffers[2], drawCmdBuffer = -1, objVertBuffer = -1, objFragBuffer = -1, objLightBuffer = -1, guiDataBuffer = -1; bool bloom = false, hdr = false; float exposure = 1, gamma = 1; Box *skybox = nullptr, *iblBox = nullptr; @@ -121,7 +131,7 @@ namespace vb01{ GLFWwindow *window; Node *rootNode, *guiNode; Camera *camera; - Shader *blurShader = nullptr, *phongShader = nullptr; + Shader *blurShader = nullptr, *phongShader = nullptr, *guiShader = nullptr; Texture *pingPongTextures[2]; std::vector drawCmdMeshes; std::vector currentGpuVertices; @@ -132,14 +142,15 @@ namespace vb01{ std::vector objVertData; std::vector objFragData; std::vector lightData; - std::vector textureGpuData; + std::vector guiData; + std::vector textureGpuData; std::string libPath; Root(); void framebuffer_size_callback(GLFWwindow*, int, int); void renderMeshes(); void renderParticles(std::vector&); - void renderGui(std::vector&); + void renderGui(); void initWindow(std::string); void initMainFramebuffer(Texture*, Texture*); void initBloomFramebuffer(); diff --git a/texture.cpp b/texture.cpp index 505f56f..b8fc822 100755 --- a/texture.cpp +++ b/texture.cpp @@ -1,21 +1,23 @@ #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" -#include -#include FT_FREETYPE_H -#include "texture.h" -#include "assetManager.h" -#include "imageAsset.h" #include "root.h" +#include "texture.h" +#include "fontAsset.h" +#include "imageAsset.h" +#include "assetManager.h" #include + #include + #include using namespace std; namespace vb01{ + //TODO deallocate (V)RAM for this constructor Texture::Texture(int w, int h, bool shadowMap, bool hiRes) : Animatable(Animatable::TEXTURE), width(w), height(h), texture(new u32){ if(shadowMap){ /* @@ -55,31 +57,13 @@ namespace vb01{ Root::getSingleton()->createCubemap(depth, false, p, ml); } - Texture::Texture(FT_Face face) : Animatable(Animatable::TEXTURE){ - texture = new u32; - - glGenTextures(1, &texture[0]); - glBindTexture(GL_TEXTURE_2D, texture[0]); - 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); - glBindTexture(GL_TEXTURE_2D, 0); + Texture::Texture(string path, int id) : Animatable(Animatable::TEXTURE){ + FontAsset *fontAsset = (FontAsset*)AssetManager::getSingleton()->getAsset(path); + frames.push_back(Frame(nullptr, fontAsset->getGlyph(id).layerId)); } Texture::~Texture(){ - delete paths; + if(paths) delete paths; } void Texture::animate(float value, KeyframeChannel keyframeChannel){ diff --git a/texture.h b/texture.h index 8406ffd..b90268d 100755 --- a/texture.h +++ b/texture.h @@ -18,7 +18,7 @@ namespace vb01{ Texture(int, int, bool = true, bool = false); Texture(std::string[], int, bool, int = 0, bool = false, std::string = ""); Texture(int, bool = true, int = 0, std::string = ""); - Texture(FT_Face); + Texture(std::string, int); void select(int = 0, int = 0); void update(int = 0); void animate(float, KeyframeChannel);