/// <summary> /// /// </summary> public void Draw() { int instanceCount = this.InstanceCount; uint mode = (uint)this.CurrentMode; IndexBuffer indexBuffer = this.indexBuffer; int vertexCount = indexBuffer.Length; IndexBufferElementType elementType = indexBuffer.ElementType; IntPtr offset = GetOffset(elementType, this.FirstVertex); uint rs = this.PrimitiveRestartIndex; if (rs != 0) { GL.Instance.Enable(GL.GL_PRIMITIVE_RESTART); glPrimitiveRestartIndex(rs); } GLBuffer.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, indexBuffer.BufferId); glDrawElementsInstanced(mode, this.VertexCount, (uint)elementType, offset, instanceCount); GLBuffer.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0); if (rs != 0) { GL.Instance.Disable(GL.GL_PRIMITIVE_RESTART); } }
/// <summary> /// 设置要高亮显示的图元。 /// </summary> /// <param name="mode">要高亮显示的图元类型</param> /// <param name="indexes">要高亮显示的图元的索引。</param> public void SetHighlightIndexes(DrawMode mode, params uint[] indexes) { int indexesLength = indexes.Length; if (indexesLength > this.maxElementCount) { IndexBuffer original = this.indexBuffer; this.indexBuffer = GLBuffer.Create(IndexBufferElementType.UInt, indexesLength, mode, BufferUsage.StaticDraw); this.maxElementCount = indexesLength; original.Dispose(); } var indexBuffer = this.indexBuffer as OneIndexBuffer; IntPtr pointer = indexBuffer.MapBuffer(MapBufferAccess.WriteOnly); unsafe { var array = (uint *)pointer.ToPointer(); for (int i = 0; i < indexesLength; i++) { array[i] = indexes[i]; } } indexBuffer.UnmapBuffer(); indexBuffer.Mode = mode; indexBuffer.ElementCount = indexesLength; }
/// <summary> /// 在三角形图元中拾取指定位置的Point /// </summary> /// <param name="arg">渲染参数</param> /// <param name="x">mouse position(Left Down is (0, 0)).</param> /// <param name="y">mouse position(Left Down is (0, 0)).</param> /// <param name="lastVertexId">三角形图元的最后一个顶点</param> /// <param name="modernRenderer">目标Renderer</param> /// <returns></returns> internal override uint Search(RenderEventArgs arg, int x, int y, uint lastVertexId, ZeroIndexRenderer modernRenderer) { // 创建临时索引 OneIndexBuffer buffer = GLBuffer.Create(IndexBufferElementType.UInt, 3, DrawMode.Points, BufferUsage.StaticDraw); unsafe { var array = (uint *)buffer.MapBuffer(MapBufferAccess.WriteOnly); array[0] = lastVertexId - 0; array[1] = lastVertexId - 1; array[2] = lastVertexId - 2; buffer.UnmapBuffer(); } // 用临时索引渲染此三角形图元(仅渲染此三角形图元) modernRenderer.Render4InnerPicking(arg, buffer); // id是拾取到的Line的Last Vertex Id uint id = ColorCodedPicking.ReadStageVertexId(x, y); buffer.Dispose(); // 对比临时索引,找到那个Line if (lastVertexId - 2 <= id && id <= lastVertexId - 0) { return(id); } else { throw new Exception("This should not happen!"); } }
/// <summary> /// /// </summary> /// <param name="arg"></param> /// <param name="x">mouse position(Left Down is (0, 0)).</param> /// <param name="y">mouse position(Left Down is (0, 0)).</param> /// <param name="lastVertexId"></param> /// <param name="modernRenderer"></param> /// <returns></returns> internal override uint[] Search(PickEventArgs arg, uint lastVertexId, ZeroIndexPicker picker) { OneIndexBuffer buffer = GLBuffer.Create(IndexBufferElementType.UInt, 6, DrawMode.Lines, BufferUsage.StaticDraw); unsafe { var array = (uint *)buffer.MapBuffer(MapBufferAccess.WriteOnly); array[0] = 0; array[1] = lastVertexId - 1; array[2] = lastVertexId - 1; array[3] = lastVertexId - 0; array[4] = lastVertexId - 0; array[5] = 0; buffer.UnmapBuffer(); } picker.Renderer.Render4InnerPicking(arg, buffer); uint id = ColorCodedPicking.ReadStageVertexId(arg.X, arg.Y); buffer.Dispose(); if (id + 1 == lastVertexId) { return(new uint[] { 0, lastVertexId - 1, }); } else if (id == lastVertexId) { return(new uint[] { lastVertexId - 1, lastVertexId - 0, }); } else if (id == 0) { return(new uint[] { lastVertexId - 0, 0, }); } else { throw new Exception("This should not happen!"); } }
/// <summary> /// /// </summary> /// <param name="arg"></param> /// <param name="flatColorVertexId"></param> /// <param name="picker"></param> /// <returns></returns> internal override uint Search(PickingEventArgs arg, uint flatColorVertexId, DrawArraysPicker picker) { IndexBuffer buffer = GLBuffer.Create(IndexBufferElementType.UInt, 3, BufferUsage.StaticDraw); unsafe { var array = (uint *)buffer.MapBuffer(MapBufferAccess.WriteOnly); array[0] = flatColorVertexId - 0; array[1] = flatColorVertexId - 2; array[2] = flatColorVertexId - 4; buffer.UnmapBuffer(); } var cmd = new DrawElementsCmd(buffer, DrawMode.Points); picker.Node.Render4InnerPicking(arg, cmd); uint id = ColorCodedPicking.ReadStageVertexId(arg.X, arg.Y); buffer.Dispose(); if (flatColorVertexId - 0 == id || flatColorVertexId - 2 == id || flatColorVertexId - 4 == id) { return(id); } else { throw new Exception("This should not happen!"); } }
/// <summary> /// /// </summary> /// <param name="arg"></param> /// <param name="x">mouse position(Left Down is (0, 0)).</param> /// <param name="y">mouse position(Left Down is (0, 0)).</param> /// <param name="lastVertexId"></param> /// <param name="modernRenderer"></param> /// <returns></returns> internal override uint Search(RenderEventArgs arg, int x, int y, uint lastVertexId, ZeroIndexRenderer modernRenderer) { OneIndexBuffer buffer = GLBuffer.Create(IndexBufferElementType.UInt, 3, DrawMode.Points, BufferUsage.StaticDraw); unsafe { var array = (uint *)buffer.MapBuffer(MapBufferAccess.WriteOnly); array[0] = lastVertexId - 0; array[1] = lastVertexId - 2; array[2] = lastVertexId - 4; buffer.UnmapBuffer(); } modernRenderer.Render4InnerPicking(arg, buffer); uint id = ColorCodedPicking.ReadStageVertexId(x, y); buffer.Dispose(); if (lastVertexId - 0 == id || lastVertexId - 2 == id || lastVertexId - 4 == id) { return(id); } else { throw new Exception("This should not happen!"); } }
/// <summary> /// 在三角形图元中拾取指定位置的Point /// </summary> /// <param name="arg">渲染参数</param> /// <param name="flatColorVertexId">三角形图元的最后一个顶点</param> /// <param name="picker">目标Renderer</param> /// <returns></returns> internal override uint Search(PickingEventArgs arg, uint flatColorVertexId, DrawArraysPicker picker) { // 创建临时索引 IndexBuffer buffer = GLBuffer.Create(IndexBufferElementType.UInt, 3, BufferUsage.StaticDraw); unsafe { var array = (uint *)buffer.MapBuffer(MapBufferAccess.WriteOnly); array[0] = flatColorVertexId - 0; array[1] = flatColorVertexId - 1; array[2] = flatColorVertexId - 2; buffer.UnmapBuffer(); } var cmd = new DrawElementsCmd(buffer, DrawMode.Points); // 用临时索引渲染此三角形图元(仅渲染此三角形图元) picker.Node.Render4InnerPicking(arg, IndexAccessMode.ByFrame, cmd); // id是拾取到的Line的Last Vertex Id uint id = ColorCodedPicking.ReadStageVertexId(arg.X, arg.Y); buffer.Dispose(); // 对比临时索引,找到那个Line if (flatColorVertexId - 2 <= id && id <= flatColorVertexId - 0) { return(id); } else { throw new Exception("This should not happen!"); } }
/// <summary> /// /// </summary> protected override void DoInitialize() { // init shader program. ShaderProgram program = this.shaderCodes.CreateProgram(); // init property buffer objects. VertexBuffer positionBuffer = null; IBufferable model = this.DataSource; VertexBuffer[] vertexAttributeBuffers; { var list = new List <VertexBuffer>(); 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)); } if (item.NameInIBufferable == positionNameInIBufferable) { if (positionBuffer != null) { throw new Exception(string.Format("Duplicate position buffer is not allowed!")); } positionBuffer = buffer.Clone() as VertexBuffer; positionBuffer.VarNameInVertexShader = "in_Position";// in_Postion same with in the PickingShader.vert shader } list.Add(buffer); } vertexAttributeBuffers = list.ToArray(); } // init index buffer OneIndexBuffer indexBuffer; { var mode = DrawMode.Points;//any mode is OK as we'll update it later in other place. indexBuffer = GLBuffer.Create(IndexBufferElementType.UInt, positionBuffer.ByteLength / (positionBuffer.Config.GetDataSize() * positionBuffer.Config.GetDataTypeByteLength()), mode, BufferUsage.StaticDraw); this.maxElementCount = indexBuffer.ElementCount; indexBuffer.ElementCount = 0;// 高亮0个图元 // RULE: Renderer takes uint.MaxValue, ushort.MaxValue or byte.MaxValue as PrimitiveRestartIndex. So take care this rule when designing a model's index buffer. GLState glState = new PrimitiveRestartState(indexBuffer.ElementType); this.stateList.Add(glState); } // init VAO. var vertexArrayObject = new VertexArrayObject(indexBuffer, vertexAttributeBuffers); vertexArrayObject.Initialize(program); // sets fields. this.Program = program; this.vertexAttributeBuffers = vertexAttributeBuffers; this.indexBuffer = indexBuffer; this.vertexArrayObject = vertexArrayObject; this.positionBuffer = positionBuffer; }
/// <summary> /// /// </summary> /// <param name="arg"></param> /// <param name="x">mouse position(Left Down is (0, 0)).</param> /// <param name="y">mouse position(Left Down is (0, 0)).</param> /// <param name="lastVertexId"></param> /// <param name="modernRenderer"></param> /// <returns></returns> internal override uint Search(PickEventArgs arg, uint lastVertexId, ZeroIndexPicker picker) { OneIndexBuffer buffer = GLBuffer.Create(IndexBufferElementType.UInt, 4, DrawMode.Points, BufferUsage.StaticDraw); unsafe { var array = (uint *)buffer.MapBuffer(MapBufferAccess.WriteOnly); array[0] = lastVertexId - 0; array[1] = lastVertexId - 1; array[2] = lastVertexId - 2; array[3] = lastVertexId - 3; buffer.UnmapBuffer(); } picker.Renderer.Render4InnerPicking(arg, buffer); uint id = ColorCodedPicking.ReadStageVertexId(arg.X, arg.Y); buffer.Dispose(); if (lastVertexId - 3 <= id && id <= lastVertexId - 0) { return(id); } else { throw new Exception("This should not happen!"); } }
/// <summary> /// Generates an independent buffer. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="array"></param> /// <param name="target"></param> /// <param name="usage"></param> /// <returns></returns> private static GLBuffer GenIndependentBuffer <T>(this T[] array, IndependentBufferTarget target, BufferUsage usage) where T : struct { GCHandle pinned = GCHandle.Alloc(array, GCHandleType.Pinned); IntPtr header = Marshal.UnsafeAddrOfPinnedArrayElement(array, 0); UnmanagedArrayBase unmanagedArray = new TempUnmanagedArray <T>(header, array.Length);// It's not neecessary to call Dispose() for this unmanaged array. GLBuffer buffer = GenIndependentBuffer(unmanagedArray, target, usage); pinned.Free(); return(buffer); }
///// <summary> ///// Generates an atomic counter buffer. ///// </summary> ///// <param name="array"></param> ///// <param name="usage"></param> ///// <returns></returns> //public static AtomicCounterBuffer GenAtomicCounterBuffer(this UnmanagedArrayBase array, BufferUsage usage) //{ // return GenIndependentBuffer(array, IndependentBufferTarget.AtomicCounterBuffer, usage) as AtomicCounterBuffer; //} ///// <summary> ///// Generates a pixel pack buffer. ///// </summary> ///// <param name="array"></param> ///// <param name="usage"></param> ///// <returns></returns> //public static PixelPackBuffer GenPixelPackBuffer(this UnmanagedArrayBase array, BufferUsage usage) //{ // return GenIndependentBuffer(array, IndependentBufferTarget.PixelPackBuffer, usage) as PixelPackBuffer; //} ///// <summary> ///// Generates a pixel unpack buffer. ///// </summary> ///// <param name="array"></param> ///// <param name="usage"></param> ///// <returns></returns> //public static PixelUnpackBuffer GenPixelUnpackBuffer(this UnmanagedArrayBase array, BufferUsage usage) //{ // return GenIndependentBuffer(array, IndependentBufferTarget.PixelUnpackBuffer, usage) as PixelUnpackBuffer; //} ///// <summary> ///// Generates a shader storage buffer. ///// </summary> ///// <param name="array"></param> ///// <param name="usage"></param> ///// <returns></returns> //public static ShaderStorageBuffer GenShaderStorageBuffer(this UnmanagedArrayBase array, BufferUsage usage) //{ // return GenIndependentBuffer(array, IndependentBufferTarget.ShaderStorageBuffer, usage) as ShaderStorageBuffer; //} ///// <summary> ///// Generates a texture buffer. ///// </summary> ///// <param name="array"></param> ///// <param name="usage"></param> ///// <returns></returns> //public static TextureBuffer GenTextureBuffer(this UnmanagedArrayBase array, BufferUsage usage) //{ // return GenIndependentBuffer(array, IndependentBufferTarget.TextureBuffer, usage) as TextureBuffer; //} ///// <summary> ///// Generates an uniform buffer. ///// </summary> ///// <param name="array"></param> ///// <param name="usage"></param> ///// <returns></returns> //public static UniformBuffer GenUniformBuffer(this UnmanagedArrayBase array, BufferUsage usage) //{ // return GenIndependentBuffer(array, IndependentBufferTarget.UniformBuffer, usage) as UniformBuffer; //} /// <summary> /// Generates an independent buffer. /// </summary> /// <param name="array"></param> /// <param name="bufferTarget"></param> /// <param name="usage"></param> /// <returns></returns> private static GLBuffer GenIndependentBuffer(this UnmanagedArrayBase array, IndependentBufferTarget bufferTarget, BufferUsage usage) { uint[] ids = new uint[1]; { glGenBuffers(1, ids); var target = (uint)bufferTarget; glBindBuffer(target, ids[0]); glBufferData(target, array.ByteLength, array.Header, (uint)usage); glBindBuffer(target, 0); } GLBuffer buffer = null; switch (bufferTarget) { case IndependentBufferTarget.AtomicCounterBuffer: buffer = new AtomicCounterBuffer(ids[0], array.Length, array.ByteLength); break; case IndependentBufferTarget.PixelPackBuffer: buffer = new PixelPackBuffer(ids[0], array.Length, array.ByteLength); break; case IndependentBufferTarget.PixelUnpackBuffer: buffer = new PixelUnpackBuffer(ids[0], array.Length, array.ByteLength); break; case IndependentBufferTarget.ShaderStorageBuffer: buffer = new ShaderStorageBuffer(ids[0], array.Length, array.ByteLength); break; case IndependentBufferTarget.TextureBuffer: buffer = new TextureBuffer(ids[0], array.Length, array.ByteLength); break; case IndependentBufferTarget.UniformBuffer: buffer = new UniformBuffer(ids[0], array.Length, array.ByteLength); break; case IndependentBufferTarget.TransformFeedbackBuffer: buffer = new TransformFeedbackBuffer(ids[0], array.Length, array.ByteLength); break; default: throw new NotDealWithNewEnumItemException(typeof(IndependentBufferTarget)); } return(buffer); }
///// <summary> ///// Generates an atomic counter buffer. ///// </summary> ///// <param name="array"></param> ///// <param name="usage"></param> ///// <returns></returns> //public static AtomicCounterBuffer GenAtomicCounterBuffer(this UnmanagedArrayBase array, BufferUsage usage) //{ // return GenIndependentBuffer(array, IndependentBufferTarget.AtomicCounterBuffer, usage) as AtomicCounterBuffer; //} ///// <summary> ///// Generates a pixel pack buffer. ///// </summary> ///// <param name="array"></param> ///// <param name="usage"></param> ///// <returns></returns> //public static PixelPackBuffer GenPixelPackBuffer(this UnmanagedArrayBase array, BufferUsage usage) //{ // return GenIndependentBuffer(array, IndependentBufferTarget.PixelPackBuffer, usage) as PixelPackBuffer; //} ///// <summary> ///// Generates a pixel unpack buffer. ///// </summary> ///// <param name="array"></param> ///// <param name="usage"></param> ///// <returns></returns> //public static PixelUnpackBuffer GenPixelUnpackBuffer(this UnmanagedArrayBase array, BufferUsage usage) //{ // return GenIndependentBuffer(array, IndependentBufferTarget.PixelUnpackBuffer, usage) as PixelUnpackBuffer; //} ///// <summary> ///// Generates a shader storage buffer. ///// </summary> ///// <param name="array"></param> ///// <param name="usage"></param> ///// <returns></returns> //public static ShaderStorageBuffer GenShaderStorageBuffer(this UnmanagedArrayBase array, BufferUsage usage) //{ // return GenIndependentBuffer(array, IndependentBufferTarget.ShaderStorageBuffer, usage) as ShaderStorageBuffer; //} ///// <summary> ///// Generates a texture buffer. ///// </summary> ///// <param name="array"></param> ///// <param name="usage"></param> ///// <returns></returns> //public static TextureBuffer GenTextureBuffer(this UnmanagedArrayBase array, BufferUsage usage) //{ // return GenIndependentBuffer(array, IndependentBufferTarget.TextureBuffer, usage) as TextureBuffer; //} ///// <summary> ///// Generates an uniform buffer. ///// </summary> ///// <param name="array"></param> ///// <param name="usage"></param> ///// <returns></returns> //public static UniformBuffer GenUniformBuffer(this UnmanagedArrayBase array, BufferUsage usage) //{ // return GenIndependentBuffer(array, IndependentBufferTarget.UniformBuffer, usage) as UniformBuffer; //} /// <summary> /// Generates an independent buffer. /// </summary> /// <param name="array"></param> /// <param name="bufferTarget"></param> /// <param name="usage"></param> /// <returns></returns> private static GLBuffer GenIndependentBuffer(this UnmanagedArrayBase array, IndependentBufferTarget bufferTarget, BufferUsage usage) { if (glGenBuffers == null) { InitFunctions(); } uint[] buffers = new uint[1]; glGenBuffers(1, buffers); var target = (uint)bufferTarget; glBindBuffer(target, buffers[0]); glBufferData(target, array.ByteLength, array.Header, (uint)usage); glBindBuffer(target, 0); GLBuffer buffer = null; switch (bufferTarget) { case IndependentBufferTarget.AtomicCounterBuffer: buffer = new AtomicCounterBuffer(buffers[0], array.Length, array.ByteLength); break; case IndependentBufferTarget.PixelPackBuffer: buffer = new PixelPackBuffer(buffers[0], array.Length, array.ByteLength); break; case IndependentBufferTarget.PixelUnpackBuffer: buffer = new PixelUnpackBuffer(buffers[0], array.Length, array.ByteLength); break; case IndependentBufferTarget.ShaderStorageBuffer: buffer = new ShaderStorageBuffer(buffers[0], array.Length, array.ByteLength); break; case IndependentBufferTarget.TextureBuffer: buffer = new TextureBuffer(buffers[0], array.Length, array.ByteLength); break; case IndependentBufferTarget.UniformBuffer: buffer = new UniformBuffer(buffers[0], array.Length, array.ByteLength); break; default: throw new NotImplementedException(); } return(buffer); }
private IndexBuffer GetBufferInUInt(int length) { IndexBuffer buffer = GLBuffer.Create(IndexBufferElementType.UInt, length, 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(); } return(buffer); }
/// <summary> /// /// </summary> /// <param name="arg"></param> /// <param name="lastVertexId"></param> /// <param name="picker"></param> /// <returns></returns> internal override uint[] Search(PickingEventArgs arg, uint lastVertexId, DrawArraysPicker picker) { IndexBuffer buffer = GLBuffer.Create(IndexBufferElementType.UInt, 8, BufferUsage.StaticDraw); unsafe { var array = (uint *)buffer.MapBuffer(MapBufferAccess.WriteOnly); array[0] = lastVertexId - 0; array[1] = lastVertexId - 2; array[2] = lastVertexId - 2; array[3] = lastVertexId - 3; array[4] = lastVertexId - 3; array[5] = lastVertexId - 1; array[6] = lastVertexId - 1; array[7] = lastVertexId - 0; buffer.UnmapBuffer(); } var cmd = new DrawElementsCmd(buffer, DrawMode.Lines); picker.Node.Render4InnerPicking(arg, ControlMode.ByFrame, cmd); uint id = ColorCodedPicking.ReadStageVertexId(arg.X, arg.Y); buffer.Dispose(); if (id + 2 == lastVertexId) { return(new uint[] { lastVertexId - 0, lastVertexId - 2, }); } else if (id + 3 == lastVertexId) { return(new uint[] { lastVertexId - 2, lastVertexId - 3 }); } else if (id + 1 == lastVertexId) { return(new uint[] { lastVertexId - 3, lastVertexId - 1, }); } else if (id + 0 == lastVertexId) { return(new uint[] { lastVertexId - 1, lastVertexId - 0, }); } else { throw new Exception("This should not happen!"); } }
/// <summary> /// /// </summary> /// <returns></returns> public IndexBuffer GetIndexBuffer() { if (this.indexBuffer == null) { int length = TetrahedronModel.index.Length; OneIndexBuffer buffer = GLBuffer.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); }
private IndexBuffer GetBufferInBytes(int length) { IndexBuffer buffer = GLBuffer.Create(IndexBufferElementType.UByte, length, 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(); } return(buffer); }
/// <summary> /// /// </summary> /// <returns></returns> public IndexBuffer GetIndexBuffer() { if (indexBuffer == null) { ushort[] faces = model.GetFaces(); int length = faces.Length; OneIndexBuffer buffer = GLBuffer.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); }
public IndexBuffer GetIndexBuffer() { if (this.indexBuffer == null) { Face[] faces = Teapot.faceData; int length = faces.Length * 3; OneIndexBuffer buffer = GLBuffer.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 * 3 + 0] = (ushort)(faces[i].vertexId1 - 1); array[i * 3 + 1] = (ushort)(faces[i].vertexId2 - 1); array[i * 3 + 2] = (ushort)(faces[i].vertexId3 - 1); } buffer.UnmapBuffer(); } this.indexBuffer = buffer; } return(this.indexBuffer); }
/// <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); }
/// <summary> /// Creates a <see cref="AtomicCounterBuffer"/> object directly in server side(GPU) without initializing its value. /// </summary> /// <param name="elementType"></param> /// <param name="length"></param> /// <param name="usage"></param> /// <returns></returns> public static AtomicCounterBuffer Create(Type elementType, int length, BufferUsage usage) { return(GLBuffer.Create(IndependentBufferTarget.AtomicCounterBuffer, elementType, length, usage) as AtomicCounterBuffer); }
/// <summary> /// /// </summary> /// <param name="internalFormat"></param> /// <param name="buffer"></param> /// <param name="autoDispose">Dispose <paramref name="buffer"/> when disposing returned texture.</param> /// <returns></returns> public static Texture CreateBufferTexture(uint internalFormat, GLBuffer buffer, bool autoDispose) { return(buffer.DumpBufferTexture(internalFormat, autoDispose)); }
/// <summary> /// Creates a <see cref="ShaderStorageBuffer"/> object directly in server side(GPU) without initializing its value. /// </summary> /// <param name="elementType"></param> /// <param name="usage"></param> /// <param name="length"></param> /// <returns></returns> public static ShaderStorageBuffer Create(Type elementType, int length, BufferUsage usage) { return(GLBuffer.Create(IndependentBufferTarget.ShaderStorageBuffer, elementType, length, usage) as ShaderStorageBuffer); }
/// <summary> /// Creates a <see cref="PixelUnpackBuffer"/> object directly in server side(GPU) without initializing its value. /// </summary> /// <param name="elementType"></param> /// <param name="usage"></param> /// <param name="length"></param> /// <returns></returns> public static PixelUnpackBuffer Create(Type elementType, int length, BufferUsage usage) { return(GLBuffer.Create(IndependentBufferTarget.PixelUnpackBuffer, elementType, length, usage) as PixelUnpackBuffer); }
/// <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> /// /// </summary> /// <param name="internalformat"></param> /// <param name="buffer"></param> /// <param name="autoDispose">Dispose <paramref name="buffer"/> when this filler is disposed.</param> public TexBufferImageFiller(uint internalformat, GLBuffer buffer, bool autoDispose) { this.internalformat = internalformat; this.buffer = buffer; this.autoDispose = autoDispose; }
/// <summary> /// Creates a <see cref="TextureBuffer"/> object directly in server side(GPU) without initializing its value. /// </summary> /// <param name="elementType"></param> /// <param name="length"></param> /// <param name="usage"></param> /// <returns></returns> public static TextureBuffer Create(Type elementType, int length, BufferUsage usage) { return(GLBuffer.Create(IndependentBufferTarget.TextureBuffer, elementType, length, usage) as TextureBuffer); }
/// <summary> /// /// </summary> /// <param name="internalFormat"></param> /// <param name="buffer"></param> /// <param name="autoDispose">Dispose <paramref name="buffer"/> when this <see cref="TexBufferStorage"/> object is disposed?</param> public TexBufferStorage(uint internalFormat, GLBuffer buffer, bool autoDispose) : base(TextureTarget.TextureBuffer, internalFormat) { this.buffer = buffer; this.autoDispose = autoDispose; }
/// <summary> /// Bind specified buffer to specified binding point of this transform feedback object. /// Then data will be dumped to the specified buffer when this transform feedback object works. /// </summary> /// <param name="index"></param> /// <param name="buffer"></param> public void BindBuffer(uint index, GLBuffer buffer) { this.Bind(); glBindBufferBase(GL.GL_TRANSFORM_FEEDBACK_BUFFER, index, buffer.BufferId); this.Unbind(); }
/// <summary> /// Creates a <see cref="AtomicCounterBuffer"/> object directly in server side(GPU) without initializing its value. /// </summary> /// <param name="elementType"></param> /// <param name="length"></param> /// <param name="usage"></param> /// <returns></returns> public static TransformFeedbackBuffer Create(Type elementType, int length, BufferUsage usage) { return(GLBuffer.Create(IndependentBufferTarget.TransformFeedbackBuffer, elementType, length, usage) as TransformFeedbackBuffer); }