Hey Guys,
I’m currently working with the fixed-function pipeline, but I’ve decided to begin the upgrade to Modern OpenGL.
One of the first areas I’m looking at is GLSL, and more specifically, Shadow Mapping.
In order to do this, I’ve created a test program (in Java, using LWJGL), to try and figure out how to use the Shadow2DProj function.
The following code is what I use to render the depth map, followed by the actual render:
private void drawShadowScene() {
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, fbo);
GL11.glViewport(0, 0, 800, 600);
GL11.glColorMask(false, false, false, false);
OpenGL.clearScreen();
lightCamera.lookThrough();
updateLightingMatrix();
GL11.glPushMatrix();
GL11.glColor3f(0.0f, 0.0f, 1.0f);
GL11.glBegin(GL11.GL_QUADS);
GL11.glVertex3f(-20.0f, 0.0f, -20.0f);
GL11.glVertex3f(20.0f, 0.0f, -20.0f);
GL11.glVertex3f(20.0f, 0.0f, 0.0f);
GL11.glVertex3f(-20.0f, 0.0f, 0.0f);
GL11.glEnd();
GL11.glPopMatrix();
GL11.glColor3f(1.0f, 0.0f, 0.0f);
GL11.glPushMatrix();
drawCube(0.0f, 2.0f, -10.0f, 1.0f, 1.0f, 1.0f, false, false);
GL11.glPopMatrix();
GL11.glColorMask(true, true, true, true);
GL11.glViewport(0, 0, 800, 600);
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0);
}
private void drawCombinedScene() {
OpenGL.clearScreen();
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, depthTexture);
shadowMapShader.enable();
shadowMapShader.setMatrix4Property("lightingMatrix", lightMatrix);
shadowMapShader.setProperty("depthSampler", 0);
player.render();
GL11.glPushMatrix();
GL11.glColor3f(0.0f, 0.0f, 1.0f);
GL11.glBegin(GL11.GL_QUADS);
GL11.glVertex3f(-20.0f, 0.0f, -20.0f);
GL11.glVertex3f(20.0f, 0.0f, -20.0f);
GL11.glVertex3f(20.0f, 0.0f, 0.0f);
GL11.glVertex3f(-20.0f, 0.0f, 0.0f);
GL11.glEnd();
GL11.glPopMatrix();
GL11.glColor3f(1.0f, 0.0f, 0.0f);
GL11.glPushMatrix();
drawCube(0.0f, 2.0f, -10.0f, 1.0f, 1.0f, 1.0f, false, false);
GL11.glPopMatrix();
shadowMapShader.disable();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
}
And here is the code I use to generate the FrameBuffer and Texture, as well as the function I use to create the light matrix:
private void setupDepthRendering() {
depthTexture = GL11.glGenTextures();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, depthTexture);
GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_DEPTH_COMPONENT, 800, 600, 0, GL11.GL_DEPTH_COMPONENT, GL11.GL_FLOAT, (FloatBuffer)null);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL14.GL_TEXTURE_COMPARE_MODE, GL14.GL_COMPARE_R_TO_TEXTURE);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL14.GL_TEXTURE_COMPARE_FUNC, GL11.GL_LEQUAL);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
fbo = GL30.glGenFramebuffers();
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, fbo);
GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL11.GL_TEXTURE_2D, depthTexture, 0);
GL11.glDrawBuffer(GL11.GL_NONE);
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0);
}
and…
public void updateLightingMatrix() {
FloatBuffer modelView = BufferUtils.createFloatBuffer(16);
FloatBuffer projection = BufferUtils.createFloatBuffer(16);
// Texture bias matrix
float[] biasValues = {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};
FloatBuffer biasMatrix = (FloatBuffer)BufferUtils.createFloatBuffer(16).put(biasValues).flip();
GL11.glGetFloat(GL11.GL_MODELVIEW_MATRIX, modelView);
GL11.glGetFloat(GL11.GL_PROJECTION_MATRIX, projection);
GL11.glPushMatrix();
GL11.glLoadIdentity();
GL11.glLoadMatrix(biasMatrix);
GL11.glMultMatrix(modelView);
GL11.glMultMatrix(projection);
lightMatrix = BufferUtils.createFloatBuffer(16);
GL11.glGetFloat(GL11.GL_MODELVIEW_MATRIX, lightMatrix);
GL11.glPopMatrix();
}
Finally, here is my vertex and fragment shader:
varying vec4 shadowCoordinate;
uniform sampler2DShadow depthSampler;
void main() {
float shadow = 1.0f;
shadow = shadow2DProj(depthSampler, shadowCoordinate);
gl_FragColor = shadow;
}
and…
varying vec4 shadowCoordinate;
uniform mat4 lightingMatrix;
void main() {
shadowCoordinate = lightingMatrix * gl_Vertex;
gl_FrontColor = gl_Color;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
However, none of this seems to have any impact. All I see on the screen is a white plane below a white cube, with no ‘shadowing’ at all.
Am I setting any render states that I shouldn’t be? I’m pretty sure the depth map is rendering correctly, as when I previously rendered it to a quad, I could clearly make out the cube/plane.
Thanks for the help,
Matt.