mirror of
https://github.com/ApfelTeeSaft/vb01.git
synced 2026-08-26 19:33:45 +00:00
rendering classes refactoring
This commit is contained in:
@@ -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<Node*> descendants;
|
||||
vector<Light*> lights;
|
||||
rootNode->getDescendants(rootNode, descendants);
|
||||
@@ -79,98 +82,112 @@ namespace vb01{
|
||||
|
||||
void Light::renderShadow(std::vector<Node*> 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<Mesh*> meshes=n->getMeshes();
|
||||
vector<Mesh*> 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],1<j&&j<4?vec3(0,0,-1):vec3(0,-1,0)),"shadowMat["+to_string(j)+"]");
|
||||
}
|
||||
else{
|
||||
depthMapShader->setMat4(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<Material*> 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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user