Example #1
0
        //! On load window (once)
        protected override void OnLoad()
        {
            _version        = openGLFactory.NewVersionInformation(Console.WriteLine);
            _extensions     = openGLFactory.NewExtensionInformation();
            _debug_callback = openGLFactory.NewDebugCallback(Console.WriteLine);

            // Version strings
            _version.Retrieve();

            // Get OpenGL extensions
            _extensions.Retrieve();

            // Debug callback
            _debug_callback.Init();

            // Create shader program

            string vert_shader = @"#version 460

            layout (location = 0) in vec2 in_pos;
            layout (location = 1) in vec2 in_uv;

            out vec2 vUV;

            layout (location = 0) uniform mat4 model;
            layout (location = 1) uniform mat4 projection;
            
            void main()
            {
                vUV         = in_uv.xy;
		        gl_Position = projection * model * vec4(in_pos.xy, 0.0, 1.0);
            }";

            string frag_shader = @"#version 460

            in vec2 vUV;

            layout (binding=0) uniform sampler2D u_texture;

             layout (location = 2) uniform vec3 textColor;

            out vec4 fragColor;

            void main()
            {
                vec2 uv = vUV.xy;
                float text = texture(u_texture, uv).r;
                fragColor = vec4(textColor.rgb*text, text);
            }";

            this._text_prog = openGLFactory.VertexAndFragmentShaderProgram(vert_shader, frag_shader);
            this._text_prog.Generate();
            this._text_prog.Use();

            // load font
            _font = new FreeTypeFont(32);

            base.OnLoad();
        }
Example #2
0
        //! On load window (once)
        protected override void OnLoad()
        {
            _version        = openGLFactory.NewVersionInformation(Console.WriteLine);
            _extensions     = openGLFactory.NewExtensionInformation();
            _debug_callback = openGLFactory.NewDebugCallback(Console.WriteLine);

            // Version strings
            _version.Retrieve();

            // Get OpenGL extensions
            _extensions.Retrieve();

            // Debug callback
            _debug_callback.Init();

            // create Vertex Array Object, Array Buffer Object and Element Array Buffer Object

            float[] vquad =
            {
                // x      y     z      r     g     b     a
                -1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
                1.0f,  -1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
                1.0f,   1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
                -1.0f,  1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f
            };

            uint[] iquad = { 0, 1, 2, 0, 2, 3 };

            TVertexFormat[] format =
            {
                new TVertexFormat(0, 0, 3, 0, false),
                new TVertexFormat(0, 1, 4, 3, false),
            };

            int vao = GL.GenVertexArray();

            GL.BindVertexArray(vao);

            // Create shader program

            string vert_shader = @"
            #version 460 core

            layout(std430, binding = 0) buffer TVertex
            {
               vec4 vertex[]; 
            };

            uniform mat4  u_mvp;
            uniform vec2  u_resolution;
            uniform float u_thickness;
            
            void main()
            {
                int line_i = gl_VertexID / 6;
                int tri_i  = gl_VertexID % 6;
                vec4 va[4];
                for (int i=0; i<4; ++i)
                {
                    va[i] = u_mvp * vertex[line_i+i];
                    va[i].xyz /= va[i].w;
                    va[i].xy = (va[i].xy + 1.0) * 0.5 * u_resolution;
                }
                vec2 v_line  = normalize(va[2].xy - va[1].xy);
                vec2 nv_line = vec2(-v_line.y, v_line.x);
    
                vec4 pos;
                if (tri_i == 0 || tri_i == 1 || tri_i == 3)
                {
                    vec2 v_pred  = normalize(va[1].xy - va[0].xy);
                    vec2 v_miter = normalize(nv_line + vec2(-v_pred.y, v_pred.x));
                    pos = va[1];
                    pos.xy += v_miter * u_thickness * (tri_i == 1 ? -0.5 : 0.5) / dot(v_miter, nv_line);
                }
                else
                {
                    vec2 v_succ  = normalize(va[3].xy - va[2].xy);
                    vec2 v_miter = normalize(nv_line + vec2(-v_succ.y, v_succ.x));
                    pos = va[2];
                    pos.xy += v_miter * u_thickness * (tri_i == 5 ? 0.5 : -0.5) / dot(v_miter, nv_line);
                }
                pos.xy = pos.xy / u_resolution * 2.0 - 1.0;
                pos.xyz *= pos.w;
                gl_Position = pos;
            }";

            string frag_shader = @"
            #version 460 core
            
            out vec4 fragColor;
            uniform vec4 u_color;
            
            void main()
            {
                fragColor = u_color;
            }";

            _test_prog = openGLFactory.VertexAndFragmentShaderProgram(vert_shader, frag_shader);
            _test_prog.Generate();

            mvpLocation        = GL.GetUniformLocation(this._test_prog.Object, "u_mvp");
            resolutionLocation = GL.GetUniformLocation(this._test_prog.Object, "u_resolution");
            thicknessLocation  = GL.GetUniformLocation(this._test_prog.Object, "u_thickness");
            colorLocation      = GL.GetUniformLocation(this._test_prog.Object, "u_color");
            _test_prog.Use();

            float[] p0    = { -1.0f, -1.0f, 0.0f, 1.0f };
            float[] p1    = { 1.0f, -1.0f, 0.0f, 1.0f };
            float[] p2    = { 1.0f, 1.0f, 0.0f, 1.0f };
            float[] p3    = { -1.0f, 1.0f, 0.0f, 1.0f };
            float[] line1 = p3.Concat(p0).Concat(p1).Concat(p2).Concat(p3).Concat(p0).Concat(p1).ToArray();
            _lineBuffer1 = openGLFactory.NewStorageBuffer();
            _lineBuffer1.Create(line1);
            _no_vertices_1 = line1.Length / 4;

            var ll2 = new List <float>();

            for (int u = -8; u <= 368; u += 8)
            {
                double a = u * Math.PI / 180.0;
                double c = Math.Cos(a), s = Math.Sin(a);
                ll2.AddRange(new float[] { (float)c, (float)s, 0.0f, 1.0f });
            }
            float[] line2 = ll2.ToArray();
            _lineBuffer2 = openGLFactory.NewStorageBuffer();
            _lineBuffer2.Create(line2);
            _no_vertices_2 = line2.Length / 4;

            // states

            GL.ClearColor(0.8f, 0.9f, 1.0f, 1.0f);

            base.OnLoad();
        }
Example #3
0
        public void Setup(int cx, int cy)
        {
            this._cx = cx;
            this._cy = cy;

            // Version strings
            _version.Retrieve();

            // Get OpenGL extensions
            _extensions.Retrieve();

            // Debug callback
            _debug_callback.Init();

            // to do mesh buffer creator form multi indices mesh
            // use in-source wave font file?

            float[] attributes =
            {
                // left
                -1.0f,  1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
                -1.0f, -1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
                -1.0f, -1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
                -1.0f,  1.0f,  1.0f, 1.0f, 0.0f, 1.0f, 0.0f,

                // right
                1.0f,  -1.0f, -1.0f, 0.0f, 0.0f, 2.0f, 0.0f,
                1.0f,   1.0f, -1.0f, 0.0f, 1.0f, 2.0f, 0.0f,
                1.0f,   1.0f,  1.0f, 1.0f, 1.0f, 2.0f, 0.0f,
                1.0f,  -1.0f,  1.0f, 1.0f, 0.0f, 2.0f, 0.0f,

                // front
                -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 3.0f, 0.0f,
                1.0f,  -1.0f, -1.0f, 0.0f, 1.0f, 3.0f, 0.0f,
                1.0f,  -1.0f,  1.0f, 1.0f, 1.0f, 3.0f, 0.0f,
                -1.0f, -1.0f,  1.0f, 1.0f, 0.0f, 3.0f, 0.0f,

                // back
                1.0f,   1.0f, -1.0f, 0.0f, 0.0f, 4.0f, 0.0f,
                -1.0f,  1.0f, -1.0f, 0.0f, 1.0f, 4.0f, 0.0f,
                -1.0f,  1.0f,  1.0f, 1.0f, 1.0f, 4.0f, 0.0f,
                1.0f,   1.0f,  1.0f, 1.0f, 0.0f, 4.0f, 0.0f,

                // bottom
                -1.0f,  1.0f, -1.0f, 0.0f, 0.0f, 5.0f, 0.0f,
                1.0f,   1.0f, -1.0f, 0.0f, 1.0f, 5.0f, 0.0f,
                1.0f,  -1.0f, -1.0f, 1.0f, 1.0f, 5.0f, 0.0f,
                -1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 5.0f, 0.0f,

                // top
                -1.0f, -1.0f,  1.0f, 0.0f, 0.0f, 6.0f, 0.0f,
                1.0f,  -1.0f,  1.0f, 0.0f, 1.0f, 6.0f, 0.0f,
                1.0f,   1.0f,  1.0f, 1.0f, 1.0f, 6.0f, 0.0f,
                -1.0f,  1.0f,  1.0f, 1.0f, 0.0f, 6.0f, 0.0f
            };

            uint[] indices =
            {
                0,   1,  2,  0,  2, 3,  // front
                4,   5,  6,  4,  6, 7,  // back
                8,   9, 10,  8, 10, 11, // left
                12, 13, 14, 12, 14, 15, // right
                16, 17, 18, 16, 18, 19, // bottom
                20, 21, 22, 20, 22, 23  // top
            };

            // create Vertex Array Object, Array Buffer Object and Element Array Buffer Object

            TVertexFormat[] format =
            {
                new TVertexFormat(0, 0, 3, 0, false),
                new TVertexFormat(0, 1, 4, 3, false),
            };

            _vao = openGLFactory.NewVertexArrayObject();
            _vao.AppendVertexBuffer(0, 7, attributes);
            _vao.Create(format, indices);
            _vao.Bind();

            // Create shader program

            string vert_shader = @"
            #version 460 core

            layout (location = 0) in vec3 inPos;
            layout (location = 1) in vec4 inAttr;

            out vec3  vertPos;
            out vec4  vertTex;
            out float highlight;

            layout (std430, binding = 1) buffer UB_MVP
            { 
                mat4 u_projection;
                mat4 u_view;
                mat4 u_model;
            };

            layout (std430, binding = 2) buffer UB_RUBIKS
            { 
                mat4 u_rubiks_model[27];
                int  u_cube_hit;
                int  u_side_hit;
            };

            void main()
            {
                vec4 tex     = inAttr;
                int  cube_i  = gl_InstanceID;
                int  color_i = int(tex.z + 0.5); 
                int  x_i     = cube_i % 3;
                int  y_i     = (cube_i % 9) / 3;
                int  z_i     = cube_i / 9;

                if ( color_i == 1 )
                    tex.z = x_i == 0 ? tex.z : 0.0;
                else if ( color_i == 2 )
                    tex.z = x_i == 2 ? tex.z : 0.0;
                else if ( color_i == 3 )
                    tex.z = y_i == 0 ? tex.z : 0.0;
                else if ( color_i == 4 )
                    tex.z = y_i == 2 ? tex.z : 0.0;
                else if ( color_i == 5 )
                    tex.z = z_i == 0 ? tex.z : 0.0;
                else if ( color_i == 6 )
                    tex.z = z_i == 2 ? tex.z : 0.0;

                mat4 model_view = u_view * u_model * u_rubiks_model[cube_i];
                vec4 vertex_pos = model_view * vec4(inPos, 1.0);

                vertPos     = vertex_pos.xyz;
                vertTex     = tex;
                //highlight   = tex.z > 0.5 && cube_i == u_cube_hit ? 1.0 : 0.0;	
                //highlight   = tex.z > 0.5 && color_i == u_side_hit ? 1.0 : 0.0;
                highlight   = tex.z > 0.5 && cube_i == u_cube_hit && color_i == u_side_hit ? 1.0 : 0.0;		

		        gl_Position = u_projection * vertex_pos;
            }";

            string frag_shader = @"
            #version 460 core

            in vec3  vertPos;
            in vec4  vertTex;
            in float highlight;

            out vec4 fragColor;

            vec4 color_table[7] = vec4[7](
                vec4(0.5, 0.5, 0.5, 1.0),
                vec4(1.0, 0.0, 0.0, 1.0),
                vec4(0.0, 1.0, 0.0, 1.0),
                vec4(0.0, 0.0, 1.0, 1.0),
                vec4(1.0, 0.5, 0.0, 1.0),
                vec4(1.0, 1.0, 0.0, 1.0),
                vec4(1.0, 0.0, 1.0, 1.0)
            );

            void main()
            {
                int color_i = int(vertTex.z + 0.5);

                vec4 color = color_table[color_i]; 
                color.rgb *= max(0.5, highlight);

                fragColor  = color;
            }";

            this._prog = openGLFactory.VertexAndFragmentShaderProgram(vert_shader, frag_shader);
            this._prog.Generate();

            // matrices

            this._view = Matrix4.LookAt(0.0f, -4.0f, 0.0f, 0, 0, 0, 0, 0, 1);

            float angle  = 70.0f * (float)Math.PI / 180.0f;
            float aspect = (float)this._cx / (float)this._cy;

            this._projection = Matrix4.CreatePerspectiveFieldOfView(angle, aspect, 0.1f, 100.0f);

            // Model view projection shader storage block objects and buffers
            this._mvp_data = new TMVP(Matrix4.Identity, this._view, this._projection);
            this._mvp_ssbo = openGLFactory.NewStorageBuffer();
            this._mvp_ssbo.Create(ref this._mvp_data);
            this._mvp_ssbo.Bind(1);

            T_RUBIKS_DATA rubiks_data = rubiks_data = new T_RUBIKS_DATA();

            this._rubiks_ssbo = openGLFactory.NewStorageBuffer();
            this._rubiks_ssbo.Create(ref rubiks_data);
            this._rubiks_ssbo.Bind(2);

            TLightSource light_source = new TLightSource(new Vector4(-1.0f, -0.5f, -2.0f, 0.0f), 0.2f, 0.8f, 0.8f, 10.0f);

            this._light_ssbo = openGLFactory.NewStorageBuffer();
            this._light_ssbo.Create(ref light_source);
            this._light_ssbo.Bind(3);

            this._depth_pack_buffer = openGLFactory.NewPixelPackBuffer();
            this._depth_pack_buffer.Create <float>();

            // states

            GL.Viewport(0, 0, this._cx, this._cy);
            //GL.ClearColor(System.Drawing.Color.Beige);
            GL.ClearColor(0.2f, 0.3f, 0.3f, 1.0f);
            GL.Enable(EnableCap.DepthTest);
            GL.Enable(EnableCap.CullFace);
            GL.FrontFace(FrontFaceDirection.Ccw);
            GL.CullFace(CullFaceMode.Back);

            // controller

            var spin = new ModelSpinningControls(
                () => { return(this._period); },
                () => { return(new float[] { 0, 0, (float)this._cx, (float)this._cy }); },
                () => { return(this._view); }
                );

            spin.SetAttenuation(1.0f, 0.05f, 0.0f);
            _controls = new RubiksMouseControlsProxy(spin);

            float offset = 2.0f * 1.1f;
            float scale  = 1.0f / 3.0f;

            this._rubiks_cube = new RubiksControls(
                () => { return(this._period); },
                offset, scale
                );

            int shuffles = 11;

            this._rubiks_cube.Shuffle(shuffles);
            double time_s = 1.0;

            _rubiks_cube.AnimationTime = time_s;
        }
Example #4
0
        public void Setup(int cx, int cy)
        {
            this._cx = cx;
            this._cy = cy;

            // Version strings
            _version.Retrieve();

            // Get OpenGL extensions
            _extensions.Retrieve();

            // Debug callback
            _debug_callback.Init();

            // create Vertex Array Object, Array Buffer Object and Element Array Buffer Object

            (float[] attributes, uint[] indices) = new Cube().Create();
            TVertexFormat[] format =
            {
                new TVertexFormat(0, 0, 3, 0, false),
                new TVertexFormat(0, 1, 3, 3, false),
                //new TVertexFormat(0, ?, 2, 6, false),
                new TVertexFormat(0, 2, 4, 8, false),
            };

            _test_vao = openGLFactory.NewVertexArrayObject();
            _test_vao.AppendVertexBuffer(0, 12, attributes);
            _test_vao.Create(format, indices);
            _test_vao.Bind();

            // Create shader program

            string vert_shader = @"#version 460 core
            layout (location = 0) in vec4 a_pos;
            layout (location = 1) in vec3 a_nv;
            layout (location = 2) in vec4 a_color;
      
            layout (location = 0) out TVertexData
            {
                vec3 pos;
                vec3 nv;
                vec4 col;
            } outData;

            layout(std430, binding = 1) buffer MVP
            {
                mat4 proj;
                mat4 view;
                mat4 model;
            } mvp;

            void main()
            {
                mat4 mv_mat     = mvp.view * mvp.model;
                mat3 normal_mat = inverse(transpose(mat3(mv_mat))); 

                outData.nv   = normalize(normal_mat * a_nv);
                outData.col  = a_color;
                vec4 viewPos = mv_mat * a_pos;
                outData.pos  = viewPos.xyz / viewPos.w;
                gl_Position  = mvp.proj * viewPos;
            }";

            string frag_shader = @"#version 460 core
            out vec4 frag_color;
            
            layout (location = 0) in TVertexData
            {
                vec3 pos;
                vec3 nv;
                vec4 col;
            } inData;

            layout(std430, binding = 2) buffer TLight
            {
                vec4  u_lightDir;
                float u_ambient;
                float u_diffuse;
                float u_specular;
                float u_shininess;
            } light_data;
      
            void main()
            {
                vec3 color = inData.col.rgb;

                // ambient part
                vec3 lightCol = light_data.u_ambient * color;
                vec3 normalV  = normalize( inData.nv );
                vec3 eyeV     = normalize( -inData.pos );
                vec3 lightV   = normalize( -light_data.u_lightDir.xyz );

                // diffuse part
                float NdotL   = max( 0.0, dot( normalV, lightV ) );
                lightCol     += NdotL * light_data.u_diffuse * color;

                // specular part
                vec3  halfV     = normalize( eyeV + lightV );
                float NdotH     = max( 0.0, dot( normalV, halfV ) );
                float kSpecular = ( light_data.u_shininess + 2.0 ) * pow( NdotH, light_data.u_shininess ) / ( 2.0 * 3.14159265 );
                lightCol       += kSpecular * light_data.u_specular * color;

                frag_color = vec4( lightCol.rgb, inData.col.a );
            }";

            this._test_prog = openGLFactory.VertexAndFragmentShaderProgram(vert_shader, frag_shader);
            this._test_prog.Generate();

            // Model view projection shader storage block objects and buffers
            TMVP mvp = new TMVP(Matrix4.Identity, Matrix4.Identity, Matrix4.Identity);

            this._mvp_ssbo = openGLFactory.NewStorageBuffer();
            this._mvp_ssbo.Create(ref mvp);
            this._mvp_ssbo.Bind(1);

            TLightSource light_source = new TLightSource(new Vector4(-1.0f, -0.5f, -2.0f, 0.0f), 0.2f, 0.8f, 0.8f, 10.0f);

            this._light_ssbo = openGLFactory.NewStorageBuffer();
            this._light_ssbo.Create(ref light_source);
            this._light_ssbo.Bind(2);

            this._depth_pack_buffer = openGLFactory.NewPixelPackBuffer();
            this._depth_pack_buffer.Create <float>();

            // states

            GL.Viewport(0, 0, this._cx, this._cy);
            //GL.ClearColor(System.Drawing.Color.Beige);
            GL.ClearColor(0.2f, 0.3f, 0.3f, 1.0f);
            GL.Enable(EnableCap.DepthTest);
            GL.Enable(EnableCap.CullFace);
            GL.FrontFace(FrontFaceDirection.Ccw);
            GL.CullFace(CullFaceMode.Back);

            // matrices and controller

            this._view = Matrix4.LookAt(0.0f, -4.0f, 0.0f, 0, 0, 0, 0, 0, 1);

            float angle  = 90.0f * (float)Math.PI / 180.0f;
            float aspect = (float)this._cx / (float)this._cy;

            this._projection = Matrix4.CreatePerspectiveFieldOfView(angle, aspect, 0.1f, 100.0f);

            _controls = new NavigationControls(
                () => { return(new float[] { 0, 0, (float)this._cx, (float)this._cy }); },
                () => { return(this._view); },
                () => { return(this._projection); },
                this.GetDepth,
                (cursor_pos) => { return(new Vector3(0, 0, 0)); },
                (Matrix4 view) => { this._view = view; }
                );
        }
Example #5
0
        public void Setup(int cx, int cy)
        {
            this._cx = cx;
            this._cy = cy;

            // Version strings
            _version.Retrieve();

            // Get OpenGL extensions
            _extensions.Retrieve();

            // Debug callback
            _debug_callback.Init();

            // create Vertex Array Object, Array Buffer Object and Element Array Buffer Object

            (float[] attributes, uint[] indices) = new Cube().Create();
            TVertexFormat[] format =
            {
                new TVertexFormat(0, 0, 3, 0, false),
                new TVertexFormat(0, 1, 3, 3, false),
                new TVertexFormat(0, 2, 2, 6, false),
                //new TVertexFormat(0, 2, 4, 8, false),
            };

            _cube_vao = openGLFactory.NewVertexArrayObject();
            _cube_vao.AppendVertexBuffer(0, 12, attributes);
            _cube_vao.Create(format, indices);
            _cube_vao.Bind();

            // Create textures objects

            _tbos = new List <ITexture>();
            _tbos.Add(openGLFactory.NewTexture());
            _tbos[0].Create2D(_image_cx, _image_cy, ITexture.Format.RGBA_8);
            _tbos.Add(openGLFactory.NewTexture());
            _tbos[1].Create2D(_image_cx, _image_cy, ITexture.Format.RGBA_F32);
            _tbos.Add(openGLFactory.NewTexture());
            _tbos[2].Create2D(_image_cx, _image_cy, ITexture.Format.RGBA_F32);
            GL.TextureParameter(_tbos[2].Object, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
            GL.TextureParameter(_tbos[2].Object, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);

            // Create generators

            this._generators = new List <TextureGenerator>();
            this._generators.Add(new TextureGenerator(openGLFactory, TextureGenerator.TType.texture_test1, new ITexture[] { _tbos[0] }));
            this._generators.Add(new TextureGenerator(openGLFactory, TextureGenerator.TType.heightmap_test1, new ITexture[] { _tbos[1] }));
            this._generators.Add(new TextureGenerator(openGLFactory, TextureGenerator.TType.cone_step_map, new ITexture[] { _tbos[2] }, new ITexture[] { _tbos[1] }));

            // Create textures

            foreach (var generator in this._generators)
            {
                generator.Generate();
            }

            // Create shader program

            string vert_shader = @"#version 460 core
            
            layout (location = 0) in vec3 inPos;
            layout (location = 1) in vec3 inNV;
            layout (location = 2) in vec2 inUV;

            out TVertexData
            {
                vec3  pos;
                vec3  nv;
                vec2  uv;
                float clip;
            } out_data;

            layout(std430, binding = 1) buffer MVP
            {
                mat4 proj;
                mat4 view;
                mat4 model;
            } mvp;

            layout(location=1) uniform vec4 u_clipPlane;

            void main()
            {
                vec3 modelNV   = mat3( mvp.model ) * normalize( inNV );
                out_data.nv    = mat3( mvp.view ) * modelNV;
                out_data.uv    = inUV;
                vec4 worldPos  = mvp.model * vec4( inPos, 1.0 );
                vec4 viewPos   = mvp.view * worldPos;
                out_data.pos   = viewPos.xyz / viewPos.w;
                gl_Position    = mvp.proj * viewPos;
                vec4 clipPlane = vec4(normalize(u_clipPlane.xyz), u_clipPlane.w);
                out_data.clip  = dot(worldPos, clipPlane);
            }";

            string frag_shader = @"#version 460 core
            //#define NORMAL_MAP_TEXTURE
            #define NORMAL_MAP_QUALITY 1

            in TVertexData
            {
                vec3  pos;
                vec3  nv;
                vec2  uv;
                float clip;
            } in_data;

            out vec4 fragColor;

            layout(std430, binding = 1) buffer MVP
            {
                mat4 proj;
                mat4 view;
                mat4 model;
            } mvp;

            layout(location=1) uniform vec4 u_clipPlane;

            layout(std430, binding = 2) buffer TLight
            {
                vec4  u_lightDir;
                float u_ambient;
                float u_diffuse;
                float u_specular;
                float u_shininess;
            } light_data;

            layout(binding=1)  uniform sampler2D u_texture;
            layout(binding=2)  uniform sampler2D u_displacement_map;
            layout(location=2) uniform float     u_displacement_scale;
            layout(location=3) uniform vec2      u_parallax_quality;

            #if defined(NORMAL_MAP_TEXTURE)
            uniform sampler2D u_normal_map;
            #endif

            vec2 GetHeightAndCone( in vec2 texCoords )
            {
                vec2 h_and_c = texture( u_displacement_map, texCoords ).rg;
                return clamp( h_and_c, 0.0, 1.0 );
            }

            vec4 CalculateNormal( in vec2 texCoords )
            {
            #if defined(NORMAL_MAP_TEXTURE)
                float height = GetHeight( texCoords );
                vec3  tempNV = texture( u_normal_map, texCoords ).xyz * 2.0 / 1.0;
                return vec4( normalize( tempNV ), height );
            #else
                vec2 texOffs = 1.0 / textureSize( u_displacement_map, 0 ).xy;
                vec2 scale   = 1.0 / texOffs;
            #if NORMAL_MAP_QUALITY > 1
                float hx[9];
                hx[0] = texture( u_displacement_map, texCoords.st + texOffs * vec2(-1.0, -1.0) ).r;
                hx[1] = texture( u_displacement_map, texCoords.st + texOffs * vec2( 0.0, -1.0) ).r;
                hx[2] = texture( u_displacement_map, texCoords.st + texOffs * vec2( 1.0, -1.0) ).r;
                hx[3] = texture( u_displacement_map, texCoords.st + texOffs * vec2(-1.0,  0.0) ).r;
                hx[4] = texture( u_displacement_map, texCoords.st ).r;
                hx[5] = texture( u_displacement_map, texCoords.st + texOffs * vec2( 1.0, 0.0) ).r;
                hx[6] = texture( u_displacement_map, texCoords.st + texOffs * vec2(-1.0, 1.0) ).r;
                hx[7] = texture( u_displacement_map, texCoords.st + texOffs * vec2( 0.0, 1.0) ).r;
                hx[8] = texture( u_displacement_map, texCoords.st + texOffs * vec2( 1.0, 1.0) ).r;
                vec2  deltaH = vec2(hx[0]-hx[2] + 2.0*(hx[3]-hx[5]) + hx[6]-hx[8], hx[0]-hx[6] + 2.0*(hx[1]-hx[7]) + hx[2]-hx[8]); 
                float h_mid  = hx[4];
            #elif NORMAL_MAP_QUALITY > 0
                float h_mid  = texture( u_displacement_map, texCoords.st ).r;
                float h_xa   = texture( u_displacement_map, texCoords.st + texOffs * vec2(-1.0,  0.0) ).r;
                float h_xb   = texture( u_displacement_map, texCoords.st + texOffs * vec2( 1.0,  0.0) ).r;
                float h_ya   = texture( u_displacement_map, texCoords.st + texOffs * vec2( 0.0, -1.0) ).r;
                float h_yb   = texture( u_displacement_map, texCoords.st + texOffs * vec2( 0.0,  1.0) ).r;
                vec2  deltaH = vec2(h_xa-h_xb, h_ya-h_yb); 
            #else
                vec4  heights = textureGather( u_displacement_map, texCoords, 0 );
                vec2  deltaH  = vec2(dot(heights, vec4(1.0, -1.0, -1.0, 1.0)), dot(heights, vec4(-1.0, -1.0, 1.0, 1.0)));
                float h_mid   = heights.w; 
            #endif
                return vec4( normalize( vec3( deltaH * scale, 1.0 ) ), h_mid );
            #endif 
            }

            // the super fast version
            // (change number of iterations at run time)
            float intersect_cone_fixed(in vec2 dp, in vec3 ds)
            {
                // the 'not Z' component of the direction vector
                // (requires that the vector ds was normalized!)
                float iz = sqrt(1.0 - ds.z * ds.z);
                // my starting location (is at z=1,
                // and moving down so I don't have
                // to invert height maps)
                // texture lookup (and initialized to starting location)
                vec4 t;
                // scaling distance along vector ds
                float sc;
                // the ds.z component is positive!
                // (headed the wrong way, since
                // I'm using heightmaps)
                // find the initial location and height
                t = texture(u_displacement_map, dp);
                // right, I need to take one step.
                // I use the current height above the texture,
                // and the information about the cone-ratio
                // to size a single step. So it is fast and
                // precise! (like a coneified version of
                // 'space leaping', but adapted from voxels)
                sc = (1.0 - ds.z * sc - t.r) / (ds.z + iz / (t.g * t.g));
                // and repeat a few (4x) times
                t = texture(u_displacement_map, dp + ds.xy * sc);
                sc += (1.0 - ds.z * sc - t.r) / (ds.z + iz / (t.g * t.g));
                t = texture(u_displacement_map, dp + ds.xy * sc);
                sc += (1.0 - ds.z * sc - t.r) / (ds.z + iz / (t.g * t.g));
                t = texture(u_displacement_map, dp + ds.xy * sc);
                sc += (1.0 - ds.z * sc - t.r) / (ds.z + iz / (t.g * t.g));
                t = texture(u_displacement_map, dp + ds.xy * sc);
                sc += (1.0 - ds.z * sc - t.r) / (ds.z + iz / (t.g * t.g));
                // and another five!
                t = texture(u_displacement_map, dp + ds.xy * sc);
                sc += (1.0 - ds.z * sc - t.r) / (ds.z + iz / (t.g * t.g));
                t = texture(u_displacement_map, dp + ds.xy * sc);
                sc += (1.0 - ds.z * sc - t.r) / (ds.z + iz / (t.g * t.g));
                t = texture(u_displacement_map, dp + ds.xy * sc);
                sc += (1.0 - ds.z * sc - t.r) / (ds.z + iz / (t.g * t.g));
                t = texture(u_displacement_map, dp + ds.xy * sc);
                sc += (1.0 - ds.z * sc - t.r) / (ds.z + iz / (t.g * t.g));
                t = texture(u_displacement_map, dp + ds.xy * sc);
                sc += (1.0 - ds.z * sc - t.r) / (ds.z + iz / (t.g * t.g));
                // return the vector length needed to hit the height-map
                return (sc);
            }

            // (and you can do LOD by changing 'conesteps' based on size/distance, etc.)
            float intersect_cone_loop(in vec2 dp, in vec3 ds)
            {
                float maxBumpHeight = u_displacement_scale;

                const int conesteps = 10; // ???
                                          // the 'not Z' component of the direction vector
                                          // (requires that the vector ds was normalized!)
                float iz = sqrt(1.0 - ds.z * ds.z);
                // my starting location (is at z=1,
                // and moving down so I don't have
                // to invert height maps)
                // texture lookup (and initialized to starting location)
                vec4 t;
                // scaling distance along vector ds
                float sc = 0.0;
                //t=texture2D(stepmap,dp);
                //return (max(0.0,-(t.b-0.5)*ds.x-(t.a-0.5)*ds.y));
                // the ds.z component is positive!
                // (headed the wrong way, since
                // I'm using heightmaps)
                // adaptive (same speed as it averages the same # steps)
                //for (int i = int(float(conesteps)*(0.5+iz)); i > 0; --i)
                // fixed
                for (int i = conesteps; i > 0; --i)
                {
                    // find the new location and height
                    t = texture(u_displacement_map, dp + ds.xy * sc);
                    t.r = t.r * maxBumpHeight;
                    t.g = t.g / maxBumpHeight;

                    // right, I need to take one step.
                    // I use the current height above the texture,
                    // and the information about the cone-ratio
                    // to size a single step. So it is fast and
                    // precise! (like a coneified version of
                    // 'space leaping', but adapted from voxels)
                    sc += (1.0 - ds.z * sc - t.r) / (ds.z + iz / (t.g * t.g));
                }
                // return the vector length needed to hit the height-map
                return (sc);
            }

            // slowest, but best quality
            float intersect_cone_exact(in vec2 dp, in vec3 ds)
            {
                vec2 texsize = textureSize(u_displacement_map, 0);

                // minimum feature size parameter
                float w = 1.0 / max(texsize.x, texsize.y);
                // the 'not Z' component of the direction vector
                // (requires that the vector ds was normalized!)
                float iz = sqrt(1.0 - ds.z * ds.z);
                // my starting location (is at z=1,
                // and moving down so I don't have
                // to invert height maps)
                // texture lookup
                vec4 t;
                // scaling distance along vector ds
                float sc = 0.0;
                // the ds.z component is positive!
                // (headed the wrong way, since
                // I'm using heightmaps)
                // find the starting location and height
                t = texture(u_displacement_map, dp);
                while (1.0 - ds.z * sc > t.r)
                {
                    // right, I need to take one step.
                    // I use the current height above the texture,
                    // and the information about the cone-ratio
                    // to size a single step. So it is fast and
                    // precise! (like a coneified version of
                    // 'space leaping', but adapted from voxels)
                    sc += w + (1.0 - ds.z * sc - t.r) / (ds.z + iz / (t.g * t.g));
                    // find the new location and height
                    t = texture(u_displacement_map, dp + ds.xy * sc);
                }
                // back off one step
                sc -= w;
                // return the vector length needed to hit the height-map
                return (sc);
            }

            // Parallax Occlusion Mapping in GLSL [http://sunandblackcat.com/tipFullView.php?topicid=28]
            vec3 ConeStep(in float frontFace, in vec3 texDir3D, in vec2 texCoord)
            {
                float maxBumpHeight = 1.0;
                vec2 quality_range = u_parallax_quality;

                // [Determinante](https://de.wikipedia.org/wiki/Determinante)
                // A x B = A.x * B.y - A.y * B.x = dot(A, vec2(B.y,-B.x)) = det(mat2(A,B))

                // [How do you detect where two line segments intersect?](https://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect)
                vec2 R = normalize(vec2(length(texDir3D.xy), texDir3D.z));
                vec2 P = R * maxBumpHeight / texDir3D.z;

                vec2 tex_size = textureSize(u_displacement_map, 0).xy;
                vec2 min_tex_step = normalize(texDir3D.xy) / tex_size;
                float min_step = length(min_tex_step) * 1.0 / R.x;

                float t = 0.0;
                const int max_no_of_steps = int(5.0 + quality_range * 45.0);
                for (int i = 0; i < max_no_of_steps; ++i)
                {
                    vec3 sample_pt = vec3(texCoord.xy, maxBumpHeight) + texDir3D * t;

                    vec2 h_and_c = GetHeightAndCone(sample_pt.xy);
                    float h = h_and_c.x * maxBumpHeight;
                    float c = h_and_c.y * h_and_c.y / maxBumpHeight;

                    vec2 C = P + R * t;
                    if (C.y <= h)
                        break;

                    vec2 Q = vec2(C.x, h);
                    vec2 S = normalize(vec2(c, 1.0));
                    float new_t = dot(Q - P, vec2(S.y, -S.x)) / dot(R, vec2(S.y, -S.x));
                    t = max(t + min_step, new_t);
                }

                vec2 texC = texCoord.xy + texDir3D.xy * t;
                float mapHeight = GetHeightAndCone(texC.xy).x - step(frontFace, 0.0);
                return vec3(texC.xy, mapHeight);
            }

            void main()
            {
                vec3 objPosEs = in_data.pos;
                vec3 objNormalEs = in_data.nv;
                vec2 texCoords = in_data.uv.st;
                float frontFace = gl_FrontFacing ? 1.0 : -1.0; // TODO $$$ sign(dot(N,objPosEs));
                                                               //vec3  normalEs     = frontFace * normalize( objNormalEs );

                // orthonormal tangent space matrix
                //vec3  p_dx         = dFdx( objPosEs );
                //vec3  p_dy         = dFdy( objPosEs );
                //vec2  tc_dx        = dFdx( texCoords );
                //vec2  tc_dy        = dFdy( texCoords );
                //float texDet       = determinant( mat2( tc_dx, tc_dy ) );
                //vec3  tangentVec   = ( tc_dy.y * p_dx - tc_dx.y * p_dy ) / abs( texDet );
                //vec3  tangentEs    = normalize( tangentVec - normalEs * dot(tangentVec, normalEs ) );
                //mat3  tbnMat       = mat3( sign( texDet ) * tangentEs, cross( normalEs, tangentEs ), normalEs );

                // Followup: Normal Mapping Without Precomputed Tangents [http://www.thetenthplanet.de/archives/1180]
                vec3 N = frontFace * normalize(objNormalEs);
                vec3 dp1 = dFdx(objPosEs);
                vec3 dp2 = dFdy(objPosEs);
                vec2 duv1 = dFdx(texCoords);
                vec2 duv2 = dFdy(texCoords);
                vec3 dp2perp = cross(dp2, N);
                vec3 dp1perp = cross(N, dp1);
                vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;
                vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;
                float invmax = inversesqrt(max(dot(T, T), dot(B, B)));
                mat3 tbnMat = mat3(T * invmax, B * invmax, N * u_displacement_scale);
                mat3 inv_tbnMat = inverse(tbnMat);

                vec3 texDir3D = normalize(inv_tbnMat * objPosEs);
                vec3 newTexCoords = abs(u_displacement_scale) < 0.001 ? vec3(texCoords.st, 0.0) : ConeStep(frontFace, texDir3D, texCoords.st);

                //float depth_displ    = length(tbnMat * (newTexCoords.z * texDir3D.xyz / abs(texDir3D.z))); 
                //vec3  view_pos_displ = objPosEs - depth_displ * normalize(objPosEs);
                vec3 displ_vec = tbnMat * (newTexCoords.z * texDir3D.xyz / abs(texDir3D.z));
                vec3 view_pos_displ = objPosEs - displ_vec;
                vec4 modelPos = inverse(mvp.view) * vec4(view_pos_displ, 1.0);
                vec4 clipPlane = vec4(normalize(u_clipPlane.xyz), u_clipPlane.w);
                float clip_dist = dot(modelPos, clipPlane);
                //float clip_dist      = in_data.clip;
                if (clip_dist < 0.0)
                    discard;

                texCoords.st = newTexCoords.xy;
                vec4 normalVec = CalculateNormal(texCoords);
                //vec3  nvMappedEs   = normalize( tbnMat * normalVec.xyz );
                vec3 nvMappedEs = u_displacement_scale < 0.001 ? normalize(objNormalEs) : (normalize(transpose(inv_tbnMat) * normalVec.xyz));

                //vec3 color = in_data.col;
                vec3 color = texture(u_texture, texCoords.st).rgb;

                // ambient part
                vec3 lightCol = light_data.u_ambient * color;

                // diffuse part
                vec3 normalV = normalize(nvMappedEs);
                vec3 lightV = -normalize(mat3(mvp.view) * light_data.u_lightDir.xyz);
                float NdotL = max(0.0, dot(normalV, lightV));
                lightCol += NdotL * light_data.u_diffuse * color;

                // specular part
                vec3 eyeV = normalize(-objPosEs);
                vec3 halfV = normalize(eyeV + lightV);
                float NdotH = max(0.0, dot(normalV, halfV));
                float kSpecular = (light_data.u_shininess + 2.0) * pow(NdotH, light_data.u_shininess) / (2.0 * 3.14159265);
                lightCol += kSpecular * light_data.u_specular * color;

                fragColor = vec4(lightCol.rgb, 1.0);

                vec4 proj_pos_displ = mvp.proj * vec4(view_pos_displ.xyz, 1.0);
                float depth = 0.5 + 0.5 * proj_pos_displ.z / proj_pos_displ.w;
                gl_FragDepth = u_displacement_scale < 0.001 ? gl_FragCoord.z : depth;

                //fragColor = vec4( vec3(1.0-depth), 1.0 );
            }";

            this._parallax_prog = openGLFactory.VertexAndFragmentShaderProgram(vert_shader, frag_shader);
            this._parallax_prog.Generate();

            // Model view projection shader storage block objects and buffers
            TMVP mvp = new TMVP(Matrix4.Identity, Matrix4.Identity, Matrix4.Identity);

            this._mvp_ssbo = openGLFactory.NewStorageBuffer();
            this._mvp_ssbo.Create(ref mvp);
            this._mvp_ssbo.Bind(1);

            TLightSource light_source = new TLightSource(new Vector4(-1.0f, -0.5f, -2.0f, 0.0f), 0.2f, 0.8f, 0.8f, 10.0f);

            this._light_ssbo = openGLFactory.NewStorageBuffer();
            this._light_ssbo.Create(ref light_source);
            this._light_ssbo.Bind(2);

            // states

            GL.Viewport(0, 0, this._cx, this._cy);
            //GL.ClearColor(System.Drawing.Color.Beige);
            GL.ClearColor(0.2f, 0.3f, 0.3f, 1.0f);
            GL.Enable(EnableCap.DepthTest);

            // no face culling, because of clipping
            //GL.Enable(EnableCap.CullFace);
            GL.FrontFace(FrontFaceDirection.Ccw);
            GL.CullFace(CullFaceMode.Back);

            // matrices and controller

            this._view = Matrix4.LookAt(0.0f, 0.0f, 2.5f, 0, 0, 0, 0, 1, 0);

            float angle  = 90.0f * (float)Math.PI / 180.0f;
            float aspect = (float)this._cx / (float)this._cy;

            this._projection = Matrix4.CreatePerspectiveFieldOfView(angle, aspect, 0.1f, 100.0f);

            this._spin = new ModelSpinningControls(
                () => { return(this._period); },
                () => { return(new float[] { 0, 0, (float)this._cx, (float)this._cy }); },
                () => { return(this._view); }
                );
            this._spin.SetAttenuation(1.0f, 0.05f, 0.0f);

            // properties
            ViewModel.HeightScale  = 50;
            ViewModel.QualityScale = 50;
            ViewModel.ClipScale    = 50;
        }
Example #6
0
        public void Setup(int cx, int cy)
        {
            this._cx = cx;
            this._cy = cy;

            // Version strings
            _version.Retrieve();

            // Get OpenGL extensions
            _extensions.Retrieve();

            // Debug callback
            _debug_callback.Init();

            // create Vertex Array Object, Array Buffer Object and Element Array Buffer Object

            (float[] attributes, uint[] indices) = new Cube().Create();
            TVertexFormat[] format =
            {
                new TVertexFormat(0, 0, 3, 0, false),
                new TVertexFormat(0, 1, 3, 3, false),
                new TVertexFormat(0, 2, 2, 6, false),
                //new TVertexFormat(0, 2, 4, 8, false),
            };

            _cube_vao = openGLFactory.NewVertexArrayObject();
            _cube_vao.AppendVertexBuffer(0, 12, attributes);
            _cube_vao.Create(format, indices);
            _cube_vao.Bind();

            // Create textures

            Assembly assembly = Assembly.GetExecutingAssembly();
            //string[] names = assembly.GetManifestResourceNames();
            Stream textue_stream          = assembly.GetManifestResourceStream("OpenTK_parallax_relief_mapping.Resource.woodtiles.jpg");
            Stream normalmap_stream       = assembly.GetManifestResourceStream("OpenTK_parallax_relief_mapping.Resource.toy_box_normal.png");
            Stream displacementmap_stream = assembly.GetManifestResourceStream("OpenTK_parallax_relief_mapping.Resource.toy_box_disp.png");

            _texture = openGLFactory.NewTexture();
            _texture.Create2D(new Bitmap(textue_stream));
            _normalmap = openGLFactory.NewTexture();
            _normalmap.Create2D(new Bitmap(normalmap_stream));
            _displacementmap = openGLFactory.NewTexture();
            _displacementmap.Create2D(new Bitmap(displacementmap_stream));

            // Create shader program

            string vert_shader = @"#version 460 core
            layout (location = 0) in vec4 a_pos;
            layout (location = 1) in vec3 a_nv;
            layout (location = 2) in vec2 a_uv;
      
            layout (location = 0) out TVertexData
            {
                vec3 w_pos;
                vec3 w_nv;
                vec2 uv;
                vec3 eye_pos;
            } outData;

            layout(std430, binding = 1) buffer MVP
            {
                mat4 proj;
                mat4 view;
                mat4 model;
            } mvp;

            void main()
            {
                mat3 normal_mat = inverse(transpose(mat3(mvp.model))); 

                outData.w_nv    = normalize(normal_mat * a_nv);
                outData.uv      = a_uv;
                vec4 worldPos   = mvp.model * a_pos;
                outData.w_pos   = worldPos.xyz / worldPos.w;
                outData.eye_pos = inverse(mvp.view)[3].xyz;
                gl_Position     = mvp.proj * mvp.view * mvp.model * a_pos;
            }";

            string frag_shader = @"#version 460 core
            out vec4 frag_color;
            
            layout (location = 0) in TVertexData
            {
                vec3 w_pos;
                vec3 w_nv;
                vec2 uv;
                vec3 eye_pos;
            } inData;

            layout(std430, binding = 2) buffer TLight
            {
                vec4  u_lightDir;
                float u_ambient;
                float u_diffuse;
                float u_specular;
                float u_shininess;
            } light_data;

            layout(binding=1) uniform sampler2D u_diffuse;
            layout(binding=2) uniform sampler2D u_normal_map;
            layout(binding=3) uniform sampler2D u_displacement_map;
            layout(location=1) uniform float u_height_scale;

            vec2 ParallaxMapping (vec2 texCoord, vec3 viewDir)
            {
                float numLayers = 32.0 - 31.0 * abs(dot(vec3(0.0, 0.0, 1.0), viewDir));
                float layerDepth = 1.0 / numLayers;

                vec2 P = viewDir.xy / viewDir.z * u_height_scale;
                vec2 deltaTexCoords = P / numLayers;
                vec2 currentTexCoords = texCoord;

                float currentLayerDepth = 0.0;
                float currentDepthMapValue = texture2D(u_displacement_map, currentTexCoords).r;
                for (int i=0; i<32; ++ i)
                {
                    if (currentLayerDepth >= currentDepthMapValue)
                        break;
                    currentTexCoords -= deltaTexCoords;
                    currentDepthMapValue = texture2D(u_displacement_map, currentTexCoords).r;
                    currentLayerDepth += layerDepth;
                }

                vec2 prevTexCoords = currentTexCoords + deltaTexCoords;
                float afterDepth = currentDepthMapValue - currentLayerDepth;
                float beforeDepth = texture2D(u_displacement_map, prevTexCoords).r - currentLayerDepth + layerDepth;

                float weight = afterDepth / (afterDepth - beforeDepth);
                return prevTexCoords * weight + currentTexCoords * (1.0 - weight);
            }
      
            void main()
            {
                vec3  N       = normalize(inData.w_nv);
                vec3  dp1     = dFdx( inData.w_pos );
                vec3  dp2     = dFdy( inData.w_pos );
                vec2  duv1    = dFdx( inData.uv );
                vec2  duv2    = dFdy( inData.uv );
                vec3  dp2perp = cross(dp2, N);
                vec3  dp1perp = cross(N, dp1);
                vec3  T       = dp2perp * duv1.x + dp1perp * duv2.x;
                vec3  B       = dp2perp * duv1.y + dp1perp * duv2.y;
                float invmax  = inversesqrt(max(dot(T, T), dot(B, B)));
                mat3  tm      = mat3(T * invmax, B * invmax, N);
                mat3  tbn_inv = mat3(vec3(tm[0].x, tm[1].x, tm[2].x), vec3(tm[0].y, tm[1].y, tm[2].y), vec3(tm[0].z, tm[1].z, tm[2].z));

                vec3 view_dir = tbn_inv * normalize(inData.w_pos - inData.eye_pos);
                vec2 uv = ParallaxMapping(inData.uv, view_dir);
                if (uv.x > 1.0 || uv.y > 1.0 || uv.x < 0.0 || uv.y < 0.0)
                    discard;

                vec4 color   = texture(u_diffuse, uv.xy);
                vec3 normalV = texture2D(u_normal_map, uv.st).xyz * 2.0 - 1.0;
                normalV      = normalize(vec3(normalV.xy, normalV.z / max(0.001, 10.0 * u_height_scale)));

                // ambient part
                vec3 lightCol = light_data.u_ambient * color.rgb;
                vec3 eyeV     = normalize(inData.eye_pos - inData.w_pos);
                vec3 lightV   = tbn_inv * normalize( -light_data.u_lightDir.xyz );

                // diffuse part
                float NdotL   = max( 0.0, dot( normalV, lightV ) );
                lightCol     += NdotL * light_data.u_diffuse * color.rgb;

                // specular part
                vec3  halfV     = normalize( eyeV + lightV );
                float NdotH     = max( 0.0, dot( normalV, halfV ) );
                float kSpecular = ( light_data.u_shininess + 2.0 ) * pow( NdotH, light_data.u_shininess ) / ( 2.0 * 3.14159265 );
                lightCol       += kSpecular * light_data.u_specular * color.rgb;
 
                frag_color = vec4( lightCol.rgb, color.a );
            }";

            this._parallax_prog = openGLFactory.VertexAndFragmentShaderProgram(vert_shader, frag_shader);
            this._parallax_prog.Generate();

            // Model view projection shader storage block objects and buffers
            TMVP mvp = new TMVP(Matrix4.Identity, Matrix4.Identity, Matrix4.Identity);

            this._mvp_ssbo = openGLFactory.NewStorageBuffer();
            this._mvp_ssbo.Create(ref mvp);
            this._mvp_ssbo.Bind(1);

            TLightSource light_source = new TLightSource(new Vector4(-1.0f, -0.5f, -2.0f, 0.0f), 0.2f, 0.8f, 0.8f, 10.0f);

            this._light_ssbo = openGLFactory.NewStorageBuffer();
            this._light_ssbo.Create(ref light_source);
            this._light_ssbo.Bind(2);

            // states

            GL.Viewport(0, 0, this._cx, this._cy);
            //GL.ClearColor(System.Drawing.Color.Beige);
            GL.ClearColor(0.2f, 0.3f, 0.3f, 1.0f);
            GL.Enable(EnableCap.DepthTest);
            GL.Enable(EnableCap.CullFace);
            GL.FrontFace(FrontFaceDirection.Ccw);
            GL.CullFace(CullFaceMode.Back);

            // matrices and controller

            this._view = Matrix4.LookAt(0.0f, 0.0f, 3.0f, 0, 0, 0, 0, 1, 0);

            float angle  = 90.0f * (float)Math.PI / 180.0f;
            float aspect = (float)this._cx / (float)this._cy;

            this._projection = Matrix4.CreatePerspectiveFieldOfView(angle, aspect, 0.1f, 100.0f);

            this._spin = new ModelSpinningControls(
                () => { return(this._period); },
                () => { return(new float[] { 0, 0, (float)this._cx, (float)this._cy }); },
                () => { return(this._view); }
                );
            this._spin.SetAttenuation(1.0f, 0.05f, 0.0f);

            // properties
            ViewModel.HeightScale = 100;
        }
Example #7
0
        //! On load window (once)
        protected override void OnLoad()
        {
            _version        = openGLFactory.NewVersionInformation(Console.WriteLine);
            _extensions     = openGLFactory.NewExtensionInformation();
            _debug_callback = openGLFactory.NewDebugCallback(Console.WriteLine);

            // Version strings
            _version.Retrieve();

            // Get OpenGL extensions
            _extensions.Retrieve();

            // Debug callback
            _debug_callback.Init();

            // create Vertex Array Object, Array Buffer Object and Element Array Buffer Object

            float[] vquad =
            {
                // x      y     z      r     g     b     a
                -1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
                1.0f,  -1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
                1.0f,   1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
                -1.0f,  1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f
            };

            uint [] iquad = { 0, 1, 2, 0, 2, 3 };

            TVertexFormat[] format =
            {
                new TVertexFormat(0, 0, 3, 0, false),
                new TVertexFormat(0, 1, 4, 3, false),
            };

            _test_vao = openGLFactory.NewVertexArrayObject();
            _test_vao.AppendVertexBuffer(0, 7, vquad);
            _test_vao.Create(format, iquad);

            // Create shader program

            string vert_shader = @"#version 460 core
            layout (location = 0) in vec4 a_pos;
            layout (location = 1) in vec4 a_color;
      
            out vec4 v_color;
            uniform mat4 u_transform;

            void main()
            {
                v_color     = a_color;
                gl_Position = u_transform * a_pos; 
            }";

            string frag_shader = @"#version 460 core
            out vec4 frag_color;
            in  vec4 v_color;
      
            void main()
            {
                frag_color = v_color; 
            }";

            this._test_prog = openGLFactory.VertexAndFragmentShaderProgram(vert_shader, frag_shader);
            this._test_prog.Generate();

            this._test_prog.Use();

            // states

            GL.ClearColor(0.2f, 0.3f, 0.3f, 1.0f);

            base.OnLoad();
        }
Example #8
0
        //! On load window (once)
        protected override void OnLoad()
        {
            _version        = openGLFactory.NewVersionInformation(Console.WriteLine);
            _extensions     = openGLFactory.NewExtensionInformation();
            _debug_callback = openGLFactory.NewDebugCallback(Console.WriteLine);

            // Version strings
            _version.Retrieve();

            // Get OpenGL extensions
            _extensions.Retrieve();

            // Debug callback
            _debug_callback.Init();

            // create Vertex Array Object, Array Buffer Object and Element Array Buffer Object

            (float[] attributes, uint[] indices) = new TrefoilKnot(256, 16).Create();
            TVertexFormat[] format =
            {
                new TVertexFormat(0, 0, 3, 0, false),
                new TVertexFormat(0, 1, 3, 3, false),
                //new TVertexFormat(0, ?, 2, 6, false),
                new TVertexFormat(0, 2, 4, 8, false),
            };

            _test_vao = openGLFactory.NewVertexArrayObject();
            _test_vao.AppendVertexBuffer(0, 12, attributes);
            _test_vao.Create(format, indices);
            _test_vao.Bind();

            // Create shader program

            string vert_shader = @"#version 460 core
            layout (location = 0) in vec4 a_pos;
            layout (location = 1) in vec3 a_nv;
            layout (location = 2) in vec4 a_color;
      
            layout (location = 0) out TVertexData
            {
                vec3 pos;
                vec3 nv;
                vec4 col;
            } outData;

            layout(std430, binding = 1) buffer MVP
            {
                mat4 proj;
                mat4 view;
                mat4 model;
            } mvp;

            void main()
            {
                mat4 mv_mat     = mvp.view * mvp.model;
                mat3 normal_mat = inverse(transpose(mat3(mv_mat))); 

                outData.nv   = normalize(normal_mat * a_nv);
                outData.col  = a_color;
                vec4 viewPos = mv_mat * a_pos;
                outData.pos  = viewPos.xyz / viewPos.w;
                gl_Position  = mvp.proj * viewPos;
            }";

            string frag_shader = @"#version 460 core
            out vec4 frag_color;
            
            layout (location = 0) in TVertexData
            {
                vec3 pos;
                vec3 nv;
                vec4 col;
            } inData;

            layout(std430, binding = 2) buffer TLight
            {
                vec4  u_lightDir;
                float u_ambient;
                float u_diffuse;
                float u_specular;
                float u_shininess;
            } light_data;
      
            void main()
            {
                vec3 color = inData.col.rgb;

                // ambient part
                vec3 lightCol = light_data.u_ambient * color;
                vec3 normalV  = normalize( inData.nv );
                vec3 eyeV     = normalize( -inData.pos );
                vec3 lightV   = normalize( -light_data.u_lightDir.xyz );

                // diffuse part
                float NdotL   = max( 0.0, dot( normalV, lightV ) );
                lightCol     += NdotL * light_data.u_diffuse * color;

                // specular part
                vec3  halfV     = normalize( eyeV + lightV );
                float NdotH     = max( 0.0, dot( normalV, halfV ) );
                float kSpecular = ( light_data.u_shininess + 2.0 ) * pow( NdotH, light_data.u_shininess ) / ( 2.0 * 3.14159265 );
                lightCol       += kSpecular * light_data.u_specular * color;

                frag_color = vec4( lightCol.rgb, inData.col.a );
            }";

            this._test_prog = openGLFactory.VertexAndFragmentShaderProgram(vert_shader, frag_shader);
            this._test_prog.Generate();

            // Model view projection shader storage block objects and buffers
            TMVP mvp = new TMVP(Matrix4.Identity, Matrix4.Identity, Matrix4.Identity);

            this._mvp_ssbo = openGLFactory.NewStorageBuffer();
            this._mvp_ssbo.Create(ref mvp);
            this._mvp_ssbo.Bind(1);

            TLightSource light_source = new TLightSource(new Vector4(-1.0f, -0.5f, -2.0f, 0.0f), 0.2f, 0.8f, 0.8f, 10.0f);

            this._light_ssbo = openGLFactory.NewStorageBuffer();
            this._light_ssbo.Create(ref light_source);
            this._light_ssbo.Bind(2);

            // states

            GL.ClearColor(0.2f, 0.3f, 0.3f, 1.0f);
            GL.Enable(EnableCap.DepthTest);
            GL.Enable(EnableCap.CullFace);
            GL.FrontFace(FrontFaceDirection.Ccw);
            GL.CullFace(CullFaceMode.Back);

            // matrices and controller

            this._view = Matrix4.LookAt(0.0f, 0.0f, 1.5f, 0, 0, 0, 0, 1, 0);

            var spin = new ModelSpinningControls(
                () => { return(this._period); },
                () => { return(new float[] { 0, 0, (float)this.Size.X, (float)this.Size.Y }); },
                () => { return(this._view); }
                );

            spin.SetAttenuation(1.0f, 0.05f, 0.0f);
            this._controls = spin;

            base.OnLoad();
        }
Example #9
0
        //! On load window (once)
        protected override void OnLoad()
        {
            _version        = openGLFactory.NewVersionInformation(Console.WriteLine);
            _extensions     = openGLFactory.NewExtensionInformation();
            _debug_callback = openGLFactory.NewDebugCallback(Console.WriteLine);

            // Version strings
            _version.Retrieve();

            // Get OpenGL extensions
            _extensions.Retrieve();

            // Debug callback
            _debug_callback.Init();

            // create Vertex Array Object, Array Buffer Object and Element Array Buffer Object

            float[] vquad =
            {
                // x      y     z      u     v
                -0.5f, -0.5f, 0.0f, 0.0f, 1.0f,
                0.5f,  -0.5f, 0.0f, 1.0f, 1.0f,
                0.5f,   0.5f, 0.0f, 1.0f, 0.0f,
                -0.5f,  0.5f, 0.0f, 0.0f, 0.0f
            };

            uint[] iquad = { 0, 1, 2, 0, 2, 3 };

            TVertexFormat[] format =
            {
                new TVertexFormat(0, 0, 3, 0, false),
                new TVertexFormat(0, 1, 2, 3, false),
            };

            _test_vao = openGLFactory.NewVertexArrayObject();
            _test_vao.AppendVertexBuffer(0, 5, vquad);
            _test_vao.Create(format, iquad);

            // Create texture

            Assembly assembly = Assembly.GetExecutingAssembly();

            string[] names           = assembly.GetManifestResourceNames();
            Stream   resource_stream = assembly.GetManifestResourceStream("OpenTK_example_3.Resource.background.jpg");

            _test_texture = openGLFactory.NewTexture();
            _test_texture.Create2D(new Bitmap(resource_stream));

            // Create shader program

            string vert_shader = @"#version 460 core
            layout (location = 0) in vec4 a_pos;
            layout (location = 1) in vec2 a_uv;
      
            out vec2 v_uv;

            void main()
            {
                v_uv        = a_uv;
                gl_Position = a_pos; 
            }";

            string frag_shader = @"#version 460 core
            out vec4 frag_color;
            in  vec2 v_uv;
            layout(binding = 7) uniform sampler2D u_texture; 
      
            void main()
            {
                frag_color = texture(u_texture, v_uv).rgba; 
            }";

            this._test_prog = openGLFactory.VertexAndFragmentShaderProgram(vert_shader, frag_shader);
            this._test_prog.Generate();

            this._test_prog.Use();

            // states

            GL.ClearColor(0.2f, 0.3f, 0.3f, 1.0f);

            base.OnLoad();
        }