Opentk/Source/Examples/OpenGL/GLU/Tessellation.cs
the_fiddler 989be84c96 Moved and renamed examples to match the new example structurs.
Made example source code visible for all examples in example browser.
Updated Prebuild.exe to newest SVN version (resolves issues with resources).
Added .rtf and .resx files to Examples project in Prebuild.xml.
2009-04-20 09:48:33 +00:00

272 lines
8.7 KiB
C#

#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.Diagnostics;
using System.Runtime.InteropServices;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Input;
namespace Examples
{
[Example("GLU Tesselation Functions Test", ExampleCategory.OpenGL, "GLU", Visible = false)]
public class Test : GameWindow
{
int startList;
IntPtr tess;
// Define the signatures for the callback functions, and declare the callbacks.
delegate void BeginCallbackDelegate(BeginMode mode);
delegate void EndCallbackDelegate();
delegate void VertexCallbackDelegate(IntPtr v);
delegate void ErrorCallbackDelegate(GluErrorCode code);
unsafe delegate void CombineCallbackDelegate(
[MarshalAs(UnmanagedType.LPArray, SizeConst = 3)]double[] coordinates,
[MarshalAs(UnmanagedType.LPArray, SizeConst = 4)]double*[] vertexData,
[MarshalAs(UnmanagedType.LPArray, SizeConst = 4)]float[] weight,
double** dataOut);
BeginCallbackDelegate tessBegin;
EndCallbackDelegate tessEnd;
ErrorCallbackDelegate tessError;
VertexCallbackDelegate tessVertex;
CombineCallbackDelegate tessCombine;
public Test() : base()
{
Keyboard.KeyDown += KeyDownHandler;
}
#region --- GLU Tessellation callbacks ---
#region BeginHandler
void BeginHandler(BeginMode mode)
{
GL.Begin(mode);
}
#endregion
#region EndHandler
void EndHandler()
{
GL.End();
}
#endregion
#region VertexHandler
void VertexHandler(IntPtr v)
{
unsafe { GL.Vertex3((double*)v); }
}
#endregion
#region ErrorHandler
void ErrorHandler(GluErrorCode code)
{
System.Windows.Forms.MessageBox.Show(
String.Format("GLU Error {0}: {1}", code.ToString(), Glu.ErrorString(code)),
"An error occured while tesselating.");
this.Exit();
}
#endregion
#region CombineHandler
unsafe double*[] combineData;
int data_index = 0;
unsafe void CombineHandler(double[] coordinates, double*[] data, float[] weight, double** dataOut)
{
// Workaround Mono 1.2.6 bug with unsafe inline initializers
if (combineData == null)
combineData = new double*[16];
double* out_data = combineData[data_index] = (double*)Marshal.AllocHGlobal(6 * sizeof(double));
int i;
out_data[0] = coordinates[0];
out_data[1] = coordinates[1];
out_data[2] = coordinates[2];
for (i = 3; i < 6; i++)
{
double* real_data = (double*)data[i-3];
out_data[i] = weight[0] * real_data[0] +
weight[1] * real_data[1] +
weight[2] * real_data[2] +
weight[3] * real_data[3];
}
data_index++;
*dataOut = out_data;
}
#endregion
#endregion
#region KeyDownHandler
public void KeyDownHandler(KeyboardDevice sender, Key key)
{
switch (key)
{
case Key.Escape:
this.Exit();
return;
}
}
#endregion
#region OnResize
protected override void OnResize(OpenTK.Platform.ResizeEventArgs e)
{
GL.Viewport(0, 0, Width, Height);
GL.MatrixMode(MatrixMode.Projection);
GL.LoadIdentity();
Glu.Ortho2D(0.0, (double)Width, 0.0, (double)Height);
}
#endregion
#region OnLoad
public override void OnLoad(EventArgs e)
{
double[][] rect = new double[4][] {
new double[] {50.0, 50.0, 0.0},
new double[] {200.0, 50.0, 0.0},
new double[] {200.0, 200.0, 0.0},
new double[] {50.0, 200.0, 0.0}
};
double[][] tri = new double[3][] {
new double[] {75.0, 75.0, 0.0},
new double[] {125.0, 175.0, 0.0},
new double[] {175.0, 75.0, 0.0}
};
double[][] star = new double[5][] {
new double[] {250.0, 50.0, 0.0, 1.0, 0.0, 1.0},
new double[] {325.0, 200.0, 0.0, 1.0, 1.0, 0.0},
new double[] {400.0, 50.0, 0.0, 0.0, 1.0, 1.0},
new double[] {250.0, 150.0, 0.0, 1.0, 0.0, 0.0},
new double[] {400.0, 150.0, 0.0, 0.0, 1.0, 0.0}
};
GL.ClearColor(System.Drawing.Color.MidnightBlue);
tess = Glu.NewTess();
startList = GL.GenLists(3);
tessVertex = this.VertexHandler;
tessBegin = this.BeginHandler;
tessEnd = this.EndHandler;
tessError = this.ErrorHandler;
unsafe { tessCombine = this.CombineHandler; }
Trace.Assert(tessVertex != null, "Failed to load tesselator callback function.");
Trace.Assert(tessBegin != null, "Failed to load tesselator begin callback function.");
Trace.Assert(tessEnd != null, "Failed to load tesselator end callback function.");
Trace.Assert(tessError != null, "Failed to load tesselator error callback function.");
Trace.Assert(tessCombine != null, "Failed to load tesselator combine callback function.");
Glu.TessCallback(tess, TessCallback.TessVertex, tessVertex);
Glu.TessCallback(tess, TessCallback.TessBegin, tessBegin);
Glu.TessCallback(tess, TessCallback.TessEnd, tessEnd);
Glu.TessCallback(tess, TessCallback.TessError, tessError);
// rectangle with triangular hole inside
GL.NewList(startList, ListMode.Compile);
GL.ShadeModel(ShadingModel.Flat);
Glu.TessBeginPolygon(tess, IntPtr.Zero);
Glu.TessBeginContour(tess);
Glu.TessVertex(tess, rect[0], rect[0]);
Glu.TessVertex(tess, rect[1], rect[1]);
Glu.TessVertex(tess, rect[2], rect[2]);
Glu.TessVertex(tess, rect[3], rect[3]);
Glu.TessEndContour(tess);
Glu.TessBeginContour(tess);
Glu.TessVertex(tess, tri[0], tri[0]);
Glu.TessVertex(tess, tri[1], tri[1]);
Glu.TessVertex(tess, tri[2], tri[2]);
Glu.TessEndContour(tess);
Glu.TessEndPolygon(tess);
GL.EndList();
Glu.TessCallback(tess, TessCallback.TessVertex, tessVertex);
Glu.TessCallback(tess, TessCallback.TessBegin, tessBegin);
Glu.TessCallback(tess, TessCallback.TessEnd, tessEnd);
Glu.TessCallback(tess, TessCallback.TessError, tessError);
Glu.TessCallback(tess, TessCallback.TessCombine, tessCombine);
// smooth shaded, self-intersecting star
GL.NewList(startList + 1, ListMode.Compile);
GL.ShadeModel(ShadingModel.Smooth);
Glu.TessWindingRuleProperty(tess, TessWinding.TessWindingPositive);
Glu.TessBeginPolygon(tess, IntPtr.Zero);
Glu.TessBeginContour(tess);
Glu.TessVertex(tess, star[0], star[0]);
Glu.TessVertex(tess, star[1], star[1]);
Glu.TessVertex(tess, star[2], star[2]);
Glu.TessVertex(tess, star[3], star[3]);
Glu.TessVertex(tess, star[4], star[4]);
Glu.TessEndContour(tess);
Glu.TessEndPolygon(tess);
GL.EndList();
}
#endregion
#region OnUnload
public override void OnUnload(EventArgs e)
{
if (tess != IntPtr.Zero)
Glu.DeleteTess(tess);
GL.DeleteLists(startList, 3);
while (data_index != 0)
unsafe { Marshal.FreeHGlobal((IntPtr)combineData[data_index--]); }
}
#endregion
#region OnRenderFrame
public override void OnRenderFrame(RenderFrameEventArgs e)
{
GL.Clear(ClearBufferMask.ColorBufferBit);
GL.Color3(1.0f, 1.0f, 1.0f);
GL.CallList(startList);
GL.CallList(startList + 1);
GL.Flush();
this.SwapBuffers();
}
#endregion
public static void Main()
{
using (Test test = new Test())
{
Utilities.SetWindowTitle(test);
test.Run(30.0, 0.0);
}
}
}
}