Click here to Skip to main content
Click here to Skip to main content
Articles » Multimedia » OpenGL » General » Downloads
 

SharpGL: A C# OpenGL Class Library

By , 22 Feb 2012
 
SharpGL_2.0_Binaries.zip
SharpGL Binaries
Debug
Apex.dll
SharpGL.dll
SharpGL.SceneGraph.dll
SharpGL.Serialization.dll
SharpGL.WinForms.dll
SharpGL.WPF.dll
Release
Apex.dll
SharpGL.dll
SharpGL.SceneGraph.dll
SharpGL.Serialization.dll
SharpGL.WinForms.dll
SharpGL.WPF.dll
SharpGL.vsix
SharpGL_2.0_Samples.zip
SharpGL 2.0 Samples
Apex.dll
Apple.cob
Crate.bmp
Decal.bmp
ducky.obj
ExtensionsSample.exe
HitTestSample.exe
NativeTexturesSample.exe
Normal Map.bmp
Particle.png
ParticleSystemSample.exe
PolygonLoadingSample.exe
RadialBlurSample.exe
RenderContextsSample.exe
SceneSample.exe
SharpGL.dll
SharpGL.SceneGraph.dll
SharpGL.Serialization.dll
SharpGL.WinForms.dll
SharpGL.WPF.dll
SharpGLTexturesSample.exe
SimpleShaderSample.exe
TeapotSample.exe
TextRenderingSample.exe
SharpGL_2.0_Source_Code.zip
SharpGL
Assets
Images
Icons.psd
SharpGL.ico
SharpGLWinForms.ico
SharpGLWpfProject.ico
Models
Apple.cob
ducky.obj
Scenes
Apple.sglsx
Shaders
lambert01vert.glsl
marblelambfrag.glsl
Core
SharpGL.SceneGraph
Assets
Cameras
Core
Effects
Evaluators
Feedback
Helpers
Lighting
OpenGLAttributes
ParticleSystem
Primitives
Properties
Quadrics
Raytracing
Shaders
SharpGL.SceneGraph.csproj.vspscc
SharpGL.snk
Transformations
SharpGL.Serialization
Caligari
Discreet
Properties
SharpGL.Serialization.csproj.vspscc
SharpGL.snk
SharpGL
Wavefront
SharpGL.WinForms
Properties
SharpGL.ico
SharpGL.png
SharpGL.snk
SharpGL.WinForms.csproj.vspscc
SharpGL.WPF
Properties
Settings.settings
Resources
Folder_16x16.png
Light_16x16.png
Star_16x16.png
SceneTree
SharpGL.snk
SharpGL.WPF.csproj.vspscc
Themes
SharpGL
Enumerations
Properties
RenderContextProviders
SharpGL.csproj.vspscc
SharpGL.snk
Dependencies
Apex.dll
Apex.WinForms.dll
ICSharpCode.AvalonEdit.dll
RibbonControlsLibrary.dll
Extensions
SharpGL
Properties
SharpGL.csproj.vspscc
SharpGL.ico
SharpGL.JPG
SharpGL.snk
source.extension.vsixmanifest
WinformsTemplate
Dependencies
SharpGL.dll
SharpGL.SceneGraph.dll
SharpGL.WinForms.dll
Properties
Settings.settings
WinformsTemplate.csproj.vspscc
WinformsTemplateProject
__TemplateIcon.ico
Dependencies
SharpGL.dll
SharpGL.SceneGraph.dll
SharpGL.WinForms.dll
Properties
Settings.settings
WinformsTemplateProject.csproj.vspscc
WinformsTemplateProject.vstemplate
WpfTemplate
Dependencies
SharpGL.dll
SharpGL.SceneGraph.dll
SharpGL.WPF.dll
Properties
Settings.settings
WpfTemplate.csproj.vspscc
WpfTemplateProject
__TemplateIcon.ico
Dependencies
SharpGL.dll
SharpGL.SceneGraph.dll
SharpGL.WPF.dll
Properties
Settings.settings
WpfTemplateProject.csproj.vspscc
WpfTemplateProject.ico
WpfTemplateProject.vstemplate
Samples
WinForms
ExtensionsExample
ExtensionsExample.csproj.vspscc
Properties
Settings.settings
ExtensionsSample
Decal.bmp
ExtensionsSample.csproj.vspscc
Normal Map.bmp
Properties
Settings.settings
SharpGL.ico
HitTestSample
HitTestSample.csproj.vspscc
Properties
Settings.settings
SceneSample.csproj.vspscc
SharpGL.ico
NativeTexturesSample
Crate.bmp
NativeTexturesSample.csproj.vspscc
Properties
Settings.settings
SharpGL.ico
ParticleSystemSample
Particle.png
ParticleSystemSample.csproj.vspscc
Properties
Settings.settings
SharpGL.ico
PolygonLoadingSample
Apple.cob
ducky.obj
PolygonLoadingSample.csproj.vspscc
Properties
Settings.settings
SharpGL.ico
RadialBlurSample
Properties
Settings.settings
RadialBlurSample.csproj.vspscc
SharpGL.ico
RenderContextsSample
Properties
Settings.settings
RenderContextsSample.csproj.vspscc
SharpGL.ico
SceneSample
Properties
Settings.settings
SceneSample.csproj.vspscc
SharpGL.ico
SharpGLTexturesSample
Crate.bmp
NeHe.bmp
Properties
Settings.settings
SharpGL.ico
SharpGLTexturesSample.csproj.vspscc
SimpleDrawingSample
Properties
Settings.settings
SharpGL.ico
SimpleDrawingSample.csproj.vspscc
WPF
CelShadingSample
CelShadingSample.csproj.vspscc
PerPixelLightingFragment.glsl
PerPixelLightingVertex.glsl
Properties
Settings.settings
SimpleShaderSample
Properties
Settings.settings
SimpleShaderSample.csproj.vspscc
TeapotSample.csproj.vspscc
TeapotSample
Properties
Settings.settings
SharpGL.ico
TeapotSample.csproj.vspscc
TextRenderingSample
Properties
Settings.settings
SharpGL.ico
TextRenderingSample.csproj.vspscc
TwoDSample
Properties
Settings.settings
TwoDSample.csproj.vspscc
Tools
DataLoader
DataLoader.csproj.vspscc
Properties
Settings.settings
OpenGLInfo
OpenGLInfo.csproj.vspscc
Properties
Settings.settings
SceneBuilder
App.ico
Images
move.gif
rotate.gif
scale.gif
Scene Tree
Tabs
Info.gif
PointsBuilder
PolygonBuilder
SceneBuilder.csproj.vspscc
Thumbs.db
ShaderBuilder
ShaderBuilder
glsl.xshd
Properties
Settings.settings
Resources
BackgroundBrush.bmp
Shader
ShaderBuilder.csproj.vspscc
SharpGL.ico
SharpGLStudio
Dependencies
Apex.dll
Images
AlignCenter_16x16.png
AlignLeft_16x16.png
AlignRight_16x16.png
Bold_16x16.png
Borders_16x16.png
BordersAndShading_16x16.png
BottomBorder_16x16.png
Bullets_16x16.png
ChooseColor_16x16.png
ClearFormatting_16x16.png
Close_16x16.png
Color_16x16.png
ColorPalette.png
ConnectionManager_48x48.png
Copy_16x16.png
Cut_16x16.png
DecreaseIndent_16x16.png
Default_16x16.png
DiagonalDownBorder_16x16.png
DiagonalUpBorder_16x16.png
Document_16x16.png
DownArrow_16x16.png
DownArrow_32x32.png
DrawTable_16x16.png
EditRedo_16x16.png
EditUndo_16x16.png
Erase_16x16.png
Find_16x16.png
Find_32x32.png
FolderClosed_48x48.png
Font_16x16.png
Font_32x32.png
FontColor_16x16.png
FontScript_16x16.png
Forecolor_16x16.png
FormatPainter_16x16.png
GoTo_16x16.png
Help_16x16.png
Highlight_16x16.png
IncreaseIndent_16x16.png
InsideBorders_16x16.png
InsideHorizontalBorder_16x16.png
InsideVerticalBorder_16x16.png
Italic_16x16.png
Justify_16x16.png
LeftArrow_32x32.png
LeftBorder_16x16.png
LineColor_16x16.png
LineSpacing_16x16.png
Minus_32x32.png
MultilevelList_16x16.png
NewDocument_16x16.png
NewPermission_32x32.png
NoBorder_16x16.png
Numbering_16x16.png
Open_16x16.png
Options_16x16.png
OuterBorders_16x16.png
Paragraph_16x16.png
Paragraph_32x32.png
ParagraphSpacing_16x16.png
Paste_16x16.png
Paste_32x32.png
Plus_32x32.png
Print_16x16.png
Printer_48x48.png
PrintPreview_16x16.png
PublishPlan_16x16.png
RefreshArrow_32x32.png
Replace_16x16.png
RightArrow_32x32.png
RightBorder_16x16.png
Save_16x16.png
Select_16x16.png
SelectionPane_16x16.png
SendLinkByEmail_32x32.png
Shading_16x16.png
ShowGridlines_16x16.png
ShowHide_16x16.png
Sort_16x16.png
Styles_32x32.png
StylesGroup.png
Table_32x32.png
ThemeFonts.png
Tick_32x32.png
TopBorder_16x16.png
UpArrow_16x16.png
UpArrow_32x32.png
Properties
Settings.settings
Resources
BackgroundBrush.bmp
SharpGLStudio.csproj.vspscc
SharpGL_2.0_Visual_Studio_Extension.zip
SharpGL 2.0 Visual Studio Extension
SharpGL.vsix
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;

using SharpGL.SceneGraph.Collections;
using SharpGL.SceneGraph.Core;
using SharpGL.SceneGraph.Lighting;
using SharpGL.SceneGraph.Raytracing;
using SharpGL.SceneGraph.Helpers;
using System.Xml.Serialization;
using SharpGL.SceneGraph.Transformations;

namespace SharpGL.SceneGraph.Primitives
{
	/// <summary>
	/// A polygon contains a set of 'faces' which are indexes into a single list
	/// of vertices. The main thing about polygons is that they are easily editable
	/// by the user, depending on the Context they're in.
	/// </summary>
	[Serializable]
	public class Polygon : 
        SceneElement, 
        IHasObjectSpace,
        IRenderable,
        IRayTracable,
        IFreezable,
        IVolumeBound,
        IDeepCloneable<Polygon>
	{
        /// <summary>
        /// Initializes a new instance of the <see cref="Polygon"/> class.
        /// </summary>
		public Polygon() 
		{
			Name = "Polygon";
		}

		/// <summary>
		/// This function is cool, just stick in a set of points, it'll add them to the
		/// array, and create a face. It will take account of duplicate vertices too!
		/// </summary>
		/// <param name="vertexData">A set of vertices to make into a face.</param>
		public virtual void AddFaceFromVertexData(Vertex[] vertexData)
		{
			//	Create a face.
			Face newFace = new Face();

			//	Go through the vertices...
			foreach(Vertex v in vertexData)
			{
				//	Do we have this vertex already?
				int at = VertexSearch.Search(vertices, 0, v, 0.01f);
				
				//	Add the vertex, and index it.
                if (at == -1)
                {
                    newFace.Indices.Add(new Index(vertices.Count));
                    vertices.Add(v);
                }
                else
                {
                    newFace.Indices.Add(new Index(at));
                }
			}

			//	Add the face.
			faces.Add(newFace);
		}

		/// <summary>
		/// Triangulate this polygon.
		/// </summary>
		public void Triangulate()
		{
			List<Face> newFaces = new List<Face>();

			//	Go through each face...
			foreach(Face face in faces)
			{
				//	Number of triangles = vertices - 2.
				int triangles = face.Indices.Count - 2;

				//	Is it a triangle already?...
				if(triangles == 1)
				{
					newFaces.Add(face);
					continue;
				}

				//	Add a set of triangles.
				for(int i=0; i<triangles; i++)
				{
					Face triangle = new Face();
					triangle.Indices.Add(new Index(face.Indices[0]));
					triangle.Indices.Add(new Index(face.Indices[i+1]));
					triangle.Indices.Add(new Index(face.Indices[i+2]));
					triangle.Indices.Add(new Index(face.Indices[i+2]));
					triangle.Indices.Add(new Index(face.Indices[i+1]));
					newFaces.Add(triangle);
				}
			}

			faces.Clear();
			faces = newFaces;
		}

        /// <summary>
        /// Render to the provided instance of OpenGL.
        /// </summary>
        /// <param name="gl">The OpenGL instance.</param>
        /// <param name="renderMode">The render mode.</param>
        public virtual void Render(OpenGL gl, RenderMode renderMode)
        {
            //  If we're frozen, use the helper.
            if (freezableHelper.IsFrozen)
            {
                freezableHelper.Render(gl);
                return;
            }

            foreach (Face face in faces)
            {
                //	Begin drawing a polygon.
                if (face.Indices.Count == 2)
                    gl.Begin(OpenGL.GL_LINES);
                else
                    gl.Begin(OpenGL.GL_POLYGON);

                foreach (Index index in face.Indices)
                {
                    //	Set a texture coord (if any).
                    if (index.UV != -1)
                        gl.TexCoord(uvs[index.UV]);

                    //	Set a normal, or generate one.
                    if (index.Normal != -1)
                        gl.Normal(normals[index.Normal]);
                    else
                    {
                        //	Do we have enough vertices for a normal?
                        if (face.Indices.Count >= 3)
                        {
                            //	Create a normal.
                            Vertex vNormal = face.GetSurfaceNormal(this);
                            vNormal.UnitLength();

                            // todo use auto smoothing instead
                            //	Add it to the normals, setting the index for next time.
                            normals.Add(vNormal);
                            index.Normal = normals.Count - 1;

                            gl.Normal(vNormal);
                        }
                    }

                    //	Set the vertex.
                    gl.Vertex(vertices[index.Vertex]);
                }

                gl.End();
            }

            //	Draw normals if we have to.
            if (drawNormals)
            {
                //	Set the colour to red.
                gl.PushAttrib(OpenGL.GL_ALL_ATTRIB_BITS);
                gl.Color(1, 0, 0, 1);
                gl.Disable(OpenGL.GL_LIGHTING);

                //	Go through each face.
                foreach (Face face in faces)
                {
                    //	Go though each index.
                    foreach (Index index in face.Indices)
                    {
                        //	Make sure it's got a normal, and a vertex.
                        if (index.Normal != -1 && index.Vertex != -1)
                        {
                            //	Get the vertex.
                            Vertex vertex = vertices[index.Vertex];

                            //	Get the normal vertex.
                            Vertex normal = normals[index.Normal];
                            Vertex vertex2 = vertex + normal;

                            gl.Begin(OpenGL.GL_LINES);
                            gl.Vertex(vertex);
                            gl.Vertex(vertex2);
                            gl.End();
                        }
                    }
                }

                //	Restore the attributes.
                gl.PopAttrib();
            }
        }

		

		/// <summary>
		/// This creates a polygon from a height map (any picture). Black is low, 
		/// and the colors are high (the lighter the color, the higher the surface).
		/// </summary>
		/// <param name="filename">Path of the image file.</param>
		/// <param name="xPoints">Number of points along X.</param>
		/// <param name="yPoints">Number of points along Y.</param>
		/// <returns>True if sucessful, false otherwise.</returns>
		public virtual bool CreateFromMap(string filename, int xPoints, int yPoints)
		{
			//	Try and load the image file.
			System.Drawing.Bitmap map = new System.Drawing.Bitmap(filename);
			if(map.Size.IsEmpty)
				return false;

			//	Set the descriptive name.
			Name = "Map created from '" + filename + "'";

			//	Get points.
			for(int y=0; y < yPoints; y++)
			{
				int yValue = (map.Height / yPoints) * y;

				for(int x=0; x < xPoints; x++)
				{
					int xValue = (map.Width / xPoints) * x;

					//	Get the pixel.
					System.Drawing.Color col = map.GetPixel(xValue, yValue);

					float xPos = (float)x / (float)xPoints;
					float yPos = (float)y / (float)yPoints;

					//	Create a control point from it.
					Vertex v = new Vertex(xPos, 0, yPos);

					//	Add the 'height', based on color.
					v.Y = (float)col.R / 255.0f + (float)col.G / 255.0f + 
						(float)col.B / 255.0f;
					
					//	Add this vertex to the vertices array.
					Vertices.Add(v);
				}
			}

			//	Create faces for the polygon.
			for(int y=0; y < (yPoints-1); y++)
			{
				for(int x=0; x < (xPoints-1); x++)
				{
					//	Create the face.
					Face face = new Face();

					//	Create vertex indicies.
					int nTopLeft = (y * xPoints) + x;
					int nBottomLeft = ((y + 1) * xPoints) + x;
					
					face.Indices.Add(new Index(nTopLeft));
					face.Indices.Add(new Index(nTopLeft + 1));
					face.Indices.Add(new Index(nBottomLeft + 1));
					face.Indices.Add(new Index(nBottomLeft));

					// Add the face.
					Faces.Add(face);
				}
			}

			return true;
		}

		/// <summary>
		/// This function performs lossless optimisation on the polygon, it should be 
		/// called when the geometry changes, and the polygon goes into static mode.
		/// </summary>
		/// <returns>The amount of optimisation (as a %).</returns>
		protected virtual float OptimisePolygon()
		{
			//	Check for any null faces.
			float facesBefore = faces.Count;

			for(int i=0; i<faces.Count; i++)
			{
				if(faces[i].Count == 0)
					faces.RemoveAt(i--);
			}
			float facesAfter = faces.Count;

			return (facesAfter / facesBefore) * 100;
		}

		/// <summary>
		/// Call this function as soon as you change the polygons geometry, it will
		/// re-generate normals, etc.
		/// </summary>
		/// <param name="regenerateNormals">Regenerate Normals.</param>
		public virtual void Validate(bool regenerateNormals)
		{
			if(regenerateNormals)
				normals.Clear();

			//	Go through each face.
			foreach(Face face in faces)
			{
				if(regenerateNormals)
				{
					//	Find a normal for the face.
                    Vertex normal = face.GetSurfaceNormal(this);

					//	Does this normal already exist?
					int index = VertexSearch.Search(normals, 0, normal, 0.001f);

                    if (index == -1)
                    {
                        index = normals.Count;
                        normals.Add(normal);
                    }
					//	Set the index normal.
					foreach(Index i in face.Indices)
						i.Normal = index;
				}
			}
		}
        
        /// <summary>
        /// This function tests to see if a ray interesects the polygon.
        /// </summary>
        /// <param name="ray">The ray you want to test.</param>
        /// <returns>
        /// The distance from the origin of the ray to the intersection, or -1 if there
        /// is no intersection.
        /// </returns>
		private Intersection TestIntersection(Ray ray)
		{
			Intersection intersect = new Intersection();

			//	This code came from jgt intersect_triangle code (search dogpile for it).
			foreach(Face face in faces)
			{
				//	Assert that it's a triangle.
				if(face.Count != 3)
					continue;
			
				//	Find the point of intersection upon the plane, as a point 't' along
				//	the ray.
				Vertex point1OnPlane = vertices[face.Indices[0].Vertex];
				Vertex point2OnPlane = vertices[face.Indices[1].Vertex];
				Vertex point3OnPlane = vertices[face.Indices[2].Vertex];
				Vertex midpointOpp1 = (point2OnPlane + point3OnPlane) / 2;
				Vertex midpointOpp2 = (point1OnPlane + point3OnPlane) / 2;
				Vertex midpointOpp3 = (point1OnPlane + point2OnPlane) / 2;
				
				Vertex planeNormal = face.GetSurfaceNormal(this);


				Vertex diff = point1OnPlane - ray.origin;
				float s1 = diff.ScalarProduct(planeNormal);
				float s2 =  ray.direction.ScalarProduct(planeNormal);

				if(s2 == 0)
					continue;
				float t = s1 / s2;
				if(t < 0)
					continue;
	
				float denomintor = planeNormal.ScalarProduct(ray.direction);
				if(denomintor < 0.00001f && denomintor > -0.00001f)
					continue;	//	doesn't intersect the plane.

			//	Vertex v = point1OnPlane - ray.origin;
			//	float t = (v.ScalarProduct(planeNormal)) / denomintor;

				//	Now we can get the point of intersection.
				Vertex vIntersect = ray.origin + (ray.direction * t);

				//	Do my cool test.
				Vertex vectorTo1 = vIntersect - point1OnPlane;
				Vertex vectorTo2 = vIntersect - point2OnPlane;
				Vertex vectorTo3 = vIntersect - point3OnPlane;
				Vertex vectorMidTo1 = midpointOpp1 - point1OnPlane;
				Vertex vectorMidTo2 = midpointOpp2 - point2OnPlane;
				Vertex vectorMidTo3 = midpointOpp3 - point3OnPlane;
				
				if(vectorTo1.Magnitude() > vectorMidTo1.Magnitude())
					continue;
				if(vectorTo2.Magnitude() > vectorMidTo2.Magnitude())
					continue;
				if(vectorTo3.Magnitude() > vectorMidTo3.Magnitude())
					continue;

				if(intersect.closeness == -1 || t < intersect.closeness) 
				{
					//	It's fucking intersection city man
					intersect.point = vIntersect;
					intersect.intersected = true;
					intersect.normal = planeNormal;
					intersect.closeness = t;
				}
			}

			return intersect;
		}

        /// <summary>
        /// Raytraces the specified ray. If an intersection is found, it is returned,
        /// otherwise null is returned.
        /// </summary>
        /// <param name="ray">The ray.</param>
        /// <param name="scene">The scene.</param>
        /// <returns>
        /// The intersection with the object, or null.
        /// </returns>
		public Intersection Raytrace(Ray ray, Scene scene)
		{
			//	First we see if this ray intersects this polygon.
			Intersection intersect = TestIntersection(ray);

			//	If there wasn't an intersection, return.
			if(intersect.intersected == false)
				return intersect;

			//	There was an intersection, find the color of this point on the 
			//	polygon.
            var lights = from se in scene.SceneContainer.Traverse()
                         where se is Light
                         select se;
			foreach(Light light in lights)
			{
				if(light.On)
				{
					//	Can we see this light? Cast a shadow ray.
					Ray shadowRay = new Ray();
					bool shadow = false;
					shadowRay.origin = intersect.point;
					shadowRay.direction = light.Position - shadowRay.origin;

					//	Test it with every polygon.
					foreach(Polygon p in scene.SceneContainer.Traverse<Polygon>())
					{
						if(p == this) continue;
						Intersection shadowIntersect = p.TestIntersection(shadowRay);
						if(shadowIntersect.intersected)
						{
							shadow = true;
							break;
						}
					}

					if(shadow == false)
					{
						//	Now find out what this light complements to our color.
						//todofloat angle = light.Direction.ScalarProduct(intersect.normal);
						//todo ray.light += material.CalculateLighting(light, angle);
						ray.light.Clamp();
					}
				}
			}

			return intersect;
		}

		/// <summary>
		/// This function subdivides the faces of this polygon.
		/// </summary>
		/// <param name="smooth">If set to true the faces will be smoothed.</param>
		/// <returns>The number of faces in the new subdivided polygon.</returns>
		public int Subdivide()
		{
			List<Face> newFaces = new List<Face>();

			foreach(Face face in Faces)
			{
				//	Make sure the face is a triangle.
				if(face.Count != 3)
					continue;

				//	Now get the vertices of the face.
				Vertex v1 = Vertices[face.Indices[0].Vertex];
				Vertex v2 = Vertices[face.Indices[1].Vertex];
				Vertex v3 = Vertices[face.Indices[2].Vertex];

				//	Add the vertices to get a the midpoint of the edge formed by those
				//	vectors.
				Vertex vMidpoint = (v1 + v2 + v3) / 3;
				Index iMidpoint = new Index(Vertices.Count);
                Vertices.Add(vMidpoint);

				//	Now make three new faces from the old vertices and the midpoint.
				Face newFace = new Face();
				newFace.Indices.Add(new Index(face.Indices[0]));
				newFace.Indices.Add(new Index(face.Indices[1]));
				newFace.Indices.Add(iMidpoint);
				newFaces.Add(newFace);

				newFace = new Face();
				newFace.Indices.Add(new Index(face.Indices[1]));
				newFace.Indices.Add(new Index(face.Indices[2]));
				newFace.Indices.Add(iMidpoint);
				newFaces.Add(newFace);

				newFace = new Face();
				newFace.Indices.Add(new Index(face.Indices[2]));
				newFace.Indices.Add(new Index(face.Indices[0]));
				newFace.Indices.Add(iMidpoint);
				newFaces.Add(newFace);
			}

			faces = newFaces;

			return faces.Count;
		}

        /// <summary>
        /// Freezes this instance using the provided OpenGL instance.
        /// </summary>
        /// <param name="gl">The OpenGL instance.</param>
        public void Freeze(OpenGL gl)
        {
            //  Freeze using the helper.
            freezableHelper.Freeze(gl, this);
        }

        /// <summary>
        /// Unfreezes this instance using the provided OpenGL instance.
        /// </summary>
        /// <param name="gl">The OpenGL instance.</param>
        public void Unfreeze(OpenGL gl)
        {
            //  Unfreeze using the helper.
            freezableHelper.Unfreeze(gl);
        }

        /// <summary>
        /// Pushes us into Object Space using the transformation into the specified OpenGL instance.
        /// </summary>
        /// <param name="gl">The OpenGL instance.</param>
        public void PushObjectSpace(OpenGL gl)
        {
            //  Use the helper to push us into object space.
            hasObjectSpaceHelper.PushObjectSpace(gl);
        }

        /// <summary>
        /// Pops us from Object Space using the transformation into the specified OpenGL instance.
        /// </summary>
        /// <param name="gl">The gl.</param>
        public void PopObjectSpace(OpenGL gl)
        {
            //  Use the helper to pop us from object space.
            hasObjectSpaceHelper.PopObjectSpace(gl);
        }

        /// <summary>
        /// Creates a new object that is a copy of the current instance.
        /// </summary>
        /// <returns>
        /// A new object that is a copy of this instance.
        /// </returns>
        public Polygon DeepClone()
        {
            //  Create a new polygon.
            Polygon polygon = new Polygon();

            //  Clone the data.
            polygon.hasObjectSpaceHelper = hasObjectSpaceHelper.DeepClone();
            polygon.freezableHelper = new FreezableHelper();

            //  TODO clone lists.
            return polygon;
        }
        
        /// <summary>
        /// The IHasObjectSpace helper.
        /// </summary>
        private HasObjectSpaceHelper hasObjectSpaceHelper = new HasObjectSpaceHelper();

        /// <summary>
        /// The freezable helper.
        /// </summary>
        private FreezableHelper freezableHelper = new FreezableHelper();

		/// <summary>
		/// The faces that make up the polygon.
		/// </summary>
		private List<Face> faces = new List<Face>();

		/// <summary>
		/// The vertices that make up the polygon.
		/// </summary>
		private List<Vertex> vertices = new List<Vertex>();

		/// <summary>
		/// The UV coordinates (texture coodinates) for the polygon.
		/// </summary>
		private List<UV> uvs = new List<UV>();

		/// <summary>
		/// The normals of the polygon object.
		/// </summary>
		private List<Vertex> normals = new List<Vertex>();

		/// <summary>
		/// Should the normals be drawn?
		/// </summary>
		private bool drawNormals = false;

        /// <summary>
        /// The bounding volume helper - used to ease implementation of IBoundVolume.
        /// </summary>
        private BoundingVolumeHelper boundingVolumeHelper = new BoundingVolumeHelper();

        /// <summary>
        /// Gets or sets the faces.
        /// </summary>
        /// <value>
        /// The faces.
        /// </value>
		[Description("The faces that make up the polygon."), Category("Polygon")]
		public List<Face> Faces
		{
			get {return faces;}
			set {faces = value; }
		}

        /// <summary>
        /// Gets or sets the vertices.
        /// </summary>
        /// <value>
        /// The vertices.
        /// </value>
		[Description("The vertices that make up the polygon."), Category("Polygon")]
		public List<Vertex> Vertices
		{
			get {return vertices;}
			set {vertices = value; }
		}

        /// <summary>
        /// Gets or sets the U vs.
        /// </summary>
        /// <value>
        /// The U vs.
        /// </value>
		[Description("The material coordinates."), Category("Polygon")]
		public List<UV> UVs
		{
			get {return uvs;}
			set {uvs = value; }
		}

        /// <summary>
        /// Gets or sets the normals.
        /// </summary>
        /// <value>
        /// The normals.
        /// </value>
		[Description("The normals."), Category("Normals")]
		public List<Vertex> Normals
		{
			get {return normals;}
			set {normals = value; }
		}
        
        /// <summary>
        /// Gets or sets a value indicating whether [draw normals].
        /// </summary>
        /// <value>
        ///   <c>true</c> if [draw normals]; otherwise, <c>false</c>.
        /// </value>
		[Description("Should normals be drawn for each face?"), Category("Polygon")]
		public bool DrawNormals
		{
			get {return drawNormals;}
			set {drawNormals = value; }
		}

        /// <summary>
        /// Gets the transformation that pushes us into object space.
        /// </summary>
        [Description("The Polygon Object Space Transformation"), Category("Polygon")]
        public LinearTransformation Transformation
        {
            get { return hasObjectSpaceHelper.Transformation; }
            set { hasObjectSpaceHelper.Transformation = value; }
        }

        /// <summary>
        /// Gets the bounding volume.
        /// </summary>
        [Browsable(false)]
        [XmlIgnore]
        public BoundingVolume BoundingVolume
        {
            get 
            {
                //  todo; only create bv when vertices changed.
                boundingVolumeHelper.BoundingVolume.FromVertices(vertices);
                boundingVolumeHelper.BoundingVolume.Pad(0.1f); 
                return boundingVolumeHelper.BoundingVolume;
            }
        }

        /// <summary>
        /// Gets a value indicating whether this instance is frozen.
        /// </summary>
        /// <value>
        ///   <c>true</c> if this instance is frozen; otherwise, <c>false</c>.
        /// </value>
        [Browsable(false)]
        [XmlIgnore]
        public bool IsFrozen
        {
            get { return freezableHelper.IsFrozen; }
        }
    }

}

By viewing downloads associated with this article you agree to the Terms of use and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)

About the Author

Dave Kerr
Software Developer
United Kingdom United Kingdom
Member
Follow my blog at www.dwmkerr.com and find out about my charity at www.childrenshomesnepal.org.

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 22 Feb 2012
Article Copyright 2002 by Dave Kerr
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid