/// <summary> /// /// </summary> /// <returns></returns> public IndexBuffer GetIndexBuffer() { if (this.indexBuffer == null) { ZeroIndexBuffer buffer = ZeroIndexBuffer.Create(DrawMode.Lines, 0, this.markerCount * 2); this.indexBuffer = buffer; } return this.indexBuffer; }
/// <summary> /// /// </summary> /// <returns></returns> public IndexBuffer GetIndexBuffer() { if (this.indexBuffer == null) { ZeroIndexBuffer buffer = ZeroIndexBuffer.Create(this.Mode, this.FirstVertex, this.VertexCount, this.PrimCount); this.indexBuffer = buffer; } return this.indexBuffer; }
/// <summary> /// /// </summary> /// <returns></returns> public IndexBuffer GetIndexBuffer() { if (this.indexBuffer == null) { ZeroIndexBuffer buffer = ZeroIndexBuffer.Create(DrawMode.QuadStrip, 0, (this.quadCount + 1) * 2); this.indexBuffer = buffer; } return this.indexBuffer; }
/// <summary> /// /// </summary> /// <returns></returns> public IndexBuffer GetIndexBuffer() { if (this.indexBuffer == null) { int vertexCount = positions.Length; ZeroIndexBuffer buffer = ZeroIndexBuffer.Create(DrawMode.Lines, 0, vertexCount); this.indexBuffer = buffer; } return this.indexBuffer; }
/// <summary> /// /// </summary> /// <returns></returns> public IndexBuffer GetIndexBuffer() { if (indexBuffer == null) { ZeroIndexBuffer buffer = ZeroIndexBuffer.Create(DrawMode.LineStrip, 0, BigDipperModel.positions.Length); this.indexBuffer = buffer; } return indexBuffer; }
/// <summary> /// /// </summary> /// <returns></returns> public IndexBuffer GetIndexBuffer() { if (this.indexBuffer == null) { int vertexCount = this.model.positions.Length; ZeroIndexBuffer buffer = ZeroIndexBuffer.Create(this.model.GetDrawModel(), 0, vertexCount); this.indexBuffer = buffer; } return this.indexBuffer; }
/// <summary> /// VAO是用来管理VBO的。可以进一步减少DrawCall。 /// <para>VAO is used to reduce draw-call.</para> /// </summary> /// <param name="indexBuffer">index buffer pointer that used to invoke draw command.</param> /// <param name="vertexAttributeBuffers">给出此VAO要管理的所有VBO。<para>All VBOs that are managed by this VAO.</para></param> public VertexArrayObject(IndexBuffer indexBuffer, params VertexBuffer[] vertexAttributeBuffers) { if (indexBuffer == null) { throw new ArgumentNullException("indexBuffer"); } // Zero vertex attribute is allowed in GLSL. //if (vertexAttributeBuffers == null || vertexAttributeBuffers.Length == 0) //{ // throw new ArgumentNullException("vertexAttributeBuffers"); //} this.IndexBuffer = indexBuffer; this.VertexAttributeBuffers = vertexAttributeBuffers; }
/// <summary> /// /// </summary> /// <returns></returns> public IndexBuffer GetIndexBuffer() { if (this.indexBuffer == null) { int length = TetrahedronModel.index.Length; OneIndexBuffer buffer = Buffer.Create(IndexBufferElementType.UByte, length, DrawMode.Triangles, BufferUsage.StaticDraw); unsafe { IntPtr pointer = buffer.MapBuffer(MapBufferAccess.WriteOnly); var array = (byte*)pointer; for (int i = 0; i < TetrahedronModel.index.Length; i++) { array[i] = TetrahedronModel.index[i]; } buffer.UnmapBuffer(); } this.indexBuffer = buffer; } return this.indexBuffer; }
public override IndexBuffer GetIndexBuffer() { if (this.indexBuffer == null) { int dimSize = this.DataSource.DimenSize; int length = dimSize * 2 * (Marshal.SizeOf(typeof(HalfHexahedronIndex)) / sizeof(uint)); OneIndexBuffer buffer = CSharpGL.Buffer.Create(IndexBufferElementType.UInt, length, DrawMode.QuadStrip, BufferUsage.StaticDraw); unsafe { IntPtr pointer = buffer.MapBuffer(MapBufferAccess.WriteOnly); var array = (HalfHexahedronIndex*)pointer; for (int gridIndex = 0; gridIndex < dimSize; gridIndex++) { array[gridIndex * 2].dot0 = (uint)(8 * gridIndex + 6); array[gridIndex * 2].dot1 = (uint)(8 * gridIndex + 2); array[gridIndex * 2].dot2 = (uint)(8 * gridIndex + 7); array[gridIndex * 2].dot3 = (uint)(8 * gridIndex + 3); array[gridIndex * 2].dot4 = (uint)(8 * gridIndex + 4); array[gridIndex * 2].dot5 = (uint)(8 * gridIndex + 0); array[gridIndex * 2].dot6 = (uint)(8 * gridIndex + 5); array[gridIndex * 2].dot7 = (uint)(8 * gridIndex + 1); array[gridIndex * 2].restartIndex = uint.MaxValue; array[gridIndex * 2 + 1].dot0 = (uint)(8 * gridIndex + 3); array[gridIndex * 2 + 1].dot1 = (uint)(8 * gridIndex + 0); array[gridIndex * 2 + 1].dot2 = (uint)(8 * gridIndex + 2); array[gridIndex * 2 + 1].dot3 = (uint)(8 * gridIndex + 1); array[gridIndex * 2 + 1].dot4 = (uint)(8 * gridIndex + 6); array[gridIndex * 2 + 1].dot5 = (uint)(8 * gridIndex + 5); array[gridIndex * 2 + 1].dot6 = (uint)(8 * gridIndex + 7); array[gridIndex * 2 + 1].dot7 = (uint)(8 * gridIndex + 4); array[gridIndex * 2 + 1].restartIndex = uint.MaxValue; } buffer.UnmapBuffer(); } this.indexBuffer = buffer; } return this.indexBuffer; }
/// <summary> /// /// </summary> /// <returns></returns> public IndexBuffer GetIndexBuffer() { if (indexBuffer == null) { ushort[] faces = model.GetFaces(); int length = faces.Length; OneIndexBuffer buffer = Buffer.Create(IndexBufferElementType.UShort, length, DrawMode.Triangles, BufferUsage.StaticDraw); unsafe { IntPtr pointer = buffer.MapBuffer(MapBufferAccess.WriteOnly); var array = (ushort*)pointer; for (int i = 0; i < faces.Length; i++) { array[i] = (ushort)(faces[i] - 1); } buffer.UnmapBuffer(); } this.indexBuffer = buffer; } return indexBuffer; }
/// <summary> /// /// </summary> /// <returns></returns> public IndexBuffer GetIndexBuffer() { if (this.indexBuffer == null) { this.indexBuffer = this.model.indexes.GenIndexBuffer(this.model.mode, BufferUsage.StaticDraw); // another way to do this: //OneIndexBuffer buffer = Buffer.Create(IndexElementType.UInt, this.model.indexes.Length, this.model.mode, BufferUsage.StaticDraw); //unsafe //{ // IntPtr pointer = buffer.MapBuffer(MapBufferAccess.WriteOnly); // var array = (uint*)pointer.ToPointer(); // for (int i = 0; i < this.model.indexes.Length; i++) // { // array[i] = this.model.indexes[i]; // } // buffer.UnmapBuffer(); //} //this.indexBuffer = buffer; } return this.indexBuffer; }
/// <summary> /// render with specified index buffer. /// </summary> /// <param name="arg"></param> /// <param name="temporaryIndexBuffer"></param> private void Render4Picking(RenderEventArgs arg, IndexBuffer temporaryIndexBuffer) { UpdatePolygonMode(arg.PickingGeometryType); ShaderProgram program = this.Program; // 绑定shader program.Bind(); program.SetUniform("pickingBaseId", 0); UniformMat4 uniformmMVP4Picking = this.uniformmMVP4Picking; { mat4 projection = arg.Camera.GetProjectionMatrix(); mat4 view = arg.Camera.GetViewMatrix(); mat4 model = this.GetModelMatrix().Value; uniformmMVP4Picking.Value = projection * view * model; } uniformmMVP4Picking.SetUniform(program); PickingStateesOn(); var oneIndexBuffer = temporaryIndexBuffer as OneIndexBuffer; if (oneIndexBuffer != null) { PrimitiveRestartState glState = this.GetPrimitiveRestartState(oneIndexBuffer); glState.On(); this.vertexArrayObject.Render(arg, program, temporaryIndexBuffer); glState.Off(); } else { this.vertexArrayObject.Render(arg, program, temporaryIndexBuffer); } PickingStateesOff(); //if (mvpUpdated) { uniformmMVP4Picking.ResetUniform(program); } // 解绑shader program.Unbind(); }
/// <summary> /// /// </summary> /// <returns></returns> public IndexBuffer GetIndexBuffer() { if (this.indexBuffer == null) { //int length = CubeModel.index.Length; //OneIndexBuffer buffer = Buffer.Create(IndexElementType.UByte, length, DrawMode.Triangles, BufferUsage.StaticDraw); //unsafe //{ // IntPtr pointer = buffer.MapBuffer(MapBufferAccess.WriteOnly); // var array = (byte*)pointer; // for (int i = 0; i < CubeModel.index.Length; i++) // { // array[i] = CubeModel.index[i]; // } // buffer.UnmapBuffer(); //} //this.indexBuffer = buffer; // another way to do this: this.indexBuffer = CubeModel.index.GenIndexBuffer(DrawMode.Triangles, BufferUsage.StaticDraw); } return this.indexBuffer; }
public unsafe IndexBuffer GetIndexBuffer() { if (this.indexBuffer != null) { return this.indexBuffer; } int vertexCount = (faceCount * 2 + 2) * (this.pipeline.Count - 1); int length = vertexCount + (this.pipeline.Count - 1); OneIndexBuffer buffer = CSharpGL.Buffer.Create(IndexBufferElementType.UInt, length, DrawMode.QuadStrip, BufferUsage.StaticDraw); unsafe { IntPtr pointer = buffer.MapBuffer(MapBufferAccess.WriteOnly); var array = (uint*)pointer.ToPointer(); uint positionIndex = 0; for (int i = 0; i < buffer.Length; i++) { if (i % (faceCount * 2 + 2 + 1) == (faceCount * 2 + 2)) { array[i] = uint.MaxValue;//分割各个圆柱体 } else { array[i] = positionIndex++; } } this.indexBuffer = buffer; } return this.indexBuffer; }
/// <summary> /// 在此Buffer中的图元进行N选1 /// select a primitive geometry(point, line, triangle, quad, polygon) from points/lines/triangles/quads/polygons in this renderer. /// </summary> /// <param name="arg"></param> /// <param name="indexBuffer">indicates the primitive to pick a line from.</param> internal void Render4InnerPicking(RenderEventArgs arg, IndexBuffer indexBuffer) { arg.UsingViewPort.On(); // record clear color var originalClearColor = new float[4]; OpenGL.GetFloat(GetTarget.ColorClearValue, originalClearColor); // 白色意味着没有拾取到任何对象 // white color: nothing picked. OpenGL.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); OpenGL.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT | OpenGL.GL_STENCIL_BUFFER_BIT); // restore clear color OpenGL.glClearColor(originalClearColor[0], originalClearColor[1], originalClearColor[2], originalClearColor[3]); this.Render4Picking(arg, indexBuffer); OpenGL.Flush(); arg.UsingViewPort.Off(); //var filename = string.Format("Render4InnerPicking{0:yyyy-MM-dd_HH-mm-ss.ff}.png", DateTime.Now); //Save2PictureHelper.Save2Picture(0, 0, // e.CanvasRect.Width, e.CanvasRect.Height, filename); }
/// <summary> /// /// </summary> /// <returns></returns> public override string ToString() { int primCount = this.InstanceCount; if (primCount < 1) { return(string.Format("error: primCount is less than 1.")); } int frameCount = this.FrameCount; if (frameCount < 1) { return(string.Format("error: frameCount is less than 1.")); } var mode = this.Mode; IndexBuffer indexBuffer = this.indexBuffer; int vertexCount = indexBuffer.Length; IndexBufferElementType elementType = indexBuffer.ElementType; IntPtr offset = GetOffset(elementType, this.FirstVertex); var builder = new System.Text.StringBuilder(); builder.AppendLine("ControlMode.ByFrame:"); if (primCount == 1) { if (frameCount == 1) { builder.AppendLine(string.Format("glDrawElements(mode: {0}, vertexCount: {1}, type: {2}, offset: {3});", mode, vertexCount, elementType, offset)); } else { builder.AppendLine(string.Format("glDrawElementsBaseVertex(mode: {0}, vertexCount: {1}, type: {2}, offset: {3}, baseVertex = currentFrame * vertexCount: {4} = {5} * {6});", mode, vertexCount, elementType, offset, this.CurrentFrame * vertexCount, this.CurrentFrame, vertexCount)); } } else { if (frameCount == 1) { builder.AppendLine(string.Format("glDrawElementsInstanced(mode: {0}, vertexCount: {1}, type: {2}, offset: {3}, primCount: {4});", mode, vertexCount, elementType, offset, primCount)); } else { builder.AppendLine(string.Format("glDrawElementsInstancedBaseVertex(mode: {0}, vertexCount: {1}, type: {2}, offset: {3}, primCount: {4}, baseVertex = currentFrame * vertexCount: {5} = {6} * {7});", mode, vertexCount, elementType, offset, primCount, this.CurrentFrame * vertexCount, this.CurrentFrame, vertexCount)); } } builder.AppendLine("ControlMode.Random:"); if (primCount == 1) { if (frameCount == 1) { builder.AppendLine(string.Format("glDrawElements(mode: {0}, vertexCount: {1}, type: {2}, offset: {3});", mode, this.RenderingVertexCount, elementType, offset)); } else { builder.AppendLine(string.Format("glDrawElementsBaseVertex(mode: {0}, vertexCount: {1}, type: {2}, offset: {3}, baseVertex = currentFrame * vertexCount: {4} = {5} * {6});", mode, this.RenderingVertexCount, elementType, offset, this.CurrentFrame * vertexCount, this.CurrentFrame, vertexCount)); } } else { if (frameCount == 1) { builder.AppendLine(string.Format("glDrawElementsInstanced(mode: {0}, vertexCount: {1}, type: {2}, offset: {3}, primCount: {4});", mode, this.RenderingVertexCount, elementType, offset, primCount)); } else { builder.AppendLine(string.Format("glDrawElementsInstancedBaseVertex(mode: {0}, vertexCount: {1}, type: {2}, offset: {3}, primCount: {4}, baseVertex = currentFrame * vertexCount: {5} = {6} * {7});", mode, this.RenderingVertexCount, elementType, offset, primCount, this.CurrentFrame * vertexCount, this.CurrentFrame, vertexCount)); } } return(builder.ToString()); }
/// <summary> /// /// </summary> protected override void DoInitialize() { // init shader program. ShaderProgram program = this.renderProgramProvider.GetShaderProgram(); ShaderProgram pickProgram = this.pickProgramProvider.GetShaderProgram(); // init vertex attribute buffer objects. IBufferable model = this.DataSource; VertexBuffer positionBuffer = null; VertexShaderAttribute[] vertexAttributeBuffers; { var list = new List <VertexShaderAttribute>(); foreach (AttributeMap.NamePair item in this.attributeMap) { VertexBuffer buffer = model.GetVertexAttributeBuffer( item.NameInIBufferable, item.VarNameInShader); if (buffer == null) { throw new Exception(string.Format("[{0}] returns null buffer pointer!", model)); } list.Add(new VertexShaderAttribute(buffer, item.VarNameInShader)); if (item.VarNameInShader == this.PositionNameInVertexShader) { positionBuffer = buffer; } } vertexAttributeBuffers = list.ToArray(); } // 由于picking.vert/frag只支持vec3的position buffer,所以有此硬性规定。 if (positionBuffer == null || positionBuffer.Config != VBOConfig.Vec3) { throw new Exception(string.Format("Position buffer must use a type composed of 3 float as PropertyBuffer<T>'s T!")); } // init index buffer. IndexBuffer indexBuffer = model.GetIndexBuffer(); // RULE: Renderer takes uint.MaxValue, ushort.MaxValue or byte.MaxValue as PrimitiveRestartIndex. So take care this rule when designing a model's index buffer. var ptr = indexBuffer as OneIndexBuffer; if (ptr != null) { GLState glState = new PrimitiveRestartState(ptr.ElementType); this.stateList.Add(glState); this.picker = new OneIndexPicker(this); } else { this.picker = new ZeroIndexPicker(this); } // init VAO. var vertexArrayObject = new VertexArrayObject(indexBuffer, vertexAttributeBuffers); vertexArrayObject.Initialize(program); var pickingVAO = new VertexArrayObject(indexBuffer, new VertexShaderAttribute(positionBuffer, "in_Position")); pickingVAO.Initialize(pickProgram); // sets fields. this.RenderProgram = program; this.PickProgram = pickProgram; this.vertexShaderAttributes = vertexAttributeBuffers; this.positionBuffer = positionBuffer; this.indexBuffer = indexBuffer; this.vertexArrayObject = vertexArrayObject; this.pickVertexArrayObject = pickingVAO; }
/// <summary> /// /// </summary> /// <returns></returns> public IndexBuffer GetIndexBuffer() { if (this.indexBuffer == null) { int length = model.indexes.Length; if (model.positions.Length < byte.MaxValue) { OneIndexBuffer buffer = Buffer.Create(IndexBufferElementType.UByte, length, DrawMode.TriangleStrip, BufferUsage.StaticDraw); unsafe { IntPtr pointer = buffer.MapBuffer(MapBufferAccess.WriteOnly); var array = (byte*)pointer; for (int i = 0; i < model.indexes.Length; i++) { if (model.indexes[i] == uint.MaxValue) { array[i] = byte.MaxValue; } else { array[i] = (byte)model.indexes[i]; } } buffer.UnmapBuffer(); } this.indexBuffer = buffer; } else if (model.positions.Length < ushort.MaxValue) { OneIndexBuffer buffer = Buffer.Create(IndexBufferElementType.UShort, length, DrawMode.TriangleStrip, BufferUsage.StaticDraw); unsafe { IntPtr pointer = buffer.MapBuffer(MapBufferAccess.WriteOnly); var array = (ushort*)pointer; for (int i = 0; i < model.indexes.Length; i++) { if (model.indexes[i] == uint.MaxValue) { array[i] = ushort.MaxValue; } else { array[i] = (ushort)model.indexes[i]; } } buffer.UnmapBuffer(); } this.indexBuffer = buffer; } else { OneIndexBuffer buffer = Buffer.Create(IndexBufferElementType.UInt, length, DrawMode.TriangleStrip, BufferUsage.StaticDraw); unsafe { IntPtr pointer = buffer.MapBuffer(MapBufferAccess.WriteOnly); var array = (uint*)pointer; for (int i = 0; i < model.indexes.Length; i++) { array[i] = model.indexes[i]; } buffer.UnmapBuffer(); } this.indexBuffer = buffer; } } return indexBuffer; }
/// <summary> /// /// </summary> /// <returns></returns> public IndexBuffer GetIndexBuffer() { if (this.indexBuffer == null) { int length = model.indexes.Length; if (model.positions.Length < byte.MaxValue) { OneIndexBuffer buffer = GLBuffer.Create(IndexBufferElementType.UByte, length, DrawMode.TriangleStrip, BufferUsage.StaticDraw); unsafe { IntPtr pointer = buffer.MapBuffer(MapBufferAccess.WriteOnly); var array = (byte *)pointer; for (int i = 0; i < model.indexes.Length; i++) { if (model.indexes[i] == uint.MaxValue) { array[i] = byte.MaxValue; } else { array[i] = (byte)model.indexes[i]; } } buffer.UnmapBuffer(); } this.indexBuffer = buffer; } else if (model.positions.Length < ushort.MaxValue) { OneIndexBuffer buffer = GLBuffer.Create(IndexBufferElementType.UShort, length, DrawMode.TriangleStrip, BufferUsage.StaticDraw); unsafe { IntPtr pointer = buffer.MapBuffer(MapBufferAccess.WriteOnly); var array = (ushort *)pointer; for (int i = 0; i < model.indexes.Length; i++) { if (model.indexes[i] == uint.MaxValue) { array[i] = ushort.MaxValue; } else { array[i] = (ushort)model.indexes[i]; } } buffer.UnmapBuffer(); } this.indexBuffer = buffer; } else { OneIndexBuffer buffer = GLBuffer.Create(IndexBufferElementType.UInt, length, DrawMode.TriangleStrip, BufferUsage.StaticDraw); unsafe { IntPtr pointer = buffer.MapBuffer(MapBufferAccess.WriteOnly); var array = (uint *)pointer; for (int i = 0; i < model.indexes.Length; i++) { array[i] = model.indexes[i]; } buffer.UnmapBuffer(); } this.indexBuffer = buffer; } } return(indexBuffer); }
/// <summary> /// 执行一次渲染的过程。 /// <para>Execute rendering command.</para> /// </summary> /// <param name="arg"></param> /// <param name="shaderProgram"></param> /// <param name="temporaryIndexBuffer">render by a temporary index buffer</param> public void Render(RenderEventArgs arg, ShaderProgram shaderProgram, IndexBuffer temporaryIndexBuffer = null) { if (temporaryIndexBuffer != null) { this.Bind(); temporaryIndexBuffer.Render(arg); this.Unbind(); } else { this.Bind(); this.IndexBuffer.Render(arg); this.Unbind(); } }
//#endregion IHasIndexBuffer /// <summary> /// Wraps glDrawElementsInstanced(uint mode, int vertexCount, uint type, IntPtr offset, int primCount); /// </summary> /// <param name="indexBuffer"></param> /// <param name="mode"></param> /// <param name="instanceCount">primCount in instanced rendering.</param> /// <param name="primitiveRestartIndex">usually uint.MaxValue, ushort.MaxValue or byte.MaxValue. 0 means not need to use `glPrimitiveRestartIndex`.</param> public DrawElementsInstancedCmd(IndexBuffer indexBuffer, DrawMode mode, int instanceCount, uint primitiveRestartIndex = 0) : this(indexBuffer, mode, 0, indexBuffer.Length, instanceCount, primitiveRestartIndex) { }
//#endregion IHasIndexBuffer /// <summary> /// Wraps glDrawElements(uint mode, int count, uint type, IntPtr indices). /// </summary> /// <param name="indexBuffer"></param> /// <param name="mode"></param> /// <param name="primitiveRestartIndex">usually uint.MaxValue, ushort.MaxValue or byte.MaxValue. 0 means not need to use `glPrimitiveRestartIndex`.</param> public DrawElementsCmd(IndexBuffer indexBuffer, DrawMode mode, uint primitiveRestartIndex = 0) : this(indexBuffer, mode, 0, indexBuffer.Length, primitiveRestartIndex) { }
//#endregion IHasIndexBuffer /// <summary> /// Wraps glDrawElementsInstancedBaseVertex(uint mode, int vertexCount, uint type, IntPtr offset, int instanceCount, int baseVertex); /// </summary> /// <param name="indexBuffer"></param> /// <param name="mode"></param> /// <param name="frameVertexCount">How many vertexes to construct a frame?</param> /// <param name="instanceCount">primCount in instanced rendering.</param> /// <param name="primitiveRestartIndex">usually uint.MaxValue, ushort.MaxValue or byte.MaxValue. 0 means not need to use `glPrimitiveRestartIndex`.</param> public DrawElementsInstancedBaseVertexCmd(IndexBuffer indexBuffer, DrawMode mode, int frameVertexCount, int instanceCount, uint primitiveRestartIndex = 0) : this(indexBuffer, mode, frameVertexCount, 0, instanceCount, 0, primitiveRestartIndex) { }
/// <summary> /// /// </summary> /// <param name="controlMode">index buffer is accessable randomly or only by frame.</param> public void Draw(ControlMode controlMode) { int instanceCount = this.InstanceCount; if (instanceCount < 1) { throw new Exception("error: instanceCount is less than 1."); } int frameCount = this.FrameCount; if (frameCount < 1) { throw new Exception("error: frameCount is less than 1."); } uint mode = (uint)this.Mode; IndexBuffer indexBuffer = this.indexBuffer; int vertexCount = indexBuffer.Length; IndexBufferElementType elementType = indexBuffer.ElementType; IntPtr offset = GetOffset(elementType, this.FirstVertex); GLBuffer.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, indexBuffer.BufferId); switch (controlMode) { case ControlMode.ByFrame: if (instanceCount == 1) { if (frameCount == 1) { GL.Instance.DrawElements(mode, vertexCount, (uint)elementType, offset); } else { glDrawElementsBaseVertex(mode, vertexCount, (uint)elementType, offset, this.CurrentFrame * vertexCount); } } else { if (frameCount == 1) { glDrawElementsInstanced(mode, vertexCount, (uint)elementType, offset, instanceCount); } else { glDrawElementsInstancedBaseVertex(mode, vertexCount, (uint)elementType, offset, instanceCount, this.CurrentFrame * vertexCount); } } break; case ControlMode.Random: if (instanceCount == 1) { if (frameCount == 1) { GL.Instance.DrawElements(mode, this.RenderingVertexCount, (uint)elementType, offset); } else { glDrawElementsBaseVertex(mode, this.RenderingVertexCount, (uint)elementType, offset, this.CurrentFrame * vertexCount); } } else { if (frameCount == 1) { glDrawElementsInstanced(mode, this.RenderingVertexCount, (uint)elementType, offset, instanceCount); } else { glDrawElementsInstancedBaseVertex(mode, this.RenderingVertexCount, (uint)elementType, offset, instanceCount, this.CurrentFrame * vertexCount); } } break; default: throw new NotDealWithNewEnumItemException(typeof(ControlMode)); } GLBuffer.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0); }