// THIS IS THE INITIALIZATION FUNCTION
void createCubeShadowFBO(GLuint &fboHandle, GLuint &depthTex, GLsizei resx,GLsizei resy ){
glGenFramebuffers(1,&fboHandle);
//cube texture
glGenTextures(1,&shadowMap);
glBindTexture(GL_TEXTURE_CUBE_MAP, shadowMap);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
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);
for (int i = 0; i < 6; i++) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_R32F, resx, resy, 0, GL_RED, GL_FLOAT, 0);
}
glBindFramebuffer(GL_FRAMEBUFFER, fboHandle);
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_TEXTURE_2D,depthTex,0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
};
////RENDER GAME LOOP
targetPosition[0] = lightPosition[0];
targetPosition[1] = lightPosition[1];
targetPosition[2] = lightPosition[2];
//cubemap positions
glEnable(GL_TEXTURE_CUBE_MAP);
glEnable(GL_DEPTH_TEST);
glViewport(0, 0, (GLint)widths, (GLint) heights);
glCullFace(GL_FRONT);
for(int i = 0; i<6;i++){ // for each render, first bind the FBO to make it current, then bind the face to the first color attachment to enable writing
if(i==0){ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, shadowFBO); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X, shadowMap, 0); glDrawBuffer(GL_COLOR_ATTACHMENT0);
cam2.positionCam( targetPosition[0]+1, targetPosition[1], targetPosition[2], lightPosition[0], lightPosition[1],lightPosition[2], 0,1,0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);} // x+
if(i==1){ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, shadowFBO); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, shadowMap, 0);glDrawBuffer(GL_COLOR_ATTACHMENT0);
cam2.positionCam( targetPosition[0]-1, targetPosition[1], targetPosition[2], lightPosition[0], lightPosition[1],lightPosition[2], 0,1,0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);} // x-
if(i==2){glBindFramebuffer(GL_DRAW_FRAMEBUFFER, shadowFBO); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, shadowMap, 0);glDrawBuffer(GL_COLOR_ATTACHMENT0);
cam2.positionCam( targetPosition[0], targetPosition[1]+1, targetPosition[2], lightPosition[0], lightPosition[1],lightPosition[2], -1,0,0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);} // y+
if(i==3){ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, shadowFBO); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, shadowMap, 0);glDrawBuffer(GL_COLOR_ATTACHMENT0);
cam2.positionCam( targetPosition[0], targetPosition[1]-1, targetPosition[2], lightPosition[0], lightPosition[1],lightPosition[2], 1,0,0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);} // y-
if(i==4){ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, shadowFBO); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, shadowMap, 0);glDrawBuffer(GL_COLOR_ATTACHMENT0);
cam2.positionCam( targetPosition[0], targetPosition[1], targetPosition[2]+1, lightPosition[0], lightPosition[1],lightPosition[2], 0,1,0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);} // z+
if(i==5){ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, shadowFBO); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, shadowMap, 0);glDrawBuffer(GL_COLOR_ATTACHMENT0);
cam2.positionCam( targetPosition[0], targetPosition[1], targetPosition[2]-1, lightPosition[0], lightPosition[1],lightPosition[2], 0,1,0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);}// z-
//===========================================RENDER TEAPOT1
loadIdentity();
translate(tt,0, 0);
//translate(0,tt, 0);
rotate(ta,0, 1,0);
glUseProgram(ShaderThreeHandle);setUniformsPhong(cam2);
teapot.draw();
glUseProgram(0);
//========================================RENDER TEAPOT2
loadIdentity();
translate(0,tt, 0);
rotate(ta,0, 1,0);
glUseProgram(ShaderThreeHandle);setUniformsPhong(cam2);
teapot.draw();
glUseProgram(0);
//=========================================RENDER TEAPOT3
loadIdentity();
translate(0,20, tt);
rotate(ta,0, 1,0);
glUseProgram(ShaderThreeHandle);setUniformsPhong(cam2);
teapot.draw();
glUseProgram(0);
//==========================================RENDER GROUND
loadIdentity();
translate(40,0, -251);
glUseProgram(ShaderOneHandle);setUniformsMultiADS(cam2);
ground.draw();
glUseProgram(0);
}
glEnable(GL_TEXTURE_CUBE_MAP);
//=============================================-===========================================================SECOND PASS =============================================
glActiveTexture(GL_TEXTURE0);
glEnable(GL_DEPTH_TEST);
glViewport(0, 0, (GLint) widths, (GLint)heights);
glBindFramebuffer(GL_FRAMEBUFFER,0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//rerender entire scene===============================================
cam1.position.y=100;
cam1.positionCam(cam1.target.x, cam1.target.y, cam1.target.z, cam1.position.x, cam1.position.y, cam1.position.z, 0,1,0);
//===========================================teapot1
loadIdentity();
translate(tt,0, 0);
//translate(0,tt, 0);
rotate(ta,0, 1,0);
glUseProgram(ShaderShadowHandle2);setUniformsShadow2(cam1, lightPosition);
texLoc=glGetUniformLocation(ShaderShadowHandle2,"shadowMap");
glActiveTexture(GL_TEXTURE1);
glUniform1i(texLoc,0);
cross.draw();
glUseProgram(0);
//===========================================teapot2
loadIdentity();
translate(0,tt, 0);
rotate(ta,0, 1,0);
glUseProgram(ShaderShadowHandle2);setUniformsShadow2(cam1, lightPosition);
texLoc=glGetUniformLocation(ShaderShadowHandle2,"shadowMap");
glActiveTexture(GL_TEXTURE0);
glUniform1i(texLoc,0);
cross.draw();
glUseProgram(0);
//===========================================teapot3
loadIdentity();
translate(0,20, tt);
rotate(ta,0, 1,0);
glUseProgram(ShaderShadowHandle2);setUniformsShadow2(cam1, lightPosition);
texLoc=glGetUniformLocation(ShaderShadowHandle2,"shadowMap");
glActiveTexture(GL_TEXTURE0);
glUniform1i(texLoc,0);
cross.draw();
glUseProgram(0);
//===========================================ground1 // if you dont render the ground in the first pass then there are no self shadows on the ground
loadIdentity();
translate(40,0, -251);
glUseProgram(ShaderShadowHandle2);setUniformsShadow2(cam1, lightPosition);
texLoc=glGetUniformLocation(ShaderShadowHandle2,"shadowMap");
glActiveTexture(GL_TEXTURE0);
glUniform1i(texLoc,0);
ground.draw();
glUseProgram(0);
//===========================================sky
loadIdentity();
translate(0,-210,0);
glUseProgram(ShaderEightHandle);setUniformsSkyBox(cam1);
skybox.draw();
glUseProgram(0);
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
//
//=======================================================================================================================
glDisable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_CUBE_MAP);
//lightPosition[1]+=.1;
glGetError();
oldX=mouseX;
oldY=mouseY;
keys();
glutSwapBuffers();
glutPostRedisplay();
//diamond.~Mesh();
};
// VERTEX SHADER
#version 400
layout(location=0) in vec3 position;
layout(location=1) in vec3 normal;
layout(location=2) in vec2 texCoord;
out vec3 normala;
out vec3 worldPosition;
out vec3 worldNorm;
uniform mat4 modelMatrix,projMatrix,viewMatrix;
mat4 modelNorms, normalMatrix;
void main(){
//convert normal position to eye coords
normalMatrix=transpose(inverse(viewMatrix));
modelNorms= transpose(inverse(modelMatrix));
vec4 t= normalMatrix*modelNorms*vec4(normal,1.0);
vec3 normal2= normalize(vec3(t));
normala = normal2;
vec4 pos1 =vec4(position,1);
worldPosition=vec3(pos1);
gl_Position = projMatrix*viewMatrix*modelMatrix* vec4(position,1.0);
worldPosition = vec3(modelMatrix* vec4(position,1));
}
// FRAGMENT SHADER - THE ADS FUNCTION WORKS SCENE RENDERS BUT SHADOWS DONT
in vec3 positiona;
in vec3 normala;
in vec3 worldPosition;
in vec3 worldNorm;
in vec3 lightPosition1;
in vec3 l;
uniform samplerCube shadowMap;
uniform vec3 lightPosition;
uniform vec3 lightIntensity;
uniform float shininess;
uniform vec3 kd;
uniform vec3 ka;
uniform vec3 ks;
#define EPSILON 0.00001
layout(location=0) out vec4 fragColor;
vec3 ads(){
vec3 s = normalize(lightPosition-positiona);
vec3 v = normalize(-positiona);
vec3 r= reflect(-s,normala);// normal times modelviewmatrix
return lightIntensity*(ka+kd*max(dot(s,normala),0.0)+ks*pow(max(dot(r,v),0.0),shininess));}
float calcShadowFactor(vec3 LightDirection)
{ float SampledDistance = texture(shadowMap, LightDirection).r;
float Distance = length(LightDirection);
if (Distance <= SampledDistance + EPSILON)
return 1.0; else return 0.5;
return SampledDistance;
}
void main(){
vec3 direction = lightPosition-worldPosition;
float shadowFactor= calcShadowFactor(direction);
fragColor = vec4(ads(),1);
}