Esempio n. 1
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;
        }
Esempio n. 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      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();
        }