2006-10-12 00:10:29 +02:00
#region License
2006-10-10 00:35:25 +02:00
/ * Copyright ( c ) 2006 Stephen Apostolopoulos
* See license . txt for license info
* /
#endregion
using System ;
using System.Collections.Generic ;
using System.Text ;
using System.Windows.Forms ;
using System.Drawing ;
using System.Threading ;
using OpenTK.Platform.Windows ;
using System.Runtime.InteropServices ;
2006-10-11 23:42:22 +02:00
using OpenTK.OpenGL.Platform ;
2006-10-12 00:10:29 +02:00
using OpenTK.OpenGL ;
2006-10-10 00:35:25 +02:00
2006-10-12 00:10:29 +02:00
namespace OpenTK
2006-10-10 00:35:25 +02:00
{
2006-10-11 23:42:22 +02:00
public class Framework : Form , IDisposable
2006-10-10 00:35:25 +02:00
{
#region Context
private GLContext _context ;
public GLContext Context
{
get { return _context ; }
set { _context = value ; }
}
#endregion
2006-10-11 23:42:22 +02:00
delegate bool IsIdleDelegate ( ) ;
IsIdleDelegate IsIdle ;
2006-10-10 00:35:25 +02:00
#region Constructors
2006-10-11 23:42:22 +02:00
public Framework ( )
2006-10-10 00:35:25 +02:00
{
Open ( null , 640 , 480 , 8 , 8 , 8 , 8 , 16 , 0 , false ) ;
}
2006-10-11 23:42:22 +02:00
public Framework ( string title , int width , int height , int red , int green , int blue , int alpha , int depth , int stencil , bool fullscreen )
{
Open ( title , width , height , red , green , blue , alpha , depth , stencil , fullscreen ) ;
}
2006-10-12 00:10:29 +02:00
2006-10-10 00:35:25 +02:00
#endregion
public void Open ( string title , int width , int height , int red , int green , int blue , int alpha , int depth , int stencil , bool fullscreen )
2006-10-11 23:42:22 +02:00
{
Application . Idle + = new EventHandler ( OnIdle ) ;
try
{
if ( Environment . OSVersion . Platform = = PlatformID . Win32NT | |
Environment . OSVersion . Platform = = PlatformID . Win32Windows )
{
IsIdle = new IsIdleDelegate ( WindowsIsIdle ) ;
WindowsOpen ( title , width , height , red , green , blue , alpha , depth , stencil , fullscreen ) ;
}
else if ( Environment . OSVersion . Platform = = PlatformID . Unix )
{
IsIdle = new IsIdleDelegate ( XIsIdle ) ;
}
else
{
throw new PlatformNotSupportedException ( "The platform on which you are trying to run this program is not currently supported. Sorry for the inconvenience." ) ;
}
}
catch ( Exception e )
{
MessageBox . Show ( e . ToString ( ) ) ;
}
}
public void WindowsOpen ( string title , int width , int height , int red , int green , int blue , int alpha , int depth , int stencil , bool fullscreen )
2006-10-10 00:35:25 +02:00
{
// Hack! Should add more constructors to the GLContext class.
Context = GLContext . Create ( this , 8 , 8 , 8 , 8 , 16 , 0 ) ;
// Todo: Why doesn't this work?
if ( title = = null )
title = "OpenTK application" ;
this . Text = title ;
// Code taken from NeHe tutorials
this . CreateParams . Style | = ( int ) Api . WindowClassStyle . HRedraw | ( int ) Api . WindowClassStyle . VRedraw | ( int ) Api . WindowClassStyle . OwnDC ;
this . SetStyle ( ControlStyles . AllPaintingInWmPaint , true ) ; // No Need To Erase Form Background
this . SetStyle ( ControlStyles . Opaque , true ) ; // No Need To Draw Form Background
//this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); // Buffer Control
//this.SetStyle(ControlStyles.ResizeRedraw, true); // Redraw On Resize
this . SetStyle ( ControlStyles . UserPaint , true ) ; // We'll Handle Painting Ourselves
if ( fullscreen )
{
Api . DeviceMode ScreenSettings = new Api . DeviceMode ( ) ; // Device Mode
ScreenSettings . Size = ( short ) Marshal . SizeOf ( ScreenSettings ) ; // Size Of The Devmode Structure
ScreenSettings . PelsWidth = width ; // Selected Screen Width
ScreenSettings . PelsHeight = height ; // Selected Screen Height
ScreenSettings . BitsPerPel = red + green + blue + alpha ; // Selected Bits Per Pixel
ScreenSettings . Fields = Api . Constants . DM_BITSPERPEL | Api . Constants . DM_PELSWIDTH | Api . Constants . DM_PELSHEIGHT ;
// Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.
if ( Api . ChangeDisplaySettings ( ref ScreenSettings , Api . Constants . CDS_FULLSCREEN ) = = Api . Constants . DISP_CHANGE_SUCCESSFUL )
{
this . FormBorderStyle = FormBorderStyle . None ;
this . StartPosition = FormStartPosition . Manual ;
this . Location = new System . Drawing . Point ( 0 , 0 ) ;
this . Region = new Region ( new Rectangle ( 0 , 0 , width , height ) ) ;
this . Capture = true ;
this . SetTopLevel ( true ) ;
Cursor . Hide ( ) ;
}
else
{
// Handle failure.
}
}
this . Size = new Size ( width , height ) ;
// Cross-platformness?
2006-10-11 23:42:22 +02:00
2006-10-10 00:35:25 +02:00
}
2006-10-11 23:42:22 +02:00
//override protected void WndProc(ref Message m)
//{
// base.WndProc(ref m);
// //OnPaint(null);
//}
#region IDisposable Members
void IDisposable . Dispose ( )
{
Application . Idle - = OnIdle ;
}
#endregion
#region Event Handlers
2006-10-10 00:35:25 +02:00
/// <summary>
/// Called when all pending messages have been processed, this is where the application 'Main Loop' resides.
/// </summary>
/// <param name="sender">Not used.</param>
/// <param name="e">Not used.</param>
2006-10-11 23:42:22 +02:00
private void OnIdle ( object sender , EventArgs e )
2006-10-10 00:35:25 +02:00
{
2006-10-11 23:42:22 +02:00
while ( IsIdle ( ) )
{
if ( ActiveForm ! = this )
Thread . Sleep ( 100 ) ;
OnPaint ( null ) ;
}
2006-10-10 00:35:25 +02:00
}
/// <summary>
/// Checks if there all pending messages have been processed.
/// </summary>
/// <returns>Returns true if there are no messages left, false otherwise.</returns>
2006-10-11 23:42:22 +02:00
private bool WindowsIsIdle ( )
2006-10-10 00:35:25 +02:00
{
2006-10-11 23:42:22 +02:00
Api . Message msg ;
return ! OpenTK . Platform . Windows . Api . PeekMessage ( out msg , IntPtr . Zero , 0 , 0 , 0 ) ;
2006-10-10 00:35:25 +02:00
}
2006-10-11 23:42:22 +02:00
private bool XIsIdle ( )
2006-10-10 00:35:25 +02:00
{
2006-10-11 23:42:22 +02:00
throw new NotImplementedException ( "IsIdle handler not implemented yet!" ) ;
2006-10-10 00:35:25 +02:00
}
#endregion
}
}