#include"root.h" #include"node.h" #include"box.h" #include"texture.h" #include"skeleton.h" #include #include #include #include #include #include using namespace std; 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; construct(); } Mesh::~Mesh(){ for(Mesh *m : meshes) delete m; if(material) delete material; glDeleteVertexArrays(1,&VAO); glDeleteBuffers(1,&EBO); glDeleteBuffers(1,&VBO); delete[] indices; delete[] vertices; } void Mesh::construct(){ 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); glGenFramebuffers(1,&environmentBuffer); glBindFramebuffer(GL_FRAMEBUFFER,environmentBuffer); glFramebufferTexture(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,*(environmentMap->getTexture()),0); /* glGenRenderbuffers(1,&RBO); glBindRenderbuffer(GL_RENDERBUFFER,RBO); glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH24_STENCIL8,width,width); 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); glGenVertexArrays(1,&VAO); glGenBuffers(1,&VBO); glGenBuffers(1,&EBO); u32 base=sizeof(float); u32 size=(14+3*numShapeKeys)*base; size=sizeof(Vertex); //size=(18)*sizeof(float)+sizeof(Vector3*); //cout<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(); } if(reflect){ glViewport(0,0,width,width); glBindFramebuffer(GL_FRAMEBUFFER,environmentBuffer); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 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) }; environmentShader->use(); Node *rootNode=root->getRootNode(); vector 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(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],1render(); } } glBindFramebuffer(GL_FRAMEBUFFER,*(root->getFBO())); glViewport(0,0,root->getWidth(),root->getHeight()); } Vector3 rotAxis=orient.norm().getAxis(); if(rotAxis==Vector3::VEC_ZERO) rotAxis=Vector3::VEC_I; mat4 model=translate(mat4(1.),vec3(pos.x,pos.y,pos.z)); model=rotate(model,orient.norm().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->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(skeleton){ 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++){ Bone *bone = skeleton->getBone(i), *parent = (Bone*)bone->getParent(); Vector3 boneAxis[]{ bone->getInitAxis(0), bone->getInitAxis(1), bone->getInitAxis(2) }; Vector3 posePos = bone->getPosePos(); Quaternion poseRot = bone->getPoseRot(); Vector3 trans = boneAxis[0]*posePos.x+boneAxis[1]*posePos.y+boneAxis[2]*posePos.z; Vector3 scale = bone->getPoseScale(); Vector3 bonePos = (bone->getRestPos()); //bonePos = modelNode->globalToLocalPosition(bonePos); int vertGroupId = -1,parentId = -1; for(int j=0;jgetName() == vertexGroups[j]) vertGroupId = 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"); } } if(reflect){ shader->setBool(reflect,"environmentMapEnabled"); root->getSkybox()->getMaterial()->getDiffuseMap(0)->select(4); environmentMap->select(4); } if(material->getType()==Material::MATERIAL_GUI){ shader->setVec2(Vector2((float)width,(float)height),"screen"); if(node) shader->setVec3(pos,"pos"); } render(); } 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); } glPolygonMode(GL_FRONT_AND_BACK,wireframe?GL_LINE:GL_FILL); glDrawElements(GL_TRIANGLES,3*numTris,GL_UNSIGNED_INT,0); } }