moved texture GPU data loading to Root

reordered node and mesh rendering data generation
materials no longer create their own shaders
This commit is contained in:
devZoGok
2026-06-27 10:21:40 +03:00
parent cc59f9160c
commit 4578f0c6ad
10 changed files with 278 additions and 149 deletions
+188 -110
View File
@@ -7,6 +7,7 @@
#include "camera.h"
#include "lineRenderer.h"
#include "assetManager.h"
#include "imageAsset.h"
#include "animationController.h"
#include "glad.h"
@@ -65,6 +66,15 @@ namespace vb01{
glGenBuffers(1, &drawCmdBuffer);
glGenBuffers(1, &objVertBuffer);
glGenBuffers(1, &objFragBuffer);
guiPlaneTextureBuffer = new u32;
glGenTextures(1, guiPlaneTextureBuffer);
meshTextureBuffer = new u32[NUM_MAX_TEXTURE_UNITS];
glGenTextures(NUM_MAX_TEXTURE_UNITS, meshTextureBuffer);
glBindTexture(GL_TEXTURE_2D_ARRAY, meshTextureBuffer[0]);
phongShader = new Shader(libPath + "phong4");
initMeshRendering(meshVAO, meshVBO, meshEBO);
initParticleRendering();
@@ -113,6 +123,67 @@ namespace vb01{
*/
}
void Root::initTextureDataOnGpu(int width, int height){
glBindTexture(GL_TEXTURE_2D, guiPlaneTextureBuffer[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
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);
//textureGpuData.push_back(TextureGpuData(textureBuffer, , width, height));
}
void Root::initTextureDataOnGpu(u32 *textureBuffer, u8 *data, int width, int height, int &layerId){
bool present = false;
for(pair<int, int> &p : currTextureDims)
if(p.first == width && p.second == height){
present = true;
break;
}
if(!present) currTextureDims.push_back(make_pair(width, height));
AssetManager *assetManager = AssetManager::getSingleton();
vector<Asset*> assets = assetManager->getAssets(assetManager->getImageFormats());
for(int i = 0; i < currTextureDims.size(); i++){
vector<ImageAsset*> imgAssets;
pair<int, int> &resPair = currTextureDims[i];
for(Asset *asset : assets){
ImageAsset *a = (ImageAsset*)asset;
if(a->width == resPair.first && a->height == resPair.second)
imgAssets.push_back((ImageAsset*)asset);
}
//layerId = currNumLayers, currNumLayers++;
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 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){
int lid = 0 + (imgAssets.size() == 0 ? 0 : 1);
layerId = lid;
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, lid, width, height, 1, GL_RGB, GL_UNSIGNED_BYTE, data);
}
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
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);
}
//textureGpuData.push_back(TextureGpuData(textureBuffer, , width, height));
}
void Root::initVertexDataOnGpu(MeshData &meshData, u32 &VAO, u32 &VBO, u32 &EBO, bool updateDrawCommands){
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
@@ -167,8 +238,8 @@ namespace vb01{
for(int i = 0; i < 2; i++)
pingPongTextures[i] = new Texture(width, height, false);
Texture *fragTexture = new Texture(width, height, false);
Texture *brightTexture = new Texture(width, height, false);
//Texture *fragTexture = new Texture(width, height, false);
//Texture *brightTexture = new Texture(width, height, false);
}
void Root::addMeshes(Node *rootNode){
@@ -250,7 +321,7 @@ namespace vb01{
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
u32 colorAttachments[]{GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[0], GL_TEXTURE_2D, *fragTexture->getTexture(), 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[0], GL_TEXTURE_2D, *guiPlaneTextureBuffer, 0);
if(brightTexture){
glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[1], GL_TEXTURE_2D, *brightTexture->getTexture(), 0);
@@ -276,7 +347,7 @@ namespace vb01{
initMeshRendering(guiPlaneVAO, guiPlaneVBO, guiPlaneEBO);
initVertexDataOnGpu(guiPlane->getMeshBase(), guiPlaneVAO, guiPlaneVBO, guiPlaneEBO, false);
Material *mat = new Material(libPath + "postProcess");
Material *mat = new Material(new Shader(libPath + "postProcess"));
mat->addTexUniform("frag", pingPongTextures[0], false);
mat->addTexUniform("bright", pingPongTextures[1], false);
guiPlane->setMaterial(mat);
@@ -355,6 +426,11 @@ namespace vb01{
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, objFragBuffer);
*/
for(int i = 0; i < currTextureDims.size(); i++){
glActiveTexture(GL_TEXTURE0 + i);
glBindTexture(GL_TEXTURE_2D_ARRAY, meshTextureBuffer[i]);
}
glBindVertexArray(meshVAO);
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, drawCmdBuffer);
@@ -371,123 +447,27 @@ namespace vb01{
void Root::renderGui(vector<Mesh*> &meshes){
}
void Root::updateNode(Node *node, mat4 &proj, mat4 &view, bool gui){
Quaternion orient = Quaternion::QUAT_W;
Vector3 pos = Vector3::VEC_ZERO, scale = Vector3::VEC_IJK;
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;
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));
vector<Mesh*> mesh = node->getMeshes();
vector<ParticleEmitter*> pe = node->getParticleEmitters();
/*
for(Mesh *m : mesh){
}
*/
//meshes.insert(meshes.end(), mesh.begin(), mesh.end());
//particleEmitters.insert(particleEmitters.end(), pe.begin(), pe.end());
node->update();
}
//TODO replace sorting algorithm
//TODO specify differentiation of nodes with translucent meshes AND texts
void Root::updateNodeTree(Node *node, mat4 &projView, bool gui){
objVertData.clear();
objFragData.clear();
for(DrawElementsIndirectCommand &cmd : drawCmds)
cmd.instanceCount = 0;
vector<Node*> descendants, opaqueNodes, transparentNodes;
node->getDescendants(descendants);
for(Node *desc : descendants){
if(!desc->isVisible()) continue;
vector<Mesh*> meshes = desc->getMeshes();
if(!desc->getMeshes().empty()){
Quaternion orient = Quaternion::QUAT_W;
Vector3 pos = Vector3::VEC_ZERO, scale = Vector3::VEC_IJK;
if(!gui){
pos = desc->localToGlobalPosition(Vector3::VEC_ZERO);
orient = desc->localToGlobalOrientation(Quaternion::QUAT_W);
scale = desc->getScale();
if(!meshes.empty())
for(Mesh *mesh : meshes){
bool transparentMesh = (mesh->getMaterial()->isTransparent());
(transparentMesh ? transparentNodes : opaqueNodes).push_back(desc);
}
Vector3 rotAxis = orient.getAxis();
if(rotAxis == Vector3::VEC_ZERO)
rotAxis = Vector3::VEC_I;
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));
for(Mesh *mesh : desc->getMeshes()){
if(mesh->getMaterial()->isTransparent()){
transparentNodes.push_back(desc);
}
else{
mesh->getMaterial()->getShader()->use();
ObjectVertexData ovd;
ovd.viewProj = projView;
ovd.model = model;
//ovd.animated = 0;
//ovd.bones[0];
MeshData &meshData = mesh->getMeshBase();
for(int i = 0; i < drawCmdMeshes.size(); i++)
if(*(drawCmdMeshes[i]) == meshData)
drawCmds[i].instanceCount++;
/*
*/
//for(int i = 0; i < meshData.numShapeKeys; i++) ovd.shapeKeyFactors[i] = meshData.shapeKeys[i].value;
objVertData.push_back(ovd);
ObjectFragmentData ofd;
ofd.diffuseColor = Vector4::VEC_IJKL;
ofd.specularColor;
ofd.shinyness;
ofd.specularStrength;
ofd.lightingEnabled = false,
ofd.constLightingEnabled = false,
ofd.texturingEnabled = false,
ofd.normalMapEnabled = false,
ofd.specularMapEnabled = false,
ofd.castShadow = false,
ofd.environmentMapEnabled = false;
objFragData.push_back(ofd);
//updateNode(desc, projView, gui);
}
break;
}
}
else if(!desc->getTexts().empty())
transparentNodes.push_back(desc);
else{
//updateNode(desc, proj, view, gui);
//opaqueNodes.push_back(desc);
}
opaqueNodes.push_back(desc);
}
}
int numNodes = transparentNodes.size();
@@ -515,6 +495,102 @@ namespace vb01{
}
}
objVertData.clear();
objFragData.clear();
for(DrawElementsIndirectCommand &cmd : drawCmds)
cmd.instanceCount = 0;
vector<Node*> renderNodes = opaqueNodes;
renderNodes.insert(renderNodes.end(), transparentNodes.begin(), transparentNodes.end());
for(Node *renderNode : renderNodes){
renderNode->update();
Quaternion orient = Quaternion::QUAT_W;
Vector3 pos = Vector3::VEC_ZERO, scale = Vector3::VEC_IJK;
if(!gui){
pos = renderNode->localToGlobalPosition(Vector3::VEC_ZERO);
orient = renderNode->localToGlobalOrientation(Quaternion::QUAT_W);
scale = renderNode->getScale();
}
Vector3 rotAxis = orient.getAxis();
if(rotAxis == Vector3::VEC_ZERO)
rotAxis = Vector3::VEC_I;
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));
for(Mesh *mesh : renderNode->getMeshes()){
Material *mat = mesh->getMaterial();
mat->getShader()->use();
mat->getShader()->setInt(0, "textureSampler");
ObjectVertexData ovd;
ovd.viewProj = projView;
ovd.model = model;
//ovd.animated = 0;
//ovd.bones[0];
MeshData &meshData = mesh->getMeshBase();
for(int i = 0; i < drawCmdMeshes.size(); i++)
if(*(drawCmdMeshes[i]) == meshData)
drawCmds[i].instanceCount++;
/*
for(int i = 0; i < meshData.numShapeKeys; i++)
ovd.shapeKeyFactors[i] = meshData.shapeKeys[i].value;
*/
objVertData.push_back(ovd);
ObjectFragmentData ofd;
ofd.texturingEnabled = true;
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 = false;
if(ofd.lightingEnabled){
ofd.constLightingEnabled = false;
ofd.texturingEnabled = 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);
}
}
if(gui){} //renderGui();
else{
renderMeshes();
@@ -555,7 +631,9 @@ namespace vb01{
shader->setFloat(gamma, "gamma");
shader->setInt(0, "frag");
((Material::TextureUniform*)material->getUniform("frag"))->value->select(0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, guiPlaneTextureBuffer[0]);
//((Material::TextureUniform*)material->getUniform("frag"))->value->select(0);
if(hdr){
shader->setInt(1, "bright");
@@ -572,7 +650,7 @@ namespace vb01{
void Root::createSkybox(Texture *texture){
skybox = new Box(Vector3::VEC_IJK * 10);
Material *skyboxMat = new Material(libPath + "skybox");
Material *skyboxMat = new Material(new Shader(libPath + "skybox"));
skyboxMat->addTexUniform("tex", texture, true);
skybox->setMaterial(skyboxMat);
}