Beispiel #1
0
        protected override void OnUpdateFrame(FrameEventArgs e)
        {
            base.OnUpdateFrame(e);

            ProcessInput();

            List <Vector3> verts     = new List <Vector3>();
            List <int>     inds      = new List <int>();
            List <Vector3> colors    = new List <Vector3>();
            List <Vector2> texcoords = new List <Vector2>();

            // Assemble vertex and indice data for all volumes
            int vertcount = 0;

            foreach (Volume v in objects)
            {
                verts.AddRange(v.GetVerts().ToList());
                inds.AddRange(v.GetIndices(vertcount).ToList());
                colors.AddRange(v.GetColorData().ToList());
                texcoords.AddRange(v.GetTextureCoords());
                vertcount += v.VertCount;
            }

            vertdata     = verts.ToArray();
            indicedata   = inds.ToArray();
            coldata      = colors.ToArray();
            texcoorddata = texcoords.ToArray();

            GL.BindBuffer(BufferTarget.ArrayBuffer, shaders[activeShader].GetBuffer("vPosition"));

            GL.BufferData <Vector3>(BufferTarget.ArrayBuffer, (IntPtr)(vertdata.Length * Vector3.SizeInBytes), vertdata, BufferUsageHint.StaticDraw);
            GL.VertexAttribPointer(shaders[activeShader].GetAttribute("vPosition"), 3, VertexAttribPointerType.Float, false, 0, 0);

            // Buffer vertex color if shader supports it
            if (shaders[activeShader].GetAttribute("vColor") != -1)
            {
                GL.BindBuffer(BufferTarget.ArrayBuffer, shaders[activeShader].GetBuffer("vColor"));
                GL.BufferData <Vector3>(BufferTarget.ArrayBuffer, (IntPtr)(coldata.Length * Vector3.SizeInBytes), coldata, BufferUsageHint.StaticDraw);
                GL.VertexAttribPointer(shaders[activeShader].GetAttribute("vColor"), 3, VertexAttribPointerType.Float, true, 0, 0);
            }


            // Buffer texture coordinates if shader supports it
            if (shaders[activeShader].GetAttribute("texcoord") != -1)
            {
                GL.BindBuffer(BufferTarget.ArrayBuffer, shaders[activeShader].GetBuffer("texcoord"));
                GL.BufferData <Vector2>(BufferTarget.ArrayBuffer, (IntPtr)(texcoorddata.Length * Vector2.SizeInBytes), texcoorddata, BufferUsageHint.StaticDraw);
                GL.VertexAttribPointer(shaders[activeShader].GetAttribute("texcoord"), 2, VertexAttribPointerType.Float, true, 0, 0);
            }

            // Update object positions
            time += (float)e.Time;

            objects[0].Position = new Vector3(0.3f, -0.5f + (float)Math.Sin(time), -3.0f);
            objects[0].Rotation = new Vector3(0.55f * time, 0.25f * time, 0);
            objects[0].Scale    = new Vector3(0.5f, 0.5f, 0.5f);

            objects[1].Position = new Vector3(-1f, 0.5f + (float)Math.Cos(time), -2.0f);
            objects[1].Rotation = new Vector3(-0.25f * time, -0.35f * time, 0);
            objects[1].Scale    = new Vector3(0.7f, 0.7f, 0.7f);

            // Update model view matrices
            foreach (Volume v in objects)
            {
                v.CalculateModelMatrix();
                v.ViewProjectionMatrix      = cam.GetViewMatrix() * Matrix4.CreatePerspectiveFieldOfView(1.3f, ClientSize.Width / (float)ClientSize.Height, 1.0f, 40.0f);
                v.ModelViewProjectionMatrix = v.ModelMatrix * v.ViewProjectionMatrix;
            }

            GL.UseProgram(shaders[activeShader].ProgramID);

            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);

            // Buffer index data
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, ibo_elements);
            GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(indicedata.Length * sizeof(int)), indicedata, BufferUsageHint.StaticDraw);
        }
        public void Draw()
        {
            Image.Clear(Color.Gray);

            float avgSteps    = 0;
            float height_mult = (float)Math.Tan(MathHelper.DegreesToRadians(fov * 0.5f));

            //int col = Color.Black.ToArgb();

            unsafe
            {
                Matrix4 projMat = Matrix4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(fov), w / (float)h, 0.001f);
                Matrix4 viewMat = Matrix4.LookAt(Position, Position + Direction, Up);
                var     vp      = viewMat * projMat;
                var     ivp     = Matrix4.Invert(vp);

                //Compute the corners of the frustum
                //Determine AABB and adjust pixel range

                //Compute world position for each vertical 'ray'
                for (int ix = -w * 2; ix < w * 2; ix++)
                {
                    int   raySteps = 0;
                    float fx       = ix / (w * 0.5f);

                    Vector3 rayDir   = new Vector3(fx, 0, 0.001f);
                    var     rayDir_4 = Vector4.Transform(new Vector4(rayDir, 1), ivp);
                    rayDir_4 /= rayDir_4.W;
                    rayDir    = rayDir_4.Xyz - Position;

                    VoxelSpan[] spans = null;
                    float       z     = 1f;
                    rayDir *= z;

                    Vector3 rayPos = rayDir + Position;
                    raySteps++;

                    do
                    {
                        float col_h = (raySteps * z * height_mult);
                        col_h = col_h / Vector3.Dot(Vector3.UnitZ, Up);
                        var topPos = rayPos + Up * col_h;
                        var btmPos = rayPos - Up * col_h;

                        spans = data.Get(rayPos.X, rayPos.Y);
                        if (spans != null)
                        {
                            if ((btmPos.Z >= spans[spans.Length - 1].Stop) | (topPos.Z < spans[0].Start))
                            {
                                rayPos += rayDir;
                                raySteps++;
                                continue;
                            }

                            //For now trace columns with brute force samples, later use a proper line drawing algorithm instead
                            //Apply this span from top to bottom with depth test
                            //Check if the Z-coordinate falls within a span
                            //Determine visible bounds for all spans
                            for (int j = 0; j < spans.Length; j++)
                            {
                                if (topPos.Z >= spans[j].Start && btmPos.Z < spans[j].Stop)
                                {
                                    Vector4 stStart = new Vector4(rayPos.X, rayPos.Y, Math.Min(topPos.Z, spans[j].Start), 1);
                                    Vector4 stStop  = new Vector4(rayPos.X, rayPos.Y, Math.Max(btmPos.Z, spans[j].Stop), 1);

                                    var stStart_ = Vector4.Transform(stStart, vp);
                                    var stStop_  = Vector4.Transform(stStop, vp);

                                    var stStart_w = stStart_ / stStart_.W;
                                    var stStop_w  = stStop_ / stStop_.W;

                                    var startX = (stStart_w.X * w / 2 + w / 2);
                                    var startY = h - (stStart_w.Y * h / 2 + h / 2);

                                    var stopX = (stStop_w.X * w / 2 + w / 2);
                                    var stopY = h - (stStop_w.Y * h / 2 + h / 2);

                                    float dist  = (float)Math.Sqrt((rayPos.X - Position.X) * (rayPos.X - Position.X) + (rayPos.Y - Position.Y) * (rayPos.Y - Position.Y));
                                    int   iDist = (int)dist % 256;
                                    var   col   = Color.FromArgb(iDist, iDist, iDist);

                                    bool lineVis = true;
                                    if (startX < 0 && stopX < 0)
                                    {
                                        lineVis = false;
                                    }
                                    if (startX >= w && stopX >= w)
                                    {
                                        lineVis = false;
                                    }
                                    if (startY < 0 && stopY < 0)
                                    {
                                        lineVis = false;
                                    }
                                    if (startY >= h && stopY >= h)
                                    {
                                        lineVis = false;
                                    }

                                    if (lineVis)
                                    {
                                        Image.DrawLine(startX, startY, stStart_w.Z, stopX, stopY, stStop_w.Z, col);
                                    }
                                }
                            }
                        }
                        rayPos += rayDir;
                        raySteps++;
                    } while (rayPos.X < VoxelData.WorldSide && rayPos.Y < VoxelData.WorldSide && rayPos.X >= 0 && rayPos.Y >= 0);

                    avgSteps += raySteps;
                }
            }

            Console.WriteLine("Average Steps: " + avgSteps / w);
        }
Beispiel #3
0
        protected override void OnUpdateFrame(FrameEventArgs e)
        {
            base.OnUpdateFrame(e);

            if (!Focused)
            {
                return;
            }

            KeyboardState k = OpenTK.Input.Keyboard.GetState();
            MouseState    m = OpenTK.Input.Mouse.GetState();

            bool isShiftDown = false;

            if (k[Key.LShift] || k[Key.RShift])
            {
                isShiftDown = true;
            }

            //TODO make cam speed/shift speedup controllable from GUI
            float camSpeed  = 10f * (float)e.Time * (isShiftDown ? 3f : 1f);
            float zoomSpeed = (float)Math.PI * (float)e.Time * (isShiftDown ? 0.2f : 0.1f);

            if (k[Key.W])
            {
                cam.Move(-camSpeed);
            }
            if (k[Key.A])
            {
                cam.Strafe(-camSpeed);
            }
            if (k[Key.S])
            {
                cam.Move(camSpeed);
            }
            if (k[Key.D])
            {
                cam.Strafe(camSpeed);
            }
            if (k[Key.Q])
            {
                cam.Elevate(camSpeed);
            }
            if (k[Key.E])
            {
                cam.Elevate(-camSpeed);
            }
            if (k[Key.Z])
            {
                zoom += zoomSpeed;
                if (zoom > MathHelper.PiOver2)
                {
                    zoom = MathHelper.PiOver2;
                }
            }
            if (k[Key.C])
            {
                zoom -= zoomSpeed;
                if (zoom < 0.002f)
                {
                    zoom = 0.002f;
                }
            }

            if (m[MouseButton.Right])
            {
                cam.RotatePitch((m.X - prevM.X) * (float)e.Time * 2f);
                cam.RotateHeading((prevM.Y - m.Y) * (float)e.Time * 2f);
            }

            float   aspect = Width / (float)Height;
            Matrix4 persp  = Matrix4.CreatePerspectiveFieldOfView(zoom, aspect, 0.1f, 1000f);

            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadMatrix(ref persp);
            GL.MatrixMode(MatrixMode.Modelview);
            cam.LoadView();
            if (crowd != null)
            {
                crowd.Update((float)e.Time);
            }

            prevK = k;
            prevM = m;

            if (gwenRenderer.TextCacheSize > 1000)
            {
                gwenRenderer.FlushTextCache();
            }
        }
Beispiel #4
0
        static void Main(string[] args)
        {
            // Инициализируем главное окно
            Glut.glutInit();
            Glut.glutInitDisplayMode(Glut.GLUT_DOUBLE | Glut.GLUT_DEPTH);
            Glut.glutInitWindowSize(Width, Height);
            Glut.glutCreateWindow("OpenGL Ex. #44");
            Gl.Viewport(0, 0, Width, Height);

            Glut.glutIdleFunc(OnRenderFrame);
            Glut.glutDisplayFunc(OnDisplay);
            Glut.glutCloseFunc(OnClose);

            Gl.Enable(EnableCap.Blend);
            Gl.Enable(EnableCap.DepthTest);
            Gl.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
            Gl.DepthFunc(DepthFunction.Less);
            Gl.ClearColor(0.44f, 0.49f, 0.527f, 1);

            program          = new ShaderProgram(VertexShader, FragmentShader);
            program_cyrcle   = new ShaderProgram(VertexShader_Cyrcle, FragmentShader);
            program_cylindre = new ShaderProgram(VertexShader_Cylinder, FragmentShader);

            ProjectionMatrix = Matrix4.CreatePerspectiveFieldOfView(0.41f, (float)Width / Height, 0.1f, 1000f);
            ViewMatrix       = Matrix4.LookAt(new Vector3(32.5f, 10.8f, -54.8f), new Vector3(13.4f, 0.7f, -3.0f), new Vector3(0, 1, 0));

            program.Use();
            program["projection_matrix"].SetValue(ProjectionMatrix);
            program["view_matrix"].SetValue(ViewMatrix);

            program_cyrcle.Use();
            program_cyrcle["projection_matrix"].SetValue(ProjectionMatrix);
            program_cyrcle["view_matrix"].SetValue(ViewMatrix);

            program_cylindre.Use();
            program_cylindre["projection_matrix"].SetValue(ProjectionMatrix);
            program_cylindre["view_matrix"].SetValue(ViewMatrix);

            ChessboardTexrute  = loadTexture("ChessBoard.png");
            panelTexture       = loadTexture("panel.png");
            cornerTexture      = loadTexture("corner.png");
            crossTexture       = loadTexture("cross.png");
            cyrcleTexture      = loadTexture("cyrcle.png");
            cylindrBodyTexture = loadTexture("Wood.jpg");
            sphereTexture      = loadTexture("Earth.jpg");

            panel = new VBO <Vector3>(new Vector3[] {
                new Vector3(0.0f, 0.0f, 0.0f),
                new Vector3(1.0f, 0.0f, 0.0f),
                new Vector3(1.0f, 0.0f, 1.0f),
                new Vector3(0.0f, 0.0f, 1.0f)
            });
            panelUV = new VBO <Vector2>(new Vector2[]  {
                new Vector2(0, 0),
                new Vector2(1, 0),
                new Vector2(1, 1),
                new Vector2(0, 1)
            });
            panelTriangles = new VBO <uint>(new uint[] {
                0, 1, 2,
                0, 2, 3
            }, BufferTarget.ElementArrayBuffer);

            corner = new VBO <Vector3>(new Vector3[] {
                new Vector3(0.0f, 0.0f, 0.0f),
                new Vector3(1.0f, 0.0f, 0.0f),
                new Vector3(1.0f, 0.0f, 0.5f),
                new Vector3(0.5f, 0.0f, 0.5f),
                new Vector3(0.5f, 0.0f, 1.0f),
                new Vector3(0.0f, 0.0f, 1.0f)
            });
            cornerUV = new VBO <Vector2>(new Vector2[]  {
                new Vector2(0.0f, 0.0f),
                new Vector2(1.0f, 0.0f),
                new Vector2(1.0f, 0.5f),
                new Vector2(0.5f, 0.5f),
                new Vector2(0.5f, 1.0f),
                new Vector2(0.0f, 1.0f)
            });
            cornerTriangles = new VBO <uint>(new uint[] {
                0, 1, 5,
                1, 2, 3,
                3, 4, 5
            }, BufferTarget.ElementArrayBuffer);

            cross = new VBO <Vector3>(new Vector3[] {
                new Vector3(0.0f, 0.0f, 0.0f),
                new Vector3(0.25f, 0.0f, 0.0f),
                new Vector3(0.5f, 0.0f, 0.25f),
                new Vector3(0.75f, 0.0f, 0.0f),
                new Vector3(1.0f, 0.0f, 0.0f),
                new Vector3(1.0f, 0.0f, 0.25f),
                new Vector3(0.75f, 0.0f, 0.5f),
                new Vector3(1.0f, 0.0f, 0.75f),
                new Vector3(1.0f, 0.0f, 1.0f),
                new Vector3(0.75f, 0.0f, 1.0f),
                new Vector3(0.5f, 0.0f, 0.75f),
                new Vector3(0.25f, 0.0f, 1.0f),
                new Vector3(0.0f, 0.0f, 1.0f),
                new Vector3(0.0f, 0.0f, 0.75f),
                new Vector3(0.25f, 0.0f, 0.5f),
                new Vector3(0.0f, 0.0f, 0.25f)
            });
            crossUV = new VBO <Vector2>(new Vector2[]  {
                new Vector2(0.0f, 0.0f),
                new Vector2(0.25f, 0.0f),
                new Vector2(0.5f, 0.25f),
                new Vector2(0.75f, 0.0f),
                new Vector2(1.0f, 0.0f),
                new Vector2(1.0f, 0.25f),
                new Vector2(0.75f, 0.5f),
                new Vector2(1.0f, 0.75f),
                new Vector2(1.0f, 1.0f),
                new Vector2(0.75f, 1.0f),
                new Vector2(0.5f, 0.75f),
                new Vector2(0.25f, 1.0f),
                new Vector2(0.0f, 1.0f),
                new Vector2(0.0f, 0.75f),
                new Vector2(0.25f, 0.5f),
                new Vector2(0.0f, 0.25f)
            });
            crossTriangles = new VBO <uint>(new uint[] {
                0, 1, 15,
                1, 2, 15,
                2, 14, 15,
                3, 6, 13,
                3, 4, 5,
                3, 5, 6,
                11, 12, 13,
                6, 11, 13,
                6, 9, 10,
                7, 8, 9,
                6, 7, 9
            }, BufferTarget.ElementArrayBuffer);

            cyrcle = new VBO <Vector3>(new Vector3[] {
                new Vector3(0.0f, 0.0f, 0.0f),
                new Vector3(1.0f, 0.0f, 0.0f),
                new Vector3(0.5f, 0.0f, 0.5f),
            });
            cyrcleUV = new VBO <Vector2>(new Vector2[]  {
                new Vector2(0.5f, 0.5f),
                new Vector2(1.0f, 0.5f),
                new Vector2(0, 0)
            });
            cyrcleTriangles = new VBO <uint>(new uint[] {
                0, 1, 2
            }, BufferTarget.ElementArrayBuffer);

            float angle = (float)((Math.PI) / n);

            List <Vector3> sphere_vertex  = new List <Vector3>();
            List <Vector2> sphere_to      = new List <Vector2>();
            List <uint>    sphere_indeses = new List <uint>();

            sphere_vertex.Add(new Vector3(0, 1, 0));
            sphere_to.Add(new Vector2(0, 1));
            sphere_vertex.Add(new Vector3((float)Math.Cos(Math.PI / 2 - angle), (float)Math.Sin(Math.PI / 2 - angle), 0));
            sphere_to.Add(new Vector2(0, 1.0f - 1.0f / n));
            sphere_vertex.Add(Matrix4.CreateFromAxisAngle(Vector3.UnitY, angle) * sphere_vertex[sphere_vertex.Count - 1]);
            sphere_to.Add(new Vector2(1.0f / (2 * n), 1.0f - 1.0f / n));
            sphere_indeses.Add(0);
            sphere_indeses.Add(1);
            sphere_indeses.Add(2);

            for (uint i = 2; i < n; i++)
            {
                sphere_vertex.Add(new Vector3((float)Math.Cos(Math.PI / 2 - angle * i), (float)Math.Sin(Math.PI / 2 - angle * i), 0));
                sphere_to.Add(new Vector2(0, 1.0f - i / n));
                sphere_vertex.Add(Matrix4.CreateFromAxisAngle(Vector3.UnitY, angle) * sphere_vertex[sphere_vertex.Count - 1]);
                sphere_to.Add(new Vector2(1.0f / (2 * n), 1.0f - i / n));
                sphere_indeses.Add(2 * i - 3);
                sphere_indeses.Add(2 * i - 2);
                sphere_indeses.Add(2 * i - 1);
                sphere_indeses.Add(2 * i - 2);
                sphere_indeses.Add(2 * i - 1);
                sphere_indeses.Add(2 * i);
            }

            sphere_vertex.Add(new Vector3(0, -1, 0));
            sphere_to.Add(new Vector2(0, 0));
            sphere_indeses.Add(2 * (uint)n - 3);
            sphere_indeses.Add(2 * (uint)n - 2);
            sphere_indeses.Add(2 * (uint)n - 1);

            sphere          = new VBO <Vector3>(sphere_vertex.ToArray());
            sphereUV        = new VBO <Vector2>(sphere_to.ToArray());
            sphereTriangles = new VBO <uint>(sphere_indeses.ToArray(), BufferTarget.ElementArrayBuffer);


            Glut.glutMainLoop();
        }
Beispiel #5
0
        public void Update(float time)
        {
            _aspectRatio = (float)Engine.Instance.Width / (float)Engine.Instance.Height;
            _projection  = Matrix4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(_fildOfView), _aspectRatio, _nearPlane, _farPlane);

            /*Vector3 cameraTarget = Vector3.Zero;
             * Vector3 cameraDirection = Vector3.Normalize(gameObject._transform._Position - cameraTarget);
             * Vector3 up = Vector3.UnitY;
             * Vector3 cameraRight = Vector3.Normalize(Vector3.Cross(up, cameraDirection));
             * Vector3 cameraUp = Vector3.Cross(cameraDirection, cameraRight);*/

            MouseState state      = Mouse.GetState();
            var        moveVector = new Vector3(0, 0, 0);

            var curMousePos = new Point(Mouse.GetState().X, Mouse.GetState().Y);

            if (curMousePos != Point.Zero)
            {
                mouseVector = (curMousePos - Point.Zero).ToVector2();
            }

            if (Input.GetKeyDown(Key.P))
            {
                if (MouseLook)
                {
                    MouseLook = false;
                    Engine.Instance.CursorVisible = true;
                }
                else
                {
                    MouseLook = true;
                    Engine.Instance.CursorVisible = false;
                }
            }

            if (Input.GetKey(Key.W))
            {
                moveVector.Z += MoveSpeed;
            }
            if (Input.GetKey(Key.S))
            {
                moveVector.Z -= MoveSpeed;
            }
            if (Input.GetKey(Key.A))
            {
                moveVector.X += MoveSpeed;
            }
            if (Input.GetKey(Key.D))
            {
                moveVector.X -= MoveSpeed;
            }

            if (Input.GetKey(Key.Q))
            {
                moveVector.Y -= MoveSpeed;
            }
            if (Input.GetKey(Key.E))
            {
                moveVector.Y += MoveSpeed;
            }

            if (Input.GetKey(Key.ShiftLeft))
            {
                MoveSpeed = 200;
            }
            else
            {
                MoveSpeed = 100;
            }

            if (MouseLook)
            {
                if (state != laststate)
                {
                    mouseRotationBuffer.X -= 0.1f * Input.GetMouse.XDelta * rotationSpeed * (float)time;
                    mouseRotationBuffer.Y -= 0.1f * Input.GetMouse.YDelta * rotationSpeed * (float)time;

                    if (mouseRotationBuffer.Y < MathHelper.DegreesToRadians(-75.0f))
                    {
                        mouseRotationBuffer.Y = mouseRotationBuffer.Y - (mouseRotationBuffer.Y - MathHelper.DegreesToRadians(-75.0f));
                    }

                    if (mouseRotationBuffer.Y > MathHelper.DegreesToRadians(75.0f))
                    {
                        mouseRotationBuffer.Y = mouseRotationBuffer.Y - (mouseRotationBuffer.Y - MathHelper.DegreesToRadians(75.0f));
                    }

                    gameObject._transform.Rotation      = new Quaternion(-MathHelper.Clamp(mouseRotationBuffer.Y, MathHelper.DegreesToRadians(-75.0f), MathHelper.DegreesToRadians(75.0f)), 0, 0, 0);
                    gameObject._transform.Root.Rotation = new Quaternion(0, WrapAngle(mouseRotationBuffer.X), 0, 0);
                }
            }
            laststate = state;
            AddToCameraPosition(moveVector * (float)time);
            UpdateViewMatrix();
        }
Beispiel #6
0
        //画面描画で実行される。
        protected override void OnRenderFrame(FrameEventArgs e)
        {
            base.OnRenderFrame(e);

            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit);

            #region TransFormationMatrix

            Matrix4 modelView = Matrix4.LookAt(Vector3.UnitZ * 10 / zoom, Vector3.Zero, Vector3.UnitY);
            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadMatrix(ref modelView);
            GL.MultMatrix(ref rotate);

            Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView(MathHelper.PiOver4 / zoom, (float)this.Width / (float)this.Height, 1.0f, 64.0f);
            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadMatrix(ref projection);

            #endregion

            //ライトの指定
            GL.Light(LightName.Light0, LightParameter.Position, lightPosition);
            GL.Light(LightName.Light0, LightParameter.Ambient, lightAmbient);
            GL.Light(LightName.Light0, LightParameter.Diffuse, lightDiffuse);
            GL.Light(LightName.Light0, LightParameter.Specular, lightSpecular);

            //材質の指定
            GL.Material(MaterialFace.Front, MaterialParameter.Ambient, materialAmbient);
            //GL.Material(MaterialFace.Front, MaterialParameter.Diffuse, materialDiffuse);
            GL.Material(MaterialFace.Front, MaterialParameter.Specular, materialSpecular);
            GL.Material(MaterialFace.Front, MaterialParameter.Shininess, materialShininess);
            //GL.Material(MaterialFace.Front, MaterialParameter.Emission, Color4.Black);

            GL.MatrixMode(MatrixMode.Modelview);

            plate.Draw();

            GL.ColorMask(false, false, false, false);
            GL.DepthMask(false);
            GL.StencilFunc(StencilFunction.Always, 1, ~0);
            GL.StencilOp(StencilOp.Keep, StencilOp.Replace, StencilOp.Replace);

            //型紙描画
            clip.Draw();

            GL.ColorMask(true, true, true, true);
            GL.DepthMask(true);
            GL.StencilFunc(StencilFunction.Equal, 1, ~0);
            GL.StencilOp(StencilOp.Keep, StencilOp.Keep, StencilOp.Keep);

            //ステンシル値==+1で見えるものを描画
            GL.PushMatrix();
            GL.Translate(-7.5f, 0.0f, 0.0f);

            torus.Draw();

            GL.PopMatrix();

            GL.StencilFunc(StencilFunction.Equal, 0, ~0);

            //ステンシル値==0で見えるものを描画
            GL.PushMatrix();
            GL.Translate(7.5f, 0.0f, 0.0f);

            sphere.Draw();

            GL.PopMatrix();

            SwapBuffers();
        }
Beispiel #7
0
	    // tick for OpenGL rendering code
	    public void RenderGL()
	    {
		    // measure frame duration
		    float frameDuration = timer.ElapsedMilliseconds;
		    timer.Reset();
		    timer.Start();
            var keyboard = OpenTK.Input.Keyboard.GetState();
            if (keyboard[OpenTK.Input.Key.W])
            {
                cam *= Matrix4.CreateTranslation(0, 0, acceleration * 0.1f);
            }
            if(keyboard[OpenTK.Input.Key.S])
            {
                cam *= Matrix4.CreateTranslation(0, 0, acceleration * -0.1f);
            }
            if (keyboard[OpenTK.Input.Key.Space])
            {
                cam *= Matrix4.CreateTranslation(0, acceleration * -0.1f, 0);
            }
            if (keyboard[OpenTK.Input.Key.ShiftLeft])
            {
                cam *= Matrix4.CreateTranslation(0, acceleration * 0.1f, 0);
            }
            if (keyboard[OpenTK.Input.Key.A])
            {
                cam *= Matrix4.CreateTranslation(acceleration * 0.1f, 0, 0);
            }
            if (keyboard[OpenTK.Input.Key.D])
            {
                cam *= Matrix4.CreateTranslation(acceleration * -0.1f, 0, 0);
            }
            if (keyboard[OpenTK.Input.Key.I])
            {
                cam *= Matrix4.CreateRotationX(acceleration * 0.01f);
            }
            if (keyboard[OpenTK.Input.Key.Q])
            {
                cam *= Matrix4.CreateRotationY(acceleration * -0.01f);
            }
            if (keyboard[OpenTK.Input.Key.E])
            {
                cam *= Matrix4.CreateRotationY(acceleration * 0.01f);
            }
            if (keyboard[OpenTK.Input.Key.K])
            {
                cam *= Matrix4.CreateRotationX(acceleration * -0.01f);
            }
            if (keyboard[OpenTK.Input.Key.J])
            {
                cam *= Matrix4.CreateRotationZ(acceleration * -0.01f);
            } 
            if (keyboard[OpenTK.Input.Key.L])
            {
                cam *= Matrix4.CreateRotationZ(acceleration * 0.01f);
            }
		    // prepare matrix for vertex shader
		    Matrix4 transform = Matrix4.CreateFromAxisAngle( new Vector3( 0, 1, 0 ), a );
		    transform *= Matrix4.CreateTranslation( 0, -4, -15 );
            transform *= cam;
		    transform *= Matrix4.CreatePerspectiveFieldOfView( 1.2f, 1.3f, .1f, 1000 );

            // update rotation
            if (automaticRotation) a += 0.001f * frameDuration; 
		    if (a > 2 * PI) a -= 2 * PI;

            // render scene
            scenegraph.Render(transform, lights, camera, Matrix4.Identity);
	    }
Beispiel #8
0
        static void Main(string[] args)
        {
            Glut.glutInit();
            Glut.glutInitDisplayMode(Glut.GLUT_DOUBLE | Glut.GLUT_DEPTH | Glut.GLUT_MULTISAMPLE);
            Glut.glutInitWindowSize(width, height);
            Glut.glutCreateWindow("Project #3");

            Glut.glutIdleFunc(OnRenderFrame);
            Glut.glutDisplayFunc(OnDisplay);

            Glut.glutKeyboardFunc(OnKeyboardDown);
            Glut.glutKeyboardUpFunc(OnKeyboardUp);

            Glut.glutCloseFunc(OnClose);
            Glut.glutReshapeFunc(OnReshape);

            // add our mouse callbacks for this tutorial
            Glut.glutMouseFunc(OnMouse);
            Glut.glutMotionFunc(OnMove);

            Gl.Enable(EnableCap.DepthTest);

            // create our shader program
            program = new ShaderProgram(VertexShader, FragmentShader);

            // set up the projection and view matrix
            program.Use();
            program["projection_matrix"].SetValue(Matrix4.CreatePerspectiveFieldOfView(0.45f, (float)width / height, 0.1f, 1000f));
            program["view_matrix"].SetValue(Matrix4.LookAt(new Vector3(0, 0, 10), Vector3.Zero, new Vector3(0, 1, 0)));

            program["light_direction"].SetValue(new Vector3(0, 0, 1));
            program["enable_lighting"].SetValue(lighting);
            program["normalTexture"].SetValue(1);
            program["enable_mapping"].SetValue(normalMapping);

            brickDiffuse = new Texture(@"D:\Diego Jacobs\Google Dirve\UVG\Semestre 9\Graficas\Proyecto 3\3D-House\3D-House\Images\AlternatingBrick-ColorMap.png");
            brickNormals = new Texture(@"D:\Diego Jacobs\Google Dirve\UVG\Semestre 9\Graficas\Proyecto 3\3D-House\3D-House\Images\AlternatingBrick-NormalMap.png");

            // create a pyramid
            pyramid = new VBO<Vector3>(new Vector3[] {
                new Vector3(-1, 1, 1), new Vector3(1, 1, 1), new Vector3(0, 2, 0),        // front face
                new Vector3(1, 1, 1), new Vector3(0, 2, 0), new Vector3(1, 1, -1),        // right face
                new Vector3(-1, 1, -1), new Vector3(0, 2, 0), new Vector3(1, 1, -1),      // back face
                new Vector3(-1, 1, 1), new Vector3(0, 2, 0), new Vector3(-1, 1, -1) });   // left face
            pyramidTriangles = new VBO<int>(new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }, BufferTarget.ElementArrayBuffer);


            Vector3[] vertices = new Vector3[] {
                new Vector3(1, 1, -1), new Vector3(-1, 1, -1), new Vector3(-1, 1, 1), new Vector3(1, 1, 1),         // top
                new Vector3(1, -1, 1), new Vector3(-1, -1, 1), new Vector3(-1, -1, -1), new Vector3(1, -1, -1),     // bottom
                new Vector3(1, 1, 1), new Vector3(-1, 1, 1), new Vector3(-1, -1, 1), new Vector3(1, -1, 1),         // front face
                new Vector3(1, -1, -1), new Vector3(-1, -1, -1), new Vector3(-1, 1, -1), new Vector3(1, 1, -1),     // back face
                new Vector3(-1, 1, 1), new Vector3(-1, 1, -1), new Vector3(-1, -1, -1), new Vector3(-1, -1, 1),     // left
                new Vector3(1, 1, -1), new Vector3(1, 1, 1), new Vector3(1, -1, 1), new Vector3(1, -1, -1) };       // right
            cube = new VBO<Vector3>(vertices);

            Vector2[] uvs = new Vector2[] {
                new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 1),
                new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 1),
                new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 1),
                new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 1),
                new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 1),
                new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 1) };
            cubeUV = new VBO<Vector2>(uvs);

            List<int> triangles = new List<int>();
            for (int i = 0; i < 6; i++)
            {
                triangles.Add(i * 4);
                triangles.Add(i * 4 + 1);
                triangles.Add(i * 4 + 2);
                triangles.Add(i * 4);
                triangles.Add(i * 4 + 2);
                triangles.Add(i * 4 + 3);
            }
            cubeTriangles = new VBO<int>(triangles.ToArray(), BufferTarget.ElementArrayBuffer);

            Vector3[] normals = Geometry.CalculateNormals(vertices, triangles.ToArray());
            cubeNormals = new VBO<Vector3>(normals);

            Vector3[] tangents = CalculateTangents(vertices, normals, triangles.ToArray(), uvs);
            cubeTangents = new VBO<Vector3>(tangents);
            
            watch = System.Diagnostics.Stopwatch.StartNew();

            Glut.glutMainLoop();
        }
Beispiel #9
0
        // draws a simple colored cube in a GLViewport control
        private void OnRenderViewport(object sender, double deltaTime)
        {
            var viewport = (GLViewport)sender;

            GL.Enable(EnableCap.DepthTest);
            GL.ClearColor(0, 0, 0, 1);
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

            GL.MatrixMode(MatrixMode.Projection);
            var proj = Matrix4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(90.0f), viewport.AspectRatio, 1.0f, 100.0f);

            GL.LoadMatrix(ref proj);
            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadIdentity();

            GL.Translate(0, 0, -2.0f);
            GL.Rotate(time * 100.0f, 1, 0, 0);
            GL.Rotate(time * 42.0f, 0, 1, 0);

            GL.Begin(PrimitiveType.Quads);
            GL.Color3(1.0, 0.0, 0.0);
            GL.Vertex3(0.5, -0.5, -0.5);
            GL.Color3(0.0, 1.0, 0.0);
            GL.Vertex3(0.5, 0.5, -0.5);
            GL.Color3(0.0, 0.0, 1.0);
            GL.Vertex3(-0.5, 0.5, -0.5);
            GL.Color3(1.0, 0.0, 1.0);
            GL.Vertex3(-0.5, -0.5, -0.5);

            GL.Color3(1.0, 1.0, 1.0);
            GL.Vertex3(0.5, -0.5, 0.5);
            GL.Vertex3(0.5, 0.5, 0.5);
            GL.Vertex3(-0.5, 0.5, 0.5);
            GL.Vertex3(-0.5, -0.5, 0.5);

            GL.Color3(1.0, 0.0, 1.0);
            GL.Vertex3(0.5, -0.5, -0.5);
            GL.Vertex3(0.5, 0.5, -0.5);
            GL.Vertex3(0.5, 0.5, 0.5);
            GL.Vertex3(0.5, -0.5, 0.5);

            GL.Color3(0.0, 1.0, 0.0);
            GL.Vertex3(-0.5, -0.5, 0.5);
            GL.Vertex3(-0.5, 0.5, 0.5);
            GL.Vertex3(-0.5, 0.5, -0.5);
            GL.Vertex3(-0.5, -0.5, -0.5);

            GL.Color3(0.0, 0.0, 1.0);
            GL.Vertex3(0.5, 0.5, 0.5);
            GL.Vertex3(0.5, 0.5, -0.5);
            GL.Vertex3(-0.5, 0.5, -0.5);
            GL.Vertex3(-0.5, 0.5, 0.5);

            GL.Color3(1.0, 0.0, 0.0);
            GL.Vertex3(0.5, -0.5, -0.5);
            GL.Vertex3(0.5, -0.5, 0.5);
            GL.Vertex3(-0.5, -0.5, 0.5);
            GL.Vertex3(-0.5, -0.5, -0.5);
            GL.End();

            GL.Disable(EnableCap.DepthTest);
        }
        protected override void OnUpdateFrame(FrameEventArgs e)
        {
            base.OnUpdateFrame(e);

            List <Vector3> verts  = new List <Vector3>();
            List <int>     inds   = new List <int>();
            List <Vector3> colors = new List <Vector3>();


            int vertcount = 0;

            foreach (Volume v in objects)
            {
                verts.AddRange(v.GetVerts().ToList());
                inds.AddRange(v.GetIndices(vertcount).ToList());
                colors.AddRange(v.GetColorData().ToList());
                vertcount += v.VertCount;
            }

            vertdata   = verts.ToArray();
            indicedata = inds.ToArray();
            coldata    = colors.ToArray();

            GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_position);
            GL.BufferData <Vector3>(BufferTarget.ArrayBuffer, (IntPtr)(vertdata.Length * Vector3.SizeInBytes), vertdata, BufferUsageHint.StaticDraw);
            GL.VertexAttribPointer(attribute_vpos, 3, VertexAttribPointerType.Float, false, 0, 0);

            GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_position);
            GL.BufferData <Vector3>(BufferTarget.ArrayBuffer, (IntPtr)(vertdata.Length * Vector3.SizeInBytes), vertdata, BufferUsageHint.StaticDraw);
            GL.VertexAttribPointer(attribute_vpos, 3, VertexAttribPointerType.Float, false, 0, 0);

            GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_color);
            GL.BufferData <Vector3>(BufferTarget.ArrayBuffer, (IntPtr)(coldata.Length * Vector3.SizeInBytes), coldata, BufferUsageHint.StaticDraw);
            GL.VertexAttribPointer(attribute_vcol, 3, VertexAttribPointerType.Float, true, 0, 0);

            objects[0].Position = new Vector3(0.3f, -0.5f + (float)Math.Sin(time), -3.0f);
            objects[0].Rotation = new Vector3(0.55f * time, 0.25f * time, 0);
            objects[0].Scale    = new Vector3(0.1f, 0.1f, 0.1f);

            objects[1].Position = new Vector3(-1f, 0.5f + (float)Math.Cos(time), -2.0f);
            objects[1].Rotation = new Vector3(-0.25f * time, -0.35f * time, 0);
            objects[1].Scale    = new Vector3(0.25f, 0.25f, 0.25f);

            objects[2].Position = new Vector3(1.8f, 0.1f + (float)Math.Tan(time), -5.0f);
            objects[2].Rotation = new Vector3(-0.05f * time, -0.15f * time, 0);
            objects[2].Scale    = new Vector3(0.4f, 0.4f, 0.4f);

            objects[3].Position = new Vector3(-4.0f, 1.0f + (float)Math.Cos(time), -4.0f);
            objects[3].Rotation = new Vector3(-0.05f * time, -0.15f * time, 0);
            objects[3].Scale    = new Vector3(0.9f, 0.9f, 0.9f);

            GL.UseProgram(pgmID);
            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);

            GL.BindBuffer(BufferTarget.ElementArrayBuffer, ibo_elements);
            GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(indicedata.Length * sizeof(int)), indicedata, BufferUsageHint.StaticDraw);

            foreach (Volume v in objects)
            {
                v.CalculateModelMatrix();
                v.ViewProjectionMatrix      = Matrix4.CreatePerspectiveFieldOfView(1.3f, ClientSize.Width / (float)ClientSize.Height, 1.0f, 40.0f);
                v.ModelViewProjectionMatrix = v.ModelMatrix * v.ViewProjectionMatrix;
            }
            time += (float)e.Time;
        }
Beispiel #11
0
 public override Matrix4 GetProjectionMatrix()
 {
     return(Matrix4.CreatePerspectiveFieldOfView(_fov, AspectRatio, 1, FarPlane));
 }
Beispiel #12
0
        private void Timer_Tick(object sender, EventArgs e)
        {
            // update
            elapsedTime = currentTime;
            currentTime = DateTime.Now;
            float dt = (float)(currentTime - elapsedTime).TotalSeconds;

            if (dt < 0.0f)
            {
                dt = 0.0f;
            }
            if (dt > (1.0f / 10.0f))
            {
                dt = (1.0f / 10.0f);
            }                                                 // min. 10fps

            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

            Matrix4 m_world     = Matrix4.Identity;
            Matrix4 m_view      = Matrix4.LookAt(new Vector3(2, 6, 15), new Vector3(0, 2, 0), new Vector3(0, 1, 0));
            Matrix4 m_modelview = Matrix4.Mult(m_world, m_view);
            Matrix4 m_proj      = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 2.0f, (float)glControl.Width / (float)glControl.Height, 0.05f, 1000.0f);

            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadMatrix(ref m_proj);

            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadMatrix(ref m_modelview);

            float step = 1.0f / 500.0f;

            for (float i = 0; i < dt; i += step)
            {
                rigidBody1.Update(step);
                rigidBody2.Update(step);

                // collision detection and response
                List <Hit> listHits1 = new List <Hit>();
                Physics.CollisionDetection.RigidBodyAndPlane(rigidBody1, plane, ref listHits1);
                Physics.CollisionResponse.Apply(rigidBody1, listHits1, step);

                List <Hit> listHits2 = new List <Hit>();
                Physics.CollisionDetection.RigidBodyAndPlane(rigidBody2, plane, ref listHits2);
                Physics.CollisionResponse.Apply(rigidBody2, listHits2, step);

                List <Hit> listHits3 = new List <Hit>();
                Physics.CollisionDetection.RigidBodyAndRigidBody(rigidBody1, rigidBody2, ref listHits3);
                Physics.CollisionResponse.Apply(rigidBody2, rigidBody1, listHits3, step);

                // draw hits
                //Physics.CollisionDetection.DrawHits(listHits1);
                //Physics.CollisionDetection.DrawHits(listHits2);
                //Physics.CollisionDetection.DrawHits(listHits3);
            }

            plane.Draw();
            rigidBody1.Draw();
            rigidBody2.Draw();

            glControl.SwapBuffers();
        }
Beispiel #13
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.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
            GL.TexParameter(TextureTarget.Texture2D, 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 world_pos;
                vec3 world_nv;
                vec2 uv;
            } out_data;

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

            void main()
            {
                vec4 worldPos      = mvp.model * vec4(inPos, 1.0);
                out_data.world_pos = worldPos.xyz / worldPos.w;
                out_data.world_nv  = normalize( mat3(mvp.model) * inNV );
                out_data.uv        = inUV;
            }";

            string geo_shader = @"#version 460 core
            
            layout( triangles ) in;
            layout( triangle_strip, max_vertices = 15 ) out;

            in TVertexData
            {
                vec3 world_pos;
                vec3 world_nv;
                vec2 uv;
            } inData[];

            out TGeometryData
            {
                vec3  pos;
                vec3  nv;
                vec3  tv;
                vec3  bv;
                vec3  uvh;
                vec4  d;
                float clip;
            } outData;

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

            layout(location=1) uniform vec4  u_clipPlane;
            layout(location=2) uniform float u_displacement_scale;

            void main()
            {
                // tangent space
                //vec3  p_dA       = vsPos[1].xyz - vsPos[0].xyz;
                //vec3  p_dB       = vsPos[2].xyz - vsPos[0].xyz;
                //vec2  tc_dA      = inData[1].uv - inData[0].uv;
                //vec2  tc_dB      = inData[2].uv - inData[0].uv;
                //float texDet     = determinant( mat2( tc_dA, tc_dB ) );
                //outData.vsTV     = ( tc_dB.y * p_dA - tc_dA.y * p_dB ) / texDet;
                //outData.vsBVsign = sign(texDet);

                vec3 world_pos_up[3];
                for (int i = 0; i < 3; ++ i)
                    world_pos_up[i] = inData[i].world_pos + inData[i].world_nv * u_displacement_scale;

                vec3 view_nv[3];
                vec3 view_pos[3];
                vec3 view_pos_up[3];
                for (int i = 0; i < 3; ++ i)
                {
                    vec4 viewPos   = mvp.view * vec4(inData[i].world_pos, 1.0);
                    view_nv[i]     = normalize(mat3(mvp.view) * inData[i].world_nv);
                    view_pos[i]    = viewPos.xyz;
                    view_pos_up[i] = view_pos[i] + view_nv[i] * u_displacement_scale;
                    //view_pos_up[i] = (mvp.view * vec4(world_pos_up[i], 1.0)).xyz;
                }

                // tangent space
                // Followup: Normal Mapping Without Precomputed Tangents [http://www.thetenthplanet.de/archives/1180]
                vec3  dp1  = view_pos[1].xyz - view_pos[0].xyz;
                vec3  dp2  = view_pos[2].xyz - view_pos[0].xyz;
                vec2  duv1 = inData[1].uv.xy - inData[0].uv.xy;
                vec2  duv2 = inData[2].uv.xy - inData[0].uv.xy;

                vec3 nv[3];
                vec3 tv[3];
                vec3 bv[3];
                for ( int i=0; i < 3; ++i )
                {
                    vec3 dp2perp = cross(dp2, view_nv[i]); 
                    vec3 dp1perp = cross(view_nv[i], dp1);
        
                    nv[i] = view_nv[i] * u_displacement_scale;
                    tv[i] = dp2perp * duv1.x + dp1perp * duv2.x;
                    bv[i] = dp2perp * duv1.y + dp1perp * duv2.y;
                }

    
                // distance to opposite planes
                float d[3];
                float d_up[3];
                float d_opp[3];
                float d_opp_up[3];
                float d_top[3];
                for ( int i0=0; i0 < 3; ++i0 )
                {
                  d[i0]    = length(view_pos[i0].xyz);
                  d_up[i0] = length(view_pos_up[i0].xyz);

                  int i1 = (i0+1) % 3; 
                  int i2 = (i0+2) % 3; 
                  vec3 edge    = view_pos[i2].xyz - view_pos[i1].xyz;
                  vec3 edge_up = view_pos_up[i2].xyz - view_pos_up[i1].xyz;
                  vec3 up      = view_nv[i1].xyz + view_nv[i2].xyz;

                  // intersect the view ray trough a corner point of the prism (with triangular base)
                  // with the opposite side face of the prism
                  //
                  // d = dot(P0 - R0, N) / dot(D, N)
                  //
                  // R0 : point on the ray
                  // D  : direction of the ray
                  // P0 : point on the plane
                  // N  : norma vector of the plane
                  // d  :: distance from R0 to the intersection with the plane along D
      
                  //vec3  R0      = vec3(view_pos[i0].xy, 0.0); // for orthographic projection
                  //vec3  D       = vec3(0.0, 0.0, -1.0); // for orthographic projection
                  vec3  R0      = vec3(0.0); // for persepctive projection
                  vec3  D       = normalize(view_pos[i0].xyz); // for persepctive projection
                  vec3  N       = normalize(cross(edge, up));
                  vec3  P0      = (view_pos[i1].xyz+view_pos[i2].xyz)/2.0;
                  d_opp[i0]     = dot(P0 - R0, N) / dot(D, N);

                  //vec3  R0_up   = vec2(view_pos_up[i0].xyz, 0.0); // for orthographic projection
                  //vec3  D_up  = vec3(0.0, 0.0, -1.0); // for orthographic projection
                  vec3  R0_up   = vec3(0.0); // for persepctive projection 
                  vec3  D_up    = normalize(view_pos_up[i0].xyz); // for persepctive projection
                  vec3  N_up    = normalize(cross(edge_up, up));
                  vec3  P0_up   = (view_pos_up[i1].xyz+view_pos_up[i2].xyz)/2.0;
                  d_opp_up[i0]  = dot(P0_up - R0_up, N_up) / dot(D_up, N_up);

                  //vec3  N_top   = view_nv[i0];
                  vec3  N_top   = normalize(view_nv[0]+view_nv[1]+view_nv[2]);
                  vec3  P0_top  = (view_pos_up[0].xyz + view_pos_up[1].xyz + view_pos_up[2].xyz)/3.0;
                  d_top[i0]     = dot(P0_top - R0, N_top) / dot(D, N_top);
                }

                vec4 clipPlane = vec4(normalize(u_clipPlane.xyz), u_clipPlane.w);

                for ( int i=0; i < 3; ++i )
                {
                    outData.nv   = nv[i];
                    outData.tv   = tv[i];
                    outData.bv   = bv[i];
                    outData.pos  = view_pos[i];
                    outData.uvh  = vec3(inData[i].uv, 0.0);
                    outData.d    = vec4( i==0 ? d_opp[i] : d[i], i==1 ? d_opp[i] : d[i], i==2 ? d_opp[i] : d[i], d_top[i] );
                    outData.clip = dot(vec4(inData[i].world_pos, 1.0), clipPlane);
                    gl_Position  = mvp.proj * vec4( outData.pos, 1.0 );
                    EmitVertex();
                }
                EndPrimitive();

                vec3 cpt_tri = (view_pos[0] + view_pos[1] + view_pos[2]) / 3.0;
                for ( int i0=0; i0 < 3; ++i0 )
                {
                    int i1 = (i0+1) % 3;
                    int i2 = (i0+2) % 3; 

                    vec3 cpt_edge    = (view_pos[i0] + view_pos[i1]) / 2.0;
                    vec3 dir_to_edge = cpt_edge - cpt_tri; // direction from thge center of the triangle to the edge

                    vec3 edge    = view_pos[i1] - view_pos[i0];
                    vec3 nv_edge  = nv[i0] + nv[i1];
                    vec3 nv_side = cross(edge, nv_edge); // normal vector of a side of the prism
                    nv_side *= sign(dot(nv_side, dir_to_edge)); // orentate the normal vector out of the center of the triangle

                    // a front face is a side of the prism, where the normal vector is directed against the view vector
                    float frontface = sign(dot(cpt_edge, -nv_side));

                    float d_opp0, d_opp1, d_opp_up0, d_opp_up1;
                    if ( frontface > 0.0 )
                    {
                        d_opp0    = max(d[i0], d_opp[i0]);
                        d_opp1    = max(d[i1], d_opp[i1]);
                        d_opp_up0 = max(d_up[i0], d_opp_up[i0]);
                        d_opp_up1 = max(d_up[i1], d_opp_up[i1]);
                    }
                    else
                    {
                        d_opp0    = min(d[i0], d_opp[i0]);
                        d_opp1    = min(d[i1], d_opp[i1]);
                        d_opp_up0 = min(d_up[i0], d_opp_up[i0]);
                        d_opp_up1 = min(d_up[i1], d_opp_up[i1]);
                    }

                    outData.nv   = nv[i0];
                    outData.tv   = tv[i0];
                    outData.bv   = bv[i0];
                    outData.pos  = view_pos[i0];
                    outData.uvh  = vec3(inData[i0].uv, 0.0);
                    outData.d    = vec4(d_opp0, d[i0], frontface, d_top[i0]);
                    outData.clip = dot(vec4(inData[i0].world_pos, 1.0), clipPlane);
                    gl_Position  = mvp.proj * vec4( outData.pos, 1.0 );
                    EmitVertex();

                    outData.nv   = nv[i1];
                    outData.tv   = tv[i1];
                    outData.bv   = bv[i1];
                    outData.pos  = view_pos[i1];
                    outData.uvh  = vec3(inData[i1].uv, 0.0);
                    outData.d    = vec4(d[i1], d_opp1, frontface, d_top[i1]);
                    outData.clip = dot(vec4(inData[i1].world_pos, 1.0), clipPlane);
                    gl_Position  = mvp.proj * vec4( outData.pos, 1.0 );
                    EmitVertex();

                    outData.nv   = nv[i0];
                    outData.tv   = tv[i0];
                    outData.bv   = bv[i0];
                    outData.pos  = view_pos_up[i0];
                    outData.uvh  = vec3(inData[i0].uv, 1.0);
                    outData.d    = vec4(d_opp_up0, d_up[i0], frontface, 0.0);
                    outData.clip = dot(vec4(world_pos_up[i0], 1.0), clipPlane);
                    gl_Position  = mvp.proj * vec4( outData.pos, 1.0 );
                    EmitVertex();

                    outData.nv   = nv[i1];
                    outData.tv   = tv[i1];
                    outData.bv   = bv[i1];
                    outData.pos  = view_pos_up[i1];
                    outData.uvh  = vec3(inData[i1].uv, 1.0);
                    outData.d    = vec4(d_up[i1], d_opp_up1, frontface, 0.0);
                    outData.clip = dot(vec4(world_pos_up[i1], 1.0), clipPlane);
                    gl_Position  = mvp.proj * vec4( outData.pos, 1.0 );
                    EmitVertex();

                    EndPrimitive();
                }
            }";

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

            in TGeometryData
            {
                vec3  pos;
                vec3  nv;
                vec3  tv;
                vec3  bv;
                vec3  uvh;
                vec4  d;
                float clip;
            } in_data;

            out vec4 fragColor;

            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;

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

            layout(location=1) uniform vec4 u_clipPlane;

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

            float CalculateHeight( in vec2 texCoords )
            {
                float height = texture( u_displacement_map, texCoords ).x;
                return clamp( height, 0.0, 1.0 );
            }

            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 = CalculateHeight( texCoords );
                vec3  tempNV = texture( u_normal_map, texCoords ).xyz * 2.0 / 1.0;
                return vec4( normalize( tempNV ), height );
            #else
                vec2 texOffs = 1.0 / vec2(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 
            }

            vec3 Parallax( in float frontFace, in vec3 texCoord, in vec3 tbnP0, in vec3 tbnP1, in vec3 tbnStep )
            {   
                // inverse height map: -1 for inverse height map or 1 if not inverse
                // height maps of back faces base triangles are inverted
                float back_face = step(0.0, -frontFace); 
                vec3 texC0 = texCoord.xyz + tbnP0 + back_face * vec3(tbnStep.xy, 0.0);
                vec3 texC1 = texCoord.xyz + tbnP1 + back_face * vec3(tbnStep.xy, 0.0);

                // sample steps and quality
                vec2  quality_range  = u_parallax_quality;
                float quality        = mix( quality_range.x, quality_range.y, 1.0 - abs(normalize(tbnStep).z) );
                float numSteps       = clamp( quality * 50.0, 1.0, 50.0 );
                int   numBinarySteps = int( clamp( quality * 10.0, 1.0, 10.0 ) );

                // change of the height per step
                float bumpHeightStep = (texC0.z-texC1.z) / (numSteps-1.0);

                float bestBumpHeight = texC1.z;
                float mapHeight      = 1.0;
                for ( int i = 0; i < int( numSteps ); ++ i )
                {
                    mapHeight = back_face + frontFace * CalculateHeight( mix(texC0.xy, texC1.xy, (bestBumpHeight-texC0.z)/(texC1.z-texC0.z)) );
                    if ( mapHeight >= bestBumpHeight || bestBumpHeight > 1.0 )
                        break;
                    bestBumpHeight += bumpHeightStep;   
                } 

                if ( texCoord.z < 0.0001 || bestBumpHeight >= 0.0 ) // if not a silhouett 
                {
                    // binary steps, starting at the previous sample point 
                    bestBumpHeight -= bumpHeightStep;
                    for ( int i = 0; i < numBinarySteps; ++ i )
                    {
                        bumpHeightStep *= 0.5;
                        bestBumpHeight += bumpHeightStep;
                        mapHeight       = back_face + frontFace * CalculateHeight( mix(texC0.xy, texC1.xy, (bestBumpHeight-texC0.z)/(texC1.z-texC0.z)) );
                        bestBumpHeight -= ( bestBumpHeight < mapHeight ) ? bumpHeightStep : 0.0;
                    }

                    // final linear interpolation between the last to heights 
                    bestBumpHeight += bumpHeightStep * clamp( ( bestBumpHeight - mapHeight ) / abs(bumpHeightStep), 0.0, 1.0 );
                }

                // set displaced texture coordiante and intersection height
                vec2 texC  = mix(texC0.xy, texC1.xy, (bestBumpHeight-texC0.z)/(texC1.z-texC0.z));
                mapHeight  = bestBumpHeight;
    
                return vec3(texC.xy, mapHeight);
            }

            void main()
            {
                vec3  objPosEs    = in_data.pos;
                vec3  objNormalEs = in_data.nv;
                vec3  texCoords   = in_data.uvh.stp;
                float frontFace   = (texCoords.p > 0.0) ? 1.0 : (gl_FrontFacing ? 1.0 : -1.0); // TODO $$$ sign(dot(N,objPosEs));
    
                //vec3  tangentEs    = normalize( tangentVec - normalEs * dot(tangentVec, normalEs ) );
                //mat3  tbnMat       = mat3( tangentEs, binormalSign * cross( normalEs, tangentEs ), normalEs );

                // tangent space
                // Followup: Normal Mapping Without Precomputed Tangents [http://www.thetenthplanet.de/archives/1180]
                //   If backface, then the normal vector is downwards the (co-)tangent space.
                //   In this case the normal has to be mirrored to make the parallax algorithm prpper work.
                vec3  N           = frontFace * objNormalEs;  
                vec3  T           = in_data.tv;
                vec3  B           = in_data.bv;
                float invmax      = inversesqrt(max(dot(T, T), dot(B, B)));
                mat3  tbnMat      = mat3(T * invmax, B * invmax, N * invmax);
                mat3  inv_tbnMat  = inverse( tbnMat );

                // distances to the sides of the prism
                bool  is_silhouette    = texCoords.p > 0.0001;
                bool  silhouette_front = in_data.d.z > 0.0;
                float df = length( objPosEs );
                float d0;
                float d1;
                if ( is_silhouette == false )
                {
                    if ( frontFace > 0.0 )
                    {
                        d1 = 0.0;
                        d0 = min(min(in_data.d.x, in_data.d.y), in_data.d.z) - df; // TODO $$$ * 0.9
                    }
                    else
                    {
                        d0 = 0.0;
                        d1 = max(max(in_data.d.x, in_data.d.y), in_data.d.z) - df;
                    }
                }
                else
                {
                    d1 = min(in_data.d.x, in_data.d.y) - df;
                    d0 = max(in_data.d.x, in_data.d.y) - df;
                }

                // intersection points
                vec3  V  = objPosEs / df;
                vec3  P0 = V * d0;
                vec3  P1 = V * d1;
   
                vec3  tbnP0        = inv_tbnMat * P0;
                vec3  tbnP1        = inv_tbnMat * P1;
                vec3  tbnDir       = normalize(inv_tbnMat * objPosEs);
                vec3  tbnTopMax    = tbnDir / tbnDir.z;

                // geometry situation
                float base_height  = texCoords.p;                     // intersection level (height) on the silhouette (side of prism geometry)
                bool  is_up_isect  = is_silhouette && tbnDir.z > 0.0; // upwards intersection on potential silhouette (side of prism geometry)

                // sample start and end height (level)
                float delta_height0 = is_up_isect ? 1.05*(1.0-base_height) : base_height; // TODO $$$ 1.05 ??? 
                float delta_height1 = is_up_isect ? 0.0 : (base_height - 1.0);

                // sample distance
                //vec3 texDist = tbnDir / abs(tbnDir.z); // (z is negative) the direction vector points downwards int tangent-space
                vec3 texDist = is_silhouette == false ? tbnDir / abs(tbnDir.z) : tbnDir / max(abs(tbnDir.z), 0.5*length(tbnDir.xy));
                vec3 tbnStep = vec3(texDist.xy, sign(tbnDir.z));

                // start and end of samples
                tbnP0 = delta_height0 * tbnStep; // sample end - bottom of prism 
                tbnP1 = delta_height1 * tbnStep; // sample start - top of prism 
                if ( is_silhouette )
                {
                    if ( silhouette_front )
                    {
                        tbnP1 = vec3(0.0);
                    }
                    else
                    {
                        tbnP0 = vec3(0.0);
                    }
                }

                vec3  newTexCoords = abs(u_displacement_scale) < 0.001 ? vec3(texCoords.st, 0.0) : Parallax( frontFace, texCoords.stp, tbnP0, tbnP1, tbnStep );
                vec3  tex_offst    = newTexCoords.stp-texCoords.stp;
    
                // slihouett discard (clipping)
                if ( is_silhouette )
                {
                    if ( newTexCoords.z > 1.000001 ||                // clip at top plane of the prism
                         newTexCoords.z < 0.0 ||                    // clip at bottom plane of the prism
                         dot(tex_offst, tbnDir)*in_data.d.z < 0.0 ) // clip back side faces at the back and clip front side faces at the front
                        discard;
                    if ( silhouette_front == false && is_up_isect )
                        discard;
                }
    
                vec3  displ_vec      = tbnMat * tex_offst/invmax;
                vec3  view_pos_displ = objPosEs + displ_vec;
                texCoords.st         = newTexCoords.xy;

            #define DEBUG_CLIP
            #define DEBUG_CLIP_DISPLACED

            #if defined (DEBUG_CLIP)
                vec4  modelPos       = inverse(mvp.view) * vec4(view_pos_displ, 1.0);
                vec4  clipPlane      = vec4(normalize(u_clipPlane.xyz), u_clipPlane.w);
            #if defined (DEBUG_CLIP_DISPLACED)
                float clip_dist      = dot(modelPos, clipPlane);
            #else
                float clip_dist      = in_data.clip;
            #endif
                if ( clip_dist < 0.0 )
                    discard;
            #endif
    
                vec4  normalVec = CalculateNormal( texCoords.st );
                // If back face, then the height map has been inverted (except cone step map). This causes that the normalvector has to be adapted.
                normalVec.xy *= frontFace;
                //vec3  nvMappedEs = normalize( tbnMat * normalVec.xyz );
                vec3  nvMappedEs = normalize( transpose(inv_tbnMat) * normalVec.xyz ); // TODO $$$ evaluate `invmax`?

                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 = depth;

            //#define DEBUG_FRONT_SILHOUETTES
            //#define DEBUG_BACK_SILHOUETTES
            //#define DEBUG_DEPTH

            #if defined(DEBUG_FRONT_SILHOUETTES)
                if ( texCoords.p < 0.0001 )
                    discard;
                if ( in_data.d.z < 0.0 )
                    discard;
                fragColor = vec4(vec2(in_data.d.xy-df), in_data.d.z, 1.0);
                //fragColor = vec4(vec2(d1), in_data.d.z, 1.0);
            #endif

            #if defined(DEBUG_BACK_SILHOUETTES)
                if ( texCoords.p < 0.0001 )
                    discard;
                if ( in_data.d.z > 0.0 )
                    discard;
                fragColor = vec4(vec2(df-in_data.d.xy), -in_data.d.z, 1.0);
                //fragColor = vec4(vec2(-d0), -in_data.d.z, 1.0);
            #endif

            #if defined(DEBUG_DEPTH)
                fragColor = vec4( vec3(1.0-depth), 1.0 );
            #endif
            }";

            this._parallax_prog = openGLFactory.VertexGeometryFragmentShaderProgram(vert_shader, geo_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;
        }
Beispiel #14
0
        public static void Main(string[] args)
        {
            using (var win = new GameWindow(1280, 720, GraphicsMode.Default, "OpenTK Intro",
                                            GameWindowFlags.Default, DisplayDevice.Default,
                                            // ask for an OpenGL 3.0 forward compatible context
                                            3, 0, GraphicsContextFlags.ForwardCompatible))
            {
                VertexBuffer <ColouredVertex> vertexBuffer = null;
                ShaderProgram shaderProgram = null;
                VertexArray <ColouredVertex> vertexArray = null;
                Matrix4Uniform projectionMatrix          = null;

                win.Load += (s, e) =>
                {
                    var vertexShader = new Shader(ShaderType.VertexShader,
                                                  File.ReadAllText(@"../../VertexShaders/vertex-shader.vs"));
                    var fragmentShader = new Shader(ShaderType.FragmentShader,
                                                    File.ReadAllText(@"../../FragmentShaders/fragment-shader.fs"));

                    // link shaders into shader program
                    shaderProgram = new ShaderProgram(vertexShader, fragmentShader);

                    // create projection matrix uniform
                    projectionMatrix = new Matrix4Uniform("projectionMatrix")
                    {
                        Matrix = Matrix4.CreatePerspectiveFieldOfView(MathHelper.PiOver2, 16f / 9, 0.1f, 100f)
                    };
                };
                win.Unload      += (s, e) => { /* dispose global GL resources here */ };
                win.RenderFrame += (s, e) =>
                {
                    GL.ClearColor(128, 0, 1, 256);
                    GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

                    //http://genericgamedev.com/tutorials/opengl-in-csharp-an-object-oriented-introduction-to-opentk/4/

                    // activate shader program and set uniforms
                    shaderProgram.Use();
                    projectionMatrix.Set(shaderProgram);

                    // bind vertex buffer and array objects
                    vertexBuffer.Bind();
                    vertexArray.Bind();

                    // upload vertices to GPU and draw them
                    vertexBuffer.BufferData();
                    vertexBuffer.Draw();

                    // reset state for potential further draw calls (optional, but good practice)
                    GL.BindVertexArray(0);
                    GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
                    GL.UseProgram(0);

                    // swap backbuffer
                    win.SwapBuffers();
                };
                win.Resize += (s, e) =>
                {
                    GL.Viewport(0, 0, win.Width, win.Height);
                };

                long updateCount = 0;
                var  random      = new Random();

                var tetrahedron = new RegularTetrahedron();

                win.UpdateFrame += (s, e) =>
                {
                    var keyboardState = win.Keyboard.GetState();

                    // create and fill a vertex buffer
                    vertexBuffer = new VertexBuffer <ColouredVertex>(ColouredVertex.Size);

                    //foreach (var i in Enumerable.Range(0, random.Next(100, 1000)))
                    //{
                    //    vertexBuffer.AddVertex(new ColouredVertex(new Vector3(-1f * (0.01f * updateCount), -1, -i), Color4.Lime));
                    //    vertexBuffer.AddVertex(new ColouredVertex(new Vector3(1, 1, -i), Color4.Red));
                    //    vertexBuffer.AddVertex(new ColouredVertex(new Vector3(1f * (0.01f * updateCount), -1, -i), Color4.Blue));
                    //}


                    tetrahedron.Draw(vertexBuffer);



                    // create vertex array to specify vertex layout
                    vertexArray = new VertexArray <ColouredVertex>(
                        vertexBuffer, shaderProgram,
                        new VertexAttribute("vPosition", 3, VertexAttribPointerType.Float, ColouredVertex.Size, 0),
                        new VertexAttribute("vColor", 4, VertexAttribPointerType.Float, ColouredVertex.Size, 12)
                        );

                    ++updateCount;
                };

                win.Run();
            }
        }
Beispiel #15
0
        static void Main(string[] args)
        {
            Glut.glutInit();
            Glut.glutInitDisplayMode(Glut.GLUT_DOUBLE | Glut.GLUT_DEPTH);
            Glut.glutInitWindowSize(width, height);
            Glut.glutCreateWindow("OpenGL Tutorial");

            Glut.glutIdleFunc(OnRenderFrame);
            Glut.glutDisplayFunc(OnDisplay);

            Glut.glutKeyboardFunc(OnKeyboardDown);
            Glut.glutKeyboardUpFunc(OnKeyboardUp);

            Glut.glutCloseFunc(OnClose);
            Glut.glutReshapeFunc(OnReshape);

            // enable blending and set to accumulate the star colors
            Gl.Enable(EnableCap.DepthTest);
            Gl.Enable(EnableCap.Blend);

            // create our shader program
            program = new ShaderProgram(VertexShader, FragmentShader);

            // set up the projection and view matrix
            program.Use();
            program["projection_matrix"].SetValue(Matrix4.CreatePerspectiveFieldOfView(0.45f, (float)width / height, 0.1f, 1000f));
            program["view_matrix"].SetValue(Matrix4.LookAt(new Vector3(0, 0, 20), Vector3.Zero, Vector3.Up));
            program["model_matrix"].SetValue(Matrix4.Identity);

            // load the flag texture
            flagTexture = new Texture("flag.png");

            // create the flag, which is just a plane with a certain number of segments
            List <Vector3> vertices  = new List <Vector3>();
            List <Vector2> uvs       = new List <Vector2>();
            List <int>     triangles = new List <int>();

            for (int x = 0; x < 40; x++)
            {
                for (int y = 0; y < 40; y++)
                {
                    vertices.Add(new Vector3((x - 20) / 5.0, (y - 20) / 10.0, 0));
                    uvs.Add(new Vector2(x / 39.0, 1 - y / 39.0));

                    if (y == 39 || x == 39)
                    {
                        continue;
                    }

                    triangles.Add(x * 40 + y);
                    triangles.Add((x + 1) * 40 + y);
                    triangles.Add((x + 1) * 40 + y + 1);
                    triangles.Add(x * 40 + y + 1);
                }
            }

            flagVertices  = new VBO <Vector3>(vertices.ToArray());
            flagUVs       = new VBO <Vector2>(uvs.ToArray());
            flagTriangles = new VBO <int>(triangles.ToArray(), BufferTarget.ElementArrayBuffer);

            // load the bitmap font for this tutorial
            font        = new BMFont("font24.fnt", "font24.png");
            fontProgram = new ShaderProgram(BMFont.FontVertexSource, BMFont.FontFragmentSource);

            fontProgram.Use();
            fontProgram["ortho_matrix"].SetValue(Matrix4.CreateOrthographic(width, height, 0, 1000));
            fontProgram["color"].SetValue(new Vector3(1, 1, 1));

            information = font.CreateString(fontProgram, "OpenGL  C#  Tutorial  11");

            watch = System.Diagnostics.Stopwatch.StartNew();

            Glut.glutMainLoop();
        }
Beispiel #16
0
        public void Update(FrameEventArgs e, GameWindow window)
        {
            KeyboardState input      = Keyboard.GetState();
            MouseState    mouseInput = Mouse.GetState();

            if (!window.Focused)
            {
                return;
            }
            if (input.IsKeyDown(Key.W))
            {
                position += frontDirection * moveSpeed * (float)e.Time;
            }
            if (input.IsKeyDown(Key.S))
            {
                position -= frontDirection * moveSpeed * (float)e.Time;
            }
            if (input.IsKeyDown(Key.A))
            {
                position -= Vector3.Normalize(Vector3.Cross(frontDirection, Vector3.UnitY)) * moveSpeed * (float)e.Time;
            }
            if (input.IsKeyDown(Key.D))
            {
                position += Vector3.Normalize(Vector3.Cross(frontDirection, Vector3.UnitY)) * moveSpeed * (float)e.Time;
            }
            if (input.IsKeyDown(Key.Q))
            {
                position -= Vector3.UnitY * moveSpeed * (float)e.Time;
            }
            if (input.IsKeyDown(Key.E))
            {
                position += Vector3.UnitY * moveSpeed * (float)e.Time;
            }

            if (mouseJustEntered)
            {
                lastMouseInput   = Mouse.GetState();
                mouseJustEntered = false;
            }
            else
            {
                yaw   += (mouseInput.X - lastMouseInput.X) * lookSensitivity * (float)e.Time;
                pitch -= (mouseInput.Y - lastMouseInput.Y) * lookSensitivity * (float)e.Time;
                if (pitch > 89.0f)
                {
                    pitch = 89.0f;
                }
                else if (pitch < -89.0f)
                {
                    pitch = -89.0f;
                }
            }

            RecalculateFront();

            view       = Matrix4.LookAt(position, position + frontDirection, Vector3.UnitY);
            projection = Matrix4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(fov), (float)window.Width / window.Height, 0.01f, 1000f);

            lastKeyboardInput = input;
            lastMouseInput    = mouseInput;
        }
Beispiel #17
0
        protected override void OnRenderFrame(FrameEventArgs e)
        {
            base.OnRenderFrame(e);

            GL.Enable(EnableCap.DepthTest);
            GL.Enable(EnableCap.LineSmooth);

            GL.ClearColor(0.1f, 0.1f, 0.1f, 0.1f);
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

            modelShader.UseProgram();

            modelShader.SetFloat("material.shininess", 32.0f);

            modelShader.SetVec3("light.position", lightPos);
            modelShader.SetVec3("light.ambient", 0.2f, 0.2f, 0.2f);
            modelShader.SetVec3("light.diffuse", 0.5f, 0.5f, 0.5f);
            modelShader.SetVec3("light.specular", 1.0f, 1.0f, 1.0f);
            modelShader.SetFloat("light.constant", 1.0f);
            modelShader.SetFloat("light.linear", 0.09f);
            modelShader.SetFloat("light.quadratic", 0.032f);

            modelShader.SetVec3("viewPos", viewerPos);

            var view = Matrix4.LookAt(viewerPos, new Vector3(0, 0, 0), new Vector3(0, 1, 0));

            modelShader.SetMat4("view", view);

            var projection = Matrix4.CreatePerspectiveFieldOfView((float)(45.0f * Math.PI / 180),
                                                                  Width / Height, 0.1f, 100.0f);

            modelShader.SetMat4("projection", projection);

            GL.ActiveTexture(TextureUnit.Texture0);
            GL.BindTexture(TextureTarget.Texture2D, diffuseMap);

            GL.ActiveTexture(TextureUnit.Texture1);
            GL.BindTexture(TextureTarget.Texture2D, specularMap);

            GL.BindVertexArray(cubeVAO);

            for (int i = 0; i < 10; i++)
            {
                float angle = 20.0f * i;

                var translation = Matrix4.CreateTranslation(cubePositions[i]);
                var rotation    = Matrix4.CreateFromAxisAngle(new Vector3(1.0f, 0.3f, 0.5f), MathUtil.ToRadian(angle));
                var model       = rotation * translation;

                modelShader.SetMat4("model", model);

                GL.DrawArrays(PrimitiveType.Triangles, 0, 36);
            }

            lampShader.UseProgram();
            lampShader.SetMat4("projection", projection);
            lampShader.SetMat4("view", view);

            var lampModel = Matrix4.CreateScale(0.2f) * Matrix4.CreateTranslation(lightPos);

            lampShader.SetMat4("model", lampModel);

            GL.BindVertexArray(lightVAO);
            GL.DrawArrays(PrimitiveType.Triangles, 0, 36);

            SwapBuffers();
        }
Beispiel #18
0
        public static void Start()
        {
            Bitmap bMap = new Bitmap(@"Textures/bricks.jpg");

            using (var w = new GameWindow(720, 480, null, "ComGr", GameWindowFlags.Default, DisplayDevice.Default, 4, 0, OpenTK.Graphics.GraphicsContextFlags.ForwardCompatible))
            {
                int hProgram = 0;

                float alpha = 0f;

                int   vaoTriangle        = 0;
                int[] triangleIndices    = null;
                int   vboTriangleIndices = 0;

                w.Load += (o, ea) =>
                {
                    //set up opengl
                    GL.ClearColor(0.5f, 0.5f, 0.5f, 0);
                    //GL.ClearDepth(1f);
                    GL.Enable(EnableCap.DepthTest);
                    GL.DepthMask(true);
                    GL.DepthRange(0, 50);
                    //GL.DepthFunc(DepthFunction.Less);
                    GL.Enable(EnableCap.Blend);
                    GL.BlendFunc(BlendingFactor.One, BlendingFactor.One);
                    GL.Disable(EnableCap.CullFace);


                    //load, compile and link shaders
                    //see https://www.khronos.org/opengl/wiki/Vertex_Shader
                    var VertexShaderSource = @"
                        #version 400 core

                        in vec3 pos;
                        in vec3 normals;
                        
                        uniform mat4 m;
                        uniform mat4 proj;

                        out vec3 norms;
                        out vec3 point;

                        void main()
                        {
                            gl_Position =  proj * vec4(pos,1);

                            vec4 hNorm = vec4(normals, 0);
                            vec4 hPos = vec4(pos,1);
                            norms = (m * hNorm).xyz;
                            point = (m * hPos).xyz;
                        }
                        ";

                    var hVertexShader = GL.CreateShader(ShaderType.VertexShader);
                    GL.ShaderSource(hVertexShader, VertexShaderSource);
                    GL.CompileShader(hVertexShader);
                    GL.GetShader(hVertexShader, ShaderParameter.CompileStatus, out int status);
                    if (status != 1)
                    {
                        throw new Exception(GL.GetShaderInfoLog(hVertexShader));
                    }

                    //see https://www.khronos.org/opengl/wiki/Fragment_Shader
                    var FragmentShaderSource = @"
                        #version 400 core
            
                        in vec3 norms;
                        in vec3 point;
    
                        uniform vec4 oClr;

                        out vec4 color;

                        void main()
                        {
                            //vec4 clr = vec4(1, 0, 0, 0.5);   
                            vec4 tmpClr = oClr;

                            vec3 lPos = vec3(0, 0, 5);
                            vec4 lCol = vec4(0.8, 0.8, 0.8, 1);
                            vec3 eye = vec3(0, 0, 0);
                            vec3 PL = normalize(lPos - point);
                            

                            vec3 diff = vec3(0);
                            float nL = dot(norms, PL);
                            if (tmpClr.a < 1)
                            {
                                nL = max(nL, 1 - nL);
                            }
                            
                            if(nL >= 0) { diff = lCol.xyz * tmpClr.xyz * nL; } 

                            vec3 viewDir = normalize(eye - point);
                            vec3 reflectDir = reflect(-PL, norms);
                            float fSpec = pow(max(dot(viewDir, reflectDir), 0.0), 128);
                            vec3 spec = 0.5 * fSpec * lCol.rgb;

                            color = vec4(diff + spec, oClr.a);
                         }
                        ";
                    var hFragmentShader      = GL.CreateShader(ShaderType.FragmentShader);
                    GL.ShaderSource(hFragmentShader, FragmentShaderSource);
                    GL.CompileShader(hFragmentShader);
                    GL.GetShader(hFragmentShader, ShaderParameter.CompileStatus, out status);
                    if (status != 1)
                    {
                        throw new Exception(GL.GetShaderInfoLog(hFragmentShader));
                    }

                    //link shaders to a program
                    hProgram = GL.CreateProgram();
                    GL.AttachShader(hProgram, hFragmentShader);
                    GL.AttachShader(hProgram, hVertexShader);
                    GL.LinkProgram(hProgram);
                    GL.GetProgram(hProgram, GetProgramParameterName.LinkStatus, out status);
                    if (status != 1)
                    {
                        throw new Exception(GL.GetProgramInfoLog(hProgram));
                    }

                    //upload model vertices to a vbo

                    var triangleVertices = OpenGLArrays.TriangleVertices();

                    var vboTriangleVertices = GL.GenBuffer();
                    GL.BindBuffer(BufferTarget.ArrayBuffer, vboTriangleVertices);
                    GL.BufferData(BufferTarget.ArrayBuffer, triangleVertices.Length * sizeof(float), triangleVertices, BufferUsageHint.StaticDraw);

                    // upload model indices to a vbo
                    triangleIndices = OpenGLArrays.TriangleIndices();

                    vboTriangleIndices = GL.GenBuffer();
                    GL.BindBuffer(BufferTarget.ElementArrayBuffer, vboTriangleIndices);
                    GL.BufferData(BufferTarget.ElementArrayBuffer, triangleIndices.Length * sizeof(int), triangleIndices, BufferUsageHint.StaticDraw);

                    // upload normals to a vbo
                    var normals = OpenGLArrays.Normals();

                    var vboNormals = GL.GenBuffer();
                    GL.BindBuffer(BufferTarget.ArrayBuffer, vboNormals);
                    GL.BufferData(BufferTarget.ArrayBuffer, normals.Length * sizeof(float), normals, BufferUsageHint.StaticDraw);

                    //set up a vao
                    vaoTriangle = GL.GenVertexArray();
                    GL.BindVertexArray(vaoTriangle);

                    var posAttribIndex = GL.GetAttribLocation(hProgram, "pos");
                    if (posAttribIndex != -1)
                    {
                        GL.EnableVertexAttribArray(posAttribIndex);
                        GL.BindBuffer(BufferTarget.ArrayBuffer, vboTriangleVertices);
                        GL.VertexAttribPointer(posAttribIndex, 3, VertexAttribPointerType.Float, false, 0, 0);
                    }

                    var normAttribIndex = GL.GetAttribLocation(hProgram, "normals");
                    if (normAttribIndex != -1)
                    {
                        GL.EnableVertexAttribArray(normAttribIndex);
                        GL.BindBuffer(BufferTarget.ArrayBuffer, vboNormals);
                        GL.VertexAttribPointer(normAttribIndex, 3, VertexAttribPointerType.Float, false, 0, 0);
                    }

                    //check for errors during all previous calls
                    var error = GL.GetError();
                    if (error != ErrorCode.NoError)
                    {
                        throw new Exception(error.ToString());
                    }
                };

                w.UpdateFrame += (o, fea) =>
                {
                    //perform logic

                    alpha += 0.5f * (float)fea.Time;
                };

                w.RenderFrame += (o, fea) =>
                {
                    //clear screen and z-buffer
                    GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

                    //switch to our shader
                    GL.UseProgram(hProgram);

                    GL.DepthMask(true);
                    GL.Disable(EnableCap.Blend);

                    var scale   = Matrix4.CreateScale(0.5f);
                    var rotateY = Matrix4.CreateRotationY(alpha);
                    var rotateX = Matrix4.CreateRotationX(alpha);

                    var modelView =
                        //model
                        Matrix4.Identity

                        //view
                        * Matrix4.LookAt(new Vector3(0, 0, -10), new Vector3(0, 0, 0), new Vector3(0, 1, 0)); //view
                    var projection =
                        //projection
                        Matrix4.CreatePerspectiveFieldOfView(45 * (float)(Math.PI / 180d), w.ClientRectangle.Width / (float)w.ClientRectangle.Height, 0.1f, 100f);

                    // Solid Cube
                    var translate = Matrix4.CreateTranslation(-1.3f, 0, 0);
                    var M         = rotateX * rotateY * translate * modelView;

                    var mAttribIndex = GL.GetUniformLocation(hProgram, "m");
                    if (mAttribIndex != -1)
                    {
                        GL.UniformMatrix4(mAttribIndex, false, ref M);
                    }

                    var MVP             = M * projection;
                    var projAttribIndex = GL.GetUniformLocation(hProgram, "proj");
                    if (projAttribIndex != -1)
                    {
                        GL.UniformMatrix4(projAttribIndex, false, ref MVP);
                    }

                    var clrSolid = new Vector4(1, 0, 0, 1);

                    var clrAttribIndex = GL.GetUniformLocation(hProgram, "oClr");
                    if (clrAttribIndex != -1)
                    {
                        GL.Uniform4(clrAttribIndex, ref clrSolid);
                    }

                    //render our model
                    GL.BindVertexArray(vaoTriangle);
                    GL.BindBuffer(BufferTarget.ElementArrayBuffer, vboTriangleIndices);
                    GL.DrawElements(PrimitiveType.Triangles, triangleIndices.Length, DrawElementsType.UnsignedInt, 0);



                    GL.Enable(EnableCap.Blend);
                    GL.DepthMask(false);

                    // Transparent Cube
                    var rotateZ = Matrix4.CreateRotationZ(alpha);

                    M = rotateY * rotateZ * modelView;

                    mAttribIndex = GL.GetUniformLocation(hProgram, "m");
                    if (mAttribIndex != -1)
                    {
                        GL.UniformMatrix4(mAttribIndex, false, ref M);
                    }

                    MVP             = M * projection;
                    projAttribIndex = GL.GetUniformLocation(hProgram, "proj");
                    if (projAttribIndex != -1)
                    {
                        GL.UniformMatrix4(projAttribIndex, false, ref MVP);
                    }

                    var clrTransparent = new Vector4(0, 1, 0, 0.5f);

                    clrAttribIndex = GL.GetUniformLocation(hProgram, "oClr");
                    if (clrAttribIndex != -1)
                    {
                        GL.Uniform4(clrAttribIndex, ref clrTransparent);
                    }


                    //render our model
                    GL.BindVertexArray(vaoTriangle);
                    GL.BindBuffer(BufferTarget.ElementArrayBuffer, vboTriangleIndices);
                    GL.DrawElements(PrimitiveType.Triangles, triangleIndices.Length, DrawElementsType.UnsignedInt, 0);


                    GL.DepthMask(true);

                    //display
                    w.SwapBuffers();

                    var error = GL.GetError();
                    if (error != ErrorCode.NoError)
                    {
                        throw new Exception(error.ToString());
                    }
                };

                w.Resize += (o, ea) =>
                {
                    GL.Viewport(w.ClientRectangle);
                };

                w.Run();
            }
        }
Beispiel #19
0
 /// <summary>
 /// Call to update the projection matrix of the camera
 /// </summary>
 public void UpdateCameraProjection()
 {
     mProjection = mView * Matrix4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(45), (float)mWidth / (float)mHeight, 10f, 100f);
 }
Beispiel #20
0
 public void SetProjectionPerspective(float aspect, float fov, float zNear, float zFar)
 {
     Matrix4.CreatePerspectiveFieldOfView((float)Math.PI * (fov / 180.0f), aspect, zNear, zFar, out mProjection);
 }
Beispiel #21
0
        public static void Main()
        {
            using (var game = new GameWindow())
            {
                game.Load += (sender, e) =>
                {
                    // setup settings, load textures, sounds
//                    game.VSync = VSyncMode.On;
                    GL.ClearColor(Color.Black);
                    GL.Enable(EnableCap.DepthTest);

                    Matrix4 p = Matrix4.CreatePerspectiveFieldOfView((float)(80 * Math.PI / 180), 1, 20, 500);
                    GL.MatrixMode(MatrixMode.Projection);
                    GL.LoadMatrix(ref p);

                    Matrix4 modelview = Matrix4.LookAt(70, 70, 70, 0, 0, 0, 0, 1, 0);
                    GL.MatrixMode(MatrixMode.Modelview);
                    GL.LoadMatrix(ref modelview);

                    float[] light_position = { 20.0f, 20.0f, 20.0f, 1.0f };
                    GL.Light(LightName.Light0, LightParameter.Position, light_position);
                    GL.Enable(EnableCap.Lighting);
                    GL.Enable(EnableCap.Light0);
//                    GL.Enable(EnableCap.ColorMaterial);
//                    GL.Material(MaterialFace.Front, MaterialParameter.Emission, new float[] { 0.3f, 0.3f, 0.3f, 1.0f });
                };

                game.Resize += (sender, e) =>
                {
                    GL.Viewport(0, 0, game.Width, game.Height);
                };

                game.UpdateFrame += (sender, e) =>
                {
                    // add game logic, input handling
                    if (game.Keyboard[Key.Escape])
                    {
                        game.Exit();
                    }

                    if (game.Mouse[OpenTK.Input.MouseButton.Left])
                    {
                        x_angle = game.Mouse.X;
                    }
                    else
                    //x_angle += 0.5f;

                    if (game.Keyboard[Key.M])
                    {
                        GL.Disable(EnableCap.ColorMaterial);
                        GL.Enable(EnableCap.ColorMaterial);
                        GL.Material(MaterialFace.Front, MaterialParameter.Ambient, new float[] { 0.3f, 0.3f, 0.3f, 1.0f });
                    }

                    if (game.Keyboard[Key.K])
                    {
                        GL.Disable(EnableCap.ColorMaterial);
//                        GL.Enable(EnableCap.ColorMaterial);
//                        GL.Material(MaterialFace.Front, MaterialParameter.Ambient, new float[] { 0.3f, 0.3f, 0.3f, 1.0f });
                    }
                    if (game.Keyboard[Key.E])
                    {
                        GL.Disable(EnableCap.ColorMaterial);
                        GL.Enable(EnableCap.ColorMaterial);
                        GL.Material(MaterialFace.Front, MaterialParameter.Emission, new float[] { 0.3f, 0.3f, 0.3f, 1.0f });
                    }
                    if (game.Keyboard[Key.D])
                    {
                        GL.Disable(EnableCap.ColorMaterial);
                        GL.Enable(EnableCap.ColorMaterial);
                        GL.Material(MaterialFace.Front, MaterialParameter.Diffuse, new float[] { 0.5f, 0.5f, 0.5f, 1.0f });
                    }

                    if (game.Keyboard[Key.S])
                    {
                        GL.Disable(EnableCap.ColorMaterial);
                        GL.Enable(EnableCap.ColorMaterial);
                        GL.Material(MaterialFace.Front, MaterialParameter.Shininess, new float[] { 0.3f, 0.3f, 0.3f, 1.0f });
                    }

                    zoom = game.Mouse.Wheel * 0.5f;   // Mouse.Wheel is broken on both Linux and Windows.

                    // Do not leave x_angle drift too far away, as this will cause inaccuracies.
                    if (x_angle > 360.0f)
                    {
                        x_angle -= 360.0f;
                    }
                    else if (x_angle < -360.0f)
                    {
                        x_angle += 360.0f;
                    }

//                    Matrix4d projection_matrix;//Матрица 4x4, элементы типа double
//                    GL.GetDouble(GetPName.ProjectionMatrix, out projection_matrix);//Загружаем матрицу проецирования в projection_matrix
//
////Подготавливаем матрицу поворота вокруг оси OZ
//                    double cos = Math.Cos(x_angle * Math.PI / 180);
//                    double sin = Math.Sin(x_angle * Math.PI / 180);
//
//                    Matrix4d rotating_matrix = new Matrix4d(
//                        cos, -sin, 0, 0,
//                        sin, cos,  0, 0,
//                        0,     0,  1, 0,
//                        0,     0,  0, 1
//                    );
//
//                    projection_matrix *= rotating_matrix;//умножаем матрицу проецирования на матрицу поворота
//                    GL.MatrixMode(MatrixMode.Projection);//переходим в режим проецирования
//                    GL.LoadMatrix(ref projection_matrix);//устанавливаем новую матрицу проецирования
//                    GL.Material(MaterialFace.Front, MaterialParameter.Ambient, new float[] { 0.3f, 0.3f, 0.3f, 1.0f });
                };



                game.RenderFrame += (sender, e) =>
                {
                    // render graphics
//                    GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
                    float width = 20;
                    GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

                    Matrix4 lookat = Matrix4.LookAt(-20.5f + zoom, -20.5f + zoom, -20.5f + zoom, 0, 0, 0, 0, 1, 0);
                    GL.MatrixMode(MatrixMode.Modelview);
                    GL.LoadMatrix(ref lookat);

//                    if (!(rotate_matrix[0] == 0 && rotate_matrix[1] == 0 && rotate_matrix[2] == 0))
//                    {
//                        Matrix4d projection_matrix;//Матрица 4x4, элементы типа double
//                    GL.GetDouble(GetPName.ProjectionMatrix, out projection_matrix);//Загружаем матрицу проецирования в projection_matrix
//
////Подготавливаем матрицу поворота вокруг оси OZ
//                    double cos = Math.Cos(x_angle * Math.PI / 180);
//                    double sin = Math.Sin(x_angle * Math.PI / 180);
//
//                    Matrix4d rotating_matrix = new Matrix4d(
//                        cos, -sin, 0, 0,
//                        sin, cos,  0, 0,
//                        0,     0,  1, 0,
//                        0,     0,  0, 1
//                    );
//
//                    projection_matrix *= rotating_matrix;//умножаем матрицу проецирования на матрицу поворота
//                    GL.MatrixMode(MatrixMode.Projection);//переходим в режим проецирования
//                    GL.LoadMatrix(ref projection_matrix);//устанавливаем новую матрицу проецирования
//                    }
                    //GL.Rotate(x_angle, rotate_matrix[0], rotate_matrix[1], rotate_matrix[2]);
                    GL.Rotate(x_angle, 0.0f, 1.0f, 0.0f);
                    GL.Rotate(x_angle, 1.0f, 0.0f, 0.0f);
                    //GL.Rotate(x_angle, 0.0f, 0.0f, 1.0f);
                    drawCube(width, 0, 0, 0);
                    drawCube(width, 0, width, 0);
                    drawCube(width, width, 0, 0);
                    drawCube(width, -width, 0, 0);
                    /*задняя*/
//            GL.Color3(Color.Red);
//            GL.Begin(BeginMode.Polygon);
//            GL.Vertex3(0, 0, 0);
//            GL.Vertex3(width, 0, 0);
//            GL.Vertex3(width, width, 0);
//            GL.Vertex3(0, width, 0);
//            GL.End();
//
//            /*левая*/
//            GL.Begin(BeginMode.Polygon);
//
//            GL.Vertex3(0, 0, 0);
//            GL.Vertex3(0, 0, width);
//            GL.Vertex3(0, width, width);
//            GL.Vertex3(0, width, 0);
//            GL.End();
//
//            /*нижняя*/
//            GL.Begin(BeginMode.Polygon);
//            GL.Vertex3(0, 0, 0);
//            GL.Vertex3(0, 0, width);
//            GL.Vertex3(width, 0, width);
//            GL.Vertex3(width, 0, 0);
//            GL.End();
//
//            /*верхняя*/
//            GL.Begin(BeginMode.Polygon);
//            GL.Vertex3(0, width, 0);
//            GL.Vertex3(0, width, width);
//            GL.Vertex3(width, width, width);
//            GL.Vertex3(width, width, 0);
//            GL.End();
//
//            /*передняя*/
//            GL.Begin(BeginMode.Polygon);
//            GL.Vertex3(0, 0, width);
//            GL.Vertex3(width, 0, width);
//            GL.Vertex3(width, width, width);
//            GL.Vertex3(0, width, width);
//            GL.End();
//
//            /*правая*/
//            GL.Begin(BeginMode.Polygon);
//            GL.Vertex3(width, 0, 0);
//            GL.Vertex3(width, 0, width);
//            GL.Vertex3(width, width, width);
//            GL.Vertex3(width, width, 0);
//            GL.End();
//
//			/*ребра*/
//            GL.Color3(Color.Black);
//            GL.Begin(BeginMode.LineLoop);
//            GL.Vertex3(0, 0, 0);
//            GL.Vertex3(0, width, 0);
//            GL.Vertex3(width, width, 0);
//            GL.Vertex3(width, 0, 0);
//            GL.End();
//
//            GL.Begin(BeginMode.LineLoop);
//            GL.Vertex3(width, 0, 0);
//            GL.Vertex3(width, 0, width);
//            GL.Vertex3(width, width, width);
//            GL.Vertex3(width, width, 0);
//            GL.End();
//
//            GL.Begin(BeginMode.LineLoop);
//            GL.Vertex3(0, 0, width);
//            GL.Vertex3(width, 0, width);
//            GL.Vertex3(width, width, width);
//            GL.Vertex3(0, width, width);
//            GL.End();
//
//            GL.Begin(BeginMode.LineLoop);
//            GL.Vertex3(0, 0, 0);
//            GL.Vertex3(0, 0, width);
//            GL.Vertex3(0, width, width);
//            GL.Vertex3(0, width, 0);
//            GL.End();
//
//
//            GL.Color3(Color.Red);
//            GL.Begin(BeginMode.Polygon);
//            GL.Vertex3(0, width, 0);
//            GL.Vertex3(width, width, 0);
//            GL.Vertex3(width, width + width, 0);
//            GL.Vertex3(0, width + width, 0);
//            GL.End();
//
//            /*левая*/
//            GL.Begin(BeginMode.Polygon);
//
//            GL.Vertex3(0, width, 0);
//            GL.Vertex3(0, width, width);
//            GL.Vertex3(0, width + width, width);
//            GL.Vertex3(0, width + width, 0);
//            GL.End();
//
//            /*нижняя*/
//            GL.Begin(BeginMode.Polygon);
//            GL.Vertex3(0, width, 0);
//            GL.Vertex3(0, width, width);
//            GL.Vertex3(width, width, width);
//            GL.Vertex3(width, width, 0);
//            GL.End();
//
//            /*верхняя*/
//            GL.Begin(BeginMode.Polygon);
//            GL.Vertex3(0, width + width, 0);
//            GL.Vertex3(0, width + width, width);
//            GL.Vertex3(width, width + width, width);
//            GL.Vertex3(width, width + width, 0);
//            GL.End();
//
//            /*передняя*/
//            GL.Begin(BeginMode.Polygon);
//            GL.Vertex3(0, width, width);
//            GL.Vertex3(width, width, width);
//            GL.Vertex3(width, width + width, width);
//            GL.Vertex3(0, width + width, width);
//            GL.End();
//
//            /*правая*/
//            GL.Begin(BeginMode.Polygon);
//            GL.Vertex3(width, width, 0);
//            GL.Vertex3(width, width, width);
//            GL.Vertex3(width, width + width, width);
//            GL.Vertex3(width, width + width, 0);
//            GL.End();
//
//			/*ребра*/
//            GL.Color3(Color.Black);
//            GL.Begin(BeginMode.LineLoop);
//            GL.Vertex3(0, width, 0);
//            GL.Vertex3(0, width + width, 0);
//            GL.Vertex3(width, width + width, 0);
//            GL.Vertex3(width, width, 0);
//            GL.End();
//
//            GL.Begin(BeginMode.LineLoop);
//            GL.Vertex3(width, width, 0);
//            GL.Vertex3(width, width, width);
//            GL.Vertex3(width, width + width, width);
//            GL.Vertex3(width, width + width, 0);
//            GL.End();
//
//            GL.Begin(BeginMode.LineLoop);
//            GL.Vertex3(0, width, width);
//            GL.Vertex3(width, width, width);
//            GL.Vertex3(width, width + width, width);
//            GL.Vertex3(0, width + width, width);
//            GL.End();
//
//            GL.Begin(BeginMode.LineLoop);
//            GL.Vertex3(0, width, 0);
//            GL.Vertex3(0,  width, width);
//            GL.Vertex3(0, width + width, width);
//            GL.Vertex3(0, width + width, 0);
//            GL.End();



                    game.SwapBuffers();
                };

                // Run the game at 60 updates per second
                game.Run(60.0);
            }
        }
Beispiel #22
0
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            // Set the view to use the default device
            device = MTLDevice.SystemDefault;

            if (device == null)
            {
                Console.WriteLine("Metal is not supported on this device");
                View = new NSView(View.Frame);
            }

            // Create a new command queue
            commandQueue = device.CreateCommandQueue();

            // Load all the shader files with a metal file extension in the project
            defaultLibrary = device.CreateDefaultLibrary();

            // Setup view
            mtkView          = (MTKView)View;
            mtkView.Delegate = this;
            mtkView.Device   = device;

            mtkView.SampleCount              = 1;
            mtkView.DepthStencilPixelFormat  = MTLPixelFormat.Depth32Float_Stencil8;
            mtkView.ColorPixelFormat         = MTLPixelFormat.BGRA8Unorm;
            mtkView.PreferredFramesPerSecond = 60;
            mtkView.ClearColor = new MTLClearColor(0.5f, 0.5f, 0.5f, 1.0f);

            // Load the vertex program into the library
            IMTLFunction vertexProgram = defaultLibrary.CreateFunction("cube_vertex");

            // Load the fragment program into the library
            IMTLFunction fragmentProgram = defaultLibrary.CreateFunction("cube_fragment");

            // Create a vertex descriptor from the MTKMesh
            MTLVertexDescriptor vertexDescriptor = new MTLVertexDescriptor();

            vertexDescriptor.Attributes[0].Format      = MTLVertexFormat.Float4;
            vertexDescriptor.Attributes[0].BufferIndex = 0;
            vertexDescriptor.Attributes[0].Offset      = 0;
            vertexDescriptor.Attributes[1].Format      = MTLVertexFormat.Float4;
            vertexDescriptor.Attributes[1].BufferIndex = 0;
            vertexDescriptor.Attributes[1].Offset      = 4 * sizeof(float);
            vertexDescriptor.Attributes[2].Format      = MTLVertexFormat.Float2;
            vertexDescriptor.Attributes[2].BufferIndex = 0;
            vertexDescriptor.Attributes[2].Offset      = 8 * sizeof(float);

            vertexDescriptor.Layouts[0].Stride = 10 * sizeof(float);

            vertexDescriptor.Layouts[0].StepRate     = 1;
            vertexDescriptor.Layouts[0].StepFunction = MTLVertexStepFunction.PerVertex;

            vertexBuffer = device.CreateBuffer(vertexData, MTLResourceOptions.CpuCacheModeDefault);// (MTLResourceOptions)0);

            this.clock = new System.Diagnostics.Stopwatch();
            clock.Start();

            this.view = CreateLookAt(new Vector3(0, 0, 5), new Vector3(0, 0, 0), Vector3.UnitY);
            var aspect = (float)(View.Bounds.Size.Width / View.Bounds.Size.Height);

            proj = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, aspect, 0.1f, 100);

            this.constantBuffer1 = device.CreateBuffer((uint)Marshal.SizeOf(this.param), MTLResourceOptions.CpuCacheModeDefault);
            this.constantBuffer2 = device.CreateBuffer((uint)Marshal.SizeOf(this.param), MTLResourceOptions.CpuCacheModeDefault);

            // Create a reusable pipeline state
            var pipelineStateDescriptor = new MTLRenderPipelineDescriptor
            {
                SampleCount                  = mtkView.SampleCount,
                VertexFunction               = vertexProgram,
                FragmentFunction             = fragmentProgram,
                VertexDescriptor             = vertexDescriptor,
                DepthAttachmentPixelFormat   = mtkView.DepthStencilPixelFormat,
                StencilAttachmentPixelFormat = mtkView.DepthStencilPixelFormat,
            };

            MTLRenderPipelineColorAttachmentDescriptor renderBufferAttachment = pipelineStateDescriptor.ColorAttachments[0];

            renderBufferAttachment.PixelFormat = mtkView.ColorPixelFormat;

            NSError error;

            pipelineState = device.CreateRenderPipelineState(pipelineStateDescriptor, out error);
            if (pipelineState == null)
            {
                Console.WriteLine("Failed to created pipeline state, error {0}", error);
            }

            var depthStencilState1Description = new MTLDepthStencilDescriptor
            {
                DepthCompareFunction = MTLCompareFunction.Less,
                DepthWriteEnabled    = true,
                FrontFaceStencil     = new MTLStencilDescriptor()
                {
                    WriteMask = 0xff,
                    StencilCompareFunction    = MTLCompareFunction.Always,
                    DepthStencilPassOperation = MTLStencilOperation.IncrementClamp,
                }
            };

            depthStencilState1 = device.CreateDepthStencilState(depthStencilState1Description);

            var depthStencilState2Description = new MTLDepthStencilDescriptor
            {
                DepthCompareFunction = MTLCompareFunction.Less,
                DepthWriteEnabled    = true,
                FrontFaceStencil     = new MTLStencilDescriptor()
                {
                    ReadMask  = 0xff,
                    WriteMask = 0x0,
                    StencilCompareFunction = MTLCompareFunction.NotEqual,
                }
            };

            depthStencilState2 = device.CreateDepthStencilState(depthStencilState2Description);

            // Texture
            NSImage          image            = NSImage.ImageNamed("crate.png");
            MTKTextureLoader mTKTextureLoader = new MTKTextureLoader(device);

            this.texture = mTKTextureLoader.FromCGImage(image.CGImage, new MTKTextureLoaderOptions(), out error);

            MTLSamplerDescriptor samplerDescriptor = new MTLSamplerDescriptor()
            {
                MinFilter    = MTLSamplerMinMagFilter.Linear,
                MagFilter    = MTLSamplerMinMagFilter.Linear,
                SAddressMode = MTLSamplerAddressMode.Repeat,
                TAddressMode = MTLSamplerAddressMode.Repeat,
            };

            this.sampler = device.CreateSamplerState(samplerDescriptor);
        }
Beispiel #23
0
 public void SetProjectionMatrix()
 {
     projectionMatrix = Matrix4.CreatePerspectiveFieldOfView((float)(FieldOfView * Math.PI / 180.0), AspectRatio, ZNear, ZFar);
 }
        public void Render(Bitmap output, SceneBrep scene)
        {
            if (output == null ||
                scene == null)
            {
                return;
            }

            Vector3 center;
            float   diameter = scene.GetDiameter(out center);

            if (Distance < diameter)
            {
                Distance = diameter;
            }

            // and the rest of projection matrix goes here:
            int    width  = output.Width;
            int    height = output.Height;
            float  aspect = width / (float)height;
            double az     = Azimuth / 180.0 * Math.PI;
            double el     = Elevation / 180.0 * Math.PI;

            Vector3 eye = new Vector3((float)(center.X + Distance * Math.Sin(az) * Math.Cos(el)),
                                      (float)(center.Y + Distance * Math.Sin(el)),
                                      (float)(center.Z + Distance * Math.Cos(az) * Math.Cos(el)));
            Matrix4 modelView = Matrix4.LookAt(eye, center, Vector3.UnitY);
            Matrix4 proj;

            if (Perspective)
            {
                float vv = (float)(2.0 * Math.Atan2(diameter * 0.5, Distance));
                proj = Matrix4.CreatePerspectiveFieldOfView(vv, aspect, 1.0f, 50.0f);
            }
            else
            {
                float vHalf = diameter * 0.52f;
                proj = Matrix4.CreateOrthographicOffCenter(-vHalf, vHalf,
                                                           -vHalf / aspect, vHalf / aspect,
                                                           1.0f, 50.0f);
            }

            Matrix4 compound = Matrix4.Mult(modelView, proj);
            Matrix4 viewport = Geometry.SetViewport(0, 0, width, height);

            compound = Matrix4.Mult(compound, viewport);

            // wireframe rendering:
            Graphics gr  = Graphics.FromImage(output);
            Pen      pen = new Pen(Color.FromArgb(255, 255, 80), 1.0f);
            int      n   = scene.Triangles;

            for (int i = 0; i < n; i++)
            {
                Vector4 A, B, C;
                scene.GetTriangleVertices(i, out A, out B, out C);
                A = Vector4.Transform(A, compound);
                B = Vector4.Transform(B, compound);
                C = Vector4.Transform(C, compound);
                Vector2 a = new Vector2(A.X / A.W, A.Y / A.W);
                Vector2 b = new Vector2(B.X / B.W, B.Y / B.W);
                Vector2 c = new Vector2(C.X / C.W, C.Y / C.W);
                gr.DrawLine(pen, a.X, a.Y, b.X, b.Y);
                gr.DrawLine(pen, b.X, b.Y, c.X, c.Y);
                gr.DrawLine(pen, c.X, c.Y, a.X, a.Y);
            }

            if (DrawNormals && scene.Normals > 0)
            {
                pen = new Pen(Color.FromArgb(255, 80, 80), 1.0f);
                n   = scene.Vertices;
                for (int i = 0; i < n; i++)
                {
                    Vector4 V = new Vector4(scene.GetVertex(i), 1.0f);
                    Vector3 N = scene.GetNormal(i);
                    N.Normalize();
                    N *= diameter * 0.03f;
                    Vector4 W = V + new Vector4(N);
                    V = Vector4.Transform(V, compound);
                    W = Vector4.Transform(W, compound);
                    Vector2 v = new Vector2(V.X / V.W, V.Y / V.W);
                    Vector2 w = new Vector2(W.X / W.W, W.Y / W.W);
                    gr.DrawLine(pen, v.X, v.Y, w.X, w.Y);
                }
            }
        }
        private void gl_custom_Paint(object sender, PaintEventArgs e)
        {
            if (!m_gl_loaded)
            {
                return;
            }

            // GL Setup
            gl_custom.MakeCurrent();
            GL.ClearColor(GLView.C_bg);
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
            GL.Viewport(0, 0, (int)m_control_sz.X, (int)m_control_sz.Y);

            // Perspective mode
            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadIdentity();
            m_persp_mat  = Matrix4.CreatePerspectiveFieldOfView(Utility.RAD_45 * 1.0f, m_control_sz.X / m_control_sz.Y, 0.3f, 2000f);
            m_persp_mat2 = Matrix4.CreatePerspectiveFieldOfView(Utility.RAD_45 * 1.0f, m_control_sz.X / m_control_sz.Y, 0.3f, 2000f);
            GL.LoadMatrix(ref m_persp_mat);

            // Camera position
            Vector3 cam_pos = Vector3.Transform(Vector3.UnitZ * m_cam_distance, Matrix4.CreateRotationX(m_cam_angles.X) * Matrix4.CreateRotationY(m_cam_angles.Y));

            m_cam_mat = Matrix4.LookAt(cam_pos, Vector3.Zero, Vector3.UnitY);
            Vector3 cam_pos2 = Vector3.Transform(Vector3.UnitZ * m_cam_distance * 1.0f, Matrix4.CreateRotationX(m_cam_angles.X) * Matrix4.CreateRotationY(m_cam_angles.Y));

            m_cam_mat2 = Matrix4.LookAt(cam_pos2, Vector3.Zero, Vector3.UnitY);
            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadMatrix(ref m_cam_mat);

            GL.Scale(1f, 1f, -1f);

            // Draw the grid
            if (m_view_mode == DViewMode.WIRE)
            {
                GL.Disable(EnableCap.DepthTest);
            }
            GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
            GL.Disable(EnableCap.CullFace);
            GL.Disable(EnableCap.Lighting);
            GL.Disable(EnableCap.Texture2D);
            GL.CallList(GL_GRID);

            // Rotate the decal to be XY for viewing (XZ is better for editing)
            GL.Rotate(-90, Vector3.UnitX);

            GL.CullFace(CullFaceMode.Front);
            GL.Enable(EnableCap.CullFace);
            GL.Enable(EnableCap.PolygonOffsetFill);
            GL.Enable(EnableCap.PolygonOffsetLine);
            GL.PolygonOffset(1f, 1f);
            if (m_view_mode != DViewMode.WIRE)
            {
                GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
                GL.Enable(EnableCap.DepthTest);
                GL.Enable(EnableCap.Lighting);
                GL.Enable(EnableCap.Light0);
                if (m_view_mode == DViewMode.TEXTURE)
                {
                    GL.Enable(EnableCap.Texture2D);
                }
            }
            else
            {
                GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
                GL.Disable(EnableCap.Lighting);
            }

            if (m_decal_loaded)
            {
                GL.CallList(GL_DECAL);
            }
            GL.Disable(EnableCap.PolygonOffsetLine);
            GL.Disable(EnableCap.PolygonOffsetFill);

            GL.Disable(EnableCap.Lighting);
            GL.Disable(EnableCap.Texture2D);

            if (m_decal_loaded)
            {
                // Lights
                for (int i = 0; i < DMesh.NUM_LIGHTS; i++)
                {
                    if (m_active_dmesh.light[i].enabled)
                    {
                        DLight dl = m_active_dmesh.light[i];
                        if (i == m_selected_light)
                        {
                            GL.Color3(Color.GreenYellow);
                        }
                        else
                        {
                            GL.Color3(Color.LightYellow);
                        }
                        GL.PushMatrix();
                        GL.Translate(dl.position);
                        GL.CallList(GL_LIGHT);
                        if (dl.style == LightStyle.SPOT)
                        {
                            var light_rotation = dl.rotation;
                            GL.MultMatrix(ref light_rotation);
                            GL.CallList(GL_LIGHT_CONE);
                        }
                        GL.PopMatrix();
                    }
                }
            }

            if (m_selected_face > -1)
            {
                // Selected face
                GL.Disable(EnableCap.DepthTest);
                GL.CallList(GL_SELECTED);
            }

            if (m_show_vert_normals)
            {
                GL.Disable(EnableCap.DepthTest);
                GL.CallList(GL_VERT_NORMALS);
            }

            GL.End();

            gl_custom.SwapBuffers();
        }
Beispiel #26
0
        private Matrix4 CreatePerspective()
        {
            var perspective = Matrix4.CreatePerspectiveFieldOfView((float)ConvertToRadians(Fov), _aspectRatio > 0?_aspectRatio:1, 1f, 7500f);

            return(perspective);
        }
Beispiel #27
0
        static void Main(string[] args)
        {
            Glut.glutInit();
            Glut.glutInitDisplayMode(Glut.GLUT_DOUBLE | Glut.GLUT_DEPTH | Glut.GLUT_MULTISAMPLE);   // multisampling makes things beautiful!
            Glut.glutInitWindowSize(width, height);
            Glut.glutCreateWindow("OpenGL Tutorial");

            Glut.glutIdleFunc(OnRenderFrame);
            Glut.glutDisplayFunc(OnDisplay);

            Glut.glutKeyboardFunc(OnKeyboardDown);
            Glut.glutKeyboardUpFunc(OnKeyboardUp);

            Glut.glutCloseFunc(OnClose);
            Glut.glutReshapeFunc(OnReshape);

            Gl.Enable(EnableCap.DepthTest);
            Gl.Enable(EnableCap.Multisample);

            // create our shader program
            program = new ShaderProgram(VertexShader, FragmentShader);

            // set up the projection and view matrix
            program.Use();
            program["projection_matrix"].SetValue(Matrix4.CreatePerspectiveFieldOfView(0.45f, (float)width / height, 0.1f, 1000f));
            program["view_matrix"].SetValue(Matrix4.LookAt(new Vector3(0, 0, 10), Vector3.Zero, new Vector3(0, 1, 0)));

            program["light_direction"].SetValue(new Vector3(0, 0, 1));
            program["enable_lighting"].SetValue(lighting);
            program["normalTexture"].SetValue(1);
            program["enable_mapping"].SetValue(normalMapping);

            brickDiffuse = new Texture("AlternatingBrick-ColorMap.png");
            brickNormals = new Texture("AlternatingBrick-NormalMap.png");

            Vector3[] vertices = new Vector3[] {
                new Vector3(1, 1, -1), new Vector3(-1, 1, -1), new Vector3(-1, 1, 1), new Vector3(1, 1, 1),         // top
                new Vector3(1, -1, 1), new Vector3(-1, -1, 1), new Vector3(-1, -1, -1), new Vector3(1, -1, -1),     // bottom
                new Vector3(1, 1, 1), new Vector3(-1, 1, 1), new Vector3(-1, -1, 1), new Vector3(1, -1, 1),         // front face
                new Vector3(1, -1, -1), new Vector3(-1, -1, -1), new Vector3(-1, 1, -1), new Vector3(1, 1, -1),     // back face
                new Vector3(-1, 1, 1), new Vector3(-1, 1, -1), new Vector3(-1, -1, -1), new Vector3(-1, -1, 1),     // left
                new Vector3(1, 1, -1), new Vector3(1, 1, 1), new Vector3(1, -1, 1), new Vector3(1, -1, -1)
            };
            cube = new VBO <Vector3>(vertices);

            Vector2[] uvs = new Vector2[] {
                new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 1),
                new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 1),
                new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 1),
                new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 1),
                new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 1),
                new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 1)
            };
            cubeUV = new VBO <Vector2>(uvs);

            List <int> triangles = new List <int>();

            for (int i = 0; i < 6; i++)
            {
                triangles.Add(i * 4);
                triangles.Add(i * 4 + 1);
                triangles.Add(i * 4 + 2);
                triangles.Add(i * 4);
                triangles.Add(i * 4 + 2);
                triangles.Add(i * 4 + 3);
            }
            cubeTriangles = new VBO <int>(triangles.ToArray(), BufferTarget.ElementArrayBuffer);

            Vector3[] normals = Geometry.CalculateNormals(vertices, triangles.ToArray());
            cubeNormals = new VBO <Vector3>(normals);

            Vector3[] tangents = CalculateTangents(vertices, normals, triangles.ToArray(), uvs);
            cubeTangents = new VBO <Vector3>(tangents);

            // load the bitmap font for this tutorial
            font        = new BMFont("font24.fnt", "font24.png");
            fontProgram = new ShaderProgram(BMFont.FontVertexSource, BMFont.FontFragmentSource);

            fontProgram.Use();
            fontProgram["ortho_matrix"].SetValue(Matrix4.CreateOrthographic(width, height, 0, 1000));
            fontProgram["color"].SetValue(new Vector3(1, 1, 1));

            information = font.CreateString(fontProgram, "OpenGL  C#  Tutorial  13");

            watch = System.Diagnostics.Stopwatch.StartNew();

            Glut.glutMainLoop();
        }
Beispiel #28
0
 /// <summary>
 /// Calculates <see cref="perspectiveMatrix"/>.
 /// </summary>
 protected virtual void UpdatePerspectiveMatrix()
 {
     perspectiveMatrix = Matrix4.CreatePerspectiveFieldOfView(fovRadians, RenderWidth / (float)RenderHeight, nearClipPlane, farClipPlane);
 }
 public Matrix4 Update()
 {
     PerspectiveMatrix = Matrix4.LookAt(Position, Position + LookAt, Vector3.UnitY) * Matrix4.CreatePerspectiveFieldOfView(FieldOfView * Radian, AspectRatio, MinViewDistance, MaxViewDistance);
     return(PerspectiveMatrix);
 }
Beispiel #30
0
        protected override void InitializeScene()
        {
            Texture test = TextureLoader.FileToTexture("textures/ground4k.png");


            int rayLayer     = LayerManager.RegisterLayer("raycast", new Layer(1, 2));
            int hybLayer     = LayerManager.RegisterLayer("hybrid", new Layer(1, 1 | 2));
            int physicsLayer = LayerManager.RegisterLayer("physics", new Layer(1, 1));

            LayerManager.DisableCollisions(rayLayer, physicsLayer);

            Mesh bgBox  = MeshLoader.FileToMesh("models/cube_flat.obj");
            Mesh box    = MeshLoader.FileToMesh("models/cube_flat.obj");
            Mesh sphere = MeshLoader.FileToMesh("models/sphere_smooth.obj");


            ShaderProgram.TryCreate(new Dictionary <ShaderType, string>
            {
                { ShaderType.FragmentShader, "shader/UITextRender.fs" },
                { ShaderType.VertexShader, "shader/UIRender.vs" }
            }, out ShaderProgram textShader);

            ShaderProgram.TryCreate(new Dictionary <ShaderType, string>
            {
                { ShaderType.FragmentShader, "shader/texture.fs" },
                { ShaderType.VertexShader, "shader/texture.vs" }
            }, out ShaderProgram shader);

            PhysicsDemoComponent phys = new PhysicsDemoComponent();

            GameEngine.Instance.CurrentScene.AddComponent(phys); //Adding Physics Component to world.


            DebugConsoleComponent dbg = DebugConsoleComponent.CreateConsole().GetComponent <DebugConsoleComponent>();

            dbg.AddCommand("mov", cmd_ChangeCameraPos);
            dbg.AddCommand("rot", cmd_ChangeCameraRot);
            dbg.AddCommand("reload", cmd_ReLoadScene);
            dbg.AddCommand("next", cmd_NextScene);
            GameEngine.Instance.CurrentScene.Add(dbg.Owner);

            GameObject bgObj = new GameObject(Vector3.UnitY * -3, "BG");

            bgObj.Scale = new Vector3(250, 1, 250);
            bgObj.AddComponent(new MeshRendererComponent(shader, bgBox,
                                                         TextureLoader.FileToTexture("textures/ground4k.png"), 1));
            Collider groundCol = new Collider(new Box(Vector3.Zero, 500, 1, 500), hybLayer);

            bgObj.AddComponent(groundCol);
            GameEngine.Instance.CurrentScene.Add(bgObj);

            GameObject boxO = new GameObject(Vector3.UnitY * 3, "Box");

            boxO.AddComponent(new MeshRendererComponent(shader, bgBox,
                                                        TextureLoader.FileToTexture("textures/ground4k.png"), 1));
            boxO.AddComponent(new Collider(new Box(Vector3.Zero, 1, 1, 1), physicsLayer));
            boxO.Translate(new Vector3(55, 0, 35));
            GameEngine.Instance.CurrentScene.Add(boxO);


            GameObject mouseTarget = new GameObject(Vector3.UnitY * -3, "BG");

            mouseTarget.Scale = new Vector3(1, 1, 1);
            mouseTarget.AddComponent(new MeshRendererComponent(shader, sphere,
                                                               TextureLoader.FileToTexture("textures/ground4k.png"), 1));

            GameEngine.Instance.CurrentScene.Add(mouseTarget);


            BasicCamera c = new BasicCamera(
                Matrix4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(75f),
                                                     GameEngine.Instance.Width / (float)GameEngine.Instance.Height, 0.01f, 1000f), Vector3.Zero);

            c.Rotate(new Vector3(1, 0, 0), MathHelper.DegreesToRadians(-25));
            c.Translate(new Vector3(1, 30, 45));
            c.AddComponent(new CameraRaycaster(mouseTarget, 3, boxO));
            GameEngine.Instance.CurrentScene.Add(c);
            GameEngine.Instance.CurrentScene.SetCamera(c);
        }