diff --git a/box.cpp b/box.cpp index 2988ef2..9171bbc 100755 --- a/box.cpp +++ b/box.cpp @@ -2,8 +2,13 @@ #include "root.h" namespace vb01{ - Box::Box(Vector3 sz) : size(sz){ + Box::Box(Vector3 sz, bool renderMesh) : size(sz){ init(); + + if(renderMesh){ + Root *root = Root::getSingleton(); + root->initVertexDataOnGpu(meshBase, root->getMeshVAO(), root->getMeshVBO(), root->getMeshEBO(), true); + } } Box::Box(Box *b){ @@ -71,7 +76,5 @@ namespace vb01{ } meshBase = MeshData(pos, nullptr, nullptr, nullptr, 8, norm, vertices, indices, numTris); - Root *root = Root::getSingleton(); - root->initVertexDataOnGpu(meshBase, root->getMeshVAO(), root->getMeshVBO(), root->getMeshEBO(), true); } } diff --git a/box.h b/box.h index 254cd7c..c81b6e4 100755 --- a/box.h +++ b/box.h @@ -6,7 +6,7 @@ namespace vb01{ class Box : public Mesh{ public: - Box(Vector3); + Box(Vector3, bool = true); inline Box* clone(){return new Box(this);} inline void setSize(Vector3 size){this->size = size;} inline Vector3 getSize(){return size;} diff --git a/imageReader.cpp b/imageReader.cpp index 695f417..6d3deae 100644 --- a/imageReader.cpp +++ b/imageReader.cpp @@ -6,20 +6,23 @@ using namespace std; namespace vb01{ - ImageReader *imageReader = nullptr; + ImageReader *imageReader = nullptr; - ImageReader* ImageReader::getSingleton(){ - if(!imageReader) - imageReader = new ImageReader(); + ImageReader* ImageReader::getSingleton(){ + if(!imageReader) + imageReader = new ImageReader(); - return imageReader; - } + return imageReader; + } - Asset* ImageReader::readAsset(string path){ - stbi_set_flip_vertically_on_load(flip); - int width, height, numChannels, layerId; - u8 *data = stbi_load(path.c_str(), &width, &height, &numChannels, 0); + Asset* ImageReader::readAsset(string path){ + stbi_set_flip_vertically_on_load(flip); + 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); - return new ImageAsset(path, data, width, height, numChannels, layerId); - } + + return new ImageAsset(path, data, width, height, numChannels, layerId); + } } diff --git a/imageReader.h b/imageReader.h index 0cabda7..202e067 100644 --- a/imageReader.h +++ b/imageReader.h @@ -6,17 +6,19 @@ #include "abstractAssetReader.h" namespace vb01{ - class ImageReader : public AbstractAssetReader{ - public: - static ImageReader* getSingleton(); - inline void setFlip(bool flip){this->flip = flip;} - inline bool isFlip(){return flip;} - Asset* readAsset(std::string); - private: - ImageReader(){} + class ImageReader : public AbstractAssetReader{ + public: + static ImageReader* getSingleton(); + inline void setFlip(bool flip){this->flip = flip;} + inline bool isFlip(){return flip;} + inline void setLoadToGpu(bool ltg){this->loadToGpu = ltg;} + inline bool isLoadToGpu(){return loadToGpu;} + Asset* readAsset(std::string); + private: + ImageReader(){} - bool flip = true; - }; + bool flip = true, loadToGpu = true; + }; } #endif diff --git a/material.cpp b/material.cpp index 1937488..5eff7c4 100755 --- a/material.cpp +++ b/material.cpp @@ -7,20 +7,16 @@ using namespace glm; namespace vb01{ Material::Material(Shader *sh) : shader(sh){} - Material::~Material(){ - delete shader; - } - Material::Uniform* Material::getUniform(string name){ - Uniform *uni = nullptr; + Uniform *uni = nullptr; - for(Uniform *u : uniforms) - if(u->name == name){ - uni = u; - break; - } + for(Uniform *u : uniforms) + if(u->name == name){ + uni = u; + break; + } - return uni; + return uni; } void Material::setIntUniform(string name, int value){ @@ -65,68 +61,69 @@ namespace vb01{ int i = 0; for(Uniform *uni : uniforms){ - switch(uni->type){ - case Uniform::INT:{ - IntUniform *u = (IntUniform*)uni; - shader->setInt(u->value, u->name); - break; - } - case Uniform::BOOL:{ - BoolUniform *u = (BoolUniform*)uni; - shader->setBool(u->value, u->name); - break; - } - case Uniform::FLOAT:{ - FloatUniform *u = (FloatUniform*)uni; - shader->setFloat(u->value, u->name); - break; - } - case Uniform::VECTOR_2:{ - Vector2Uniform *u = (Vector2Uniform*)uni; - shader->setVec2(u->value, u->name); - break; - } - case Uniform::VECTOR_3:{ - Vector3Uniform *u = (Vector3Uniform*)uni; - shader->setVec3(u->value, u->name); - break; - } - case Uniform::VECTOR_4:{ - Vector4Uniform *u = (Vector4Uniform*)uni; - shader->setVec4(u->value, u->name); - break; - } - case Uniform::TEXTURE:{ - TextureUniform *u = (TextureUniform*)uni; - shader->setInt(2 * i, u->name + (u->animatable ? ".pastTexture" : "")); + if(!uni->uniform) continue; - if(u->animatable) { - if(u->value->getNumFrames() > 1){ - shader->setInt(2 * i + 1, u->name + ".nextTexture"); - shader->setFloat(u->value->getMixRatio(), u->name + ".mixRatio"); - shader->setBool(true, u->name + ".animated"); - } - else - shader->setBool(false, u->name + ".animated"); - } - - u->value->update(2 * i); - - ++i; - break; - } + switch(uni->type){ + case Uniform::INT:{ + IntUniform *u = (IntUniform*)uni; + shader->setInt(u->value, u->name); + break; } + case Uniform::BOOL:{ + BoolUniform *u = (BoolUniform*)uni; + shader->setBool(u->value, u->name); + break; + } + case Uniform::FLOAT:{ + FloatUniform *u = (FloatUniform*)uni; + shader->setFloat(u->value, u->name); + break; + } + case Uniform::VECTOR_2:{ + Vector2Uniform *u = (Vector2Uniform*)uni; + shader->setVec2(u->value, u->name); + break; + } + case Uniform::VECTOR_3:{ + Vector3Uniform *u = (Vector3Uniform*)uni; + shader->setVec3(u->value, u->name); + break; + } + case Uniform::VECTOR_4:{ + Vector4Uniform *u = (Vector4Uniform*)uni; + shader->setVec4(u->value, u->name); + break; + } + case Uniform::TEXTURE:{ + TextureUniform *u = (TextureUniform*)uni; + shader->setInt(2 * i, u->name + (u->animatable ? ".pastTexture" : "")); + if(u->animatable) { + if(u->value->getNumFrames() > 1){ + shader->setInt(2 * i + 1, u->name + ".nextTexture"); + shader->setFloat(u->value->getMixRatio(), u->name + ".mixRatio"); + shader->setBool(true, u->name + ".animated"); + } + else + shader->setBool(false, u->name + ".animated"); + } + + u->value->update(2 * i); + + ++i; + break; + } + } } } vector Material::getUniformsByType(Material::Uniform::Type type){ - vector uniforms; + vector uniforms; - for(Uniform *uni : this->uniforms) - if(uni->type == type) - uniforms.push_back(uni); + for(Uniform *uni : this->uniforms) + if(uni->type == type) + uniforms.push_back(uni); - return uniforms; + return uniforms; } } diff --git a/material.h b/material.h index d71b048..f678321 100755 --- a/material.h +++ b/material.h @@ -15,42 +15,40 @@ namespace vb01{ class Material{ public: struct Uniform : public Animatable{ - enum Type{ - INT, - BOOL, - FLOAT, - VECTOR_2, - VECTOR_3, - VECTOR_4, - TEXTURE - }; + enum Type{ + INT, + BOOL, + FLOAT, + VECTOR_2, + VECTOR_3, + VECTOR_4, + TEXTURE + }; - Uniform(std::string name, Type type) : Animatable(Animatable::MATERIAL_UNIFORM, name){ - this->name = name; - this->type = type; - } + Uniform(std::string n, Type t, bool un) : Animatable(Animatable::MATERIAL_UNIFORM, n), name(n), type(t), uniform(un){} - void animate(float val, KeyframeChannel channel){ - switch(channel.type){ - case KeyframeChannel::UNIFORM_1: - animateComponent1(val); - break; - case KeyframeChannel::UNIFORM_2: - animateComponent2(val); - break; - case KeyframeChannel::UNIFORM_3: - animateComponent3(val); - break; - case KeyframeChannel::UNIFORM_4: - animateComponent4(val); - break; - } + void animate(float val, KeyframeChannel channel){ + switch(channel.type){ + case KeyframeChannel::UNIFORM_1: + animateComponent1(val); + break; + case KeyframeChannel::UNIFORM_2: + animateComponent2(val); + break; + case KeyframeChannel::UNIFORM_3: + animateComponent3(val); + break; + case KeyframeChannel::UNIFORM_4: + animateComponent4(val); + break; } + } - std::string name; - Type type; + Type type; + bool uniform; + std::string name; - protected: + protected: virtual void animateComponent1(float val){} virtual void animateComponent2(float val){} virtual void animateComponent3(float val){} @@ -58,89 +56,74 @@ namespace vb01{ }; struct IntUniform : public Uniform{ - int value; + int value; - IntUniform(std::string name, int value) : Uniform(name, Uniform::INT){ - this->value = value; - } + IntUniform(std::string name, int val, bool unif) : Uniform(name, Uniform::INT, unif), value(val){} - void animateComponent1(float val){value = (int)val;} + void animateComponent1(float val){value = (int)val;} }; struct BoolUniform : public Uniform{ - bool value; + bool value; - BoolUniform(std::string name, bool value) : Uniform(name, Uniform::BOOL){ - this->value = value; - } + BoolUniform(std::string name, bool val, bool unif) : Uniform(name, Uniform::BOOL, unif), value(val){} - void animateComponent1(float val){value = (bool)val;} + void animateComponent1(float val){value = (bool)val;} }; struct FloatUniform : public Uniform{ - float value; + float value; - FloatUniform(std::string name, float value) : Uniform(name, Uniform::FLOAT){ - this->value = value; - } + FloatUniform(std::string name, float val, bool unif) : Uniform(name, Uniform::FLOAT, unif), value(val){} - void animateComponent1(float val){value = val;} + void animateComponent1(float val){value = val;} }; struct Vector2Uniform : public Uniform{ - Vector2 value; + Vector2 value; - Vector2Uniform(std::string name, Vector2 value) : Uniform(name, Uniform::VECTOR_2){ - this->value = value; - } + Vector2Uniform(std::string name, Vector2 val, bool unif) : Uniform(name, Uniform::VECTOR_2, unif), value(val){} - void animateComponent1(float val){value.x = val;} + void animateComponent1(float val){value.x = val;} - void animateComponent2(float val){value.y = val;} + void animateComponent2(float val){value.y = val;} }; struct Vector3Uniform : public Uniform{ - Vector3 value; + Vector3 value; - Vector3Uniform(std::string name, Vector3 value) : Uniform(name, Uniform::VECTOR_3){ - this->value = value; - } + Vector3Uniform(std::string name, Vector3 val, bool unif) : Uniform(name, Uniform::VECTOR_3, unif), value(val){} - void animateComponent1(float val){value.x = val;} + void animateComponent1(float val){value.x = val;} - void animateComponent2(float val){value.y = val;} + void animateComponent2(float val){value.y = val;} - void animateComponent3(float val){value.z = val;} + void animateComponent3(float val){value.z = val;} }; struct Vector4Uniform : public Uniform{ - Vector4 value; + Vector4 value; - Vector4Uniform(std::string name, Vector4 value) : Uniform(name, Uniform::VECTOR_4){ - this->value = value; - } + Vector4Uniform(std::string name, Vector4 val, bool unif) : Uniform(name, Uniform::VECTOR_4, unif), value(val){} - void animateComponent1(float val){value.x = val;} + void animateComponent1(float val){value.x = val;} - void animateComponent2(float val){value.y = val;} + void animateComponent2(float val){value.y = val;} - void animateComponent3(float val){value.z = val;} + void animateComponent3(float val){value.z = val;} - void animateComponent4(float val){value.w = val;} + void animateComponent4(float val){value.w = val;} }; struct TextureUniform : public Uniform{ - Texture *value = nullptr; - bool animatable = false; + Texture *value = nullptr; + bool animatable = false; - TextureUniform(std::string name, Texture *value, bool animatable) : Uniform(name, Uniform::TEXTURE){ - this->value = value; - this->animatable = animatable; - } + TextureUniform(std::string name, Texture *val, bool anim, bool unif) : Uniform(name, Uniform::TEXTURE, unif), value(val), animatable(anim){} }; Material(Shader*); - ~Material(); + ~Material(){} void update(); void setIntUniform(std::string, int); void setBoolUniform(std::string, bool); @@ -152,13 +135,13 @@ namespace vb01{ Uniform* getUniform(std::string); std::vector getUniformsByType(Uniform::Type); inline Uniform* getUniform(int i){return uniforms[i];} - inline void addIntUniform(std::string name, int value){uniforms.push_back(new IntUniform(name, value));} - inline void addBoolUniform(std::string name, bool value){uniforms.push_back(new BoolUniform(name, value));} - inline void addFloatUniform(std::string name, float value){uniforms.push_back(new FloatUniform(name, value));} - inline void addVec2Uniform(std::string name, Vector2 value){uniforms.push_back(new Vector2Uniform(name, value));} - inline void addVec3Uniform(std::string name, Vector3 value){uniforms.push_back(new Vector3Uniform(name, value));} - inline void addVec4Uniform(std::string name, Vector4 value){uniforms.push_back(new Vector4Uniform(name, value));} - inline void addTexUniform(std::string name, Texture *value, bool animatable){uniforms.push_back(new TextureUniform(name, value, animatable));} + inline void addIntUniform(std::string name, int value, bool uniform = true){uniforms.push_back(new IntUniform(name, value, uniform));} + inline void addBoolUniform(std::string name, bool value, bool uniform = true){uniforms.push_back(new BoolUniform(name, value, uniform));} + inline void addFloatUniform(std::string name, float value, bool uniform = true){uniforms.push_back(new FloatUniform(name, value, uniform));} + inline void addVec2Uniform(std::string name, Vector2 value, bool uniform = true){uniforms.push_back(new Vector2Uniform(name, value, uniform));} + inline void addVec3Uniform(std::string name, Vector3 value, bool uniform = true){uniforms.push_back(new Vector3Uniform(name, value, uniform));} + inline void addVec4Uniform(std::string name, Vector4 value, bool uniform = true){uniforms.push_back(new Vector4Uniform(name, value, uniform));} + inline void addTexUniform(std::string name, Texture *value, bool animatable, bool uniform = true){uniforms.push_back(new TextureUniform(name, value, animatable, uniform));} inline Shader* getShader(){return shader;} inline bool isTransparent(){return transparent;} inline void setTransparent(bool t){this->transparent = t;} diff --git a/node.cpp b/node.cpp index 46a9e7e..aec95ba 100755 --- a/node.cpp +++ b/node.cpp @@ -72,10 +72,15 @@ namespace vb01{ for(Skeleton *sk : skeletons) sk->update(); - } - for(Driver *driver : drivers) - driver->drive(getDriverValue(driver->getType())); + for(Driver *driver : drivers) + driver->drive(getDriverValue(driver->getType())); + + Root::getSingleton()->updateRenderNodeData(this); + + for(Node *child : children) + child->update(); + } } Node* Node::clone(){ diff --git a/quad.cpp b/quad.cpp index 9d02e47..89bd543 100755 --- a/quad.cpp +++ b/quad.cpp @@ -6,8 +6,13 @@ namespace vb01{ using namespace std; - Quad::Quad(Vector3 sz, bool sp, int nvd, int nhd) : size(sz), spatial(sp), numVertDiv(nvd), numHorDiv(nhd){ + Quad::Quad(Vector3 sz, bool sp, int nvd, int nhd, bool renderMesh) : size(sz), spatial(sp), numVertDiv(nvd), numHorDiv(nhd){ init(); + + if(renderMesh){ + Root *root = Root::getSingleton(); + root->initVertexDataOnGpu(meshBase, root->getMeshVAO(), root->getMeshVBO(), root->getMeshEBO(), true); + } } Quad::Quad(Quad *q){ @@ -86,7 +91,6 @@ namespace vb01{ } meshBase = MeshData(faceVertPos, nullptr, nullptr, nullptr, 6, norm, vertices, indices, numTris); - //Root::getSingleton()->initVertexDataOnGpu(meshBase); } //TODO improve functionality for GUI quads diff --git a/quad.h b/quad.h index 1a68d78..8dd43bd 100755 --- a/quad.h +++ b/quad.h @@ -7,7 +7,7 @@ namespace vb01{ class Quad : public Mesh{ public: - Quad(Vector3, bool = true, int numVertDiv = 0, int numHorDiv = 0); + Quad(Vector3, bool = true, int numVertDiv = 0, int numHorDiv = 0, bool = true); Vector3 getSubquadCorner(int, int, int, int, bool, bool); Vector2 getSubquadIds(int, int, Vector3, Vector3); inline Quad* clone(){return new Quad(this);} diff --git a/root.cpp b/root.cpp index a0b12df..1c3db93 100755 --- a/root.cpp +++ b/root.cpp @@ -5,6 +5,7 @@ #include "box.h" #include "quad.h" #include "camera.h" +#include "light.h" #include "lineRenderer.h" #include "assetManager.h" #include "imageAsset.h" @@ -66,6 +67,9 @@ namespace vb01{ glGenBuffers(1, &drawCmdBuffer); glGenBuffers(1, &objVertBuffer); glGenBuffers(1, &objFragBuffer); + glGenBuffers(1, &objLightBuffer); + + glGenTextures(1, &skyboxBuffer); guiPlaneTextureBuffer = new u32; glGenTextures(1, guiPlaneTextureBuffer); @@ -76,6 +80,7 @@ namespace vb01{ phongShader = new Shader(libPath + "phong4"); + initMeshRendering(meshVAO, meshVBO, meshEBO); initParticleRendering(); initGuiRendering(); @@ -131,11 +136,9 @@ namespace vb01{ 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)); } + //TODO check loading of textures with different dimensions void Root::initTextureDataOnGpu(u32 *textureBuffer, u8 *data, int width, int height, int &layerId){ bool present = false; @@ -180,8 +183,169 @@ namespace vb01{ 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::updateRenderNodeData(Node *node){ + Quaternion orient = Quaternion::QUAT_W; + Vector3 pos = Vector3::VEC_ZERO, scale = Vector3::VEC_IJK; + bool gui = false; + + 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)); + + 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(); + + 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.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); + } + + 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); + } + } + + void Root::createCubemap(bool depth, bool fromFile, string paths[6], int mipmapLevel){ + for(int i = 0; i < 6; i++){ + if(!depth){ + if(paths[0] != ""){ + ImageAsset *asset = (ImageAsset*)AssetManager::getSingleton()->getAsset(paths[i]); + int width = asset->width; + + glBindTexture(GL_TEXTURE_CUBE_MAP, skyboxBuffer); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, width, width, 0, GL_RGB, GL_UNSIGNED_BYTE, asset->image); + } + else{ + glBindTexture(GL_TEXTURE_CUBE_MAP, NULL); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, width, width, 0, GL_RGB, GL_UNSIGNED_INT, NULL); + } + } + else{ + glBindTexture(GL_TEXTURE_CUBE_MAP, NULL); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT, width, width, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); + } + } + + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + if(mipmapLevel > 0){ + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glGenerateMipmap(GL_TEXTURE_CUBE_MAP); + } + else + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } void Root::initVertexDataOnGpu(MeshData &meshData, u32 &VAO, u32 &VBO, u32 &EBO, bool updateDrawCommands){ @@ -342,7 +506,7 @@ namespace vb01{ } void Root::initGuiPlane(){ - guiPlane = new Quad(Vector3(width, height, -1), false); + guiPlane = new Quad(Vector3(width, height, -1), false, 0, 0, false); initMeshRendering(guiPlaneVAO, guiPlaneVBO, guiPlaneEBO); initVertexDataOnGpu(guiPlane->getMeshBase(), guiPlaneVAO, guiPlaneVBO, guiPlaneEBO, false); @@ -365,7 +529,8 @@ namespace vb01{ glCullFace(GL_FRONT); skybox->update(); - renderMesh(skybox, meshVAO); + skybox->getMaterial()->getShader()->setMat4(calculateProjView(), "projView"); + renderMesh(skybox, skyboxVAO, skyboxBuffer, true); glDepthMask(GL_TRUE); glCullFace(GL_BACK); @@ -373,17 +538,9 @@ namespace vb01{ AnimationController::getSingleton()->update(); - Vector3 camPos = camera->getPosition(); - - Vector3 dir = camera->getDirection(), up = camera->getUp(); - mat4 view = lookAt(vec3(camPos.x, camPos.y, camPos.z), vec3(camPos.x + dir.x, camPos.y + dir.y, camPos.z + dir.z), vec3(up.x, up.y, up.z)); - - float fov = camera->getFov(), nearPlane = camera->getNearPlane(), farPlane = camera->getFarPlane(); - mat4 proj = perspective(radians(fov), (float)width / height, nearPlane, farPlane); - - mat4 projView = proj * view; - - updateNodeTree(rootNode, projView, false); + updateNodeTree(phongShader, false); + rootNode->update(); + renderMeshes(); //LineRenderer::getSingleton()->drawLines(); @@ -398,13 +555,17 @@ namespace vb01{ updateGuiPlane(); glEnable(GL_DEPTH_TEST); + //updateNodeTree(guiShader, true); //updateNodeTree(guiNode, true); glfwSwapBuffers(window); glfwPollEvents(); } - void Root::renderMesh(Mesh *mesh, u32 &vao){ + void Root::renderMesh(Mesh *mesh, u32 &vao, u32 &texBuffer, bool cubemap){ + glActiveTexture(GL_TEXTURE0); + glBindTexture(cubemap ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D, texBuffer); + MeshData meshData = mesh->getMeshBase(); glBindVertexArray(vao); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); @@ -421,10 +582,8 @@ namespace vb01{ glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(ObjectFragmentData) * objFragData.size(), objFragData.data(), GL_DYNAMIC_DRAW); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, objFragBuffer); - /* - glNamedBufferSubData(objFragBuffer, 0, sizeof(ObjectFragmentData) * objFragData.size(), objFragData.data()); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, objFragBuffer); - */ + glNamedBufferSubData(objLightBuffer, 0, sizeof(LightData) * lightData.size(), lightData.data()); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, objLightBuffer); for(int i = 0; i < currTextureDims.size(); i++){ glActiveTexture(GL_TEXTURE0 + i); @@ -447,9 +606,43 @@ namespace vb01{ void Root::renderGui(vector &meshes){ } + mat4 Root::calculateProjView(Vector3 camPos){ + Vector3 dir = camera->getDirection(), up = camera->getUp(); + mat4 view = lookAt(vec3(camPos.x, camPos.y, camPos.z), vec3(camPos.x + dir.x, camPos.y + dir.y, camPos.z + dir.z), vec3(up.x, up.y, up.z)); + + float fov = camera->getFov(), nearPlane = camera->getNearPlane(), farPlane = camera->getFarPlane(); + mat4 proj = perspective(radians(fov), (float)width / height, nearPlane, farPlane); + + return proj * view; + } + //TODO replace sorting algorithm //TODO specify differentiation of nodes with translucent meshes AND texts - void Root::updateNodeTree(Node *node, mat4 &projView, bool gui){ + void Root::updateNodeTree(Shader *shader, bool gui){ + shader->use(); + + if(!gui){ + Vector3 camPos = camera->getPosition(); + shader->setVec3(camPos, "camPos"); + projView = calculateProjView(camPos); + } + + objVertData.clear(); + objFragData.clear(); + + for(DrawElementsIndirectCommand &cmd : drawCmds) + cmd.instanceCount = 0; + + 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); @@ -495,107 +688,21 @@ namespace vb01{ } } - objVertData.clear(); - objFragData.clear(); - - for(DrawElementsIndirectCommand &cmd : drawCmds) - cmd.instanceCount = 0; - vector renderNodes = opaqueNodes; renderNodes.insert(renderNodes.end(), transparentNodes.begin(), transparentNodes.end()); + for(Node *renderNode : renderNodes){ - renderNode->update(); + //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(); - //renderParticles(particleEmitters); - } + */ } void Root::updateBloomFramebuffer(){ @@ -612,7 +719,7 @@ namespace vb01{ else pingPongTextures[!horizontal]->select(); - renderMesh(guiPlane, guiPlaneVAO); + renderMesh(guiPlane, guiPlaneVAO, meshVAO, false); horizontal = !horizontal; } @@ -631,8 +738,6 @@ namespace vb01{ shader->setFloat(gamma, "gamma"); shader->setInt(0, "frag"); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, guiPlaneTextureBuffer[0]); //((Material::TextureUniform*)material->getUniform("frag"))->value->select(0); if(hdr){ @@ -640,7 +745,7 @@ namespace vb01{ ((Material::TextureUniform*)material->getUniform("bright"))->value->select(1); } - renderMesh(guiPlane, guiPlaneVAO); + renderMesh(guiPlane, guiPlaneVAO, guiPlaneTextureBuffer[0], false); } void Root::createSkybox(string paths[6]){ @@ -649,7 +754,13 @@ namespace vb01{ } void Root::createSkybox(Texture *texture){ - skybox = new Box(Vector3::VEC_IJK * 10); + skybox = new Box(Vector3::VEC_IJK * 10, false); + + if(skyboxVBO == -1){ + initMeshRendering(skyboxVAO, skyboxVBO, skyboxEBO); + initVertexDataOnGpu(skybox->getMeshBase(), skyboxVAO, skyboxVBO, skyboxEBO, false); + } + Material *skyboxMat = new Material(new Shader(libPath + "skybox")); skyboxMat->addTexUniform("tex", texture, true); skybox->setMaterial(skyboxMat); diff --git a/root.h b/root.h index f44b8b3..a3b3ee1 100755 --- a/root.h +++ b/root.h @@ -44,6 +44,8 @@ namespace vb01{ void initVertexDataOnGpu(MeshData&, u32&, u32&, u32&, bool); void initTextureDataOnGpu(int, int); void initTextureDataOnGpu(u32*, u8*, int, int, int&); + void updateRenderNodeData(Node*); + void createCubemap(bool, bool, std::string[6], int); inline Shader* getPhongShader(){return phongShader;} inline u32& getMeshVAO(){return meshVAO;} inline u32& getMeshVBO(){return meshVBO;} @@ -89,6 +91,13 @@ namespace vb01{ float shinyness, specularStrength; int lightingEnabled, constLightingEnabled, texturingEnabled, normalMapEnabled, specularMapEnabled, castShadow, environmentMapEnabled; }; + struct LightData { + int useAngle, additive, render; + int type, attenuation; + float pos[3], color[3], direction[3]; + float innerAngle, outerAngle; + float a, b, c, near, far, radius; + }; struct TextureGpuData { u32 *buffer = nullptr; int unitId = 0, layerId = 0, width = 0, height = 0; @@ -96,9 +105,15 @@ namespace vb01{ TextureGpuData(u32 *b, int u, int l, int w, int h) : buffer(b), unitId(u), layerId(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, particleVAO, particleVBO, guiPlaneVAO, guiPlaneVBO, guiPlaneEBO, *meshTextureBuffer = nullptr, *guiPlaneTextureBuffer = nullptr, *depthmapBuffer = nullptr, FBO, RBO, pingpongBuffers[2], drawCmdBuffer = -1, objVertBuffer = -1, objFragBuffer = -1; + u32 meshVAO, meshVBO, meshEBO, *meshTextureBuffer = nullptr, *depthmapBuffer = nullptr; + u32 particleVAO, particleVBO; + u32 guiVAO, guiVBO, guiEBO, *guiTextureBuffer = nullptr; + u32 guiPlaneVAO, guiPlaneVBO, guiPlaneEBO, *guiPlaneTextureBuffer = nullptr; + u32 skyboxVAO = -1, skyboxVBO = -1, skyboxEBO = -1, skyboxBuffer = -1; + u32 FBO, RBO, pingpongBuffers[2], drawCmdBuffer = -1, objVertBuffer = -1, objFragBuffer = -1, objLightBuffer = -1; bool bloom = false, hdr = false; float exposure = 1, gamma = 1; Box *skybox = nullptr, *iblBox = nullptr; @@ -116,6 +131,7 @@ namespace vb01{ std::vector drawCmds; std::vector objVertData; std::vector objFragData; + std::vector lightData; std::vector textureGpuData; std::string libPath; @@ -130,8 +146,9 @@ namespace vb01{ void initGuiPlane(); void updateBloomFramebuffer(); void updateGuiPlane(); - void updateNodeTree(vb01::Node*, glm::mat4&, bool); - void renderMesh(Mesh*, u32&); + glm::mat4 calculateProjView(Vector3 = Vector3::VEC_ZERO); + void updateNodeTree(Shader*, bool); + void renderMesh(Mesh*, u32&, u32&, bool); protected: virtual void initMeshRendering(u32 &vao, u32 &vbo, u32 &ebo); diff --git a/skybox.vert b/skybox.vert index 282f92d..396e66c 100755 --- a/skybox.vert +++ b/skybox.vert @@ -4,10 +4,10 @@ layout (location = 0) in vec3 aPos; out vec3 texCoords; -uniform mat4 proj, view; +uniform mat4 projView; void main(){ texCoords = aPos; - vec4 pos = proj * view * vec4(aPos, 1); + vec4 pos = projView * vec4(aPos, 1); gl_Position = pos; } diff --git a/texture.cpp b/texture.cpp index 97dc839..505f56f 100755 --- a/texture.cpp +++ b/texture.cpp @@ -31,110 +31,28 @@ namespace vb01{ glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor); */ } - else{ - Root::getSingleton()->initTextureDataOnGpu(width, height); - /* - glTexImage2D(GL_TEXTURE_2D, 0, (hiRes ? GL_RGB16F : GL_RGB), width, height, 0, GL_RGB, GL_FLOAT, 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); - */ - } - } - - Texture::Texture(string paths[], int numPaths, bool cubemap, int mipmapLevel, bool flip, string name) : Animatable(Animatable::TEXTURE, name){ - this->cubemap = cubemap; - this->paths = new string[numPaths]; - - for(int i = 0; i < numPaths; i++) - this->paths[i] = paths[i]; - - if(cubemap){ - texture = new u32; - createCubemap(false, flip, true); - } - else{ - this->numFrames = numPaths; - //texture = new u32[numPaths]; - //create2DTexture(flip); - // - for(int i = 0; i < numFrames; i++){ - ImageAsset *imgAsset = (ImageAsset*)AssetManager::getSingleton()->getAsset(paths[i]); - frames.push_back(Frame(nullptr, imgAsset->layerId)); - } - } - } - - void Texture::loadImageData(ImageAsset *asset, bool creating, int i){ - if(!creating) glDeleteTextures(1, &texture[i]); - - width = asset->width; - height = asset->height; - - glGenTextures(1, &texture[i]); - glBindTexture(GL_TEXTURE_2D, texture[i]); - glTexImage2D(GL_TEXTURE_2D, 0, png ? GL_RGBA : GL_RGB, width, height, 0, png ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, asset->image); - glGenerateMipmap(GL_TEXTURE_2D); - } - - void Texture::create2DTexture(bool flip){ - mixRatio = .1; - - for(int i = 0; i < numFrames; i++){ - int length = paths[i].length(); - - if(paths[i].substr(length - 4, string::npos) == ".png") - png = true; - - loadImageData((ImageAsset*)AssetManager::getSingleton()->getAsset(paths[i]), true); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } - } - - Texture::Texture(int width, bool depth, int mipmapLevel, string name) : Animatable(Animatable::TEXTURE, name){ - this->width = width; - this->mipmapLevel = mipmapLevel; - this->cubemap = true; - texture = new u32; - - createCubemap(depth, false, false); - } - - void Texture::createCubemap(bool depth, bool flip, bool fromFile){ - glGenTextures(1, &texture[0]); - glBindTexture(GL_TEXTURE_CUBE_MAP, texture[0]); - - for(int i = 0; i < 6; i++){ - if(!depth){ - if(fromFile){ - ImageAsset *asset = (ImageAsset*)AssetManager::getSingleton()->getAsset(paths[i]); - width = asset->width; - - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, width, width, 0, GL_RGB, GL_UNSIGNED_BYTE, asset->image); - } - else - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, width, width, 0, GL_RGB, GL_UNSIGNED_INT, NULL); - } - else - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT, width, width, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); - } - - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - if(mipmapLevel > 0){ - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glGenerateMipmap(GL_TEXTURE_CUBE_MAP); - } else - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + Root::getSingleton()->initTextureDataOnGpu(width, height); + } + + Texture::Texture(string paths[], int np, bool cm, int ml, bool flip, string name) : Animatable(Animatable::TEXTURE, name), numFrames(np), cubemap(cm), mipmapLevel(ml){ + this->paths = new string[np]; + + for(int i = 0; i < np; i++){ + this->paths[i] = paths[i]; + + if(!cm){ + ImageAsset *imgAsset = (ImageAsset*)AssetManager::getSingleton()->getAsset(paths[i]); + frames.push_back(Frame(nullptr, imgAsset->layerId)); + } + } + + if(cm) Root::getSingleton()->createCubemap(false, true, paths, ml); + } + + Texture::Texture(int w, bool depth, int ml, string name) : Animatable(Animatable::TEXTURE, name), width(w), mipmapLevel(ml), cubemap(true){ + string p[6]{""}; + Root::getSingleton()->createCubemap(depth, false, p, ml); } Texture::Texture(FT_Face face) : Animatable(Animatable::TEXTURE){ @@ -161,18 +79,7 @@ namespace vb01{ } Texture::~Texture(){ - glBindTexture(cubemap ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D, 0); - - if(numFrames > 0){ - for(int i = 0; i < numFrames; i++) - glDeleteTextures(1, &texture[i]); - - delete[] texture; - } - else{ - glDeleteTextures(1, &texture[0]); - delete texture; - } + delete paths; } void Texture::animate(float value, KeyframeChannel keyframeChannel){ diff --git a/texture.h b/texture.h index dc4df0d..8406ffd 100755 --- a/texture.h +++ b/texture.h @@ -46,8 +46,6 @@ namespace vb01{ std::string *paths = nullptr; std::vector frames; - void createCubemap(bool, bool, bool); - void create2DTexture(bool); inline int getNextFrame(int frameId){return (frameId + 1 < numFrames ? frameId + 1 : 0);} }; }