PDA

View Full Version : Help with 2D Light Attenuation



Falcdawg21
10-20-2010, 08:45 PM
Hi all,

I am fairly new to OpenGL and I have been trying to follow a tutorial on how to do 2D Dynamic Soft Shadows and I am stuck on getting the lights in the scene to work by only allowing images to show when the light is on them. I am also using Objective C to write this.

Here is the link to the tutorial I am working through.
http://www.gamedev.net/reference/articles/article2032.asp

This is what I have so far:


// clear color is glClearColor(0.0f, 0.0f, 0.0f, 0.0f)
// this all happens in a draw/update call

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

glDisable(GL_BLEND);// full screen quad drawn without blending
glDisable(GL_DEPTH_TEST); // depth testing
glColorMask(FALSE, FALSE, FALSE, TRUE); // or colour writing to reset the alpha channel in the framebuffer to 0f

// draw quad
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, squareVertices); // variable populated else where (this works, I have seen it)
glColorPointer(4, GL_UNSIGNED_BYTE, 0, squareColors); // variable populated else where (this works, I have seen it)
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

//load the lights intensity into the alpha buffer. This does not need any blending,
//but depth testing is enabled this time to allow lights to be restricted to illuminating only the objects beneath them
//Again colour writing is left disabled since we are not ready to render any visible geometry yet
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glDisable(GL_BLEND);
glColorMask(FALSE, FALSE, FALSE, TRUE);


// Draw triangle fan for the light/////////////////////////////
float *vertices = malloc( sizeof(float)*3*(segs+2));
float *colors = malloc( sizeof(float)*4*(segs+2));
if(!vertices || !colors)
return;

memset( vertices,0, sizeof(float)*3*(segs+2));
memset( colors,0, sizeof(float)*4*(segs+2));

int index = 0;

vertices[index*3] = center.x;
vertices[index*3+1] = center.y;
vertices[index*3+2] = depth;

colors[index*4] = 1.0f;
colors[index*4+1] = 0.0f;
colors[index*4+2] = 0.0f;
colors[index*4+3] = intensity;

index++;
for(float angle = 0; angle <= M_PI * 2; angle += ((M_PI * 2 ) / segs))
{
vertices[index*3] = r * (float)cosf(angle) + center.x;
vertices[index*3+1] = r * (float)sinf(angle) + center.y;
vertices[index*3+2] = depth;

colors[index*4] = 1.0f;
colors[index*4+1] = 0.0f;
colors[index*4+2] = 0.0f;
colors[index*4+3] = 0.0f;

index++;
}

vertices[(segs+1)*3] = center.x + r;
vertices[(segs+1)*3+1] = center.y;
vertices[(segs+1)*3+2] = depth;

colors[(segs+1)*4] = 1.0f;
colors[(segs+1)*4+1] = 0.0f;
colors[(segs+1)*4+2] = 0.0f;
colors[(segs+1)*4+3] = 0.0f;

glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

glVertexPointer(3, GL_FLOAT, 0, vertices);
glColorPointer(4, GL_FLOAT, 0, colors);

glDrawArrays(GL_TRIANGLE_FAN, 0, segs+2);

glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);

free( vertices );
free( colors );
///////////////////end of Triangle fan/////////////////

glColorMask(TRUE, TRUE, TRUE, TRUE);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);

glEnable(GL_BLEND);
glBlendFunc(GL_DST_ALPHA, GL_ONE);

// draw background objects....



What I think this should be doing is drawing a transparent background quad (which it does) and sets the alpha buffer to 0.
Then when I draw my light on top of the quad, it replaces the values in the alpha buffer to the values of my attenuated light. And the blend function should only allow objects to be drawn when the alpha value at there location is non-transparent (like where the light is), but this does not happen. All I get is an object drawn on the screen no matter where it is with a black background(the clear color). I'm sure it has to do with my usage and lack of knowledge with blending.

Please if anyone could point me in the right direction, that would be awesome. I have been working at this for two days now and its driving me nuts :)

Thanks,