Trying to get Shadow Mapping working

Started by
0 comments, last by Ameise 13 years, 1 month ago
I am working on an isometric game, and want to use shadow mapping to shadows properly project across the scene.

I know that these guides are inefficient, and once they are working, I will switch to shaders, but I want it working for now fixed function. I used these guides:
http://www.paulsproj...ls/smt/smt.html
http://www.opengl.or...without_shaders

The problem is, I am not seeing shadowing. I am seeing only my normal scene.

This is the code so far (snippets):

Graphics Code:

...



bool xgl::initialize (const VectorI &resolution, bool fullscreen)
{
assert(smInitialized == false);
smInitialized = true;

smResolution = resolution;

int argc = 0;
glutInit(&argc, NULL);
glutInitWindowPosition(0, 0);
glutInitWindowSize(smResolution.x, smResolution.y);
glutInitDisplayString("depth>=24 rgb double alpha samples<=8");
smWindowID = glutCreateWindow("Game");

if (smWindowID == 0)
return false;

smWindow = WindowFromDC(wglGetCurrentDC());
//SetWindowLongPtr(smWindow, GWLP_WNDPROC, (LONG_PTR)&processMessages);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glShadeModel(GL_SMOOTH);
glClearColor(0.f, 0.f, 0.f, 0.f);
glColor4f(1.f, 1.f, 1.f, 1.f);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glClearDepth(1.f);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glEnable(GL_NORMALIZE);
//glEnable(GL_BLEND);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
const float ambient[4] = {0.5, 0.5, 0.5, 1.f};
const float diffuse[4] = {1.f, 1.f, 1.f, 1.f};
const float position[4] = {light[0], light[1], light[2], 0.f};
glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
glLightfv(GL_LIGHT1, GL_POSITION, position);
glEnable(GL_LIGHT1);

glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_NORMALIZE);

resize(resolution, fullscreen);
return true;
}
...

void xgl::resize (const VectorI &resolution, bool fullscreen)
{
assert(smInitialized == true);

const double ratio = double(smResolution.x) / double(smResolution.y);

glPushMatrix();
glLoadIdentity();
glOrtho(
(40 / 2) * ratio,
(-40 / 2) * ratio,
40 / 2, -40 / 2, 0.1, 100.0
);
gluLookAt(
-5, -5, 5,
0.0, 0.0, 0.0,
0.0, 0.0, -1.0
);
glGetDoublev(GL_MODELVIEW_MATRIX, smCameraProjectionMatrix);

glLoadIdentity();
glOrtho(
(40 / 2),
(-40 / 2),
40 / 2, -40 / 2, 0.1, 100.0
);
gluLookAt(
light[0] * 10, light[1] * 10, light[2] * 2,
0.0, 0.0, 0.0,
0.0, 0.0, -1.0
);
glGetDoublev(GL_MODELVIEW_MATRIX, smLightProjectionMatrix);

glPopMatrix();
}

...


void xgl::prepareRenderPass1 ()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
glLoadMatrixd(smLightProjectionMatrix);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glViewport(
0,
0,
ShadowMap::getShadowResolution().x,
ShadowMap::getShadowResolution().y
);

glCullFace(GL_FRONT);
glShadeModel(GL_FLAT);
glColorMask(0, 0, 0, 0);
}

void xgl::finalRenderPass1 ()
{
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, ShadowMap::getShadowTexture());
glCopyTexSubImage2D(
GL_TEXTURE_2D,
0, 0, 0, 0, 0,
ShadowMap::getShadowResolution().x,
ShadowMap::getShadowResolution().y
);
glDisable(GL_TEXTURE_2D);

glCullFace(GL_BACK);
glShadeModel(GL_SMOOTH);
glColorMask(1, 1, 1, 1);
}

void xgl::prepareRenderPass2 ()
{
glClear(GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadMatrixd(smCameraProjectionMatrix);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glViewport(
0, 0,
smResolution.x,
smResolution.y
);

const float black[] = {0.f, 0.f, 0.f, 1.f};

glLightfv(GL_LIGHT1, GL_AMBIENT, black);
glLightfv(GL_LIGHT1, GL_DIFFUSE, black);
glEnable(GL_LIGHT1);
glEnable(GL_LIGHTING);
}

void xgl::finalRenderPass2 ()
{
}

static void multiplyMatrix (const double a[16], const double b[16], double o[16])
{
for(int i = 0; i < 4; i++){
for(int j = 0; j < 4; j++){
for(int x = 0; x < 4; x++)
o[i * 4 + j] = a[i * 4 + x] * b[x * 4 + j];
}
}
}

static void getRow (int row, const double m[16], double v[4])
{
v[0] = m[0 * 4 + row];
v[1] = m[1 * 4 + row];
v[2] = m[2 * 4 + row];
v[3] = m[3 * 4 + row];
}

void xgl::prepareRenderPass3 ()
{
const float ambient[] = {0.5f, 0.5f, 0.5f, 1.f}
const float white[] = {1.f, 1.f, 1.f, 1.f};
glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
glLightfv(GL_LIGHT1, GL_DIFFUSE, white);

static double biasMatrix[] = {
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
};

double outMatrix[16];

multiplyMatrix(biasMatrix, smLightProjectionMatrix, outMatrix);

double vector[4];

getRow(0, outMatrix, vector);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGendv(GL_S, GL_EYE_PLANE, vector);
glEnable(GL_TEXTURE_GEN_S);

getRow(1, outMatrix, vector);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGendv(GL_T, GL_EYE_PLANE, vector);
glEnable(GL_TEXTURE_GEN_T);

getRow(2, outMatrix, vector);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGendv(GL_R, GL_EYE_PLANE, vector);
glEnable(GL_TEXTURE_GEN_R);

getRow(3, outMatrix, vector);
glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGendv(GL_Q, GL_EYE_PLANE, vector);
glEnable(GL_TEXTURE_GEN_Q);

glBindTexture(GL_TEXTURE_2D, ShadowMap::getShadowTexture());
glEnable(GL_TEXTURE_2D);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);

glAlphaFunc(GL_GEQUAL, 0.99f);
glEnable(GL_ALPHA_TEST);
}

void xgl::finalRenderPass3 ()
{
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
glDisable(GL_TEXTURE_GEN_Q);

glDisable(GL_LIGHTING);
glDisable(GL_ALPHA_TEST);
}


The Shadow Map texture is created here:





void ShadowMap::initialize (const VectorI &resolution)
{
smShadowResolution = resolution;
glGenTextures(1, &smShadowTexture);
glBindTexture(GL_TEXTURE_2D, smShadowTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_DEPTH_COMPONENT24,
smShadowResolution.x,
smShadowResolution.y,
0,
GL_DEPTH_COMPONENT,
GL_UNSIGNED_BYTE,
NULL
);
}




To render, I am doing this:



xgl::clear();
xgl::prepareRenderPass1();
Scene::draw();
xgl::finalRenderPass1();
xgl::prepareRenderPass2();
Scene::draw();
xgl::finalRenderPass2();
xgl::prepareRenderPass3();
Scene::draw();
xgl::finalRenderPass3();
xgl::swap();


Again, it is rendering, but with no semblance of shadows -- I am just seeing the regular scene. What am I doing wrong? If I use smLightProjectionMatrix to draw the regular scene, I do see the scene properly from the camera's perspective.

When using a GL debugger, I can verify that the depth map is indeed being created, so I am supposing that the error lies in pass 3, but I am unsure as to what.
Advertisement
Figured it out - my multiply matrix function was wrong.

This topic is closed to new replies.

Advertisement