diff --git a/ClassicalSharp/GraphicsAPI/Direct3D9Api.cs b/ClassicalSharp/GraphicsAPI/Direct3D9Api.cs index e5f049f5c..59b843746 100644 --- a/ClassicalSharp/GraphicsAPI/Direct3D9Api.cs +++ b/ClassicalSharp/GraphicsAPI/Direct3D9Api.cs @@ -306,11 +306,16 @@ namespace ClassicalSharp.GraphicsAPI { device.SetVertexFormat( formatMapping[(int)VertexFormat.Pos3fTex2fCol4b] ); batchStride = VertexPos3fTex2fCol4b.Size; } - - public override void DrawIndexedVbBatch( DrawMode mode, int vb, int ib, int indicesCount, - int startVertex, int startIndex ) { - device.SetIndices( iBuffers[ib] ); + + public override void BindVb( int vb ) { device.SetStreamSource( 0, vBuffers[vb], 0, batchStride ); + } + + public override void BindIb( int ib ) { + device.SetIndices( iBuffers[ib] ); + } + + public override void DrawIndexedVb( DrawMode mode, int indicesCount, int startVertex, int startIndex ) { device.DrawIndexedPrimitives( modeMappings[(int)mode], startVertex, startVertex, indicesCount / 6 * 4, startIndex, NumPrimitives( indicesCount, mode ) ); } diff --git a/ClassicalSharp/GraphicsAPI/IGraphicsApi.cs b/ClassicalSharp/GraphicsAPI/IGraphicsApi.cs index d5a1b0489..6aa18068e 100644 --- a/ClassicalSharp/GraphicsAPI/IGraphicsApi.cs +++ b/ClassicalSharp/GraphicsAPI/IGraphicsApi.cs @@ -110,6 +110,8 @@ namespace ClassicalSharp.GraphicsAPI { public abstract int InitIb( ushort[] indices, int indicesCount ); + public abstract int InitIb( IntPtr indices, int indicesCount ); + public abstract bool IsValidVb( int vb ); public abstract bool IsValidIb( int ib ); diff --git a/ClassicalSharp/GraphicsAPI/OpenGLApi.cs b/ClassicalSharp/GraphicsAPI/OpenGLApi.cs index 5b67bcd94..d0c5838ad 100644 --- a/ClassicalSharp/GraphicsAPI/OpenGLApi.cs +++ b/ClassicalSharp/GraphicsAPI/OpenGLApi.cs @@ -184,45 +184,47 @@ namespace ClassicalSharp.GraphicsAPI { #region Vertex buffers Action setupBatchFunc; - Action setupBatchFuncTex2f, setupBatchFuncCol4b, setupBatchFuncTex2fCol4b; + Action setupBatchFuncTex2f, setupBatchFuncCol4b, setupBatchFuncTex2fCol4b; public unsafe override int CreateDynamicVb( VertexFormat format, int maxVertices ) { - int id = 0; - GL.GenBuffersARB( 1, &id ); + int id = GenAndBind( BufferTarget.ArrayBuffer ); int sizeInBytes = maxVertices * strideSizes[(int)format]; - GL.BindBufferARB( BufferTarget.ArrayBuffer, id ); GL.BufferDataARB( BufferTarget.ArrayBuffer, new IntPtr( sizeInBytes ), IntPtr.Zero, BufferUsageHint.DynamicDraw ); return id; } public unsafe override int InitVb( T[] vertices, VertexFormat format, int count ) { - int id = 0; - GL.GenBuffersARB( 1, &id ); + int id = GenAndBind( BufferTarget.ArrayBuffer ); int sizeInBytes = count * strideSizes[(int)format]; - GL.BindBufferARB( BufferTarget.ArrayBuffer, id ); - GCHandle handle = GCHandle.Alloc( vertices, GCHandleType.Pinned ); - GL.BufferDataARB( BufferTarget.ArrayBuffer, new IntPtr( sizeInBytes ), handle.AddrOfPinnedObject(), BufferUsageHint.StaticDraw ); - handle.Free(); + GL.BufferDataARB( BufferTarget.ArrayBuffer, new IntPtr( sizeInBytes ), vertices, BufferUsageHint.StaticDraw ); return id; } public unsafe override int InitIb( ushort[] indices, int indicesCount ) { + int id = GenAndBind( BufferTarget.ElementArrayBuffer ); + int sizeInBytes = indicesCount * sizeof( ushort ); + GL.BufferDataARB( BufferTarget.ElementArrayBuffer, new IntPtr( sizeInBytes ), indices, BufferUsageHint.StaticDraw ); + return id; + } + + public unsafe override int InitIb( IntPtr indices, int indicesCount ) { + int id = GenAndBind( BufferTarget.ElementArrayBuffer ); + int sizeInBytes = indicesCount * sizeof( ushort ); + GL.BufferDataARB( BufferTarget.ElementArrayBuffer, new IntPtr( sizeInBytes ), indices, BufferUsageHint.StaticDraw ); + return id; + } + + unsafe static int GenAndBind( BufferTarget target ) { int id = 0; GL.GenBuffersARB( 1, &id ); - int sizeInBytes = indicesCount * sizeof( ushort ); - GL.BindBufferARB( BufferTarget.ElementArrayBuffer, id ); - fixed( ushort* ptr = indices ) { - GL.BufferDataARB( BufferTarget.ElementArrayBuffer, new IntPtr( sizeInBytes ), (IntPtr)ptr, BufferUsageHint.StaticDraw ); - } + GL.BindBufferARB( target, id ); return id; } public override void DrawDynamicVb( DrawMode mode, int id, T[] vertices, VertexFormat format, int count ) { int sizeInBytes = count * strideSizes[(int)format]; GL.BindBufferARB( BufferTarget.ArrayBuffer, id ); - GCHandle handle = GCHandle.Alloc( vertices, GCHandleType.Pinned ); - GL.BufferSubDataARB( BufferTarget.ArrayBuffer, IntPtr.Zero, new IntPtr( sizeInBytes ), handle.AddrOfPinnedObject() ); - handle.Free(); + GL.BufferSubDataARB( BufferTarget.ArrayBuffer, IntPtr.Zero, new IntPtr( sizeInBytes ), vertices ); BeginVbBatch( format ); setupBatchFunc(); @@ -317,20 +319,21 @@ namespace ClassicalSharp.GraphicsAPI { GL.BindBufferARB( BufferTarget.ElementArrayBuffer, 0 ); } + IntPtr zero = new IntPtr( 0 ), twelve = new IntPtr( 12 ), sixteen = new IntPtr( 16 ); void SetupVbPos3fTex2f() { - GL.VertexPointer( 3, PointerType.Float, 20, new IntPtr( 0 ) ); - GL.TexCoordPointer( 2, PointerType.Float, 20, new IntPtr( 12 ) ); + GL.VertexPointer( 3, PointerType.Float, VertexPos3fTex2f.Size, zero ); + GL.TexCoordPointer( 2, PointerType.Float, VertexPos3fTex2f.Size, twelve ); } void SetupVbPos3fCol4b() { - GL.VertexPointer( 3, PointerType.Float, 16, new IntPtr( 0 ) ); - GL.ColorPointer( 4, PointerType.UnsignedByte, 16, new IntPtr( 12 ) ); + GL.VertexPointer( 3, PointerType.Float, VertexPos3fCol4b.Size, zero ); + GL.ColorPointer( 4, PointerType.UnsignedByte, VertexPos3fCol4b.Size, twelve ); } void SetupVbPos3fTex2fCol4b() { - GL.VertexPointer( 3, PointerType.Float, 24, new IntPtr( 0 ) ); - GL.ColorPointer( 4, PointerType.UnsignedByte, 24, new IntPtr( 12 ) ); - GL.TexCoordPointer( 2, PointerType.Float, 24, new IntPtr( 16 ) ); + GL.VertexPointer( 3, PointerType.Float, VertexPos3fTex2fCol4b.Size, zero ); + GL.ColorPointer( 4, PointerType.UnsignedByte, VertexPos3fTex2fCol4b.Size, twelve ); + GL.TexCoordPointer( 2, PointerType.Float, VertexPos3fTex2fCol4b.Size, sixteen ); } #endregion @@ -378,8 +381,8 @@ namespace ClassicalSharp.GraphicsAPI { game.SwapBuffers(); } - public override void SetVSync( Game game, bool value ) { - game.VSync = value; + public override void SetVSync( Game game, bool value ) { + game.VSync = value; } public unsafe override void PrintApiSpecificInfo() { diff --git a/OpenTK/Graphics/OpenGL/GL.cs b/OpenTK/Graphics/OpenGL/GL.cs index 830b51996..fb4732151 100644 --- a/OpenTK/Graphics/OpenGL/GL.cs +++ b/OpenTK/Graphics/OpenGL/GL.cs @@ -38,6 +38,11 @@ namespace OpenTK.Graphics.OpenGL { Interop.Calli( (int)target, size, data, (int)usage, BufferDataARBAddress ); } static IntPtr BufferDataARBAddress; + public static void BufferDataARB( BufferTarget target, IntPtr size, T[] data, BufferUsageHint usage ) where T : struct { + IntPtr dataPtr = Interop.Fixed( ref data[0] ); + Interop.Calli( (int)target, size, dataPtr, (int)usage, BufferDataARBAddress ); + } + public static void BufferSubData( BufferTarget target, IntPtr offset, IntPtr size, IntPtr data ) { Interop.Calli( (int)target, offset, size, data, BufferSubDataAddress ); } static IntPtr BufferSubDataAddress; @@ -45,6 +50,11 @@ namespace OpenTK.Graphics.OpenGL { public static void BufferSubDataARB( BufferTarget target, IntPtr offset, IntPtr size, IntPtr data ) { Interop.Calli( (int)target, offset, size, data, BufferSubDataARBAddress ); } static IntPtr BufferSubDataARBAddress; + + public static void BufferSubDataARB( BufferTarget target, IntPtr offset, IntPtr size, T[] data ) where T : struct { + IntPtr dataPtr = Interop.Fixed( ref data[0] ); + Interop.Calli( (int)target, offset, size, dataPtr, BufferSubDataARBAddress ); + } public static void Clear( ClearBufferMask mask ) { Interop.Calli( (int)mask, ClearAddress ); diff --git a/OpenTK/Graphics/OpenGL/Interop.cs b/OpenTK/Graphics/OpenGL/Interop.cs index 999c3347b..2f78a2088 100644 --- a/OpenTK/Graphics/OpenGL/Interop.cs +++ b/OpenTK/Graphics/OpenGL/Interop.cs @@ -5,6 +5,7 @@ namespace OpenTK.Graphics.OpenGL { internal static unsafe class Interop { static Exception rewriteEx = new NotImplementedException( "You need to run InteropPatcher on this dll." ); + public static IntPtr Fixed( ref T data ) { throw rewriteEx; } public static void Calli( IntPtr address ) { throw rewriteEx; } public static int Calli_Int32( IntPtr address ) { throw rewriteEx; } public static void Calli( int arg0, IntPtr address ) { throw rewriteEx; }