mirror of
https://github.com/Ryujinx/Opentk.git
synced 2025-03-30 09:27:01 +00:00
Added anaglyph rendering example (for red/cyan glasses).
This commit is contained in:
parent
c9502aae54
commit
ceca4403ad
204
Source/Examples/OpenGL/1.x/Anaglyph.cs
Normal file
204
Source/Examples/OpenGL/1.x/Anaglyph.cs
Normal file
|
@ -0,0 +1,204 @@
|
|||
using System;
|
||||
using System.Drawing;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
using OpenTK.Input;
|
||||
|
||||
namespace Examples.Tutorial
|
||||
{
|
||||
[Example( "Anaglyph Stereo", ExampleCategory.OpenGL, "1.x", Documentation = "Anaglyph" )]
|
||||
|
||||
class Anaglyph : GameWindow
|
||||
{
|
||||
|
||||
Examples.Shapes.DrawableShape Object;
|
||||
|
||||
/// <summary>Creates a 800x600 window with the specified title.</summary>
|
||||
public Anaglyph()
|
||||
: base(800, 600, GraphicsMode.Default, "OpenTK Quick Start Sample", GameWindowFlags.Default, DisplayDevice.Default, 3, 1, GraphicsContextFlags.Default)
|
||||
{
|
||||
VSync = VSyncMode.On;
|
||||
}
|
||||
|
||||
/// <summary>Load resources here.</summary>
|
||||
/// <param name="e">Not used.</param>
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
base.OnLoad(e);
|
||||
|
||||
GL.ClearColor(System.Drawing.Color.Black);
|
||||
GL.Enable(EnableCap.DepthTest);
|
||||
|
||||
GL.Enable( EnableCap.Lighting );
|
||||
GL.Enable( EnableCap.Light0 );
|
||||
|
||||
Object = new Examples.Shapes.MengerSponge(1.0, Shapes.MengerSponge.eSubdivisions.Two, true );
|
||||
// Object = new Examples.Shapes.TorusKnot( 256, 32, 0.1, 3, 4, 1, true );
|
||||
}
|
||||
|
||||
protected override void OnUnload( EventArgs e )
|
||||
{
|
||||
base.OnUnload( e );
|
||||
|
||||
Object.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when your window is resized. Set your viewport here. It is also
|
||||
/// a good place to set up your projection matrix (which probably changes
|
||||
/// along when the aspect ratio of your window).
|
||||
/// </summary>
|
||||
/// <param name="e">Not used.</param>
|
||||
protected override void OnResize(EventArgs e)
|
||||
{
|
||||
base.OnResize(e);
|
||||
|
||||
GL.Viewport(ClientRectangle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when it is time to setup the next frame. Add you game logic here.
|
||||
/// </summary>
|
||||
/// <param name="e">Contains timing information for framerate independent logic.</param>
|
||||
protected override void OnUpdateFrame(FrameEventArgs e)
|
||||
{
|
||||
base.OnUpdateFrame(e);
|
||||
|
||||
if (Keyboard[Key.Escape])
|
||||
Exit();
|
||||
}
|
||||
|
||||
struct Camera
|
||||
{
|
||||
public Vector3 Position, Direction, Up;
|
||||
public double NearPlane, FarPlane;
|
||||
public double EyeSeparation;
|
||||
public double Aperture; // FOV in degrees
|
||||
public double FocalLength;
|
||||
}
|
||||
|
||||
enum Eye
|
||||
{
|
||||
left,
|
||||
right,
|
||||
}
|
||||
|
||||
void SetupCamera( Eye eye )
|
||||
{
|
||||
Camera camera;
|
||||
|
||||
camera.Position = Vector3.UnitZ;
|
||||
camera.Up = Vector3.UnitY;
|
||||
camera.Direction = -Vector3.UnitZ;
|
||||
camera.NearPlane = 1.0;
|
||||
camera.FarPlane = 5.0;
|
||||
camera.FocalLength = 2.0;
|
||||
camera.EyeSeparation = camera.FocalLength / 30.0;
|
||||
camera.Aperture = 75.0;
|
||||
|
||||
double left, right,
|
||||
bottom, top;
|
||||
|
||||
double widthdiv2 = camera.NearPlane * Math.Tan( MathHelper.DegreesToRadians( (float)( camera.Aperture / 2.0 ) ) ); // aperture in radians
|
||||
double precalc1 = ClientRectangle.Width / (double)ClientRectangle.Height * widthdiv2;
|
||||
double precalc2 = 0.5 * camera.EyeSeparation * camera.NearPlane / camera.FocalLength;
|
||||
|
||||
Vector3 Right = Vector3.Cross( camera.Direction, camera.Up ); // Each unit vectors
|
||||
Right.Normalize();
|
||||
|
||||
Right.X *= (float)( camera.EyeSeparation / 2.0 );
|
||||
Right.Y *= (float)( camera.EyeSeparation / 2.0 );
|
||||
Right.Z *= (float)( camera.EyeSeparation / 2.0 );
|
||||
|
||||
// Projection Matrix
|
||||
top = widthdiv2;
|
||||
bottom = -widthdiv2;
|
||||
if ( eye == Eye.right )
|
||||
{
|
||||
left = -precalc1 - precalc2;
|
||||
right = precalc1 - precalc2;
|
||||
}
|
||||
else
|
||||
{
|
||||
left = -precalc1 + precalc2;
|
||||
right = precalc1 + precalc2;
|
||||
}
|
||||
|
||||
GL.MatrixMode( MatrixMode.Projection );
|
||||
GL.LoadIdentity();
|
||||
GL.Frustum( left, right, bottom, top, camera.NearPlane, camera.FarPlane );
|
||||
|
||||
// Modelview Matrix
|
||||
Matrix4 modelview;
|
||||
if ( eye == Eye.right )
|
||||
{
|
||||
modelview = Matrix4.LookAt(
|
||||
new Vector3( camera.Position.X + Right.X, camera.Position.Y + Right.Y, camera.Position.Z + Right.Z ),
|
||||
new Vector3( camera.Position.X + Right.X + camera.Direction.X, camera.Position.Y + Right.Y + camera.Direction.Y, camera.Position.Z + Right.Z + camera.Direction.Z ),
|
||||
camera.Up );
|
||||
}
|
||||
else
|
||||
{
|
||||
modelview = Matrix4.LookAt(
|
||||
new Vector3( camera.Position.X - Right.X, camera.Position.Y - Right.Y, camera.Position.Z - Right.Z ),
|
||||
new Vector3( camera.Position.X - Right.X + camera.Direction.X, camera.Position.Y - Right.Y + camera.Direction.Y, camera.Position.Z - Right.Z + camera.Direction.Z ),
|
||||
camera.Up );
|
||||
}
|
||||
GL.MatrixMode( MatrixMode.Modelview );
|
||||
GL.LoadIdentity();
|
||||
GL.MultMatrix( ref modelview );
|
||||
|
||||
}
|
||||
|
||||
float Angle;
|
||||
|
||||
void Draw()
|
||||
{
|
||||
GL.Translate( 0f, 0f, -2f );
|
||||
GL.Rotate( Angle, Vector3.UnitY );
|
||||
Object.Draw();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when it is time to render the next frame. Add your rendering code here.
|
||||
/// </summary>
|
||||
/// <param name="e">Contains timing information.</param>
|
||||
protected override void OnRenderFrame( FrameEventArgs e )
|
||||
{
|
||||
Angle += (float)(e.Time *20.0);
|
||||
|
||||
|
||||
GL.Clear( ClearBufferMask.DepthBufferBit | ClearBufferMask.ColorBufferBit );
|
||||
SetupCamera( Eye.right );
|
||||
GL.ColorMask( true, false, false, true );
|
||||
Draw();
|
||||
|
||||
GL.Clear( ClearBufferMask.DepthBufferBit ); //
|
||||
SetupCamera( Eye.left );
|
||||
GL.ColorMask( false, true, true, true );
|
||||
Draw();
|
||||
|
||||
GL.ColorMask( true, true, true, true );
|
||||
SwapBuffers();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
// The 'using' idiom guarantees proper resource cleanup.
|
||||
// We request 30 UpdateFrame events per second, and unlimited
|
||||
// RenderFrame events (as fast as the computer can handle).
|
||||
using (Anaglyph game = new Anaglyph())
|
||||
{
|
||||
game.Run(10.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
BIN
Source/Examples/OpenGL/1.x/Anaglyph.rtf
Normal file
BIN
Source/Examples/OpenGL/1.x/Anaglyph.rtf
Normal file
Binary file not shown.
|
@ -143,7 +143,10 @@
|
|||
<Compile Include="ExampleInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="OpenGL\1.x\OpenGLDiagnostics.cs" />
|
||||
<Compile Include="OpenGL\1.x\Anaglyph.cs" />
|
||||
<Compile Include="OpenGL\1.x\OpenGLDiagnostics.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="SamplesTreeViewSorter.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
|
@ -545,6 +548,7 @@
|
|||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<EmbeddedResource Include="OpenGL\1.x\OpenGLDiagnostics.rtf" />
|
||||
<EmbeddedResource Include="OpenGL\1.x\Anaglyph.rtf" />
|
||||
<None Include="Resources\App.ico">
|
||||
</None>
|
||||
<None Include="..\OpenTK\OpenTK.dll.config">
|
||||
|
|
Loading…
Reference in a new issue