#include"root.h" #include"node.h" #include"mesh.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){ this->vertices=vertices; this->indices=indices; this->numTris=numTris; construct(); } Mesh::~Mesh(){} void Mesh::construct(){ glGenVertexArrays(1,&VAO); glGenBuffers(1,&VBO); glGenBuffers(1,&EBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER,VBO); glBufferData(GL_ARRAY_BUFFER, 3*numTris*sizeof(Vertex),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); glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,sizeof(Vertex),(void*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,sizeof(Vertex),(void*)(offsetof(Vertex,norm))); glEnableVertexAttribArray(1); glVertexAttribPointer(2,2,GL_FLOAT,GL_FALSE,sizeof(Vertex),(void*)(offsetof(Vertex,texCoords))); glEnableVertexAttribArray(2); } 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; 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(); } pos=origin; camPos=cam->getPosition(); } Vector3 rotAxis=orient.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.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->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(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); } glDrawElements(GL_TRIANGLES,3*numTris,GL_UNSIGNED_INT,0); } }