Пример #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();

            // 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;
        }
Пример #2
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; }
                );
        }