From 58a839db8191708cbdc754b5917c69b2eea590bc Mon Sep 17 00:00:00 2001 From: "SND\\AstrorEnales_cp" Date: Sun, 20 Nov 2011 12:49:11 +0000 Subject: [PATCH] Working on OpenGL vertex buffer, index buffer, effect and EffectParameter --- ANX.Framework/Graphics/IndexBuffer.cs | 5 +- ANX.Framework/Graphics/VertexBuffer.cs | 5 +- .../DatatypesMapping.cs | 92 +++++++++++++++++++ .../ANX.Framework.Windows.GL3/EffectGL3.cs | 6 +- .../EffectParameterGL3.cs | 19 +++- .../GraphicsDeviceWindowsGL3.cs | 43 +++++---- .../IndexBufferGL3.cs | 11 ++- .../ShaderByteCode.cs | 45 +++++---- .../VertexBufferGL3.cs | 49 +++++++++- shader/GL3/SpriteBatch_GLSL.fx | 17 +++- 10 files changed, 239 insertions(+), 53 deletions(-) diff --git a/ANX.Framework/Graphics/IndexBuffer.cs b/ANX.Framework/Graphics/IndexBuffer.cs index 60eeac37..a6f428d8 100644 --- a/ANX.Framework/Graphics/IndexBuffer.cs +++ b/ANX.Framework/Graphics/IndexBuffer.cs @@ -130,8 +130,9 @@ namespace ANX.Framework.Graphics throw new NotImplementedException(); } - [Obsolete("This is not a original XNA property")] - public INativeBuffer NativeIndexBuffer + // This is now internal because via befriending the assemblies + // it's usable in the modules but doesn't confuse the enduser. + internal INativeBuffer NativeIndexBuffer { get { diff --git a/ANX.Framework/Graphics/VertexBuffer.cs b/ANX.Framework/Graphics/VertexBuffer.cs index e6b1ecb4..e7776cd4 100644 --- a/ANX.Framework/Graphics/VertexBuffer.cs +++ b/ANX.Framework/Graphics/VertexBuffer.cs @@ -159,8 +159,9 @@ namespace ANX.Framework.Graphics } } - [Obsolete("This is not a original XNA property")] - public INativeBuffer NativeVertexBuffer + // This is now internal because via befriending the assemblies + // it's usable in the modules but doesn't confuse the enduser. + internal INativeBuffer NativeVertexBuffer { get { diff --git a/RenderSystems/ANX.Framework.Windows.GL3/DatatypesMapping.cs b/RenderSystems/ANX.Framework.Windows.GL3/DatatypesMapping.cs index 6a2854fa..35e98d5c 100644 --- a/RenderSystems/ANX.Framework.Windows.GL3/DatatypesMapping.cs +++ b/RenderSystems/ANX.Framework.Windows.GL3/DatatypesMapping.cs @@ -234,6 +234,98 @@ namespace ANX.Framework.Windows.GL3 } #endregion + #region PrimitiveTypeToBeginMode + /// + /// Translate the XNA PrimitiveType to an OpenGL BeginMode. + /// + /// XNA PrimitiveType. + /// Translated BeginMode for OpenGL. + public static BeginMode PrimitiveTypeToBeginMode(PrimitiveType type) + { + switch (type) + { + case PrimitiveType.LineList: + return BeginMode.Lines; + + case PrimitiveType.LineStrip: + return BeginMode.LineStrip; + + default: + case PrimitiveType.TriangleList: + return BeginMode.Triangles; + + case PrimitiveType.TriangleStrip: + return BeginMode.TriangleStrip; + } + } + #endregion + + #region VertexElementFormatToVertexPointerType (TODO) + /// + /// Translate the XNA VertexElementFormat to an OpenGL VertexPointerType. + /// + /// XNA VertexElementFormat. + /// Returns the size of the vertex element. + /// Translated VertexPointerType for OpenGL. + public static VertexPointerType VertexElementFormatToVertexPointerType( + VertexElementFormat format, out int size) + { + switch (format) + { + default: + case VertexElementFormat.Vector2: + size = 2; + return VertexPointerType.Float; + + case VertexElementFormat.Vector3: + size = 3; + return VertexPointerType.Float; + + case VertexElementFormat.Vector4: + size = 4; + return VertexPointerType.Float; + + case VertexElementFormat.Single: + size = 1; + return VertexPointerType.Float; + + case VertexElementFormat.HalfVector2: + size = 2; + return VertexPointerType.HalfFloat; + + case VertexElementFormat.HalfVector4: + size = 4; + return VertexPointerType.HalfFloat; + + // TODO: check difference Short2/NormalizedShort2 + case VertexElementFormat.NormalizedShort2: + size = 2; + return VertexPointerType.Short; + + // TODO: check difference Short4/NormalizedShort4 + case VertexElementFormat.NormalizedShort4: + size = 4; + return VertexPointerType.Short; + + // TODO: check difference Short2/NormalizedShort2 + case VertexElementFormat.Short2: + size = 2; + return VertexPointerType.Short; + + // TODO: check difference Short4/NormalizedShort4 + case VertexElementFormat.Short4: + size = 4; + return VertexPointerType.Short; + + // TODO: check + case VertexElementFormat.Byte4: + case VertexElementFormat.Color: + size = 1; + return VertexPointerType.Int; + } + } + #endregion + #region Tests private class Tests { diff --git a/RenderSystems/ANX.Framework.Windows.GL3/EffectGL3.cs b/RenderSystems/ANX.Framework.Windows.GL3/EffectGL3.cs index d59d17c7..83d8e301 100644 --- a/RenderSystems/ANX.Framework.Windows.GL3/EffectGL3.cs +++ b/RenderSystems/ANX.Framework.Windows.GL3/EffectGL3.cs @@ -107,7 +107,7 @@ namespace ANX.Framework.Windows.GL3 List names = new List(); for (int index = 0; index < uniformCount; index++) { - string name = GL.GetActiveUniformName(programHandle, 0); + string name = GL.GetActiveUniformName(programHandle, index); if (names.Contains(name) == false) { @@ -115,7 +115,8 @@ namespace ANX.Framework.Windows.GL3 int uniformIndex = GL.GetUniformLocation(programHandle, name); parameters.Add(new EffectParameter() { - NativeParameter = new EffectParameterGL3(name, uniformIndex), + NativeParameter = + new EffectParameterGL3(this, name, uniformIndex), }); } } @@ -304,6 +305,7 @@ namespace ANX.Framework.Windows.GL3 #region Apply (TODO) public void Apply(GraphicsDevice graphicsDevice) { + GL.Enable(EnableCap.Texture2D); GL.UseProgram(programHandle); } #endregion diff --git a/RenderSystems/ANX.Framework.Windows.GL3/EffectParameterGL3.cs b/RenderSystems/ANX.Framework.Windows.GL3/EffectParameterGL3.cs index 36720412..5408dadb 100644 --- a/RenderSystems/ANX.Framework.Windows.GL3/EffectParameterGL3.cs +++ b/RenderSystems/ANX.Framework.Windows.GL3/EffectParameterGL3.cs @@ -1,6 +1,7 @@ using System; using ANX.Framework.NonXNA; using ANX.Framework.Graphics; +using OpenTK.Graphics.OpenGL; #region License @@ -56,6 +57,10 @@ namespace ANX.Framework.Windows.GL3 /// public class EffectParameterGL3 : INativeEffectParameter { + #region Private + private EffectGL3 parentEffect; + #endregion + #region Public /// /// The name of the effect parameter. @@ -80,20 +85,23 @@ namespace ANX.Framework.Windows.GL3 /// /// Create a ne effect parameter object. /// - internal EffectParameterGL3(string setName, int setUniformIndex) + internal EffectParameterGL3(EffectGL3 setParentEffect, + string setName, int setUniformIndex) { + parentEffect = setParentEffect; Name = setName; UniformIndex = setUniformIndex; } #endregion - #region SetValue (TODO) + #region SetValue /// /// Set a matrix value to the effect parameter. /// /// Value for the parameter public void SetValue(Matrix value) { + GL.UniformMatrix4(UniformIndex, 16, false, ref value.M11); } /// @@ -102,6 +110,13 @@ namespace ANX.Framework.Windows.GL3 /// Value for the parameter public void SetValue(Texture value) { + // TODO: multiple texture units + TextureUnit textureUnit = TextureUnit.Texture0; + GL.ActiveTexture(textureUnit); + int handle = (value.NativeTexture as Texture2DGL3).NativeHandle; + GL.BindTexture(TextureTarget.Texture2D, handle); + int unitIndex = (int)(textureUnit - TextureUnit.Texture0); + GL.Uniform1(UniformIndex, 1, ref unitIndex); } #endregion } diff --git a/RenderSystems/ANX.Framework.Windows.GL3/GraphicsDeviceWindowsGL3.cs b/RenderSystems/ANX.Framework.Windows.GL3/GraphicsDeviceWindowsGL3.cs index dbc529e6..729a60a5 100644 --- a/RenderSystems/ANX.Framework.Windows.GL3/GraphicsDeviceWindowsGL3.cs +++ b/RenderSystems/ANX.Framework.Windows.GL3/GraphicsDeviceWindowsGL3.cs @@ -238,7 +238,9 @@ namespace ANX.Framework.Windows.GL3 int baseVertex, int minVertexIndex, int numVertices, int startIndex, int primitiveCount) { - throw new NotImplementedException(); + // TODO: DrawElementsType, baseVertex, minVertexIndex, numVertices, startIndex + GL.DrawElements(DatatypesMapping.PrimitiveTypeToBeginMode(primitiveType), + numVertices, DrawElementsType.UnsignedShort, 0); } public void DrawInstancedPrimitives(PrimitiveType primitiveType, @@ -266,17 +268,25 @@ namespace ANX.Framework.Windows.GL3 public void DrawPrimitives(PrimitiveType primitiveType, int vertexOffset, int primitiveCount) { - throw new NotImplementedException(); + // TODO: DrawElementsType + GL.DrawElements(DatatypesMapping.PrimitiveTypeToBeginMode(primitiveType), + primitiveCount, DrawElementsType.UnsignedInt, vertexOffset); } public void SetVertexBuffers(VertexBufferBinding[] vertexBuffers) { - throw new NotImplementedException(); + foreach (VertexBufferBinding binding in vertexBuffers) + { + INativeBuffer vertexBuffer = binding.VertexBuffer.NativeVertexBuffer; + GL.BindBuffer(BufferTarget.ArrayBuffer, + ((VertexBufferGL3)vertexBuffer).BufferHandle); + } } public void SetIndexBuffer(IndexBuffer indexBuffer) { - throw new NotImplementedException(); + GL.BindBuffer(BufferTarget.ElementArrayBuffer, + ((IndexBufferGL3)indexBuffer.NativeIndexBuffer).BufferHandle); } public void SetRenderTargets(params RenderTargetBinding[] renderTargets) @@ -305,17 +315,16 @@ namespace ANX.Framework.Windows.GL3 throw new NotImplementedException(); } - - public bool VSync - { - get - { - throw new NotImplementedException(); - } - set - { - throw new NotImplementedException(); - } - } - } + public bool VSync + { + get + { + throw new NotImplementedException(); + } + set + { + throw new NotImplementedException(); + } + } + } } diff --git a/RenderSystems/ANX.Framework.Windows.GL3/IndexBufferGL3.cs b/RenderSystems/ANX.Framework.Windows.GL3/IndexBufferGL3.cs index 2cb2496c..539ba618 100644 --- a/RenderSystems/ANX.Framework.Windows.GL3/IndexBufferGL3.cs +++ b/RenderSystems/ANX.Framework.Windows.GL3/IndexBufferGL3.cs @@ -58,10 +58,17 @@ namespace ANX.Framework.Windows.GL3 public class IndexBufferGL3 : INativeBuffer { #region Private + private int bufferHandle; /// /// Native index buffer handle. /// - private int bufferHandle; + internal int BufferHandle + { + get + { + return bufferHandle; + } + } private int indexCount; @@ -166,5 +173,5 @@ namespace ANX.Framework.Windows.GL3 GL.DeleteBuffers(1, ref bufferHandle); } #endregion - } + } } diff --git a/RenderSystems/ANX.Framework.Windows.GL3/ShaderByteCode.cs b/RenderSystems/ANX.Framework.Windows.GL3/ShaderByteCode.cs index 777dfa8f..83787181 100644 --- a/RenderSystems/ANX.Framework.Windows.GL3/ShaderByteCode.cs +++ b/RenderSystems/ANX.Framework.Windows.GL3/ShaderByteCode.cs @@ -54,25 +54,32 @@ namespace ANX.Framework.Windows.GL3 #region SpriteBatchShader internal static byte[] SpriteBatchByteCode = new byte[] { - 153, - 002, 117, 110, 105, 102, 111, 114, 109, 032, 109, 097, 116, 052, 032, 077, 097, 116, 114, 105, 120, - 084, 114, 097, 110, 115, 102, 111, 114, 109, 059, 010, 118, 111, 105, 100, 032, 109, 097, 105, 110, - 040, 118, 111, 105, 100, 041, 123, 010, 103, 108, 095, 080, 111, 115, 105, 116, 105, 111, 110, 061, - 103, 108, 095, 077, 111, 100, 101, 108, 086, 105, 101, 119, 080, 114, 111, 106, 101, 099, 116, 105, - 111, 110, 077, 097, 116, 114, 105, 120, 042, 103, 108, 095, 086, 101, 114, 116, 101, 120, 059, 010, - 103, 108, 095, 084, 101, 120, 067, 111, 111, 114, 100, 091, 048, 093, 061, 103, 108, 095, 077, 117, - 108, 116, 105, 084, 101, 120, 067, 111, 111, 114, 100, 048, 059, 010, 103, 108, 095, 070, 114, 111, - 110, 116, 067, 111, 108, 111, 114, 061, 103, 108, 095, 067, 111, 108, 111, 114, 059, 125, 010, 035, - 035, 033, 102, 114, 097, 103, 109, 101, 110, 116, 033, 035, 035, 010, 117, 110, 105, 102, 111, 114, - 109, 032, 115, 097, 109, 112, 108, 101, 114, 050, 068, 032, 084, 101, 120, 116, 117, 114, 101, 059, - 010, 118, 111, 105, 100, 032, 109, 097, 105, 110, 040, 118, 111, 105, 100, 041, 123, 010, 103, 108, - 095, 070, 114, 097, 103, 067, 111, 108, 111, 114, 061, 116, 101, 120, 116, 117, 114, 101, 050, 068, - 040, 084, 101, 120, 116, 117, 114, 101, 044, 118, 101, 099, 050, 040, 103, 108, 095, 084, 101, 120, - 067, 111, 111, 114, 100, 091, 048, 093, 041, 041, 042, 103, 108, 095, 067, 111, 108, 111, 114, 059, - 125, 010, 158, 137, 116, 152, 114, 087, 034, 194, 190, 191, 004, 241, 045, 226, 015, 222, 146, 050, - 005, 201, 127, 023, 220, 186, 170, 186, 147, 127, 228, 201, 229, 208, 024, 188, 126, 121, 005, 218, - 091, 005, 195, 101, 015, 122, 021, 003, 169, 237, 192, 224, 104, 229, 065, 240, 081, 150, 216, 205, - 237, 050, 203, 242, 163, 253 + 160, + 003, 117, 110, 105, 102, 111, 114, 109, 032, 109, 097, 116, 052, 032, 077, 097, 116, 114, 105, 120, + 084, 114, 097, 110, 115, 102, 111, 114, 109, 059, 010, 097, 116, 116, 114, 105, 098, 117, 116, 101, + 032, 118, 101, 099, 052, 032, 112, 111, 115, 059, 010, 097, 116, 116, 114, 105, 098, 117, 116, 101, + 032, 118, 101, 099, 052, 032, 099, 111, 108, 059, 010, 097, 116, 116, 114, 105, 098, 117, 116, 101, + 032, 118, 101, 099, 050, 032, 116, 101, 120, 059, 010, 118, 097, 114, 121, 105, 110, 103, 032, 118, + 101, 099, 052, 032, 100, 105, 102, 102, 117, 115, 101, 067, 111, 108, 111, 114, 059, 010, 118, 097, + 114, 121, 105, 110, 103, 032, 118, 101, 099, 050, 032, 100, 105, 102, 102, 117, 115, 101, 084, 101, + 120, 067, 111, 111, 114, 100, 059, 010, 118, 111, 105, 100, 032, 109, 097, 105, 110, 040, 118, 111, + 105, 100, 041, 123, 010, 103, 108, 095, 080, 111, 115, 105, 116, 105, 111, 110, 061, 077, 097, 116, + 114, 105, 120, 084, 114, 097, 110, 115, 102, 111, 114, 109, 042, 112, 111, 115, 059, 010, 100, 105, + 102, 102, 117, 115, 101, 084, 101, 120, 067, 111, 111, 114, 100, 061, 116, 101, 120, 059, 010, 100, + 105, 102, 102, 117, 115, 101, 067, 111, 108, 111, 114, 061, 099, 111, 108, 059, 125, 010, 035, 035, + 033, 102, 114, 097, 103, 109, 101, 110, 116, 033, 035, 035, 010, 117, 110, 105, 102, 111, 114, 109, + 032, 115, 097, 109, 112, 108, 101, 114, 050, 068, 032, 084, 101, 120, 116, 117, 114, 101, 059, 010, + 118, 097, 114, 121, 105, 110, 103, 032, 118, 101, 099, 052, 032, 100, 105, 102, 102, 117, 115, 101, + 067, 111, 108, 111, 114, 059, 010, 118, 097, 114, 121, 105, 110, 103, 032, 118, 101, 099, 050, 032, + 100, 105, 102, 102, 117, 115, 101, 084, 101, 120, 067, 111, 111, 114, 100, 059, 010, 118, 111, 105, + 100, 032, 109, 097, 105, 110, 040, 118, 111, 105, 100, 041, 123, 010, 103, 108, 095, 070, 114, 097, + 103, 067, 111, 108, 111, 114, 061, 116, 101, 120, 116, 117, 114, 101, 050, 068, 040, 084, 101, 120, + 116, 117, 114, 101, 044, 100, 105, 102, 102, 117, 115, 101, 084, 101, 120, 067, 111, 111, 114, 100, + 041, 042, 100, 105, 102, 102, 117, 115, 101, 067, 111, 108, 111, 114, 059, 125, 010, 095, 046, 094, + 078, 240, 054, 006, 106, 005, 190, 104, 250, 201, 129, 166, 050, 199, 249, 189, 159, 008, 207, 084, + 062, 171, 010, 076, 101, 119, 047, 079, 245, 134, 024, 149, 110, 166, 213, 153, 023, 179, 120, 191, + 146, 106, 047, 180, 084, 037, 088, 036, 132, 126, 030, 027, 054, 044, 236, 120, 086, 102, 211, 178, + 125 }; #endregion //SpriteBatchShader diff --git a/RenderSystems/ANX.Framework.Windows.GL3/VertexBufferGL3.cs b/RenderSystems/ANX.Framework.Windows.GL3/VertexBufferGL3.cs index 43168167..f4062b78 100644 --- a/RenderSystems/ANX.Framework.Windows.GL3/VertexBufferGL3.cs +++ b/RenderSystems/ANX.Framework.Windows.GL3/VertexBufferGL3.cs @@ -55,7 +55,8 @@ namespace ANX.Framework.Windows.GL3 /// /// Native OpenGL implementation of a Vertex Buffer. /// - /// Information about vbo/ibo: http://playcontrol.net/ewing/jibberjabber/opengl_vertex_buffer_object.html + /// Great tutorial about VBO/IBO directly for OpenTK: + /// http://www.opentk.com/doc/graphics/geometry/vertex-buffer-objects /// public class VertexBufferGL3 : INativeBuffer { @@ -64,6 +65,13 @@ namespace ANX.Framework.Windows.GL3 /// Native vertex buffer handle. /// private int bufferHandle; + internal int BufferHandle + { + get + { + return bufferHandle; + } + } private VertexDeclaration vertexDeclaration; @@ -92,6 +100,7 @@ namespace ANX.Framework.Windows.GL3 usageHint = BufferUsageHint.DynamicDraw; GL.GenBuffers(1, out bufferHandle); + GL.BindBuffer(BufferTarget.ArrayBuffer, bufferHandle); IntPtr size = (IntPtr)(vertexDeclaration.VertexStride * setVertexCount); GL.BufferData(BufferTarget.ArrayBuffer, size, IntPtr.Zero, usageHint); } @@ -148,8 +157,42 @@ namespace ANX.Framework.Windows.GL3 GL.BindBuffer(BufferTarget.ArrayBuffer, bufferHandle); - // TODO: check the different handling with MapBuffer etc. (See link above) - //GL.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr)offset, size, data); + // TODO: check the handling with MapBuffer etc. (See link above) + + MapVertexDeclaration(); + + GL.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr)offset, size, data); + } + #endregion + + #region MapVertexDeclaration + private void MapVertexDeclaration() + { + foreach (VertexElement element in vertexDeclaration.GetVertexElements()) + { + int size; + VertexPointerType type = + DatatypesMapping.VertexElementFormatToVertexPointerType( + element.VertexElementFormat, out size); + + switch (element.VertexElementUsage) + { + case VertexElementUsage.Position: + GL.EnableClientState(ArrayCap.VertexArray); + break; + // case VertexElementUsage.Color: + //GL.EnableClientState(ArrayCap.ColorArray); + // break; + // case VertexElementUsage.TextureCoordinate: + //GL.EnableClientState(ArrayCap.TextureCoordArray); + // break; + // TODO more + } + + // TODO: usage index? + GL.VertexPointer(size, type, vertexDeclaration.VertexStride, + element.Offset); + } } #endregion diff --git a/shader/GL3/SpriteBatch_GLSL.fx b/shader/GL3/SpriteBatch_GLSL.fx index dcbb6b7b..727d1e9f 100644 --- a/shader/GL3/SpriteBatch_GLSL.fx +++ b/shader/GL3/SpriteBatch_GLSL.fx @@ -46,11 +46,17 @@ // uniform mat4 MatrixTransform; +attribute vec4 pos; +attribute vec4 col; +attribute vec2 tex; + +varying vec4 diffuseColor; +varying vec2 diffuseTexCoord; void main(void) { - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; - gl_TexCoord[0] = gl_MultiTexCoord0; - gl_FrontColor = gl_Color; + gl_Position = MatrixTransform * pos; + diffuseTexCoord = tex; + diffuseColor = col; } ##!fragment!## @@ -60,7 +66,10 @@ void main(void) // uniform sampler2D Texture; +varying vec4 diffuseColor; +varying vec2 diffuseTexCoord; + void main(void) { - gl_FragColor = texture2D(Texture, vec2(gl_TexCoord[0])) * gl_Color; + gl_FragColor = texture2D(Texture, diffuseTexCoord) * diffuseColor; } \ No newline at end of file