mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-01-22 17:12:25 -05:00
113 lines
4.5 KiB
C#
113 lines
4.5 KiB
C#
using System;
|
|
using OpenTK;
|
|
using OpenTK.Graphics.OpenGL;
|
|
|
|
namespace ClassicalSharp.GraphicsAPI {
|
|
|
|
public abstract class ShadowMap {
|
|
|
|
public Vector3 LightPosition = new Vector3( 256, 160, 256 );
|
|
public Vector3 LightTarget = new Vector3( 128, 128, 128 );
|
|
public Matrix4 ShadowMatrix;
|
|
|
|
public abstract void Create( int width, int height );
|
|
|
|
public abstract void BindForReading( IGraphicsApi graphics );
|
|
|
|
public abstract void BindForWriting( IGraphicsApi graphics );
|
|
|
|
public abstract void UnbindForWriting( IGraphicsApi graphics );
|
|
|
|
public abstract void SetupState( IGraphicsApi graphics, Game game );
|
|
|
|
public abstract void RestoreState( IGraphicsApi graphics, Game g );
|
|
|
|
public abstract void Dispose();
|
|
}
|
|
|
|
public sealed class OpenGLShadowMap : ShadowMap {
|
|
|
|
int depthTextureId, fboId;
|
|
int fboWidth, fboHeight;
|
|
public override void Create( int width, int height ) {
|
|
GL.GenTextures( 1, out depthTextureId );
|
|
GL.BindTexture( TextureTarget.Texture2D, depthTextureId );
|
|
|
|
//GL.TexParameter( TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear );
|
|
//GL.TexParameter( TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear );
|
|
GL.TexParameter( TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Nearest );
|
|
GL.TexParameter( TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Nearest );
|
|
GL.TexParameter( TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.Clamp );
|
|
GL.TexParameter( TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.Clamp );
|
|
GL.TexImage2D( TextureTarget.Texture2D, 0, PixelInternalFormat.DepthComponent,
|
|
width, height, 0, PixelFormat.DepthComponent,
|
|
PixelType.UnsignedByte, IntPtr.Zero );
|
|
GL.BindTexture( TextureTarget.Texture2D, 0 );
|
|
|
|
GL.Ext.GenFramebuffers( 1, out fboId );
|
|
GL.Ext.BindFramebuffer( FramebufferTarget.Framebuffer, fboId );
|
|
GL.DrawBuffer( DrawBufferMode.None );
|
|
GL.ReadBuffer( (ReadBufferMode)DrawBufferMode.None );
|
|
|
|
GL.Ext.FramebufferTexture2D( FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment,
|
|
TextureTarget.Texture2D, depthTextureId, 0 );
|
|
FramebufferErrorCode status = GL.Ext.CheckFramebufferStatus( FramebufferTarget.Framebuffer );
|
|
if( status != FramebufferErrorCode.FramebufferComplete ) Console.WriteLine( "ERROR FBO: " + status );
|
|
|
|
GL.Ext.BindFramebuffer( FramebufferTarget.Framebuffer, 0 );
|
|
fboWidth = width;
|
|
fboHeight = height;
|
|
}
|
|
|
|
public override void BindForReading( IGraphicsApi graphics ) {
|
|
GL.Arb.ActiveTexture( TextureUnit.Texture1 );
|
|
GL.BindTexture( TextureTarget.Texture2D, depthTextureId );
|
|
GL.Arb.ActiveTexture( TextureUnit.Texture0 );
|
|
}
|
|
|
|
public override void BindForWriting( IGraphicsApi graphics ) {
|
|
GL.Ext.BindFramebuffer( FramebufferTarget.Framebuffer, fboId );
|
|
}
|
|
|
|
public override void UnbindForWriting( IGraphicsApi graphics ) {
|
|
GL.Ext.BindFramebuffer( FramebufferTarget.Framebuffer, 0 );
|
|
}
|
|
|
|
public override void SetupState( IGraphicsApi graphics, Game game ) {
|
|
graphics.SetMatrixMode( MatrixType.Projection );
|
|
graphics.PushMatrix();
|
|
Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView(
|
|
(float)Math.PI / 4, game.Width / (float)game.Height, 1, 1000 );
|
|
graphics.LoadMatrix( ref projection );
|
|
|
|
graphics.SetMatrixMode( MatrixType.Modelview );
|
|
graphics.PushMatrix();
|
|
Matrix4 modelview = Matrix4.LookAt( LightPosition, LightTarget, Vector3.UnitY );
|
|
graphics.LoadMatrix( ref modelview );
|
|
ShadowMatrix = modelview * projection * bias;
|
|
graphics.ColourMask( false, false, false, false );
|
|
GL.Viewport( 0, 0, fboWidth, fboHeight );
|
|
GL.Clear( ClearBufferMask.DepthBufferBit );
|
|
}
|
|
|
|
public override void RestoreState( IGraphicsApi graphics, Game game ) {
|
|
graphics.SetMatrixMode( MatrixType.Projection );
|
|
graphics.PopMatrix();
|
|
graphics.SetMatrixMode( MatrixType.Modelview );
|
|
graphics.PopMatrix();
|
|
graphics.ColourMask( true, true, true, true );
|
|
GL.Viewport( 0, 0, game.Width, game.Height );
|
|
}
|
|
static Matrix4 bias = new Matrix4(
|
|
0.5f, 0.0f, 0.0f, 0.0f,
|
|
0.0f, 0.5f, 0.0f, 0.0f,
|
|
0.0f, 0.0f, 0.5f, 0.0f,
|
|
0.5f, 0.5f, 0.5f, 1.0f
|
|
);
|
|
|
|
public override void Dispose() {
|
|
GL.DeleteTexture( depthTextureId );
|
|
GL.Ext.DeleteFramebuffers( 1, ref fboId );
|
|
}
|
|
}
|
|
}
|