Пример #1
0
        private void OpenGLControl_OpenGLDraw(object sender, OpenGLRoutedEventArgs args)
        {
            //  Get the OpenGL instance.
            var gl = args.OpenGL;

            //  Add a bit to theta (how much we're rotating the scene) and create the modelview
            //  and normal matrices.
            theta += 0.01f;
            scene.CreateModelviewAndNormalMatrix(theta);

            //  Clear the color and depth buffer.
            gl.ClearColor(0f, 0f, 0f, 1f);
            gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT | OpenGL.GL_STENCIL_BUFFER_BIT);

            //  Render the scene in either immediate or retained mode.
            switch (comboRenderMode.SelectedIndex)
            {
            case 0:
            {
                scene.RenderRetainedMode(gl, checkBoxUseToonShader.IsChecked.Value); break;
            }

            case 1:
            {
                axies.Render(gl, RenderMode.Design);
                scene.RenderImmediateMode(gl);
                break;
            }
            }
        }
Пример #2
0
        /// <summary>
        /// Handles the OpenGLInitialized event of the OpenGLControl control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="args">The <see cref="OpenGLRoutedEventArgs"/> instance containing the event data.</param>
        private void OpenGLControl_OpenGLInitialized(object sender, OpenGLRoutedEventArgs args)
        {
            OpenGL gl = args.OpenGL;

            gl.Enable(OpenGL.GL_DEPTH_TEST);

            float[] global_ambient = new float[] { 0.5f, 0.5f, 0.5f, 1.0f };
            float[] light0pos      = new float[] { 0.0f, 5.0f, 10.0f, 1.0f };
            float[] light0ambient  = new float[] { 0.2f, 0.2f, 0.2f, 1.0f };
            float[] light0diffuse  = new float[] { 0.3f, 0.3f, 0.3f, 1.0f };
            float[] light0specular = new float[] { 0.8f, 0.8f, 0.8f, 1.0f };

            float[] lmodel_ambient = new float[] { 0.2f, 0.2f, 0.2f, 1.0f };
            gl.LightModel(OpenGL.GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);

            gl.LightModel(OpenGL.GL_LIGHT_MODEL_AMBIENT, global_ambient);
            gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_POSITION, light0pos);
            gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_AMBIENT, light0ambient);
            gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_DIFFUSE, light0diffuse);
            gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_SPECULAR, light0specular);
            gl.Enable(OpenGL.GL_LIGHTING);
            gl.Enable(OpenGL.GL_LIGHT0);

            gl.ShadeModel(OpenGL.GL_SMOOTH);
        }
Пример #3
0
        private void OpenGLControl_OpenGLInitialized(object sender, OpenGLRoutedEventArgs args)
        {
            OpenGL gl = args.OpenGL;

            //  Initialise the scene.
            scene.Initialise(gl);
        }
Пример #4
0
        /// <summary>
        /// Handles the OpenGLDraw event of the OpenGLControl control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="args">The <see cref="OpenGLRoutedEventArgs"/> instance containing the event data.</param>
        private void OpenGLControl_OpenGLDraw(object sender, OpenGLRoutedEventArgs args)
        {
            var gl = args.OpenGL;

            //  Clear the screen and the depth buffer.
            gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);

            //  Reset the projection matrix, move left and into the screen, scale the font.
            gl.LoadIdentity();
            gl.Translate(0f, 0.0f, -6.0f);
            gl.Rotate(rotation, 1.0f, 0.0f, 0.0f);
            var scale = viewModel.FontSize3D / 12.0f;

            gl.Scale(scale, scale, scale);

            gl.DrawText3D(viewModel.FaceName3D, viewModel.Deviation3D, viewModel.Extrusion3D, viewModel.Text3D);

            rotation += 3.0f;

            //  Now render some text.
            gl.DrawText(viewModel.X, viewModel.Y, viewModel.R,
                        viewModel.G, viewModel.B, viewModel.FaceName, viewModel.FontSize,
                        viewModel.Text);
            gl.Flush();
        }
Пример #5
0
        private void GL_Init(object sender, OpenGLRoutedEventArgs args)
        {
            OpenGL gl = args.OpenGL;

            gl.Enable(OpenGL.GL_DEPTH_TEST);

            float[] global_ambient = new float[] { 0.5f, 0.5f, 0.5f, 1.0f };
            float[] light0pos      = new float[] { 0.0f, 5.0f, 10.0f, 1.0f };
            float[] light0ambient  = new float[] { 0.2f, 0.2f, 0.2f, 1.0f };
            float[] light0diffuse  = new float[] { 0.3f, 0.3f, 0.3f, 1.0f };
            float[] light0specular = new float[] { 0.8f, 0.8f, 0.8f, 1.0f };

            float[] lmodel_ambient = new float[] { 0.2f, 0.2f, 0.2f, 1.0f };
            gl.LightModel(OpenGL.GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);

            gl.LightModel(OpenGL.GL_LIGHT_MODEL_AMBIENT, global_ambient);
            gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_POSITION, light0pos);
            gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_AMBIENT, light0ambient);
            gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_DIFFUSE, light0diffuse);
            gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_SPECULAR, light0specular);
            gl.Enable(OpenGL.GL_LIGHTING);
            gl.Enable(OpenGL.GL_LIGHT0);

            gl.ShadeModel(OpenGL.GL_SMOOTH);

            grid.GenerateGeometry(gl);

            ShaderStore.CompileShaders(gl);
        }
Пример #6
0
        /// <summary>
        /// Handles the OpenGLDraw event of the OpenGLControl control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="args">The <see cref="OpenGLRoutedEventArgs"/> instance containing the event data.</param>
        private void OpenGLControl_OpenGLDraw(object sender, OpenGLRoutedEventArgs args)
        {
            OpenGL gl = args.OpenGL;

            // Clear The Screen And The Depth Buffer
            gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);

            // Move Left And Into The Screen
            gl.LoadIdentity();


            gl.Translate(0f, 0.0f, -6.0f);
            gl.Rotate(rotation, 1.0f, 0.0f, 0.0f);


            gl.DrawText3D(viewModel.FaceName3D, viewModel.FontSize3D,
                          viewModel.Deviation3D, viewModel.Extrusion3D, viewModel.Text3D);

            rotation += 3.0f;

            //  Now render some text.
            gl.DrawText(viewModel.X, viewModel.Y, viewModel.R,
                        viewModel.G, viewModel.B, viewModel.FaceName, viewModel.FontSize,
                        viewModel.Text);
            gl.Flush();
        }
Пример #7
0
        private void openGLControl1_OpenGLDraw(object sender, OpenGLRoutedEventArgs args)
        {
            //  If there aren't any shapes, create them.
            if (!shapes.Any())
            {
                CreateShapes();
            }

            //  Get the OpenGL instance.
            var gl = args.OpenGL;

            gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);

            gl.PointSize(2.0f);

            foreach (var shape in shapes)
            {
                gl.Color(shape.Red, shape.Green, shape.Blue);

                gl.Begin(BeginMode.LineLoop);
                shape.Points.ForEach(sp => gl.Vertex(sp.Position));
                gl.End();
            }

            Tick();
        }
Пример #8
0
 public void OpenGLControl_OpenGLDraw(object sender, OpenGLRoutedEventArgs args) //Ивент для отрисовки кадра
 {
     args.OpenGL.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT); //Отчищаем полотно
     //if (FabricFiguries.CurrentFigure != null) Figure.Draw(Painter); //Отрисовка новой фигуры
     FabricFiguries.DrawCurrenFigure(Painter);
     FabricFiguries.DrawAll(Painter); //Рисуем все фигуры из фабрики
 }
Пример #9
0
        private void OpenGLControl_Resized(object sender, OpenGLRoutedEventArgs args)
        {
            //  Get the OpenGL instance.
            var gl = args.OpenGL;

            //  Create the projection matrix for the screen size.
            scene.CreateProjectionMatrix(gl, (float)ActualWidth, (float)ActualHeight);
        }
Пример #10
0
        private void OpenGLControl_OpenGLInitialized(object sender, OpenGLRoutedEventArgs args)
        {
            OpenGL gl = args.OpenGL;

            gl.Enable(OpenGL.GL_DEPTH_TEST);

            float[] global_ambient = new float[] { 0.5f, 0.5f, 0.5f, 1.0f };
            float[] light0pos      = new float[] { 0.0f, 5.0f, 10.0f, 1.0f };
            float[] light0ambient  = new float[] { 0.2f, 0.2f, 0.2f, 1.0f };
            float[] light0diffuse  = new float[] { 0.3f, 0.3f, 0.3f, 1.0f };
            float[] light0specular = new float[] { 0.8f, 0.8f, 0.8f, 1.0f };

            float[] lmodel_ambient = new float[] { 0.2f, 0.2f, 0.2f, 1.0f };
            gl.LightModel(OpenGL.GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);

            gl.LightModel(OpenGL.GL_LIGHT_MODEL_AMBIENT, global_ambient);
            gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_POSITION, light0pos);
            gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_AMBIENT, light0ambient);
            gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_DIFFUSE, light0diffuse);
            gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_SPECULAR, light0specular);
            gl.Enable(OpenGL.GL_LIGHTING);
            gl.Enable(OpenGL.GL_LIGHT0);

            gl.ShadeModel(OpenGL.GL_SMOOTH);

            //  Create a vertex shader.
            VertexShader vertexShader = new VertexShader();

            vertexShader.CreateInContext(gl);
            vertexShader.SetSource(
                "void main()" + Environment.NewLine +
                "{" + Environment.NewLine +
                "gl_Position = ftransform();" + Environment.NewLine +
                "}" + Environment.NewLine);

            //  Create a fragment shader.
            FragmentShader fragmentShader = new FragmentShader();

            fragmentShader.CreateInContext(gl);
            fragmentShader.SetSource(
                "void main()" + Environment.NewLine +
                "{" + Environment.NewLine +
                "gl_FragColor = vec4(0.4,0.4,0.8,1.0);" + Environment.NewLine +
                "}" + Environment.NewLine);

            //  Compile them both.
            vertexShader.Compile();
            fragmentShader.Compile();

            //  Build a program.
            program.CreateInContext(gl);

            //  Attach the shaders.
            program.AttachShader(vertexShader);
            program.AttachShader(fragmentShader);
            program.Link();
        }
Пример #11
0
        private void OpenGLControl_OpenGLInitialized(object sender, OpenGLRoutedEventArgs args)
        {
            OpenGL gl = args.OpenGL;

            //  Initialise the scene.
            scene.Initialise(gl);

            gl.Enable(OpenGL.GL_DEPTH_TEST);
        }
Пример #12
0
        public void OpenGLControl_Resized(object sender, OpenGLRoutedEventArgs args) //Ивент изменения размера окна
        {
            var glContol = (OpenGLControl)sender;

            //Присваиваем новые размеры полотна
            NormPoint.Height = glContol.ActualHeight;
            NormPoint.Widht  = glContol.ActualWidth;
            //Изменяем положение фигур на новом холсте
            FabricFiguries.Update();
        }
Пример #13
0
        private void GL_Draw(object sender, OpenGLRoutedEventArgs args)
        {
            OpenGL gl = args.OpenGL;


            foreach (var sceneObject in Hierarchy.HierarchyObjectList)
            {
                if (!sceneObject.MeshRenderer.Mesh.GeometryGenerated)
                {
                    sceneObject.MeshRenderer.Mesh.GenerateGeometry(gl);
                }
            }

#if DEBUG
            #region Hot Reload Shaders
            ShaderStore.CompileShadersHotReload(gl);
            shaderErrorLabel.Text       = "\n" + ShaderStore.GetShaderErrors();
            shaderErrorLabel.Visibility = (shaderErrorLabel.Text) == "\n" ? Visibility.Hidden : Visibility.Visible;
            #endregion
#endif

            gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT | OpenGL.GL_STENCIL_BUFFER_BIT);
            gl.ClearColor((float)37 / 255, (float)37 / 255, (float)38 / 255, 1);

            ShaderProgram program = ShaderStore.programs["unlitColor"];

            program.Push(gl, null);

            //  Set the variables for the shader program.
            gl.Uniform3(program.GetUniformLocation("AmbientMaterial"), 0.04f, 0.04f, 0.04f);
            gl.Uniform3(program.GetUniformLocation("SpecularMaterial"), 0.5f, 0.5f, 0.5f);
            gl.Uniform1(program.GetUniformLocation("Shininess"), 50f);

            //  Set the light position.
            gl.Uniform3(program.GetUniformLocation("LightPosition"), 0.25f, 0.25f, 1f);

            //  Set the matrices.
            gl.UniformMatrix4(program.GetUniformLocation("Projection"), 1, false, projectionMatrix.ToArray());
            gl.UniformMatrix4(program.GetUniformLocation("View"), 1, false, cameraTransform.ToArray());
            gl.UniformMatrix3(program.GetUniformLocation("NormalMatrix"), 1, false, normalMatrix.ToArray());

            //  Draw Grid
            grid.Draw(gl, program);

            foreach (var sceneObject in Hierarchy.HierarchyObjectList)
            {
                GLColor col = sceneObject.MeshRenderer.Color;
                gl.Uniform3(program.GetUniformLocation("DiffuseMaterial"), col.R, col.G, col.B);

                gl.UniformMatrix4(program.GetUniformLocation("Model"), 1, false, sceneObject.Transform.Matrix.ToArray());
                sceneObject.MeshRenderer.Mesh.Draw(gl);
            }

            program.Pop(gl, null);
        }
Пример #14
0
        private void openGLControl1_Resized(object sender, OpenGLRoutedEventArgs args)
        {
            //  Get the OpenGL instance.
            var gl = args.OpenGL;

            //  Create an orthographic projection.
            gl.MatrixMode(MatrixMode.Projection);
            gl.LoadIdentity();
            gl.Ortho(0, openGLControl1.ActualWidth, openGLControl1.ActualHeight, 0, -10, 10);

            //  Back to the modelview.
            gl.MatrixMode(MatrixMode.Modelview);
        }
Пример #15
0
        private void OpenGLControl_Resized(object sender, OpenGLRoutedEventArgs args)
        {
            //  Get the OpenGL instance.
            var gl = args.OpenGL;

            //  Create a projection matrix for the scene with the screen size.
            scene.CreateProjectionMatrix((float)ActualWidth, (float)ActualHeight);

            //  When we do immediate mode drawing, OpenGL needs to know what our projection matrix
            //  is, so set it now.
            gl.MatrixMode(OpenGL.GL_PROJECTION);
            gl.LoadIdentity();
            gl.MultMatrix(scene.ProjectionMatrix.to_array());
            gl.MatrixMode(OpenGL.GL_MODELVIEW);
        }
Пример #16
0
        private void ogl_OpenGLInitialized(object sender, OpenGLRoutedEventArgs args)
        {
            var gl = args.OpenGL;

            gl.GenTextures(3, _textures);
            _fbos[0]     = _fbos[1] = _fbos[2] = _fbos[3] = _fbos[4] = 0;
            _textures[3] = _textures[4] = _textures[5] = _textures[6] = _textures[7] = 0;
            try
            {
                _blurShader1 = new ShaderProgram();
                var frag = ReadResource(@"LibDmd.Output.Virtual.Dmd.Blur.frag") + "void main() { FragColor = vec4(blur_level_2(texture, uv, direction).rgb, 1.0); }";
                _blurShader1.Create(gl, ReadResource(@"LibDmd.Output.Virtual.Dmd.Blur.vert"), frag, _attributeLocations);
                _bs1Texture   = _blurShader1.GetUniformLocation(gl, "texture");
                _bs1Direction = _blurShader1.GetUniformLocation(gl, "direction");
            }
            catch (ShaderCompilationException e)
            {
                Logger.Error(e, "Blur Shader 1 compilation failed");
                Logger.Error(e.CompilerOutput);
            }
            try
            {
                _blurShader2 = new ShaderProgram();
                var frag = ReadResource(@"LibDmd.Output.Virtual.Dmd.Blur.frag") + "void main() { FragColor = vec4(blur_level_12(texture, uv, direction).rgb, 1.0); }";
                _blurShader2.Create(gl, ReadResource(@"LibDmd.Output.Virtual.Dmd.Blur.vert"), frag, _attributeLocations);
                _bs2Texture   = _blurShader2.GetUniformLocation(gl, "texture");
                _bs2Direction = _blurShader2.GetUniformLocation(gl, "direction");
            }
            catch (ShaderCompilationException e)
            {
                Logger.Error(e, "Blur Shader 2 compilation failed");
                Logger.Error(e.CompilerOutput);
            }
            _quadVbo = new VertexBufferArray();
            _quadVbo.Create(gl);
            _quadVbo.Bind(gl);
            var posVBO = new VertexBuffer();

            posVBO.Create(gl);
            posVBO.Bind(gl);
            posVBO.SetData(gl, PositionAttribute, new float[] { -1f, -1f, -1f, 1f, 1f, 1f, 1f, -1f }, false, 2);
            var texVBO = new VertexBuffer();

            texVBO.Create(gl);
            texVBO.Bind(gl);
            texVBO.SetData(gl, TexCoordAttribute, new float[] { 0f, 1f, 0f, 0f, 1f, 0f, 1f, 1f }, false, 2);
            _quadVbo.Unbind(gl);
        }
Пример #17
0
        /// <summary>
        /// Handles the OpenGLDraw event of the OpenGLControl control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="args">The <see cref="OpenGLRoutedEventArgs"/> instance containing the event data.</param>
        private void OpenGLControl_OpenGLDraw(object sender, OpenGLRoutedEventArgs args)
        {
            OpenGL gl = args.OpenGL;

            // Clear The Screen And The Depth Buffer
            gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);

            // Move Left And Into The Screen
            gl.LoadIdentity();
            gl.Translate(0.0f, 0.0f, -6.0f);


            gl.Rotate(rotation, 0.0f, 1.0f, 0.0f);

            Teapot tp = new Teapot();

            tp.Draw(gl, 14, 1, OpenGL.GL_FILL);

            rotation += 3.0f;
        }
Пример #18
0
        private void openGLCtrl_OpenGLInitialized(object sender, OpenGLRoutedEventArgs args)
        {
            //  Create the vertices.
            vertices = GeometryGenerator.GenerateGeometry(Properties.Settings.Default.NumberOfVertices, 1f);

            //  Override with test values if needed.
            ProvideTestValues(vertices);

            vertexArrayValues = new float[vertices.Length * 3];
            uint counter = 0;

            for (uint i = 0; i < vertices.Length; i++)
            {
                vertexArrayValues[counter++] = vertices[i].X;
                vertexArrayValues[counter++] = vertices[i].Y;
                vertexArrayValues[counter++] = vertices[i].Z;
            }

            args.OpenGL.PointSize(3.0f);
        }
Пример #19
0
        private void openGLCtrl_OpenGLDraw(object sender, OpenGLRoutedEventArgs args)
        {
            //  Get the OpenGL instance that's been passed to us.
            OpenGL gl = args.OpenGL;

            //  Clear the color and depth buffers.
            gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);

            //  Reset the modelview matrix.
            gl.LoadIdentity();

            //  Move the geometry into a fairly central position.
            gl.Translate(0f, 0.0f, -6.0f);

            axies.Render(gl, RenderMode.Design);


            switch (this.drawingMechanismCombo.SelectedIndex)
            {
            case 0:
                RenderVertices_Immediate(args.OpenGL);
                break;

            case 1:
                RenderVertices_VertexArray(args.OpenGL);
                break;
            }

            //  Flush OpenGL.
            gl.Flush();

            /*
             * //  Clear the color and depth buffers.
             * gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
             *
             * //  Reset the modelview matrix.
             * gl.LoadIdentity(); */
        }
Пример #20
0
        private void ogl_OpenGLDraw(object sender, OpenGLRoutedEventArgs args)
        {
            var gl = args.OpenGL;

            gl.ClearColor(0f, 0f, 0f, 1f);
            gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
            var createTexture = false;

            if (_dmdShaderInvalid)
            {
                // Create a dedicated DMD shader based on the selected style settings
                createTexture     = true;
                _dmdShaderInvalid = false;
                _dmdShader?.Delete(gl);
                try
                {
                    _dmdShader = new ShaderProgram();
                    var code = new StringBuilder();
                    code.Append("#version 130\n");
                    if (_style.HasBackGlow)
                    {
                        code.Append("#define BACKGLOW\n");
                    }
                    if (_style.HasDotGlow)
                    {
                        code.Append("#define DOTGLOW\n");
                    }
                    if (_style.HasBrightness)
                    {
                        code.Append("#define BRIGHTNESS\n");
                    }
                    if (_style.HasUnlitDot)
                    {
                        code.Append("#define UNLIT\n");
                    }
                    if (_style.HasGlass)
                    {
                        code.Append("#define GLASS\n");
                    }
                    if (_style.HasGamma)
                    {
                        code.Append("#define GAMMA\n");
                    }
                    if (_style.DotSize > 0.5)
                    {
                        code.Append("#define DOT_OVERLAP\n");
                    }
                    var nfi = System.Globalization.NumberFormatInfo.InvariantInfo;
                    code.AppendFormat(nfi, "const float dotSize = {0:0.00000};\n", _style.DotSize);
                    code.AppendFormat(nfi, "const float dotRounding = {0:0.00000};\n", _style.DotRounding);
                    code.AppendFormat(nfi, "const float sharpMax = {0:0.00000};\n", 0.01 + _style.DotSize * (1.0 - _style.DotSharpness));
                    code.AppendFormat(nfi, "const float sharpMin = {0:0.00000};\n", -0.01 - _style.DotSize * (1.0 - _style.DotSharpness));
                    code.AppendFormat(nfi, "const float brightness = {0:0.00000};\n", _style.Brightness);
                    code.AppendFormat(nfi, "const float backGlow = {0:0.00000};\n", _style.BackGlow);
                    code.AppendFormat(nfi, "const float dotGlow = {0:0.00000};\n", _style.DotGlow);
                    code.AppendFormat(nfi, "const float gamma = {0:0.00000};\n", _style.Gamma);
                    code.Append(ReadResource(@"LibDmd.Output.Virtual.Dmd.Dmd.frag"));
                    _dmdShader.Create(gl, ReadResource(@"LibDmd.Output.Virtual.Dmd.Dmd.vert"), code.ToString(), _attributeLocations);
                    _dsDmdTexture     = _dmdShader.GetUniformLocation(gl, "dmdTexture");
                    _dsDmdDotGlow     = _dmdShader.GetUniformLocation(gl, "dmdDotGlow");
                    _dsDmdBackGlow    = _dmdShader.GetUniformLocation(gl, "dmdBackGlow");
                    _dsDmdSize        = _dmdShader.GetUniformLocation(gl, "dmdSize");
                    _dsUnlitDot       = _dmdShader.GetUniformLocation(gl, "unlitDot");
                    _dsGlassTexture   = _dmdShader.GetUniformLocation(gl, "glassTexture");
                    _dsGlassTexOffset = _dmdShader.GetUniformLocation(gl, "glassTexOffset");
                    _dsGlassTexScale  = _dmdShader.GetUniformLocation(gl, "glassTexScale");
                    _dsGlassColor     = _dmdShader.GetUniformLocation(gl, "glassColor");
                }
                catch (ShaderCompilationException e)
                {
                    Logger.Error(e, "DMD Shader compilation failed:");
                    Logger.Error(e.CompilerOutput);
                }
            }

            if (_fboInvalid)
            {
                _fboInvalid   = false;
                createTexture = true;
                // Release previous textures and FBOs if any (0 are ignored by OpenGL driver)
                uint[] texs = new uint[5] {
                    _textures[3], _textures[4], _textures[5], _textures[6], _textures[7]
                };
                gl.DeleteTextures(5, texs);
                gl.DeleteFramebuffersEXT(5, _fbos);
                Logger.Info("Creating FBOs for {0}x{1}", DmdWidth, DmdHeight);
                gl.GenTextures(5, texs);
                gl.GenFramebuffersEXT(5, _fbos);
                _textures[3] = texs[0];
                _textures[4] = texs[1];
                _textures[5] = texs[2];
                _textures[6] = texs[3];
                _textures[7] = texs[4];
                for (int i = 0; i < _fbos.Length; i++)
                {
                    gl.BindFramebufferEXT(OpenGL.GL_FRAMEBUFFER_EXT, _fbos[i]);
                    gl.BindTexture(OpenGL.GL_TEXTURE_2D, _textures[i + 3]);
                    gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_BORDER_COLOR, new float[] { 0f, 0f, 0f, 0f });
                    gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_WRAP_S, OpenGL.GL_CLAMP_TO_BORDER);
                    gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_WRAP_T, OpenGL.GL_CLAMP_TO_BORDER);
                    gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MIN_FILTER, OpenGL.GL_LINEAR);
                    gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MAG_FILTER, OpenGL.GL_LINEAR);
                    gl.TexImage2D(OpenGL.GL_TEXTURE_2D, 0, OpenGL.GL_RGB, DmdWidth, DmdHeight, 0, OpenGL.GL_RGB, OpenGL.GL_UNSIGNED_BYTE, IntPtr.Zero);
                    gl.FramebufferTexture2DEXT(OpenGL.GL_FRAMEBUFFER_EXT, OpenGL.GL_COLOR_ATTACHMENT0_EXT, OpenGL.GL_TEXTURE_2D, _textures[i + 3], 0);
                    uint status = gl.CheckFramebufferStatusEXT(OpenGL.GL_FRAMEBUFFER_EXT);
                    switch (status)
                    {
                    case OpenGL.GL_FRAMEBUFFER_COMPLETE_EXT:
                        break;

                    case OpenGL.GL_FRAMEBUFFER_UNSUPPORTED_EXT:
                        Logger.Info("Failed to build FBO for virtual DMD [error: GL_FRAMEBUFFER_UNSUPPORTED_EXT]");
                        break;

                    default:
                        Logger.Info("Failed to build FBO for virtual DMD [{0}]", status);
                        break;
                    }
                }
            }

            _quadVbo.Bind(gl);

            for (int i = 0; i < _textures.Length; i++)
            {
                gl.ActiveTexture(OpenGL.GL_TEXTURE0 + (uint)i);
                gl.BindTexture(OpenGL.GL_TEXTURE_2D, _textures[i]);
            }

            if (_glassToRender != null)
            {
                // Upload glass bitmap to GPU, generate mipmaps, then release bitmap
                gl.ActiveTexture(OpenGL.GL_TEXTURE0);
                var data = _glassToRender.LockBits(new System.Drawing.Rectangle(0, 0, _glassToRender.Width, _glassToRender.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb).Scan0;
                gl.TexImage2D(OpenGL.GL_TEXTURE_2D, 0, OpenGL.GL_RGB, _glassToRender.Width, _glassToRender.Height, 0, OpenGL.GL_BGR, OpenGL.GL_UNSIGNED_BYTE, data);
                gl.GenerateMipmapEXT(OpenGL.GL_TEXTURE_2D);
                gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_WRAP_S, OpenGL.GL_CLAMP_TO_EDGE);
                gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_WRAP_T, OpenGL.GL_CLAMP_TO_EDGE);
                gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MIN_FILTER, OpenGL.GL_LINEAR_MIPMAP_LINEAR);
                gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MAG_FILTER, OpenGL.GL_LINEAR);
                _glassToRender = null;
            }

            if (_hasFrame)
            {
                // Update palette (small 16x1 texture used as a LUT (lookup table) when processing the DMD data on the GPU)
                if (_lutInvalid)
                {
                    _lutInvalid = false;
                    byte[] data = new byte[3 * 16];
                    if (_nextFrameType == FrameFormat.Gray2 && _gray2Palette != null)
                    {
                        for (int i = 0; i < 16; i++)
                        {
                            data[i * 3]     = _gray2Palette[i / 4].R;
                            data[i * 3 + 1] = _gray2Palette[i / 4].G;
                            data[i * 3 + 2] = _gray2Palette[i / 4].B;
                        }
                    }
                    else if (_nextFrameType == FrameFormat.Gray4 && _gray4Palette != null)
                    {
                        for (int i = 0; i < 16; i++)
                        {
                            data[i * 3]     = _gray4Palette[i].R;
                            data[i * 3 + 1] = _gray4Palette[i].G;
                            data[i * 3 + 2] = _gray4Palette[i].B;
                        }
                    }
                    else
                    {
                        var alpha = 1.0f - _style.Tint.ScA;
                        var beta  = _style.Tint.ScA;
                        ColorUtil.RgbToHsl(_dotColor.R, _dotColor.G, _dotColor.B, out var dotHue, out var dotSat, out var dotLum);
                        ColorUtil.RgbToHsl(_style.Tint.R, _style.Tint.G, _style.Tint.B, out var tintHue, out var tintSat, out var tintLum);
                        for (int i = 0; i < 16; i++)
                        {
                            ColorUtil.HslToRgb(dotHue, dotSat, dotLum * i / 15.0, out var dotRed, out var dotGreen, out var dotBlue);
                            ColorUtil.HslToRgb(tintHue, tintSat, tintLum * i / 15.0, out var tintRed, out var tintGreen, out var tintBlue);
                            var red   = (byte)(dotRed * alpha + tintRed * beta);
                            var green = (byte)(dotGreen * alpha + tintGreen * beta);
                            var blue  = (byte)(dotBlue * alpha + tintBlue * beta);
                            data[i * 3]     = red;
                            data[i * 3 + 1] = green;
                            data[i * 3 + 2] = blue;
                        }
                    }
                    gl.ActiveTexture(OpenGL.GL_TEXTURE1);
                    gl.TexImage2D(OpenGL.GL_TEXTURE_2D, 0, OpenGL.GL_RGB, 16, 1, 0, OpenGL.GL_RGB, OpenGL.GL_UNSIGNED_BYTE, data);
                    gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_WRAP_S, OpenGL.GL_CLAMP_TO_EDGE);
                    gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_WRAP_T, OpenGL.GL_CLAMP_TO_EDGE);
                    gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MIN_FILTER, OpenGL.GL_NEAREST);
                    gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MAG_FILTER, OpenGL.GL_NEAREST);
                }

                if (_convertShader == null || _convertShaderType != _nextFrameType)
                {
                    _convertShader?.Delete(gl);
                    _convertShaderType = _nextFrameType;
                    createTexture      = true;
                    try
                    {
                        _convertShader = new ShaderProgram();
                        var code = new StringBuilder();
                        code.Append("#version 130\n");
                        code.Append("#define ");
                        code.Append(_convertShaderType.ToString().ToUpperInvariant());
                        code.Append("\n");
                        if (_style.HasGamma)
                        {
                            code.Append("#define GAMMA\n");
                        }
                        var nfi = System.Globalization.NumberFormatInfo.InvariantInfo;
                        code.AppendFormat(nfi, "const float gamma = {0:0.00000};\n", _style.Gamma);
                        code.AppendFormat(nfi, "const int dmdWidth = {0};\n", DmdWidth);
                        code.Append(ReadResource(@"LibDmd.Output.Virtual.Dmd.Convert.frag"));
                        _convertShader.Create(gl, ReadResource(@"LibDmd.Output.Virtual.Dmd.Convert.vert"), code.ToString(), _attributeLocations);
                        _csTexture = _convertShader.GetUniformLocation(gl, "dmdData");
                        _csPalette = _convertShader.GetUniformLocation(gl, "palette");
                    }
                    catch (ShaderCompilationException e)
                    {
                        Logger.Error(e, "Convert shader compilation failed");
                        Logger.Error(e.CompilerOutput);
                    }
                }

                // Update DMD texture with latest frame
                _hasFrame = false;
                gl.ActiveTexture(OpenGL.GL_TEXTURE2);
                switch (_nextFrameType)
                {
                case FrameFormat.Gray2:
                    if (_nextFrameData.Length != DmdWidth * DmdHeight)
                    {
                        throw new ArgumentException($"Invalid frame buffer size of {_nextFrameData.Length} bytes for a frame size of {DmdWidth}x{DmdHeight}");
                    }
                    if (createTexture)
                    {
                        gl.TexImage2D(OpenGL.GL_TEXTURE_2D, 0, OpenGL.GL_LUMINANCE8, DmdWidth, DmdHeight, 0, OpenGL.GL_LUMINANCE, OpenGL.GL_UNSIGNED_BYTE, _nextFrameData);
                    }
                    else
                    {
                        glTexSubImage2D(OpenGL.GL_TEXTURE_2D, 0, 0, 0, DmdWidth, DmdHeight, OpenGL.GL_LUMINANCE, OpenGL.GL_UNSIGNED_BYTE, _nextFrameData);
                    }
                    break;

                case FrameFormat.Gray4:
                    if (_nextFrameData.Length != DmdWidth * DmdHeight)
                    {
                        throw new ArgumentException($"Invalid frame buffer size of {_nextFrameData.Length} bytes for a frame size of {DmdWidth}x{DmdHeight}");
                    }
                    if (createTexture)
                    {
                        gl.TexImage2D(OpenGL.GL_TEXTURE_2D, 0, OpenGL.GL_LUMINANCE8, DmdWidth, DmdHeight, 0, OpenGL.GL_LUMINANCE, OpenGL.GL_UNSIGNED_BYTE, _nextFrameData);
                    }
                    else
                    {
                        glTexSubImage2D(OpenGL.GL_TEXTURE_2D, 0, 0, 0, DmdWidth, DmdHeight, OpenGL.GL_LUMINANCE, OpenGL.GL_UNSIGNED_BYTE, _nextFrameData);
                    }
                    break;

                case FrameFormat.Rgb24:
                    if (_nextFrameData.Length % 3 != 0)
                    {
                        throw new ArgumentException("RGB24 buffer must be divisible by 3, but " + _nextFrameData.Length + " isn't.");
                    }
                    if (createTexture)
                    {
                        gl.TexImage2D(OpenGL.GL_TEXTURE_2D, 0, OpenGL.GL_RGB, DmdWidth, DmdHeight, 0, OpenGL.GL_RGB, OpenGL.GL_UNSIGNED_BYTE, _nextFrameData);
                    }
                    else
                    {
                        glTexSubImage2D(OpenGL.GL_TEXTURE_2D, 0, 0, 0, DmdWidth, DmdHeight, OpenGL.GL_RGB, OpenGL.GL_UNSIGNED_BYTE, _nextFrameData);
                    }
                    break;

                case FrameFormat.Bitmap:
                    var _bitmapToRender = ImageUtil.ConvertToImage(_nextFrameBitmap) as System.Drawing.Bitmap;
                    var data            = _bitmapToRender.LockBits(new System.Drawing.Rectangle(0, 0, _bitmapToRender.Width, _bitmapToRender.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                    if (createTexture)
                    {
                        gl.TexImage2D(OpenGL.GL_TEXTURE_2D, 0, OpenGL.GL_RGB, _bitmapToRender.Width, _bitmapToRender.Height, 0, OpenGL.GL_BGR, OpenGL.GL_UNSIGNED_BYTE, data.Scan0);
                    }
                    else
                    {
                        glTexSubImage2D(OpenGL.GL_TEXTURE_2D, 0, 0, 0, DmdWidth, DmdHeight, OpenGL.GL_BGR, OpenGL.GL_UNSIGNED_BYTE, data.Scan0);
                    }
                    _bitmapToRender.UnlockBits(data);
                    break;
                }
                if (createTexture)
                {
                    gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_BORDER_COLOR, new float[] { 0f, 0f, 0f, 0f });
                    gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_WRAP_S, OpenGL.GL_CLAMP_TO_BORDER);
                    gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_WRAP_T, OpenGL.GL_CLAMP_TO_BORDER);
                    gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MIN_FILTER, OpenGL.GL_NEAREST);
                    gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MAG_FILTER, OpenGL.GL_NEAREST);
                }

                // Apply palette, tinting and gamma
                _convertShader.Bind(gl);
                gl.BindFramebufferEXT(OpenGL.GL_FRAMEBUFFER_EXT, _fbos[0]);
                gl.Viewport(0, 0, DmdWidth, DmdHeight);
                gl.Uniform1(_csPalette, 1);                 // Color palette
                gl.Uniform1(_csTexture, 2);                 // DMD texture
                gl.DrawArrays(OpenGL.GL_TRIANGLE_FAN, 0, 4);
                _convertShader.Unbind(gl);

                // Compute blur levels
                if (_style.HasGlass || _style.HasDotGlow || _style.HasBackGlow)
                {
                    _blurShader1.Bind(gl);
                    gl.BindFramebufferEXT(OpenGL.GL_FRAMEBUFFER_EXT, _fbos[4]); // Horizontal pass (from last blur level, to temp FBO (Tex #7))
                    gl.Viewport(0, 0, DmdWidth, DmdHeight);
                    gl.Uniform1(_bs1Texture, 3);                                // DMD texture
                    gl.Uniform2(_bs1Direction, 1.0f / DmdWidth, 0.0f);
                    gl.DrawArrays(OpenGL.GL_TRIANGLE_FAN, 0, 4);
                    gl.BindFramebufferEXT(OpenGL.GL_FRAMEBUFFER_EXT, _fbos[1]);                     // Vertical pass (from temp to destination FBO)
                    gl.Viewport(0, 0, DmdWidth, DmdHeight);
                    gl.Uniform1(_bs1Texture, 7);
                    gl.Uniform2(_bs1Direction, 0.0f, 1.0f / DmdHeight);
                    gl.DrawArrays(OpenGL.GL_TRIANGLE_FAN, 0, 4);
                    _blurShader1.Unbind(gl);

                    _blurShader2.Bind(gl);
                    gl.BindFramebufferEXT(OpenGL.GL_FRAMEBUFFER_EXT, _fbos[4]); // Horizontal pass (from last blur level, to temp FBO (Tex #7))
                    gl.Viewport(0, 0, DmdWidth, DmdHeight);
                    gl.Uniform1(_bs2Texture, 4);                                // Previous Blur
                    gl.Uniform2(_bs2Direction, 1.0f / DmdWidth, 0.0f);
                    gl.DrawArrays(OpenGL.GL_TRIANGLE_FAN, 0, 4);
                    gl.BindFramebufferEXT(OpenGL.GL_FRAMEBUFFER_EXT, _fbos[2]);                     // Vertical pass (from temp to destination FBO)
                    gl.Viewport(0, 0, DmdWidth, DmdHeight);
                    gl.Uniform1(_bs2Texture, 7);
                    gl.Uniform2(_bs2Direction, 0.0f, 1.0f / DmdHeight);
                    gl.DrawArrays(OpenGL.GL_TRIANGLE_FAN, 0, 4);

                    gl.BindFramebufferEXT(OpenGL.GL_FRAMEBUFFER_EXT, _fbos[4]); // Horizontal pass (from last blur level, to temp FBO (Tex #7))
                    gl.Viewport(0, 0, DmdWidth, DmdHeight);
                    gl.Uniform1(_bs2Texture, 5);                                // Previous Blur
                    gl.Uniform2(_bs2Direction, 1.0f / DmdWidth, 0.0f);
                    gl.DrawArrays(OpenGL.GL_TRIANGLE_FAN, 0, 4);
                    gl.BindFramebufferEXT(OpenGL.GL_FRAMEBUFFER_EXT, _fbos[3]);                     // Vertical pass (from temp to destination FBO)
                    gl.Viewport(0, 0, DmdWidth, DmdHeight);
                    gl.Uniform1(_bs2Texture, 7);
                    gl.Uniform2(_bs2Direction, 0.0f, 1.0f / DmdHeight);
                    gl.DrawArrays(OpenGL.GL_TRIANGLE_FAN, 0, 4);
                    _blurShader2.Unbind(gl);
                }
            }

            // Render Dmd
            gl.BindFramebufferEXT(OpenGL.GL_FRAMEBUFFER_EXT, 0);
            gl.Viewport(0, 0, (int)Dmd.Width, (int)Dmd.Height);
            _dmdShader.Bind(gl);
            if (_dsGlassTexture != -1)
            {
                gl.Uniform1(_dsGlassTexture, 0);
            }
            if (_dsDmdTexture != -1)
            {
                gl.Uniform1(_dsDmdTexture, 3);
            }
            if (_dsDmdDotGlow != -1)
            {
                gl.Uniform1(_dsDmdDotGlow, 4);
            }
            if (_dsDmdBackGlow != -1)
            {
                gl.Uniform1(_dsDmdBackGlow, 6);
            }
            if (_dsDmdSize != -1)
            {
                gl.Uniform2(_dsDmdSize, (float)DmdWidth, DmdHeight);
            }
            if (_dsUnlitDot != -1)
            {
                gl.Uniform3(_dsUnlitDot, (float)(_style.UnlitDot.ScR / _style.Brightness), (float)(_style.UnlitDot.ScG / _style.Brightness), (float)(_style.UnlitDot.ScB / _style.Brightness));
            }
            if (_dsGlassTexOffset != -1)
            {
                gl.Uniform2(_dsGlassTexOffset, (float)(_style.GlassPadding.Left / DmdWidth), (float)(_style.GlassPadding.Top / DmdHeight));
            }
            if (_dsGlassTexScale != -1)
            {
                gl.Uniform2(_dsGlassTexScale, (float)(1f + (_style.GlassPadding.Left + _style.GlassPadding.Right) / DmdWidth), (float)(1f + (_style.GlassPadding.Top + _style.GlassPadding.Bottom) / DmdHeight));
            }
            if (_dsGlassColor != -1)
            {
                gl.Uniform4(_dsGlassColor, _style.GlassColor.ScR, _style.GlassColor.ScG, _style.GlassColor.ScB, (float)_style.GlassLighting);
            }
            gl.DrawArrays(OpenGL.GL_TRIANGLE_FAN, 0, 4);
            _dmdShader.Unbind(gl);

            _quadVbo.Unbind(gl);
        }
Пример #21
0
        /*
         * Сегмент кода про OpenGL
         */
        public void OpenGLControl_OpenGLInitialized(object sender, OpenGLRoutedEventArgs args) //Инициализация полотна
        {
            var gl = args.OpenGL;

            Painter = new GLpainter(ref gl); //Создаем экземляр класса GLpainter с помощью которого рисуем графику
        }