protected vec3[] FillPickedGeometrysPosition(uint[] indexes) { var positions = new vec3[indexes.Length]; OpenGL.BindBuffer(BufferTarget.ArrayBuffer, this.positionBufferPtr.BufferId); for (int i = 0; i < indexes.Length; i++) { int offset = (int)(indexes[i] * this.positionBufferPtr.DataSize * this.positionBufferPtr.DataTypeByteLength); //IntPtr pointer = GL.MapBuffer(BufferTarget.ArrayBuffer, MapBufferAccess.ReadOnly); IntPtr pointer = OpenGL.MapBufferRange(BufferTarget.ArrayBuffer, offset, 1 * this.positionBufferPtr.DataSize * this.positionBufferPtr.DataTypeByteLength, MapBufferRangeAccess.MapReadBit); if (pointer.ToInt32() != 0) { unsafe { var array = (vec3 *)pointer.ToPointer(); positions[i] = array[0]; } } else { ErrorCode error = (ErrorCode)OpenGL.GetError(); Debug.WriteLine(string.Format( "Error:[{0}] MapBufferRange failed: buffer ID: [{1}]", error, this.positionBufferPtr.BufferId)); } OpenGL.UnmapBuffer(BufferTarget.ArrayBuffer); } OpenGL.BindBuffer(BufferTarget.ArrayBuffer, 0); return(positions); }
protected vec3[] FillPickedGeometrysPosition(uint firstIndex, int indexCount) { int offset = (int)(firstIndex * this.positionBufferPtr.DataSize * this.positionBufferPtr.DataTypeByteLength); OpenGL.BindBuffer(BufferTarget.ArrayBuffer, this.positionBufferPtr.BufferId); //IntPtr pointer = GL.MapBuffer(BufferTarget.ArrayBuffer, MapBufferAccess.ReadOnly); IntPtr pointer = OpenGL.MapBufferRange(BufferTarget.ArrayBuffer, offset, indexCount * this.positionBufferPtr.DataSize * this.positionBufferPtr.DataTypeByteLength, MapBufferRangeAccess.MapReadBit); var positions = new vec3[indexCount]; if (pointer.ToInt32() != 0) { unsafe { var array = (vec3 *)pointer.ToPointer(); for (uint i = 0; i < indexCount; i++) { positions[i] = array[i]; } } } else { ErrorCode error = (ErrorCode)OpenGL.GetError(); throw new Exception(string.Format( "Error:[{0}] MapBufferRange failed: buffer ID: [{1}]", error, this.positionBufferPtr.BufferId)); } OpenGL.UnmapBuffer(BufferTarget.ArrayBuffer); OpenGL.BindBuffer(BufferTarget.ArrayBuffer, 0); return(positions); }
/// <summary> /// 遍历以<see cref="lastVerteID"/>为最后一个顶点的图元, /// 瞄准每个图元的索引(例如1个三角形有3个索引)中的最后一个索引, /// 将此索引在<see cref="indexBufferPtr"/>中的索引(位置)收集起来。 /// </summary> /// <param name="lastVertexId"></param> /// <returns></returns> private List <RecognizedPrimitiveIndex> GetLastIndexIdList(RenderEventArgs arg, uint lastVertexId) { PrimitiveRecognizer recognizer = PrimitiveRecognizerFactory.Create( (arg.RenderMode == RenderModes.ColorCodedPicking && arg.PickingGeometryType == GeometryType.Point && this.indexBufferPtr.Mode.ToGeometryType() == GeometryType.Line) ? DrawMode.Points : this.indexBufferPtr.Mode); PrimitiveRestartSwitch glSwitch = GetPrimitiveRestartSwitch(); OpenGL.BindBuffer(BufferTarget.ElementArrayBuffer, this.indexBufferPtr.BufferId); IntPtr pointer = OpenGL.MapBuffer(BufferTarget.ElementArrayBuffer, MapBufferAccess.ReadOnly); List <RecognizedPrimitiveIndex> lastIndexIdList = null; if (glSwitch == null) { lastIndexIdList = recognizer.Recognize(lastVertexId, pointer, this.indexBufferPtr as OneIndexBufferPtr); } else { lastIndexIdList = recognizer.Recognize(lastVertexId, pointer, this.indexBufferPtr as OneIndexBufferPtr, glSwitch.RestartIndex); } OpenGL.UnmapBuffer(BufferTarget.ElementArrayBuffer); OpenGL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); return(lastIndexIdList); }
/// <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; }
private void PickingLastLineInLineLoop(PickedGeometry pickedGeometry) { const int vertexCount = 2; var offsets = new int[vertexCount] { (this.positionBufferPtr.Length - 1) * this.positionBufferPtr.DataSize * this.positionBufferPtr.DataTypeByteLength, 0, }; pickedGeometry.Positions = new vec3[vertexCount]; pickedGeometry.Indexes = new uint[vertexCount]; for (int i = 0; i < vertexCount; i++) { OpenGL.BindBuffer(BufferTarget.ArrayBuffer, this.positionBufferPtr.BufferId); IntPtr pointer = OpenGL.MapBufferRange(BufferTarget.ArrayBuffer, offsets[i], 1 * this.positionBufferPtr.DataSize * this.positionBufferPtr.DataTypeByteLength, MapBufferRangeAccess.MapReadBit); unsafe { var array = (vec3 *)pointer.ToPointer(); pickedGeometry.Positions[i] = array[0]; } OpenGL.UnmapBuffer(BufferTarget.ArrayBuffer); pickedGeometry.Indexes[i] = (uint)offsets[i] / (uint)(this.positionBufferPtr.DataSize * this.positionBufferPtr.DataTypeByteLength); } }
unsafe private void SetupGlyphPositions(string content, FontResource fontResource) { FullDictionary <char, CharacterInfo> charInfoDict = fontResource.CharInfoDict; OpenGL.BindBuffer(BufferTarget.ArrayBuffer, this.model.positionBufferPtr.BufferId); IntPtr pointer = OpenGL.MapBuffer(BufferTarget.ArrayBuffer, MapBufferAccess.ReadWrite); var array = (GlyphPosition *)pointer.ToPointer(); int currentWidth = 0; int currentHeight = 0; /* * 0 3 4 7 8 11 12 15 * ------- ------- ------- ------- * | | | | | | | | * | | | | | | | | * | | | | | | | | * ------- ------- ------- ------- * 1 2 5 6 9 10 13 14 */ for (int i = 0; i < content.Length; i++) { char ch = content[i]; CharacterInfo info = charInfoDict[ch]; array[i] = new GlyphPosition( new vec2(currentWidth, currentHeight + fontResource.FontHeight), new vec2(currentWidth, currentHeight), new vec2(currentWidth + info.width, currentHeight), new vec2(currentWidth + info.width, currentHeight + fontResource.FontHeight)); currentWidth += info.width + fontResource.FontHeight / 10; } // move to center for (int i = 0; i < content.Length; i++) { GlyphPosition position = array[i]; position.leftUp.x -= currentWidth / 2.0f; //position.leftUp.x /= currentWidth / factor; position.leftDown.x -= currentWidth / 2.0f; //position.leftDown.x /= currentWidth / factor; position.rightUp.x -= currentWidth / 2.0f; //position.rightUp.x /= currentWidth / factor; position.rightDown.x -= currentWidth / 2.0f; //position.rightDown.x /= currentWidth / factor; position.leftUp.y -= (currentHeight + fontResource.FontHeight) / 2.0f; position.leftDown.y -= (currentHeight + fontResource.FontHeight) / 2.0f; position.rightUp.y -= (currentHeight + fontResource.FontHeight) / 2.0f; position.rightDown.y -= (currentHeight + fontResource.FontHeight) / 2.0f; position.leftUp.x /= (currentHeight + fontResource.FontHeight); position.leftDown.x /= (currentHeight + fontResource.FontHeight); position.rightUp.x /= (currentHeight + fontResource.FontHeight); position.rightDown.x /= (currentHeight + fontResource.FontHeight); position.leftUp.y /= (currentHeight + fontResource.FontHeight); position.leftDown.y /= (currentHeight + fontResource.FontHeight); position.rightUp.y /= (currentHeight + fontResource.FontHeight); position.rightDown.y /= (currentHeight + fontResource.FontHeight); array[i] = position; } OpenGL.UnmapBuffer(BufferTarget.ArrayBuffer); OpenGL.BindBuffer(BufferTarget.ArrayBuffer, 0); }
/// <summary> /// 根据<paramref name="differenceOnWindow"/>来修改指定索引处的顶点位置。 /// </summary> /// <param name="differenceOnWindow"></param> /// <param name="viewMatrix"></param> /// <param name="projectionMatrix"></param> /// <param name="viewport"></param> /// <param name="positionIndexes"></param> public void MovePositions(Point differenceOnWindow, mat4 viewMatrix, mat4 projectionMatrix, vec4 viewport, params uint[] positionIndexes) { OpenGL.BindBuffer(BufferTarget.ArrayBuffer, this.positionBufferPtr.BufferId); IntPtr pointer = OpenGL.MapBuffer(BufferTarget.ArrayBuffer, MapBufferAccess.ReadWrite); unsafe { var array = (vec3 *)pointer.ToPointer(); foreach (var index in positionIndexes) { vec3 windowPos = glm.project(array[index], viewMatrix, projectionMatrix, viewport); vec3 newWindowPos = new vec3(windowPos.x + differenceOnWindow.X, windowPos.y + differenceOnWindow.Y, windowPos.z); array[index] = glm.unProject(newWindowPos, viewMatrix, projectionMatrix, viewport); } } OpenGL.UnmapBuffer(BufferTarget.ArrayBuffer); OpenGL.BindBuffer(BufferTarget.ArrayBuffer, 0); }
/// <summary> /// 根据<paramref name="differenceOnScreen"/>来修改指定索引处的顶点位置。 /// </summary> /// <param name="differenceOnScreen"></param> /// <param name="viewMatrix"></param> /// <param name="projectionMatrix"></param> /// <param name="viewport"></param> /// <param name="positionIndexes"></param> public void MovePositions(Point differenceOnScreen, mat4 viewMatrix, mat4 projectionMatrix, vec4 viewport, IEnumerable <uint> positionIndexes) { OpenGL.BindBuffer(BufferTarget.ArrayBuffer, this.positionBufferPtr.BufferId); IntPtr pointer = OpenGL.MapBuffer(BufferTarget.ArrayBuffer, MapBufferAccess.ReadWrite); unsafe { var array = (vec3 *)pointer.ToPointer(); foreach (var index in positionIndexes) { vec3 projected = glm.project(array[index], viewMatrix, projectionMatrix, viewport); vec3 newProjected = new vec3(projected.x + differenceOnScreen.X, projected.y + differenceOnScreen.Y, projected.z); array[index] = glm.unProject(newProjected, viewMatrix, projectionMatrix, viewport); } } OpenGL.UnmapBuffer(BufferTarget.ArrayBuffer); OpenGL.BindBuffer(BufferTarget.ArrayBuffer, 0); }
unsafe private void SetupGlyphTexCoord(string content, FontResource fontResource) { FullDictionary <char, CharacterInfo> charInfoDict = fontResource.CharInfoDict; OpenGL.BindBuffer(BufferTarget.ArrayBuffer, this.model.uvBufferPtr.BufferId); IntPtr pointer = OpenGL.MapBuffer(BufferTarget.ArrayBuffer, MapBufferAccess.WriteOnly); var array = (GlyphTexCoord *)pointer.ToPointer(); int width = fontResource.TextureSize.Width; int height = fontResource.TextureSize.Height; /* * 0 3 4 6 8 11 12 15 * ------- ------- ------- ------- * | | | | | | | | * | | | | | | | | * | | | | | | | | * ------- ------- ------- ------- * 1 2 5 6 9 10 13 14 */ for (int i = 0; i < content.Length; i++) { char ch = content[i]; CharacterInfo info = fontResource.CharInfoDict[ch]; const int shrimp = 0; array[i] = new GlyphTexCoord( //new vec2(0, 0), //new vec2(0, 1), //new vec2(1, 1), //new vec2(1, 0) new vec2((float)(info.xoffset + shrimp) / (float)width, (float)(info.yoffset) / (float)height), new vec2((float)(info.xoffset + shrimp) / (float)width, (float)(info.yoffset + info.height) / (float)height), new vec2((float)(info.xoffset - shrimp + info.width) / (float)width, (float)(info.yoffset + info.height) / (float)height), new vec2((float)(info.xoffset - shrimp + info.width) / (float)width, (float)(info.yoffset) / (float)height) ); } OpenGL.UnmapBuffer(BufferTarget.ArrayBuffer); OpenGL.BindBuffer(BufferTarget.ArrayBuffer, 0); }