Created branch for Mac OS support.

This commit is contained in:
kanato 2008-11-04 16:50:31 +00:00
commit 7b1c546abd
51 changed files with 1746 additions and 442 deletions

View file

@ -1,8 +1,19 @@
[Legend: complete('+') | WIP('*') | missing('-')]
-----------------------
---------------------
OpenTK 0.9.1 -> 0.9.2
---------------------
+ OpenTK
+ Platform
+ Added GdiPlus bindings.
+ Utilities
+ Fonts
+ Updated the layout code to use the new GdiPlus bindings.
---------------------
OpenTK 0.9.0 -> 0.9.1
-----------------------
---------------------
+ Bind
+ Corrected Glu.NewTess and Glu.DeleteTess (were NewTes and DeleteTes respectively).
+ Corrected typemaping for NurbsObj, QuadricObj, TesselatorObj and FunctionPointer.

View file

@ -173,10 +173,15 @@ Extensions define:
###############################################################################
#
# Edited by Stefanos Apostolopoulos for OpenTK. Revision 2
# Edited by Stefanos Apostolopoulos for OpenTK. Revision 3
#
###############################################################################
StencilFace enum:
use DrawBufferMode FRONT
use DrawBufferMode BACK
use DrawBufferMode FRONT_AND_BACK
DrawElementsType enum:
use DataType UNSIGNED_BYTE
use DataType UNSIGNED_SHORT
@ -285,15 +290,18 @@ AlphaFunction enum:
###############################################################################
# Edited for OpenTK
BlendingFactorDest enum:
ZERO = 0
ONE = 1
ONE = 1
SRC_COLOR = 0x0300
ONE_MINUS_SRC_COLOR = 0x0301
ONE_MINUS_SRC_COLOR = 0x0301
DST_COLOR = 0x0306
ONE_MINUS_DST_COLOR = 0x0307
SRC_ALPHA = 0x0302
ONE_MINUS_SRC_ALPHA = 0x0303
ONE_MINUS_SRC_ALPHA = 0x0303
DST_ALPHA = 0x0304
ONE_MINUS_DST_ALPHA = 0x0305
ONE_MINUS_DST_ALPHA = 0x0305
use EXT_blend_color CONSTANT_COLOR_EXT
use EXT_blend_color ONE_MINUS_CONSTANT_COLOR_EXT
use EXT_blend_color CONSTANT_ALPHA_EXT
@ -301,16 +309,19 @@ BlendingFactorDest enum:
###############################################################################
# Edited for OpenTK
BlendingFactorSrc enum:
use BlendingFactorDest ZERO
use BlendingFactorDest ONE
DST_COLOR = 0x0306
ONE_MINUS_DST_COLOR = 0x0307
SRC_ALPHA_SATURATE = 0x0308
use BlendingFactorDest SRC_COLOR
use BlendingFactorDest ONE_MINUS_SRC_COLOR
use BlendingFactorDest DST_COLOR
use BlendingFactorDest ONE_MINUS_DST_COLOR
use BlendingFactorDest SRC_ALPHA
use BlendingFactorDest ONE_MINUS_SRC_ALPHA
use BlendingFactorDest DST_ALPHA
use BlendingFactorDest ONE_MINUS_DST_ALPHA
SRC_ALPHA_SATURATE = 0x0308
use EXT_blend_color CONSTANT_COLOR_EXT
use EXT_blend_color ONE_MINUS_CONSTANT_COLOR_EXT
use EXT_blend_color CONSTANT_ALPHA_EXT

View file

@ -5868,12 +5868,14 @@ StencilOpSeparate(face, sfail, dpfail, dppass)
glsopcode ?
offset ?
StencilFuncSeparate(frontfunc, backfunc, ref, mask)
# Edited for OpenTK
StencilFuncSeparate(face, func, ref, mask)
return void
param frontfunc StencilFunction in value
param backfunc StencilFunction in value
param face StencilFace in value
param func StencilFunction in value
param ref ClampedStencilValue in value
param mask MaskedStencilValue in value
param mask MaskedStencilValue in value
category VERSION_2_0
version 2.0
extension

View file

@ -32,7 +32,7 @@ namespace OpenTK.Build
static string PrebuildXml = Path.Combine(ToolPath, "Prebuild.xml");
static Regex DataFiles = new Regex(@"^.*\.(bmp|png|jpg|txt|glsl|wav|ogg)$",
static Regex DataFiles = new Regex(@"^.*\.(bmp|png|jpg|txt|glsl|wav|ogg)$",
RegexOptions.Compiled | RegexOptions.IgnoreCase);
enum BuildMode

View file

@ -25,7 +25,7 @@ namespace Examples.OpenAL
const int buffer_size = (int)(0.5*44100);
const int buffer_count = 4;
static object openal_lock = new object(); // Should be global in your app.
//static object openal_lock = new object(); // Should be global in your app.
public static void Main()
{

View file

@ -164,9 +164,31 @@ namespace Examples.Tutorial
PixelType.UnsignedByte, data.Scan0);
bitmap.UnlockBits(data);
}
#endregion Textures
#endregion Textures
Keyboard.KeyUp += KeyUp;
}
int i = 0;
void KeyUp(OpenTK.Input.KeyboardDevice sender, OpenTK.Input.Key e)
{
if (e == OpenTK.Input.Key.F12)
{
Bitmap bmp = new Bitmap(this.Width, this.Height);
System.Drawing.Imaging.BitmapData data =
bmp.LockBits(new Rectangle(0, 0, this.Width, this.Height),
System.Drawing.Imaging.ImageLockMode.WriteOnly,
System.Drawing.Imaging.PixelFormat.Format24bppRgb);
GL.ReadPixels(0, 0, this.Width, this.Height,
OpenTK.Graphics.PixelFormat.Bgr,
OpenTK.Graphics.PixelType.UnsignedByte,
data.Scan0);
bmp.UnlockBits(data);
bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);
bmp.Save("Screenshot" + (i++).ToString() + ".png", ImageFormat.Png);
}
}
#endregion
#region OnUnLoad
@ -219,7 +241,7 @@ namespace Examples.Tutorial
if (Keyboard[OpenTK.Input.Key.Escape])
{
this.Exit();
}
}
}
#endregion

View file

@ -0,0 +1,69 @@
#region --- License ---
/* Licensed under the MIT/X11 license.
* Copyright (c) 2006-2008 the OpenTK team.
* This notice may not be removed.
* See license.txt for licensing detailed licensing details.
*/
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;
#if false
using System.Xml.Serialization;
using OpenTK.Math;
namespace Examples.Tests
{
[Example("Serialization", ExampleCategory.Test)]
public class MathSerialization
{
public static void Main()
{
using (MemoryStream stream = new MemoryStream())
{
XmlSerializer xs = new XmlSerializer(typeof(Matrix4));
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.NewLineHandling = NewLineHandling.Entitize;
settings.Indent = true;
XmlWriter xw = XmlTextWriter.Create(stream, settings);
xs.Serialize(xw, Matrix4.Identity);
xw.Close();
}
stream.Position = 0;
byte[] text = new byte[stream.Length];
int pos = 0;
do
{
pos += stream.Read(text, pos, (int)stream.Length);
}
while (pos != stream.Length);
Console.WriteLine(System.Text.Encoding.Default.GetChars(text));
stream.Position = 0;
Matrix4 matrix = (Matrix4)xs.Deserialize(stream);
if (Matrix4.Identity == matrix)
Console.WriteLine("Matrix deserialized correctly.");
else
Console.WriteLine("Error deserializing matrix.");
Console.WriteLine("Press any key to continue...");
Console.ReadKey(false);
}
}
}
}
#endif

View file

@ -16,7 +16,8 @@ namespace Examples.Tests
public class MathSpeed
{
public static void Main()
{
{
/*
Stopwatch watch = new Stopwatch();
Vector3 a = new Vector3(0.0f, 0.0f, 0.0f);
@ -31,7 +32,7 @@ namespace Examples.Tests
Vector3.Add(ref a, ref b, out res);
res = a + b;
res = Vector3.Zero;
/*
watch.Reset();
watch.Start();
for (int i = 100000000; --i != 0; )
@ -82,12 +83,12 @@ namespace Examples.Tests
*/
}
static Vector3 pos = new Vector3();
//static Vector3 pos = new Vector3();
static Vector3 Pos
{
get { return pos; }
set { pos = value; }
}
//static Vector3 Pos
//{
// get { return pos; }
// set { pos = value; }
//}
}
}

View file

@ -175,10 +175,11 @@ namespace Examples.Tutorial
}
// Move to the right, and print using the second font.
float width, height;
fonts[handles.Length / 2 - 1].MeasureString(text, out width, out height);
//float width, height;
//fonts[handles.Length / 2 - 1].MeasureString(text, out width, out height);
RectangleF rect = fonts[handles.Length / 2 - 1].MeasureText(text);
GL.LoadIdentity();
GL.Translate(width + 32.0f, 0, 0);
GL.Translate(rect.Width + 32.0f, 0, 0);
for (int i = handles.Length / 2; i < handles.Length; i++)
{
printer.Draw(handles[i]);

View file

@ -30,8 +30,8 @@ namespace Examples.Tutorial
float angle = 0.0f;
Shapes.Shape shape = new Examples.Shapes.Plane(16, 16, 2.0f, 2.0f);
TextureFont sans = new TextureFont(new Font(FontFamily.GenericSansSerif, 32, FontStyle.Regular,
GraphicsUnit.Pixel));
//TextureFont sans = new TextureFont(new Font(FontFamily.GenericSansSerif, 32, FontStyle.Regular,
// GraphicsUnit.Pixel));
#region Constructor

View file

@ -27,7 +27,7 @@ namespace Examples.Tutorial
#region --- Private Fields ---
Shapes.Shape cube = new Examples.Shapes.Cube();
Shapes.Shape plane = new Examples.Shapes.Plane(16, 16, 2.0f, 2.0f);
//Shapes.Shape plane = new Examples.Shapes.Plane(16, 16, 2.0f, 2.0f);
struct Vbo
{

View file

@ -45,7 +45,7 @@ namespace Examples.Tutorial
public override void OnLoad(EventArgs e)
{
GL.ClearColor(Color.SteelBlue);
current_position = initial_position;
scroll_speed = -1.0f;
text.Prepare(poem, serif, out poem_handle);
@ -125,7 +125,7 @@ namespace Examples.Tutorial
// used in 2d graphics, and is necessary for achieving pixel-perfect glyph rendering.
// TextPrinter.End() restores your previous projection/modelview matrices.
text.Begin();
GL.Color3(Color.PaleGoldenrod);
GL.Color3(Color.LightBlue);
text.Draw((1.0 / e.Time).ToString("F2"), sans);
GL.Translate(0.0f, current_position, 0.0f);
GL.Color3(Color.White);

View file

@ -13,7 +13,12 @@ namespace Examples.WinForms
{
public partial class DerivedGLControl : GLControl
{
Color clearColor;
Color clearColor;
public DerivedGLControl()
{
this.InitializeComponent();
}
public Color ClearColor
{

View file

@ -27,7 +27,7 @@ namespace Examples.WinForms
GLControl glControl = new GLControl(GraphicsMode.Default);
Type glClass;
Type delegatesClass;
Type importsClass;
//Type importsClass;
int supported, all; // Number of supported extensions.
string driver;
@ -37,7 +37,7 @@ namespace Examples.WinForms
glClass = typeof(GL);
delegatesClass = glClass.GetNestedType("Delegates", BindingFlags.Static | BindingFlags.NonPublic);
importsClass = glClass.GetNestedType("Imports", BindingFlags.Static | BindingFlags.NonPublic);
//importsClass = glClass.GetNestedType("Imports", BindingFlags.Static | BindingFlags.NonPublic);
glControl.CreateControl();
Application.Idle += StartAsync;

View file

@ -256,12 +256,12 @@ namespace OpenTK.Audio
if (!String.IsNullOrEmpty(device))
device_handle = Alc.OpenDevice(device);
if (device_handle == IntPtr.Zero)
device_handle = Alc.OpenDevice(null);
if (device_handle == IntPtr.Zero)
Alc.OpenDevice(Alc.GetString(IntPtr.Zero, AlcGetString.DefaultDeviceSpecifier));
if (device_handle == IntPtr.Zero && available_devices.Count > 0)
device_handle = Alc.OpenDevice(available_devices[0]);
if (device_handle == IntPtr.Zero)
device_handle = Alc.OpenDevice(null);
if (device_handle == IntPtr.Zero)
throw new AudioDeviceException(String.Format("Audio device '{0}' does not exist or is tied up by another application.",
String.IsNullOrEmpty(device) ? "default" : device));

View file

@ -16,7 +16,7 @@ using OpenTK.Math;
/* Type Mapping
// 8-bit boolean
typedef char ALboolean;
* byte
* bool
// character
typedef char ALchar;
* byte
@ -26,7 +26,7 @@ typedef char ALbyte;
// unsigned 8-bit integer
typedef unsigned char ALubyte;
* ubyte
* byte
// signed 16-bit 2's complement integer
typedef short ALshort;
@ -67,6 +67,7 @@ namespace OpenTK.Audio
{
public static partial class AL
{
#region Constants
public const string Lib = "openal32.dll";
@ -441,6 +442,14 @@ namespace OpenTK.Audio
return (int)temp;
}
/// <summary>This function generates one source only. References to sources are uint values, which are used wherever a source reference is needed (in calls such as AL.DeleteSources and AL.Source with parameter ALSourcei).</summary>
/// <param name="source">Pointer to an uint value which will store the name of the new source.</param>
[CLSCompliant( false )]
public static void GenSource( out uint source )
{
GenSources( 1, out source );
}
#endregion GenSources()
#region DeleteSources()
@ -490,7 +499,7 @@ namespace OpenTK.Audio
/// <summary>This function deletes one source only.</summary>
/// <param name="source">Pointer to a source name identifying the source to be deleted.</param>
[CLSCompliant(false)]
public static void DeleteSource(uint source)
public static void DeleteSource( ref uint source)
{
DeleteSources(1, ref source);
}
@ -1305,6 +1314,14 @@ namespace OpenTK.Audio
return (int)temp;
}
/// <summary>This function generates one buffer only, which contain audio data (see AL.BufferData). References to buffers are uint values, which are used wherever a buffer reference is needed (in calls such as AL.DeleteBuffers, AL.Source with parameter ALSourcei, AL.SourceQueueBuffers, and AL.SourceUnqueueBuffers).</summary>
/// <param name="buffers">Pointer to an uint value which will store the names of the new buffer.</param>
[CLSCompliant( false )]
public static void GenBuffer( out uint buffer )
{
GenBuffers( 1, out buffer );
}
#endregion GenBuffers
#region DeleteBuffers
@ -1355,7 +1372,7 @@ namespace OpenTK.Audio
/// <summary>This function deletes one buffer only, freeing the resources used by the buffer. Buffers which are attached to a source can not be deleted. See AL.Source (ALSourcei) and AL.SourceUnqueueBuffers for information on how to detach a buffer from a source.</summary>
/// <param name="buffer">Pointer to a buffer name identifying the buffer to be deleted.</param>
[CLSCompliant(false)]
public static void DeleteBuffer(uint buffer)
public static void DeleteBuffer( ref uint buffer)
{
DeleteBuffers(1, ref buffer);
}
@ -1363,7 +1380,7 @@ namespace OpenTK.Audio
/// <summary>This function deletes one buffer only, freeing the resources used by the buffer. Buffers which are attached to a source can not be deleted. See AL.Source (ALSourcei) and AL.SourceUnqueueBuffers for information on how to detach a buffer from a source.</summary>
/// <param name="buffer">Pointer to a buffer name identifying the buffer to be deleted.</param>
[CLSCompliant(true)]
public static void DeleteBuffer(int buffer)
public static void DeleteBuffer( int buffer)
{
DeleteBuffers(1, ref buffer);
}
@ -1560,5 +1577,59 @@ namespace OpenTK.Audio
// AL_API void AL_APIENTRY alDistanceModel( ALenum distanceModel );
#endregion Global Parameters
#region Helpers
/// <summary>(Helper) Returns Source state information.</summary>
/// <param name="sid">The source to be queried.</param>
/// <returns>state information from OpenAL.</returns>
[CLSCompliant( false )]
public static ALSourceState GetSourceState( uint sid )
{
int temp;
AL.GetSource( sid, ALGetSourcei.SourceState, out temp );
return (ALSourceState) temp;
}
/// <summary>(Helper) Returns Source state information.</summary>
/// <param name="sid">The source to be queried.</param>
/// <returns>state information from OpenAL.</returns>
[CLSCompliant( true )]
public static ALSourceState GetSourceState( int sid )
{
int temp;
AL.GetSource( sid, ALGetSourcei.SourceState, out temp );
return (ALSourceState) temp;
}
/// <summary>(Helper) Returns Source type information.</summary>
/// <param name="sid">The source to be queried.</param>
/// <returns>type information from OpenAL.</returns>
[CLSCompliant( false )]
public static ALSourceType GetSourceType( uint sid )
{
int temp;
AL.GetSource( sid, ALGetSourcei.SourceType, out temp );
return (ALSourceType) temp;
}
/// <summary>(Helper) Returns Source type information.</summary>
/// <param name="sid">The source to be queried.</param>
/// <returns>type information from OpenAL.</returns>
[CLSCompliant( true )]
public static ALSourceType GetSourceType( int sid )
{
int temp;
AL.GetSource( sid, ALGetSourcei.SourceType, out temp );
return (ALSourceType) temp;
}
[CLSCompliant( true )]
public static ALDistanceModel GetDistanceModel( )
{
return (ALDistanceModel) AL.Get( ALGetInteger.DistanceModel );
}
#endregion Helpers
}
}

View file

@ -17,6 +17,7 @@ namespace OpenTK.Audio
{
public partial class EffectsExtension
{
#region Helpers
#region BindEffect
@ -184,6 +185,22 @@ namespace OpenTK.Audio
return temp;
}
/// <summary>Generates a single effect object.</summary>
/// <param name="effect">A handle to the generated effect object.</param>
[CLSCompliant(false)]
public void GenEffect( out uint effect )
{
unsafe
{
fixed ( uint* ptr = &effect )
{
Imported_alGenEffects( 1, ptr );
effect = *ptr;
}
}
}
#endregion alGenEffects
#region alDeleteEffects
@ -244,10 +261,21 @@ namespace OpenTK.Audio
/// <summary>This function deletes one Effect only.</summary>
/// <param name="effect">Pointer to an effect name/handle identifying the Effect Object to be deleted.</param>
public void DeleteEffect(int effect)
{
DeleteEffects( 1, ref effect );
}
/// <summary>This function deletes one Effect only.</summary>
/// <param name="effect">Pointer to an effect name/handle identifying the Effect Object to be deleted.</param>
[CLSCompliant(false)]
public void DeleteEffect( ref uint effect )
{
unsafe
{
Imported_alDeleteEffects(1, (uint*)&effect);
fixed ( uint* ptr = &effect )
{
Imported_alDeleteEffects( 1, ptr );
}
}
}
@ -560,7 +588,7 @@ namespace OpenTK.Audio
}
/// <summary>This function generates only one Filter.</summary>
/// <returns>Storage UInt32 for the new filter name/handle.</returns>
/// <returns>Storage Int32 for the new filter name/handle.</returns>
public int GenFilter()
{
int filter;
@ -568,6 +596,21 @@ namespace OpenTK.Audio
return filter;
}
/// <summary>This function generates only one Filter.</summary>
/// <param name="filter">Storage UInt32 for the new filter name/handle.</param>
[CLSCompliant(false)]
unsafe public void GenFilter( out uint filter )
{
unsafe
{
fixed ( uint* ptr = &filter )
{
Imported_alGenFilters( 1, ptr );
filter = *ptr;
}
}
}
#endregion alGenFilters
#region alDeleteFilters
@ -632,6 +675,20 @@ namespace OpenTK.Audio
DeleteFilters(1, ref filter);
}
/// <summary>This function deletes one Filter only.</summary>
/// <param name="filter">Pointer to an filter name/handle identifying the Filter Object to be deleted.</param>
[CLSCompliant(false)]
public void DeleteFilter( ref uint filter )
{
unsafe
{
fixed ( uint* ptr = &filter )
{
Imported_alDeleteFilters( 1, ptr );
}
}
}
#endregion alDeleteFilters
#region alIsFilter
@ -864,14 +921,29 @@ namespace OpenTK.Audio
}
/// <summary>This function generates only one Auxiliary Effect Slot.</summary>
/// <returns>Storage UInt32 for the new auxiliary effect slot name/handle.</returns>
public int GenAuxiliaryEffectSlots()
/// <returns>Storage Int32 for the new auxiliary effect slot name/handle.</returns>
public int GenAuxiliaryEffectSlot()
{
int temp;
GenAuxiliaryEffectSlots(1, out temp);
return temp;
}
/// <summary>This function generates only one Auxiliary Effect Slot.</summary>
/// <returns>Storage UInt32 for the new auxiliary effect slot name/handle.</returns>
[CLSCompliant(false)]
public void GenAuxiliaryEffectSlot( out uint slot )
{
unsafe
{
fixed ( uint* ptr = &slot )
{
Imported_alGenAuxiliaryEffectSlots( 1, ptr );
slot = *ptr;
}
}
}
#endregion alGenAuxiliaryEffectSlots
#region DeleteAuxiliaryEffectSlots
@ -930,7 +1002,7 @@ namespace OpenTK.Audio
/// <summary>This function deletes one AuxiliaryEffectSlot only.</summary>
/// <param name="slot">Pointer to an auxiliary effect slot name/handle identifying the Auxiliary Effect Slot Object to be deleted.</param>
public void DeleteAuxiliaryEffectSlots(int slot)
public void DeleteAuxiliaryEffectSlot(int slot)
{
DeleteAuxiliaryEffectSlots(1, ref slot);
}
@ -938,9 +1010,15 @@ namespace OpenTK.Audio
/// <summary>This function deletes one AuxiliaryEffectSlot only.</summary>
/// <param name="slot">Pointer to an auxiliary effect slot name/handle identifying the Auxiliary Effect Slot Object to be deleted.</param>
[CLSCompliant(false)]
public void DeleteAuxiliaryEffectSlots(uint slot)
public void DeleteAuxiliaryEffectSlot( ref uint slot)
{
DeleteAuxiliaryEffectSlots(1, ref slot);
unsafe
{
fixed ( uint* ptr = &slot )
{
Imported_alDeleteAuxiliaryEffectSlots( 1, ptr );
}
}
}
#endregion alDeleteAuxiliaryEffectSlots

View file

@ -12,7 +12,7 @@ using System.Text;
namespace OpenTK.Audio
{
/// <summary>Encapsulates a pointer to decoded sound buffer.</summary>
/// <summary>Encapsulates a pointer to a decoded sound buffer.</summary>
public class SoundData
{
byte[] buffer;

View file

@ -436,7 +436,7 @@ namespace OpenTK
#endif
#region void Run()
#region public void Run()
/// <summary>
/// Enters the game loop of the GameWindow updating and rendering at the maximum possible frequency.
@ -448,6 +448,10 @@ namespace OpenTK
Run(0.0, 0.0);
}
#endregion
#region public void Run(double updateFrequency)
/// <summary>
/// Enters the game loop of the GameWindow updating the specified update frequency, while maintaining the
/// maximum possible render frequency.
@ -459,6 +463,10 @@ namespace OpenTK
Run(updateFrequency, 0.0);
}
#endregion
#region public void Run(double updates_per_second, double frames_per_second)
/// <summary>
/// Enters the game loop of the GameWindow updating and rendering at the specified frequency.
/// </summary>
@ -1364,14 +1372,20 @@ namespace OpenTK
/// <summary>
/// Disposes of the GameWindow, releasing all resources consumed by it.
/// </summary>
public virtual void Dispose()
public void Dispose()
{
if (disposed) throw new ObjectDisposedException("GameWindow");
Dispose(true);
try
{
Dispose(true);
}
finally
{
DisposeInternal(true);
}
GC.SuppressFinalize(this);
}
private void Dispose(bool manual)
private void DisposeInternal(bool manual)
{
if (!disposed)
{
@ -1393,10 +1407,19 @@ namespace OpenTK
}
}
/// <summary>Finalizes unmanaged resources consumed by the GameWindow.</summary>
/// <summary>
/// Override to add custom cleanup logic.
/// </summary>
/// <param name="manual">True, if this method was called by the application; false if this was called by the finalizer thread.</param>
protected virtual void Dispose(bool manual)
{
}
///// <summary>Finalizes unmanaged resources consumed by the GameWindow.</summary>
//~GameWindow()
//{
// Dispose(false);
// DisposeInternal(false);
//}
#endregion

View file

@ -9532,15 +9532,15 @@ namespace OpenTK.Graphics
[System.CLSCompliant(false)]
public static
void StencilFuncSeparate(OpenTK.Graphics.StencilFunction frontfunc, OpenTK.Graphics.StencilFunction backfunc, Int32 @ref, UInt32 mask)
void StencilFuncSeparate(OpenTK.Graphics.StencilFace face, OpenTK.Graphics.StencilFunction func, Int32 @ref, UInt32 mask)
{
Delegates.glStencilFuncSeparate((OpenTK.Graphics.StencilFunction)frontfunc, (OpenTK.Graphics.StencilFunction)backfunc, (Int32)@ref, (UInt32)mask);
Delegates.glStencilFuncSeparate((OpenTK.Graphics.StencilFace)face, (OpenTK.Graphics.StencilFunction)func, (Int32)@ref, (UInt32)mask);
}
public static
void StencilFuncSeparate(OpenTK.Graphics.StencilFunction frontfunc, OpenTK.Graphics.StencilFunction backfunc, Int32 @ref, Int32 mask)
void StencilFuncSeparate(OpenTK.Graphics.StencilFace face, OpenTK.Graphics.StencilFunction func, Int32 @ref, Int32 mask)
{
Delegates.glStencilFuncSeparate((OpenTK.Graphics.StencilFunction)frontfunc, (OpenTK.Graphics.StencilFunction)backfunc, (Int32)@ref, (UInt32)mask);
Delegates.glStencilFuncSeparate((OpenTK.Graphics.StencilFace)face, (OpenTK.Graphics.StencilFunction)func, (Int32)@ref, (UInt32)mask);
}
[System.CLSCompliant(false)]

View file

@ -1471,7 +1471,7 @@ namespace OpenTK.Graphics
internal extern static void StencilOpSeparate(OpenTK.Graphics.All face, OpenTK.Graphics.StencilOp sfail, OpenTK.Graphics.StencilOp dpfail, OpenTK.Graphics.StencilOp dppass);
[System.Security.SuppressUnmanagedCodeSecurity()]
[System.Runtime.InteropServices.DllImport(GL.Library, EntryPoint = "glStencilFuncSeparate", ExactSpelling = true)]
internal extern static void StencilFuncSeparate(OpenTK.Graphics.StencilFunction frontfunc, OpenTK.Graphics.StencilFunction backfunc, Int32 @ref, UInt32 mask);
internal extern static void StencilFuncSeparate(OpenTK.Graphics.StencilFace face, OpenTK.Graphics.StencilFunction func, Int32 @ref, UInt32 mask);
[System.Security.SuppressUnmanagedCodeSecurity()]
[System.Runtime.InteropServices.DllImport(GL.Library, EntryPoint = "glStencilMaskSeparate", ExactSpelling = true)]
internal extern static void StencilMaskSeparate(OpenTK.Graphics.All face, UInt32 mask);

View file

@ -1472,7 +1472,7 @@ namespace OpenTK.Graphics
internal delegate void StencilOpSeparate(OpenTK.Graphics.All face, OpenTK.Graphics.StencilOp sfail, OpenTK.Graphics.StencilOp dpfail, OpenTK.Graphics.StencilOp dppass);
internal static StencilOpSeparate glStencilOpSeparate;
[System.Security.SuppressUnmanagedCodeSecurity()]
internal delegate void StencilFuncSeparate(OpenTK.Graphics.StencilFunction frontfunc, OpenTK.Graphics.StencilFunction backfunc, Int32 @ref, UInt32 mask);
internal delegate void StencilFuncSeparate(OpenTK.Graphics.StencilFace face, OpenTK.Graphics.StencilFunction func, Int32 @ref, UInt32 mask);
internal static StencilFuncSeparate glStencilFuncSeparate;
[System.Security.SuppressUnmanagedCodeSecurity()]
internal delegate void StencilMaskSeparate(OpenTK.Graphics.All face, UInt32 mask);

View file

@ -2,6 +2,13 @@ namespace OpenTK.Graphics
{
#pragma warning disable 1591
public enum StencilFace
{
Front = ((int)0X0404),
FrontAndBack = ((int)0X0408),
Back = ((int)0X0405),
}
public enum DrawElementsType
{
UnsignedByte = ((int)0X1401),
@ -100,10 +107,12 @@ namespace OpenTK.Graphics
OneMinusConstantColorExt = ((int)0X8002),
SrcColor = ((int)0X0300),
OneMinusSrcColor = ((int)0X0301),
OneMinusDstColor = ((int)0X0307),
ConstantAlphaExt = ((int)0X8003),
SrcAlpha = ((int)0X0302),
DstAlpha = ((int)0X0304),
DstColor = ((int)0X0306),
Zero = ((int)0),
DstAlpha = ((int)0X0304),
OneMinusConstantAlphaExt = ((int)0X8004),
}
@ -112,9 +121,11 @@ namespace OpenTK.Graphics
ConstantColorExt = ((int)0X8001),
OneMinusSrcAlpha = ((int)0X0303),
One = ((int)1),
SrcAlphaSaturate = ((int)0X0308),
OneMinusConstantColorExt = ((int)0X8002),
OneMinusDstAlpha = ((int)0X0305),
OneMinusConstantColorExt = ((int)0X8002),
SrcColor = ((int)0X0300),
SrcAlphaSaturate = ((int)0X0308),
OneMinusSrcColor = ((int)0X0301),
OneMinusDstColor = ((int)0X0307),
ConstantAlphaExt = ((int)0X8003),
SrcAlpha = ((int)0X0302),

View file

@ -344,9 +344,10 @@ namespace OpenTK.Graphics
static bool SupportsFunction(MethodInfo method)
{
throw new NotImplementedException();
#if false
lock (gl_lock)
{
/*
if (function == null)
throw new ArgumentNullException("function");
@ -362,9 +363,10 @@ namespace OpenTK.Graphics
return false;
return f.GetValue(null) != null;
*/
return false;
}
#endif
}
#endregion
@ -641,7 +643,7 @@ namespace OpenTK.Graphics
#endregion
#region overloads using OpenTK.Math classes
#region --- Overloads for OpenTK.Math ---
public static void Normal3(Vector3 normal)
{
@ -794,27 +796,27 @@ namespace OpenTK.Graphics
}
}
#endregion
#region public static void GetProgramInfoLog(Int32 program, out string info)
public static void GetProgramInfoLog(Int32 program, out string info)
{
unsafe
{
int length;
GL.GetProgram(program, ProgramParameter.InfoLogLength, out length);
if (length == 0)
{
info = "";
return;
}
StringBuilder sb = new StringBuilder(length);
Delegates.glGetProgramInfoLog((UInt32)program, sb.Capacity, &length, sb);
info = sb.ToString();
}
}
#endregion
#region public static void GetProgramInfoLog(Int32 program, out string info)
public static void GetProgramInfoLog(Int32 program, out string info)
{
unsafe
{
int length;
GL.GetProgram(program, ProgramParameter.InfoLogLength, out length);
if (length == 0)
{
info = "";
return;
}
StringBuilder sb = new StringBuilder(length);
Delegates.glGetProgramInfoLog((UInt32)program, sb.Capacity, &length, sb);
info = sb.ToString();
}
}
#endregion
#region public static void PointParameter(PointSpriteCoordOriginParameter param)
@ -831,60 +833,98 @@ namespace OpenTK.Graphics
GL.PointParameter(PointParameterName.PointSpriteCoordOrigin, (int)param);
}
#endregion
#region public static void VertexAttrib2(Int32 index, ref Vector2 v)
public static void VertexAttrib2(Int32 index, ref Vector2 v)
{
GL.VertexAttrib2(index, v.X, v.Y);
}
#endregion
#region public static void VertexAttrib3(Int32 index, ref Vector3 v)
public static void VertexAttrib3(Int32 index, ref Vector3 v)
{
GL.VertexAttrib3(index, v.X, v.Y, v.Z);
}
#endregion
#region public static void VertexAttrib4(Int32 index, ref Vector4 v)
public static void VertexAttrib4(Int32 index, ref Vector4 v)
{
GL.VertexAttrib4(index, v.X, v.Y, v.Z, v.W);
}
#endregion
#region public static void MultiTexCoord2(TextureUnit target, ref Vector2 v)
public static void MultiTexCoord2(TextureUnit target, ref Vector2 v)
{
GL.MultiTexCoord2(target, v.X, v.Y);
}
#endregion
#region public static void MultiTexCoord3(TextureUnit target, ref Vector3 v)
public static void MultiTexCoord3(TextureUnit target, ref Vector3 v)
{
GL.MultiTexCoord3(target, v.X, v.Y, v.Z);
}
#endregion
#region public static void MultiTexCoord4(TextureUnit target, ref Vector4 v)
public static void MultiTexCoord4(TextureUnit target, ref Vector4 v)
{
GL.MultiTexCoord4(target, v.X, v.Y, v.Z, v.W);
}
#endregion
#region public static void VertexAttrib2(Int32 index, ref Vector2 v)
public static void VertexAttrib2(Int32 index, ref Vector2 v)
{
GL.VertexAttrib2(index, v.X, v.Y);
}
#endregion
#region public static void VertexAttrib3(Int32 index, ref Vector3 v)
public static void VertexAttrib3(Int32 index, ref Vector3 v)
{
GL.VertexAttrib3(index, v.X, v.Y, v.Z);
}
#endregion
#region public static void VertexAttrib4(Int32 index, ref Vector4 v)
public static void VertexAttrib4(Int32 index, ref Vector4 v)
{
GL.VertexAttrib4(index, v.X, v.Y, v.Z, v.W);
}
#endregion
#region public static void MultiTexCoord2(TextureUnit target, ref Vector2 v)
public static void MultiTexCoord2(TextureUnit target, ref Vector2 v)
{
GL.MultiTexCoord2(target, v.X, v.Y);
}
#endregion
#region public static void MultiTexCoord3(TextureUnit target, ref Vector3 v)
public static void MultiTexCoord3(TextureUnit target, ref Vector3 v)
{
GL.MultiTexCoord3(target, v.X, v.Y, v.Z);
}
#endregion
#region public static void MultiTexCoord4(TextureUnit target, ref Vector4 v)
public static void MultiTexCoord4(TextureUnit target, ref Vector4 v)
{
GL.MultiTexCoord4(target, v.X, v.Y, v.Z, v.W);
}
#endregion
#region public static void Rect(System.Drawing.RectangleF rect)
public static void Rect(System.Drawing.RectangleF rect)
{
GL.Rect(rect.Left, rect.Top, rect.Right, rect.Bottom);
}
#endregion
#region public static void Rect(ref System.Drawing.RectangleF rect)
[CLSCompliant(false)]
public static void Rect(ref System.Drawing.RectangleF rect)
{
GL.Rect(rect.Left, rect.Top, rect.Right, rect.Bottom);
}
#endregion
#region public static void Rect(System.Drawing.Rectangle rect)
public static void Rect(System.Drawing.Rectangle rect)
{
GL.Rect(rect.Left, rect.Top, rect.Right, rect.Bottom);
}
#endregion
#region public static void Rect(ref System.Drawing.Rectangle rect)
[CLSCompliant(false)]
public static void Rect(ref System.Drawing.Rectangle rect)
{
GL.Rect(rect.Left, rect.Top, rect.Right, rect.Bottom);
}
#endregion
#endregion

View file

@ -23,6 +23,10 @@ namespace OpenTK.Graphics
IGraphicsContext implementation; // The actual render context implementation for the underlying platform.
List<IDisposable> dispose_queue = new List<IDisposable>();
bool disposed;
// Indicates that this context was created through external means, e.g. Tao.Sdl or GLWidget#.
// In this case, We'll assume that the external program will manage the lifetime of this
// context - we'll not destroy it manually.
bool is_external;
static bool share_contexts = true;
static bool direct_rendering = true;
@ -30,17 +34,6 @@ namespace OpenTK.Graphics
// Maps OS-specific context handles to GraphicsContext weak references.
static Dictionary<ContextHandle, WeakReference> available_contexts = new Dictionary<ContextHandle, WeakReference>();
#region public GraphicsContext(DisplayMode mode, IWindowInfo window)
/// <summary>This method is obsolete.</summary>
/// <param name="mode"></param>
/// <param name="window"></param>
public GraphicsContext(DisplayMode mode, IWindowInfo window)
: this(mode.ToGraphicsMode(), window)
{ }
#endregion
#region public GraphicsContext(GraphicsMode format, IWindowInfo window)
/// <summary>
@ -100,6 +93,42 @@ namespace OpenTK.Graphics
#endregion
private GraphicsContext()
{
}
/// <summary>
/// Attempts to create a GraphicsContext object from an existing OpenGL context.
/// </summary>
/// <param name="window">The window this context is bound to.</param>
/// <returns>A new GraphicsContext object, describing the current OpenGL context.</returns>
/// <remarks>
/// <para>Use this function to interoperate with OpenGL contexts created outside of OpenTK.</para>
/// <para>The new GraphicsContext is added to the list of available OpenTK contexts.
/// Make sure to call the Dispose() method once this context is destroyed.</para>
/// <para>You may not call this method more than once on the same context. Doing so will throw an exception.</para>
/// </remarks>
public static GraphicsContext CreateFromCurrentThread(IWindowInfo window)
{
Debug.Print("Creating context from current thread.");
GraphicsContext context = new GraphicsContext();
context.is_external = true;
if (Configuration.RunningOnWindows)
context.implementation = new OpenTK.Platform.Windows.WinGLContext(window);
else if (Configuration.RunningOnX11)
context.implementation = new OpenTK.Platform.X11.X11GLContext(window);
else
throw new PlatformNotSupportedException("Please, refer to http://www.opentk.com for more information.");
lock (context_lock)
{
available_contexts.Add((context as IGraphicsContextInternal).Context, new WeakReference(context));
}
return context;
}
#region void ContextDestroyed(IGraphicsContext context, EventArgs e)
/// <summary>
@ -377,7 +406,7 @@ namespace OpenTK.Graphics
available_contexts.Remove((this as IGraphicsContextInternal).Context);
}
if (manual)
if (manual && !is_external)
{
if (implementation != null)
implementation.Dispose();

View file

@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Text;
using OpenTK.Math;
namespace OpenTK.Input
{
#if false
/// <summary>
/// Represents a joystick device and provides methods to query its state.
/// </summary>
public class JoystickDevice : IInputDevice
{
string description;
Vector2[] axis_position;
#region --- IInputDevice Members ---
/// <summary>
/// Gets a string describing this JoystickDevice.
/// </summary>
public string Description
{
get { return description; }
internal set { description = value; }
}
/// <summary>
/// Gets a value indicating the InputDeviceType of this InputDevice.
/// </summary>
public InputDeviceType DeviceType
{
get { return InputDeviceType.HID; }
}
#endregion
#region --- Public Methods ---
//public Vector2 Axis1
//{
// get { return axis_position.Clone(); }
// internal set {
//}
#endregion
}
#endif
}

View file

@ -43,7 +43,7 @@ namespace OpenTK.Input
#region public InputDeviceType DeviceType
/// <summary>
/// Gets an value indicating the InputDeviceType of this InputDevice.
/// Gets a value indicating the InputDeviceType of this InputDevice.
/// </summary>
public InputDeviceType DeviceType
{

View file

@ -16,8 +16,9 @@ namespace OpenTK.Math
/// <summary>
/// Represents a 4x4 Matrix
/// </summary>
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct Matrix4
public struct Matrix4 : IEquatable<Matrix4>
{
#region Fields
@ -152,9 +153,14 @@ namespace OpenTK.Math
return Matrix4.Mult(left, right);
}
public float get(int x, int y)
public static bool operator ==(Matrix4 left, Matrix4 right)
{
throw new NotImplementedException();
return left.Equals(right);
}
public static bool operator !=(Matrix4 left, Matrix4 right)
{
return !left.Equals(right);
}
#endregion
@ -580,5 +586,51 @@ namespace OpenTK.Math
}
#endregion
#region public override int GetHashCode()
/// <summary>
/// Returns the hashcode for this instance.
/// </summary>
/// <returns>A System.Int32 containing the unique hashcode for this instance.</returns>
public override int GetHashCode()
{
return Row0.GetHashCode() ^ Row1.GetHashCode() ^ Row2.GetHashCode() ^ Row3.GetHashCode();
}
#endregion
#region public override bool Equals(object obj)
/// <summary>
/// Indicates whether this instance and a specified object are equal.
/// </summary>
/// <param name="obj">The object to compare to.</param>
/// <returns>True if the instances are equal; false otherwise.</returns>
public override bool Equals(object obj)
{
if (!(obj is Matrix4))
return false;
return this.Equals((Matrix4)obj);
}
#endregion
#region IEquatable<Matrix4> Members
/// <summary>Indicates whether the current matrix is equal to another matrix.</summary>
/// <param name="matrix">An matrix to compare with this matrix.</param>
/// <returns>true if the current matrix is equal to the matrix parameter; otherwise, false.</returns>
public bool Equals(Matrix4 other)
{
return
Row0 == other.Row0 &&
Row1 == other.Row1 &&
Row2 == other.Row2 &&
Row3 == other.Row3;
}
#endregion
}
}

View file

@ -16,6 +16,7 @@ namespace OpenTK.Math
/// <summary>
/// Represents a Quaternion
/// </summary>
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct Quaternion
{

View file

@ -19,8 +19,9 @@ namespace OpenTK.Math
/// <remarks>
/// The Vector2 structure is suitable for interoperation with unmanaged code requiring two consecutive floats.
/// </remarks>
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct Vector2
public struct Vector2 : IEquatable<Vector2>
{
#region Fields
@ -267,6 +268,16 @@ namespace OpenTK.Math
return vec;
}
public static bool operator ==(Vector2 left, Vector2 right)
{
return left.Equals(right);
}
public static bool operator !=(Vector2 left, Vector2 right)
{
return !left.Equals(right);
}
[CLSCompliant(false)]
unsafe public static explicit operator float*(Vector2 v)
{
@ -615,5 +626,49 @@ namespace OpenTK.Math
}
#endregion
#region public override int GetHashCode()
/// <summary>
/// Returns the hashcode for this instance.
/// </summary>
/// <returns>A System.Int32 containing the unique hashcode for this instance.</returns>
public override int GetHashCode()
{
return X.GetHashCode() ^ Y.GetHashCode();
}
#endregion
#region public override bool Equals(object obj)
/// <summary>
/// Indicates whether this instance and a specified object are equal.
/// </summary>
/// <param name="obj">The object to compare to.</param>
/// <returns>True if the instances are equal; false otherwise.</returns>
public override bool Equals(object obj)
{
if (!(obj is Vector2))
return false;
return this.Equals((Vector2)obj);
}
#endregion
#region IEquatable<Vector2> Members
/// <summary>Indicates whether the current vector is equal to another vector.</summary>
/// <param name="vector">A vector to compare with this vector.</param>
/// <returns>true if the current vector is equal to the vector parameter; otherwise, false.</returns>
public bool Equals(Vector2 other)
{
return
X == other.X &&
Y == other.Y;
}
#endregion
}
}

View file

@ -16,8 +16,9 @@ namespace OpenTK.Math
/// <summary>
/// Represents a three-dimensional vector.
/// </summary>
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct Vector3
public struct Vector3 : IEquatable<Vector3>
{
#region Fields
@ -97,6 +98,32 @@ namespace OpenTK.Math
#region Functions
#region This property
public float this[int index]
{
get
{
switch (index)
{
case 0: return X;
case 1: return Y;
case 2: return Z;
default: throw new ArgumentOutOfRangeException("index", index, "Should be 0, 1 or 2.");
}
/*
unsafe
{
fixed (float* ptr = &this.X)
return *(ptr + index);
}
*/
}
}
#endregion
#region public float Length
/// <summary>
@ -257,23 +284,14 @@ namespace OpenTK.Math
return vec;
}
public float get(int index)
public static bool operator ==(Vector3 left, Vector3 right)
{
switch (index)
{
case 0: return X;
case 1: return Y;
case 2: return Z;
default: throw new ArgumentOutOfRangeException("index", index, "Should be 0, 1 or 2.");
}
/*
unsafe
{
fixed (float* ptr = &this.X)
return *(ptr + index);
}
return left.Equals(right);
}
*/
public static bool operator !=(Vector3 left, Vector3 right)
{
return !left.Equals(right);
}
#endregion
@ -810,5 +828,50 @@ namespace OpenTK.Math
}
#endregion
}
#region public override int GetHashCode()
/// <summary>
/// Returns the hashcode for this instance.
/// </summary>
/// <returns>A System.Int32 containing the unique hashcode for this instance.</returns>
public override int GetHashCode()
{
return X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode();
}
#endregion
#region public override bool Equals(object obj)
/// <summary>
/// Indicates whether this instance and a specified object are equal.
/// </summary>
/// <param name="obj">The object to compare to.</param>
/// <returns>True if the instances are equal; false otherwise.</returns>
public override bool Equals(object obj)
{
if (!(obj is Vector3))
return false;
return this.Equals((Vector3)obj);
}
#endregion
#region IEquatable<Vector3> Members
/// <summary>Indicates whether the current vector is equal to another vector.</summary>
/// <param name="vector">A vector to compare with this vector.</param>
/// <returns>true if the current vector is equal to the vector parameter; otherwise, false.</returns>
public bool Equals(Vector3 other)
{
return
X == other.X &&
Y == other.Y &&
Z == other.Z;
}
#endregion
}
}

View file

@ -16,8 +16,9 @@ namespace OpenTK.Math
/// <summary>
/// Represents a four-dimensional vector.
/// </summary>
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct Vector4
public struct Vector4 : IEquatable<Vector4>
{
#region Fields
@ -276,6 +277,16 @@ namespace OpenTK.Math
return vec;
}
public static bool operator ==(Vector4 left, Vector4 right)
{
return left.Equals(right);
}
public static bool operator !=(Vector4 left, Vector4 right)
{
return !left.Equals(right);
}
[CLSCompliant(false)]
unsafe public static explicit operator float*(Vector4 v)
{
@ -682,5 +693,51 @@ namespace OpenTK.Math
}
#endregion
}
#region public override int GetHashCode()
/// <summary>
/// Returns the hashcode for this instance.
/// </summary>
/// <returns>A System.Int32 containing the unique hashcode for this instance.</returns>
public override int GetHashCode()
{
return X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode() ^ W.GetHashCode();
}
#endregion
#region public override bool Equals(object obj)
/// <summary>
/// Indicates whether this instance and a specified object are equal.
/// </summary>
/// <param name="obj">The object to compare to.</param>
/// <returns>True if the instances are equal; false otherwise.</returns>
public override bool Equals(object obj)
{
if (!(obj is Vector4))
return false;
return this.Equals((Vector4)obj);
}
#endregion
#region IEquatable<Vector4> Members
/// <summary>Indicates whether the current vector is equal to another vector.</summary>
/// <param name="vector">A vector to compare with this vector.</param>
/// <returns>true if the current vector is equal to the vector parameter; otherwise, false.</returns>
public bool Equals(Vector4 other)
{
return
X == other.X &&
Y == other.Y &&
Z == other.Z &&
W == other.W;
}
#endregion
}
}

View file

@ -0,0 +1,120 @@
#region --- License ---
/* Licensed under the MIT/X11 license.
* Copyright (c) 2006-2008 the OpenTK Team.
* This notice may not be removed from any source distribution.
* See license.txt for licensing details.
*/
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Reflection;
using System.Diagnostics;
namespace OpenTK.Platform
{
internal static class GdiPlus
{
static IGdiPlusInternals internals;
const string gdi_plus_library = "gdiplus.dll";
#region --- Constructors ---
static GdiPlus()
{
if (Configuration.RunningOnWindows)
internals = new Windows.WinGdiPlusInternals();
else
internals = new X11.X11GdiPlusInternals();
}
#endregion
#region --- Public Methods ---
public static IntPtr GetNativeGraphics(System.Drawing.Graphics graphics)
{
return internals.GetNativeGraphics(graphics);
}
public static IntPtr GetNativeFont(Font font)
{
return internals.GetNativeFont(font);
}
public static IntPtr GetNativeStringFormat(StringFormat format)
{
return internals.GetNativeStringFormat(format);
}
public static int MaxMeasurableCharacterRanges
{
get
{
return 32; // This is a GDI+ limitation. TODO: Can we query this somehow?
}
}
[DllImport(gdi_plus_library, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true, EntryPoint = "GdipSetStringFormatMeasurableCharacterRanges")]
public static extern int SetStringFormatMeasurableCharacterRanges(HandleRef format, int rangeCount, [In, Out] CharacterRange[] range);
[DllImport(gdi_plus_library, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true, EntryPoint = "GdipGetStringFormatMeasurableCharacterRangeCount")]
public static extern int GetStringFormatMeasurableCharacterRangeCount(HandleRef format, out int count);
[DllImport(gdi_plus_library, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true, EntryPoint = "GdipMeasureCharacterRanges")]
public static extern int MeasureCharacterRanges(HandleRef graphics, string textString, int length, HandleRef font, ref RectangleF layoutRect, HandleRef stringFormat, int characterCount, [In, Out] IntPtr[] region);
[DllImport("gdiplus.dll", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true, EntryPoint = "GdipGetRegionBounds")]
public static extern int GetRegionBounds(IntPtr region, HandleRef graphics, ref RectangleF gprectf);
[DllImport("gdiplus.dll", EntryPoint = "GdipCreateRegion", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
public static extern int CreateRegion(out IntPtr region);
[DllImport("gdiplus.dll", EntryPoint = "GdipDeleteRegion", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
public static extern int DeleteRegion(IntPtr region);
#endregion
#if false
[StructLayout(LayoutKind.Sequential)]
internal struct GPRECTF
{
internal float X;
internal float Y;
internal float Width;
internal float Height;
internal GPRECTF(float x, float y, float width, float height)
{
this.X = x;
this.Y = y;
this.Width = width;
this.Height = height;
}
internal GPRECTF(RectangleF rect)
{
this.X = rect.X;
this.Y = rect.Y;
this.Width = rect.Width;
this.Height = rect.Height;
}
internal SizeF SizeF
{
get
{
return new SizeF(this.Width, this.Height);
}
}
internal RectangleF ToRectangleF()
{
return new RectangleF(this.X, this.Y, this.Width, this.Height);
}
}
#endif
}
}

View file

@ -0,0 +1,29 @@
#region --- License ---
/* Licensed under the MIT/X11 license.
* Copyright (c) 2006-2008 the OpenTK Team.
* This notice may not be removed from any source distribution.
* See license.txt for licensing detailed licensing details.
*/
#endregion
using System;
using System.Collections.Generic;
using System.Text;
namespace OpenTK.Platform
{
// Provides methods to access internal GdiPlus fields. This is necessary for
// managed <-> native GdiPlus interoperability.
// Note that the fields are named differently between .Net and Mono.
// GdiPlus is considered deprecated by Microsoft - it is highly unlikely that
// future framework upgrades will break this code, but it is something to
// keep in mind.
interface IGdiPlusInternals
{
IntPtr GetNativeGraphics(System.Drawing.Graphics graphics);
IntPtr GetNativeFont(System.Drawing.Font font);
IntPtr GetNativeStringFormat(System.Drawing.StringFormat format);
}
}

View file

@ -149,7 +149,7 @@ namespace OpenTK.Platform
return false;
}
FieldInfo f = type.GetField(extension, BindingFlags.Static | BindingFlags.NonPublic);
FieldInfo f = extensions_class.GetField(extension, BindingFlags.Static | BindingFlags.NonPublic);
if (f == null)
{
Debug.Print("Extension \"", extension, "\" not found in ", type.ToString());
@ -212,6 +212,132 @@ namespace OpenTK.Platform
}
#endregion
#region --- Creating an Graphics Context ---
#region --- CreateWindowInfo ---
/// <summary>
/// Creates GraphicsContext and IWindowInfo objects for a WinForms control.
/// </summary>
/// <param name="cntrl"></param>
/// <param name="context"></param>
/// <param name="info"></param>
/// <param name="mode"></param>
public static void CreateGraphicsContext(Graphics.GraphicsMode mode, Control cntrl, out Graphics.GraphicsContext context, out IWindowInfo info)
{
CreateGraphicsContext(mode, cntrl.Handle, out context, out info);
}
/// <summary>
/// Creates GraphicsContext and IWindowInfo objects for a WinForms control.
/// </summary>
/// <param name="cntrlHandle"></param>
/// <param name="context"></param>
/// <param name="info"></param>
/// <param name="mode"></param>
public static void CreateGraphicsContext(Graphics.GraphicsMode mode, IntPtr cntrlHandle, out Graphics.GraphicsContext context, out IWindowInfo info)
{
info = CreateWindowInfo(mode, cntrlHandle);
context = new Graphics.GraphicsContext(mode, info);
context.MakeCurrent(info);
(context as OpenTK.Graphics.IGraphicsContextInternal).LoadAll();
}
/// <summary>
/// Creates an object which implements the IWindowInfo interface for the platform
/// currently running on. This will create a handle for the control, so it is not
/// recommended that this be called in the constructor of a custom control.
/// </summary>
/// <param name="cntrl"></param>
/// <returns></returns>
public static IWindowInfo CreateWindowInfo(Graphics.GraphicsMode mode, Control cntrl)
{
return CreateWindowInfo(mode, cntrl.Handle);
}
/// <summary>
/// Creates an object which implements the IWindowInfo interface for the platform
/// currently running on.
/// </summary>
/// <param name="controlHandle">The handle to the control, obtained from Control.Handle.</param>
/// <returns></returns>
public static IWindowInfo CreateWindowInfo(Graphics.GraphicsMode mode, IntPtr controlHandle)
{
if (Configuration.RunningOnWindows) return CreateWinWindowInfo(controlHandle);
else if (Configuration.RunningOnX11) return CreateX11WindowInfo(mode, controlHandle);
else if (Configuration.RunningOnOSX) return CreateOSXWindowInfo(controlHandle);
else
throw new PlatformNotSupportedException("Refer to http://www.opentk.com for more information.");
}
#endregion
#region --- X11 Platform-specific implementation ---
private static IWindowInfo CreateX11WindowInfo(Graphics.GraphicsMode mode, IntPtr controlHandle)
{
Platform.X11.X11WindowInfo window = new OpenTK.Platform.X11.X11WindowInfo();
Type xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms");
if (xplatui == null) throw new PlatformNotSupportedException(
"System.Windows.Forms.XplatUIX11 missing. Unsupported platform or Mono runtime version, aborting.");
window.WindowHandle = controlHandle;
// get the required handles from the X11 API.
window.Display = (IntPtr)GetStaticFieldValue(xplatui, "DisplayHandle");
window.RootWindow = (IntPtr)GetStaticFieldValue(xplatui, "RootWindow");
window.Screen = (int)GetStaticFieldValue(xplatui, "ScreenNo");
// get the X11 Visual info for the display.
Platform.X11.XVisualInfo info = new Platform.X11.XVisualInfo();
info.visualid = mode.Index;
int dummy;
window.VisualInfo = (Platform.X11.XVisualInfo)Marshal.PtrToStructure(
Platform.X11.Functions.XGetVisualInfo(window.Display, Platform.X11.XVisualInfoMask.ID,
ref info, out dummy), typeof(Platform.X11.XVisualInfo));
// set the X11 colormap.
SetStaticFieldValue(xplatui, "CustomVisual", window.VisualInfo.visual);
SetStaticFieldValue(xplatui, "CustomColormap",
Platform.X11.Functions.XCreateColormap(window.Display, window.RootWindow, window.VisualInfo.visual, 0));
return window;
}
#endregion
#region --- Windows Platform-specific implementation ---
private static IWindowInfo CreateWinWindowInfo(IntPtr controlHandle)
{
return new OpenTK.Platform.Windows.WinWindowInfo(controlHandle, null);
}
#endregion
#region --- Mac OS X Platform-specific implementation ---
private static IWindowInfo CreateOSXWindowInfo(IntPtr controlHandle)
{
throw new PlatformNotSupportedException("Refer to http://www.opentk.com for more information.");
}
#endregion
#region --- Utility functions for reading/writing non-public static fields through reflection ---
private static object GetStaticFieldValue(Type type, string fieldName)
{
return type.GetField(fieldName,
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
}
private static void SetStaticFieldValue(Type type, string fieldName, object value)
{
type.GetField(fieldName,
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).SetValue(null, value);
}
#endregion
#endregion
}
}

View file

@ -1433,7 +1433,9 @@ namespace OpenTK.Platform.Windows
#endregion
#region PixelFormatDescriptor
#pragma warning disable 0169
/// <summary>
/// Describes a pixel format. It is used when interfacing with the WINAPI to create a new Context.
/// Found in WinGDI.h
@ -1467,7 +1469,9 @@ namespace OpenTK.Platform.Windows
internal int LayerMask;
internal int VisibleMask;
internal int DamageMask;
}
}
#pragma warning restore 0169
#endregion

View file

@ -144,7 +144,7 @@ namespace OpenTK.Platform.Windows
// TODO: Not 100% reliable, when both keys are pressed at once.
if (ShiftRightScanCode != 0)
{
if ((((int)msg.LParam >> 16) & 0xFF) == ShiftRightScanCode)
if (((msg.LParam.ToInt32() >> 16) & 0xFF) == ShiftRightScanCode)
keyboard[Input.Key.ShiftRight] = pressed;
else
keyboard[Input.Key.ShiftLeft] = pressed;

View file

@ -90,6 +90,17 @@ namespace OpenTK.Platform.Windows
}
}
public WinGLContext(IWindowInfo window)
{
if (window == null) throw new ArgumentNullException("window");
renderContext = Wgl.GetCurrentContext();
if (renderContext == IntPtr.Zero)
throw new InvalidOperationException("No OpenGL context is current in the calling thread.");
currentWindow = (WinWindowInfo)window;
}
#endregion
#region --- IGraphicsContext Members ---

View file

@ -0,0 +1,53 @@
#region --- License ---
/* Licensed under the MIT/X11 license.
* Copyright (c) 2006-2008 the OpenTK Team.
* This notice may not be removed from any source distribution.
* See license.txt for licensing detailed licensing details.
*/
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Reflection;
namespace OpenTK.Platform.Windows
{
class WinGdiPlusInternals : IGdiPlusInternals
{
static readonly PropertyInfo native_graphics_property, native_font_property;
static readonly FieldInfo native_string_format_field;
static WinGdiPlusInternals()
{
native_graphics_property =
typeof(System.Drawing.Graphics).GetProperty("NativeGraphics", BindingFlags.Instance | BindingFlags.NonPublic);
native_font_property =
typeof(System.Drawing.Font).GetProperty("NativeFont", BindingFlags.Instance | BindingFlags.NonPublic);
native_string_format_field =
typeof(System.Drawing.StringFormat).GetField("nativeFormat", BindingFlags.Instance | BindingFlags.NonPublic);
}
#region --- IGdiPlusInternals Members ---
public IntPtr GetNativeGraphics(System.Drawing.Graphics graphics)
{
return (IntPtr)native_graphics_property.GetValue(graphics, null);
}
public IntPtr GetNativeFont(Font font)
{
return (IntPtr)native_font_property.GetValue(font, null);
}
public IntPtr GetNativeStringFormat(StringFormat format)
{
return (IntPtr)native_string_format_field.GetValue(format);
}
#endregion
}
}

View file

@ -4,9 +4,8 @@ using System.Text;
namespace OpenTK.Platform.Windows
{
/// <internal />
/// <summary>Describes a win32 window.</summary>
internal sealed class WinWindowInfo : IWindowInfo
public sealed class WinWindowInfo : IWindowInfo
{
IntPtr handle, dc;
WinWindowInfo parent;

View file

@ -39,7 +39,7 @@ namespace OpenTK.Platform.X11
GraphicsContext.GetCurrentContext = X11GLContext.GetCurrentContext;
}
internal X11GLContext(GraphicsMode mode, IWindowInfo info, IGraphicsContext shared, bool directRendering)
public X11GLContext(GraphicsMode mode, IWindowInfo info, IGraphicsContext shared, bool directRendering)
{
//if (mode == null) mode = GraphicsMode.Default;
if (info == null) throw new ArgumentNullException("info", "Should point to a valid window.");
@ -52,6 +52,17 @@ namespace OpenTK.Platform.X11
CreateContext(shared, directRendering, currentWindow);
}
public X11GLContext(IWindowInfo window)
{
if (window == null) throw new ArgumentNullException("window");
//renderContext = Glx.GetCurrentContext();
//if (renderContext == IntPtr.Zero)
// throw new InvalidOperationException("No OpenGL context is current in the calling thread.");
//currentWindow = window;
}
#endregion
#region --- Private Methods ---

View file

@ -0,0 +1,52 @@
#region --- License ---
/* Licensed under the MIT/X11 license.
* Copyright (c) 2006-2008 the OpenTK Team.
* This notice may not be removed from any source distribution.
* See license.txt for licensing detailed licensing details.
*/
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Reflection;
namespace OpenTK.Platform.X11
{
class X11GdiPlusInternals : IGdiPlusInternals
{
static readonly PropertyInfo native_graphics_property, native_font_property, native_string_format_property;
static X11GdiPlusInternals()
{
native_graphics_property =
typeof(System.Drawing.Graphics).GetProperty("NativeObject", BindingFlags.Instance | BindingFlags.NonPublic);
native_font_property =
typeof(System.Drawing.Font).GetProperty("NativeObject", BindingFlags.Instance | BindingFlags.NonPublic);
native_string_format_property =
typeof(System.Drawing.StringFormat).GetProperty("NativeObject", BindingFlags.Instance | BindingFlags.NonPublic);
}
#region --- IGdiPlusInternals Members ---
public IntPtr GetNativeGraphics(System.Drawing.Graphics graphics)
{
return (IntPtr)native_graphics_property.GetValue(graphics, null);
}
public IntPtr GetNativeFont(Font font)
{
return (IntPtr)native_font_property.GetValue(font, null);
}
public IntPtr GetNativeStringFormat(StringFormat format)
{
return (IntPtr)native_string_format_property.GetValue(format, null);
}
#endregion
}
}

View file

@ -56,9 +56,9 @@ namespace OpenTK.Platform.X11
public IntPtr RootWindow { get { return rootWindow; } set { rootWindow = value; } }
/// <summary>Gets or sets the connection to the X11 display.</summary>
public IntPtr Display { get { return display; } set { display = value; } }
/// <summary>Gets or sets the X11 screen.</summary>
public int Screen { get { return screen; } set { screen = value; } }
//{ get { return Functions.XRRRootToScreen(display, rootWindow); } set { } }
/// <summary>Gets or sets the X11 screen.</summary>
public int Screen { get { return screen; } set { screen = value; } }
//{ get { return Functions.XRRRootToScreen(display, rootWindow); } set { } }
//public int Screen { get { return screen; } set { screen = value; } }
/// <summary>Gets or sets the X11 VisualInfo.</summary>
public XVisualInfo VisualInfo { get { return visualInfo; } set { visualInfo = value; } }

View file

@ -86,7 +86,7 @@ namespace OpenTK.Audio
}
}
}
catch (Exception e)
catch (Exception)
{
s.Close();
throw;

View file

@ -191,7 +191,7 @@ namespace OpenTK.Audio
//return new SoundData(decoded_data, new SoundFormat(channels, bits_per_sample, sample_rate));
return decoded_data;
}
catch (AudioReaderException e)
catch (AudioReaderException)
{
reader.Close();
throw;

View file

@ -16,13 +16,11 @@ namespace OpenTK.Graphics
/// <summary>
/// Represents a single character of a specific Font.
/// </summary>
class Glyph : IPackable<Glyph>
struct Glyph : IPackable<Glyph>
{
char character;
Font font;
int width;
static Bitmap bmp = new Bitmap(1, 1);
object obj = new object();
SizeF size;
#region --- Constructors ---
@ -31,16 +29,19 @@ namespace OpenTK.Graphics
/// </summary>
/// <param name="c">The character to represent.</param>
/// <param name="f">The Font of the character.</param>
public Glyph(char c, Font f)
public Glyph(char c, Font f, SizeF s)
{
if (f == null)
throw new ArgumentNullException("f", "You must specify a valid font");
character = c;
font = f;
size = s;
}
#endregion
#region --- Public Methods ---
#region public char Character
/// <summary>
@ -73,7 +74,52 @@ namespace OpenTK.Graphics
#endregion
#region IPackable<T> Members
#region public override bool Equals(object obj)
/// <summary>
/// Checks whether the given object is equal (memberwise) to the current Glyph.
/// </summary>
/// <param name="obj">The obj to check.</param>
/// <returns>True, if the object is identical to the current Glyph.</returns>
public override bool Equals(object obj)
{
if (obj is Glyph)
return this.Equals((Glyph)obj);
return base.Equals(obj);
}
#endregion
#region public override string ToString()
/// <summary>
/// Describes this Glyph object.
/// </summary>
/// <returns>Returns a System.String describing this Glyph.</returns>
public override string ToString()
{
return String.Format("'{0}', {1} {2}, {3} {4}, ({5}, {6})", Character, Font.Name, font.Style, font.Size, font.Unit, Width, Height);
}
#endregion
#region public override int GetHashCode()
/// <summary>
/// Calculates the hashcode for this Glyph.
/// </summary>
/// <returns>A System.Int32 containing a hashcode that uniquely identifies this Glyph.</returns>
public override int GetHashCode()
{
//return character.GetHashCode() ^ font.Style.GetHashCode() ^ font.Size.GetHashCode() ^ font.Unit.GetHashCode();
return character.GetHashCode() ^ font.GetHashCode() ^ size.GetHashCode();
}
#endregion
#endregion
#region --- IPackable<T> Members ---
/// <summary>
/// Gets an integer representing the width of the Glyph in pixels.
@ -82,17 +128,7 @@ namespace OpenTK.Graphics
{
get
{
if (width == 0)
{
lock (obj)
using (Graphics gfx = Graphics.FromImage(bmp))
{
float w = gfx.MeasureString(Character.ToString(), font).Width;
width = (int)System.Math.Ceiling(w);
}
}
return width;
return (int)System.Math.Ceiling(size.Width);
}
}
@ -103,30 +139,13 @@ namespace OpenTK.Graphics
{
get
{
return font.Height;
return (int)System.Math.Ceiling(size.Height);
}
}
#endregion
public override bool Equals(object obj)
{
if (obj is Glyph)
return this.Equals((Glyph)obj);
return base.Equals(obj);
}
public override string ToString()
{
return String.Format("'{0}', {1} {2}, {3} {4}", Character, Font.Name, font.Style, font.Size, font.Unit);
}
public override int GetHashCode()
{
return character.GetHashCode() ^ font.Style.GetHashCode() ^ font.Size.GetHashCode() ^ font.Unit.GetHashCode();
}
#region IEquatable<Glyph> Members
#region --- IEquatable<Glyph> Members ---
/// <summary>
/// Compares the current Glyph with the given Glyph.

View file

@ -15,10 +15,31 @@ namespace OpenTK.Graphics
/// <summary>
/// Defines the interface for TextPrinter implementations.
/// </summary>
interface ITextPrinterImplementation
public interface ITextPrinterImplementation
{
TextHandle Load(Vector2[] vertices, ushort[] indices, int index_count);
/// <summary>
/// Caches a text fragment for future use.
/// </summary>
/// <param name="vertices">The vertex array for the text fragment.</param>
/// <param name="indices">The index array for the text fragment. Please use the indexCount parameter
/// instead of indices.Count, as the indices array may be larger than necessary for performance reasons.</param>
/// <param name="indexCount">The actual number of indices in the text fragment.</param>
/// <returns>A TextHandle that can be used to draw the text fragment.</returns>
TextHandle Load(Vector2[] vertices, ushort[] indices, int indexCount);
/// <summary>
/// Draws the specified cached text fragment.
/// </summary>
/// <param name="handle">The TextHandle corresponding to the desired text fragment.</param>
void Draw(TextHandle handle);
void Draw(Vector2[] vertices, ushort[] indices, int index_count);
/// <summary>
/// Draws a text fragment, without caching.
/// </summary>
/// <param name="vertices">The vertex array for the text fragment.</param>
/// <param name="indices">The index array for the text fragment. Please use the indexCount parameter
/// instead of indices.Count, as the indices array may be larger than necessary for performance reasons.</param>
/// <param name="indexCount">The actual number of indices in the text fragment.</param>
void Draw(Vector2[] vertices, ushort[] indices, int indexCount);
}
}

View file

@ -13,20 +13,39 @@ namespace OpenTK.Graphics
/// <summary>
/// Represents a handle to cached text.
/// </summary>
public class TextHandle : IDisposable
public abstract class TextHandle : IDisposable
{
internal TextHandle(int handle)
/// <summary>
/// Constructs a new TextHandle,
/// </summary>
/// <param name="handle"></param>
public TextHandle(int handle)
{
Handle = handle;
}
private int handle;
protected TextureFont font;
protected bool disposed;
/// <summary>
/// The handle of the cached text. Call the OpenTK.Graphics.ITextPrinter.Draw() method
/// Gets the handle of the cached text run. Call the OpenTK.Graphics.ITextPrinter.Draw() method
/// to draw the text represented by this TextHandle.
/// </summary>
public readonly int Handle;
internal TextureFont font;
protected bool disposed;
public int Handle
{
get { return handle; }
protected set { handle = value; }
}
/// <summary>
/// Gets the TextureFont used for this text run.
/// </summary>
public TextureFont Font
{
get { return font; }
internal set { font = value; }
}
#region public override string ToString()

View file

@ -28,23 +28,32 @@ namespace OpenTK.Graphics
public class TextPrinter : ITextPrinter
{
//static Regex break_point = new Regex("[ .,/*-+?\\!=]", RegexOptions.Compiled | RegexOptions.IgnoreCase);
//static char[] split_chars = new char[]
//{
// ' ', '\n', '\t', ',', '.', '/', '?', '!', ';', '\\', '-', '+', '*', '='
//static char[] split_chars = new char[]
//{
// ' ', '\n', '\t', ',', '.', '/', '?', '!', ';', '\\', '-', '+', '*', '='
//};
static ITextPrinterImplementation printer;
float[] viewport = new float[4];
float[] viewport = new float[4];
// Interleaved, vertex, texcoord, vertex, etc... Starts with 8 chars, will expand as needed.
Vector2[] vertices = new Vector2[8 * 8];
ushort[] indices = new ushort[6 * 8];
IList<RectangleF> ranges = new List<RectangleF>();
#region --- Constructor ---
#region --- Constructors ---
/// <summary>
/// Constructs a new TextPrinter object.
/// </summary>
public TextPrinter() { }
public TextPrinter(ITextPrinterImplementation implementation)
{
if (implementation == null)
throw new ArgumentNullException("implementation");
printer = implementation;
}
#endregion
#region --- Private Members ---
@ -155,7 +164,7 @@ namespace OpenTK.Graphics
PerformLayout(text, font, width, wordWarp, alignment, rightToLeft, ref vertices, ref indices, out num_indices);
handle = Printer.Load(vertices, indices, num_indices);
handle.font = font;
handle.Font = font;
}
#endregion
@ -175,11 +184,11 @@ namespace OpenTK.Graphics
if (wordWarp || rightToLeft || alignment != StringAlignment.Near)
throw new NotImplementedException();
while (8 * text.Length > vertices.Length)
vertices = new Vector2[vertices.Length << 1];
if (8 * text.Length > vertices.Length)
vertices = new Vector2[Math.Functions.NextPowerOfTwo(8 * text.Length)];
while (6 * text.Length > indices.Length)
indices = new ushort[indices.Length << 1];
if (6 * text.Length > indices.Length)
indices = new ushort[Math.Functions.NextPowerOfTwo(6 * text.Length)];
num_indices = 6 * text.Length;
@ -187,65 +196,59 @@ namespace OpenTK.Graphics
//ushort[] indices = new ushort[6 * text.Length];
float x_pos = 0, y_pos = 0;
ushort i = 0, index_count = 0, vertex_count = 0, last_break_point = 0;
Box2 rect = new Box2();
float char_width, char_height, measured_width, measured_height;
RectangleF rect = new RectangleF();
float char_width, char_height;
int texture;
font.LoadGlyphs(text);
// Every character comprises of 4 vertices, forming two triangles. We generate an index array which
// indexes vertices in a triangle-strip fashion. To create a single strip for the whole string, we
// need to add a degenerate triangle (0 height) to connect the last vertex of the previous line with
// the first vertex of the next line.
// indexes vertices in a triangle-list fashion.
// This algorithm works for left-to-right scripts.
if (alignment == StringAlignment.Near && !rightToLeft || alignment == StringAlignment.Far && rightToLeft)
{
foreach (char c in text)
font.MeasureText(text, SizeF.Empty, null, ranges);
int current = 0;
foreach (RectangleF range in ranges)
{
char c = text[current++];
if (Char.IsSeparator(c))
last_break_point = index_count;
if (c != '\n' && c != '\r')
{
font.GlyphData(c, out char_width, out char_height, out rect, out texture);
x_pos = range.X;
y_pos = range.Y;
vertices[vertex_count].X = x_pos; // Vertex
vertices[vertex_count++].Y = y_pos;
vertices[vertex_count].X = rect.Left; // Texcoord
vertices[vertex_count++].Y = rect.Top;
vertices[vertex_count].X = x_pos; // Vertex
vertices[vertex_count++].Y = y_pos + char_height;
vertices[vertex_count].X = rect.Left; // Texcoord
vertices[vertex_count++].Y = rect.Bottom;
font.GlyphData(c, out char_width, out char_height, out rect, out texture);
vertices[vertex_count].X = x_pos + char_width; // Vertex
vertices[vertex_count++].Y = y_pos + char_height;
vertices[vertex_count].X = rect.Right; // Texcoord
vertices[vertex_count++].Y = rect.Bottom;
vertices[vertex_count].X = x_pos + char_width; // Vertex
vertices[vertex_count++].Y = y_pos;
vertices[vertex_count].X = rect.Right; // Texcoord
vertices[vertex_count++].Y = rect.Top;
vertices[vertex_count].X = x_pos; // Vertex
vertices[vertex_count++].Y = y_pos;
vertices[vertex_count].X = rect.Left; // Texcoord
vertices[vertex_count++].Y = rect.Top;
vertices[vertex_count].X = x_pos; // Vertex
vertices[vertex_count++].Y = y_pos + char_height;
vertices[vertex_count].X = rect.Left; // Texcoord
vertices[vertex_count++].Y = rect.Bottom;
indices[index_count++] = (ushort)(vertex_count - 8);
indices[index_count++] = (ushort)(vertex_count - 6);
indices[index_count++] = (ushort)(vertex_count - 4);
vertices[vertex_count].X = x_pos + char_width; // Vertex
vertices[vertex_count++].Y = y_pos + char_height;
vertices[vertex_count].X = rect.Right; // Texcoord
vertices[vertex_count++].Y = rect.Bottom;
vertices[vertex_count].X = x_pos + char_width; // Vertex
vertices[vertex_count++].Y = y_pos;
vertices[vertex_count].X = rect.Right; // Texcoord
vertices[vertex_count++].Y = rect.Top;
indices[index_count++] = (ushort)(vertex_count - 4);
indices[index_count++] = (ushort)(vertex_count - 2);
indices[index_count++] = (ushort)(vertex_count - 8);
indices[index_count++] = (ushort)(vertex_count - 8);
indices[index_count++] = (ushort)(vertex_count - 6);
indices[index_count++] = (ushort)(vertex_count - 4);
indices[index_count++] = (ushort)(vertex_count - 4);
indices[index_count++] = (ushort)(vertex_count - 2);
indices[index_count++] = (ushort)(vertex_count - 8);
font.MeasureString(text.Substring(i, 1), out measured_width, out measured_height, false);
x_pos += measured_width;
}
else if (c == '\n')
{
//x_pos = layoutRect.Left;
x_pos = 0;
y_pos += font.Height;
}
++i;
}
}
@ -269,7 +272,7 @@ namespace OpenTK.Graphics
/// <param name="handle">The TextHandle to the cached text.</param>
public void Draw(TextHandle handle)
{
GL.BindTexture(TextureTarget.Texture2D, handle.font.Texture);
GL.BindTexture(TextureTarget.Texture2D, handle.Font.Texture);
Printer.Draw(handle);
}

View file

@ -25,7 +25,7 @@ namespace OpenTK.Graphics
public class TextureFont : IFont
{
Font font;
Dictionary<char, Box2> loaded_glyphs = new Dictionary<char, Box2>(64);
Dictionary<char, RectangleF> loaded_glyphs = new Dictionary<char, RectangleF>(64);
Bitmap bmp;
Graphics gfx;
@ -33,15 +33,18 @@ namespace OpenTK.Graphics
static int texture;
static TexturePacker<Glyph> pack;
static int texture_width, texture_height;
static readonly StringFormat default_string_format = StringFormat.GenericTypographic; // Check the constructor, too, for additional flags.
static readonly StringFormat load_glyph_string_format = StringFormat.GenericDefault;
static SizeF maximum_graphics_size;
int[] data = new int[256]; // Used to upload the glyph buffer to the OpenGL texture.
int[] data = new int[256]; // Used to upload glyph buffer to the OpenGL texture.
object upload_lock = new object();
#region --- Constructor ---
/// <summary>
/// Constructs a new TextureFont object, using the specified System.Drawing.Font.
/// Constructs a new TextureFont, using the specified System.Drawing.Font.
/// </summary>
/// <param name="font">The System.Drawing.Font to use.</param>
public TextureFont(Font font)
@ -53,23 +56,337 @@ namespace OpenTK.Graphics
bmp = new Bitmap(font.Height * 2, font.Height * 2);
gfx = Graphics.FromImage(bmp);
maximum_graphics_size = gfx.ClipBounds.Size;
// Adjust font rendering mode. Small sizes look blurry without gridfitting, so turn
// that on. Increasing contrast also seems to help.
if (font.Size <= 18.0f)
{
gfx.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
gfx.TextContrast = 1;
//gfx.TextContrast = 11;
}
else
{
gfx.TextRenderingHint = TextRenderingHint.AntiAlias;
gfx.TextContrast = 0;
//gfx.TextContrast = 0;
}
default_string_format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
}
/// <summary>
/// Constructs a new TextureFont, using the specified parameters.
/// </summary>
/// <param name="font">The System.Drawing.FontFamily to use for the typeface.</param>
/// <param name="emSize">The em size to use for the typeface.</param>
public TextureFont(FontFamily family, float emSize)
: this(new Font(family, emSize))
{ }
/// <summary>
/// Constructs a new TextureFont, using the specified parameters.
/// </summary>
/// <param name="font">The System.Drawing.FontFamily to use for the typeface.</param>
/// <param name="emSize">The em size to use for the typeface.</param>
/// <param name="family">The style to use for the typeface.</param>
public TextureFont(FontFamily family, float emSize, FontStyle style)
: this(new Font(family, emSize, style))
{ }
#endregion
#region --- Public Methods ---
#region public void LoadGlyphs(string glyphs)
/// <summary>
/// Prepares the specified glyphs for rendering.
/// </summary>
/// <param name="glyphs">The glyphs to prepare for rendering.</param>
public void LoadGlyphs(string glyphs)
{
RectangleF rect = new RectangleF();
foreach (char c in glyphs)
{
try
{
if (!loaded_glyphs.ContainsKey(c))
LoadGlyph(c, out rect);
}
catch (Exception e)
{
Debug.Print(e.ToString());
throw;
}
}
}
#endregion
#region public void LoadGlyph(char glyph)
/// <summary>
/// Prepares the specified glyph for rendering.
/// </summary>
/// <param name="glyphs">The glyph to prepare for rendering.</param>
public void LoadGlyph(char glyph)
{
RectangleF rect = new RectangleF();
if (!loaded_glyphs.ContainsKey(glyph))
LoadGlyph(glyph, out rect);
}
#endregion
#region public bool GlyphData(char glyph, out float width, out float height, out RectangleF textureRectangle, out int texture)
/// <summary>
/// Returns the characteristics of a loaded glyph.
/// </summary>
/// <param name="glyph">The character corresponding to this glyph.</param>
/// <param name="width">The width of this glyph.</param>
/// <param name="height">The height of this glyph (line spacing).</param>
/// <param name="textureRectangle">The bounding box of the texture buffer of this glyph.</param>
/// <param name="texture">The handle to the texture that contains this glyph.</param>
/// <returns>True if the glyph has been loaded, false otherwise.</returns>
/// <seealso cref="LoadGlyphs"/>
public bool GlyphData(char glyph, out float width, out float height, out RectangleF textureRectangle, out int texture)
{
if (loaded_glyphs.TryGetValue(glyph, out textureRectangle))
{
width = textureRectangle.Width * texture_width;
height = textureRectangle.Height * texture_height;
texture = TextureFont.texture;
return true;
}
width = height = texture = 0;
return false;
}
#endregion
#region public float Height
/// <summary>
/// Gets a float indicating the default line spacing of this font.
/// </summary>
public float Height
{
get { return font.Height; }
}
#endregion
#region public float Width
/// <summary>
/// Gets a float indicating the default size of this font, in points.
/// </summary>
public float Width
{
get { return font.SizeInPoints; }
}
#endregion
#region public void MeasureString(string str, out float width, out float height, bool accountForOverhangs)
/// <summary>
/// Measures the width of the specified string.
/// </summary>
/// <param name="str">The string to measure.</param>
/// <param name="width">The measured width.</param>
/// <param name="height">The measured height.</param>
/// <param name="accountForOverhangs">If true, adds space to account for glyph overhangs. Set to true if you wish to measure a complete string. Set to false if you wish to perform layout on adjacent strings.</param>
[Obsolete("Returns invalid results - use MeasureText() instead")]
public void MeasureString(string str, out float width, out float height, bool accountForOverhangs)
{
System.Drawing.StringFormat format = accountForOverhangs ? System.Drawing.StringFormat.GenericDefault : System.Drawing.StringFormat.GenericTypographic;
//format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
System.Drawing.SizeF size = gfx.MeasureString(str, font, 16384, format);
height = size.Height;
width = size.Width;
//width = height = 0;
//RectangleF rect = new RectangleF(0, 0, 0, 0);
//ICollection<RectangleF> ranges = new List<RectangleF>();
//MeasureCharacterRanges(gfx, str, font, ref rect, format, ref ranges);
//foreach (RectangleF range in ranges)
//{
// width += range.Width;
// height = range.Height > height ?range.Height : height;
//}
// width = 0;
// height = 0;
// int i = 0;
// foreach (char c in str)
// {
// if (c != '\n' && c != '\r')
// {
// SizeF size = gfx.MeasureString(str.Substring(i, 1), font, 16384, System.Drawing.StringFormat.GenericTypographic);
// width += size.Width == 0 ? font.SizeInPoints * 0.5f : size.Width;
// if (height < size.Height)
// height = size.Height;
// }
// ++i;
// }
}
#endregion
#region public void MeasureString(string str, out float width, out float height)
/// <summary>
/// Measures the width of the specified string.
/// </summary>
/// <param name="str">The string to measure.</param>
/// <param name="width">The measured width.</param>
/// <param name="height">The measured height.</param>
/// <seealso cref="public void MeasureString(string str, out float width, out float height, bool accountForOverhangs)"/>
[Obsolete("Returns invalid results - use MeasureText() instead")]
public void MeasureString(string str, out float width, out float height)
{
MeasureString(str, out width, out height, true);
}
#endregion
#region public RectangleF MeasureText(string text)
/// <summary>
/// Calculates size information for the specified text.
/// </summary>
/// <param name="text">The string to measure.</param>
/// <returns>A RectangleF containing the bounding box for the specified text.</returns>
public RectangleF MeasureText(string text)
{
return MeasureText(text, SizeF.Empty, default_string_format, null);
}
#endregion
#region public RectangleF MeasureText(string text, SizeF bounds)
/// <summary>
/// Calculates size information for the specified text.
/// </summary>
/// <param name="text">The string to measure.</param>
/// <param name="bounds">A SizeF structure containing the maximum desired width and height of the text. Default is SizeF.Empty.</param>
/// <returns>A RectangleF containing the bounding box for the specified text.</returns>
public RectangleF MeasureText(string text, SizeF bounds)
{
return MeasureText(text, bounds, default_string_format, null);
}
#endregion
#region public RectangleF MeasureText(string text, SizeF bounds, StringFormat format)
/// <summary>
/// Calculates size information for the specified text.
/// </summary>
/// <param name="text">The string to measure.</param>
/// <param name="bounds">A SizeF structure containing the maximum desired width and height of the text. Pass SizeF.Empty to disable wrapping calculations. A width or height of 0 disables the relevant calculation.</param>
/// <param name="format">A StringFormat object which specifies the measurement format of the string. Pass null to use the default StringFormat (StringFormat.GenericTypographic).</param>
/// <returns>A RectangleF containing the bounding box for the specified text.</returns>
public RectangleF MeasureText(string text, SizeF bounds, StringFormat format)
{
return MeasureText(text, bounds, format, null);
}
#endregion
#region public RectangleF MeasureText(string text, SizeF bounds, StringFormat format, IList<RectangleF> ranges)
/// <summary>
/// Calculates size information for the specified text.
/// </summary>
/// <param name="text">The string to measure.</param>
/// <param name="bounds">A SizeF structure containing the maximum desired width and height of the text. Pass SizeF.Empty to disable wrapping calculations. A width or height of 0 disables the relevant calculation.</param>
/// <param name="format">A StringFormat object which specifies the measurement format of the string. Pass null to use the default StringFormat (StringFormat.GenericDefault).</param>
/// <param name="ranges">Fills the specified IList of RectangleF structures with position information for individual characters. If this argument is null, these calculations are skipped.</param>
/// <returns>A RectangleF containing the bounding box for the specified text.</returns>
public RectangleF MeasureText(string text, SizeF bounds, StringFormat format, IList<RectangleF> ranges)
{
int status = 0;
if (String.IsNullOrEmpty(text))
return RectangleF.Empty;
if (bounds == SizeF.Empty)
bounds = maximum_graphics_size;
if (format == null)
format = default_string_format;
if (ranges != null)
ranges.Clear();
IntPtr[] regions = new IntPtr[GdiPlus.MaxMeasurableCharacterRanges];
CharacterRange[] characterRanges = new CharacterRange[GdiPlus.MaxMeasurableCharacterRanges];
PointF origin = PointF.Empty;
SizeF size = SizeF.Empty;
RectangleF rect = new RectangleF();
for (int i = 0; i < text.Length; i += GdiPlus.MaxMeasurableCharacterRanges)
{
int num_characters = text.Length - i > GdiPlus.MaxMeasurableCharacterRanges ? GdiPlus.MaxMeasurableCharacterRanges : text.Length - i;
for (int j = 0; j < num_characters; j++)
{
characterRanges[j] = new CharacterRange(i + j, 1);
IntPtr region;
status = GdiPlus.CreateRegion(out region);
regions[j] = region;
if (status != 0)
Debug.Print("GDI+ error: {0}", status);
}
CharacterRange[] a = (CharacterRange[])characterRanges.Clone();
Array.Resize(ref a, num_characters);
format.SetMeasurableCharacterRanges(a);
IntPtr native_graphics = GdiPlus.GetNativeGraphics(gfx);
IntPtr native_font = GdiPlus.GetNativeFont(font);
IntPtr native_string_format = GdiPlus.GetNativeStringFormat(format);
RectangleF layoutRect = new RectangleF(PointF.Empty, bounds);
status = GdiPlus.MeasureCharacterRanges(new HandleRef(gfx, native_graphics), text, text.Length,
new HandleRef(font, native_font), ref layoutRect,
new HandleRef(format, (format == null) ? IntPtr.Zero : native_string_format),
num_characters, regions);
for (int j = 0; j < num_characters; j++)
{
status = GdiPlus.GetRegionBounds(regions[j], new HandleRef(gfx, GdiPlus.GetNativeGraphics(gfx)), ref rect);
if (i == 0 && j == 0)
origin = rect.Location;
//if (origin.X > 0)
// rect.X -= (float)System.Math.Floor(origin.X);
if (ranges != null)
ranges.Add(rect);
status = GdiPlus.DeleteRegion(regions[j]);
}
}
//origin.X = 0;
return new RectangleF(origin.X, origin.Y, rect.Right, rect.Bottom);
}
#endregion
#endregion
#region --- Private Methods ---
#region private void PrepareTexturePacker()
/// <summary>
@ -101,53 +418,18 @@ namespace OpenTK.Graphics
#endregion
#region public void LoadGlyphs(string glyphs)
#region private void LoadGlyph(char c, out RectangleF rectangle)
/// <summary>
/// Prepares the specified glyphs for rendering.
/// </summary>
/// <param name="glyphs">The glyphs to prepare for rendering.</param>
public void LoadGlyphs(string glyphs)
{
Box2 rect = new Box2();
foreach (char c in glyphs)
{
if (!loaded_glyphs.ContainsKey(c))
LoadGlyph(c, out rect);
}
}
#endregion
#region public void LoadGlyph(char glyph)
/// <summary>
/// Prepares the specified glyph for rendering.
/// </summary>
/// <param name="glyphs">The glyph to prepare for rendering.</param>
public void LoadGlyph(char glyph)
{
Box2 rect = new Box2();
if (!loaded_glyphs.ContainsKey(glyph))
LoadGlyph(glyph, out rect);
}
#endregion
#region private void LoadGlyph(char c, out Box2 rectangle)
/// <summary>
/// Adds a glyph to the texture packer.
/// </summary>
/// <param name="c">The character of the glyph.</param>
/// <param name="rectangle">An OpenTK.Math.Box2 that will hold the buffer for this glyph.</param>
private void LoadGlyph(char c, out Box2 rectangle)
// Adds the specified caharacter to the texture packer.
private void LoadGlyph(char c, out RectangleF rectangle)
{
if (pack == null)
PrepareTexturePacker();
Glyph g = new Glyph(c, font);
Rectangle rect = new Rectangle();
RectangleF glyph_rect = MeasureText(c.ToString(), SizeF.Empty, load_glyph_string_format);
SizeF glyph_size = new SizeF(glyph_rect.Right, glyph_rect.Bottom); // We need to do this, since the origin might not be (0, 0)
Glyph g = new Glyph(c, font, glyph_size);
Rectangle rect;
try
{
@ -162,8 +444,9 @@ namespace OpenTK.Graphics
GL.BindTexture(TextureTarget.Texture2D, texture);
//gfx.TextRenderingHint = TextRenderingHint.AntiAlias;
gfx.Clear(System.Drawing.Color.Transparent);
gfx.DrawString(g.Character.ToString(), g.Font, System.Drawing.Brushes.White, 0.0f, 0.0f);
gfx.DrawString(g.Character.ToString(), g.Font, System.Drawing.Brushes.White, 0.0f, 0.0f, default_string_format);
//BitmapData bitmap_data = bitmap.LockBits(new Rectangle(0, 0, rect.Width, rect.Height), ImageLockMode.ReadOnly,
// System.Drawing.Imaging.PixelFormat.Format32bppArgb);
@ -181,12 +464,8 @@ namespace OpenTK.Graphics
{
int* bitmap_data_ptr = (int*)bitmap_data.Scan0;
for (int y = 0; y < rect.Height; y++)
{
for (int x = 0; x < rect.Width; x++)
{
data[y * rect.Width + x] = *(bitmap_data_ptr + y * bmp.Width + x);
}
}
fixed (int* data_ptr = data)
GL.TexSubImage2D(TextureTarget.Texture2D, 0, rect.Left, rect.Top, rect.Width, rect.Height,
@ -194,7 +473,7 @@ namespace OpenTK.Graphics
}
bmp.UnlockBits(bitmap_data);
rectangle = new Box2(
rectangle = RectangleF.FromLTRB(
rect.Left / (float)texture_width,
rect.Top / (float)texture_height,
rect.Right / (float)texture_width,
@ -206,56 +485,9 @@ namespace OpenTK.Graphics
#endregion
#region public bool GlyphData(char glyph, out float width, out float height, out Box2 textureRectangle, out int texture)
/// <summary>
/// Returns the characteristics of a loaded glyph.
/// </summary>
/// <param name="glyph">The character corresponding to this glyph.</param>
/// <param name="width">The width of this glyph.</param>
/// <param name="height">The height of this glyph (line spacing).</param>
/// <param name="textureRectangle">The bounding box of the texture buffer of this glyph.</param>
/// <param name="texture">The handle to the texture that contains this glyph.</param>
/// <returns>True if the glyph has been loaded, false otherwise.</returns>
/// <seealso cref="LoadGlyphs"/>
public bool GlyphData(char glyph, out float width, out float height, out Box2 textureRectangle, out int texture)
{
if (loaded_glyphs.TryGetValue(glyph, out textureRectangle))
{
width = textureRectangle.Width * texture_width;
height = textureRectangle.Height * texture_height;
texture = TextureFont.texture;
return true;
}
width = height = texture = 0;
return false;
}
#endregion
#region public float Height
/// <summary>
/// Gets a float indicating the default line spacing of this font.
/// </summary>
public float Height
{
get { return font.Height; }
}
#endregion
#region public float Width
/// <summary>
/// Gets a float indicating the default line spacing of this font.
/// </summary>
public float Width
{
get { return font.SizeInPoints; }
}
#endregion
#region --- Internal Methods ---
#region internal int Texture
@ -269,56 +501,6 @@ namespace OpenTK.Graphics
#endregion
#region public void MeasureString(string str, out float width, out float height, bool accountForOverhangs)
/// <summary>
/// Measures the width of the specified string.
/// </summary>
/// <param name="str">The string to measure.</param>
/// <param name="width">The measured width.</param>
/// <param name="height">The measured height.</param>
/// <param name="addSpace">If true, adds space to account for glyph overhangs. Set to true if you wish to measure a complete string. Set to false if you wish to perform layout on adjacent strings.</param>
public void MeasureString(string str, out float width, out float height, bool accountForOverhangs)
{
System.Drawing.StringFormat format = accountForOverhangs ? System.Drawing.StringFormat.GenericDefault : System.Drawing.StringFormat.GenericTypographic;
format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
System.Drawing.SizeF size = gfx.MeasureString(str, font, 16384, format);
height = size.Height;
width = size.Width;
// width = 0;
// height = 0;
// int i = 0;
// foreach (char c in str)
// {
// if (c != '\n' && c != '\r')
// {
// SizeF size = gfx.MeasureString(str.Substring(i, 1), font, 16384, System.Drawing.StringFormat.GenericTypographic);
// width += size.Width == 0 ? font.SizeInPoints * 0.5f : size.Width;
// if (height < size.Height)
// height = size.Height;
// }
// ++i;
// }
}
#endregion
#region public void MeasureString(string str, out float width, out float height)
/// <summary>
/// Measures the width of the specified string.
/// </summary>
/// <param name="str">The string to measure.</param>
/// <param name="width">The measured width.</param>
/// <param name="height">The measured height.</param>
/// <seealso cref="public void MeasureString(string str, out float width, out float height, bool accountForOverhangs)"/>
public void MeasureString(string str, out float width, out float height)
{
MeasureString(str, out width, out height, true);
}
#endregion
#region --- IDisposable Members ---

View file

@ -31,6 +31,8 @@ namespace OpenTK
#endregion
#region --- Public Methods ---
#region public Rectangle Add(T item)
/// <summary>
@ -91,6 +93,8 @@ namespace OpenTK
#endregion
#endregion
#region Node
class Node