File Skybox.cs
File List > Render > src > Skybox.cs
Go to the documentation of this file.
using System;
using System.Drawing;
using Qkmaxware.Geometry;
namespace Qkmaxware.Rendering {
public class Skybox {
public virtual Color GetPixel(BaseCamera camera, int x, int y) {
return Color.Black;
}
}
public class SolidSkybox : Skybox {
public Color Colour {get; private set;}
public SolidSkybox() {
this.Colour = Color.Black;
}
public SolidSkybox(Color colour) {
this.Colour = colour;
}
public override Color GetPixel(BaseCamera camera, int x, int y) {
return this.Colour;
}
}
public class GradientSkybox : Skybox {
private Color bottom;
private Color top;
public GradientSkybox(Color first, Color second) {
this.bottom = first;
this.top = second;
}
private static Color Blend(Color backColor, Color color, double amount) {
byte r = (byte) ((color.R * amount) + backColor.R * (1 - amount));
byte g = (byte) ((color.G * amount) + backColor.G * (1 - amount));
byte b = (byte) ((color.B * amount) + backColor.B * (1 - amount));
return Color.FromArgb(r, g, b);
}
public override Color GetPixel(BaseCamera camera, int x, int y) {
// Use angles from polar coorinates
var point = camera.ScreenToWorldPoint(new Vec2(x,y));
var z = point.Z;
var length = point.Length;
if (length == 0) {
return top;
} else {
var vangle = Math.Acos(z / length);
var interpolation_factor = vangle / Math.PI; // angles are 0deg to 180deg (0 to Pi radians)
return Blend(bottom, top, interpolation_factor);
}
}
}
public class TexturedSkybox : Skybox {
public Texture2D Texture {get; private set;}
public TexturedSkybox(Texture2D texture) {
this.Texture = texture;
}
public override Color GetPixel(BaseCamera camera, int x, int y) {
var point = camera.ScreenToWorldPoint(new Vec2(x,y));
var z = point.Z;
var length = point.Length;
if (length == 0)
return Color.White;
// Vertical angle (0 - 180deg)
var vangle = Math.Acos(z / length);
var v_interpolation_factor = vangle / Math.PI;
var uvy = (int)(Texture.Height * v_interpolation_factor);
// Horizontal angle (0 - 360deg)
var hangle = Math.Asin( point.Y / (length * Math.Sin(vangle)) ) + (Math.PI * 0.5);
var h_interpolation_factor = hangle / (2 * Math.PI);
var uvx = (int)(Texture.Width * h_interpolation_factor);
return this.Texture[uvy, uvx];
}
}
}