Hi, I’m new with openGL and I can’t seems to make textures work properly. I need to cast shadows and I refer to this toturial for this purpose : http://fabiensanglard.net/shadowmapping/index.php. Since I try tu use the latest GLSL version, I had to change some pieces of code.
Before going further, so far, here is what I get without searching for shadows.
[ATTACH=CONFIG]139[/ATTACH]
For each instance of light, I have a framebuffer object and a texture attached to it.
CLight::CLight():
m_type(POINT),
m_intensity(1),
m_ambient(0.5),
m_diffuse(0.3, 0.6, 0.6),
m_specular(0.3, 0.7, 0.7),
m_enabled(true)
{
glGenTextures(1, &m_texId);
glBindTexture(GL_TEXTURE_2D, m_texId);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 256, 256, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glGenFramebuffers(1, &m_fboId);
glBindFramebuffer(GL_FRAMEBUFFER, m_fboId);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_texId, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
Before rendering, I TRY to get the view of each light by bindding the framebuffer before rendering.
void CGLWidget::paintGL(){
//Shadow maps generation
m_shadow.use(); //shadow program
for(int a = 0; a < m_light.size(); a++){
CLight* current = m_light[a];
if(current->enabled()){
m_currentCamera = current;
current->bindFB(); //glBindFramebuffer(GL_FRAMEBUFFER, m_fboId);
drawObjects();
current->unbindFB(); //glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
}
//Draw final render
m_render.use(); //render program
m_currentCamera = &m_camera;
drawObjects();
}
If I comment the final render part and don’t bind the frame buffer I get this :
[ATTACH=CONFIG]140[/ATTACH]
Which is normal considering the shaders :
//shadow.vertexShader
#version 420
in vec3 position;
uniform mat4 mvp;
void main()
{
gl_Position = mvp * vec4(position, 1.0f);
}
//shadow.fragmentShader
#version 420
out vec4 fragColor;
void main (void)
{
fragColor = vec4(0.5, 0.5, 0.5, 1) ;
}
When I keep the render part commented but uncomment the binding part I get a dark screen, which is once again normal, I guess. Thus I though my texture was correctly made and I tried to use it on the render’s fragment shader.
Here is the method of CLight used just before drawing :
void CLight::sendTo(CProgram* p_program, const CMVP* p_camera, int p_id){
//blabla
//blabla
p_program->sendUniform1i(QString("light[%1].type").arg(p_id), m_type);
p_program->sendUniform4f(QString("light[%1].position").arg(p_id), position.x(), position.y(), position.z(), position.w());
p_program->sendUniform3f(QString("light[%1].direction").arg(p_id), direction.x(), direction.y(), direction.z());
p_program->sendUniform1i(QString("shadowMap[%1]").arg(p_id), p_id); //The cursed line
p_program->sendUniform1f(QString("light[%1].intensity").arg(p_id), m_intensity);
p_program->sendUniform1f(QString("light[%1].ambient").arg(p_id), m_ambient);
p_program->sendUniform3f(QString("light[%1].diffuse").arg(p_id), m_diffuse.x(), m_diffuse.y(), m_diffuse.z());
p_program->sendUniform3f(QString("light[%1].specular").arg(p_id), m_specular.x(), m_specular.y(), m_specular.z());
p_program->sendUniformMatrix4fv(QString("light[%1].shadowMat").arg(p_id), 1, GL_TRUE, texMat);
glActiveTexture(GL_TEXTURE0 + p_id); //Maybe some cursed lines again
glBindTexture(GL_TEXTURE_2D, m_texId); //
}
And here are the render shaders :
//render.vertexShader
#version 420
in vec3 position;
in vec3 color;
in vec3 normal;
uniform mat4 mvp;
uniform mat4 mv;
uniform mat3 mvi;
out vec4 vertexInitPosition;
out vec4 vertexPosition;
out vec3 vertexColor;
out vec3 vertexNormal;
void main()
{
int a;
vertexInitPosition = vec4(position, 1);
vertexPosition = mv * vec4(position, 1);
vertexColor = color;
vertexNormal = normalize(mvi * normal);
gl_Position = mvp * vec4(position, 1.0f);
}
//render.fragmentShader
#version 420
const int nbrLight = 8;
in vec4 vertexInitPosition;
in vec4 vertexPosition;
in vec3 vertexColor;
in vec3 vertexNormal;
uniform int nbrLightUsed;
uniform struct lightStruct {
int type;
vec4 position;
vec3 direction;
mat4 shadowMat;
float intensity;
float ambient;
vec3 diffuse;
vec3 specular;
} light[nbrLight];
uniform sampler2D shadowMap[nbrLight];
out vec4 fragColor;
void main (void)
{
int a;
vec3 iDiff = vec3(0,0,0);
vec3 iSpec = vec3(0,0,0);
vec4 shadowCoord;
for(a = 0; a < nbrLight && a < nbrLightUsed; a++){
//Compute shadows
shadowCoord = light[a].shadowMat * vertexInitPosition;
vec4 shadowCoordinateWdivide = shadowCoord / shadowCoord.w ;
shadowCoordinateWdivide.z += 0.0005;
float distanceFromLight = texture2D(shadowMap[a],shadowCoordinateWdivide.st).z;
float shadow = 1.0;
if (shadowCoord.w > 0.0 && distanceFromLight < shadowCoordinateWdivide.z)
shadow = 0.5;
//Compute rays
vec3 L;
if(light[a].type == 0) //Point light
L = vec3(normalize(vertexPosition - light[a].position));
else if(light[a].type == 1) //Directionnal light
L = normalize(light[a].direction);
vec3 E = -normalize(vec3(vertexPosition));
vec3 R = normalize(reflect(L,vertexNormal));
//Add light
iDiff = iDiff + shadow * light[a].diffuse * (light[a].intensity * (light[a].ambient + (1.0 - 0.5*light[a].ambient) * dot(-L, vertexNormal)));
iSpec = iSpec + light[a].specular * (light[a].intensity * pow(max(dot(R,E),0.0),7.0));
}
fragColor = vec4(iDiff + iSpec, 1) ;
}
Everything works fine except the “Compute shadows” part. I’m sure my textureMatrix is correct because when I make my render only arround it, I get this :
[ATTACH=CONFIG]141[/ATTACH]
Thus, the last problem that remains is the integrity of the sampler2D used. I tried a render using only the z values of this sampler and got only 1.0 values. I also tried with empty samplers and got the same result.
I don’t know what’s wrong here, till then it was funny because I could tuch every data by hand. Now with textures it’s different, I have no idea if the transfert from the framebuffer was a success nor the transfert vie glUniform1i().
Does anyone have an idea ?