3 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGL
5 using System.Collections.Generic;
6 using SiliconStudio.Core.Collections;
7 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
8 using OpenTK.Graphics.ES30;
10 using OpenTK.Graphics.OpenGL;
13 namespace SiliconStudio.
Paradox.Graphics
15 internal class VertexArrayObjectInstance : IDisposable
17 private readonly VertexAttrib[] vertexAttribs;
19 private readonly Dictionary<string, int> programAttributes;
21 private readonly uint enabledVertexAttribArrays;
23 private bool hasDynamicStagingVB;
27 private readonly GraphicsDevice graphicsDevice;
29 private readonly
int indexBufferId;
31 public VertexArrayObjectInstance(GraphicsDevice graphicsDevice, EffectInputSignature effectInputSignature, VertexAttrib[] sharedVertexAttribs,
int indexBufferId)
33 this.graphicsDevice = graphicsDevice;
34 this.indexBufferId = indexBufferId;
35 programAttributes = effectInputSignature.Attributes;
37 int vertexAttributeCount = 0;
38 for (
int i = 0; i < sharedVertexAttribs.Length; i++)
40 if (programAttributes.ContainsKey(sharedVertexAttribs[i].AttributeName))
42 vertexAttributeCount++;
46 vertexAttribs =
new VertexAttrib[vertexAttributeCount];
49 for (
int i = 0; i < sharedVertexAttribs.Length; i++)
51 AddAttribute(ref j, ref sharedVertexAttribs[i], ref enabledVertexAttribArrays);
59 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
60 if (graphicsDevice.HasVAO)
61 OpenTK.Graphics.ES20.GL.Oes.DeleteVertexArrays(1, ref vaoId);
63 GL.DeleteVertexArrays(1, ref vaoId);
69 private void AddAttribute(ref
int index, ref VertexAttrib attrib, ref uint enabledVertexAttribArrays)
72 if (programAttributes.TryGetValue(attrib.AttributeName, out attribIndex))
74 vertexAttribs[index] = attrib;
75 vertexAttribs[index].Index = attribIndex;
77 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
78 hasDynamicStagingVB |= attrib.VertexBufferId == 0;
81 if (attribIndex != -1)
82 enabledVertexAttribArrays |= 1
U << attribIndex;
91 internal void Apply(GraphicsDevice graphicsDevice)
93 if (graphicsDevice.HasVAO)
95 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
96 if (hasDynamicStagingVB)
98 OpenTK.Graphics.ES20.GL.Oes.BindVertexArray(0);
99 ApplyAttributes(ref graphicsDevice.enabledVertexAttribArrays);
105 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
106 OpenTK.Graphics.ES20.GL.Oes.GenVertexArrays(1, out vaoId);
107 OpenTK.Graphics.ES20.GL.Oes.BindVertexArray(vaoId);
109 GL.GenVertexArrays(1, out vaoId);
110 GL.BindVertexArray(vaoId);
114 uint currentlyEnabledVertexAttribArrays = 0;
115 ApplyAttributes(ref currentlyEnabledVertexAttribArrays);
119 #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
120 OpenTK.Graphics.ES20.GL.Oes.BindVertexArray(vaoId);
122 GL.BindVertexArray(vaoId);
125 #if SILICONSTUDIO_PLATFORM_ANDROID
131 if (graphicsDevice.Workaround_VAO_PowerVR_SGX_540)
134 var vertexAttribsToReenable = enabledVertexAttribArrays;
136 int currentVertexAttribIndex = 0;
137 while (vertexAttribsToReenable != 0)
139 if ((vertexAttribsToReenable & 1) == 1)
141 GL.DisableVertexAttribArray(currentVertexAttribIndex);
142 GL.EnableVertexAttribArray(currentVertexAttribIndex);
145 currentVertexAttribIndex++;
146 vertexAttribsToReenable >>= 1;
154 ApplyAttributes(ref graphicsDevice.enabledVertexAttribArrays);
158 private void ApplyAttributes(ref uint currentlyEnabledVertexAttribArrays)
160 GL.BindBuffer(BufferTarget.ElementArrayBuffer, indexBufferId);
163 var vertexAttribsToDisable = currentlyEnabledVertexAttribArrays & ~enabledVertexAttribArrays;
165 int currentVertexAttribIndex = 0;
166 while (vertexAttribsToDisable != 0)
168 if ((vertexAttribsToDisable & 1) == 1)
170 GL.DisableVertexAttribArray(currentVertexAttribIndex);
173 currentVertexAttribIndex++;
174 vertexAttribsToDisable >>= 1;
177 int vertexBuffer = -1;
179 foreach (var vertexAttrib
in vertexAttribs)
181 if (vertexAttrib.VertexBufferId != vertexBuffer)
183 GL.BindBuffer(BufferTarget.ArrayBuffer, vertexAttrib.VertexBufferId);
184 vertexBuffer = vertexAttrib.VertexBufferId;
186 var vertexAttribMask = 1
U << vertexAttrib.Index;
187 if ((currentlyEnabledVertexAttribArrays & vertexAttribMask) == 0)
189 GL.EnableVertexAttribArray(vertexAttrib.Index);
192 #if !SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
193 if (vertexAttrib.IsInteger && !vertexAttrib.Normalized)
194 GL.VertexAttribIPointer(vertexAttrib.Index, vertexAttrib.Size, (VertexAttribIPointerType)vertexAttrib.Type, vertexAttrib.Stride, vertexAttrib.Offset);
197 GL.VertexAttribPointer(vertexAttrib.Index, vertexAttrib.Size, vertexAttrib.Type, vertexAttrib.Normalized, vertexAttrib.Stride, vertexAttrib.Offset);
200 currentlyEnabledVertexAttribArrays = enabledVertexAttribArrays;