diff --git a/fontAsset.h b/fontAsset.h index 2de54ff..59a195b 100644 --- a/fontAsset.h +++ b/fontAsset.h @@ -16,13 +16,12 @@ namespace vb01{ struct FontAsset : public Asset{ struct Glyph{ - int id; u8 *data; - Vector2 size, bearing; u32 advance; - int layerId; + int id, bufferId, layerId; + Vector2 size, bearing; - 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){} + Glyph(int i, u8 *d, Vector2 s, Vector2 b, u32 adv, int bid, int lid) : id(i), data(d), size(s), bearing(b), advance(adv), bufferId(bid), layerId(lid){} }; const Glyph& getGlyph(int); diff --git a/fontReader.cpp b/fontReader.cpp index 1e79d33..c479c2d 100644 --- a/fontReader.cpp +++ b/fontReader.cpp @@ -36,7 +36,6 @@ namespace vb01{ 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)){ @@ -50,9 +49,10 @@ namespace vb01{ Vector2(face->glyph->bitmap.width, face->glyph->bitmap.rows), Vector2(face->glyph->bitmap_left, face->glyph->bitmap_top), face->glyph->advance.x, + -1, -1 ); - root->initTextureDataOnGpu(buffer, glyph.data, glyph.size.x, glyph.size.y, glyph.layerId); + root->initTextureDataOnGpu(glyph.data, glyph.size.x, glyph.size.y, glyph.bufferId, glyph.layerId, false); glyphs.push_back(glyph); } diff --git a/imageAsset.h b/imageAsset.h index 017d57e..b0ff960 100644 --- a/imageAsset.h +++ b/imageAsset.h @@ -5,18 +5,21 @@ namespace vb01{ struct ImageAsset : public Asset{ - ImageAsset(std::string p, u8 *img, int w, int h, int nc, int lid) : + ImageAsset(std::string p, u8 *img, int w, int h, int nc, int bid, int lid, bool ltg) : image(img), width(w), height(h), numChannels(nc), - layerId(lid) + bufferId(lid), + layerId(lid), + loadedToGpu(ltg) { this->path = p; } u8 *image; - int width, height, numChannels, layerId; + int width, height, numChannels, bufferId, layerId; + bool loadedToGpu = true; }; } diff --git a/imageReader.cpp b/imageReader.cpp index 62c9762..a09d59e 100644 --- a/imageReader.cpp +++ b/imageReader.cpp @@ -17,15 +17,12 @@ namespace vb01{ Asset* ImageReader::readAsset(string path){ stbi_set_flip_vertically_on_load(flip); - int width, height, numChannels, layerId; + int width, height, numChannels, bufferId, layerId; u8 *data = stbi_load(path.c_str(), &width, &height, &numChannels, 0); - if(loadToGpu){ - Root *root = Root::getSingleton(); - u32 *texBuffer = (sceneImage ? root->getMeshTextureBuffer() : root->getGuiTextureBuffer()); - root->initTextureDataOnGpu(texBuffer, data, width, height, layerId); - } + if(loadToGpu) + Root::getSingleton()->initTextureDataOnGpu(data, width, height, bufferId, layerId, sceneImage); - return new ImageAsset(path, data, width, height, numChannels, layerId); + return new ImageAsset(path, data, width, height, numChannels, bufferId, layerId, loadToGpu); } } diff --git a/phong4.frag b/phong4.frag index 9f22047..e8cd232 100755 --- a/phong4.frag +++ b/phong4.frag @@ -1,7 +1,7 @@ #version 460 core const bool checkLights=false; -in flat int ID; +in flat int drawId, instanceId; in vec3 fragPos; in vec3 tan; in vec3 biTan; @@ -81,7 +81,8 @@ float getShadow(int id){ } void main(){ - int id = ID; + int id = drawId; + vec4 diffuseColor = vec4(objData[id].diffuseColor[0], objData[id].diffuseColor[1], objData[id].diffuseColor[2], objData[id].diffuseColor[3]); vec4 finalColor = diffuseColor; diff --git a/phong4.vert b/phong4.vert index c3fcf9e..3c1ec89 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 ID; +out int drawId, instanceId; struct Bone{ float angle; @@ -80,10 +80,10 @@ float getWeight(Bone bone){ } void main(){ + int id = gl_DrawID; + vec4 vertPos = vec4(aPos, 1); bool anyWeights = false; - - int id = gl_DrawID + gl_InstanceID; mat4 model = objData[id].model; mat3 normalMat = mat3(transpose(inverse(model))); norm = (normalMat * aNorm); @@ -147,5 +147,6 @@ void main(){ gl_Position = viewProj * model * vertPos; fragPos = vec3(model * vertPos); texCoords = aTexCoords; - ID = id; + drawId = gl_DrawID; + instanceId = gl_InstanceID; } diff --git a/root.cpp b/root.cpp index aef4b85..c2e0c5a 100755 --- a/root.cpp +++ b/root.cpp @@ -76,12 +76,6 @@ namespace vb01{ guiPlaneTextureBuffer = new u32; glGenTextures(1, guiPlaneTextureBuffer); - meshTextureBuffer = new u32[NUM_MAX_TEXTURE_UNITS]; - glGenTextures(NUM_MAX_TEXTURE_UNITS, meshTextureBuffer); - - guiTextureBuffer = new u32[NUM_MAX_TEXTURE_UNITS]; - glGenTextures(NUM_MAX_TEXTURE_UNITS, guiTextureBuffer); - phongShader = new Shader(libPath + "phong4"); guiShader = new Shader(libPath + "gui"); @@ -144,42 +138,49 @@ namespace vb01{ } //TODO check loading of textures with different dimensions - void Root::initTextureDataOnGpu(u32 *textureBuffer, u8 *data, int width, int height, int &layerId){ - bool present = false; + void Root::initTextureDataOnGpu(u8 *data, int width, int height, int &bufferId, int &layerId, bool scene){ + int textureUnitId = -1; + vector &textureData = (scene ? meshTextureData : guiTextureData); - for(pair &p : currTextureDims) - if(p.first == width && p.second == height){ - present = true; + for(int i = 0; i < textureData.size(); i++) + if(textureData[i].width == width && textureData[i].height == height){ + textureUnitId = i; break; } - if(!present) currTextureDims.push_back(make_pair(width, height)); + if(textureUnitId == -1){ + textureData.push_back(TextureUnitGpuData(width, height)); + textureUnitId = textureData.size() - 1; + glGenTextures(1, &textureData[textureUnitId].buffer); + } AssetManager *assetManager = AssetManager::getSingleton(); vector assets = assetManager->getAssets(assetManager->getImageFormats()); - for(int i = 0; i < currTextureDims.size(); i++){ + for(int i = 0; i < textureData.size(); i++){ vector imgAssets; - pair &resPair = currTextureDims[i]; + TextureUnitGpuData &texData = textureData[i]; for(Asset *asset : assets){ ImageAsset *a = (ImageAsset*)asset; - if(a->width == resPair.first && a->height == resPair.second) + if(a->loadedToGpu && a->width == texData.width && a->height == texData.height) imgAssets.push_back((ImageAsset*)asset); } - //layerId = currNumLayers, currNumLayers++; + glBindTexture(GL_TEXTURE_2D_ARRAY, texData.buffer); + glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, texData.width, texData.height, imgAssets.size() + 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); - glBindTexture(GL_TEXTURE_2D_ARRAY, textureBuffer[i]); - glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, resPair.first, resPair.second, imgAssets.size() + 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + for(int j = 0; j < imgAssets.size(); j++) + glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, j, imgAssets[j]->width, imgAssets[j]->height, 1, GL_RGB, GL_UNSIGNED_BYTE, imgAssets[j]->image); - for(int i = 0; i < imgAssets.size(); i++) - glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, i, width, height, 1, GL_RGB, GL_UNSIGNED_BYTE, imgAssets[i]->image); - - if(resPair.first == width && resPair.second == height){ + if(textureUnitId == i){ + bufferId = i; + int lid = 0 + (imgAssets.size() == 0 ? 0 : 1); layerId = lid; + texData.numLayers++; + glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, lid, width, height, 1, GL_RGB, GL_UNSIGNED_BYTE, data); } @@ -187,6 +188,7 @@ namespace vb01{ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } } @@ -296,8 +298,20 @@ namespace vb01{ bool lightingEnabled = ((Material::BoolUniform*)mat->getUniform("lightingEnabled"))->value; for(int i = 0; i < drawCmdMeshes.size(); i++) - if(*(drawCmdMeshes[i]) == meshData) - drawCmds[i].instanceCount++; + if(*(drawCmdMeshes[i]) == meshData){ + int sum = 0; + + for(int j = 0; j < i; j++) + sum += 3 * drawCmdMeshes[j]->numTris; + + DrawElementsIndirectCommand cmd; + cmd.count = 3 * meshData.numTris; + cmd.instanceCount = 1; + cmd.firstIndex = sum; + cmd.baseVertex = 0; + cmd.baseInstance = 0; + drawCmds.push_back(cmd); + } ObjectVertexData ovd; ovd.viewProj = projView; @@ -422,18 +436,7 @@ namespace vb01{ u32 vertSize = sizeof(MeshData::GpuVertex), indexSize = sizeof(u32); if(updateDrawCommands){ - DrawElementsIndirectCommand drawCmd; - drawCmd.count = 3 * meshData.numTris; - drawCmd.instanceCount = 0; - drawCmd.firstIndex = currentIndices.size(); - drawCmd.baseVertex = currentGpuVertices.size(); - drawCmd.baseInstance = 0; - drawCmds.push_back(drawCmd); drawCmdMeshes.push_back(&meshData); - - glBindBuffer(GL_DRAW_INDIRECT_BUFFER, drawCmdBuffer); - glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand) * drawCmds.size(), drawCmds.data(), GL_DYNAMIC_DRAW); - int currNumIndices = currentIndices.size(); for(int i = 0; i < 3 * meshData.numTris; i++) @@ -471,18 +474,6 @@ namespace vb01{ //Texture *brightTexture = new Texture(width, height, false); } - void Root::addMeshes(Node *rootNode){ - vector descendants; - rootNode->getDescendants(descendants); - - vector meshes; - - for(Node *desc : descendants){ - vector m = desc->getMeshes(); - meshes.insert(meshes.end(), m.begin(), m.end()); - } - } - void Root::toggleHDR(bool hdr){ glDeleteFramebuffers((hdr ? 2 : 1), &FBO); glDeleteRenderbuffers(1, &RBO); @@ -651,9 +642,9 @@ namespace vb01{ glNamedBufferSubData(objLightBuffer, 0, sizeof(LightData) * lightData.size(), lightData.data()); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, objLightBuffer); - for(int i = 0; i < currTextureDims.size(); i++){ + for(int i = 0; i < meshTextureData.size(); i++){ glActiveTexture(GL_TEXTURE0 + i); - glBindTexture(GL_TEXTURE_2D_ARRAY, meshTextureBuffer[i]); + glBindTexture(GL_TEXTURE_2D_ARRAY, meshTextureData[i].buffer); } glBindVertexArray(meshVAO); @@ -674,9 +665,9 @@ namespace vb01{ 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++){ + for(int i = 0; i < guiTextureData.size(); i++){ glActiveTexture(GL_TEXTURE0 + i); - glBindTexture(GL_TEXTURE_2D_ARRAY, guiTextureBuffer[i]); + glBindTexture(GL_TEXTURE_2D_ARRAY, guiTextureData[i].buffer); } glBindVertexArray(guiVAO); @@ -702,6 +693,7 @@ namespace vb01{ if(!gui){ objVertData.clear(); objFragData.clear(); + drawCmds.clear(); for(DrawElementsIndirectCommand &cmd : drawCmds) cmd.instanceCount = 0; @@ -717,74 +709,6 @@ namespace vb01{ for(int i = 0; i < currTextureDims.size(); i++) shader->setInt(i, "textureSamplers[" + to_string(i) + "]"); - - /* - if(gui){} //renderGui(); - else{ - renderMeshes(); - //renderParticles(particleEmitters); - } - - vector descendants, opaqueNodes, transparentNodes; - node->getDescendants(descendants); - - for(Node *desc : descendants){ - if(!desc->isVisible()) continue; - - vector meshes = desc->getMeshes(); - - if(!meshes.empty()) - for(Mesh *mesh : meshes){ - bool transparentMesh = (mesh->getMaterial()->isTransparent()); - (transparentMesh ? transparentNodes : opaqueNodes).push_back(desc); - } - else if(!desc->getTexts().empty()) - transparentNodes.push_back(desc); - else{ - opaqueNodes.push_back(desc); - } - } - - int numNodes = transparentNodes.size(); - - for(int i = 0; i < numNodes; i++){ - float d1 = transparentNodes[i]->getPosition().z; - - if(!gui){ - Vector3 v1 = transparentNodes[i]->getPosition() - camera->getPosition(); - float a1 = v1.norm().getAngleBetween(camera->getDirection()); - d1 = v1.getLength() * cos(a1); - } - - for(int j = i; j < numNodes; j++){ - float d2 = transparentNodes[j]->getPosition().z; - - if(!gui){ - Vector3 v2 = transparentNodes[j]->getPosition() - camera->getPosition(); - float a2 = v2.norm().getAngleBetween(camera->getDirection()); - d2 = v2.getLength() * cos(a2); - } - - if(d1 > d2) - swap(transparentNodes[i], transparentNodes[j]); - } - } - - vector renderNodes = opaqueNodes; - renderNodes.insert(renderNodes.end(), transparentNodes.begin(), transparentNodes.end()); - - - for(Node *renderNode : renderNodes){ - //renderNode->update(); - - - for(Mesh *mesh : renderNode->getMeshes()){ - mat->getShader()->use(); - mat->getShader()->setInt(0, "textureSampler"); - - } - } - */ } void Root::updateBloomFramebuffer(){ diff --git a/root.h b/root.h index 4def3af..295fdd6 100755 --- a/root.h +++ b/root.h @@ -37,13 +37,12 @@ namespace vb01{ void start(int, int, std::string, std::string); void toggleHDR(bool); void toggleBloom(bool); - void addMeshes(Node*); void createSkybox(std::string[6]); void createSkybox(vb01::Texture*); void removeSkybox(); void initVertexDataOnGpu(MeshData&, u32&, u32&, u32&, bool); void initTextureDataOnGpu(int, int); - void initTextureDataOnGpu(u32*, u8*, int, int, int&); + void initTextureDataOnGpu(u8*, int, int, int&, int&, bool); void updateRenderNodeData(Node*); void createCubemap(bool, bool, std::string[6], int); inline Shader* getPhongShader(){return phongShader;} @@ -54,8 +53,6 @@ namespace vb01{ 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;} @@ -83,6 +80,9 @@ namespace vb01{ int baseVertex = 0; u32 baseInstance = 0; }; + struct ObjectIdData{ + int drawId = 0, instanceId = 0; + }; struct ObjectVertexData { float shapeKeyFactors[24]; glm::mat4 viewProj, model, bones[256]; @@ -109,18 +109,18 @@ namespace vb01{ float diffuseColor[4]; }; struct TextureUnitGpuData { - u32 *buffer = nullptr; + u32 buffer = -1; int numLayers = 0, width = 0, height = 0; - TextureUnitGpuData(u32 *b, int l, int w, int h) : buffer(b), numLayers(l), width(w), height(h){} + TextureUnitGpuData(int w, int h) : 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 = -1, meshVBO = -1, meshEBO = -1, *meshTextureBuffer = nullptr, *depthmapBuffer = nullptr; + u32 meshVAO = -1, meshVBO = -1, meshEBO = -1; u32 particleVAO = -1, particleVBO = -1; - u32 guiVAO = -1, guiVBO = -1, guiEBO = -1, *guiTextureBuffer = nullptr; + u32 guiVAO = -1, guiVBO = -1, guiEBO = -1; u32 guiPlaneVAO = -1, guiPlaneVBO = -1, guiPlaneEBO = -1, *guiPlaneTextureBuffer = nullptr; u32 skyboxVAO = -1, skyboxVBO = -1, skyboxEBO = -1, skyboxBuffer = -1; u32 FBO = -1, RBO = -1, pingpongBuffers[2], drawCmdBuffer = -1, objVertBuffer = -1, objFragBuffer = -1, objLightBuffer = -1, guiDataBuffer = -1; @@ -138,12 +138,14 @@ namespace vb01{ std::vector> currTextureDims; std::vector currentIndices; std::vector meshes; - std::vector drawCmds; + std::vector drawCmds, drawCmds2; + std::vector objIdData; std::vector objVertData; std::vector objFragData; std::vector lightData; std::vector guiData; - std::vector textureGpuData; + std::vector numObjGpuInstances; + std::vector meshTextureData, depthmapData, guiTextureData; std::string libPath; Root(); diff --git a/texture.cpp b/texture.cpp index b8fc822..beb1a92 100755 --- a/texture.cpp +++ b/texture.cpp @@ -45,7 +45,7 @@ namespace vb01{ if(!cm){ ImageAsset *imgAsset = (ImageAsset*)AssetManager::getSingleton()->getAsset(paths[i]); - frames.push_back(Frame(nullptr, imgAsset->layerId)); + frames.push_back(Frame(imgAsset->bufferId, imgAsset->layerId)); } } @@ -59,7 +59,8 @@ namespace vb01{ 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)); + const FontAsset::Glyph &glyph = fontAsset->getGlyph(id); + frames.push_back(Frame(glyph.bufferId, glyph.layerId)); } Texture::~Texture(){ diff --git a/texture.h b/texture.h index b90268d..5bdc8b1 100755 --- a/texture.h +++ b/texture.h @@ -32,10 +32,9 @@ namespace vb01{ inline bool isTransparent(){return png;} private: struct Frame{ - u32 *buffer = nullptr; - int layerId = 0; + int bufferId = 0, layerId = 0; - Frame(u32 *b, int lid) : buffer(b), layerId(lid){} + Frame(int bid, int lid) : bufferId(bid), layerId(lid){} }; bool cubemap = false, png = false; diff --git a/xmlModelReader.cpp b/xmlModelReader.cpp index cb771bf..81c7f70 100644 --- a/xmlModelReader.cpp +++ b/xmlModelReader.cpp @@ -208,9 +208,9 @@ namespace vb01{ numShapeKeys ); - Root *root = Root::getSingleton(); - root->initVertexDataOnGpu(meshData, root->getMeshVAO(), root->getMeshVBO(), root->getMeshEBO(), true); Mesh *mesh = new Mesh(meshData); + Root *root = Root::getSingleton(); + root->initVertexDataOnGpu(mesh->getMeshBase(), root->getMeshVAO(), root->getMeshVBO(), root->getMeshEBO(), true); return mesh; }