/// <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 = Buffer.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="mode">要高亮显示的图元类型</param> /// <param name="indexes">要高亮显示的图元的索引。</param> public void SetHighlightIndexes(DrawMode mode, params uint[] indexes) { int indexesLength = indexes.Length; if (indexesLength > this.maxElementCount) { IndexBufferPtr original = this.indexBufferPtr; using (var buffer = new OneIndexBuffer(IndexElementType.UInt, mode, BufferUsage.DynamicDraw)) { buffer.Create(indexesLength); this.indexBufferPtr = buffer.GetBufferPtr() as OneIndexBufferPtr; } this.maxElementCount = indexesLength; original.Dispose(); } var indexBufferPtr = this.indexBufferPtr as OneIndexBufferPtr; IntPtr pointer = indexBufferPtr.MapBuffer(MapBufferAccess.WriteOnly); unsafe { var array = (uint *)pointer.ToPointer(); for (int i = 0; i < indexesLength; i++) { array[i] = indexes[i]; } } indexBufferPtr.UnmapBuffer(); indexBufferPtr.Mode = mode; indexBufferPtr.ElementCount = indexesLength; }
/// <summary> /// /// </summary> /// <param name="arg"></param> /// <param name="lastVertexId"></param> /// <param name="picker"></param> /// <returns></returns> internal override uint Search(PickingEventArgs 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!"); } }
protected override void RecognizeUShort(uint lastVertexId, IntPtr pointer, OneIndexBuffer oneIndexBuffer, List <RecognizedPrimitiveInfo> primitiveInfoList, uint primitiveRestartIndex) { int length = oneIndexBuffer.VertexCount; unsafe { var array = (ushort *)pointer.ToPointer(); long nearestRestartIndex = -1; uint i = 0; while (i < length && array[i] == primitiveRestartIndex) { nearestRestartIndex = i; i++; } for (i = i + 2; i < length; i++) { var value = array[i]; if (value == primitiveRestartIndex) { // try the loop back line. nearestRestartIndex = i; } else if (value == lastVertexId && array[i - 1] != primitiveRestartIndex && array[nearestRestartIndex + 1] != primitiveRestartIndex && nearestRestartIndex + 2 < i) { var item = new RecognizedPrimitiveInfo(i, array[nearestRestartIndex + 1], array[i - 1], lastVertexId); primitiveInfoList.Add(item); } } } }
/// <summary> /// 识别出以<paramref name="lastVertexId"/>结尾的图元。 /// </summary> /// <param name="lastVertexId"></param> /// <param name="pointer"></param> /// <param name="oneIndexBuffer"></param> /// <returns></returns> public List <RecognizedPrimitiveInfo> Recognize( uint lastVertexId, IntPtr pointer, OneIndexBuffer oneIndexBuffer) { var lastIndexIdList = new List <RecognizedPrimitiveInfo>(); switch (oneIndexBuffer.ElementType) { case IndexBufferElementType.UByte: RecognizeByte(lastVertexId, pointer, oneIndexBuffer, lastIndexIdList); break; case IndexBufferElementType.UShort: RecognizeUShort(lastVertexId, pointer, oneIndexBuffer, lastIndexIdList); break; case IndexBufferElementType.UInt: RecognizeUInt(lastVertexId, pointer, oneIndexBuffer, lastIndexIdList); break; default: throw new NotDealWithNewEnumItemException(typeof(IndexBufferElementType)); } return(lastIndexIdList); }
/// <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="primitiveInfo"></param> /// <param name="modernRenderer"></param> /// <returns></returns> internal override uint Search(RenderEventArgs arg, int x, int y, RecognizedPrimitiveInfo primitiveInfo, OneIndexRenderer modernRenderer) { uint[] indexList = primitiveInfo.VertexIds; if (indexList.Length < 3) { throw new ArgumentException(); } OneIndexBuffer buffer = indexList.GenIndexBuffer(DrawMode.Points, BufferUsage.StaticDraw); modernRenderer.Render4InnerPicking(arg, buffer); uint id = ColorCodedPicking.ReadStageVertexId(x, y); buffer.Dispose(); if (id != uint.MaxValue) { return(id); } else { throw new Exception("This should not happen!"); } }
protected override void RecognizeUInt(uint lastVertexId, IntPtr pointer, OneIndexBuffer oneIndexBuffer, List <RecognizedPrimitiveInfo> primitiveInfoList) { int length = oneIndexBuffer.VertexCount; unsafe { var array = (uint *)pointer.ToPointer(); for (uint i = 1; i < length; i++) { var value = array[i]; if (value == lastVertexId) { var item = new RecognizedPrimitiveInfo(i, array[i - 1], lastVertexId); primitiveInfoList.Add(item); } } if (array[0] == lastVertexId && length > 1) { var item = new RecognizedPrimitiveInfo(0, array[length - 1], lastVertexId); primitiveInfoList.Add(item); } } }
/// <summary> /// /// </summary> /// <returns></returns> public OneIndexBuffer GetIndexBuffer() { if (this.buffer == null) { //this.buffer = OneIndexBuffer.Create(this.ElementType, this.Length, this.Mode, this.Usage); switch (this.ElementType) { case IndexBufferElementType.UByte: { var array = this.data as byte[]; this.buffer = array.GenIndexBuffer(this.Mode, this.Usage, this.PrimCount); } break; case IndexBufferElementType.UShort: { var array = this.data as ushort[]; this.buffer = array.GenIndexBuffer(this.Mode, this.Usage, this.PrimCount); } break; case IndexBufferElementType.UInt: { var array = this.data as uint[]; this.buffer = array.GenIndexBuffer(this.Mode, this.Usage, this.PrimCount); } break; default: throw new Exception(); } } return(this.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, 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="recognizedPrimitiveIndex0"></param> /// <param name="recognizedPrimitiveIndex1"></param> /// <param name="drawMode"></param> /// <param name="oneIndexBuffer"></param> /// <param name="lastIndex0"></param> /// <param name="lastIndex1"></param> private void AssembleIndexBuffer( RecognizedPrimitiveInfo recognizedPrimitiveIndex0, RecognizedPrimitiveInfo recognizedPrimitiveIndex1, DrawMode drawMode, out OneIndexBuffer oneIndexBuffer, out uint lastIndex0, out uint lastIndex1) { List <uint> indexArray = ArrangeIndexes( recognizedPrimitiveIndex0, recognizedPrimitiveIndex1, drawMode, out lastIndex0, out lastIndex1); if (indexArray.Count != recognizedPrimitiveIndex0.VertexIds.Length + 1 + recognizedPrimitiveIndex1.VertexIds.Length) { throw new Exception(string.Format("index array[{0}] not same length with [recognized primitive1 index length{1}] + [1] + recognized primitive2 index length[{2}]", recognizedPrimitiveIndex0.VertexIds.Length, recognizedPrimitiveIndex1.VertexIds.Length)); } oneIndexBuffer = indexArray.ToArray().GenIndexBuffer(drawMode, BufferUsage.StaticDraw); //oneIndexBuffer = Buffer.Create(IndexElementType.UInt, // recognizedPrimitiveIndex0.VertexIds.Length // + 1 // + recognizedPrimitiveIndex1.VertexIds.Length, // drawMode, BufferUsage.StaticDraw); //unsafe //{ // var array = (uint*)oneIndexBuffer.MapBuffer(MapBufferAccess.WriteOnly); // for (int i = 0; i < indexArray.Count; i++) // { // array[i] = indexArray[i]; // } // oneIndexBuffer.UnmapBuffer(); //} }
/// <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] = 0; array[1] = lastVertexId - 1; array[2] = lastVertexId - 0; buffer.UnmapBuffer(); } modernRenderer.Render4InnerPicking(arg, buffer); uint id = ColorCodedPicking.ReadStageVertexId(x, y); buffer.Dispose(); if (0 == id || lastVertexId - 1 == id || lastVertexId - 0 == id) { return(id); } else { throw new Exception("This should not happen!"); } }
/// <summary> /// Creates a <see cref="OneIndexBuffer"/> object directly in server side(GPU) without initializing its value. /// </summary> /// <param name="type"></param> /// <param name="length">How many indexes are there?(How many uint/ushort/bytes?)</param> /// <param name="mode"></param> /// <param name="usage"></param> /// <returns></returns> public static OneIndexBuffer Create(IndexBufferElementType type, int length, DrawMode mode, BufferUsage usage) { if (glGenBuffers == null) { glGenBuffers = OpenGL.GetDelegateFor <OpenGL.glGenBuffers>(); } if (glBindBuffer == null) { glBindBuffer = OpenGL.GetDelegateFor <OpenGL.glBindBuffer>(); } if (glBufferData == null) { glBufferData = OpenGL.GetDelegateFor <OpenGL.glBufferData>(); } int byteLength = GetSize(type) * length; uint[] buffers = new uint[1]; glGenBuffers(1, buffers); const uint target = OpenGL.GL_ELEMENT_ARRAY_BUFFER; glBindBuffer(target, buffers[0]); glBufferData(target, byteLength, IntPtr.Zero, (uint)usage); glBindBuffer(target, 0); var buffer = new OneIndexBuffer( buffers[0], mode, type, length, byteLength); return(buffer); }
/// <summary> /// /// </summary> /// <param name="arg"></param> /// <param name="primitiveInfo"></param> /// <param name="picker"></param> /// <returns></returns> internal override uint Search(PickingEventArgs arg, RecognizedPrimitiveInfo primitiveInfo, OneIndexPicker picker) { uint[] indexList = primitiveInfo.VertexIds; if (indexList.Length != 3) { throw new ArgumentException(); } OneIndexBuffer buffer = indexList.GenIndexBuffer(DrawMode.Points, BufferUsage.StaticDraw); picker.Renderer.Render4InnerPicking(arg, buffer); uint id = ColorCodedPicking.ReadStageVertexId(arg.X, arg.Y); buffer.Dispose(); if (id == indexList[0] || id == indexList[1] || id == indexList[2]) { return(id); } else { throw new Exception("This should not happen!"); } }
/// <summary> /// 识别出以<paramref name="lastVertexId"/>结尾的图元。 /// <para>识别过程中要考虑排除PrimitiveRestartIndex</para> /// </summary> /// <param name="lastVertexId"></param> /// <param name="pointer"></param> /// <param name="oneIndexBuffer"></param> /// <param name="primitiveRestartIndex"></param> /// <returns></returns> public List <RecognizedPrimitiveInfo> Recognize( uint lastVertexId, IntPtr pointer, OneIndexBuffer oneIndexBuffer, uint primitiveRestartIndex) { var lastIndexIdList = new List <RecognizedPrimitiveInfo>(); if (lastVertexId != primitiveRestartIndex) { switch (oneIndexBuffer.ElementType) { case IndexBufferElementType.UByte: RecognizeByte(lastVertexId, pointer, oneIndexBuffer, lastIndexIdList, primitiveRestartIndex); break; case IndexBufferElementType.UShort: RecognizeUShort(lastVertexId, pointer, oneIndexBuffer, lastIndexIdList, primitiveRestartIndex); break; case IndexBufferElementType.UInt: RecognizeUInt(lastVertexId, pointer, oneIndexBuffer, lastIndexIdList, primitiveRestartIndex); break; default: throw new NotImplementedException(); } } return(lastIndexIdList); }
public IndexBuffer GetIndexBuffer() { if (this.indexBuffer == null) { int polygon = (this.mesh.faces[0] is ObjVNFTriangle) ? 3 : 4; DrawMode mode = (this.mesh.faces[0] is ObjVNFTriangle) ? DrawMode.Triangles : DrawMode.Quads; OneIndexBuffer indexBuffer = OneIndexBuffer.Create(IndexBufferElementType.UInt, polygon * this.mesh.faces.Length, mode, BufferUsage.StaticDraw); unsafe { var array = (uint *)indexBuffer.MapBuffer(MapBufferAccess.WriteOnly); int index = 0; foreach (var face in this.mesh.faces) { foreach (var vertexIndex in face.VertexIndexes()) { array[index++] = vertexIndex; } } indexBuffer.UnmapBuffer(); } this.indexBuffer = indexBuffer; } return(this.indexBuffer); }
internal override uint[] Search(RenderEventArgs arg, int x, int y, uint lastVertexId, ZeroIndexRenderer modernRenderer) { OneIndexBufferPtr indexBufferPtr = null; using (var buffer = new OneIndexBuffer <uint>(DrawMode.Lines, BufferUsage.StaticDraw)) { buffer.Create(8); unsafe { var array = (uint *)buffer.Header.ToPointer(); array[0] = lastVertexId - 1; array[1] = lastVertexId - 0; array[2] = lastVertexId - 2; array[3] = lastVertexId - 1; array[4] = lastVertexId - 3; array[5] = lastVertexId - 2; array[6] = lastVertexId - 0; array[7] = lastVertexId - 3; } indexBufferPtr = buffer.GetBufferPtr() as OneIndexBufferPtr; } modernRenderer.Render4InnerPicking(arg, indexBufferPtr); uint id = ColorCodedPicking.ReadPixel(x, y, arg.CanvasRect.Height); indexBufferPtr.Dispose(); if (id + 3 == lastVertexId) { return(new uint[] { id + 3, id, }); } else { return(new uint[] { id - 1, id, }); } }
internal override uint Search(RenderEventArgs arg, int x, int y, uint lastVertexId, ZeroIndexRenderer modernRenderer) { OneIndexBufferPtr indexBufferPtr = null; using (var buffer = new OneIndexBuffer <uint>(DrawMode.Points, BufferUsage.StaticDraw)) { buffer.Create(3); unsafe { var array = (uint *)buffer.Header.ToPointer(); array[0] = lastVertexId - 0; array[1] = lastVertexId - 1; array[2] = lastVertexId - 2; } indexBufferPtr = buffer.GetBufferPtr() as OneIndexBufferPtr; } modernRenderer.Render4InnerPicking(arg, indexBufferPtr); uint id = ColorCodedPicking.ReadPixel(x, y, arg.CanvasRect.Height); indexBufferPtr.Dispose(); if (lastVertexId - 2 <= id && id <= lastVertexId - 0) { return(id); } else { throw new Exception("This should not happen!"); } }
protected override void RecognizeByte(uint lastVertexId, IntPtr pointer, OneIndexBuffer oneIndexBuffer, List <RecognizedPrimitiveInfo> primitiveInfoList, uint primitiveRestartIndex) { int length = oneIndexBuffer.VertexCount; unsafe { var array = (byte *)pointer.ToPointer(); long nearestRestartIndex = -1; uint i = 0; while (i < length && array[i] == primitiveRestartIndex) { nearestRestartIndex = i; i++; } for (i = i + 2; i < length; i++) { var value = array[i]; if (value == primitiveRestartIndex) { nearestRestartIndex = i; } else if (value == lastVertexId && array[i - 1] != primitiveRestartIndex && array[i - 2] != primitiveRestartIndex && (i - nearestRestartIndex) % 3 == 0) { var item = new RecognizedPrimitiveInfo(i, array[i - 2], array[i - 1], lastVertexId); primitiveInfoList.Add(item); } } } }
/// <summary> /// 设置要高亮显示的图元。 /// </summary> /// <param name="mode">要高亮显示的图元类型</param> /// <param name="indexes">要高亮显示的图元的索引。</param> public void SetHighlightIndexes(DrawMode mode, params uint[] indexes) { var indexBufferPtr = this.indexBufferPtr as OneIndexBufferPtr; int indexesLength = indexes.Length; if (indexesLength > this.maxElementCount) { using (var buffer = new OneIndexBuffer <uint>( indexBufferPtr.Mode, BufferUsage.DynamicDraw)) { buffer.Alloc(indexesLength); indexBufferPtr = buffer.GetBufferPtr() as OneIndexBufferPtr; } this.maxElementCount = indexesLength; } OpenGL.BindBuffer(BufferTarget.ElementArrayBuffer, indexBufferPtr.BufferId); IntPtr pointer = OpenGL.MapBuffer(BufferTarget.ElementArrayBuffer, MapBufferAccess.WriteOnly); unsafe { var array = (uint *)pointer.ToPointer(); for (int i = 0; i < indexesLength; i++) { array[i] = indexes[i]; } } OpenGL.UnmapBuffer(BufferTarget.ElementArrayBuffer); OpenGL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); indexBufferPtr.Mode = mode; indexBufferPtr.ElementCount = indexesLength; }
internal override uint[] Search(RenderEventArgs arg, int x, int y, RecognizedPrimitiveIndex lastIndexId, OneIndexRenderer modernRenderer) { List <uint> indexList = lastIndexId.IndexIdList; if (indexList.Count < 3) { throw new ArgumentException(); } OneIndexBufferPtr indexBufferPtr = null; using (var buffer = new OneIndexBuffer <uint>(DrawMode.LineLoop, BufferUsage.StaticDraw)) { buffer.Create(indexList.Count); unsafe { var array = (uint *)buffer.Header.ToPointer(); for (int i = 0; i < indexList.Count; i++) { array[i] = indexList[i]; } } indexBufferPtr = buffer.GetBufferPtr() as OneIndexBufferPtr; } modernRenderer.Render4InnerPicking(arg, indexBufferPtr); uint id = ColorCodedPicking.ReadPixel(x, y, arg.CanvasRect.Height); indexBufferPtr.Dispose(); if (id == indexList[0]) { return(new uint[] { indexList[indexList.Count - 1], id, }); } else { uint[] result = null; for (int i = 1; i < indexList.Count; i++) { if (id == indexList[i]) { result = new uint[] { indexList[i - 1], indexList[i], }; break; } } if (result != null) { return(result); } else { throw new Exception("This should not happen!"); } } }
/// <summary> /// /// </summary> /// <param name="arg"></param> /// <param name="twoPrimitivesIndexBuffer"></param> /// <returns></returns> private uint Pick(PickingEventArgs arg, OneIndexBuffer twoPrimitivesIndexBuffer) { this.Renderer.Render4InnerPicking(arg, twoPrimitivesIndexBuffer); uint pickedIndex = ColorCodedPicking.ReadStageVertexId(arg.X, arg.Y); return(pickedIndex); }
/// <summary> /// /// </summary> /// <param name="arg"></param> /// <param name="twoPrimitivesIndexBuffer"></param> /// <param name="x">mouse position(Left Down is (0, 0)).</param> /// <param name="y">mouse position(Left Down is (0, 0)).</param> /// <returns></returns> private uint Pick(RenderEventArgs arg, OneIndexBuffer twoPrimitivesIndexBuffer, int x, int y) { Render4InnerPicking(arg, twoPrimitivesIndexBuffer); uint pickedIndex = ColorCodedPicking.ReadStageVertexId(x, y); return(pickedIndex); }
public IndexBuffer GetIndexBuffer() { if (this.indexBuffer == null) { this.indexBuffer = indexes.GenIndexBuffer(DrawMode.Quads, BufferUsage.StaticDraw); } return(this.indexBuffer); }
internal override uint[] Search(RenderEventArgs arg, int x, int y, RecognizedPrimitiveIndex lastIndexId, OneIndexRenderer modernRenderer) { List <uint> indexList = lastIndexId.IndexIdList; if (indexList.Count != 4) { throw new ArgumentException(); } OneIndexBufferPtr indexBufferPtr = null; using (var buffer = new OneIndexBuffer <uint>(DrawMode.Lines, BufferUsage.StaticDraw)) { buffer.Create(8); unsafe { var array = (uint *)buffer.Header.ToPointer(); array[0] = indexList[0]; array[1] = indexList[1]; array[2] = indexList[1]; array[3] = indexList[2]; array[4] = indexList[2]; array[5] = indexList[3]; array[6] = indexList[3]; array[7] = indexList[0]; } indexBufferPtr = buffer.GetBufferPtr() as OneIndexBufferPtr; } modernRenderer.Render4InnerPicking(arg, indexBufferPtr); uint id = ColorCodedPicking.ReadPixel(x, y, arg.CanvasRect.Height); indexBufferPtr.Dispose(); if (id == indexList[1]) { return(new uint[] { indexList[0], indexList[1], }); } else if (id == indexList[2]) { return(new uint[] { indexList[1], indexList[2], }); } else if (id == indexList[3]) { return(new uint[] { indexList[2], indexList[3], }); } else if (id == indexList[0]) { return(new uint[] { indexList[2], indexList[0], }); } else { throw new Exception("This should not happen!"); } }
internal override uint[] Search(RenderEventArgs arg, int x, int y, RecognizedPrimitiveInfo primitiveInfo, OneIndexRenderer modernRenderer) { uint[] indexList = primitiveInfo.VertexIds; if (indexList.Length != 3) { throw new ArgumentException(); } //if (indexList[0] == indexList[1]) { return new uint[] { indexList[0], indexList[2], }; } //else if (indexList[0] == indexList[2]) { return new uint[] { indexList[0], indexList[1], }; } //else if (indexList[1] == indexList[2]) { return new uint[] { indexList[1], indexList[0], }; } OneIndexBufferPtr indexBufferPtr = null; using (var buffer = new OneIndexBuffer(IndexElementType.UInt, DrawMode.Lines, BufferUsage.StaticDraw)) { buffer.Create(6); unsafe { var array = (uint *)buffer.Header.ToPointer(); array[0] = indexList[0]; array[1] = indexList[1]; array[2] = indexList[1]; array[3] = indexList[2]; array[4] = indexList[2]; array[5] = indexList[0]; } indexBufferPtr = buffer.GetBufferPtr() as OneIndexBufferPtr; } modernRenderer.Render4InnerPicking(arg, indexBufferPtr); uint id = ColorCodedPicking.ReadPixel(x, arg.CanvasRect.Height - y - 1); indexBufferPtr.Dispose(); if (id == indexList[1]) { return(new uint[] { indexList[0], indexList[1], }); } else if (id == indexList[2]) { return(new uint[] { indexList[1], indexList[2], }); } else if (id == indexList[0]) { return(new uint[] { indexList[2], indexList[0], }); } else { throw new Exception("This should not happen!"); } }
/// <summary> /// /// </summary> protected override void DoInitialize() { base.DoInitialize(); foreach (var item in propertyNameMap) { PropertyBufferPtr bufferPtr = this.bufferable.GetProperty( item.NameInIBufferable, item.VarNameInShader); if (bufferPtr == null) { throw new Exception(); } if (item.NameInIBufferable == positionNameInIBufferable) { this.positionBufferPtr = new PropertyBufferPtr( "in_Position",// in_Postion same with in the PickingShader.vert shader bufferPtr.BufferId, bufferPtr.DataSize, bufferPtr.DataType, bufferPtr.Length, bufferPtr.ByteLength); break; } } // init index buffer { //IndexBufferPtr indexBufferPtr = this.bufferable.GetIndex(); using (var buffer = new OneIndexBuffer <uint>( this.indexBufferPtr.Mode, BufferUsage.DynamicDraw)) { buffer.Create(this.positionBufferPtr.ByteLength / (this.positionBufferPtr.DataSize * this.positionBufferPtr.DataTypeByteLength)); this.indexBufferPtr = buffer.GetBufferPtr() as IndexBufferPtr; } } { var oneIndexBufferPtr = this.indexBufferPtr as OneIndexBufferPtr; this.maxElementCount = oneIndexBufferPtr.ElementCount; oneIndexBufferPtr.ElementCount = 0;// 高亮0个图元 } //this.bufferable = null; //this.shaderCodes = null; //this.propertyNameMap = null; }
internal override uint[] Search(RenderEventArgs arg, int x, int y, uint lastVertexId, ZeroIndexRenderer modernRenderer) { OneIndexBufferPtr indexBufferPtr = null; using (var buffer = new OneIndexBuffer(IndexElementType.UInt, DrawMode.Lines, BufferUsage.StaticDraw)) { buffer.Create(8); unsafe { var array = (uint *)buffer.Header.ToPointer(); 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; } indexBufferPtr = buffer.GetBufferPtr() as OneIndexBufferPtr; } modernRenderer.Render4InnerPicking(arg, indexBufferPtr); uint id = ColorCodedPicking.ReadPixel(x, arg.CanvasRect.Height - y - 1); indexBufferPtr.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> /// 生成一个用于存储索引的VBO。索引指定了<see cref="VertexBuffer"/>里各个顶点的渲染顺序。 /// Generates a Vertex Buffer Object storing vertexes' indexes, which indicate the rendering order of each vertex. /// </summary> /// <param name="array"></param> /// <param name="mode">用哪种方式渲染各个顶点?(OpenGL.GL_TRIANGLES etc.)</param> /// <param name="usage"></param> /// <param name="primCount">primCount in instanced rendering.</param> /// <returns></returns> private static OneIndexBuffer GenIndexBuffer <T>(this T[] array, DrawMode mode, BufferUsage usage, int primCount = 1) where T : struct { IndexBufferElementType elementType; if (typeof(T) == typeof(uint)) { elementType = IndexBufferElementType.UInt; } else if (typeof(T) == typeof(ushort)) { elementType = IndexBufferElementType.UShort; } else if (typeof(T) == typeof(byte)) { elementType = IndexBufferElementType.UByte; } else { throw new ArgumentException(string.Format("Only uint/ushort/byte are allowed!")); } if (glGenBuffers == null) { InitFunctions(); } GCHandle pinned = GCHandle.Alloc(array, GCHandleType.Pinned); IntPtr header = Marshal.UnsafeAddrOfPinnedArrayElement(array, 0); UnmanagedArrayBase unmanagedArray = UnmanagedArray <T> .FromHandle(header, array.Length);// It's not neecessary to call Dispose() for this unmanaged array. var buffers = new uint[1]; { glGenBuffers(1, buffers); const uint target = OpenGL.GL_ELEMENT_ARRAY_BUFFER; glBindBuffer(target, buffers[0]); glBufferData(target, unmanagedArray.ByteLength, unmanagedArray.Header, (uint)usage); glBindBuffer(target, 0); } pinned.Free(); var buffer = new OneIndexBuffer(buffers[0], mode, elementType, unmanagedArray.Length, unmanagedArray.ByteLength, primCount); return(buffer); }
protected override void RecognizeByte(uint lastVertexId, IntPtr pointer, OneIndexBuffer oneIndexBuffer, List <RecognizedPrimitiveInfo> primitiveInfoList) { int length = oneIndexBuffer.Length; unsafe { var array = (byte *)pointer.ToPointer(); for (uint i = 0; i < length; i++) { var value = array[i]; if (value == lastVertexId) { var item = new RecognizedPrimitiveInfo(i, value); primitiveInfoList.Add(item); } } } }
protected override void RecognizeUShort(uint lastVertexId, IntPtr pointer, OneIndexBuffer oneIndexBuffer, List <RecognizedPrimitiveInfo> primitiveInfoList, uint primitiveRestartIndex) { int length = oneIndexBuffer.VertexCount; unsafe { var array = (ushort *)pointer.ToPointer(); for (uint i = 0; i < length; i++) { var value = array[i]; if (value == lastVertexId) { var item = new RecognizedPrimitiveInfo(i, value); primitiveInfoList.Add(item); } } } }