Original Post
Hi guys, I’d like to implement soft shadowing for spheres in real-time. After going through the maths of Humus’ sample (http://www.humus.ca/index.php?page=3D&&start=8) I finally understand his shadow shader and would now like to implement it – cut ‘n’ paste or by other means I don’t mind. However I’m having a very hard time trying to extract the key opengl ingredients/api-calls, and in their correct order, from his rather neat framework (2). Here are Humus’ functions of interest RE: the sphere shadows: In an effort at keeping it simple, the following is my humble attempt. And all I get to see is a RED quad for all my effort. :) Anyone have any tips, comments or suggestions relating to where I’ve screwed up or how to better debug? I normally prefer to implement my shadows in a 2 pass system instead of the above 3. I just don’t want to see Humus’ sample go to waste! Thanks anyone. PS: I’m not quite up to the stage of pulling my hair out (yet).
bool MainApp::drawFrame()
{
renderer->changeMask(ALL);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // added GL_COLOR_BUFFER_BIT
...
// Pass 0, ambient lighting + depth
drawRoom(0);
// Pass 1, shadows
vec4 spherePos[SPHERE_COUNT];
for (unsigned int j = 0; j < SPHERE_COUNT; j++){
spherePos[j] = vec4(spheres[j].pos, spheres[j].size * spheres[j].size);
}
renderer->setShader(shadow);
renderer->setMask(ALPHA);
renderer->apply();
renderer->changeShaderConstant3f("lightPos", spheres[SPHERE_COUNT].pos);
renderer->changeShaderConstantArray4f("spherePos", spherePos, SPHERE_COUNT);
drawRoom(1);
// Pass 2, lighting
drawRoom(2);
return true;
}
void MainApp::drawRoom(int pass){
...
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertexArray);
if (pass != 1){
glEnableVertexAttribArrayARB(1);
glVertexAttribPointerARB(1, 2, GL_FLOAT, GL_FALSE, 0, texCoordArray);
if (pass != 0){
glEnableVertexAttribArrayARB(2);
glEnableVertexAttribArrayARB(3);
glEnableVertexAttribArrayARB(4);
glVertexAttribPointerARB(2, 3, GL_FLOAT, GL_FALSE, 0, tangentArray);
glVertexAttribPointerARB(3, 3, GL_FLOAT, GL_FALSE, 0, binormalArray);
glVertexAttribPointerARB(4, 3, GL_FLOAT, GL_FALSE, 0, normalArray);
}
}
if (pass == 1){
glDrawArrays(GL_QUADS, 0, 24);
} else {
static int n[] = { 2, 1, 0, 0, 0, 0 };
for (int i = 0; i < 1; i++){ // changed from “< 6"
if (pass == 0){
renderer->setShader(roomAmbient);
renderer->setTexture("Base", base[n]);
renderer->apply();
} else {
renderer->setShader(room);
renderer->setTexture("Base", base[n]);
renderer->setTexture("Bump", bump[n]);
renderer->setBlending(DST_ALPHA, ONE);
renderer->setMask(COLOR);
renderer->apply();
renderer->changeShaderConstant3f("lightPos", spheres[SPHERE_COUNT].pos);
renderer->changeShaderConstant3f("camPos", position);
}
glDrawArrays(GL_QUADS, 4 * i, 4);
}
}
if (pass != 1){
if (pass != 0){
glDisableVertexAttribArrayARB(4);
glDisableVertexAttribArrayARB(3);
glDisableVertexAttribArrayARB(2);
}
glDisableVertexAttribArrayARB(1);
}
glDisableClientState(GL_VERTEX_ARRAY);
}
void RenderFloor(const light& point_source)
{
static vertex quad1[4] =
{
// x y z
{ -15.0f, 0.0f, -15.0f },
{ -15.0f, 0.0f, 15.0f },
{ 15.0f, 0.0f, -15.0f },
{ 15.0f, 0.0f, 15.0f }
};
static texture_normal_vertex quad2[4] =
{
// tu tv nx ny nz x y z
{ 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, -15.0f, 0.0f, -15.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, -15.0f, 0.0f, 15.0f },
{ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 15.0f, 0.0f, -15.0f },
{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 15.0f, 0.0f, 15.0f }
};
glColor4f(1.0f, 0.0f, 0.0f, 1.0f); // Test color
glInterleavedArrays(GL_V3F, 0, quad1);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
float sphere_position[MAX_SPHERES][4];
for (int i = 0; i < MAX_SPHERES; ++i)
{
sphere_position[x] = spheres.position[x];
sphere_position[y] = spheres.position[y];
sphere_position[z] = spheres.position[z];
sphere_position[w] = spheres.size * spheres.size;
char str[32];
sprintf(str, "sphere_position[%d]", i);
shadows.Bind(str, sphere_position, 4);
}
shadows.Bind("light_position", point_source.position, 3); // “shadows" is my shader object.
glDepthMask(GL_FALSE);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
glInterleavedArrays(GL_V3F, 0, quad1);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
shadows.Disable();
glEnable(GL_BLEND);
glBlendFunc(GL_DST_ALPHA, GL_ONE);
glColor4f(0.0f, 0.0f, 1.0f, 1.0f); // Test color
glInterleavedArrays(GL_V3F, 0, quad1);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
return;
}