/// <summary> /// Wraps glDrawElements(uint mode, int count, uint type, IntPtr indices). /// </summary> /// <param name="bufferId">用glGenBuffers()得到的VBO的Id。<para>Id got from glGenBuffers();</para></param> /// <param name="mode">用哪种方式渲染各个顶点?(OpenGL.GL_TRIANGLES etc.)</param> /// <param name="type">type in glDrawElements(uint mode, int count, uint type, IntPtr indices); /// <para>表示第3个参数,表示索引元素的类型。</para></param> /// <param name="length">此VBO含有多个个元素?<para>How many elements?</para></param> /// <param name="byteLength">此VBO中的数据在内存中占用多少个字节?<para>How many bytes in this buffer?</para></param> /// <param name="primCount">primCount in instanced rendering.</param> internal OneIndexBufferPtr(uint bufferId, DrawMode mode, IndexElementType type, int length, int byteLength, int primCount = 1) : base(mode, bufferId, length, byteLength, primCount) { if (glDrawElementsInstanced == null) { glDrawElementsInstanced = OpenGL.GetDelegateFor <OpenGL.glDrawElementsInstanced>(); } this.ElementCount = length; this.Type = type; }
/// <summary> /// /// </summary> public override void Render() { int primCount = this.PrimCount; if (primCount < 1) { throw new Exception("error: primCount is less than 1."); } uint mode = (uint)this.Mode; IntPtr offset; switch (this.ElementType) { case IndexBufferElementType.UByte: offset = new IntPtr(this.FirstIndex * sizeof(byte)); break; case IndexBufferElementType.UShort: offset = new IntPtr(this.FirstIndex * sizeof(ushort)); break; case IndexBufferElementType.UInt: offset = new IntPtr(this.FirstIndex * sizeof(uint)); break; default: throw new NotImplementedException(); } if (glBindBuffer == null) { glBindBuffer = OpenGL.GetDelegateFor <OpenGL.glBindBuffer>(); } glBindBuffer(OpenGL.GL_ELEMENT_ARRAY_BUFFER, this.BufferId); if (primCount == 1) { OpenGL.DrawElements(mode, this.ElementCount, (uint)this.ElementType, offset); } else { if (glDrawElementsInstanced == null) { glDrawElementsInstanced = OpenGL.GetDelegateFor <OpenGL.glDrawElementsInstanced>(); } glDrawElementsInstanced(mode, this.ElementCount, (uint)this.ElementType, offset, primCount); } glBindBuffer(OpenGL.GL_ELEMENT_ARRAY_BUFFER, 0); }
/// <summary> /// /// </summary> /// <param name="arg"></param> public override void Render(RenderEventArgs arg) { int primCount = this.PrimCount; if (primCount < 1) { throw new Exception("error: primCount is less than 1."); } uint mode = 0; IntPtr offset; if (arg.PickingGeometryType == PickingGeometryType.Point && this.Mode.ToGeometryType() == PickingGeometryType.Line) // picking point from a line { // this may render points that should not appear. // so need to select by another picking. mode = (uint)DrawMode.Points; } else { mode = (uint)this.Mode; } switch (this.ElementType) { case IndexBufferElementType.UByte: offset = new IntPtr(this.FirstIndex * sizeof(byte)); break; case IndexBufferElementType.UShort: offset = new IntPtr(this.FirstIndex * sizeof(ushort)); break; case IndexBufferElementType.UInt: offset = new IntPtr(this.FirstIndex * sizeof(uint)); break; default: throw new NotImplementedException(); } if (glBindBuffer == null) { glBindBuffer = OpenGL.GetDelegateFor <OpenGL.glBindBuffer>(); } glBindBuffer(OpenGL.GL_ELEMENT_ARRAY_BUFFER, this.BufferId); if (primCount == 1) { OpenGL.DrawElements(mode, this.ElementCount, (uint)this.ElementType, offset); } else { if (glDrawElementsInstanced == null) { glDrawElementsInstanced = OpenGL.GetDelegateFor <OpenGL.glDrawElementsInstanced>(); } glDrawElementsInstanced(mode, this.ElementCount, (uint)this.ElementType, offset, primCount); } glBindBuffer(OpenGL.GL_ELEMENT_ARRAY_BUFFER, 0); }