Created
October 1, 2012 01:46
-
-
Save Shaptic/3809002 to your computer and use it in GitHub Desktop.
Render shadows in OpenGL
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void RenderShadows(const math::CVector2& LightPos), | |
const std::vector<Object*>& shadowCastingObjects) | |
{ | |
// Set up rendering modes | |
glMatrixMode(GL_MODELVIEW); | |
glPushMatrix(); | |
glLoadIdentity(); | |
glDisable(GL_BLEND); | |
glColor4f(0.3f, 0.3f, 0.3f, 1.0f); // Dark gray | |
for(size_t i = 0; i < shadowCastingObjects.size(); ++i) | |
{ | |
math::CRay2 TopLeft, TopRight, BottomRight, BottomLeft; | |
TopLeft.Start = LightPos; | |
TopLeft.End = shadowCastingObjects[i]->GetPosition(); | |
TopRight.Start = LightPos; | |
TopRight.End.x = shadowCastingObjects[i]->GetX() + shadowCastingObjects[i]->GetW(); | |
TopRight.End.y = shadowCastingObjects[i]->GetY(); | |
BottomRight.Start = LightPos; | |
BottomRight.End.x = shadowCastingObjects[i]->GetX() + shadowCastingObjects[i]->GetW(); | |
BottomRight.End.y = shadowCastingObjects[i]->GetY() + shadowCastingObjects[i]->GetH(); | |
BottomLeft.Start = LightPos; | |
BottomLeft.End.x = shadowCastingObjects[i]->GetX(); | |
BottomLeft.End.y = shadowCastingObjects[i]->GetY() + shadowCastingObjects[i]->GetH(); | |
CreateShadowRay(LightPos, TopLeft); | |
CreateShadowRay(LightPos, TopRight); | |
CreateShadowRay(LightPos, BottomRight); | |
CreateShadowRay(LightPos, BottomLeft); | |
glBegin(GL_QUADS); | |
if(TopLeft.Start.y < LightPos.y) | |
{ | |
glVertex2f(TopLeft.Start.x, TopLeft.Start.y); | |
glVertex2f(TopLeft.End.x, TopLeft.End.y); | |
glVertex2f(TopRight.End.x, TopRight.End.y); | |
glVertex2f(TopRight.Start.x, TopRight.Start.y); | |
} | |
if(TopRight.Start.x > LightPos.x) | |
{ | |
glVertex2f(TopRight.Start.x, TopRight.Start.y); | |
glVertex2f(TopRight.End.x, TopRight.End.y); | |
glVertex2f(BottomRight.End.x, BottomRight.End.y); | |
glVertex2f(BottomRight.Start.x, BottomRight.Start.y); | |
} | |
if(BottomRight.Start.y > LightPos.y) | |
{ | |
glVertex2f(BottomRight.Start.x, BottomRight.Start.y); | |
glVertex2f(BottomRight.End.x, BottomRight.End.y); | |
glVertex2f(BottomLeft.End.x, BottomLeft.End.y); | |
glVertex2f(BottomLeft.Start.x, BottomLeft.Start.y); | |
} | |
if(BottomLeft.Start.x < LightPos.x) | |
{ | |
glVertex2f(BottomLeft.Start.x, BottomLeft.Start.y); | |
glVertex2f(BottomLeft.End.x, BottomLeft.End.y); | |
glVertex2f(TopLeft.End.x, TopLeft.End.y); | |
glVertex2f(TopLeft.Start.x, TopLeft.Start.y); | |
} | |
glEnd(); | |
} | |
// Revert rendering modes. | |
glEnable(GL_BLEND); | |
glColor4f(1, 1, 1, 1); | |
glPopMatrix(); | |
} | |
// There is a minor bug with this method, when the LightPos.x | |
// is equal to the RayCast.x value, the shadow is not created | |
// as intended. When I find a fix, I'll update this code. | |
// If anyone has a fix, feel free to comment below. | |
void CWorld::CreateShadowRay(const math::CVector2& LightPos, | |
math::CRay2& RayCast) | |
{ | |
// Calculate slope | |
// m = (y2 - y1) / (x2 - x1) | |
float slope = RayCast.GetSlope(); | |
// Translate the ray from its original position to | |
// being from the vertex to a distance | |
// approx. 5000px away. | |
RayCast.Start = RayCast.End; | |
if(RayCast.End.x > LightPos.x) | |
{ | |
RayCast.End.x += 5000; | |
RayCast.End.y += 5000 * slope; | |
} | |
else if(RayCast.End.x < LightPos.x) | |
{ | |
RayCast.End.x -= 5000; | |
RayCast.End.y -= 5000 * slope; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment