Bitmap *Buffer; void Init() { Buffer = new Bitmap(SCREEN_W, SCREEN_H); } void Draw() { if (ShowShadows) { Canvas::SetTo(*Buffer); Canvas::Fill(Rgba::BLACK); //Blenders::Set(ADDITIVE_BLENDER); Player->DrawLights(); //Blenders::Set(ALPHA_BLENDER); Canvas::SetTo(SCREEN_BACKBUF); } //DRAW THE MAP AND OBJECTS HERE if (ShowShadows) { Blenders::Set(GL_ONE_MINUS_DST_ALPHA, GL_SRC_COLOR); Buffer->Blit(0, 0); Blenders::Set(ALPHA_BLENDER); } } class CPlayer { //... vector<Vec2D> LightPoly; //... }; inline void CPlayer::CalculateLight() { float fAngle = (Angle+90)-65; LightPoly.clear(); LightPoly.push_back(Vec2D(X, Y)); for (int i=0; i<20; i++) { fAngle -= 2.5f; for (int l=0; l<200; l+=10) { float X2 = X+cos(fAngle*AL_PI/180)*l; float Y2 = Y+sin(fAngle*AL_PI/180)*l; if (Map[MAPID]->BlockedTile(X2, Y2)) //IF THE LIGHT RAY HITS A BLOCKED TILE, IE. A WALL { //FOR ADDED POLYGON SMOOTHNESS, BUT IT WORKS ONLY ON RECTANGLES if (X2<int(X2/TILESIZE)*TILESIZE+10) { X2 = int(X2/TILESIZE)*TILESIZE; } else if (X2>int(X2/TILESIZE+1)*TILESIZE-10) { X2 = int(X2/TILESIZE+1)*TILESIZE; } if (Y2<int(Y2/TILESIZE)*TILESIZE+10) { Y2 = int(Y2/TILESIZE)*TILESIZE; } else if (Y2>int(Y2/TILESIZE+1)*TILESIZE-10) { Y2 = int(Y2/TILESIZE+1)*TILESIZE; } //============================================================= LightPoly.push_back(Vec2D(X2, Y2)); break; } //ELSE ADD A VERTEX AT THE END OF THE RAY (TO AVOID HAVING 8K VERTICES) else if (l>=189) { LightPoly.push_back(Vec2D(X2, Y2)); } } } } inline void CPlayer::DrawLights() { Light.BlitTransformed(X, Y, 300, 300, 50, 50, 0.0, Tinted(Rgba(1.0, 1.0, 1.0, 1.0)), 1.0); if (ShowShadows && FlashlightON) { for (int i=0; i<LightPoly.size(); i++) { Poly(LightPoly).Draw(Rgba(0.9, 0.9, 0.8)); } } }