I’m currently trying the shadow mapping with JOGL. I tried to render grass with shadow on it. But the result comes out to be that all the objects are dark. Here is my code:
//bind framebuffer for shadow mapping
gl.glGenFramebuffers(1, framebuff);
gl.glBindFramebuffer(GL4.GL_FRAMEBUFFER, framebuff.get(0));
gl.glGenTextures(1, textureBuff);
gl.glBindTexture(GL4.GL_TEXTURE_2D, textureBuff.get(0));
gl.glTexStorage2D(GL4.GL_TEXTURE_2D, 1, GL4.GL_DEPTH_COMPONENT32F, displayWidth, displayHeight);
gl.glTexParameteri(GL4.GL_TEXTURE_2D, GL4.GL_TEXTURE_MAG_FILTER, GL4.GL_LINEAR);
gl.glTexParameteri(GL4.GL_TEXTURE_2D, GL4.GL_TEXTURE_MIN_FILTER, GL4.GL_LINEAR);
gl.glTexParameteri(GL4.GL_TEXTURE_2D, GL4.GL_TEXTURE_COMPARE_MODE, GL4.GL_COMPARE_REF_TO_TEXTURE);
gl.glTexParameteri(GL4.GL_TEXTURE_2D, GL4.GL_TEXTURE_COMPARE_FUNC, GL4.GL_LEQUAL);
gl.glFramebufferTexture(GL4.GL_FRAMEBUFFER, GL4.GL_DEPTH_ATTACHMENT, textureBuff.get(0), 0);
gl.glDrawBuffer(GL4.GL_NONE);
gl.glBindFramebuffer(GL4.GL_FRAMEBUFFER, 0);
[HR][/HR]
Here is the code calculating the shadowMatrix:
float[] sPmvMat = new float[16];
pmvMatrix.glLoadIdentity();
pmvMatrix.gluLookAt(100f, 100f, 100f, 0f, 0f, 0f, 0f, 1.0f, 0f);
pmvMatrix.glFrustumf(-1f, 1f, -1f, 1f, 1f, 100f);
pmvMatrix.multPMvMatrixf(sPmvMat, 0);
float[] scale_bias_Mat = {
0.5f, 0.0f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f
};
Matrix4 m = new Matrix4();
m.loadIdentity();
m.multMatrix(scale_bias_Mat);
m.multMatrix(sPmvMat);
shadowMat = m.getMatrix();
[HR][/HR]
Here is the drawing command:
gl.glEnable(GL4.GL_POLYGON_OFFSET_FILL);
gl.glPolygonOffset(2.0f, 4.0f);
gl.glUseProgram(shaderProgram);
setMvpMatrix();
gl.glUniformMatrix4fv(shadowM_Loc, 1, false, shadowMat, 0);
gl.glBindTexture(GL4.GL_TEXTURE_2D, textureBuff.get(0));
gl.glViewport(0, 0, displayWidth, displayHeight);
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl.glClearDepth(1.0f);
gl.glBindVertexArray(vaoBuff.get(0));
gl.glDrawArraysInstanced(GL4.GL_TRIANGLE_STRIP, 0, 5, 512 * 512);
gl.glDisable(GL4.GL_POLYGON_OFFSET_FILL);
[HR][/HR]
Here is the vertex shader code:
"#version 430
" +
"layout (location = 3) uniform mat4 mvMatrix;
" +
"layout (location = 4) uniform mat4 proMatrix;
" +
"layout (location = 10) uniform mat4 shadowMat;
" +
"layout (location = 0) in vec4 position;
" +
"out VS_OUT
" +
"{
" +
" vec4 shadowCoord;
" +
"} vs_out;
" +
"
" +
"void main(void)
" +
"{
" +
" randomize position...
" +
"
" +
" vs_out.shadowCoord = shadowMat * position;
" +
"
" +
" gl_Position = proMatrix * mvMatrix * position;
" +
"}"
[HR][/HR]
Here is the fragment shader code:
"#version 430
" +
"layout (binding = 0) uniform sampler2DShadow shadow_tex;
" +
"out vec4 output_color;
" +
"in VS_OUT
" +
"{
" +
" vec4 shadowCoord;
" +
"} fs_in;
" +
"void main(void)
" +
"{
" +
" output_color = textureProj(shadow_tex, fs_in.shadowCoord) * vec4(0.2, 0.7, 0.2, 1.0);
" +
"}"
Added:
It seems I have found the reason. I added a line checking the framebuffer status after setting up that framebuffer. Yet it returns a wrong status (36054). Any ideas?
Here is the code:
//bind framebuffer for shadow mapping
gl.glGenFramebuffers(1, framebuff);
gl.glBindFramebuffer(GL4.GL_FRAMEBUFFER, framebuff.get(0));
gl.glGenTextures(1, textureBuff);
gl.glBindTexture(GL4.GL_TEXTURE_2D, textureBuff.get(0));
gl.glTexStorage2D(GL4.GL_TEXTURE_2D, 1, GL4.GL_DEPTH_COMPONENT32F, displayWidth, displayHeight);
gl.glTexParameteri(GL4.GL_TEXTURE_2D, GL4.GL_TEXTURE_MAG_FILTER, GL4.GL_LINEAR);
gl.glTexParameteri(GL4.GL_TEXTURE_2D, GL4.GL_TEXTURE_MIN_FILTER, GL4.GL_LINEAR);//GL_LINEAR_MIPMAP_LINEAR
gl.glTexParameteri(GL4.GL_TEXTURE_2D, GL4.GL_TEXTURE_COMPARE_MODE, GL4.GL_COMPARE_REF_TO_TEXTURE);
gl.glTexParameteri(GL4.GL_TEXTURE_2D, GL4.GL_TEXTURE_COMPARE_FUNC, GL4.GL_LEQUAL);
gl.glFramebufferTexture(GL4.GL_FRAMEBUFFER, GL4.GL_DEPTH_ATTACHMENT, textureBuff.get(0), 0);
gl.glDrawBuffer(GL4.GL_NONE);
if(gl.glCheckFramebufferStatus(GL4.GL_FRAMEBUFFER) != GL4.GL_FRAMEBUFFER_COMPLETE)
return gl.glCheckFramebufferStatus(GL4.GL_FRAMEBUFFER);