/// <summary> /// </summary> /// <param name="indexAccessMode">index buffer is accessable randomly or only by frame.</param> public void Draw(IndexAccessMode indexAccessMode) { GCHandle pinAll = GCHandle.Alloc(this.allIndices, GCHandleType.Pinned); var count = this.count; var indices = new IntPtr[count.Length]; int current = 0; for (int i = 0; i < indices.Length; i++) { indices[i] = Marshal.UnsafeAddrOfPinnedArrayElement(allIndices, current); current += count[i]; } GCHandle pinIndices = GCHandle.Alloc(indices, GCHandleType.Pinned); IntPtr header = pinIndices.AddrOfPinnedObject(); if (this.baseVertex == null) { glMultiDrawElements((uint)this.Mode, this.count, (uint)this.type, header, this.count.Length); } else { glMultiDrawElementsBaseVertex((uint)this.Mode, this.count, (uint)this.type, header, this.count.Length, this.baseVertex); } pinIndices.Free(); pinAll.Free(); }
/// <summary> /// /// </summary> /// <param name="indexAccessMode">index buffer is accessable randomly or only by frame.</param> /// <param name="transformFeedbackObj"></param> public void Render(IndexAccessMode indexAccessMode, TransformFeedbackObject transformFeedbackObj) { ShaderProgram program = this.Program; GLSwitchList switchList = this.SwitchList; // 绑定shader program.Bind(); program.PushUniforms(); // push new uniform values to GPU side. switchList.On(); if (transformFeedbackObj != null) { transformFeedbackObj.Bind(); foreach (var vao in this.VertexArrayObjects) { transformFeedbackObj.Begin(vao.DrawCommand.Mode); vao.Draw(indexAccessMode); transformFeedbackObj.End(); } transformFeedbackObj.Unbind(); } else { foreach (var vao in this.VertexArrayObjects) { vao.Draw(indexAccessMode); } } switchList.Off(); // 解绑shader program.Unbind(); }
/// <summary> /// /// </summary> /// <param name="index"></param> /// <param name="indexAccessMode">index buffer is accessable randomly or only by frame.</param> /// <param name="transformFeedbackObj"></param> public void Render(int index, IndexAccessMode indexAccessMode, TransformFeedbackObject transformFeedbackObj = null) { if (index < 0 || this.Methods.Length <= index) { throw new System.IndexOutOfRangeException(); } this.Methods[index].Render(indexAccessMode, transformFeedbackObj); }
private void RenderForPicking(PickingEventArgs arg, IndexAccessMode indexAccessMode, IDrawCommand tmpCmd) { if (!this.IsInitialized) { this.Initialize(); } this.polygonModeState.Mode = arg.GeometryType.GetPolygonMode(); ShaderProgram program = this.PickingRenderMethod.Program; // 绑定shader program.Bind(); { mat4 projection = arg.Scene.Camera.GetProjectionMatrix(); mat4 view = arg.Scene.Camera.GetViewMatrix(); mat4 model = this.GetModelMatrix(); program.glUniform("MVP", projection * view * model); } this.polygonModeState.On(); this.lineWidthState.On(); this.pointSizeState.On(); //PrimitiveRestartState restart = null; //var hasIndexBuffer = tmpCmd as IHasIndexBuffer; //if (hasIndexBuffer != null) //{ // restart = this.GetPrimitiveRestartState(hasIndexBuffer.IndexBufferObject.ElementType); //} //if (restart != null) //{ // restart.On(); //} { var pickable = this as IPickable; uint baseId = pickable.PickingBaseId; foreach (var vao in this.PickingRenderMethod.VertexArrayObjects) { program.glUniform("pickingBaseId", (int)(baseId)); vao.Draw(indexAccessMode, tmpCmd); baseId += (uint)vao.VertexAttributes[0].Buffer.Length; } } //if (restart != null) //{ // restart.Off(); //} this.pointSizeState.Off(); this.lineWidthState.Off(); this.polygonModeState.Off(); // 解绑shader program.Unbind(); }
/// <summary> /// 执行一次渲染的过程。 /// <para>Execute rendering command.</para> /// </summary> /// <param name="indexAccessMode">index buffer is accessable randomly or only by frame.</param> /// <param name="temporaryIndexBuffer">render by a temporary index buffer</param> public void Draw(IndexAccessMode indexAccessMode, IDrawCommand temporaryIndexBuffer = null) { this.Bind(); if (temporaryIndexBuffer != null) { temporaryIndexBuffer.Draw(indexAccessMode); } else { this.DrawCommand.Draw(indexAccessMode); } this.Unbind(); }
/// <summary> /// 在此Buffer中的图元进行N选1 /// select a primitive geometry(point, line, triangle, quad, polygon) from points/lines/triangles/quads/polygons in this node. /// </summary> /// <param name="arg"></param> /// <param name="indexAccessMode"></param> /// <param name="drawCmd">indicates the primitive to pick a line from.</param> internal void Render4InnerPicking(PickingEventArgs arg, IndexAccessMode indexAccessMode, IDrawCommand drawCmd) { // record clear color var originalClearColor = new float[4]; GL.Instance.GetFloatv((uint)GetTarget.ColorClearValue, originalClearColor); // 白色意味着没有拾取到任何对象 // white color: nothing picked. GL.Instance.ClearColor(1.0f, 1.0f, 1.0f, 1.0f); GL.Instance.Clear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_BUFFER_BIT); // restore clear color GL.Instance.ClearColor(originalClearColor[0], originalClearColor[1], originalClearColor[2], originalClearColor[3]); this.RenderForPicking(arg, indexAccessMode, drawCmd); GL.Instance.Flush(); //var filename = string.Format("Render4InnerPicking{0:yyyy-MM-dd_HH-mm-ss.ff}.png", DateTime.Now); //Save2PictureHelper.Save2Picture(0, 0, // e.CanvasRect.Width, e.CanvasRect.Height, filename); }
/// <summary> /// /// </summary> /// <param name="indexAccessMode">index buffer is accessable randomly or only by frame.</param> public void Render(IndexAccessMode indexAccessMode = IndexAccessMode.ByFrame) { this.Render(indexAccessMode, null); }
/// <summary> /// /// </summary> /// <param name="indexAccessMode">index buffer is accessable randomly or only by frame.</param> public void Render(IndexAccessMode indexAccessMode = IndexAccessMode.Random) { this.Render(indexAccessMode, null); }
/// <summary> /// 执行此VBO的渲染操作。 /// <para>Render using this VBO.</para> /// </summary> /// <param name="indexAccessMode">index buffer is accessable randomly or only by frame.</param> public void Draw(IndexAccessMode indexAccessMode) { GL.Instance.MultiDrawArrays((uint)this.Mode, this.First, this.Count, this.First.Length); }
/// <summary> /// </summary> /// <param name="indexAccessMode">index buffer is accessable randomly or only by frame.</param> public void Draw(IndexAccessMode indexAccessMode) { uint mode = (uint)this.Mode; 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."); } switch (indexAccessMode) { case IndexAccessMode.ByFrame: int vertexCount = this.VertexCount; if (instanceCount == 1) { if (frameCount == 1) { GL.Instance.DrawArrays(mode, 0, vertexCount); } else { int vertexCountPerFrame = vertexCount / frameCount; GL.Instance.DrawArrays(mode, this.CurrentFrame * vertexCountPerFrame, vertexCountPerFrame); } } else { if (frameCount == 1) { glDrawArraysInstanced(mode, 0, this.VertexCount, instanceCount); } else { int vertexCountPerFrame = vertexCount / frameCount; glDrawArraysInstanced(mode, this.CurrentFrame * vertexCountPerFrame, vertexCountPerFrame, instanceCount); } } break; case IndexAccessMode.Random: if (instanceCount == 1) { GL.Instance.DrawArrays(mode, this.FirstVertex, this.RenderingVertexCount); } else { glDrawArraysInstanced(mode, this.FirstVertex, this.RenderingVertexCount, instanceCount); } break; default: throw new NotDealWithNewEnumItemException(typeof(IndexAccessMode)); } }
/// <summary> /// /// </summary> /// <param name="indexAccessMode">index buffer is accessable randomly or only by frame.</param> public void Draw(IndexAccessMode indexAccessMode) { 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); 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); switch (indexAccessMode) { case IndexAccessMode.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 IndexAccessMode.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(IndexAccessMode)); } GLBuffer.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0); if (rs != 0) { GL.Instance.Disable(GL.GL_PRIMITIVE_RESTART); } }