/// <summary> /// 在三角形图元中拾取指定位置的Line /// </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] = lastVertexId - 1; array[1] = lastVertexId - 0; array[2] = lastVertexId - 2; array[3] = lastVertexId - 1; array[4] = lastVertexId - 0; array[5] = lastVertexId - 2; buffer.UnmapBuffer(); } // 用临时索引渲染此三角形图元(仅渲染此三角形图元) picker.Renderer.Render4InnerPicking(arg, buffer); // id是拾取到的Line的Last Vertex Id uint id = ColorCodedPicking.ReadStageVertexId(arg.X, arg.Y); buffer.Dispose(); // 对比临时索引,找到那个Line if (id + 2 == lastVertexId) { return(new uint[] { id + 2, id, }); } else { return(new uint[] { id - 1, id, }); } }
private void RenderersDraw(RenderModes renderMode, bool renderScene = true, bool renderUI = true) { var arg = new RenderEventArgs(renderMode, this.glCanvas1.ClientRectangle, this.camera, this.PickingGeometryType); if (renderMode == RenderModes.ColorCodedPicking) { if (renderScene) { ColorCodedPicking.Render4Picking(arg, this.rendererDict[this.selectedModel].PickableRenderer); } } else if (renderMode == RenderModes.Render) { OpenGL.ClearColor(ClearColor.R / 255.0f, ClearColor.G / 255.0f, ClearColor.B / 255.0f, ClearColor.A / 255.0f); OpenGL.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT | OpenGL.GL_STENCIL_BUFFER_BIT); if (renderScene) { SceneRenderersDraw(arg); } if (renderUI) { UIRenderersDraw(arg); } } }
/// <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, 6, DrawMode.Lines, BufferUsage.StaticDraw); unsafe { var array = (uint *)buffer.MapBuffer(MapBufferAccess.WriteOnly); array[0] = lastVertexId - 2; array[1] = lastVertexId - 0; array[2] = lastVertexId - 4; array[3] = lastVertexId - 2; array[4] = lastVertexId - 0; array[5] = lastVertexId - 4; buffer.UnmapBuffer(); } modernRenderer.Render4InnerPicking(arg, buffer); uint id = ColorCodedPicking.ReadStageVertexId(x, y); buffer.Dispose(); if (id + 4 == lastVertexId) { return(new uint[] { id + 4, id, }); } else { return(new uint[] { id - 2, id, }); } }
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 - 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, arg.CanvasRect.Height - y - 1); indexBufferPtr.Dispose(); if (id + 3 == lastVertexId) { return(new uint[] { id + 3, id, }); } else { return(new uint[] { id - 1, id, }); } }
/// <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, 8, DrawMode.Lines, BufferUsage.StaticDraw); unsafe { var array = (uint *)buffer.MapBuffer(MapBufferAccess.WriteOnly); 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; buffer.UnmapBuffer(); } picker.Node.Render4InnerPicking(arg, buffer); uint id = ColorCodedPicking.ReadStageVertexId(arg.X, arg.Y); buffer.Dispose(); if (id + 3 == lastVertexId) { return(new uint[] { id + 3, id, }); } else { return(new uint[] { id - 1, id, }); } }
/// <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, 6, BufferUsage.StaticDraw); unsafe { var array = (uint *)buffer.MapBuffer(MapBufferAccess.WriteOnly); array[0] = lastVertexId - 2; array[1] = lastVertexId - 0; array[2] = lastVertexId - 4; array[3] = lastVertexId - 2; array[4] = lastVertexId - 0; array[5] = lastVertexId - 4; 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 + 4 == lastVertexId) { return(new uint[] { id + 4, id, }); } else { return(new uint[] { id - 2, id, }); } }
internal override uint[] Search(RenderEventArgs arg, int x, int y, uint lastVertexId, ZeroIndexRenderer modernRenderer) { ZeroIndexBufferPtr zeroIndexBufferPtr = modernRenderer.IndexBufferPtr; ZeroIndexBufferPtr indexBufferPtr = null; // when the temp index buffer could be long, it's no longer needed. // what a great OpenGL API design! using (var buffer = new ZeroIndexBuffer(DrawMode.LineLoop, zeroIndexBufferPtr.FirstVertex, zeroIndexBufferPtr.VertexCount)) { indexBufferPtr = buffer.GetBufferPtr() as ZeroIndexBufferPtr; } modernRenderer.Render4InnerPicking(arg, indexBufferPtr); uint id = ColorCodedPicking.ReadPixel(x, arg.CanvasRect.Height - y - 1); indexBufferPtr.Dispose(); if (id == zeroIndexBufferPtr.FirstVertex) { return(new uint[] { (uint)(zeroIndexBufferPtr.FirstVertex + zeroIndexBufferPtr.VertexCount - 1), id, }); } else { return(new uint[] { id - 1, id, }); } }
private PickedGeometry RunPicking(RenderEventArgs arg, int x, int y) { lock (this.synObj) { // prepare pickable elements PickableRenderer pickable = this.rendererDict[this.SelectedModel].PickableRenderer; pickable.MVP = this.camera.GetProjectionMat4() * this.camera.GetViewMat4(); PickedGeometry pickedGeometry = ColorCodedPicking.Pick( arg, x, y, pickable); return(pickedGeometry); } }
/// <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) { var cmd = picker.DrawCommand as DrawArraysCmd; // when the temp index buffer could be long, it's no longer needed. // what a great OpenGL API design! DrawArraysCmd drawCmd = new DrawArraysCmd(DrawMode.LineLoop, cmd.FirstVertex, cmd.RenderingVertexCount, cmd.InstanceCount, cmd.FrameCount); picker.Node.Render4InnerPicking(arg, IndexAccessMode.ByFrame, drawCmd); uint id = ColorCodedPicking.ReadStageVertexId(arg.X, arg.Y); if (id == cmd.FirstVertex) { return(new uint[] { (uint)(cmd.FirstVertex + cmd.RenderingVertexCount - 1), id, }); } else { return(new uint[] { id - 1, id, }); } }
/// <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) { var zeroIndexBuffer = picker.Node.PickingRenderUnit.VertexArrayObject.IndexBuffer as ZeroIndexBuffer; // when the temp index buffer could be long, it's no longer needed. // what a great OpenGL API design! ZeroIndexBuffer indexBuffer = ZeroIndexBuffer.Create(DrawMode.LineLoop, zeroIndexBuffer.FirstVertex, zeroIndexBuffer.RenderingVertexCount, zeroIndexBuffer.InstanceCount); picker.Node.Render4InnerPicking(arg, indexBuffer); uint id = ColorCodedPicking.ReadStageVertexId(arg.X, arg.Y); indexBuffer.Dispose(); if (id == zeroIndexBuffer.FirstVertex) { return(new uint[] { (uint)(zeroIndexBuffer.FirstVertex + zeroIndexBuffer.RenderingVertexCount - 1), id, }); } else { return(new uint[] { id - 1, id, }); } }
/// <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) { ZeroIndexBuffer zeroIndexBuffer = modernRenderer.IndexBuffer; // when the temp index buffer could be long, it's no longer needed. // what a great OpenGL API design! ZeroIndexBuffer indexBuffer = ZeroIndexBuffer.Create(DrawMode.LineLoop, zeroIndexBuffer.FirstVertex, zeroIndexBuffer.RenderingVertexCount, zeroIndexBuffer.PrimCount); modernRenderer.Render4InnerPicking(arg, indexBuffer); uint id = ColorCodedPicking.ReadStageVertexId(x, y); indexBuffer.Dispose(); if (id == zeroIndexBuffer.FirstVertex) { return(new uint[] { (uint)(zeroIndexBuffer.FirstVertex + zeroIndexBuffer.RenderingVertexCount - 1), id, }); } else { return(new uint[] { id - 1, id, }); } }
private void glCanvas1_MouseMove(object sender, MouseEventArgs e) { if (rotator.MouseDownFlag) { rotator.MouseMove(e.X, e.Y); this.cameraUpdated = true; } { IColorCodedPicking pickable = this.renderer; pickable.MVP = this.camera.GetProjectionMat4() * this.camera.GetViewMat4(); IPickedGeometry pickedGeometry = ColorCodedPicking.Pick( this.camera, e.X, e.Y, this.glCanvas1.Width, this.glCanvas1.Height, pickable); if (pickedGeometry != null) { this.bulletinBoard.SetContent(pickedGeometry.ToString()); } else { this.bulletinBoard.SetContent("picked nothing."); } } }