Esempio n. 1
0
        private LitShaderDescription setupEntityLight(Entity entity, Matrix4 modelViewMatrix, bool skin)
        {
            // Calculate lighting
            if(entity.Self?.Room == null)
            {
                var shader = ShaderManager.GetEntityShader(0, skin);
                GL.UseProgram(shader.Program);
                return shader;
            }

            var room = entity.Self.Room;

            var ambientComponent = new[]
            {
                room.AmbientLighting[0],
                room.AmbientLighting[1],
                room.AmbientLighting[2],
                1.0f
            };

            if(room.Flags.HasFlagUns(RoomFlag.Water))
            {
                EngineWorld.CalculateWaterTint(ambientComponent, false);
            }

            var currentLightNumber = 0;

            var positions = new float[MAX_NUM_LIGHTS * 3];
            var colors = new float[MAX_NUM_LIGHTS * 4];
            var innerRadiuses = new float[MAX_NUM_LIGHTS * 1];
            var outerRadiuses = new float[MAX_NUM_LIGHTS * 1];

            for (var i = 0; i < room.Lights.Count && currentLightNumber < MAX_NUM_LIGHTS; i++)
            {
                var currentLight = room.Lights[i];

                var xyz = entity.Transform.Origin - currentLight.Position;
                var distance = xyz.Length;

                // Find color
                for (var j = 0; j < 4; j++)
                    colors[currentLightNumber * 4 + i] = Math.Min(Math.Max(currentLight.Colour[i], 0.0f), 1.0f);

                if (room.Flags.HasFlagUns(RoomFlag.Water))
                {
                    unsafe
                    {
                        fixed (float* ptr = colors)
                            EngineWorld.CalculateWaterTint(&ptr[currentLightNumber * 4],
                                false);
                    }
                }

                // Find position
                var tmpPos = modelViewMatrix.MultiplyByQuaternion(currentLight.Position.ToQuat());
                Array.Copy(tmpPos.ToArray(), 0, positions, currentLightNumber * 3, 3);

                // Find fall-off
                if(currentLight.LightType == LightType.Sun)
                {
                    innerRadiuses[currentLightNumber] = 1e20f;
                    outerRadiuses[currentLightNumber] = 1e21f;
                    currentLightNumber++;
                }
                else if (distance <= currentLight.Outer + 1024.0f &&
                         (currentLight.LightType == LightType.Point || currentLight.LightType == LightType.Shadow))
                {
                    innerRadiuses[currentLightNumber] = Math.Abs(currentLight.Inner);
                    outerRadiuses[currentLightNumber] = Math.Abs(currentLight.Outer);
                    currentLightNumber++;
                }
            }

            {
                var shader = ShaderManager.GetEntityShader(currentLightNumber, skin);
                GL.UseProgram(shader.Program);
                GL.Uniform4(shader.LightAmbient, 1, ambientComponent);
                GL.Uniform4(shader.LightPosition, currentLightNumber, colors);
                GL.Uniform3(shader.LightPosition, currentLightNumber, positions);
                GL.Uniform1(shader.LightInnerRadius, currentLightNumber, innerRadiuses);
                GL.Uniform1(shader.LightOuterRadius, currentLightNumber, outerRadiuses);
                return shader;
            }
        }