public void calculateShadows(LightSource light){
		
		glColorMask(false, false, false, false);
		glStencilFunc(GL_ALWAYS, 1, 1);
		glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);

		for (Vector2 block : getOpaqueTiles()) {
			Vector2[] vertices = {
					new Vector2(block.x, block.y),
					new Vector2(block.x, block.y + tileSize),
					new Vector2(block.x + tileSize, block.y + tileSize),
					new Vector2(block.x + tileSize, block.y)
			};
			
			for (int i = 0; i < vertices.length; i++) {
				Vector2 currentVertex = vertices[i];
				Vector2 nextVertex = vertices[(i + 1) % vertices.length];
				Vector2 edge = Vector2.sub(nextVertex, currentVertex);
				Vector2 normal = new Vector2(edge.y, -edge.x);
				Vector2 lightToCurrent = Vector2.sub(currentVertex, new Vector2(light.location.x, light.location.y));
				if (Vector2.dot(normal, lightToCurrent) > 0) {
					Vector2 point1 = Vector2.add(currentVertex, Vector2.sub(currentVertex, new Vector2(light.location.x, light.location.y)).scale(800));
					Vector2 point2 = Vector2.add(nextVertex, Vector2.sub(nextVertex, new Vector2(light.location.x, light.location.y)).scale(800));
					glBegin(GL_QUADS); {
						glVertex2f(currentVertex.x, currentVertex.y);
						glVertex2f(point1.x, point1.y);
						glVertex2f(point2.x, point2.y);
						glVertex2f(nextVertex.x, nextVertex.y);
					} glEnd();
				}
			}
		}

		glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
		glStencilFunc(GL_EQUAL, 0, 1);
		glColorMask(true, true, true, true);

		glUseProgram(Main.shaderProgram);
		glUniform2f(glGetUniformLocation(Main.shaderProgram, "lightLocation"), light.location.x + Main.px, Main.HEIGHT - light.location.y + Main.py);
		glUniform3f(glGetUniformLocation(Main.shaderProgram, "lightColor"), light.red, light.green, light.blue);
		glEnable(GL_BLEND);
		glBlendFunc(GL_ONE, GL_ONE);

		glBegin(GL_QUADS); {
			glVertex2f(0, 0);
			glVertex2f(0, worldHeight * tileSize);
			glVertex2f(worldWidth * tileSize, worldHeight * tileSize);
			glVertex2f(worldWidth * tileSize, 0);
		} glEnd();

		glDisable(GL_BLEND);
		glUseProgram(0);
		
		glClear(GL_STENCIL_BUFFER_BIT);
	}