From 8f49bd1125a420da60275eac145457359e09dd0d Mon Sep 17 00:00:00 2001 From: devZoGok Date: Fri, 4 Dec 2020 20:27:44 +0200 Subject: [PATCH] rendering classes refactoring --- CMakeLists.txt | 2 +- bone.cpp | 2 +- box.cpp | 88 ++++++++--------- light.cpp | 197 ++++++++++++++++++++----------------- light.h | 35 +++---- material.cpp | 91 +++++++++-------- material.h | 50 +++++----- mesh.cpp | 233 +++++++++++++++++++++++--------------------- mesh.h | 44 +++++---- model.cpp | 16 +-- model.h | 2 +- node.cpp | 138 +++++++++++++------------- node.h | 19 ++-- particle.frag | 17 ++-- particle.vert | 34 +++---- particleEmitter.cpp | 233 +++++++++++++++++++++++--------------------- particleEmitter.h | 42 ++++---- quad.cpp | 88 ++++++++--------- quad.h | 2 +- root.cpp | 175 ++++++++++++++++++--------------- root.h | 36 ++++--- shader.cpp | 167 ++++++++++++++++--------------- shader.h | 32 +++--- texture.cpp | 202 +++++++++++++++++++------------------- texture.h | 34 ++++--- 25 files changed, 1028 insertions(+), 951 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f2189f..3e69076 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.6) +cmake_minimum_required(VERSION 2.9) project(vb01) include_directories(/usr/include/GLFW) diff --git a/bone.cpp b/bone.cpp index 2b95680..3275fa8 100644 --- a/bone.cpp +++ b/bone.cpp @@ -32,7 +32,7 @@ namespace vb01{ Vector3 Bone::getModelSpacePos(){ Vector3 modelSpacePos = Vector3::VEC_ZERO; Bone *rootBone = skeleton->getRootBone(); - vector boneHierarchy = getAncestors(this, rootBone); + vector boneHierarchy = getAncestors(rootBone); while(!boneHierarchy.empty()){ int id = boneHierarchy.size() - 1; diff --git a/box.cpp b/box.cpp index d25b236..b063844 100755 --- a/box.cpp +++ b/box.cpp @@ -2,11 +2,11 @@ namespace vb01{ Box::Box(Vector3 size){ - this->staticVerts=false; + this->staticVerts = false; - numTris=12; - indices=new unsigned int[3*numTris]; - vertices=new Vertex[3*numTris]; + numTris = 12; + indices = new u32[3 * numTris]; + vertices = new Vertex[3 * numTris]; setSize(size); @@ -14,59 +14,59 @@ namespace vb01{ } void Box::setSize(Vector3 size){ - this->size=size; - Vector3 pos[]={ - Vector3(size.x/2,size.y/2,size.z/2), - Vector3(-size.x/2,size.y/2,size.z/2), - Vector3(-size.x/2,size.y/2,-size.z/2), - Vector3(size.x/2,size.y/2,-size.z/2), + this->size = size; + Vector3 pos[] = { + Vector3(size.x / 2, size.y / 2, size.z / 2), + Vector3(-size.x / 2, size.y / 2, size.z / 2), + Vector3(-size.x / 2, size.y / 2, -size.z / 2), + Vector3(size.x / 2, size.y / 2, -size.z / 2), - Vector3(size.x/2,-size.y/2,size.z/2), - Vector3(-size.x/2,-size.y/2,size.z/2), - Vector3(-size.x/2,-size.y/2,-size.z/2), - Vector3(size.x/2,-size.y/2,-size.z/2) + Vector3(size.x / 2, -size.y / 2, size.z / 2), + Vector3(-size.x / 2, -size.y / 2, size.z / 2), + Vector3(-size.x / 2, -size.y / 2, -size.z / 2), + Vector3(size.x / 2, -size.y / 2, -size.z / 2) }; - Vector3 norm[]={ - Vector3(0,0,1), - Vector3(0,1,0), - Vector3(1,0,0), + Vector3 norm[] = { + Vector3(0, 0, 1), + Vector3(0, 1, 0), + Vector3(1, 0, 0), - Vector3(0,0,-1), - Vector3(0,-1,0), - Vector3(-1,0,0) + Vector3(0, 0, -1), + Vector3(0, -1, 0), + Vector3(-1, 0, 0) }; - Vector2 tex[]={ - Vector2(1,1), - Vector2(0,1), - Vector2(0,0), - Vector2(1,0) + Vector2 tex[] = { + Vector2(1, 1), + Vector2(0, 1), + Vector2(0, 0), + Vector2(1, 0) }; unsigned int data[]={ - 0,3,1, 4,3,0, 1,3,2, - 5,3,3, 1,3,2, 4,3,0, + 0, 3, 1, 4, 3, 0, 1, 3, 2, + 5, 3, 3, 1, 3, 2, 4, 3, 0, - 2,0,1, 6,0,0, 3,0,2, - 6,0,2, 7,0,0, 3,0,3, + 2, 0, 1, 6, 0, 0, 3, 0, 2, + 6, 0, 2, 7, 0, 0, 3, 0, 3, - 3,2,0, 7,2,1, 4,2,2, - 4,2,2, 0,2,3, 3,2,0, + 3, 2, 0, 7, 2, 1, 4, 2, 2, + 4, 2, 2, 0, 2, 3, 3, 2, 0, - 1,5,0, 5,5,1, 6,5,2, - 6,5,2, 2,5,3, 1,5,0, + 1, 5, 0, 5, 5, 1, 6, 5, 2, + 6, 5, 2, 2, 5, 3, 1, 5, 0, - 0,1,0, 1,1,1, 2,1,2, - 2,1,2, 3,1,3, 0,1,0, + 0, 1, 0, 1, 1, 1, 2, 1, 2, + 2, 1, 2, 3, 1, 3, 0, 1, 0, - 4,4,3, 6,4,1, 5,4,2, - 6,4,1, 4,4,3, 7,4,0 + 4, 4, 3, 6, 4, 1, 5, 4, 2, + 6, 4, 1, 4, 4, 3, 7, 4, 0 }; - for(int i=0;i<3*numTris;i++){ + for(int i = 0; i < 3 * numTris; i++){ Vertex v; - v.pos=pos[data[3*i]]; - v.norm=norm[data[3*i+1]]; - v.uv=tex[data[3*i+2]]; - vertices[i]=v; - indices[i]=i; + v.pos = pos[data[3 * i]]; + v.norm = norm[data[3 * i + 1]]; + v.uv = tex[data[3 * i + 2]]; + vertices[i] = v; + indices[i] = i; } } } diff --git a/light.cpp b/light.cpp index 31ae892..38db627 100755 --- a/light.cpp +++ b/light.cpp @@ -15,42 +15,45 @@ using namespace std; namespace vb01{ Light::Light(Type t){ - this->type=t; - string basePath="../../vb01/depthMap."; - - glGenFramebuffers(1,&depthmapFBO); - glBindFramebuffer(GL_FRAMEBUFFER,depthmapFBO); - if(this->type==POINT){ - depthMap=new Texture(depthMapSize); - glFramebufferTexture(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,*(depthMap->getTexture()),0); - depthMapShader=new Shader(basePath+"vert",basePath+"frag",basePath+"geo"); - } - else{ - depthMap=new Texture(depthMapSize,depthMapSize,true); - glFramebufferTexture2D(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_TEXTURE_2D,*(depthMap->getTexture()),0); - depthMapShader=new Shader(basePath+"vert",basePath+"frag"); - } - glDrawBuffer(GL_NONE); - glReadBuffer(GL_NONE); - if(glCheckFramebufferStatus(GL_FRAMEBUFFER)!=GL_FRAMEBUFFER_COMPLETE) - cout<<"Not complete\n"; - glBindFramebuffer(GL_FRAMEBUFFER,0); - + this->type = t; + initDepthMap(); } Light::~Light(){ - glBindFramebuffer(GL_FRAMEBUFFER,0); - glDeleteFramebuffers(1,&depthmapFBO); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glDeleteFramebuffers(1, &depthmapFBO); delete depthMap; delete depthMapShader; } + void Light::initDepthMap(){ + string basePath = "../../vb01/depthMap."; + + glGenFramebuffers(1, &depthmapFBO); + glBindFramebuffer(GL_FRAMEBUFFER, depthmapFBO); + if(type == POINT){ + depthMap = new Texture(depthMapSize); + glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, *(depthMap->getTexture()), 0); + depthMapShader = new Shader(basePath + "vert", basePath + "frag", basePath + "geo"); + } + else{ + depthMap = new Texture(depthMapSize, depthMapSize, true); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, *(depthMap->getTexture()), 0); + depthMapShader = new Shader(basePath + "vert", basePath + "frag"); + } + glDrawBuffer(GL_NONE); + glReadBuffer(GL_NONE); + if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + cout<<"Not complete\n"; + glBindFramebuffer(GL_FRAMEBUFFER, 0); + } + void Light::update(){ - Root *root=Root::getSingleton(); - Node *rootNode=root->getRootNode(); + Root *root = Root::getSingleton(); + Node *rootNode = root->getRootNode(); vector descendants; vector lights; rootNode->getDescendants(rootNode, descendants); @@ -79,98 +82,112 @@ namespace vb01{ void Light::renderShadow(std::vector descendants, mat4 &proj, mat4 &view){ vec3 dirs[]{ - vec3(1,0,0), - vec3(-1,0,0), - vec3(0,1,0), - vec3(0,-1,0), - vec3(0,0,1), - vec3(0,0,-1) + vec3(1, 0, 0), + vec3(-1, 0, 0), + vec3(0, 1, 0), + vec3(0, -1, 0), + vec3(0, 0, 1), + vec3(0, 0, -1) }; Root *root = Root::getSingleton(); - glViewport(0,0,depthMapSize,depthMapSize); - glBindFramebuffer(GL_FRAMEBUFFER,depthmapFBO); + glViewport(0, 0, depthMapSize, depthMapSize); + glBindFramebuffer(GL_FRAMEBUFFER, depthmapFBO); glClear(GL_DEPTH_BUFFER_BIT); for(Node *n : descendants){ - vector meshes=n->getMeshes(); + vector meshes = n->getMeshes(); for(Mesh *mesh : meshes){ - Material *mat=mesh->getMaterial(); - if(n->isVisible()&&mat&&mat->isLightingEnabled()){ - Vector3 pos=n->localToGlobalPosition(Vector3::VEC_ZERO); - Quaternion rot=n->localToGlobalOrientation(Quaternion::QUAT_W); - Vector3 rotAxis=rot.norm().getAxis(); + Material *mat = mesh->getMaterial(); + if(mesh->isCastShadow() && n->isVisible() && mat && mat->isLightingEnabled()){ + Vector3 pos = n->localToGlobalPosition(Vector3::VEC_ZERO); + Quaternion rot = n->localToGlobalOrientation(Quaternion::QUAT_W); + Vector3 rotAxis = rot.norm().getAxis(); - if(rotAxis==Vector3::VEC_ZERO) - rotAxis=Vector3::VEC_I; + if(rotAxis == Vector3::VEC_ZERO) + rotAxis = Vector3::VEC_I; - Vector3 upDir=direction.cross(Vector3(0,1,0)); - if(upDir==Vector3(0,0,0)) + Vector3 upDir = direction.cross(Vector3(0, 1, 0)); + if(upDir == Vector3::VEC_ZERO) upDir=Vector3::VEC_I; - vec3 dir=vec3(direction.x,direction.y,direction.z); - vec3 up=vec3(upDir.x,upDir.y,upDir.z); - vec3 p=type==DIRECTIONAL?vec3(pos.x,pos.y,pos.z)-.5f*farPlane*dir:vec3(position.x,position.y,position.z); - view=lookAt(p,p+dir,up); - proj=(type==DIRECTIONAL?ortho(-10.f,10.f,-10.f,10.f,nearPlane,farPlane):perspective(radians(90.f),1.f,nearPlane,farPlane)); - mat4 model=translate(mat4(1.f),vec3(pos.x,pos.y,pos.z)); - model=rotate(model,rot.getAngle(),vec3(rotAxis.x,rotAxis.y,rotAxis.z)); - - if(mesh->isCastShadow()){ - depthMapShader->use(); - depthMapShader->setBool(type==POINT,"point"); - depthMapShader->setMat4(model,"model"); - - if(type==POINT){ - depthMapShader->setFloat(farPlane,"farPlane"); - depthMapShader->setVec3(position,"lightPos"); - for(int j=0;j<6;j++) - depthMapShader->setMat4(proj*lookAt(p,p+dirs[j],1setMat4(proj*view,"lightMat"); - } - mesh->render(); + vec3 dir = vec3(direction.x, direction.y, direction.z); + vec3 up = vec3(upDir.x, upDir.y, upDir.z); + vec3 p; + if(type == DIRECTIONAL){ + p = vec3(pos.x, pos.y, pos.z) - .5f * farPlane * dir; + float orthoCorner = 10.f; + proj = ortho(-orthoCorner, orthoCorner, -orthoCorner, orthoCorner, nearPlane, farPlane); } + else{ + p = vec3(position.x, position.y, position.z); + proj = perspective(radians(90.f), 1.f, nearPlane, farPlane); + } + + view = lookAt(p, p + dir, up); + + mat4 model = translate(mat4(1.f), vec3(pos.x, pos.y, pos.z)); + model = rotate(model, rot.getAngle(), vec3(rotAxis.x, rotAxis.y, rotAxis.z)); + + depthMapShader->use(); + depthMapShader->setBool(type == POINT, "point"); + depthMapShader->setMat4(model, "model"); + + if(type == POINT){ + depthMapShader->setFloat(farPlane, "farPlane"); + depthMapShader->setVec3(position, "lightPos"); + for(int j = 0; j < 6; j++){ + vec3 v; + if(1 < j && j < 4) + v = vec3(0, 0, -1); + else + v = vec3(0, -1, 0); + + depthMapShader->setMat4(proj * lookAt(p, p + dirs[j], v), "shadowMat[" + to_string(j) + "]"); + } + } + else + depthMapShader->setMat4(proj * view, "lightMat"); + mesh->render(); } } } - glBindFramebuffer(GL_FRAMEBUFFER,*(root->getFBO())); - glViewport(0,0,root->getWidth(),root->getHeight()); + glBindFramebuffer(GL_FRAMEBUFFER, *(root->getFBO())); + glViewport(0, 0, root->getWidth(), root->getHeight()); } void Light::updateShader(vector materials, int thisId, mat4 &proj, mat4 &view){ for(Material *m : materials){ - Shader *shader=m->getShader(); + Shader *shader = m->getShader(); shader->use(); - shader->setInt((int)type,"light["+to_string(thisId)+"].type"); - shader->setVec3(color,"light["+to_string(thisId)+"].color"); - shader->setFloat(nearPlane,"light["+to_string(thisId)+"].near"); - shader->setFloat(farPlane,"light["+to_string(thisId)+"].far"); - shader->setInt(5,"light["+to_string(thisId)+"].depthMapCube"); - shader->setInt(6,"light["+to_string(thisId)+"].depthMap"); - depthMap->select(type==POINT?5:6); + shader->setInt((int)type, "light[" + to_string(thisId) + "].type"); + shader->setVec3(color, "light[" + to_string(thisId) + "].color"); + shader->setFloat(nearPlane, "light[" + to_string(thisId) + "].near"); + shader->setFloat(farPlane, "light[" + to_string(thisId) + "].far"); + shader->setInt(5, "light[" + to_string(thisId) + "].depthMapCube"); + shader->setInt(6, "light[" + to_string(thisId) + "].depthMap"); + depthMap->select(type == POINT ? 5 : 6); switch(type){ case POINT: - shader->setVec3(position,"light["+to_string(thisId)+"].pos"); - shader->setFloat(attenuationValues.x,"light["+to_string(thisId)+"].a"); - shader->setFloat(attenuationValues.y,"light["+to_string(thisId)+"].b"); - shader->setFloat(attenuationValues.z,"light["+to_string(thisId)+"].c"); + shader->setVec3(position, "light[" + to_string(thisId) + "].pos"); + shader->setFloat(attenuationValues.x, "light[" + to_string(thisId) + "].a"); + shader->setFloat(attenuationValues.y, "light[" + to_string(thisId) + "].b"); + shader->setFloat(attenuationValues.z, "light[" + to_string(thisId) + "].c"); break; case DIRECTIONAL: - shader->setMat4(proj*view,"light["+to_string(thisId)+"].lightMat"); - shader->setVec3(direction,"light["+to_string(thisId)+"].direction"); + shader->setMat4(proj * view, "light[" + to_string(thisId) + "].lightMat"); + shader->setVec3(direction, "light[" + to_string(thisId) + "].direction"); break; case SPOT: - shader->setMat4(proj*view,"light["+to_string(thisId)+"].lightMat"); - shader->setVec3(position,"light["+to_string(thisId)+"].pos"); - shader->setVec3(direction,"light["+to_string(thisId)+"].direction"); - shader->setFloat(attenuationValues.x,"light["+to_string(thisId)+"].a"); - shader->setFloat(attenuationValues.y,"light["+to_string(thisId)+"].b"); - shader->setFloat(attenuationValues.z,"light["+to_string(thisId)+"].c"); - shader->setFloat(innerAngle,"light["+to_string(thisId)+"].innerAngle"); - shader->setFloat(outerAngle,"light["+to_string(thisId)+"].outerAngle"); + shader->setMat4(proj * view, "light[" + to_string(thisId) + "].lightMat"); + shader->setVec3(position, "light[" + to_string(thisId) + "].pos"); + shader->setVec3(direction,"light[" + to_string(thisId) + "].direction"); + shader->setFloat(attenuationValues.x, "light["+to_string(thisId) + "].a"); + shader->setFloat(attenuationValues.y, "light["+to_string(thisId) + "].b"); + shader->setFloat(attenuationValues.z, "light["+to_string(thisId) + "].c"); + shader->setFloat(innerAngle, "light[" + to_string(thisId) + "].innerAngle"); + shader->setFloat(outerAngle, "light[" + to_string(thisId) + "].outerAngle"); break; } } diff --git a/light.h b/light.h index db7735b..6407f31 100755 --- a/light.h +++ b/light.h @@ -14,24 +14,24 @@ namespace vb01{ class Light{ public: - enum Type{POINT,DIRECTIONAL,SPOT,AMBIENT}; + enum Type{POINT, DIRECTIONAL, SPOT, AMBIENT}; Light(Type); ~Light(); void update(); - inline void setNode(Node *node){this->node=node;} - inline void setPosition(Vector3 pos){this->position=pos;} - inline void setColor(Vector3 color){this->color=color;} - inline void setDirection(Vector3 dir){this->direction=dir;} + inline void setNode(Node *node){this->node = node;} + inline void setPosition(Vector3 pos){this->position = pos;} + inline void setColor(Vector3 color){this->color = color;} + inline void setDirection(Vector3 dir){this->direction = dir;} inline void setAttenuationValues(float a, float b, float c){ - attenuationValues.x=a; - attenuationValues.y=b; - attenuationValues.z=c; + attenuationValues.x = a; + attenuationValues.y = b; + attenuationValues.z = c; } - inline void setInnerAngle(float innerAngle){this->innerAngle=innerAngle;} - inline void setOuterAngle(float outerAngle){this->outerAngle=outerAngle;} - inline void setShadowNearPlane(float nearPlane){this->nearPlane=nearPlane;} - inline void setShadowFarPlane(float farPlane){this->farPlane=farPlane;} + inline void setInnerAngle(float innerAngle){this->innerAngle = innerAngle;} + inline void setOuterAngle(float outerAngle){this->outerAngle = outerAngle;} + inline void setShadowNearPlane(float nearPlane){this->nearPlane = nearPlane;} + inline void setShadowFarPlane(float farPlane){this->farPlane = farPlane;} inline Vector3 getDirection(){return direction;} inline Vector3 getAttenuationValues(){return attenuationValues;} inline float getInnerAngle(){return innerAngle;} @@ -40,16 +40,17 @@ namespace vb01{ inline float getShadowFarPlane(){return farPlane;} inline Node* getNode(){return node;} private: + void initDepthMap(); void renderShadow(std::vector, glm::mat4&, glm::mat4&); void updateShader(std::vector, int, glm::mat4&, glm::mat4&); Type type; Shader *depthMapShader; - Texture *depthMap=nullptr; - Node *node=nullptr; - Vector3 position=Vector3::VEC_ZERO,color,attenuationValues=Vector3(1.8,.7,1),direction; - float innerAngle=.707,outerAngle=.714,nearPlane=.1,farPlane=100; - unsigned int depthmapFBO,depthMapSize=1024; + Texture *depthMap = nullptr; + Node *node = nullptr; + Vector3 position = Vector3::VEC_ZERO, color, attenuationValues = Vector3(1.8, .7, 1), direction; + float innerAngle = .707, outerAngle = .714, nearPlane = .1, farPlane = 100; + unsigned int depthmapFBO, depthMapSize = 1024; }; } diff --git a/material.cpp b/material.cpp index 62fc48f..2b64511 100755 --- a/material.cpp +++ b/material.cpp @@ -8,34 +8,7 @@ namespace vb01{ Material::Material(Type type){ this->type=type; - string basePath="../../vb01/",shaderName; - switch(type){ - case MATERIAL_2D: - shaderName="texture."; - break; - case MATERIAL_PARTICLE: - shaderName="particle."; - break; - case MATERIAL_SKYBOX: - shaderName="skybox."; - break; - case MATERIAL_GUI: - shaderName="gui."; - break; - case MATERIAL_POST: - shaderName="postProcess."; - break; - case MATERIAL_TEXT: - shaderName="text."; - break; - } - /* - if(type==MATERIAL_2D) - //shader=new Shader(basePath+shaderName+"vert",basePath+shaderName+"frag"); - shader=new Shader(basePath+shaderName+"vert",basePath+shaderName+"frag",basePath+shaderName+"geo"); - else - */ - shader=new Shader(basePath+shaderName+"vert",basePath+shaderName+"frag"); + initShader(); } Material::~Material(){ @@ -48,23 +21,56 @@ namespace vb01{ delete t; } + void Material::initShader(){ + string basePath = "../../vb01/", shaderName; + switch(type){ + case MATERIAL_2D: + shaderName = "texture."; + break; + case MATERIAL_PARTICLE: + shaderName = "particle."; + break; + case MATERIAL_SKYBOX: + shaderName = "skybox."; + break; + case MATERIAL_GUI: + shaderName = "gui."; + break; + case MATERIAL_POST: + shaderName = "postProcess."; + break; + case MATERIAL_TEXT: + shaderName = "text."; + break; + } + /* + if(type==MATERIAL_2D) + //shader=new Shader(basePath+shaderName+"vert",basePath+shaderName+"frag"); + shader=new Shader(basePath+shaderName+"vert",basePath+shaderName+"frag",basePath+shaderName+"geo"); + else + */ + shader = new Shader(basePath + shaderName + "vert", basePath + shaderName + "frag"); + } + void Material::update(){ shader->use(); - if(type==MATERIAL_2D){ - shader->setBool(lightingEnabled,"lightingEnabled"); - shader->setBool(normalMapEnabled,"normalMapEnabled"); - shader->setInt(0,"diffuseMap"); - shader->setInt(1,"normalMap"); - shader->setInt(2,"specularMap"); - shader->setInt(3,"parallaxMap"); - shader->setInt(4,"environmentMap"); + shader->setBool(texturingEnabled, "texturingEnabled"); + + if(type == MATERIAL_2D){ + shader->setBool(lightingEnabled, "lightingEnabled"); + shader->setBool(normalMapEnabled, "normalMapEnabled"); + shader->setInt(0, "diffuseMap"); + shader->setInt(1, "normalMap"); + shader->setInt(2, "specularMap"); + shader->setInt(3, "parallaxMap"); + shader->setInt(4, "environmentMap"); } - shader->setBool(texturingEnabled,"texturingEnabled"); - if(type==MATERIAL_GUI){ - shader->setBool(diffuseColorEnabled,"diffuseColorEnabled"); + else if(type == MATERIAL_GUI){ + shader->setBool(diffuseColorEnabled, "diffuseColorEnabled"); if(diffuseColorEnabled) - shader->setVec4(diffuseColor,"diffuseColor"); + shader->setVec4(diffuseColor, "diffuseColor"); } + if(texturingEnabled){ for(Texture *t : diffuseMapTextures) t->update(0); @@ -75,8 +81,7 @@ namespace vb01{ for(Texture *t : parallaxMapTextures) t->update(3); } - else { - shader->setVec4(diffuseColor,"diffuseColor"); - } + else + shader->setVec4(diffuseColor, "diffuseColor"); } } diff --git a/material.h b/material.h index c35ee71..c2dcb30 100755 --- a/material.h +++ b/material.h @@ -9,43 +9,43 @@ namespace vb01{ class Material{ public: - enum Type{MATERIAL_2D,MATERIAL_PARTICLE,MATERIAL_SKYBOX,MATERIAL_GUI,MATERIAL_POST,MATERIAL_TEXT}; + enum Type{MATERIAL_2D, MATERIAL_PARTICLE, MATERIAL_SKYBOX, MATERIAL_GUI, MATERIAL_POST, MATERIAL_TEXT}; - Material(Type=MATERIAL_2D); + Material(Type = MATERIAL_2D); ~Material(); void update(); - inline void addDiffuseMap(std::string diffuseMap,bool flip=false){ + inline void addDiffuseMap(std::string diffuseMap, bool flip = false){ std::string p[]{diffuseMap}; - diffuseMapTextures.push_back(new Texture(p,1,0,flip)); + diffuseMapTextures.push_back(new Texture(p, 1, 0, flip)); } - inline void addDiffuseMap(std::string diffuseMap[],int numFrames){diffuseMapTextures.push_back(new Texture(diffuseMap,numFrames));} + inline void addDiffuseMap(std::string diffuseMap[], int numFrames){diffuseMapTextures.push_back(new Texture(diffuseMap, numFrames));} inline void addDiffuseMap(std::string diffuseMap[6]){diffuseMapTextures.push_back(new Texture(diffuseMap));} inline void addDiffuseMap(Texture *texture){diffuseMapTextures.push_back(texture);} inline void setDiffuseMap(Texture *texture, int i){diffuseMapTextures[i]=texture;} inline void addNormalMap(std::string normalMap){ std::string p[]{normalMap}; - normalMapTextures.push_back(new Texture(p,1)); + normalMapTextures.push_back(new Texture(p, 1)); } - inline void addNormalMap(std::string normalMap[],int numFrames){normalMapTextures.push_back(new Texture(normalMap,numFrames));} - inline void setNormalMap(Texture *texture, int i){normalMapTextures[i]=texture;} + inline void addNormalMap(std::string normalMap[], int numFrames){normalMapTextures.push_back(new Texture(normalMap, numFrames));} + inline void setNormalMap(Texture *texture, int i){normalMapTextures[i] = texture;} inline void addSpecularMap(std::string specularMap){ std::string p[]{specularMap}; - specularMapTextures.push_back(new Texture(p,1)); + specularMapTextures.push_back(new Texture(p, 1)); } - inline void addSpecularMap(std::string specularMap[],int numFrames){specularMapTextures.push_back(new Texture(specularMap,numFrames));} - inline void setSpecularMap(Texture *texture, int i){specularMapTextures[i]=texture;} + inline void addSpecularMap(std::string specularMap[], int numFrames){specularMapTextures.push_back(new Texture(specularMap, numFrames));} + inline void setSpecularMap(Texture *texture, int i){specularMapTextures[i] = texture;} inline void addParallaxMap(std::string parallaxMap){ std::string p[]{parallaxMap}; - parallaxMapTextures.push_back(new Texture(p,1)); + parallaxMapTextures.push_back(new Texture(p, 1)); } - inline void addParallaxMap(std::string parallaxMap[],int numFrames){parallaxMapTextures.push_back(new Texture(parallaxMap,numFrames));} - inline void setDiffuseColor(Vector4 diffuse){this->diffuseColor=diffuse;} - inline void setSpecularColor(Vector4 specular){this->specularColor=specular;} - inline void setLightingEnabled(bool lighting){this->lightingEnabled=lighting;} - inline void setTexturingEnabled(bool texturing){this->texturingEnabled=texturing;} - inline void setDiffuseColorEnabled(bool diffuseColor){this->diffuseColorEnabled=diffuseColor;} - inline void setNormalMapEnabled(bool enabled){this->normalMapEnabled=enabled;} - inline void setParallaxMapEnabled(bool enabled){this->parallaxMapEnabled=enabled;} + inline void addParallaxMap(std::string parallaxMap[], int numFrames){parallaxMapTextures.push_back(new Texture(parallaxMap, numFrames));} + inline void setDiffuseColor(Vector4 diffuse){this->diffuseColor = diffuse;} + inline void setSpecularColor(Vector4 specular){this->specularColor = specular;} + inline void setLightingEnabled(bool lighting){this->lightingEnabled = lighting;} + inline void setTexturingEnabled(bool texturing){this->texturingEnabled = texturing;} + inline void setDiffuseColorEnabled(bool diffuseColor){this->diffuseColorEnabled = diffuseColor;} + inline void setNormalMapEnabled(bool enabled){this->normalMapEnabled = enabled;} + inline void setParallaxMapEnabled(bool enabled){this->parallaxMapEnabled = enabled;} inline bool isLightingEnabled(){return lightingEnabled;} inline bool isTexturingEnabled(){return texturingEnabled;} inline bool isDiffuseColorEnabled(){return diffuseColorEnabled;} @@ -56,10 +56,12 @@ namespace vb01{ inline Type getType(){return type;} private: Type type; - bool lightingEnabled=false,texturingEnabled=true,diffuseColorEnabled=false,normalMapEnabled=false,parallaxMapEnabled=false; - std::vector diffuseMapTextures,normalMapTextures,specularMapTextures,parallaxMapTextures; - Vector4 diffuseColor=Vector4::VEC_IJKL,specularColor=Vector4::VEC_IJKL; - Shader *shader=nullptr; + bool lightingEnabled = false, texturingEnabled = true, diffuseColorEnabled = false, normalMapEnabled = false, parallaxMapEnabled = false; + std::vector diffuseMapTextures, normalMapTextures, specularMapTextures, parallaxMapTextures; + Vector4 diffuseColor = Vector4::VEC_IJKL, specularColor = Vector4::VEC_IJKL; + Shader *shader = nullptr; + + void initShader(); }; } diff --git a/mesh.cpp b/mesh.cpp index 3df22fb..c1db1dc 100755 --- a/mesh.cpp +++ b/mesh.cpp @@ -16,15 +16,15 @@ using namespace glm; namespace vb01{ Mesh::Mesh(){} - Mesh::Mesh(Vertex *vertices,unsigned int *indices,int numTris,string *vertexGroups,int numVertexGroups,string *shapeKeys,int numShapeKeys,string name){ - this->vertices=vertices; - this->indices=indices; - this->numTris=numTris; - this->vertexGroups=vertexGroups; - this->numVertexGroups=numVertexGroups; - this->shapeKeys=shapeKeys; - this->numShapeKeys=numShapeKeys; - this->name=name; + Mesh::Mesh(Vertex *vertices, unsigned int *indices, int numTris, string *vertexGroups, int numVertexGroups, string *shapeKeys, int numShapeKeys, string name){ + this->vertices = vertices; + this->indices = indices; + this->numTris = numTris; + this->vertexGroups = vertexGroups; + this->numVertexGroups = numVertexGroups; + this->shapeKeys = shapeKeys; + this->numShapeKeys = numShapeKeys; + this->name = name; construct(); } @@ -36,25 +36,30 @@ namespace vb01{ if(material) delete material; - glDeleteVertexArrays(1,&VAO); - glDeleteBuffers(1,&EBO); - glDeleteBuffers(1,&VBO); + glDeleteVertexArrays(1, &VAO); + glDeleteBuffers(1, &EBO); + glDeleteBuffers(1, &VBO); delete[] indices; delete[] vertices; } void Mesh::construct(){ - int width=Root::getSingleton()->getWidth(); + initFramebuffer(); + initMesh(); + } + + void Mesh::initFramebuffer(){ + int width = Root::getSingleton()->getWidth(); u32 RBO; - string basePath="../../vb01/depthMap."; - environmentShader=new Shader(basePath+"vert",basePath+"frag",basePath+"geo"); - environmentMap=new Texture(width,false); + string basePath = "../../vb01/depthMap."; + environmentShader = new Shader(basePath + "vert", basePath + "frag", basePath + "geo"); + environmentMap = new Texture(width, false); - glGenFramebuffers(1,&environmentBuffer); - glBindFramebuffer(GL_FRAMEBUFFER,environmentBuffer); - glFramebufferTexture(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,*(environmentMap->getTexture()),0); + glGenFramebuffers(1, &environmentBuffer); + glBindFramebuffer(GL_FRAMEBUFFER, environmentBuffer); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, *(environmentMap->getTexture()), 0); /* glGenRenderbuffers(1,&RBO); @@ -63,65 +68,67 @@ namespace vb01{ glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_DEPTH_STENCIL_ATTACHMENT,GL_RENDERBUFFER,RBO); */ - if(glCheckFramebufferStatus(GL_FRAMEBUFFER)!=GL_FRAMEBUFFER_COMPLETE) + if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) cout<<"Not complete\n"; + } - glBindFramebuffer(GL_FRAMEBUFFER,0); + void Mesh::initMesh(){ + glBindFramebuffer(GL_FRAMEBUFFER, 0); - glGenVertexArrays(1,&VAO); - glGenBuffers(1,&VBO); - glGenBuffers(1,&EBO); + glGenVertexArrays(1, &VAO); + glGenBuffers(1, &VBO); + glGenBuffers(1, &EBO); - u32 size=sizeof(Vertex); + u32 size = sizeof(Vertex); glBindVertexArray(VAO); - glBindBuffer(GL_ARRAY_BUFFER,VBO); - glBufferData(GL_ARRAY_BUFFER, 3*numTris*size,staticVerts?vertices:NULL, staticVerts?GL_STATIC_DRAW:GL_DYNAMIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO); - glBufferData(GL_ELEMENT_ARRAY_BUFFER,3*numTris*sizeof(unsigned int),staticVerts?indices:NULL,staticVerts?GL_STATIC_DRAW:GL_DYNAMIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, 3 * numTris * size, staticVerts ? vertices : NULL, staticVerts ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * numTris * sizeof(u32), staticVerts ? indices : NULL, staticVerts ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW); - glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,size,(void*)0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, size, (void*)0); glEnableVertexAttribArray(0); - glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,size,(void*)(offsetof(Vertex,norm))); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(Vertex, norm))); glEnableVertexAttribArray(1); - glVertexAttribPointer(2,2,GL_FLOAT,GL_FALSE,size,(void*)(offsetof(Vertex,uv))); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(Vertex, uv))); glEnableVertexAttribArray(2); - glVertexAttribPointer(3,3,GL_FLOAT,GL_FALSE,size,(void*)(offsetof(Vertex,tan))); + glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(Vertex, tan))); glEnableVertexAttribArray(3); - glVertexAttribPointer(4,3,GL_FLOAT,GL_FALSE,size,(void*)(offsetof(Vertex,biTan))); + glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(Vertex, biTan))); glEnableVertexAttribArray(4); - glVertexAttribPointer(5,4,GL_FLOAT,GL_FALSE,size,(void*)(offsetof(Vertex,weights))); + glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(Vertex, weights))); glEnableVertexAttribArray(5); - glVertexAttribPointer(6,4,GL_FLOAT,GL_FALSE,size,(void*)(offsetof(Vertex,boneIndices))); + glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(Vertex, boneIndices))); glEnableVertexAttribArray(6); } void Mesh::update(){ - Root *root=Root::getSingleton(); - Camera *cam=root->getCamera(); - float fov=cam->getFov(),width=root->getWidth(),height=root->getHeight(); - float nearPlane=cam->getNearPlane(),farPlane=cam->getFarPlane(); - Vector3 dir=cam->getDirection(),up=cam->getUp(),camPos=Vector3::VEC_ZERO,pos=Vector3::VEC_ZERO,scale=Vector3::VEC_IJK; - Quaternion orient=Quaternion::QUAT_W; + Root *root = Root::getSingleton(); + Camera *cam = root->getCamera(); + float fov = cam->getFov(), width = root->getWidth(), height = root->getHeight(); + float nearPlane = cam->getNearPlane(), farPlane = cam->getFarPlane(); + Vector3 dir = cam->getDirection(), up = cam->getUp(), camPos = Vector3::VEC_ZERO, pos = Vector3::VEC_ZERO, scale = Vector3::VEC_IJK; + Quaternion orient = Quaternion::QUAT_W; if(node){ - pos=node->localToGlobalPosition(Vector3::VEC_ZERO); - orient=node->localToGlobalOrientation(Quaternion::QUAT_W); - camPos=cam->getPosition(); + pos = node->localToGlobalPosition(Vector3::VEC_ZERO); + orient = node->localToGlobalOrientation(Quaternion::QUAT_W); + camPos = cam->getPosition(); } - Vector3 rotAxis=orient.getAxis(); - if(rotAxis==Vector3::VEC_ZERO) - rotAxis=Vector3::VEC_I; + 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)); - 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)); - mat4 proj=perspective(radians(fov),width/height,nearPlane,farPlane); + 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)); + 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)); + mat4 proj = perspective(radians(fov), width / height, nearPlane, farPlane); material->update(); - Shader *shader=material->getShader(); + Shader *shader = material->getShader(); if(reflect) @@ -130,18 +137,18 @@ namespace vb01{ if(skeleton) updateSkeleton(shader); - shader->setBool(castShadow,"castShadow"); - shader->setBool(skeleton,"animated"); - shader->setBool(false,"environment"); - shader->setMat4(view,"view"); - shader->setMat4(proj,"proj"); - shader->setVec3(camPos,"camPos"); - shader->setMat4(model,"model"); + shader->setBool(castShadow, "castShadow"); + shader->setBool(skeleton, "animated"); + shader->setBool(false, "environment"); + shader->setMat4(view, "view"); + shader->setMat4(proj, "proj"); + shader->setVec3(camPos, "camPos"); + shader->setMat4(model, "model"); - if(material->getType()==Material::MATERIAL_GUI){ - shader->setVec2(Vector2((float)width,(float)height),"screen"); + if(material->getType() == Material::MATERIAL_GUI){ + shader->setVec2(Vector2((float)width, (float)height), "screen"); if(node) - shader->setVec3(pos,"pos"); + shader->setVec3(pos, "pos"); } render(); @@ -150,11 +157,11 @@ namespace vb01{ void Mesh::updateSkeleton(Shader *shader){ skeleton->update(); - shader->editShader(Shader::VERTEX_SHADER,2,"const int numBones="+to_string(skeleton->getNumBones())+";"); - shader->editShader(Shader::VERTEX_SHADER,3,"const int numVertGroups="+to_string(numVertexGroups)+";"); + shader->editShader(Shader::VERTEX_SHADER, 2, "const int numBones=" + to_string(skeleton->getNumBones()) + ";"); + shader->editShader(Shader::VERTEX_SHADER, 3, "const int numVertGroups=" + to_string(numVertexGroups) + ";"); Node *modelNode = skeleton->getRootBone()->getParent(); - for(int i=0;igetNumBones();i++){ + for(int i = 0; i < skeleton->getNumBones(); i++){ Bone *bone = skeleton->getBone(i), *parent = (Bone*)bone->getParent(); Vector3 boneAxis[]{ bone->getInitAxis(0), @@ -163,75 +170,75 @@ namespace vb01{ }; Vector3 posePos = bone->getPosePos(); Quaternion poseRot = bone->getPoseRot(); - Vector3 trans = boneAxis[0]*posePos.x+boneAxis[1]*posePos.y+boneAxis[2]*posePos.z; + Vector3 trans = boneAxis[0] * posePos.x + boneAxis[1] * posePos.y + boneAxis[2] * posePos.z; Vector3 scale = bone->getPoseScale(); Vector3 bonePos = bone->getModelSpacePos(); int vertGroupId = -1, parentId = -1; - for(int j=0;jgetName() == vertexGroups[j]) vertGroupId = j; - for(int j = 0;j < skeleton->getNumBones();j++) + for(int j = 0; j < skeleton->getNumBones(); j++) if(skeleton->getBone(j) == parent){ parentId = j; break; } - shader->setVec3(bonePos,"bones["+to_string(i)+"].pos"); - shader->setVec3(trans,"bones["+to_string(i)+"].trans"); - shader->setVec3(poseRot.getAxis(),"bones["+to_string(i)+"].rotAxis"); - shader->setFloat(poseRot.getAngle(),"bones["+to_string(i)+"].angle"); - shader->setVec3(scale,"bones["+to_string(i)+"].scale"); - shader->setInt(vertGroupId,"bones["+to_string(i)+"].vertGroup"); - shader->setInt(parentId,"bones["+to_string(i)+"].parent"); + shader->setVec3(bonePos, "bones[" + to_string(i) + "].pos"); + shader->setVec3(trans, "bones[" + to_string(i) + "].trans"); + shader->setVec3(poseRot.getAxis(), "bones[" + to_string(i) + "].rotAxis"); + shader->setFloat(poseRot.getAngle(), "bones[" + to_string(i) + "].angle"); + shader->setVec3(scale, "bones[" + to_string(i) + "].scale"); + shader->setInt(vertGroupId, "bones[" + to_string(i) + "].vertGroup"); + shader->setInt(parentId, "bones[" + to_string(i) + "].parent"); } } void Mesh::updateReflection(Shader *shader, Vector3 pos, int width, int height){ Root *root = Root::getSingleton(); vec3 dirs[]{ - vec3(1,0,0), - vec3(-1,0,0), - vec3(0,1,0), - vec3(0,-1,0), - vec3(0,0,1), - vec3(0,0,-1) + vec3(1, 0, 0), + vec3(-1, 0, 0), + vec3(0, 1, 0), + vec3(0, -1, 0), + vec3(0, 0, 1), + vec3(0, 0, -1) }; - glViewport(0,0,width,width); - glBindFramebuffer(GL_FRAMEBUFFER,environmentBuffer); + glViewport(0, 0, width, width); + glBindFramebuffer(GL_FRAMEBUFFER, environmentBuffer); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); environmentShader->use(); - Node *rootNode=root->getRootNode(); + Node *rootNode = root->getRootNode(); vector descendants; - rootNode->getDescendants(rootNode,descendants); + rootNode->getDescendants(rootNode, descendants); for(Node *n : descendants){ for(Mesh *m : n->getMeshes()) - if(m!=this){ - Vector3 position=n->localToGlobalPosition(Vector3::VEC_ZERO); - Quaternion rotation=n->localToGlobalOrientation(Quaternion::QUAT_W); - Vector3 rotAxis=rotation.norm().getAxis(); + if(m != this){ + Vector3 position = n->localToGlobalPosition(Vector3::VEC_ZERO); + Quaternion rotation = n->localToGlobalOrientation(Quaternion::QUAT_W); + Vector3 rotAxis = rotation.norm().getAxis(); - if(rotAxis==Vector3::VEC_ZERO) - rotAxis=Vector3::VEC_I; - float far=100; - vec3 p=vec3(position.x,position.y,position.z); - mat4 proj=perspective(radians(90.f),1.f,.1f,far); - mat4 model=translate(mat4(1.),p); - model=rotate(model,rotation.norm().getAngle(),vec3(rotAxis.x,rotAxis.y,rotAxis.z)); - environmentShader->setMat4(model,"model"); - environmentShader->setBool(true,"point"); - environmentShader->setVec3(pos,"lightPos"); - environmentShader->setFloat(far,"farPlane"); - for(int i=0;i<6;i++) - environmentShader->setMat4(proj*lookAt(p,p+dirs[i],1setMat4(model, "model"); + environmentShader->setBool(true, "point"); + environmentShader->setVec3(pos, "lightPos"); + environmentShader->setFloat(far, "farPlane"); + for(int i = 0; i < 6; i++) + environmentShader->setMat4(proj * lookAt(p, p + dirs[i], 1 < i && i < 4 ? vec3(0, 0, -1) : vec3(0, -1, 0)), "shadowMat[" + to_string(i) + "]"); m->render(); } } - glBindFramebuffer(GL_FRAMEBUFFER,*(root->getFBO())); - glViewport(0,0,root->getWidth(),root->getHeight()); + glBindFramebuffer(GL_FRAMEBUFFER, *(root->getFBO())); + glViewport(0, 0, root->getWidth(), root->getHeight()); - shader->setBool(reflect,"environmentMapEnabled"); + shader->setBool(reflect, "environmentMapEnabled"); root->getSkybox()->getMaterial()->getDiffuseMap(0)->select(4); environmentMap->select(4); } @@ -239,12 +246,12 @@ namespace vb01{ void Mesh::render(){ glBindVertexArray(VAO); if(!staticVerts){ - glBindBuffer(GL_ARRAY_BUFFER,VBO); - glBufferSubData(GL_ARRAY_BUFFER, 0, 3*numTris*sizeof(Vertex),vertices); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO); - glBufferSubData(GL_ELEMENT_ARRAY_BUFFER,0,3*numTris*sizeof(unsigned int),indices); + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferSubData(GL_ARRAY_BUFFER, 0, 3 * numTris * sizeof(Vertex), vertices); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, 3 * numTris * sizeof(u32), indices); } - glPolygonMode(GL_FRONT_AND_BACK,wireframe?GL_LINE:GL_FILL); - glDrawElements(GL_TRIANGLES,3*numTris,GL_UNSIGNED_INT,0); + glPolygonMode(GL_FRONT_AND_BACK, wireframe ? GL_LINE : GL_FILL); + glDrawElements(GL_TRIANGLES, 3 * numTris, GL_UNSIGNED_INT, 0); } } diff --git a/mesh.h b/mesh.h index 06e13a1..66c4d81 100755 --- a/mesh.h +++ b/mesh.h @@ -17,55 +17,57 @@ namespace vb01{ class Mesh{ public: struct Vertex{ - Vector3 pos,norm,tan,biTan; + Vector3 pos, norm, tan, biTan; Vector2 uv; //Vector4 weights; //float *weights=nullptr; - float weights[4]{0,0,0,0}; - int boneIndices[4]{-1,-1,-1,-1}; - Vector3 *shapeKeyOffsets=nullptr; + float weights[4]{0, 0, 0, 0}; + int boneIndices[4]{-1, -1, -1, -1}; + Vector3 *shapeKeyOffsets = nullptr; }; - Mesh(Vertex*,unsigned int*,int,std::string *vg=nullptr,int=0,std::string *sk=nullptr,int=0,std::string=""); + Mesh(Vertex*, unsigned int*, int, std::string *vg = nullptr, int = 0, std::string *sk = nullptr, int = 0, std::string = ""); ~Mesh(); virtual void update(); void render(); - void setMaterial(Material *mat){this->material=mat;} - inline void setNode(Node *node){this->node=node;} - inline void setCastShadow(bool castShadow){this->castShadow=castShadow;} - inline void setReflect(bool r){this->reflect=r;} - inline void setWireframe(bool w){this->wireframe=w;} - inline void setSkeleton(Skeleton *sk){this->skeleton=sk;} + void setMaterial(Material *mat){this->material = mat;} + inline void setNode(Node *node){this->node = node;} + inline void setCastShadow(bool castShadow){this->castShadow = castShadow;} + inline void setReflect(bool r){this->reflect = r;} + inline void setWireframe(bool w){this->wireframe = w;} + inline void setSkeleton(Skeleton *sk){this->skeleton = sk;} inline Node* getNode(){return node;} inline Material* getMaterial(){return material;} inline std::vector& getMeshes(){return meshes;} inline bool isCastShadow(){return castShadow;} - inline int getNumVerts(){return 3*numTris;} + inline int getNumVerts(){return 3 * numTris;} inline Vertex* getVerts(){return vertices;} inline std::string getName(){return name;} inline Skeleton* getSkeleton(){return skeleton;} inline unsigned int* getIndices(){return indices;} private: + void initFramebuffer(); + void initMesh(); void updateSkeleton(Shader*); void updateReflection(Shader*, Vector3, int, int); - Shader *environmentShader=nullptr; + Shader *environmentShader = nullptr; u32 environmentBuffer; Texture *environmentMap; - Material *material=nullptr; - Node *node=nullptr; + Material *material = nullptr; + Node *node = nullptr; std::vector meshes; - std::string name=""; - Skeleton *skeleton=nullptr; + std::string name = ""; + Skeleton *skeleton = nullptr; protected: Mesh(); void construct(); - bool staticVerts=true,castShadow=false,reflect=false,wireframe=false; + bool staticVerts = true, castShadow = false, reflect = false, wireframe = false; Vertex *vertices; - std::string *vertexGroups=nullptr,*shapeKeys=nullptr; - unsigned int *indices,VAO,VBO,EBO; - int numTris,numVertexGroups=0,numShapeKeys=0; + std::string *vertexGroups = nullptr, *shapeKeys = nullptr; + unsigned int *indices, VAO, VBO, EBO; + int numTris, numVertexGroups = 0, numShapeKeys = 0; }; } diff --git a/model.cpp b/model.cpp index 4ec9666..dce619f 100755 --- a/model.cpp +++ b/model.cpp @@ -40,7 +40,7 @@ namespace vb01{ mesh->setMaterial(nullptr); while(!children.empty()){ - Node *c=children[children.size()-1]; + Node *c = children[children.size() - 1]; dettachChild(c); delete c; } @@ -52,7 +52,7 @@ namespace vb01{ void Model::setMaterial(Material *mat){ vector descendants; - getDescendants(this,descendants); + getDescendants(this, descendants); for(Node *node : descendants) for(Mesh *mesh : node->getMeshes()) mesh->setMaterial(mat); @@ -60,28 +60,28 @@ namespace vb01{ void Model::setCastShadow(bool castShadow){ vector descendants; - getDescendants(this,descendants); + getDescendants(this, descendants); for(Node *node : descendants) for(Mesh *mesh : node->getMeshes()) mesh->setCastShadow(castShadow); - this->castShadow=castShadow; + this->castShadow = castShadow; } void Model::setReflect(bool reflect){ vector descendants; - getDescendants(this,descendants); + getDescendants(this, descendants); for(Node *node : descendants) for(Mesh *mesh : node->getMeshes()) mesh->setReflect(reflect); - this->reflect=reflect; + this->reflect = reflect; } void Model::setWireframe(bool wirefame){ vector descendants; - getDescendants(this,descendants); + getDescendants(this, descendants); for(Node *node : descendants) for(Mesh *mesh : node->getMeshes()) mesh->setWireframe(wirefame); - this->wireframe=wireframe; + this->wireframe = wireframe; } } diff --git a/model.h b/model.h index 44e27aa..b322f2f 100755 --- a/model.h +++ b/model.h @@ -26,7 +26,7 @@ namespace vb01{ void setWireframe(bool); private: Material* material; - bool castShadow=false,reflect=false,wireframe=false; + bool castShadow = false, reflect = false, wireframe = false; }; } diff --git a/node.cpp b/node.cpp index 7e3b845..851343c 100755 --- a/node.cpp +++ b/node.cpp @@ -14,13 +14,13 @@ using namespace glm; namespace vb01{ Node::Node(Vector3 pos, Quaternion orientation, Vector3 scale,string name){ - this->pos=pos; - this->scale=scale; - this->orientation=orientation; - this->name=name; - globalAxis[0]=Vector3::VEC_I; - globalAxis[1]=Vector3::VEC_J; - globalAxis[2]=Vector3::VEC_K; + this->pos = pos; + this->scale = scale; + this->orientation = orientation; + this->name = name; + globalAxis[0] = Vector3::VEC_I; + globalAxis[1] = Vector3::VEC_J; + globalAxis[2] = Vector3::VEC_K; } Node::~Node(){ @@ -61,14 +61,14 @@ namespace vb01{ void Node::dettachChild(Node *child){ child->setParent(nullptr); - int id=-1; - for(int i=0;inumLights++; + Root::getSingleton()->shiftNumLights(true); lights.push_back(light); light->setNode(this); updateShaders(); } void Node::removeLight(int id){ - Root::getSingleton()->numLights--; - Light *light=lights[id]; + Root::getSingleton()->shiftNumLights(false); + Light *light = lights[id]; light->setNode(nullptr); - lights.erase(lights.begin()+id); + lights.erase(lights.begin() + id); updateShaders(); } @@ -116,16 +116,16 @@ namespace vb01{ node->getGlobalAxis(1), node->getGlobalAxis(2) }; - newDir=(parAxis[0]*newDir.x+parAxis[1]*newDir.y+parAxis[2]*newDir.z).norm(); + newDir = (parAxis[0] * newDir.x + parAxis[1] * newDir.y + parAxis[2] * newDir.z).norm(); - float angle=globalAxis[2].getAngleBetween(newDir); - Vector3 rotAxis=globalAxis[2].cross(newDir).norm(); - if(rotAxis==Vector3::VEC_ZERO) - rotAxis=globalAxis[1]; + float angle = globalAxis[2].getAngleBetween(newDir); + Vector3 rotAxis = globalAxis[2].cross(newDir).norm(); + if(rotAxis == Vector3::VEC_ZERO) + rotAxis = globalAxis[1]; Quaternion oldRot = node->localToGlobalOrientation(orientation); Quaternion newRot = node->globalToLocalOrientation(Quaternion(angle,rotAxis)); - setOrientation(newRot*oldRot); + setOrientation(newRot * oldRot); } void Node::adjustUp(Vector3 newUp, Node *node){ @@ -134,27 +134,27 @@ namespace vb01{ node->getGlobalAxis(1), node->getGlobalAxis(2) }; - newUp=(parAxis[0]*newUp.x+parAxis[1]*newUp.y+parAxis[2]*newUp.z).norm(); + newUp = (parAxis[0] * newUp.x + parAxis[1] * newUp.y + parAxis[2] * newUp.z).norm(); mat3 mat; - mat[0][0]=globalAxis[0].x; - mat[1][0]=globalAxis[0].y; - mat[2][0]=globalAxis[0].z; - mat[0][1]=globalAxis[1].x; - mat[1][1]=globalAxis[1].y; - mat[2][1]=globalAxis[1].z; - mat[0][2]=globalAxis[2].x; - mat[1][2]=globalAxis[2].y; - mat[2][2]=globalAxis[2].z; - mat=inverse(mat); + mat[0][0] = globalAxis[0].x; + mat[1][0] = globalAxis[0].y; + mat[2][0] = globalAxis[0].z; + mat[0][1] = globalAxis[1].x; + mat[1][1] = globalAxis[1].y; + mat[2][1] = globalAxis[1].z; + mat[0][2] = globalAxis[2].x; + mat[1][2] = globalAxis[2].y; + mat[2][2] = globalAxis[2].z; + mat = inverse(mat); - vec3 nu=vec3(newUp.x,newUp.y,newUp.z)*mat; - newUp=(globalAxis[0]*nu.x+globalAxis[1]*nu.y).norm(); - float angle=globalAxis[1].getAngleBetween(newUp); + vec3 nu = vec3(newUp.x, newUp.y, newUp.z) * mat; + newUp = (globalAxis[0] * nu.x + globalAxis[1] * nu.y).norm(); + float angle = globalAxis[1].getAngleBetween(newUp); Quaternion oldRot = node->localToGlobalOrientation(orientation); - Quaternion newRot = node->globalToLocalOrientation(Quaternion(angle*(nu.x<0?1:-1),globalAxis[2])); - setOrientation(newRot*oldRot); + Quaternion newRot = node->globalToLocalOrientation(Quaternion(angle * (nu.x < 0 ? 1 : -1), globalAxis[2])); + setOrientation(newRot * oldRot); } void Node::getDescendants(Node *node, vector &descendants){ @@ -166,12 +166,9 @@ namespace vb01{ } } - vector Node::getAncestors(Node *node, Node *topAncestor){ + vector Node::getAncestors(Node *topAncestor){ vector ancestors; - Node *parent = node; - if(!topAncestor) - topAncestor = Root::getSingleton()->getRootNode(); - + Node *parent = this; while(parent){ ancestors.push_back(parent); if(parent == topAncestor) @@ -191,10 +188,11 @@ namespace vb01{ float rotAngle = orientation.getAngle(); Vector3 rotAxis = orientation.getAxis(); Vector3 newAxis = (parGlobalAxis[0] * rotAxis.x + parGlobalAxis[1] * rotAxis.y + parGlobalAxis[2] * rotAxis.z).norm(); - Quaternion rotQuat=Quaternion(rotAngle, newAxis); + Quaternion rotQuat = Quaternion(rotAngle, newAxis); for(int i = 0; i < 3; i++) globalAxis[i] = (rotQuat * parGlobalAxis[i]).norm(); + for(Node *ch : children) ch->updateAxis(); } @@ -204,15 +202,15 @@ namespace vb01{ Vector3 origin = Vector3::VEC_ZERO; while(!ancestors.empty()){ - int id=ancestors.size()-1; - Node *par=ancestors[id]->getParent(); - Vector3 parAxis[]={ - par?par->getGlobalAxis(0):Vector3::VEC_I, - par?par->getGlobalAxis(1):Vector3::VEC_J, - par?par->getGlobalAxis(2):Vector3::VEC_K + int id = ancestors.size() - 1; + Node *par = ancestors[id]->getParent(); + Vector3 parAxis[] = { + par ? par->getGlobalAxis(0) : Vector3::VEC_I, + par ? par->getGlobalAxis(1) : Vector3::VEC_J, + par ? par->getGlobalAxis(2) : Vector3::VEC_K }; - Vector3 p=ancestors[id]->getPosition(); - origin=origin+parAxis[0]*p.x+parAxis[1]*p.y+parAxis[2]*p.z; + Vector3 p = ancestors[id]->getPosition(); + origin = origin + parAxis[0] * p.x + parAxis[1] * p.y+parAxis[2] * p.z; ancestors.pop_back(); } @@ -223,16 +221,16 @@ namespace vb01{ Vector3 currentGlobalPos = localToGlobalPosition(Vector3::VEC_ZERO); mat3 mat; - mat[0][0]=globalAxis[0].x; - mat[1][0]=globalAxis[0].y; - mat[2][0]=globalAxis[0].z; - mat[0][1]=globalAxis[1].x; - mat[1][1]=globalAxis[1].y; - mat[2][1]=globalAxis[1].z; - mat[0][2]=globalAxis[2].x; - mat[1][2]=globalAxis[2].y; - mat[2][2]=globalAxis[2].z; - mat=inverse(mat); + mat[0][0] = globalAxis[0].x; + mat[1][0] = globalAxis[0].y; + mat[2][0] = globalAxis[0].z; + mat[0][1] = globalAxis[1].x; + mat[1][1] = globalAxis[1].y; + mat[2][1] = globalAxis[1].z; + mat[0][2] = globalAxis[2].x; + mat[1][2] = globalAxis[2].y; + mat[2][2] = globalAxis[2].z; + mat = inverse(mat); vec3 local = vec3(globalPos.x - currentGlobalPos.x, globalPos.y - currentGlobalPos.y, globalPos.z - currentGlobalPos.z) * mat; return Vector3(local.x, local.y, local.z); @@ -251,9 +249,9 @@ namespace vb01{ if(localToGlobal){ Node *par = ancestors[id]->getParent(); Vector3 parAxis[]{ - par?par->getGlobalAxis(0):Vector3::VEC_I, - par?par->getGlobalAxis(1):Vector3::VEC_J, - par?par->getGlobalAxis(2):Vector3::VEC_K + par ? par->getGlobalAxis(0) : Vector3::VEC_I, + par ? par->getGlobalAxis(1) : Vector3::VEC_J, + par ? par->getGlobalAxis(2) : Vector3::VEC_K }; axis = (parAxis[0] * axis.x + parAxis[1] * axis.y + parAxis[2] * axis.z).norm(); @@ -291,7 +289,8 @@ namespace vb01{ void Node::updateShaders(){ Root *root = Root::getSingleton(); - Node *rootNode = Root::getSingleton()->getRootNode(); + + Node *rootNode = root->getRootNode(); vector descendants; rootNode->getDescendants(rootNode, descendants); descendants.push_back(rootNode); @@ -300,7 +299,8 @@ namespace vb01{ vector meshes = n->getMeshes(); for(Mesh *m : meshes){ Material *mat = m->getMaterial(); - string str = "const int numLights = " + to_string(root->numLights > 0 ? root->numLights : 1) + ";"; + int numLights = root->getNumLights(); + string str = "const int numLights = " + to_string(numLights > 0 ? numLights : 1) + ";"; if(mat) mat->getShader()->editShader(Shader::FRAGMENT_SHADER, 1, str); @@ -309,7 +309,7 @@ namespace vb01{ } void Node::setOrientation(Quaternion q){ - this->orientation=q; + this->orientation = q; updateAxis(); } } diff --git a/node.h b/node.h index 2f2cabe..a9d36f1 100755 --- a/node.h +++ b/node.h @@ -3,6 +3,7 @@ #include"quaternion.h" #include"vector.h" +#include"root.h" #include #include @@ -34,8 +35,8 @@ namespace vb01{ virtual void lookAt(Vector3, Node*); void updateAxis(); void setOrientation(Quaternion); - void getDescendants(Node*,std::vector&); - std::vector getAncestors(Node*, Node *anc = nullptr); + void getDescendants(Node*, std::vector&); + std::vector getAncestors(Node *anc = Root::getSingleton()->getRootNode()); Vector3 localToGlobalPosition(Vector3); Vector3 globalToLocalPosition(Vector3); Quaternion localToGlobalOrientation(Quaternion); @@ -46,13 +47,13 @@ namespace vb01{ inline std::vector& getMeshes(){return meshes;} inline Mesh* getMesh(int i){return meshes[i];} inline Node* getParent(){return parent;} - inline void setParent(Node *par){this->parent=par;} + inline void setParent(Node *par){this->parent = par;} inline Node* getChild(int i){return children[i];} inline Vector3 getGlobalAxis(int i){return globalAxis[i];} inline Vector3 getPosition(){return pos;} inline Vector3 getScale(){return scale;} - inline void setPosition(Vector3 pos){this->pos=pos;} - inline void setScale(Vector3 scale){this->scale=scale;} + inline void setPosition(Vector3 pos){this->pos = pos;} + inline void setScale(Vector3 scale){this->scale = scale;} inline std::vector& getChildren(){return children;} inline std::vector& getLights(){return lights;} inline Light* getLight(int i){return lights[i];} @@ -61,7 +62,7 @@ namespace vb01{ inline Quaternion getOrientation(){return orientation;} inline bool isVisible(){return visible;} inline std::string getName(){return name;} - inline void setVisible(bool v){this->visible=v;} + inline void setVisible(bool v){this->visible = v;} private: void adjustUp(Vector3, Node*); void adjustDir(Vector3, Node*); @@ -69,8 +70,8 @@ namespace vb01{ protected: void updateShaders(); - bool visible=true; - Vector3 pos,scale,globalAxis[3]; + bool visible = true; + Vector3 pos, scale, globalAxis[3]; Quaternion orientation; std::vector meshes; std::vector emitters; @@ -78,7 +79,7 @@ namespace vb01{ std::vector lights; std::vector texts; std::string name; - Node *parent=nullptr; + Node *parent = nullptr; }; } diff --git a/particle.frag b/particle.frag index f5cb9ec..c3e48be 100755 --- a/particle.frag +++ b/particle.frag @@ -4,20 +4,19 @@ in vec2 texCoords; flat in int id; -layout (location=0) out vec4 FragColor; -layout (location=1) out vec4 BrightColor; +layout (location = 0) out vec4 FragColor; +layout (location = 1) out vec4 BrightColor; uniform sampler2D tex; uniform float lifePercentage[500]; uniform vec4 startColor,endColor; -//uniform vec4 color[500]; void main(){ - float alpha=texture(tex,texCoords).r; - vec4 c=startColor+(endColor-startColor)*lifePercentage[id]; - c=vec4(c.x,c.y,c.z,alpha); + float alpha = texture(tex, texCoords).r; + vec4 c = startColor + (endColor - startColor) * lifePercentage[id]; + c = vec4(c.x, c.y, c.z, alpha); float brightness = dot(c.rgb, vec3(0.2126, 0.7152, 0.0722)); - if(brightness>1) - BrightColor=vec4(c.rgb,1); - FragColor=c; + if(brightness > 1) + BrightColor = vec4(c.rgb, 1); + FragColor = c; } diff --git a/particle.vert b/particle.vert index 405c0fb..8258c5c 100755 --- a/particle.vert +++ b/particle.vert @@ -1,8 +1,8 @@ #version 330 core -layout (location=0) in vec3 aPos; -layout (location=1) in vec2 aTexCoords; -layout (location=2) in mat4 aInstancedModel; +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec2 aTexCoords; +layout (location = 2) in mat4 aInstancedModel; out vec2 texCoords; @@ -10,27 +10,23 @@ flat out int id; uniform mat4 proj; uniform mat4 view; -//uniform mat4 model[4]; uniform float lifePercentage[500]; uniform vec3 trans[500]; -//uniform vec2 size[500]; uniform vec2 startSize; uniform vec2 endSize; void main(){ - vec3 camLeft=vec3(view[0][0],view[1][0],view[2][0]); - vec3 camUp=vec3(view[0][1],view[1][1],view[2][1]); + vec3 camLeft = vec3(view[0][0], view[1][0], view[2][0]); + vec3 camUp = vec3(view[0][1], view[1][1], view[2][1]); - id=gl_InstanceID; - vec2 s=startSize+(endSize-startSize)*lifePercentage[id]; - vec3 v=camLeft*s.x*aPos.x+camUp*s.y*aPos.y; - mat4 model=aInstancedModel; - model[3][0]=trans[gl_InstanceID].x; - model[3][1]=trans[gl_InstanceID].y; - model[3][2]=trans[gl_InstanceID].z; -/* -*/ - gl_Position=proj*view*model*vec4(v,1); - //gl_Position=proj*view*model[gl_InstanceID]*vec4(s.x*aPos.x,s.y*aPos.y,aPos.z,1); - texCoords=aTexCoords; + id = gl_InstanceID; + vec2 s = startSize + (endSize - startSize) * lifePercentage[id]; + vec3 v = camLeft * s.x * aPos.x+camUp * s.y * aPos.y; + mat4 model = aInstancedModel; + model[3][0] = trans[gl_InstanceID].x; + model[3][1] = trans[gl_InstanceID].y; + model[3][2] = trans[gl_InstanceID].z; + + gl_Position = proj * view * model * vec4(v, 1); + texCoords = aTexCoords; } diff --git a/particleEmitter.cpp b/particleEmitter.cpp index 721e48f..a423d2f 100755 --- a/particleEmitter.cpp +++ b/particleEmitter.cpp @@ -16,6 +16,7 @@ using namespace std; namespace vb01{ ParticleEmitter::ParticleEmitter(int numParticles){ this->numParticles = numParticles; + Vertex v1, v2, v3, v4, v5, v6; ParticleEmitter::Vertex vertices[] = {v1, v2, v3, v4, v5, v6}; u32 indices[] = {0, 1, 2, 3, 4, 5}; @@ -25,73 +26,74 @@ namespace vb01{ } void ParticleEmitter::setupParticles(Vertex vertices[]){ - particles=new Particle*[numParticles]; + particles = new Particle*[numParticles]; - Vector2 size=Vector2(.5,.5); - vertices[0].pos=Vector3(size.x/2,size.y/2,0); - vertices[0].texCoords=Vector2(1,1); + Vector2 size = Vector2(.5,.5); + vertices[0].pos = Vector3(size.x / 2, size.y / 2, 0); + vertices[0].texCoords = Vector2(1, 1); - vertices[1].pos=Vector3(-size.x/2,size.y/2,0); - vertices[1].texCoords=Vector2(0,1); + vertices[1].pos = Vector3(-size.x / 2, size.y / 2, 0); + vertices[1].texCoords = Vector2(0, 1); - vertices[2].pos=Vector3(-size.x/2,-size.y/2,0); + vertices[2].pos = Vector3(-size.x / 2,-size.y / 2, 0); vertices[2].texCoords=Vector2(0,0); - vertices[3].pos=Vector3(-size.x/2,-size.y/2,0); - vertices[3].texCoords=Vector2(0,0); + vertices[3].pos = Vector3(-size.x / 2, -size.y / 2, 0); + vertices[3].texCoords = Vector2(0, 0); - vertices[4].pos=Vector3(size.x/2,-size.y/2,0); - vertices[4].texCoords=Vector2(1,0); + vertices[4].pos = Vector3(size.x / 2, -size.y / 2, 0); + vertices[4].texCoords = Vector2(1, 0); - vertices[5].pos=Vector3(size.x/2,size.y/2,0); - vertices[5].texCoords=Vector2(1,1); + vertices[5].pos = Vector3(size.x / 2, size.y / 2, 0); + vertices[5].texCoords = Vector2(1, 1); - matrices=new mat4[numParticles]; + matrices = new mat4[numParticles]; - for(int i=0;idir=direction; - particles[i]=p; - matrices[i]=mat4(1.f); + for(int i = 0; i < numParticles; i++){ + Particle *p = new Particle; + p->dir = direction; + particles[i] = p; + matrices[i] = mat4(1.f); } } void ParticleEmitter::setupDisplay(Vertex vertices[], u32 indices[]){ u32 MBO; - glGenVertexArrays(1,&VAO); - glGenBuffers(1,&VBO); - glGenBuffers(1,&EBO); + glGenVertexArrays(1, &VAO); + glGenBuffers(1, &VBO); + glGenBuffers(1, &EBO); glBindVertexArray(VAO); - glBindBuffer(GL_ARRAY_BUFFER,VBO); - glBufferData(GL_ARRAY_BUFFER,6*sizeof(Vertex),vertices,GL_STATIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO); - glBufferData(GL_ELEMENT_ARRAY_BUFFER,6*sizeof(u32),indices,GL_STATIC_DRAW); - glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,sizeof(Vertex),(void*)0); + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(Vertex), vertices, GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(u32), indices, GL_STATIC_DRAW); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0); glEnableVertexAttribArray(0); - glVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE,sizeof(Vertex),(void*)(offsetof(Vertex,texCoords))); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(offsetof(Vertex, texCoords))); glEnableVertexAttribArray(1); - glGenBuffers(1,&MBO); - glBindBuffer(GL_ARRAY_BUFFER,MBO); - glBufferData(GL_ARRAY_BUFFER,numParticles*sizeof(mat4),&matrices[0],GL_STATIC_DRAW); - glVertexAttribPointer(2,4,GL_FLOAT,GL_FALSE,sizeof(mat4),(void*)0); + + glGenBuffers(1, &MBO); + glBindBuffer(GL_ARRAY_BUFFER, MBO); + glBufferData(GL_ARRAY_BUFFER, numParticles * sizeof(mat4), &matrices[0], GL_STATIC_DRAW); + glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(mat4), (void*)0); glEnableVertexAttribArray(2); - glVertexAttribPointer(3,4,GL_FLOAT,GL_FALSE,sizeof(mat4),(void*)(1*sizeof(vec4))); + glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(mat4), (void*)(1 * sizeof(vec4))); glEnableVertexAttribArray(3); - glVertexAttribPointer(4,4,GL_FLOAT,GL_FALSE,sizeof(mat4),(void*)(2*sizeof(vec4))); + glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(mat4), (void*)(2 * sizeof(vec4))); glEnableVertexAttribArray(4); - glVertexAttribPointer(5,4,GL_FLOAT,GL_FALSE,sizeof(mat4),(void*)(3*sizeof(vec4))); + glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, sizeof(mat4), (void*)(3 * sizeof(vec4))); glEnableVertexAttribArray(5); - glVertexAttribDivisor(2,1); - glVertexAttribDivisor(3,1); - glVertexAttribDivisor(4,1); - glVertexAttribDivisor(5,1); + glVertexAttribDivisor(2, 1); + glVertexAttribDivisor(3, 1); + glVertexAttribDivisor(4, 1); + glVertexAttribDivisor(5, 1); } ParticleEmitter::~ParticleEmitter(){ - glDeleteVertexArrays(1,&VAO); - glDeleteBuffers(1,&VBO); + glDeleteVertexArrays(1, &VAO); + glDeleteBuffers(1, &VBO); delete material; @@ -99,96 +101,107 @@ namespace vb01{ } void ParticleEmitter::makeHeap(int offset){ - bool heap=false; + bool heap = false; while(!heap){ - bool end=true; - for(int i=0;2*i+1+offsetdd||particles[i+offset]->dd)){ - bool leftChild=particles[2*i+1+offset]->d>particles[2*i+2+offset]->d; - swap(particles[i+offset],leftChild?particles[2*i+1+offset]:particles[2*i+2+offset]); + bool end = true; + for(int i = 0; 2 * i + 1 + offset < numParticles; i++){ + if(2 * i + 2 + offset < numParticles && (particles[i + offset]->d < particles[2 * i + 1 + offset]->d || particles[i + offset]->d < particles[2 * i + 2 + offset]->d)){ + bool leftChild = particles[2 * i + 1 + offset]->d > particles[2 * i + 2 + offset]->d; + swap(particles[i + offset], leftChild ? particles[2 * i + 1 + offset] : particles[2 * i + 2 + offset]); } - else if(2*i+2+offset==numParticles&&particles[i+offset]->dd) - swap(particles[i+offset],particles[2*i+1+offset]); + else if(2 * i + 2 + offset == numParticles && particles[i + offset]->d < particles[2 * i + 1 + offset]->d) + swap(particles[i + offset], particles[2 * i + 1 + offset]); } - for(int i=0;2*i+1dd||particles[i+offset]->dd)) - end=false; - else if(2*i+2+offset==numParticles&&particles[i+offset]->dd) - end=false; + for(int i = 0; 2 * i + 1 < numParticles; i++){ + if(2 * i + 2 + offset < numParticles && (particles[i + offset]->d < particles[2 * i + 1 + offset]->d || particles[i + offset]->d < particles[2 * i + 2 + offset]->d)) + end = false; + else if(2 * i + 2 + offset == numParticles && particles[i + offset]->d < particles[2 * i + 1 + offset]->d) + end = false; } if(end) - heap=true; + heap = true; } } void ParticleEmitter::heapSort(){ - for(int i=0;igetCamera(); - float fov=cam->getFov(),width=root->getWidth(),height=root->getHeight(); - float nearPlane=cam->getNearPlane(),farPlane=cam->getFarPlane(); - Vector3 pos=node->getPosition(); - Vector3 camDir=cam->getDirection(),up=cam->getUp(),left=cam->getLeft(),camPos=cam->getPosition(); + Root *root = Root::getSingleton(); + Camera *cam = root->getCamera(); + float fov = cam->getFov(), width = root->getWidth(), height = root->getHeight(); + float nearPlane = cam->getNearPlane(), farPlane = cam->getFarPlane(); + Vector3 pos = node->getPosition(); + Vector3 camDir = cam->getDirection(), up = cam->getUp(), left = cam->getLeft(), camPos = cam->getPosition(); - mat4 view=lookAt(vec3(camPos.x,camPos.y,camPos.z),vec3(camPos.x+camDir.x,camPos.y+camDir.y,camPos.z+camDir.z),vec3(up.x,up.y,up.z)); - mat4 proj=perspective(radians(fov),width/height,nearPlane,farPlane); + mat4 view = lookAt(vec3(camPos.x, camPos.y, camPos.z), vec3(camPos.x + camDir.x, camPos.y + camDir.y, camPos.z + camDir.z), vec3(up.x, up.y, up.z)); + mat4 proj = perspective(radians(fov), width / height, nearPlane, farPlane); + + updateParticles(camDir, camPos); material->update(); Shader *shader=material->getShader(); - shader->setMat4(view,"view"); - shader->setMat4(proj,"proj"); - shader->setVec4(startColor,"startColor"); - shader->setVec4(endColor,"endColor"); - shader->setVec2(startSize,"startSize"); - shader->setVec2(endSize,"endSize"); - - Vector3 nodePos=node->localToGlobalPosition(Vector3::VEC_ZERO); - Vector3 nodeDir=node->getGlobalAxis(2); - Vector3 nodeUp=node->getGlobalAxis(1); - Vector3 nodeLeft=node->getGlobalAxis(0); - for(int i=0;idir; - if(getTime()-particles[i]->time>=particles[i]->timeToLive){ - particles[i]->time=getTime(); - float factor=(float)(rand()%100)/100; - float s1=float(rand()%(int)spread)/180*PI,s2=float(rand()%360)/180*PI; - Vector3 ra1=(Vector3(0,1,0).cross(dir)).norm(),ra2=dir.norm(); - if(ra1==Vector3::VEC_ZERO) ra1=Vector3(1,0,0); - dir=Quaternion(s1,ra1)*dir; - dir=Quaternion(s2,ra2)*dir; - particles[i]->timeToLive=s64(1000*((highLife-lowLife)*factor+lowLife)); - //particles[i].mat=translate(mat4(1.f),vec3(nodePos.x,nodePos.y,nodePos.z)); - particles[i]->trans=nodePos; - } - //dir=nodeLeft*dir.x+nodeUp*dir.y+nodeDir*dir.z; - particles[i]->dir=dir.norm()*direction.getLengthSq()+gravity; - float lifePercentage=(float)(getTime()-particles[i]->time)/particles[i]->timeToLive; - particles[i]->color=startColor+(endColor-startColor)*lifePercentage; - particles[i]->size=startSize+(endSize-startSize)*lifePercentage; - //particles[i].mat=translate(particles[i].mat,vec3(dir.x,dir.y,dir.z)); - particles[i]->trans=particles[i]->trans+dir; - - shader->setVec3(particles[i]->trans,"trans["+to_string(i)+"]"); - shader->setFloat(lifePercentage,"lifePercentage["+to_string(i)+"]"); - //shader->setVec2(particles[i]->size,"size["+to_string(i)+"]"); - - Vector3 v0=particles[i]->trans; - particles[i]->d=cos(camDir.getAngleBetween((v0-camPos).norm()))*camPos.getDistanceFrom(v0); - } + shader->setMat4(view, "view"); + shader->setMat4(proj, "proj"); + shader->setVec4(startColor, "startColor"); + shader->setVec4(endColor, "endColor"); + shader->setVec2(startSize, "startSize"); + shader->setVec2(endSize, "endSize"); + for(int i = 0; i < numParticles; i++) + shader->setVec3(particles[i]->trans, "trans[" + to_string(i) + "]"); heapSort(); - glBindVertexArray(VAO); - glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); - glDrawElementsInstanced(GL_TRIANGLES,6,GL_UNSIGNED_INT,0,numParticles); + render(); + } + + void ParticleEmitter::updateParticles(Vector3 camDir, Vector3 camPos){ + Shader *shader=material->getShader(); + Vector3 nodePos = node->localToGlobalPosition(Vector3::VEC_ZERO); + Vector3 nodeDir = node->getGlobalAxis(2); + Vector3 nodeUp = node->getGlobalAxis(1); + Vector3 nodeLeft = node->getGlobalAxis(0); + + for(int i = 0; i < numParticles; i++){ + Vector3 dir = particles[i]->dir; + if(getTime() - particles[i]->time >= particles[i]->timeToLive){ + particles[i]->time = getTime(); + float factor = (float)(rand() % 100) / 100; + float s1 = float(rand() % (int)spread) / 180 * PI, s2 = float(rand() % 360) / 180 * PI; + Vector3 ra1 = (Vector3(0, 1, 0).cross(dir)).norm(), ra2 = dir.norm(); + if(ra1 == Vector3::VEC_ZERO) + ra1 = Vector3::VEC_I; + dir = Quaternion(s1, ra1) * dir; + dir = Quaternion(s2, ra2) * dir; + + particles[i]->timeToLive = s64(1000 * ((highLife - lowLife) * factor + lowLife)); + + particles[i]->trans = nodePos; + } + + particles[i]->dir = dir.norm() * direction.getLengthSq() + gravity; + float lifePercentage = (float)(getTime() - particles[i]->time) / particles[i]->timeToLive; + particles[i]->color = startColor + (endColor - startColor) * lifePercentage; + particles[i]->size = startSize + (endSize - startSize) * lifePercentage; + particles[i]->trans = particles[i]->trans + dir; + + Vector3 trans = particles[i]->trans; + particles[i]->d = cos(camDir.getAngleBetween((trans - camPos).norm())) * camPos.getDistanceFrom(trans); + + shader->setFloat(lifePercentage, "lifePercentage[" + to_string(i) + "]"); + } } void ParticleEmitter::setDirection(Vector3 dir){ - this->direction=dir; - for(int i=0;idir=dir; + this->direction = dir; + for(int i = 0; i < numParticles; i++) + particles[i]->dir = dir; + } + + void ParticleEmitter::render(){ + glBindVertexArray(VAO); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0, numParticles); } } diff --git a/particleEmitter.h b/particleEmitter.h index 6d52d61..79e57ed 100755 --- a/particleEmitter.h +++ b/particleEmitter.h @@ -12,19 +12,19 @@ namespace vb01{ class ParticleEmitter{ public: - ParticleEmitter(int=1); + ParticleEmitter(int = 1); ~ParticleEmitter(); void update(); - inline void setMaterial(Material *mat){this->material=mat;} - inline void setNode(Node *node){this->node=node;} - inline void setStartSize(Vector2 size){this->startSize=size;} - inline void setEndSize(Vector2 size){this->endSize=size;} - inline void setStartColor(Vector4 color){this->startColor=color;} - inline void setEndColor(Vector4 color){this->endColor=color;} - inline void setSpread(float s){this->spread=s;} - inline void setLowLife(float l){this->lowLife=l;} - inline void setHighLife(float h){this->highLife=h;} - inline void setGravity(Vector3 g){this->gravity=g;} + inline void setMaterial(Material *mat){this->material = mat;} + inline void setNode(Node *node){this->node = node;} + inline void setStartSize(Vector2 size){this->startSize = size;} + inline void setEndSize(Vector2 size){this->endSize = size;} + inline void setStartColor(Vector4 color){this->startColor = color;} + inline void setEndColor(Vector4 color){this->endColor = color;} + inline void setSpread(float s){this->spread = s;} + inline void setLowLife(float l){this->lowLife = l;} + inline void setHighLife(float h){this->highLife = h;} + inline void setGravity(Vector3 g){this->gravity = g;} inline Node* getNode(){return node;} inline Vector3 getDirection(){return direction;} void setDirection(Vector3 dir); @@ -35,28 +35,30 @@ namespace vb01{ }; struct Particle{ int VAO; - s64 time=0,timeToLive=0; + s64 time = 0, timeToLive = 0; Vector4 color; - Vector3 dir,trans; + Vector3 dir, trans; Vector2 size; float d; }; void makeHeap(int); + void updateParticles(Vector3, Vector3); void heapSort(); void setupParticles(Vertex[]); void setupDisplay(Vertex[], u32[]); + void render(); - unsigned int VAO,VBO,EBO,MBO; + unsigned int VAO, VBO, EBO, MBO; glm::mat4 *matrices; int numParticles; Particle **particles; - Material *material=nullptr; - Node *node=nullptr; - Vector2 startSize=Vector2::VEC_IJ,endSize=Vector2::VEC_IJ; - Vector3 direction=Vector3(0,.1,0),gravity=Vector3::VEC_ZERO; - Vector4 startColor,endColor; - float spread=1,lowLife=1,highLife=2; + Material *material = nullptr; + Node *node = nullptr; + Vector2 startSize = Vector2::VEC_IJ, endSize = Vector2::VEC_IJ; + Vector3 direction = Vector3(0, .1, 0), gravity = Vector3::VEC_ZERO; + Vector4 startColor, endColor; + float spread = 1, lowLife = 1, highLife = 2; }; } diff --git a/quad.cpp b/quad.cpp index cfed173..d95d259 100755 --- a/quad.cpp +++ b/quad.cpp @@ -1,14 +1,14 @@ #include"quad.h" namespace vb01{ - Quad::Quad(Vector3 size,bool spatial) : Mesh(){ - this->spatial=spatial; - this->staticVerts=false; + Quad::Quad(Vector3 size, bool spatial) : Mesh(){ + this->spatial = spatial; + this->staticVerts = false; - int numPolyVerts=3; - numTris=2; - indices=new unsigned int[numTris*numPolyVerts]; - vertices=new Vertex[numTris*numPolyVerts]; + int numPolyVerts = 3; + numTris = 2; + indices = new u32[numTris * numPolyVerts]; + vertices = new Vertex[numTris * numPolyVerts]; setSize(size); @@ -16,56 +16,56 @@ namespace vb01{ } void Quad::setSize(Vector3 size){ - this->size=size; + this->size = size; Vertex v1,v2,v3,v4,v5,v6; if(spatial){ - v1.pos=Vector3(size.x/2,size.y/2,0); - v2.pos=Vector3(-size.x/2,size.y/2,0); - v3.pos=Vector3(-size.x/2,-size.y/2,0); - v4.pos=Vector3(-size.x/2,-size.y/2,0); - v5.pos=Vector3(size.x/2,-size.y/2,0); - v6.pos=Vector3(size.x/2,size.y/2,0); + v1.pos = Vector3(size.x / 2, size.y / 2, 0); + v2.pos = Vector3(-size.x / 2, size.y / 2, 0); + v3.pos = Vector3(-size.x / 2, -size.y / 2, 0); + v4.pos = Vector3(-size.x / 2, -size.y / 2, 0); + v5.pos = Vector3(size.x / 2, -size.y / 2, 0); + v6.pos = Vector3(size.x / 2, size.y / 2, 0); } else{ - v1.pos=Vector3(size.x,0,0); - v2.pos=Vector3(0,0,0); - v3.pos=Vector3(0,size.y,0); - v4.pos=Vector3(0,size.y,0); - v5.pos=Vector3(size.x,size.y,0); - v6.pos=Vector3(size.x,0,0); + v1.pos = Vector3(size.x, 0, 0); + v2.pos = Vector3(0, 0, 0); + v3.pos = Vector3(0, size.y, 0); + v4.pos = Vector3(0, size.y, 0); + v5.pos = Vector3(size.x, size.y, 0); + v6.pos = Vector3(size.x, 0, 0); } - v1.norm=Vector3(0,0,-1); - v1.uv=Vector2(1,1); + v1.norm = Vector3(0, 0, -1); + v1.uv = Vector2(1, 1); - v2.norm=Vector3(0,0,-1); - v2.uv=Vector2(0,1); + v2.norm = Vector3(0, 0, -1); + v2.uv = Vector2(0, 1); - v3.norm=Vector3(0,0,-1); - v3.uv=Vector2(0,0); + v3.norm = Vector3(0, 0, -1); + v3.uv = Vector2(0,0); - v4.norm=Vector3(0,0,-1); - v4.uv=Vector2(0,0); + v4.norm = Vector3(0, 0, -1); + v4.uv = Vector2(0, 0); - v5.norm=Vector3(0,0,-1); - v5.uv=Vector2(1,0); + v5.norm = Vector3(0, 0, -1); + v5.uv = Vector2(1,0); - v6.norm=Vector3(0,0,-1); - v6.uv=Vector2(1,1); + v6.norm = Vector3(0, 0, -1); + v6.uv = Vector2(1, 1); - indices[0]=0; - indices[1]=1; - indices[2]=2; - indices[3]=3; - indices[4]=4; - indices[5]=5; + indices[0] = 0; + indices[1] = 1; + indices[2] = 2; + indices[3] = 3; + indices[4] = 4; + indices[5] = 5; - vertices[0]=v1; - vertices[1]=v2; - vertices[2]=v3; - vertices[3]=v4; - vertices[4]=v5; - vertices[5]=v6; + vertices[0] = v1; + vertices[1] = v2; + vertices[2] = v3; + vertices[3] = v4; + vertices[4] = v5; + vertices[5] = v6; } } diff --git a/quad.h b/quad.h index 917c5e4..b9b1c03 100755 --- a/quad.h +++ b/quad.h @@ -7,7 +7,7 @@ namespace vb01{ class Quad : public Mesh{ public: - Quad(Vector3,bool=true); + Quad(Vector3, bool = true); void setSize(Vector3); private: Vector3 size; diff --git a/root.cpp b/root.cpp index bfd5f7b..74b49aa 100755 --- a/root.cpp +++ b/root.cpp @@ -12,42 +12,48 @@ using namespace std; namespace vb01{ - static Root *root=nullptr; + static Root *root = nullptr; Root* Root::getSingleton(){ if(!root) - root=new Root(); + root = new Root(); return root; } void foo(GLFWwindow *window, int width, int height){ - glViewport(0,0,width,height); + glViewport(0, 0, width, height); } Root::Root(){ - rootNode=new Node(Vector3::VEC_ZERO); - guiNode=new Node(Vector3::VEC_ZERO); + rootNode = new Node(Vector3::VEC_ZERO); + guiNode = new Node(Vector3::VEC_ZERO); - camera=new Camera(); + camera = new Camera(); } - void Root::start(int width,int height,string name){ - this->width=width; - this->height=height; + void Root::start(int width, int height, string name){ + this->width = width; + this->height = height; + initWindow(name); + initBloomFramebuffer(); + initGuiPlane(); + } + + void Root::initWindow(string name){ glfwInit(); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,4); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3); - glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE); - window=glfwCreateWindow(width,height,name.c_str(),NULL,NULL); - if(window==NULL){ - std::cout<<"Failed to load window.\n"; + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + window = glfwCreateWindow(width, height, name.c_str(), NULL, NULL); + if(window == NULL){ + cout << "Failed to load window.\n"; exit(-1); } glfwMakeContextCurrent(window); - glfwSetFramebufferSizeCallback(window,foo); + glfwSetFramebufferSizeCallback(window, foo); if(!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){ - std::cout<<"Failed to load GLAD.\n"; + cout << "Failed to load GLAD.\n"; exit(-1); } glEnable(GL_DEPTH_TEST); @@ -56,44 +62,48 @@ namespace vb01{ glCullFace(GL_BACK); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } - glGenFramebuffers(1,&FBO); + void Root::initBloomFramebuffer(){ + glGenFramebuffers(1, &FBO); glBindFramebuffer(GL_FRAMEBUFFER,FBO); - Texture *fragTexture=new Texture(width,height,false); - Texture *brightTexture=new Texture(width,height,false); - for(int i=0;i<2;i++){ - glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0+i,GL_TEXTURE_2D,*((i==0?fragTexture:brightTexture)->getTexture()),0); + + u32 colorAttachments[]{GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1}; + glDrawBuffers(2, colorAttachments); + + glGenRenderbuffers(1, &RBO); + glBindRenderbuffer(GL_RENDERBUFFER, RBO); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,RBO); + + if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + cout << "Not complete\n"; + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + string basePath = "../../vb01/blur."; + blurShader = new Shader(basePath + "vert", basePath + "frag"); + glGenFramebuffers(2, pingpongBuffers); + for(int i = 0; i < 2; i++){ + glBindFramebuffer(GL_FRAMEBUFFER, pingpongBuffers[i]); + pingPongTextures[i] = new Texture(width, height, false); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *(pingPongTextures[i]->getTexture()), 0); + if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + cout << "Not complete\n"; } - u32 colorAttachments[]{GL_COLOR_ATTACHMENT0,GL_COLOR_ATTACHMENT1}; - glDrawBuffers(2,colorAttachments); + } - glGenRenderbuffers(1,&RBO); - glBindRenderbuffer(GL_RENDERBUFFER,RBO); - glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH24_STENCIL8,width,height); - glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_DEPTH_STENCIL_ATTACHMENT,GL_RENDERBUFFER,RBO); - /* - */ - if(glCheckFramebufferStatus(GL_FRAMEBUFFER)!=GL_FRAMEBUFFER_COMPLETE) - cout<<"Not complete\n"; - glBindFramebuffer(GL_FRAMEBUFFER,0); + void Root::initGuiPlane(){ + Texture *fragTexture = new Texture(width, height, false); + Texture *brightTexture = new Texture(width, height, false); + for(int i = 0; i < 2; i++) + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, *((i == 0 ? fragTexture : brightTexture)->getTexture()), 0); - guiPlane=new Quad(Vector3(width,height,-1),false); - Material *mat=new Material(Material::MATERIAL_POST); + guiPlane = new Quad(Vector3(width, height, -1), false); + Material *mat = new Material(Material::MATERIAL_POST); mat->addDiffuseMap(fragTexture); mat->addDiffuseMap(brightTexture); guiPlane->setMaterial(mat); - - string basePath="../../vb01/blur."; - blurShader=new Shader(basePath+"vert",basePath+"frag"); - glGenFramebuffers(2,pingpongBuffers); - for(int i=0;i<2;i++){ - glBindFramebuffer(GL_FRAMEBUFFER,pingpongBuffers[i]); - pingPongTextures[i]=new Texture(width,height,false); - glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,*(pingPongTextures[i]->getTexture()),0); - if(glCheckFramebufferStatus(GL_FRAMEBUFFER)!=GL_FRAMEBUFFER_COMPLETE) - cout<<"Not complete\n"; - } } void Root::update(){ @@ -113,40 +123,14 @@ namespace vb01{ rootNode->update(); - glBindFramebuffer(GL_FRAMEBUFFER,0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); - Material *material=guiPlane->getMaterial(); - Shader *shader=material->getShader(); + updateBloomFramebuffer(); - bool horizontal=false; - blurShader->use(); - blurShader->setVec2(Vector2(width,height),"screen"); - for(int i=0;isetBool(horizontal,"horizontal"); - if(i==0) - glBindTexture(GL_TEXTURE_2D,*(material->getDiffuseMap(1)->getTexture())); - else - pingPongTextures[!horizontal]->select(); - guiPlane->render(); - horizontal=!horizontal; - } - glBindFramebuffer(GL_FRAMEBUFFER,0); - - shader->use(); - shader->setVec2(Vector2(width,height),"screen"); - shader->setBool(bloom,"bloom"); - shader->setBool(hdr,"hdr"); - shader->setFloat(exposure,"exposure"); - shader->setFloat(gamma,"gamma"); - material->getDiffuseMap(0)->select(); - pingPongTextures[!horizontal]->select(1); - shader->setInt(0,"frag"); - shader->setInt(1,"bright"); guiPlane->render(); glEnable(GL_DEPTH_TEST); @@ -156,16 +140,49 @@ namespace vb01{ glfwPollEvents(); } + void Root::updateBloomFramebuffer(){ + Material *material = guiPlane->getMaterial(); + Shader *shader = material->getShader(); + + bool horizontal = false; + blurShader->use(); + blurShader->setVec2(Vector2(width, height), "screen"); + for(int i = 0; i < blurLevel; i++){ + glBindFramebuffer(GL_FRAMEBUFFER, pingpongBuffers[horizontal]); + blurShader->setBool(horizontal, "horizontal"); + if(i == 0) + glBindTexture(GL_TEXTURE_2D, *(material->getDiffuseMap(1)->getTexture())); + else + pingPongTextures[!horizontal]->select(); + guiPlane->render(); + horizontal = !horizontal; + } + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + shader->use(); + shader->setVec2(Vector2(width, height), "screen"); + shader->setBool(bloom, "bloom"); + shader->setBool(hdr, "hdr"); + shader->setFloat(exposure, "exposure"); + shader->setFloat(gamma, "gamma"); + + material->getDiffuseMap(0)->select(); + pingPongTextures[!horizontal]->select(1); + + shader->setInt(0, "frag"); + shader->setInt(1, "bright"); + } + void Root::createSkybox(string textures[6]){ - skybox = new Box(Vector3(10,10,10)); - Material *skyboxMat=new Material(Material::MATERIAL_SKYBOX); + skybox = new Box(Vector3(1, 1, 1) * 10); + Material *skyboxMat = new Material(Material::MATERIAL_SKYBOX); skyboxMat->addDiffuseMap(textures); skybox->setMaterial(skyboxMat); } void Root::removeSkybox(){ - Material *mat=skybox->getMaterial(); + Material *mat = skybox->getMaterial(); delete skybox; - skybox=nullptr; + skybox = nullptr; } } diff --git a/root.h b/root.h index 4bd5faa..0c66ce0 100755 --- a/root.h +++ b/root.h @@ -20,7 +20,7 @@ namespace vb01{ class Root{ public: void update(); - void start(int,int,std::string); + void start(int, int, std::string); inline Camera* getCamera(){return camera;} inline Node* getRootNode(){return rootNode;} inline Node* getGuiNode(){return guiNode;} @@ -28,32 +28,38 @@ namespace vb01{ inline int getHeight(){return height;} inline unsigned int* getFBO(){return &FBO;} inline GLFWwindow* getWindow(){return window;} - inline void setHDREnabled(bool hdr){this->hdr=hdr;} - inline void setExposure(float exposure){this->exposure=exposure;} - inline void setGamma(float gamme){this->gamma=gamma;} - inline void setBloom(bool bloom){this->bloom=bloom;} - inline void setBlurLevel(bool level){this->blurLevel=level;} + inline void setHDREnabled(bool hdr){this->hdr = hdr;} + inline void setExposure(float exposure){this->exposure = exposure;} + inline void setGamma(float gamma){this->gamma = gamma;} + inline void setBloom(bool bloom){this->bloom = bloom;} + inline void setBlurLevel(bool level){this->blurLevel = level;} inline Box* getSkybox(){return skybox;} void createSkybox(std::string[6]); void removeSkybox(); static Root* getSingleton(); - int numLights=0; + inline void shiftNumLights(bool increase){numLights += (increase ? 1 : -1);} + inline int getNumLights(){return numLights;} private: - bool bloom=false,hdr=false; - float exposure=1,gamma=1; - Box *skybox=nullptr; - Quad *guiPlane=nullptr; - int width,height,blurLevel=10; - unsigned int FBO,RBO,pingpongBuffers[2]; + int numLights = 0; + bool bloom = false, hdr = false; + float exposure = 1, gamma = 1; + Box *skybox = nullptr; + Quad *guiPlane = nullptr; + int width, height, blurLevel = 10; + unsigned int FBO, RBO, pingpongBuffers[2]; GLFWwindow *window; - Node *rootNode,*guiNode; + Node *rootNode, *guiNode; Camera *camera; Shader *blurShader; Texture *pingPongTextures[2]; std::vector meshes; - void framebuffer_size_callback(GLFWwindow*,int,int); + void framebuffer_size_callback(GLFWwindow*, int, int); Root(); + void initWindow(std::string); + void initBloomFramebuffer(); + void initGuiPlane(); + void updateBloomFramebuffer(); }; } diff --git a/shader.cpp b/shader.cpp index 534aacf..fd22200 100755 --- a/shader.cpp +++ b/shader.cpp @@ -12,125 +12,124 @@ using namespace glm; namespace vb01{ Shader::Shader(string vertShaderPath, string fragShaderPath, string geoShaderPath){ - geometry=(geoShaderPath!=""); - - ifstream vertShaderFile,geoShaderFile,fragShaderFile; - vertShaderFile.open(vertShaderPath); - geoShaderFile.open(geoShaderPath); - fragShaderFile.open(fragShaderPath); - - stringstream vertShaderStream,geoShaderStream,fragShaderStream; - vertShaderStream<length(); i++) if(shaderString[0][i] == '\n'){ - if(numPassedLines==line-1) - lineStart=i+1; - if(numPassedLines==line){ - lineEnd=i; + if(numPassedLines == line - 1) + lineStart = i + 1; + if(numPassedLines == line){ + lineEnd = i; break; } numPassedLines++; } - *shaderString=shaderString->substr(0,lineStart)+insertion+shaderString->substr(lineEnd,string::npos); - - loadShaders(); + *shaderString = shaderString->substr(0, lineStart) + insertion + shaderString->substr(lineEnd); + } + void Shader::pushShader(u32 &type, string &sString, int glType, ErrorType errorType){ + type = glCreateShader(glType); + const char *shaderSource = sString.c_str(); + glShaderSource(type, 1, &shaderSource, NULL); + glCompileShader(type); + checkCompileErrors(type, errorType); } void Shader::loadShaders(){ - const char *vertShaderSource=vString.c_str(); - const char *geoShaderSource=gString.c_str(); - const char *fragShaderSource=fString.c_str(); + u32 vert, geo, frag; + pushShader(vert, vString, GL_VERTEX_SHADER, VERTEX_ERROR); + pushShader(frag, fString, GL_FRAGMENT_SHADER, FRAGMENT_ERROR); + if(geometry) + pushShader(geo, gString, GL_GEOMETRY_SHADER, GEOMETRY_ERROR); - unsigned int vert,geo,frag; - vert=glCreateShader(GL_VERTEX_SHADER); - glShaderSource(vert,1,&vertShaderSource,NULL); - glCompileShader(vert); - checkCompileErrors(vert,VERTEX_ERROR); - - if(geometry){ - geo=glCreateShader(GL_GEOMETRY_SHADER); - glShaderSource(geo,1,&geoShaderSource,NULL); - glCompileShader(geo); - checkCompileErrors(geo,GEOMETRY_ERROR); - } - - frag=glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(frag,1,&fragShaderSource,NULL); - glCompileShader(frag); - checkCompileErrors(frag,FRAGMENT_ERROR); - - id=glCreateProgram(); - glAttachShader(id,vert); - if(geometry) glAttachShader(id,geo); - glAttachShader(id,frag); + id = glCreateProgram(); + glAttachShader(id, vert); + glAttachShader(id, frag); + if(geometry) + glAttachShader(id, geo); glLinkProgram(id); - checkCompileErrors(id,PROGRAM_ERROR); + checkCompileErrors(id, PROGRAM_ERROR); glDeleteShader(vert); - if(geometry) glDeleteShader(geo); glDeleteShader(frag); + if(geometry) + glDeleteShader(geo); } - void Shader::checkCompileErrors(unsigned int shader, ErrorType type){ - int success; - char infoLog[1024]; + void Shader::checkCompileErrors(u32 shader, ErrorType type){ + int success, infoLogLen = 1024; + char infoLog[infoLogLen]; switch(type){ case PROGRAM_ERROR: - glGetProgramiv(shader,GL_LINK_STATUS,&success); + glGetProgramiv(shader, GL_LINK_STATUS, &success); if(!success){ - glGetProgramInfoLog(shader,1024,NULL,infoLog); - cout<<"ERROR::PROGRAM_LINK_ERROR: "< #include #include"vector.h" +#include"util.h" namespace vb01{ class Shader{ public: - enum ErrorType{VERTEX_ERROR,GEOMETRY_ERROR,FRAGMENT_ERROR,PROGRAM_ERROR}; - enum ShaderType{VERTEX_SHADER,FRAGMENT_SHADER,GEOMETRY_SHADER}; + enum ErrorType{VERTEX_ERROR, GEOMETRY_ERROR, FRAGMENT_ERROR, PROGRAM_ERROR}; + enum ShaderType{VERTEX_SHADER, FRAGMENT_SHADER, GEOMETRY_SHADER}; - Shader(std::string,std::string,std::string=""); + Shader(std::string, std::string, std::string = ""); ~Shader(); void setNumLights(int); void use(); - void setMat4(glm::mat4,std::string); - void setVec4(Vector4,std::string); - void setVec3(Vector3,std::string); - void setVec2(Vector2,std::string); - void setFloat(float,std::string); - void setBool(bool,std::string); - void setInt(int,std::string); - void editShader(ShaderType,int,std::string); + void setMat4(glm::mat4, std::string); + void setVec4(Vector4, std::string); + void setVec3(Vector3, std::string); + void setVec2(Vector2, std::string); + void setFloat(float, std::string); + void setBool(bool, std::string); + void setInt(int, std::string); + void editShader(ShaderType, int, std::string); private: + void initShaders(std::string, std::string, std::string); + void replaceLine(ShaderType, int, std::string); void loadShaders(); - void checkCompileErrors(unsigned int,ErrorType); + void pushShader(u32&, std::string&, int, ErrorType); + void checkCompileErrors(u32, ErrorType); unsigned int id; - bool geometry=false; - std::string vString,fString,gString; + bool geometry = false; + std::string vString, fString, gString; }; } diff --git a/texture.cpp b/texture.cpp index 17eb945..2180f88 100755 --- a/texture.cpp +++ b/texture.cpp @@ -9,113 +9,111 @@ using namespace std; namespace vb01{ Texture::Texture(int width, int height, bool shadowMap){ - this->width=width; - this->height=height; - texture=new u32; + this->width = width; + this->height = height; + texture = new u32; - glGenTextures(1,&texture[0]); - glBindTexture(GL_TEXTURE_2D,texture[0]); + glGenTextures(1, &texture[0]); + glBindTexture(GL_TEXTURE_2D, texture[0]); if(shadowMap){ - glTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT,width,height,0,GL_DEPTH_COMPONENT,GL_FLOAT,NULL); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_BORDER); - float borderColor[]={1,1,1,1}; - glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_BORDER_COLOR,borderColor); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + float borderColor[] = {1, 1, 1, 1}; + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor); } else{ - glTexImage2D(GL_TEXTURE_2D,0,GL_RGB16F,width,height,0,GL_RGB,GL_FLOAT,NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, NULL); //glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA16F,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); + 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 path[],int numPaths,int updateRate,bool flip){ - this->numFrames=numPaths; - this->updateRate=updateRate; + Texture::Texture(string path[], int numPaths, int updateRate, bool flip){ + this->numFrames = numPaths; + this->updateRate = updateRate; - texture=new u32[numPaths]; + texture = new u32[numPaths]; - for(int i=0;itype=TextureType::TEXTURE_CUBEMAP; - texture=new u32; - - glGenTextures(1,&texture[0]); - glBindTexture(GL_TEXTURE_CUBE_MAP,texture[0]); - - stbi_set_flip_vertically_on_load(flip); - - for(int i=0;i<6;i++){ - data=stbi_load(paths[i].c_str(),&width,&height,&numChannels,0); - if(data){ - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+i,0,GL_RGB,width,height,0,GL_RGB,GL_UNSIGNED_BYTE,data); - stbi_image_free(data); - } - else{ - cout<<"Failed to read cubemap texture "<type = TextureType::TEXTURE_CUBEMAP; + texture = new u32; + createCubemap(flip); } - Texture::Texture(int width,bool depth){ - this->width=width; - this->type=TextureType::TEXTURE_CUBEMAP; - texture=new u32; + Texture::Texture(int width, bool depth){ + this->width = width; + this->type = TextureType::TEXTURE_CUBEMAP; + texture = new u32; - glGenTextures(1,&texture[0]); - glBindTexture(GL_TEXTURE_CUBE_MAP,texture[0]); + createCubemap(false); + } - for(int i=0;i<6;i++) - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+i,0,depth?GL_DEPTH_COMPONENT:GL_RGB,width,width,0,depth?GL_DEPTH_COMPONENT:GL_RGB,GL_FLOAT,NULL); - - glTexParameteri(GL_TEXTURE_CUBE_MAP,GL_TEXTURE_MIN_FILTER,GL_NEAREST); - glTexParameteri(GL_TEXTURE_CUBE_MAP,GL_TEXTURE_MAG_FILTER,GL_NEAREST); - 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); + void Texture::createCubemap(bool flip){ + glGenTextures(1, &texture[0]); + glBindTexture(GL_TEXTURE_CUBE_MAP, texture[0]); + if(flip) + stbi_set_flip_vertically_on_load(flip); + + for(int i = 0; i < 6; i++){ + if(flip){ + data = stbi_load(paths[i].c_str(), &width, &height, &numChannels, 0); + if(data){ + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); + stbi_image_free(data); + } + else{ + cout<<"Failed to read cubemap texture "<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); + ); + 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(){ - glBindTexture(type==TEXTURE_2D?GL_TEXTURE_2D:GL_TEXTURE_CUBE_MAP,0); - if(numFrames>0){ - for(int i=0;i 0){ + for(int i = 0; i < numFrames; i++) + glDeleteTextures(1, &texture[i]); delete[] texture; } else{ - glDeleteTextures(1,&texture[0]); + glDeleteTextures(1, &texture[0]); delete texture; } } - void Texture::select(int id){ - glActiveTexture(GL_TEXTURE0+id); - glBindTexture(type==TEXTURE_2D?GL_TEXTURE_2D:GL_TEXTURE_CUBE_MAP,texture[numFrames>0?frame:0]); - } - void Texture::update(int id){ - if(numFrames>0){ - if(getTime()-lastUpdateTime>updateRate){ - frame++; - if(frame==numFrames) - frame=0; - lastUpdateTime=getTime(); - } - } + updateFrame(); select(id); } + + void Texture::updateFrame(){ + if(numFrames > 0){ + if(getTime() - lastUpdateTime > updateRate){ + frame++; + if(frame == numFrames) + frame = 0; + lastUpdateTime = getTime(); + } + } + } + + void Texture::select(int id){ + glActiveTexture(GL_TEXTURE0 + id); + glBindTexture(type == TEXTURE_2D ? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP, texture[numFrames > 0 ? frame : 0]); + } } diff --git a/texture.h b/texture.h index 78022f9..dd2576f 100755 --- a/texture.h +++ b/texture.h @@ -9,27 +9,31 @@ namespace vb01{ class Texture{ public: - enum TextureType{TEXTURE_2D,TEXTURE_CUBEMAP}; + enum TextureType{TEXTURE_2D, TEXTURE_CUBEMAP}; + enum TextureTypeId{DIFFUSE, NORMAL, SPECULAR, PARALLAX, ENVIRONMENT}; ~Texture(); - Texture(int,int,bool=true); - Texture(std::string[],int,int=0,bool=false); - Texture(std::string[6],bool=false); - Texture(int,bool=true); - Texture(FT_Face&,char); - void select(int=0); - void update(int=0); - inline unsigned int* getTexture(int i=0){return &(texture[i]);} + Texture(int, int, bool = true); + Texture(std::string[], int, int = 0, bool = false); + Texture(std::string[6], bool = false); + Texture(int, bool = true); + Texture(FT_Face&, char); + void select(int = 0); + void update(int = 0); + inline unsigned int* getTexture(int i = 0){return &(texture[i]);} inline std::string getPath(){return path;} private: - TextureType type=TextureType::TEXTURE_2D; - u32 *texture=nullptr; - s32 updateRate=0,numFrames=0,frame=0; - s64 lastUpdateTime=0; - int width,height,numChannels; + TextureType type = TextureType::TEXTURE_2D; + u32 *texture = nullptr; + s32 updateRate = 0, numFrames = 0,frame = 0; + s64 lastUpdateTime = 0; + int width, height, numChannels; float weight; u8 *data; - std::string path="",paths[6]; + std::string path = "", paths[6]; + + void createCubemap(bool); + void updateFrame(); }; }