public override void render(Graphics graphics, Camera camera) { if (power > 0 && isVisibleFromCamera(camera)) { var size = radius * 2f; var obstacles = Physics.boxcastBroadphase(new RectangleF(entity.transform.position.X - radius, entity.transform.position.Y - radius, size, size), collidesWithLayers); // Compute the visibility mesh var visibility = new VisibilityComputer(entity.transform.position, radius); foreach (var v in obstacles) { visibility.addSquareOccluder(v.bounds); } // Generate a triangle list from the encounter points VertexPositionTexture[] vertices; short[] indices; var encounters = visibility.computeVisibilityPolygon(); triangleListFromEncounters(encounters, out vertices, out indices); Core.graphicsDevice.BlendState = BlendState.Additive; Core.graphicsDevice.RasterizerState = RasterizerState.CullNone; // Apply the effect _lightEffect.Parameters["viewProjectionMatrix"].SetValue(entity.scene.camera.viewProjectionMatrix); _lightEffect.Parameters["lightSource"].SetValue(entity.transform.position); _lightEffect.Parameters["lightColor"].SetValue(color.ToVector3() * power); _lightEffect.Parameters["lightRadius"].SetValue(radius); _lightEffect.Techniques[0].Passes[0].Apply(); // Draw the light on screen, using the triangle fan from the computed // visibility mesh so that the light only influences the area that can be // "seen" from the light's position. Core.graphicsDevice.DrawUserIndexedPrimitives <VertexPositionTexture> ( PrimitiveType.TriangleList, vertices, 0, vertices.Length, indices, 0, indices.Length / 3 ); } }
public override void onAddedToEntity() { _lightEffect = entity.scene.content.loadEffect <Effect>("polygonLight", EffectResource.polygonLightBytes); _lightEffect.Parameters["lightRadius"].SetValue(radius); _visibility = new VisibilityComputer(); }