public void DrawPoints(string name, int pointCount, float pointSize) { if (!_objectsHandleDictionary.ContainsKey(name)) { throw new ApplicationException("Object must be added to the renderer before drawing"); } GL.BindVertexArray(_objectsHandleDictionary[name].ObjectHandle); GL.PointSize(pointSize); GL.DrawElements(BeginMode.Points, pointCount, DrawElementsType.UnsignedInt, IntPtr.Zero); }
public void DrawBackBuffer(GraphScaleData scaleData) { if (Hide || _backData == null) { return; } float height = ScaleFunction.ScaledHeight(scaleData); Matrix4 transform = Matrix4.CreateTranslation(scaleData.XShift, 0, 0) * Matrix4.Scale(2 / scaleData.BaseScale, 2 / height, 1) * Matrix4.CreateTranslation(-1, -1, 0); GL.UniformMatrix4(_shaderProgram.UniformTransform, false, ref transform); if (_drawMode == BeginMode.Lines || _drawMode == BeginMode.LineLoop || _drawMode == BeginMode.LineStrip) { GL.LineWidth(2f); } else if (_drawMode == BeginMode.Points) { GL.PointSize(2f); } if (_alphaBlend > 0) { Color4 col = Color; col.A = 1 - _alphaBlend; GL.Uniform4(_shaderProgram.UniformColor, col); } else { GL.Uniform4(_shaderProgram.UniformColor, Color); } if (_graphType == GraphType.SolidGraph) { _backBuffer.SetAttributeInfo(_shaderProgram.AttributeCoord2D, 2); _backBuffer.BeginDraw(); _backBuffer.Draw(_drawMode); _backBuffer.EndDraw(); _backBuffer.SetAttributeInfo(_shaderProgram.AttributeCoord2D, 2, false, 2 * Vector2.SizeInBytes); GL.Uniform4(_shaderProgram.UniformColor, Color4.Black); GL.LineWidth(1f); _backBuffer.BeginDraw(); _backBuffer.Draw(BeginMode.LineStrip, _backData.Length / 2); _backBuffer.EndDraw(); } else { _backBuffer.BeginDraw(); _backBuffer.Draw(_drawMode, _backData.Length / 2); _backBuffer.EndDraw(); } }
public void Draw(RenderQueueItem queueItem, ICamera camera, float aspectRatio) { var glContext = infra.GlContext; var visual = (IModelVisualElement)queueItem.VisualElement; var node = queueItem.Node; if (visual.Hide) { return; } var renderStateData = visual.RenderState.GetFallbackData(); glContext.Bindings.Program.Set(commonObjects.StandardShaderProgram); switch (renderStateData.PolygonMode) { case PolygonMode.Fill: glContext.States.Rasterizer.PolygonModeFront.Set(ObjectGL.Api.Context.States.Rasterizer.PolygonMode.Fill); break; case PolygonMode.Line: glContext.States.Rasterizer.PolygonModeFront.Set(ObjectGL.Api.Context.States.Rasterizer.PolygonMode.Line); break; case PolygonMode.Point: glContext.States.Rasterizer.PolygonModeFront.Set(ObjectGL.Api.Context.States.Rasterizer.PolygonMode.Point); break; default: throw new ArgumentOutOfRangeException(); } switch (renderStateData.CullFace) { case CullFace.None: glContext.States.Rasterizer.CullFaceEnable.Set(false); break; case CullFace.Back: glContext.States.Rasterizer.CullFaceEnable.Set(true); glContext.States.Rasterizer.CullFace.Set(CullFaceMode.Back); break; case CullFace.Front: glContext.States.Rasterizer.CullFaceEnable.Set(true); glContext.States.Rasterizer.CullFace.Set(CullFaceMode.Front); break; default: throw new ArgumentOutOfRangeException(); } glContext.States.DepthStencil.StencilTestEnable.Set(true); var stencilFunctionSettings = new StencilFunctionSettings { Function = StencilFunction.Always, Mask = 0xff, Reference = 1 }; var stencilOperationSettings = new StencilOperationSettings { DepthPass = queueItem.IsHighlighted ? StencilOp.Replace : StencilOp.Keep, DepthFail = queueItem.IsHighlighted ? StencilOp.Replace : StencilOp.Keep, StencilFail = StencilOp.Keep }; glContext.States.DepthStencil.Front.StencilWriteMask.Set(0xff); glContext.States.DepthStencil.Back.StencilWriteMask.Set(0xff); glContext.States.DepthStencil.Front.StencilFunctionSettings.Set(stencilFunctionSettings); glContext.States.DepthStencil.Back.StencilFunctionSettings.Set(stencilFunctionSettings); glContext.States.DepthStencil.Front.StencilOperationSettings.Set(stencilOperationSettings); glContext.States.DepthStencil.Back.StencilOperationSettings.Set(stencilOperationSettings); var material = visual.Material as IStandardMaterial ?? commonObjects.UndefinedMaterial; var diffuseColor = material.DiffuseColor; var glDiffuseMap = material.DiffuseMap ?.CacheContainer .GetOrAddCache(Tuples.Pair(infra, material.DiffuseMap), x => new CgImageCache(x.First, x.Second)) .GetGlTexture2D(); var glNormalMap = material.NormalMap ?.CacheContainer .GetOrAddCache(Tuples.Pair(infra, material.NormalMap), x => new CgImageCache(x.First, x.Second)) .GetGlTexture2D(); glContext.Bindings.Textures.Units[0].Set(glDiffuseMap); glContext.Bindings.Textures.Units[1].Set(glNormalMap); var sampler = samplerCache.GetGlSampler(material.Sampler); glContext.Bindings.Samplers[0].Set(sampler); glContext.Bindings.Samplers[1].Set(sampler); var cWarpScroll = node.SearchComponent <IWarpScrollComponent>(); commonObjects.MaterialUb.SetData(new MaterialUniform { Color = diffuseColor.SrgbToLinear(), IsEdited = (Bool32)(material.HighlightEffect == HighlightEffect.BlackWhiteBorder), IgnoreLighting = (Bool32)material.IgnoreLighting, IsSelected = (Bool32)(material.HighlightEffect == HighlightEffect.RainbowBorder), UseTexture = (Bool32)(glDiffuseMap != null), UseNormalMap = (Bool32)(glNormalMap != null), NoSpecular = (Bool32)material.NoSpecular, ScrollingEnabled = (Bool32)(cWarpScroll != null), ScrollingAmount = cWarpScroll?.VisibleScrollAmount ?? 0.0f, BlackIsTransparent = (Bool32)(material.RtTransparencyMode == RtTransparencyMode.BlackIsTransparent), WhiteIsTransparent = (Bool32)(material.RtTransparencyMode == RtTransparencyMode.WhiteIsTransparent), IsPulsating = (Bool32)(material.HighlightEffect == HighlightEffect.Pulsating), PulsatingColor = Color4.Orange }); // todo: Use ObjectGL bindings GL.PointSize(renderStateData.PointSize); GL.LineWidth(renderStateData.LineWidth); // todo: switch (visual.TransformSpace) var transform = visual.Transform * node.GlobalTransform; Matrix4x4 world; if (visual.TransformSpace == TransformSpace.ScreenAlighned) { var globalViewFrame = camera.GetGlobalFrame(); transform.Rotation = Quaternion.RotationToFrame(globalViewFrame.Right, globalViewFrame.Up); world = Matrix4x4.Scaling(visual.NonUniformScale) * transform.ToMatrix4x4(); } else if (visual.TransformSpace == TransformSpace.Ortho) { var props = camera.GetProps(); var viewMat = camera.GetViewMat(); var orthoProjMat = Matrix4x4.OrthoFromPerspective((props.Target - props.Frame.Eye).Length(), props.Projection.Fov, aspectRatio, -10f, 5f); var viewProjInverse = camera.GetViewProjInverse(aspectRatio); world = Matrix4x4.Scaling(visual.NonUniformScale) * transform.ToMatrix4x4(); world *= viewMat * orthoProjMat * viewProjInverse; } else { world = Matrix4x4.Scaling(visual.NonUniformScale) * transform.ToMatrix4x4(); } var zOffset = renderStateData.ZOffset + GraphicsHelper.MinZOffset * (node.ChildNodes.IsEmptyL() ? (node.ParentNode?.ChildNodes.IndexOf(node) ?? 0) : 0); commonObjects.TransformUb.SetData(new TransformUniform { World = world, WorldInverseTranspose = world.Invert().Transpose(), ZOffset = zOffset }); switch (visual.Model) { case IFlexibleModel flexibleModel: { var modelPart = flexibleModel.Parts[visual.ModelPartIndex]; var vertexSet = flexibleModel.VertexSets[modelPart.VertexSetIndex]; var vertexSetCache = vertexSet.CacheContainer.GetOrAddCache(Tuples.Pair(infra, vertexSet), x => new VertexSetCache(x.First, x.Second)); var glVao = vertexSetCache.GetGlVao(); glContext.Bindings.VertexArray.Set(glVao); var beginMode = GetBeginMode(modelPart.PrimitiveTopology); if (vertexSet.IndicesInfo == null) { glContext.Actions.Draw.Arrays(beginMode, modelPart.FirstIndex + modelPart.VertexOffset, modelPart.IndexCount); } else { AnalyzeIndexType(vertexSet.IndicesInfo.Format, out var drawElementsType, out var offsetMultiplier); var indexBufferOffset = modelPart.FirstIndex * offsetMultiplier; if (modelPart.VertexOffset == 0) { glContext.Actions.Draw.Elements(beginMode, modelPart.IndexCount, drawElementsType, indexBufferOffset); } else { glContext.Actions.Draw.ElementsBaseVertex(beginMode, modelPart.IndexCount, drawElementsType, indexBufferOffset, modelPart.VertexOffset); } } break; } case IExplicitModel explicitModel: { var modelPart = explicitModel.IndexSubranges[visual.ModelPartIndex]; var cache = explicitModel.CacheContainer.GetOrAddCache( Tuples.Pair(infra, explicitModel), x => new ExplicitModelCache(x.First, x.Second)); var glObjects = cache.GetGlObjects(); glContext.Bindings.VertexArray.Set(glObjects.Vao); var beginMode = GetBeginMode(explicitModel.Topology); if (glObjects.IndexBuffer == null) { glContext.Actions.Draw.Arrays(beginMode, modelPart.FirstIndex, modelPart.IndexCount); } else { var drawElementsType = glObjects.SixteenBitIndices ? DrawElementsType.UnsignedShort : DrawElementsType.UnsignedInt; var indexSize = glObjects.SixteenBitIndices ? sizeof(ushort) : sizeof(int); var indexBufferOffset = modelPart.FirstIndex * indexSize; glContext.Actions.Draw.Elements(beginMode, modelPart.IndexCount, drawElementsType, indexBufferOffset); } break; } default: throw new NotImplementedException(); } }