diff --git a/CMakeLists.txt b/CMakeLists.txt index ac14b28..51a5bd3 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ link_directories(/usr/lib/) set(CMAKE_BUILD_TYPE Debug) set(gui text.cpp rectangle.cpp) set(utils util.cpp) -set(math quaternion.cpp vector.cpp ray.cpp) +set(math quaternion.cpp vector.cpp matrix.cpp ray.cpp) set(render waterPlane.cpp particleEmitter.cpp camera.cpp light.cpp material.cpp mesh.cpp model.cpp node.cpp quad.cpp box.cpp root.cpp shader.cpp texture.cpp) set(armature skeleton.cpp bone.cpp) diff --git a/camera.h b/camera.h index ca79654..b734041 100755 --- a/camera.h +++ b/camera.h @@ -19,7 +19,7 @@ namespace vb01{ inline float getNearPlane(){return nearPlane;} inline float getFarPlane(){return farPlane;} private: - Vector3 position=Vector3(0,0,0),direction=Vector3(0,0,1),left=Vector3(1,0,0),up=Vector3(0,1,0); + Vector3 position=Vector3(0,0,0),direction=Vector3(0,0,-1),left=Vector3(1,0,0),up=Vector3(0,1,0); float fov=45,nearPlane=.1,farPlane=100; }; } diff --git a/light.cpp b/light.cpp index 712116c..d9d39d3 100755 --- a/light.cpp +++ b/light.cpp @@ -48,36 +48,14 @@ namespace vb01{ Node *rootNode=root->getRootNode(); Camera *cam=root->getCamera(); std::vector descendants; + std::vector materials; rootNode->getDescendants(rootNode,descendants); descendants.push_back(rootNode); - std::vector materials; int numLights=0,thisId=-1; + float fov=cam->getFov(),width=root->getWidth(),height=root->getHeight(); - vec3 dir=vec3(direction.x,direction.y,direction.z); - vec3 pos=type==DIRECTIONAL?-.5f*farPlane*dir:vec3(position.x,position.y,position.z); - mat4 view=lookAt(pos,pos+dir,vec3(0,1,0)); - mat4 proj=ortho(-10.f,10.f,-10.f,10.f,nearPlane,farPlane); - - depthMapShader->use(); - depthMapShader->setMat4(proj*view,"lightMat"); - - glViewport(0,0,depthMapSize,depthMapSize); - glBindFramebuffer(GL_FRAMEBUFFER,depthmapFBO); - for(Node *n : descendants){ - std::vector lights=n->getLights(); - vector meshes=n->getMeshes(); - for(Mesh *mesh : meshes){ - Material *mat=mesh->getMaterial(); - if(mat&&mat->isLightingEnabled()){ - materials.push_back(mat); - if(mesh->isCastShadow()){ - Vector3 pos=n->getPosition(); - mat4 model=translate(mat4(1.f),vec3(pos.x,pos.y,pos.z)); - depthMapShader->setMat4(model,"model"); - mesh->render(); - } - } - } + for(Node *d : descendants){ + std::vector lights=d->getLights(); for(Light *l : lights){ if(l){ numLights++; @@ -85,41 +63,91 @@ namespace vb01{ thisId=numLights-1; } } + for(Mesh *m : d->getMeshes()) + materials.push_back(m->getMaterial()); } - glBindFramebuffer(GL_FRAMEBUFFER,0); + for(int i=0;i meshes=n->getMeshes(); + for(Mesh *mesh : meshes){ + Material *mat=mesh->getMaterial(); + if(n->isVisible()&&mat&&mat->isLightingEnabled()){ + mat4 proj,view; + if(mesh->isCastShadow()){ + Vector3 pos=n->getWorldPosition(); + Quaternion rot=n->getWorldOrientation(); + Vector3 rotAxis=rot.norm().getAxis(); - glViewport(0,0,root->getWidth(),root->getHeight()); + if(rotAxis==Vector3::VEC_ZERO) + rotAxis=Vector3::VEC_I; - for(Material *m : materials){ - Shader *shader=m->getShader(); - shader->use(); - shader->setInt((int)type,"light["+to_string(thisId)+"].type"); - shader->setVec3(color,"light["+to_string(thisId)+"].color"); - shader->setInt(0,"tex"); - shader->setInt(thisId+1,"light["+to_string(thisId)+"].depthMap"); - depthMap->select(thisId+1); + glViewport(0,0,depthMapSize,depthMapSize); + glBindFramebuffer(GL_FRAMEBUFFER,depthmapFBO); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - 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"); - break; - case DIRECTIONAL: - 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"); - break; + Vector3 upDir=direction.cross(Vector3(0,1,0)); + if(upDir==Vector3(0,0,0)) + 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=ortho(-10.f,10.f,-10.f,10.f,nearPlane,farPlane); + + depthMapShader->use(); + depthMapShader->setMat4(proj*view,"lightMat"); + + 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->setMat4(model,"model"); + mesh->render(); + + glBindFramebuffer(GL_FRAMEBUFFER,*(root->getFBO())); + glViewport(0,0,root->getWidth(),root->getHeight()); + + /* + for(Material *m : materials){ + Shader *shader=m->getShader(); + shader->use(); + shader->setInt(1+2*thisId+i,"light["+to_string(thisId)+"].depthMap["+to_string(i)+"]"); + depthMap->select(1+2*thisId+i); + } + */ + } + for(Material *m : materials){ + Shader *shader=m->getShader(); + shader->use(); + shader->setInt((int)type,"light["+to_string(thisId)+"].type"); + shader->setVec3(color,"light["+to_string(thisId)+"].color"); + shader->setInt(0,"tex"); + shader->setInt(1,"light["+to_string(thisId)+"].depthMap["+to_string(0)+"]"); + depthMap->select(1); + + 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"); + break; + case DIRECTIONAL: + 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"); + break; + } + } + } } } } diff --git a/matrix.cpp b/matrix.cpp new file mode 100644 index 0000000..1f88ade --- /dev/null +++ b/matrix.cpp @@ -0,0 +1,191 @@ +#include"matrix.h" +#include + +using namespace std; + +namespace vb01{ + Matrix::Matrix(float **matrix,int rows,int columns){ + this->dim[0]=rows; + this->dim[1]=columns; + + this->matrix=new float*[rows]; + for(int i=0;imatrix[i]=new float[columns]; + for(int j=0;jmatrix[i][j]=matrix[i][j]; + } + } + + Matrix::Matrix(Vector3 v1,Vector3 v2,Vector3 v3){ + dim[0]=3; + dim[1]=3; + + matrix=new float*[3]; + + matrix[0]=new float[3]; + matrix[0][0]=v1.x; + matrix[0][1]=v1.y; + matrix[0][2]=v1.z; + matrix[1]=new float[3]; + matrix[1][0]=v2.x; + matrix[1][1]=v2.y; + matrix[1][2]=v2.z; + matrix[2]=new float[3]; + matrix[2][0]=v3.x; + matrix[2][1]=v3.y; + matrix[2][2]=v3.z; + } + + Matrix& Matrix::operator+(Matrix &m){ + if(dim[0]==m.dim[0]&&dim[1]==m.dim[1]){ + for(int i=0;imatrix[i][k]*m.matrix[k][j]; + return Matrix(matrix,dim[0],dim[1]); + } + else{ + cout<<"Incompatible matrix dimensions for multiplication.\n"; + exit(-1); + } + } + + Vector3 Matrix::operator* (Vector3 v){ + float **matrix=new float*[3]; + matrix[0]=new float[1]; + matrix[0][0]=v.x; + matrix[1]=new float[1]; + matrix[1][0]=v.y; + matrix[2]=new float[1]; + matrix[2][0]=v.z; + + Matrix vMat(matrix,3,1); + vMat=(*this)*vMat; + return Vector3(vMat[0][0],vMat[1][0],vMat[2][0]); + } + + template Matrix& Matrix::operator+(T s){ + for(int i=0;i Matrix& Matrix::operator-(T s){ + for(int i=0;i Matrix& Matrix::operator*(T s){ + for(int i=0;i Matrix& Matrix::operator/(T s){ + for(int i=0;imatrix[j][i]; + this->matrix=matrix; + } + + Matrix Matrix::getSubMatrix(int row,int column){ + int newRows=dim[0]-1,newColumns=dim[1]-1; + float **matrix=new float*[dim[0]]; + bool offsetRows=false,offsetColumns=false; + for(int i=0;imatrix[i][j]; + } + else if(i==row) offsetRows=true; + else if(j==column) offsetColumns=true; + } + return Matrix(matrix,newRows,newColumns); + } + + void Matrix::invert(){ + transpose(); + float **matrix=new float*[dim[0]]; + for(int i=0;imatrix=matrix; + *this/getDeterminant(); + } + + float Matrix::getMinor(int row,int column){ + return getSubMatrix(row,column).getDeterminant(); + } + + float Matrix::getCofactor(int row,int column){ + return ((row+column+2)%2==0?1:-1)*getMinor(row,column); + } + + float Matrix::getDeterminant(){ + if(dim[0]!=dim[1]){ + cout<<"Matrix not square.\n"; + exit(-1); + } + if(dim[0]==1) + return matrix[0][0]; + else if(dim[0]==2) + return matrix[0][0]*matrix[1][1]-matrix[1][0]*matrix[0][1]; + else{ + float det=0; + for(int i=0;i Matrix& operator+ (T); + template Matrix& operator- (T); + template Matrix& operator* (T); + template Matrix& operator/ (T); + void transpose(); + Matrix getSubMatrix(int,int); + void invert(); + float getMinor(int,int); + float getCofactor(int,int); + float getDeterminant(); + }; +} + +#endif diff --git a/mesh.cpp b/mesh.cpp index bc82459..747ce26 100755 --- a/mesh.cpp +++ b/mesh.cpp @@ -66,27 +66,10 @@ namespace vb01{ Quaternion orient=Quaternion::QUAT_W; if(node){ - Vector3 origin=Vector3::VEC_ZERO,axis[]={Vector3::VEC_I,Vector3::VEC_J,Vector3::VEC_K}; - vector ancestors; - ancestors.push_back(node); - Node *parent=node->getParent(); - while(parent){ - ancestors.push_back(parent); - parent=parent->getParent(); - } - while(!ancestors.empty()){ - int id=ancestors.size()-1; - Quaternion o=ancestors[id]->getOrientation(); - Vector3 p=ancestors[id]->getPosition(),s=ancestors[id]->getScale(); - origin=origin+axis[0]*p.x*s.x+axis[1]*p.y*s.y+axis[2]*p.z*s.z; - orient=o*orient; - scale=s; - for(int i=0;i<3;i++) - axis[i]=orient*axis[i]; - ancestors.pop_back(); - } + Node::Transform t=node->getWorldTransform(); - pos=origin; + pos=t.position; + orient=t.orientation; camPos=cam->getPosition(); } @@ -125,6 +108,7 @@ namespace vb01{ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO); glBufferSubData(GL_ELEMENT_ARRAY_BUFFER,0,3*numTris*sizeof(unsigned int),indices); } + 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 e4acfb1..5995954 100755 --- a/mesh.h +++ b/mesh.h @@ -31,6 +31,7 @@ namespace vb01{ 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 setWireframe(bool w){this->wireframe=w;} inline Node* getNode(){return node;} inline Material* getMaterial(){return material;} inline std::vector& getMeshes(){return meshes;} @@ -48,7 +49,7 @@ namespace vb01{ Mesh(); void construct(); - bool staticVerts=true,castShadow=false; + bool staticVerts=true,castShadow=false,wireframe=false; Vertex *vertices; VertexGroup groups; unsigned int *indices,VAO,VBO,EBO; diff --git a/model.cpp b/model.cpp index 9165de0..6c2a7d8 100755 --- a/model.cpp +++ b/model.cpp @@ -213,9 +213,20 @@ namespace vb01{ } void Model::setCastShadow(bool castShadow){ - for(Node *node : children) + vector descendants; + getDescendants(this,descendants); + for(Node *node : descendants) for(Mesh *mesh : node->getMeshes()) mesh->setCastShadow(castShadow); this->castShadow=castShadow; } + + void Model::setWireframe(bool wirefame){ + vector descendants; + getDescendants(this,descendants); + for(Node *node : descendants) + for(Mesh *mesh : node->getMeshes()) + mesh->setWireframe(wirefame); + this->wireframe=wireframe; + } } diff --git a/model.h b/model.h index e322066..471c431 100755 --- a/model.h +++ b/model.h @@ -22,6 +22,7 @@ namespace vb01{ void update(); void setMaterial(Material*); void setCastShadow(bool); + void setWireframe(bool); private: void processNode(aiNode*, const aiScene*, Node*); void processMesh(aiMesh*, const aiScene*, Node*); @@ -29,7 +30,7 @@ namespace vb01{ void processMaterial(); Material* material; - bool castShadow=false; + bool castShadow=false,wireframe=false; }; } diff --git a/node.cpp b/node.cpp index a78c299..03afe69 100755 --- a/node.cpp +++ b/node.cpp @@ -5,6 +5,7 @@ #include"light.h" #include"text.h" #include"material.h" +#include"matrix.h" using namespace std; @@ -112,11 +113,15 @@ namespace vb01{ text->setNode(this); } - void Node::lookAt(Vector3 newDir){ - Vector3 dir=getLocalAxis(0).norm(); - float angle=dir.getAngleBetween(newDir.norm()); - Vector3 rotAxis=dir.cross(newDir.norm()); + void Node::lookAt(Vector3 newDir,Vector3 upDir){ + Vector3 dir=getLocalAxis(2).norm(),newDirLocal=globalToLocal(newDir.norm()),upDirLocal=globalToLocal(upDir.norm()); + float angle=dir.getAngleBetween(newDirLocal); + Vector3 rotAxis=dir.cross(newDirLocal); orientation=Quaternion(angle,rotAxis)*orientation; + Vector3 up=getLocalAxis(1).norm(); + angle=up.getAngleBetween(upDirLocal); + rotAxis=up.cross(upDirLocal); + orientation=Quaternion(angle,rotAxis.norm())*orientation; } void Node::getDescendants(Node *node, vector &descendants){ @@ -182,4 +187,56 @@ namespace vb01{ return axis[i]; } + + Vector3 Node::localToGlobal(Vector3 p0){ + Vector3 dir=getLocalAxis(2),up=getLocalAxis(1),left=getLocalAxis(0); + float **mat=new float*[3]; + for(int i=0;i<3;i++) + mat[i]=new float[3]; + + mat[0][0]=left.x; + mat[1][0]=left.y; + mat[2][0]=left.z; + mat[0][1]=up.x; + mat[1][1]=up.y; + mat[2][1]=up.z; + mat[0][2]=dir.x; + mat[1][2]=dir.y; + mat[2][2]=dir.z; + + Vector3 p=Matrix(mat,3,3)*p0; + + for(int i=0;i<3;i++) + delete[] mat[i]; + delete[] mat; + + return p; + } + + Vector3 Node::globalToLocal(Vector3 p0){ + Vector3 dir=getLocalAxis(2),up=getLocalAxis(1),left=getLocalAxis(0); + float **mat=new float*[3]; + for(int i=0;i<3;i++) + mat[i]=new float[3]; + + mat[0][0]=left.x; + mat[1][0]=left.y; + mat[2][0]=left.z; + mat[0][1]=up.x; + mat[1][1]=up.y; + mat[2][1]=up.z; + mat[0][2]=dir.x; + mat[1][2]=dir.y; + mat[2][2]=dir.z; + + Matrix m(mat,3,3); + m.invert(); + Vector3 p=m*p0; + + for(int i=0;i<3;i++) + delete[] mat[i]; + delete[] mat; + + return p; + } } diff --git a/node.h b/node.h index 2f4cd2a..36da0a3 100755 --- a/node.h +++ b/node.h @@ -28,9 +28,11 @@ namespace vb01{ void dettachChild(Node*); void addLight(Light*); void addText(Text*); - void lookAt(Vector3); + void lookAt(Vector3,Vector3); Transform getWorldTransform(); Vector3 getLocalAxis(int); + Vector3 localToGlobal(Vector3); + Vector3 globalToLocal(Vector3); inline Text* getText(int i){return texts[i];} inline Vector3 getWorldPosition(){return getWorldTransform().position;} inline Quaternion getWorldOrientation(){return getWorldTransform().orientation;} diff --git a/particle.frag b/particle.frag index 510dd0b..716b66e 100755 --- a/particle.frag +++ b/particle.frag @@ -7,10 +7,10 @@ flat in int id; out vec4 FragColor; uniform sampler2D tex; -uniform vec4 color[100]; +uniform vec4 color[200]; void main(){ - float alpha=texture(tex,texCoords).x; + float alpha=texture(tex,texCoords).r; vec4 c=color[id]; //FragColor=vec4(1,0,0,1); FragColor=vec4(c.x,c.y,c.z,c.w*alpha); diff --git a/particle.vert b/particle.vert index b978d45..918eb40 100755 --- a/particle.vert +++ b/particle.vert @@ -9,8 +9,8 @@ flat out int id; uniform mat4 proj; uniform mat4 view; -uniform mat4 model[100]; -uniform vec2 size[100]; +uniform mat4 model[200]; +uniform vec2 size[200]; void main(){ vec3 camLeft=vec3(view[0][0],view[1][0],view[2][0]); diff --git a/particleEmitter.cpp b/particleEmitter.cpp index f1b83bf..7a41cde 100755 --- a/particleEmitter.cpp +++ b/particleEmitter.cpp @@ -89,6 +89,10 @@ namespace vb01{ shader->setMat4(view,"view"); shader->setMat4(proj,"proj"); + Vector3 nodePos=node->getWorldTransform().position; + Vector3 nodeDir=node->getLocalAxis(2); + Vector3 nodeUp=node->getLocalAxis(1); + Vector3 nodeLeft=node->getLocalAxis(0); for(int i=0;i=particles[i].timeToLive){ @@ -99,9 +103,10 @@ namespace vb01{ dir=Quaternion(s1,ra1)*dir; dir=Quaternion(s2,ra2)*dir; particles[i].timeToLive=s64(1000*((highLife-lowLife)*factor+lowLife)); - particles[i].mat=mat4(1.f); + particles[i].mat=translate(mat4(1.f),vec3(nodePos.x,nodePos.y,nodePos.z)); } - particles[i].dir=dir.norm()*direction.getLengthSq(); + //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; @@ -126,8 +131,10 @@ namespace vb01{ shader->setVec2(particles[i].size,"size["+to_string(i)+"]"); } + glDisable(GL_CULL_FACE); glBindVertexArray(VAO); glDrawElementsInstanced(GL_TRIANGLES,6,GL_UNSIGNED_INT,0,numParticles); + glEnable(GL_CULL_FACE); } void ParticleEmitter::setDirection(Vector3 dir){ diff --git a/particleEmitter.h b/particleEmitter.h index 8eb7dfa..bfb871d 100755 --- a/particleEmitter.h +++ b/particleEmitter.h @@ -22,6 +22,11 @@ namespace vb01{ 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); private: struct Vertex{ @@ -42,7 +47,7 @@ namespace vb01{ Material *material=nullptr; Node *node=nullptr; Vector2 startSize=Vector2::VEC_IJ,endSize=Vector2::VEC_IJ; - Vector3 direction=Vector3(0,.1,0); + Vector3 direction=Vector3(0,.1,0),gravity=Vector3::VEC_ZERO; Vector4 startColor,endColor; float spread=1,lowLife=1,highLife=2; }; diff --git a/ray.cpp b/ray.cpp index 5614a2e..b8de292 100644 --- a/ray.cpp +++ b/ray.cpp @@ -37,8 +37,8 @@ namespace vb01{ Vector3 bisecCVec=((pointB-pointC)+(pointA-pointC)); bool withinBisecA=(contactPoint-pointA).norm().getAngleBetween(bisecAVec.norm())<=angleA/2; bool withinBisecB=(contactPoint-pointB).norm().getAngleBetween(bisecBVec.norm())<=angleB/2; - //bool withinBisecC=(contactPoint-pointC).norm().getAngleBetween(bisecCVec.norm())<=angleC/2; - if(withinBisecA&&withinBisecB){ + bool withinBisecC=(contactPoint-pointC).norm().getAngleBetween(bisecCVec.norm())<=angleC/2; + if(withinBisecA&&withinBisecB&&withinBisecC){ CollisionResult result; result.pos=contactPoint; result.distance=distance; diff --git a/root.cpp b/root.cpp index 0f89cd5..d4f1d10 100755 --- a/root.cpp +++ b/root.cpp @@ -41,19 +41,19 @@ namespace vb01{ glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE); window=glfwCreateWindow(width,height,"KEK",NULL,NULL); if(window==NULL){ - std::cout<<"KEK\n"; + std::cout<<"Failed to load window.\n"; exit(-1); } glfwMakeContextCurrent(window); glfwSetFramebufferSizeCallback(window,foo); if(!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){ - std::cout<<"KEK2\n"; + std::cout<<"Failed to load GLAD.\n"; exit(-1); } glEnable(GL_DEPTH_TEST); glEnable(GL_STENCIL_TEST); - //glEnable(GL_CULL_FACE); - //glCullFace(GL_BACK); + glEnable(GL_CULL_FACE); + glCullFace(GL_FRONT); glDepthMask(GL_TRUE); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); @@ -82,30 +82,30 @@ namespace vb01{ } void Root::update(){ + glBindFramebuffer(GL_FRAMEBUFFER,FBO); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - - //glBindFramebuffer(GL_FRAMEBUFFER,FBO); glEnable(GL_DEPTH_TEST); - //glEnable(GL_CULL_FACE); + glEnable(GL_CULL_FACE); if(skybox){ glDepthMask(GL_FALSE); - //glCullFace(GL_BACK); + glCullFace(GL_BACK); skybox->update(); glDepthMask(GL_TRUE); - //glCullFace(GL_FRONT); + glCullFace(GL_FRONT); } 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_CULL_FACE); glDisable(GL_DEPTH_TEST); - //guiPlane->update(); + guiPlane->update(); /* */ glEnable(GL_DEPTH_TEST); diff --git a/root.h b/root.h index 3a82c07..da2d254 100755 --- a/root.h +++ b/root.h @@ -25,6 +25,7 @@ namespace vb01{ inline Node* getGuiNode(){return guiNode;} inline int getWidth(){return width;} inline int getHeight(){return height;} + inline unsigned int* getFBO(){return &FBO;} inline GLFWwindow* getWindow(){return window;} void createSkybox(std::string[6]); static Root* getSingleton(); diff --git a/texture.cpp b/texture.cpp index 6a36e4b..e629ace 100755 --- a/texture.cpp +++ b/texture.cpp @@ -8,7 +8,6 @@ using namespace std; namespace vb01{ - Texture::Texture(int width, int height, bool shadowMap){ this->width=width; this->height=height; @@ -69,6 +68,8 @@ namespace vb01{ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + //stbi_set_flip_vertically_on_load(true); + data=stbi_load(path.c_str(),&width,&height,&numChannels,0); glTexImage2D(GL_TEXTURE_2D,0,png?GL_RGBA:GL_RGB,width,height,0,png?GL_RGBA:GL_RGB,GL_UNSIGNED_BYTE,data); @@ -81,6 +82,7 @@ namespace vb01{ glGenTextures(1,&texture); glBindTexture(GL_TEXTURE_CUBE_MAP,texture); + for(int i=0;i<6;i++){ data=stbi_load(paths[i].c_str(),&width,&height,&numChannels,0); if(data){ diff --git a/texture.frag b/texture.frag index 9a5fbc8..cf6d20a 100755 --- a/texture.frag +++ b/texture.frag @@ -1,6 +1,7 @@ #version 330 core const int numLights=1; +const int numShadows=1; in vec3 fragPos; in vec3 norm; @@ -16,7 +17,7 @@ struct Light{ vec3 pos,color,direction; float innerAngle,outerAngle; float a,b,c; - sampler2D depthMap; + sampler2D depthMap[numShadows]; mat4 lightMat; }; @@ -28,10 +29,10 @@ uniform bool castShadow; uniform vec4 diffuseColor; uniform vec3 camPos; -float getShadow(int id){ +float getShadow(int id,int shadowId){ vec3 projCoords=(light[id].lightMat*vec4(fragPos,1)).xyz/(light[id].lightMat*vec4(fragPos,1)).w; projCoords=projCoords*.5+.5; - float closestDepth=texture(light[id].depthMap,projCoords.xy).r; + float closestDepth=texture(light[id].depthMap[shadowId],projCoords.xy).r; float currentDepth=projCoords.z; float bias=.005; return currentDepth-bias>closestDepth?.7:0; @@ -76,10 +77,11 @@ void main(){ diffuseColor+=light[i].color*(factor*attenuation*coef); } - for(int i=0;i