mirror of
https://github.com/Ryujinx/Opentk.git
synced 2024-12-26 18:15:39 +00:00
182 lines
6.3 KiB
C#
182 lines
6.3 KiB
C#
#region --- License ---
|
|
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
|
|
* See license.txt for license info
|
|
*/
|
|
#endregion
|
|
|
|
using System;
|
|
|
|
using OpenTK;
|
|
using OpenTK.Graphics.OpenGL;
|
|
|
|
namespace Examples.Shapes
|
|
{
|
|
// Abstract base class for procedurally generated geometry
|
|
//
|
|
// All classes derived from it must produce Counter-Clockwise (CCW) primitives.
|
|
// Derived classes must create a single VBO and IBO, without primitive restarts for strips.
|
|
// Uses an double-precision all-possible-attributes VertexT2dN3dV3d Array internally.
|
|
// Cannot directly use VBO, but has Get-methods to retrieve VBO-friendly data.
|
|
// Can use a Display List to prevent repeated immediate mode draws.
|
|
//
|
|
|
|
public abstract class DrawableShape: IDisposable
|
|
{
|
|
protected BeginMode PrimitiveMode;
|
|
protected VertexT2dN3dV3d[] VertexArray;
|
|
protected uint[] IndexArray;
|
|
|
|
public int GetTriangleCount
|
|
{
|
|
get
|
|
{
|
|
switch ( PrimitiveMode )
|
|
{
|
|
case BeginMode.Triangles:
|
|
if ( IndexArray != null )
|
|
{
|
|
return IndexArray.Length / 3;
|
|
} else
|
|
{
|
|
return VertexArray.Length / 3;
|
|
}
|
|
// break;
|
|
default: throw new NotImplementedException("Unknown primitive type.");
|
|
}
|
|
}
|
|
}
|
|
|
|
#region Display List
|
|
|
|
private bool UseDisplayList;
|
|
private int DisplayListHandle = 0;
|
|
|
|
#endregion Display List
|
|
|
|
public DrawableShape( bool useDisplayList )
|
|
{
|
|
UseDisplayList = useDisplayList;
|
|
PrimitiveMode = BeginMode.Triangles;
|
|
VertexArray = null;
|
|
IndexArray = null;
|
|
}
|
|
|
|
#region Convert to VBO
|
|
|
|
public void GetArraysforVBO(out BeginMode primitives, out VertexT2dN3dV3d[] vertices, out uint[] indices)
|
|
{
|
|
primitives = PrimitiveMode;
|
|
|
|
vertices = new VertexT2dN3dV3d[VertexArray.Length];
|
|
for (uint i = 0; i < VertexArray.Length; i++)
|
|
{
|
|
vertices[i].TexCoord = VertexArray[i].TexCoord;
|
|
vertices[i].Normal = VertexArray[i].Normal;
|
|
vertices[i].Position = VertexArray[i].Position;
|
|
}
|
|
|
|
indices = IndexArray;
|
|
}
|
|
|
|
public void GetArraysforVBO(out BeginMode primitives, out VertexT2fN3fV3f[] vertices, out uint[] indices)
|
|
{
|
|
primitives = PrimitiveMode;
|
|
|
|
vertices = new VertexT2fN3fV3f[VertexArray.Length];
|
|
for (uint i = 0; i < VertexArray.Length; i++)
|
|
{
|
|
vertices[i].TexCoord = (Vector2)VertexArray[i].TexCoord;
|
|
vertices[i].Normal = (Vector3)VertexArray[i].Normal;
|
|
vertices[i].Position = (Vector3)VertexArray[i].Position;
|
|
}
|
|
|
|
indices = IndexArray;
|
|
}
|
|
|
|
public void GetArraysforVBO(out BeginMode primitives, out VertexT2hN3hV3h[] vertices, out uint[] indices)
|
|
{
|
|
primitives = PrimitiveMode;
|
|
|
|
vertices = new VertexT2hN3hV3h[VertexArray.Length];
|
|
for (uint i = 0; i < VertexArray.Length; i++)
|
|
{
|
|
vertices[i].TexCoord = (Vector2h)VertexArray[i].TexCoord;
|
|
vertices[i].Normal = (Vector3h)VertexArray[i].Normal;
|
|
vertices[i].Position = (Vector3h)VertexArray[i].Position;
|
|
}
|
|
|
|
indices = IndexArray;
|
|
}
|
|
|
|
#endregion Convert to VBO
|
|
|
|
private void DrawImmediateMode()
|
|
{
|
|
GL.Begin( PrimitiveMode );
|
|
{
|
|
if ( IndexArray == null )
|
|
foreach ( VertexT2dN3dV3d v in VertexArray )
|
|
{
|
|
GL.TexCoord2( v.TexCoord.X, v.TexCoord.Y );
|
|
GL.Normal3( v.Normal.X, v.Normal.Y, v.Normal.Z );
|
|
GL.Vertex3( v.Position.X, v.Position.Y, v.Position.Z );
|
|
} else
|
|
{
|
|
for ( uint i = 0; i < IndexArray.Length; i++ )
|
|
{
|
|
uint index = IndexArray[i];
|
|
GL.TexCoord2( VertexArray[index].TexCoord.X, VertexArray[index].TexCoord.Y );
|
|
GL.Normal3( VertexArray[index].Normal.X, VertexArray[index].Normal.Y, VertexArray[index].Normal.Z );
|
|
GL.Vertex3( VertexArray[index].Position.X, VertexArray[index].Position.Y, VertexArray[index].Position.Z );
|
|
}
|
|
}
|
|
}
|
|
GL.End();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Does not touch any state/matrices. Does call Begin/End and Vertex&Co.
|
|
/// Creates and compiles a display list if not present yet. Requires an OpenGL context.
|
|
/// </summary>
|
|
public void Draw()
|
|
{
|
|
if ( !UseDisplayList )
|
|
DrawImmediateMode();
|
|
else
|
|
if ( DisplayListHandle == 0 )
|
|
{
|
|
if ( VertexArray == null )
|
|
throw new Exception("Cannot draw null Vertex Array.");
|
|
DisplayListHandle = GL.GenLists( 1 );
|
|
GL.NewList( DisplayListHandle, ListMode.CompileAndExecute );
|
|
DrawImmediateMode();
|
|
GL.EndList();
|
|
} else
|
|
GL.CallList( DisplayListHandle );
|
|
}
|
|
|
|
#region IDisposable Members
|
|
|
|
/// <summary>
|
|
/// Removes reference to VertexArray and IndexArray.
|
|
/// Deletes the Display List, so it requires an OpenGL context.
|
|
/// The instance is effectively destroyed.
|
|
/// </summary>
|
|
public void Dispose()
|
|
{
|
|
if ( VertexArray != null )
|
|
VertexArray = null;
|
|
if ( IndexArray != null )
|
|
IndexArray = null;
|
|
if ( DisplayListHandle != 0 )
|
|
{
|
|
GL.DeleteLists( DisplayListHandle, 1 );
|
|
DisplayListHandle = 0;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
}
|