private void OnLoad(object sender, EventArgs e) { // initialize shader _program = ProgramFactory.Create<SkyboxProgram>(); // initialize cube shape _cube = new Cube(); _cube.UpdateBuffers(); // initialize vertex array and attributes _vao = new VertexArray(); _vao.Bind(); _vao.BindAttribute(_program.InPosition, _cube.VertexBuffer); _vao.BindElementBuffer(_cube.IndexBuffer); // create cubemap texture and load all faces for (var i = 0; i < 6; i++) { using (var bitmap = new Bitmap(string.Format("Data/Textures/city{0}.jpg", i))) { bitmap.RotateFlip(RotateFlipType.RotateNoneFlipX); if (_skybox == null) BitmapTexture.CreateCompatible(bitmap, out _skybox, 1); _skybox.LoadBitmap(bitmap, i); } } // activate shader and bind texture to it _program.Use(); _program.Texture.BindTexture(TextureUnit.Texture0, _skybox); // enable seamless filtering to reduce artifacts at the edges of the cube faces GL.Enable(EnableCap.TextureCubeMapSeamless); // cull front faces because we are inside the cube // this is not really necessary but removes some artifacts when the user leaves the cube // which should be impossible for a real skybox, but in this demonstration it is possible by zooming out GL.Enable(EnableCap.CullFace); GL.CullFace(CullFaceMode.Front); // set a nice clear color GL.ClearColor(Color.MidnightBlue); }
public SpriteRenderer(SpriteSheet spriteSheet) { SpriteSheet = spriteSheet; m_program = SpriteProgram.Instance; m_instances = new List<SpriteInstance>(); m_vao = new VertexArray(); GL.BindVertexArray(m_vao); m_bufferSprite = new Buffer<SpriteData>(); m_bufferQuad = new Buffer<Vector3>(); m_bufferQuad.SetData(new Vector3[] { new Vector3(0f, 0f, 0f), new Vector3(0f, 1f, 0f), new Vector3(1f, 1f, 0f), new Vector3(1f, 0f, 0f) }); GL.UseProgram(m_program); m_program.Position.SetValue(m_bufferQuad.GetView()); m_program.Transform.SetValue(m_bufferSprite.GetView<Matrix4>("Transform")); m_program.Transform.SetDivisor(1); m_program.TextureOrigin.SetValue(m_bufferSprite.GetView<Vector2>("TextureOrigin")); m_program.TextureOrigin.SetDivisor(1); m_program.TextureTarget.SetValue(m_bufferSprite.GetView<Vector2>("TextureTarget")); m_program.TextureTarget.SetDivisor(1); GL.BindVertexArray(null); m_isDirty = true; }
private void OnLoad(object sender, EventArgs e) { // initialize shader (load sources, create/compile/link shader program, error checking) // when using the factory method the shader sources are retrieved from the ShaderSourceAttributes _program = ProgramFactory.Create<ExampleProgram>(); // this program will be used all the time so just activate it once and for all _program.Use(); // create vertices for a triangle var vertices = new[] { new Vector3(-1,-1,0), new Vector3(1,-1,0), new Vector3(0,1,0) }; // create buffer object and upload vertex data _vbo = new Buffer<Vector3>(); _vbo.Init(BufferTarget.ArrayBuffer, vertices); // create and bind a vertex array _vao = new VertexArray(); _vao.Bind(); // set up binding of the shader variable to the buffer object _vao.BindAttribute(_program.InPosition, _vbo); // set camera position Camera.DefaultState.Position = new Vector3(0,0,3); Camera.ResetToDefault(); // set a nice clear color GL.ClearColor(Color.MidnightBlue); }
public SegmentRenderer() { m_program = TriangleProgram.Instance; m_instances = new List<SegmentInstance>(); m_vao = new VertexArray(); GL.BindVertexArray(m_vao); GL.UseProgram(m_program); m_bufferSprite = new Buffer<SegmentData>(); m_bufferTriangle = new Buffer<Vector3>(); m_program.Position.SetValue(m_bufferSprite.GetView<Vector3>("Position")); m_program.Color.SetValue(m_bufferSprite.GetView<Color4ub>("Color")); //m_program.Position.SetDivisor(1); // m_program.Normal.SetValue(m_bufferSprite.GetView<Vector3>("Normal")); //// m_program.Normal.SetDivisor(1); // m_program.Transform.SetValue(m_bufferSprite.GetView<Matrix4>("Transform")); // //m_program.Transform.SetDivisor(1); // m_program.TextureOrigin.SetValue(m_bufferSprite.GetView<Vector2>("TextureOrigin")); // //m_program.TextureOrigin.SetDivisor(1); // m_program.TextureTarget.SetValue(m_bufferSprite.GetView<Vector2>("TextureTarget")); //m_program.TextureTarget.SetDivisor(1); GL.BindVertexArray(null); m_isDirty = true; }
private void OnLoad(object sender, EventArgs e) { // initialize and bind framebuffer _framebuffer = new Framebuffer(); _framebuffer.Bind(FramebufferTarget.Framebuffer); // initialize a renderbuffer and bind it to the depth attachment // to support depth testing while rendering to the texture _depthBuffer = new Renderbuffer(); _depthBuffer.Init(RenderbufferStorage.DepthComponent, FramebufferWidth, FramebufferHeight); _framebuffer.Attach(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, _depthBuffer); // initialize texture and bind it to the color attachment _texture = new Texture2D(SizedInternalFormat.Rgba8, FramebufferWidth, FramebufferHeight, 1); _framebuffer.Attach(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, _texture); Framebuffer.Unbind(FramebufferTarget.Framebuffer); // initialize demonstration geometry _cube = new ColorCube(); _cube.UpdateBuffers(); _quad = new TexturedQuad(); _quad.UpdateBuffers(); // initialize shaders _colorProgram = ProgramFactory.Create<SimpleColorProgram>(); _textureProgram = ProgramFactory.Create<SimpleTextureProgram>(); // set up vertex attributes for the cube _cubeVao = new VertexArray(); _cubeVao.Bind(); _cubeVao.BindAttribute(_colorProgram.InPosition, _cube.VertexBuffer); _cubeVao.BindAttribute(_colorProgram.InColor, _cube.ColorBuffer); _cubeVao.BindElementBuffer(_cube.IndexBuffer); // set up vertex attributes for the quad _quadVao = new VertexArray(); _quadVao.Bind(); _quadVao.BindAttribute(_textureProgram.InPosition, _quad.VertexBuffer); _quadVao.BindAttribute(_textureProgram.InTexCoord, _quad.TexCoordBuffer); // set camera position Camera.DefaultState.Position = new Vector3(0,0,3); Camera.ResetToDefault(); // enable depth testing GL.Enable(EnableCap.DepthTest); }
public Graphics(int queueCapacity = 1000) { m_queueCapacity = queueCapacity; m_queue = new QuadData[m_queueCapacity]; m_textureQueue = new Texture2D[TEXTURE_QUEUE_CAPACITY]; m_transformStack = new Stack<Matrix3x2>(); m_verticesBuffer = new Buffer<Vector2>(); m_verticesBuffer.SetData(new Vector2[] { new Vector2(0,0), new Vector2(0,1), new Vector2(1,1), new Vector2(1,0) }); m_quadsBuffer = new Buffer<QuadData>(); m_quadsBuffer.SetData(m_queueCapacity, GL.STREAM_DRAW); m_program = QuadProgram.Instance; m_vertexArray = new VertexArray(); GL.UseProgram(m_program); GL.BindVertexArray(m_vertexArray); m_program.Vertex.SetValue(m_verticesBuffer.GetView()); m_program.TextureCoordinates0.SetValue(m_quadsBuffer.GetView<Vector2>("TextureCoordinates0")); m_program.TextureCoordinates0.SetDivisor(1); m_program.TextureCoordinates1.SetValue(m_quadsBuffer.GetView<Vector2>("TextureCoordinates1")); m_program.TextureCoordinates1.SetDivisor(1); m_program.Transform.SetValue(m_quadsBuffer.GetView<Matrix3x2>("Transform")); m_program.Transform.SetDivisor(1); m_program.Color.SetValue(m_quadsBuffer.GetView<Color4ub>("Color")); m_program.Color.SetDivisor(1); m_program.Texture.SetValue(m_quadsBuffer.GetView<int>("Texture")); m_program.Texture.SetDivisor(1); GL.BindVertexArray(null); Clear(); }
public Renderer(TriangleProgram program) { m_program = program; m_datas = new List<RendererData>(); m_vao = new VertexArray(); GL.BindVertexArray(m_vao); m_buffer = new Buffer<RendererData>(); GL.UseProgram(m_program); m_program.Position.SetValue(m_buffer.GetView(s => s.Position)); m_program.Color.SetValue(m_buffer.GetView(s => s.Color)); m_program.TextureCoordinates.SetValue(m_buffer.GetView(s => s.TextureCoordinates)); GL.BindVertexArray(null); }
protected override void OnLoad(EventArgs e) { // Create and fill a vertex buffer this.vertexBuffer = new VertexBuffer<ColoredVertex>(ColoredVertex.Size); this.vertexBuffer.AddVertex(new ColoredVertex(new Vector3(-1, -1, -1.5f), Color4.Lime)); this.vertexBuffer.AddVertex(new ColoredVertex(new Vector3(1, 1, -1.5f), Color4.Red)); this.vertexBuffer.AddVertex(new ColoredVertex(new Vector3(1, -1, -1.5f), Color4.Blue)); // Load shaders string fscode, vscode; var assembly = Assembly.GetExecutingAssembly(); var fsresourceName = "VoxWorld.Shaders.fragment-shader.fs"; var vsresourceName = "VoxWorld.Shaders.vertex-shader.vs"; using (Stream stream = assembly.GetManifestResourceStream(fsresourceName)) using (StreamReader reader = new StreamReader(stream)) fscode = reader.ReadToEnd(); using (Stream stream = assembly.GetManifestResourceStream(vsresourceName)) using (StreamReader reader = new StreamReader(stream)) vscode = reader.ReadToEnd(); var vertexShader = new Shader(ShaderType.VertexShader, vscode); var fragmentShader = new Shader(ShaderType.FragmentShader, fscode); // Link shaders into shader program this.shaderProgram = new ShaderProgram(vertexShader, fragmentShader); // Create vertex array to specify vertex layout this.vertexArray = new VertexArray<ColoredVertex>( this.vertexBuffer, this.shaderProgram, new VertexAttribute("vPosition", 3, VertexAttribPointerType.Float, ColoredVertex.Size, 0), new VertexAttribute("vColor", 4, VertexAttribPointerType.Float, ColoredVertex.Size, 12) ); // Create projection matrix uniform this.projectionMatrix = new Matrix4Uniform("projectionMatrix"); this.projectionMatrix.Matrix = Matrix4.CreatePerspectiveFieldOfView( MathHelper.PiOver2, 16f / 9, 0.1f, 100f); }
public SpriteRenderer(SpriteSheet spriteSheet) { SpriteSheet = spriteSheet; textureFire = Texture2D.Load(typeof(Particle).Assembly.GetManifestResourceStream("Granite.Particle.Textures.fire_color.png")); m_program = SpriteProgram.Instance; m_instances = new List<SpriteInstance>(); m_vao = new VertexArray(); GL.BindVertexArray(m_vao); m_bufferSprite = new Buffer<SpriteData>(); m_bufferQuad = new Buffer<Vector3>(); m_bufferQuad.SetData(new Vector3[] { new Vector3(0f, 0f, 0f), new Vector3(0f, 1f, 0f), new Vector3(1f, 1f, 0f), new Vector3(1f, 0f, 0f) }); GL.UseProgram(m_program); m_program.Position.SetValue(m_bufferQuad.GetView()); //m_program.Color.SetValue(m_bufferSprite.GetView(s => s.Color)); //m_program.Color.SetDivisor(1); m_program.Transform.SetValue(m_bufferSprite.GetView<Matrix4>("Transform")); m_program.Transform.SetDivisor(1); m_program.TextureOrigin.SetValue(m_bufferSprite.GetView<Vector2>("TextureOrigin")); m_program.TextureOrigin.SetDivisor(1); m_program.TextureTarget.SetValue(m_bufferSprite.GetView<Vector2>("TextureTarget")); m_program.TextureTarget.SetDivisor(1); m_program.Progress.SetValue(m_bufferSprite.GetView(s => s.Progress)); m_program.Progress.SetDivisor(1); GL.BindVertexArray(null); m_isDirty = true; }
protected void OnLoad(object sender, EventArgs e) { // load textures into array for (var i = 0; i < _stateTextures.Length; i++) { using (var bitmap = new Bitmap(Path.Combine("Data/Textures/", _stateTextures[i]))) { bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY); if (_textureArray == null) BitmapTexture.CreateCompatible(bitmap, out _textureArray, _stateTextures.Length, 1); _textureArray.LoadBitmap(bitmap, i); } } // initialize buffer var field = new Minefield[FieldWidth*FieldHeight]; for (var i = 0; i < field.Length; i++) { field[i] = new Minefield(i%FieldWidth, i/FieldHeight, i%_stateTextures.Length); } _buffer = new Buffer<Minefield>(); _buffer.Init(BufferTarget.ArrayBuffer, field); // load program _gridProgram = ProgramFactory.Create<TextureGridProgram>(); _gridProgram.Use(); // bind the texture and set uniform _gridProgram.TextureData.BindTexture(TextureUnit.Texture0, _textureArray); // set up vertex array and attributes _vao = new VertexArray(); _vao.Bind(); _vao.BindAttribute(_gridProgram.InPosition, _buffer); _vao.BindAttribute(_gridProgram.InTexture, _buffer, 8); // set nice clear color GL.ClearColor(Color.MidnightBlue); // initialize camera position Camera.DefaultState.Position = new Vector3(0, 5, 15); Camera.ResetToDefault(); }
public static void BindVertexArray(VertexArray vertexArray) { BindVertexArray(vertexArray == null ? 0 : vertexArray.Name); }
private void OnLoad(object sender, EventArgs e) { // initialize shader (load sources, create/compile/link shader program, error checking) // when using the factory method the shader sources are retrieved from the ShaderSourceAttributes _program = ProgramFactory.Create<GravityProgram>(); // this program will be used all the time so just activate it once and for all _program.Use(); // create and bind a vertex array _vao = new VertexArray(); _vao.Bind(); // create and bind transform feedback object _feedback = new TransformFeedback(); _feedback.Bind(); // Writing to a buffer while reading from it is not allowed // so we need two buffer objects here, which can be achieved by using the BufferPod<T> type. // It contains two buffers, Ping and Pong, to simplify this process. _buffers = new BufferPod<Particle>(); InitializeParticles(_particleCount); // enable point sprite rendering GL.Enable(EnableCap.PointSprite); // enable modification of the point sprite size from the program (vertex shader in this case) GL.Enable(EnableCap.ProgramPointSize); // enable depth testing GL.Enable(EnableCap.DepthTest); // set a nice clear color GL.ClearColor(Color.Black); // set a nice camera angle Camera.DefaultState.Position = new Vector3(0,2,-8); Camera.ResetToDefault(); }
public DrawState(RenderState renderState, ShaderProgram shaderProgram, VertexArray vertexArray) { RenderState = renderState; ShaderProgram = shaderProgram; VertexArray = vertexArray; }
private void ApplyVertexArray(VertexArray vertexArray) { VertexArrayGL3x vertexArrayGL3x = (VertexArrayGL3x)vertexArray; vertexArrayGL3x.Bind(); vertexArrayGL3x.Clean(); }
public static void Append(this VertexArray vertices, float x, float y, Color color, float tx, float ty) { vertices.Append(new Vertex(new Vector2f(x, y), color.SFMLColor, new Vector2f(tx, ty))); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { if (relocsOnly) { return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, Array.Empty <ISymbolDefinitionNode>())); } ReadyToRunCodegenNodeFactory r2rFactory = (ReadyToRunCodegenNodeFactory)factory; List <EntryPoint> ridToEntryPoint = new List <EntryPoint>(); foreach (MethodWithGCInfo method in r2rFactory.EnumerateCompiledMethods()) { if (method.Method is EcmaMethod ecmaMethod) { // Strip away the token type bits, keep just the low 24 bits RID uint rid = SignatureBuilder.RidFromToken((mdToken)MetadataTokens.GetToken(ecmaMethod.Handle)); Debug.Assert(rid != 0); rid--; while (ridToEntryPoint.Count <= rid) { ridToEntryPoint.Add(EntryPoint.Null); } int methodIndex = r2rFactory.RuntimeFunctionsTable.GetIndex(method); ridToEntryPoint[(int)rid] = new EntryPoint(methodIndex, method); } } NativeWriter writer = new NativeWriter(); Section arraySection = writer.NewSection(); VertexArray vertexArray = new VertexArray(arraySection); arraySection.Place(vertexArray); Section fixupSection = writer.NewSection(); Dictionary <byte[], BlobVertex> uniqueFixups = new Dictionary <byte[], BlobVertex>(ByteArrayComparer.Instance); for (int rid = 0; rid < ridToEntryPoint.Count; rid++) { EntryPoint entryPoint = ridToEntryPoint[rid]; if (!entryPoint.IsNull) { byte[] fixups = entryPoint.Method.GetFixupBlob(factory); BlobVertex fixupBlobVertex = null; if (fixups != null && !uniqueFixups.TryGetValue(fixups, out fixupBlobVertex)) { fixupBlobVertex = new BlobVertex(fixups); fixupSection.Place(fixupBlobVertex); uniqueFixups.Add(fixups, fixupBlobVertex); } EntryPointVertex entryPointVertex = new EntryPointVertex((uint)entryPoint.MethodIndex, fixupBlobVertex); vertexArray.Set(rid, entryPointVertex); } } vertexArray.ExpandLayout(); MemoryStream arrayContent = new MemoryStream(); writer.Save(arrayContent); return(new ObjectData( data: arrayContent.ToArray(), relocs: null, alignment: 8, definedSymbols: new ISymbolDefinitionNode[] { this })); }
private void OnLoad(object sender, EventArgs e) { // load texture from file using (var bitmap = new Bitmap("Data/Textures/checker.jpg")) { BitmapTexture.CreateCompatible(bitmap, out _texture); _texture.LoadBitmap(bitmap); } _texture.GenerateMipMaps(); // initialize sampler _sampler = new Sampler(); _sampler.SetWrapMode(TextureWrapMode.Repeat); // create vertex data for a big plane const int a = 10; const int b = 10; var vertices = new[] { new Vertex(-a, 0,-a, 0, 0), new Vertex( a, 0,-a, b, 0), new Vertex(-a, 0, a, 0, b), new Vertex( a, 0, a, b, b) }; // create buffer object and upload vertex data _vbo = new Buffer<Vertex>(); _vbo.Init(BufferTarget.ArrayBuffer, vertices); // initialize shader _program = ProgramFactory.Create<SimpleTextureProgram>(); // activate shader program _program.Use(); // bind sampler _sampler.Bind(TextureUnit.Texture0); // bind texture _program.Texture.BindTexture(TextureUnit.Texture0, _texture); // which is equivalent to //_program.Texture.Set(TextureUnit.Texture0); //_texture.Bind(TextureUnit.Texture0); // set up vertex array and attributes _vao = new VertexArray(); _vao.Bind(); // memory layout of our data is XYZUVXYZUV... // the buffer abstraction knows the total size of one "pack" of vertex data // and if a vertex attribute is bound without further arguments the first N elements are taken from each pack // where N is provided via the VertexAttribAttribute on the program property: _vao.BindAttribute(_program.InPosition, _vbo); // if data should not be taken from the start of each pack, the offset must be given in bytes // to reach the texture coordinates UV the XYZ coordinates must be skipped, that is 3 floats, i.e. an offset of 12 bytes is needed _vao.BindAttribute(_program.InTexCoord, _vbo, 12); // if needed all the available arguments can be specified manually, e.g. //_vao.BindAttribute(_program.InTexCoord, _vbo, 2, VertexAttribPointerType.Float, Marshal.SizeOf(typeof(Vertex)), 12, false); // set default camera Camera.DefaultState.Position = new Vector3(0, 0.5f, 3); Camera.ResetToDefault(); // set a nice clear color GL.ClearColor(Color.MidnightBlue); }
public MeshPartData(ModelMesh mesh) { ModelMeshPart part; IndexElementSize IndexSize = mesh.MeshParts[0].IndexBuffer.IndexElementSize; Indices = new IndexArray[mesh.MeshParts.Count]; Vertices = new VertexArray[mesh.MeshParts.Count]; // apparently the index data comes in 16 or 32 bit format if (IndexSize == IndexElementSize.SixteenBits) { for (int j = 0; j < mesh.MeshParts.Count; j++) { part = mesh.MeshParts[j]; Indices[j] = new IndexArrayShort(part); Vertices[j] = new VertexArray(part); } } else if (IndexSize == IndexElementSize.ThirtyTwoBits) { for (int j = 0; j < mesh.MeshParts.Count; j++) { part = mesh.MeshParts[j]; Indices[j] = new IndexArrayInt(part); Vertices[j] = new VertexArray(part); } } }
void Append(VertexArray v, float x, float y, float tx, float ty) { v.Append(new Vertex(new Vector2f(x, y), new Vector2f(tx, ty))); }
public int Start(params string[] args) { #if UNSAFE Console.WriteLine("Usafe are enabled"); #else Console.WriteLine("Usafe are disabled"); #endif #region Something if (this != singleton) { return(-1); } fov = MathF.PI / 3; string title = "CSGL Window"; width = 1600; height = 900; //glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); // Change this to your targeted major version //glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5); // Change this to your targeted minor version if (args.Length > 0) { title = args[0]; } window = new Window(width, height, title, monitor: IntPtr.Zero, share: IntPtr.Zero); glClearColor(0.125f, 0.125f, 0.125f, 1); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); #endregion #region Matrix Init Matrix4x4 model = Matrix4x4.Identity; view = Matrix4x4.CreateTranslation(0, 0, -2); world = Matrix4x4.CreatePerspectiveFieldOfView(fov, width / (float)height, 0.125f, 1024f); matrixStack = new Stack <Matrix4x4>(); matrixStack.Push(Matrix4x4.Identity); ChangeFov(fov); #endregion #region File Checking string vertPath = @"resources/shaders/shader.vert"; string fragPath = @"resources/shaders/shader.frag"; if (!File.Exists(vertPath) || !File.Exists(fragPath)) { Console.WriteLine("Cannot read shader files"); return(-1); } string vert = File.ReadAllText(vertPath); string frag = File.ReadAllText(fragPath); string texPath = @"resources/textures/colorgrid512.bmp"; if (!File.Exists(texPath)) { Console.WriteLine("Cannot read texture file"); return(-1); } #endregion #region Shader and polygon init var program = new ShaderProgram(vert, frag); program.Bind(); var vao = new VertexArray(); vao.Bind(); const float z = 0.0625f; int length; { var vertexList = new List <Vertex>() { new Vertex(0, 1, z, 0, 0, 1, 0.5f, 1), new Vertex(-t, 0.25f, z, 0, 0, 1, 0.5f - t * 0.5f, 0.625f), new Vertex(t, 0.25f, z, 0, 0, 1, 0.5f + t * 0.5f, 0.625f), new Vertex(-s, -0.5f, z, 0, 0, 1, 0.5f - t, 0.25f), new Vertex(0, -0.5f, z, 0, 0, 1, 0.5f, 0.25f), new Vertex(s, -0.5f, z, 0, 0, 1, 0.5f + t, 0.25f), new Vertex(0, 1, -z, 0, 0, -1, 0.5f, 1), new Vertex(t, 0.25f, -z, 0, 0, -1, 0.5f - t * 0.5f, 0.625f), new Vertex(-t, 0.25f, -z, 0, 0, -1, 0.5f + t * 0.5f, 0.625f), new Vertex(s, -0.5f, -z, 0, 0, -1, 0.5f - t, 0.25f), new Vertex(0, -0.5f, -z, 0, 0, -1, 0.5f, 0.25f), new Vertex(-s, -0.5f, -z, 0, 0, -1, 0.5f + t, 0.25f), new Vertex(-s, -0.5f, -z, -0.5f, s, 0, 0, 0), new Vertex(-s, -0.5f, z, -0.5f, s, 0, z, 0), new Vertex(0, 1, z, -0.5f, s, 0, z, s), new Vertex(0, 1, -z, -0.5f, s, 0, 0, s), new Vertex(s, -0.5f, z, 0.5f, s, 0, 0, 0), new Vertex(s, -0.5f, -z, 0.5f, s, 0, z, 0), new Vertex(0, 1, -z, 0.5f, s, 0, z, s), new Vertex(0, 1, z, 0.5f, s, 0, 0, s), new Vertex(-s, -0.5f, z, 0, -1, 0, 0, 0), new Vertex(-s, -0.5f, -z, 0, -1, 0, z, 0), new Vertex(s, -0.5f, -z, 0, -1, 0, z, s), new Vertex(s, -0.5f, z, 0, -1, 0, 0, s), new Vertex(-t, 0.25f, z, 0, -1, 0, 0, 0), new Vertex(-t, 0.25f, -z, 0, -1, 0, z, 0), new Vertex(t, 0.25f, -z, 0, -1, 0, z, t), new Vertex(t, 0.25f, z, 0, -1, 0, 0, t), new Vertex(0, -0.5f, z, 0.5f, s, 0, 0, 0), new Vertex(0, -0.5f, -z, 0.5f, s, 0, z, 0), new Vertex(-t, 0.25f, -z, 0.5f, s, 0, z, t), new Vertex(-t, 0.25f, z, 0.5f, s, 0, 0, t), new Vertex(0, -0.5f, -z, -0.5f, s, 0, 0, 0), new Vertex(0, -0.5f, z, -0.5f, s, 0, z, 0), new Vertex(t, 0.25f, z, -0.5f, s, 0, z, t), new Vertex(t, 0.25f, -z, -0.5f, s, 0, 0, t), }; int[] indices = { 0, 1, 2, 1, 3, 4, 2, 4, 5, 6, 7, 8, 7, 9, 10, 8, 10, 11, 12, 13, 14, 14, 15, 12, 16, 17, 18, 18, 19, 16, 20, 21, 22, 22, 23, 20, 24, 25, 26, 26, 27, 24, 28, 29, 30, 30, 31, 28, 32, 33, 34, 34, 35, 32, }; length = indices.Length; var interleaved = new StaticInterleavedVertexBuffer(vertexList); uint positionLocation = program.GetLocation("inPosition"); uint normalLocation = program.GetLocation("inNormal"); uint texLocation = program.GetLocation("inTexCoord"); glEnableVertexAttribArray(positionLocation); glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, Vertex.SIZE_BYTES, NULL); glEnableVertexAttribArray(normalLocation); glVertexAttribPointer(normalLocation, 3, GL_FLOAT, GL_FALSE, Vertex.SIZE_BYTES, new IntPtr(3 * sizeof(float))); glEnableVertexAttribArray(texLocation); glVertexAttribPointer(texLocation, 2, GL_FLOAT, GL_FALSE, Vertex.SIZE_BYTES, new IntPtr(6 * sizeof(float))); StaticElementArrayBuffer indexBuffer = new StaticElementArrayBuffer(indices); uint ubo_location = program.GetLocation("UniformBufferObject"); glUniformBlockBinding(program.Id, ubo_location, 0); uint ubo = 0; glGenBuffers(1, ref ubo); glBindBuffer(GL_UNIFORM_BUFFER, ubo); glBufferData(GL_UNIFORM_BUFFER, 48 * sizeof(float), NULL, GL_DYNAMIC_DRAW); glBindBufferRange(GL_UNIFORM_BUFFER, 0, ubo, 0, 48 * sizeof(float)); glfwSetWindowSizeCallback(window.Id, (IntPtr _, int w, int h) => singleton.ResizeWindow(w, h)); unsafe { Matrix4x4 world = this.world; Matrix4x4 view = this.view; Matrix4x4 matrixTop = model * matrixStack.Peek(); glBufferSubData(GL_UNIFORM_BUFFER, 0 * sizeof(float), 16 * sizeof(float), new IntPtr(&matrixTop.M11)); glBufferSubData(GL_UNIFORM_BUFFER, 16 * sizeof(float), 16 * sizeof(float), new IntPtr(&view.M11)); glBufferSubData(GL_UNIFORM_BUFFER, 32 * sizeof(float), 16 * sizeof(float), new IntPtr(&world.M11)); } var texture = new Texture(texPath); if (texture.Data == null) { return(-1); } } #endregion glfwSwapInterval(1); glLoadIdentity(); glTranslatef(0, 0, 0.96875f); glScalef(height / (float)width, 1, 1); glColor3b(0, 0x22, 0x11); var speed = ((1 / 3.0f) / MathF.PI); var timer = Stopwatch.StartNew(); Console.WriteLine($"High Resolution Stopwatch: {Stopwatch.IsHighResolution}"); while (glfwWindowShouldClose(window.Id) == 0) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); var deltaTime = (float)timer.Elapsed.TotalSeconds; timer.Restart(); //model *= Matrix4x4.CreateRotationX(deltaTime); model *= Matrix4x4.CreateRotationY(speed * deltaTime); //model *= Matrix4x4.CreateRotationZ(deltaTime); //matrix4x4 matrixtop = model * matrixstack.peek(); #region Fallback Triangle program.Unbind(); glBegin(GL_TRIANGLES); glVertex3f(0, 1, 0); glVertex3f(-s, -0.5f, 0); glVertex3f(s, -0.5f, 0); glEnd(); #endregion program.Bind(); unsafe { glBufferSubData(GL_UNIFORM_BUFFER, 0 * sizeof(float), 16 * sizeof(float), new IntPtr(&model.M11)); } glDrawElements(GL_TRIANGLES, length, GL_UNSIGNED_INT, NULL); glfwSwapBuffers(window.Id); glfwPollEvents(); } glfwTerminate(); return(0); }
public GridRenderable(Document document) { _program = new ShaderProgram( new Shader(ShaderType.VertexShader, VertexShader), new Shader(ShaderType.FragmentShader, FragmentShader)); _document = document; _step = -1; _buffer = new VertexBuffer<float>(Specification, Modes, 0, sizeof(float), new float[0], new[] { new uint[0] }); _array = new VertexArray<float>(_buffer); RebuildGrid(1); }
public Presenter(Context glContext) { this.glContext = glContext; glPipeline = glContext.Pipeline; sourceFramebuffer = new Framebuffer(glContext); destinationFramebuffer = new Framebuffer(glContext); vertices = new Buffer(glContext, BufferTarget.ArrayBuffer, 4 * 8 * sizeof(float), BufferUsageHint.StaticDraw, new Data(new[] { new Vertex(-1f, -1f), new Vertex(-1f, 1f), new Vertex(1f, 1f), new Vertex(1f, -1f) })); indices = new Buffer(glContext, BufferTarget.ElementArrayBuffer, 6 * sizeof(ushort), BufferUsageHint.StaticDraw, new Data(new ushort[] { 0, 1, 2, 0, 2, 3 })); sampler = new Sampler(); sampler.SetMagFilter(TextureMagFilter.Nearest); sampler.SetMinFilter(TextureMinFilter.Nearest); string shaderErrors; if (!VertexShader.TryCompile(VertexShaderText, out vertexShader, out shaderErrors) || !FragmentShader.TryCompile(FragmentShaderText, out fragmentShader, out shaderErrors) || !ShaderProgram.TryLink(glContext, new ShaderProgramDescription { VertexShaders = vertexShader, FragmentShaders = fragmentShader, VertexAttributeNames = new[] { "in_position" }, SamplerNames = new[] { "Image" } }, out program, out shaderErrors)) throw new ArgumentException("Program errors:\n\n" + shaderErrors); vertexArray = new VertexArray(glContext); vertexArray.SetElementArrayBuffer(glContext, indices); vertexArray.SetVertexAttributeF(glContext, 0, vertices, VertexAttributeDimension.Two, VertexAttribPointerType.Float, false, 8, 0); }
protected void OnLoad(object sender, EventArgs eventArgs) { VSync = VSyncMode.Off; // Check for necessary capabilities: var extensions = GL.GetString(StringName.Extensions); if (!GL.GetString(StringName.Extensions).Contains("GL_ARB_shading_language")) { throw new NotSupportedException(String.Format("This example requires OpenGL 2.0. Found {0}. Aborting.", GL.GetString(StringName.Version).Substring(0, 3))); } if (!extensions.Contains("GL_ARB_texture_compression") || !extensions.Contains("GL_EXT_texture_compression_s3tc")) { throw new NotSupportedException("This example requires support for texture compression. Aborting."); } var temp = new int[1]; GL.GetInteger(GetPName.MaxTextureImageUnits, out temp[0]); Trace.WriteLine(temp[0] + " TMU's for Fragment Shaders found. (2 required)"); GL.GetInteger(GetPName.MaxVaryingFloats, out temp[0]); Trace.WriteLine(temp[0] + " varying floats between VS and FS allowed. (6 required)"); GL.GetInteger(GetPName.MaxVertexUniformComponents, out temp[0]); Trace.WriteLine(temp[0] + " uniform components allowed in Vertex Shader. (6 required)"); GL.GetInteger(GetPName.MaxFragmentUniformComponents, out temp[0]); Trace.WriteLine(temp[0] + " uniform components allowed in Fragment Shader. (11 required)"); Trace.WriteLine(""); // load textures TextureLoaderParameters.MagnificationFilter = TextureMagFilter.Linear; TextureLoaderParameters.MinificationFilter = TextureMinFilter.LinearMipmapLinear; TextureLoaderParameters.WrapModeS = TextureWrapMode.ClampToBorder; TextureLoaderParameters.WrapModeT = TextureWrapMode.ClampToBorder; TextureLoaderParameters.EnvMode = TextureEnvMode.Modulate; uint handle; TextureTarget target; ImageDDS.LoadFromDisk(TextureDiffuseHeightFilename, out handle, out target); _textureDiffuseHeight = TextureFactory.AquireTexture2D((int) handle); Trace.WriteLine("Loaded " + TextureDiffuseHeightFilename + " with handle " + handle + " as " + target); ImageDDS.LoadFromDisk(TextureNormalGlossFilename, out handle, out target); _textureNormalGloss = TextureFactory.AquireTexture2D((int) handle); Trace.WriteLine("Loaded " + TextureNormalGlossFilename + " with handle " + handle + " as " + target); Trace.WriteLine("End of Texture Loading. GL Error: " + GL.GetError()); Trace.WriteLine(""); // initialize buffer var normal = Vector3.UnitZ; var tangent = Vector3.UnitX; var vertices = new[] { new Vertex { Position = new Vector3(-1,-1,0), TexCoord = new Vector2(0,0), Normal = normal, Tangent = tangent }, new Vertex { Position = new Vector3(1,-1,0), TexCoord = new Vector2(1,0), Normal = normal, Tangent = tangent }, new Vertex { Position = new Vector3(-1,1,0), TexCoord = new Vector2(0,1), Normal = normal, Tangent = tangent }, new Vertex { Position = new Vector3(1,1,0), TexCoord = new Vector2(1,1), Normal = normal, Tangent = tangent } }; _buffer = new Buffer<Vertex>(); _buffer.Init(BufferTarget.ArrayBuffer, vertices); // load shader _program = ProgramFactory.Create<ParallaxProgram>(); _program.Use(); // set up vertex array _vao = new VertexArray(); _vao.Bind(); // bind vertex attributes // the buffer layout is defined by the Vertex struct: // data X Y Z NX NY NZ TX TY TZ U V *next vertex* // offset 0 4 8 12 16 20 24 28 32 36 40 44 // having to work with offsets could be prevented by using seperate buffer objects for each attribute, // but that might reduce performance and can get annoying as well. // performance increase could also be achieved by improving coherent read access // by padding the struct so that each attribute begins at a multiple of 16 bytes, i.e. 4-floats // because the GPU can then read all 4 floats at once. I did not do that here to keep it simple. _vao.BindAttribute(_program.InPosition, _buffer); _vao.BindAttribute(_program.InNormal, _buffer, 12); _vao.BindAttribute(_program.InTangent, _buffer, 24); _vao.BindAttribute(_program.InTexCoord, _buffer, 36); // set camera position Camera.DefaultState.Position = new Vector3(0,0,3); Camera.ResetToDefault(); // set state GL.ClearColor(0.2f, 0f, 0.4f, 0f); GL.PointSize(10f); GL.Disable(EnableCap.Dither); GL.FrontFace(FrontFaceDirection.Ccw); GL.PolygonMode(MaterialFace.Front, PolygonMode.Fill); GL.PolygonMode(MaterialFace.Back, PolygonMode.Line); }
protected override void UpdateDrawable() { var minWidth = sliceX1 + tWidth - sliceX2; panelScaleX = (float)Width / (float)minWidth; if (panelScaleX > 1) { panelScaleX = 1; } var minHeight = sliceY1 + tHeight - sliceY2; panelScaleY = (float)Height / (float)minHeight; if (panelScaleY > 1) { panelScaleY = 1; } var v = new VertexArray(PrimitiveType.Quads); int x0, x1, x2, x3, y0, y1, y2, y3; int u0, u1, u2, u3, v0, v1, v2, v3; x0 = 0; y0 = 0; x1 = sliceX1; y1 = sliceY1; x2 = Width - (tWidth - sliceX2); y2 = Height - (tHeight - sliceY2); x3 = Width; y3 = Height; u0 = TextureLeft; v0 = TextureTop; u1 = TextureLeft + sliceX1; v1 = TextureTop + sliceY1; u2 = TextureLeft + sliceX2; v2 = TextureTop + sliceY2; u3 = TextureLeft + tWidth; v3 = TextureTop + tHeight; if (panelScaleX < 1) { x1 = (int)Math.Round(x1 * panelScaleX); x2 = x1; } if (panelScaleY < 1) { y1 = (int)Math.Round(y1 * panelScaleY); y2 = y1; } int tileX = sliceX2 - sliceX1; int tileY = sliceY2 - sliceY1; if (PanelType == PanelType.Stretch) { //top DrawQuad(v, x1, y0, x2, y1, u1, v0, u2, v1); //left DrawQuad(v, x0, y1, x1, y2, u0, v1, u1, v2); //right DrawQuad(v, x2, y1, x3, y2, u2, v1, u3, v2); //bottom DrawQuad(v, x1, y2, x2, y3, u1, v2, u2, v3); //middle DrawQuad(v, x1, y1, x2, y2, u1, v1, u2, v2); } else { for (int xx = x1; xx < x2; xx += tileX) { for (int yy = y1; yy < y2; yy += tileY) { //middle DrawQuad(v, xx, yy, xx + tileX, yy + tileY, u1, v1, u2, v2); } } for (int yy = y1; yy < y2; yy += tileY) { //left DrawQuad(v, x0, yy, x1, yy + tileY, u0, v1, u1, v2); //right DrawQuad(v, x2, yy, x3, yy + tileY, u2, v1, u3, v2); } for (int xx = x1; xx < x2; xx += tileX) { //top DrawQuad(v, xx, y0, xx + tileX, y1, u1, v0, u2, v1); //bottom DrawQuad(v, xx, y2, xx + tileX, y3, u1, v2, u2, v3); } } //top left DrawQuad(v, x0, y0, x1, y1, u0, v0, u1, v1); //top right DrawQuad(v, x2, y0, x3, y1, u2, v0, u3, v1); //bottom left DrawQuad(v, x0, y2, x1, y3, u0, v2, u1, v3); //bottom right DrawQuad(v, x2, y2, x3, y3, u2, v2, u3, v3); SFMLVertices = v; }
public void Dispose() { VertexArray.Dispose(); ElementArray.Dispose(); }
/// <summary> /// Link an array buffer to an attribute of this vertex array. /// </summary> /// <param name="arrayBuffer"> /// A <see cref="ArrayBufferObjectBase"/> that specify the contents of the array. /// </param> /// <param name="sectionIndex"> /// A <see cref="UInt32"/> that specify the <paramref name="arrayBuffer"/> sub-array index. /// </param> /// <param name="attributeName"> /// A <see cref="String"/> that specify the name of the attribute variable. /// </param> /// <param name="blockName"> /// A <see cref="String"/> that specify the name of the attribute block encolosing <paramref name="semantic"/>. It /// can be null. /// </param> /// <exception cref="ArgumentNullException"> /// Exception thrown if <paramref name="arrayBuffer"/> is null. /// </exception> /// <exception cref="ArgumentException"> /// Exception throw if <paramref name="arrayBuffer"/> has no items. /// </exception> /// <exception cref="ArgumentException"> /// Exception thrown if <paramref name="sectionIndex"/> specify an invalid section of <paramref name="arrayBuffer"/>. /// </exception> /// <exception cref="ArgumentException"> /// Exception thrown if <paramref name="semantic"/> is null or is not a valid input name. /// </exception> public void SetArray(ArrayBufferObjectBase arrayBuffer, uint sectionIndex, string attributeName, string blockName) { if (String.IsNullOrEmpty(attributeName)) throw new ArgumentException("invalid name", "attributeName"); VertexArray vertexArray, previousVertexArray; // Dispose previous vertex array if (_VertexArrays.TryGetValue(attributeName, out previousVertexArray)) previousVertexArray.Dispose(); // Map buffer object with attribute name _VertexArrays[attributeName] = vertexArray = new VertexArray(arrayBuffer, sectionIndex); // Map buffer object with input name including block name also if (blockName != null) { // Attribute referenced in block attributeName = String.Format("{0}.{1}", blockName, attributeName); // Dispose previous vertex array if (_VertexArrays.TryGetValue(attributeName, out previousVertexArray)) previousVertexArray.Dispose(); // Map buffer object with attribute name _VertexArrays[attributeName] = vertexArray; } // Compute the actual vertex array length UpdateVertexArrayLength(); // Update vertex arrays _VertexArrayDirty = true; }
public WndAppearance(BaseObject obj, Vector2f pos) : base(obj, WndWidth, pos) { var wrapper = new ColorWrapper(() => obj.Color); var renderImg = new Image(WndWidth, SqSize + 2 * Margin, BackColor); var selector = new Canvas(); selector.SizeLayout = new Layout2d(renderImg.Size.X, renderImg.Size.Y); selector.Clear(BackColor); Add(selector); Color oldColor = default; IntPtr oldPointer = default; var userChanging = false; var previewRect = new VertexArray(PrimitiveType.Quads, 4); var previewOutline = new VertexArray(PrimitiveType.LineStrip, 5); Vector2f[] previewCorners = { new Vector2f(Margin + PreviewOffset, Margin), new Vector2f(Margin + PreviewOffset + PreviewWidth, Margin), new Vector2f(Margin + PreviewOffset + PreviewWidth, Margin + SqSize), new Vector2f(Margin + PreviewOffset, Margin + SqSize), }; var hueSelector = new RectangleShape(new Vector2f(HueWidth, 4)) { OutlineColor = SelectorOutline, OutlineThickness = 2f, FillColor = Color.Transparent, Origin = new Vector2f(HueWidth / 2, 2) }; var colorSelector = new RectangleShape(new Vector2f(8, 8)) { OutlineColor = SelectorOutline, OutlineThickness = 2f, FillColor = Color.Transparent, Origin = new Vector2f(4, 4) }; wrapper.ValueChanged += delegate { UpdateSelector(); }; void DrawSelector() { var tex = selector.RenderTexture(); if (tex == null) { return; } oldPointer = tex.CPointer; oldColor = wrapper.Value; const float fac = 1f / SqSize; selector.Clear(BackColor); for (uint y = 0; y < renderImg.Size.Y; y++) { for (uint x = 0; x < renderImg.Size.X; x++) { renderImg.SetPixel(x, y, BackColor); } } renderImg.Copy(HueImg, Margin, Margin); var hue = wrapper.H; for (uint y = 0; y < SqSize; y++) { var v = y * fac; for (uint x = 0; x < SqSize; x++) { var s = x * fac; renderImg.SetPixel(Margin + Offset + x, Margin + y, new Hsva(hue, s, 1 - v, 1)); } } tex.Texture.Update(renderImg); hueSelector.Position = new Vector2f( Margin + HueWidth / 2, Margin + (float)((360 - wrapper.H) / HueFac)); tex.Draw(hueSelector); colorSelector.Position = new Vector2f( (float)(Margin + Offset + wrapper.S * SqSize), (float)(Margin + wrapper.V * SqSize)); tex.Draw(colorSelector); var col = wrapper.Value; previewRect[0] = new Vertex(previewCorners[0], col); previewRect[1] = new Vertex(previewCorners[1], col); previewRect[2] = new Vertex(previewCorners[2], col); previewRect[3] = new Vertex(previewCorners[3], col); tex.Draw(previewRect); col.A = 255; previewOutline[0] = new Vertex(previewCorners[0], col); previewOutline[1] = new Vertex(previewCorners[1], col); previewOutline[2] = new Vertex(previewCorners[2], col); previewOutline[3] = new Vertex(previewCorners[3], col); previewOutline[4] = new Vertex(previewCorners[0], col); tex.Draw(previewOutline); } void UpdateSelector() { if (userChanging) { return; } if (Mouse.IsButtonPressed(Mouse.Button.Left)) { userChanging = true; var mpos = Mouse.GetPosition(Render.Window).F() - AbsolutePosition - new Vector2f(0, Renderer.TitleBarHeight); if (selector.MouseOnWidget(mpos)) { var(x, y) = (mpos - selector.Position).I(); x -= Margin; y -= Margin; if (x >= 0 && x <= TotalSize && y >= 0 && y < 140) { if (x <= HueWidth) { wrapper.H = y * HueFac; } else if (x >= Offset) { wrapper.Value = new Color(renderImg.GetPixel(Margin + (uint)x, Margin + (uint)y)) { A = wrapper.A } } ; } } userChanging = false; } if (wrapper.Value != oldColor || selector.RenderTexture()?.CPointer != oldPointer) { DrawSelector(); } } Ui.Drawn += UpdateSelector; Closed += delegate { Ui.Drawn -= UpdateSelector; }; Add(new NumberField <double>(0, 360, () => wrapper.H, unit: "°", inline: true, round: 0)); Add(new NumberField <double>(0, 100, () => wrapper.S, unit: "%", factor: 100, inline: true, round: 0)); Add(new NumberField <double>(0, 100, () => wrapper.V, unit: "%", factor: 100, inline: true, round: 0)); Add(new NumberField <double>(0, 100, () => wrapper.Ad, unit: "%", factor: 100, inline: true, round: 0)); Add(new NumberField <byte>(0, 255, () => wrapper.R, deci: false, inline: true)); Add(new NumberField <byte>(0, 255, () => wrapper.G, deci: false, inline: true)); Add(new NumberField <byte>(0, 255, () => wrapper.B, deci: false, inline: true)); var btnRandom = new BitmapButton(L["Random color"]) { Image = new Texture("icons/small/random.png") }; btnRandom.Clicked += delegate { wrapper.Value = new Color(Palette.Default.ColorRange.RandomColor()) { A = wrapper.A }; }; Add(btnRandom); if (obj is PhysicalObject phy) { Add(new NumberField <float>(30, 2000, () => phy.ColorFilterWidth, log: true) { RightValue = float.PositiveInfinity }); var absorbanceImg = new Image(WndWidth, AbsorbHeight + 2 * Margin, BackColor); var absorbance = new Canvas(); absorbance.SizeLayout = new Layout2d(absorbanceImg.Size.X, absorbanceImg.Size.Y); absorbance.Clear(BackColor); var txtA = new Text("A", Ui.FontMono, AbsorbTextSize) { FillColor = Color.White, Scale = new Vector2f(1, -1) }.CenterOriginText(); var txtH = new Text("H", Ui.FontMono, AbsorbTextSize) { FillColor = Color.White, Scale = new Vector2f(1, -1) }.CenterOriginText(); Add(absorbance); IntPtr oldPointerAbs = default; var oldCol = new Hsva(-1, -1, -1, -1); var oldWidth = -1f; void DrawAbsorbance() { var tex = absorbance.RenderTexture(); if (tex == null) { return; } oldCol = wrapper.ValueHsv; oldWidth = phy.ColorFilterWidth; oldPointerAbs = tex.CPointer; absorbance.Clear(BackColor); absorbanceImg.Copy(HueImgHoriz, Margin + AbsorbTextSize, Margin + AbsorbTextSize); var hsva = phy.ColorHsva; var objHue = hsva.H; var objSat = hsva.S; var alphaD = 1 - hsva.A; for (uint x = 0; x < HueWidthHoriz; x++) { var transmittance = (int)((1 - alphaD * Transmittance(x * HueFacHoriz, objHue, phy.ColorFilterWidth, objSat)) * HueHeightHoriz) + 1; for (uint y = 0; y < transmittance; y++) { absorbanceImg.SetPixel(Margin + AbsorbTextSize + x, Margin + AbsorbTextSize + y, BackColor); } } tex.Texture.Update(absorbanceImg); var hx = (float)(Margin + AbsorbTextSize + objHue / HueFacHoriz); var ay = (float)(Margin - 1 + alphaD * HueHeightHoriz); tex.Draw(new[] { new Vertex(new Vector2f(hx, Margin), Color.White), new Vertex(new Vector2f(hx, Margin + HueHeightHoriz + 2), Color.White), new Vertex(new Vector2f(Margin, ay), Color.White), new Vertex(new Vector2f(WndWidth - Margin, ay), Color.White), }, PrimitiveType.Lines); txtA.Position = new Vector2f(Margin + AbsorbTextSize / 2, ay + AbsorbTextSize); tex.Draw(txtA); txtH.Position = new Vector2f(hx, AbsorbHeight - Margin + AbsorbTextSize / 2); tex.Draw(txtH); } void UpdateAbsorbance() { if (wrapper.ValueHsv != oldCol || phy.ColorFilterWidth != oldWidth || absorbance.RenderTexture()?.CPointer != oldPointerAbs) { DrawAbsorbance(); } } Ui.Drawn += UpdateAbsorbance; Closed += delegate { Ui.Drawn -= UpdateAbsorbance; }; Add(new CheckField(() => phy.Appearance.Borders, onChanged: () => { phy.UpdateOutline(); })); Add(new CheckField(() => phy.Appearance.OpaqueBorders, onChanged: () => { phy.UpdateOutline(); })); if (phy is Circle circle) { Add(new CheckField(() => circle.Appearance.DrawCircleCakes)); Add(new CheckField(() => circle.Appearance.Protractor)); } if (phy is Box box) { Add(new CheckField(() => box.Appearance.Ruler)); } } Show(); } }