Transformations in OpenTK

37 Views Asked by At

This is what I need to do: Apply linear transformations to the triangle using linear interpolation to generate simple animation sequences. One for each type of transformation: rotation, translation, scale. When the interpolation parameter reaches 1, reset to 0 to create a loop.

This is my code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using OpenTK.Graphics.OpenGL;
using OpenTK;
using OpenTK.Mathematics;
using OpenTK.Windowing.Common;
using OpenTK.Windowing.Desktop;

namespace BasicOpenTk
{
    public class Game : GameWindow
    {
        private int vertexBufferHandle;
        private int shaderProgramHandle;
        private int vertexArrayHandle;

        private float interpolationParameter = 0.0f;  // Parámetro de interpolación para animación
        private Matrix4 modelMatrix = Matrix4.Identity;  // Matriz de modelo para almacenar las transformaciones


        public Game(int width = 1280, int height = 768, string title = "Entrega3-Lorena Goez Ruiz")
            : base(
                GameWindowSettings.Default, 
                new NativeWindowSettings()
                {
                    Title = title,
                    ClientSize = new Vector2i(width, height),
                    WindowBorder = WindowBorder.Fixed,
                    StartVisible = false,
                    StartFocused = true,
                    API = ContextAPI.OpenGL,
                    Profile = ContextProfile.Core,
                    APIVersion = new Version(3,3)
                })
        {
            this.CenterWindow(new Vector2i(1280,768));
        }

        protected override void OnResize(ResizeEventArgs e)
        {
            GL.Viewport(0,0,e.Width, e.Height);
            base.OnResize(e);
        }

        protected override void OnLoad(){


            this.IsVisible = true;

            GL.ClearColor(new Color4(0.3f, 0.4f, 0.5f, 1.0f));  

         

            float[] vertices = new float[]
            {
                0.0f, 0.5f, 0.0f, 1.0f, 1.0f, 0.5f, 0.5f, // Cambié los valores de color a (1.0, 0.5, 0.5)
                0.4f, -0.5f, 0.0f, 1.0f, 1.0f, 0.5f, 0.5f,
                -0.4f, -0.5f, 0.0f, 1.0f, 1.0f, 0.5f, 0.5f
            };





            this.vertexBufferHandle = GL.GenBuffer();
            GL.BindBuffer(BufferTarget.ArrayBuffer, this.vertexBufferHandle);
            GL.BufferData(BufferTarget.ArrayBuffer, vertices.Length * sizeof(float), vertices, BufferUsageHint.StaticDraw);
            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);

            this.vertexArrayHandle = GL.GenVertexArray();
            GL.BindVertexArray(this.vertexArrayHandle);
            GL.BindBuffer(BufferTarget.ArrayBuffer, this.vertexBufferHandle);
            GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 7 * sizeof(float), 0);
            GL.VertexAttribPointer(1, 4, VertexAttribPointerType.Float, false, 7 * sizeof(float), 3 * sizeof(float));
            GL.EnableVertexAttribArray(0);
            GL.EnableVertexAttribArray(1);
            GL.BindVertexArray(0);

            
            string vertexShaderCode =
            @"
            #version 330 core

                layout(location = 0) in vec3 aPosition;
                layout(location = 1) in vec4 aColor;
                out vec4 vColor;                
                out vec4 gl_Position ;

                void main(void)
                {
                    gl_Position = vec4(aPosition, 1.0);
                    vColor= aColor;
                }
            ";
            string pixelShaderCode =
            @"
            #version 330
            in vec4 vColor;
            out vec4 outputColor;

            void main()
            {
                outputColor = vColor;
            }
            ";


            int vertexShaderHandle = GL.CreateShader(ShaderType.VertexShader);
            GL.ShaderSource(vertexShaderHandle, vertexShaderCode);
            GL.CompileShader(vertexShaderHandle);

            int pixelShaderHandle = GL.CreateShader(ShaderType.FragmentShader);
            GL.ShaderSource(pixelShaderHandle, pixelShaderCode);
            GL.CompileShader(pixelShaderHandle);

            this.shaderProgramHandle = GL.CreateProgram();

            // Después de compilar el shader
            int status;
            GL.GetShader(vertexShaderHandle, ShaderParameter.CompileStatus, out status);
            if (status != 1)
            {
                string infoLog = GL.GetShaderInfoLog(vertexShaderHandle);
                Console.WriteLine("Error compiling vertex shader: " + infoLog);
            }

            // Después de compilar el shader de píxeles
            GL.GetShader(pixelShaderHandle, ShaderParameter.CompileStatus, out status);
            if (status != 1)
            {
                string infoLog = GL.GetShaderInfoLog(pixelShaderHandle);
                Console.WriteLine("Error compiling pixel shader: " + infoLog);
            }


            GL.AttachShader(this.shaderProgramHandle, vertexShaderHandle);
            GL.AttachShader(this.shaderProgramHandle, pixelShaderHandle);

            GL.LinkProgram(this.shaderProgramHandle);

            GL.DetachShader(this.shaderProgramHandle, vertexShaderHandle);
            GL.DetachShader(this.shaderProgramHandle, pixelShaderHandle);

            GL.DeleteShader(vertexShaderHandle);
            GL.DeleteShader(pixelShaderHandle);

            base.OnLoad();
        }

        private Vector3 InterpolateTranslation()
        {
            float translationX = 0.5f * interpolationParameter;
            float translationY = 0.0f;
            float translationZ = 0.0f;
            return new Vector3(translationX, translationY, translationZ);
        }

        private float InterpolateRotation()
        {
            return 2 * (float)Math.PI * interpolationParameter;
        }

        private Vector3 InterpolateScale()
        {
            float scaleFactor = 0.5f + 0.5f * interpolationParameter;
            return new Vector3(scaleFactor, scaleFactor, scaleFactor);
        }

        protected override void OnUnload()
        {

            GL.BindVertexArray(0);
            GL.DeleteVertexArray(this.vertexArrayHandle);

            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
            GL.DeleteBuffer(this.vertexBufferHandle);

            GL.UseProgram(0);
            GL.DeleteProgram(this.shaderProgramHandle);

            base.OnUnload();
        }

        protected override void OnUpdateFrame(FrameEventArgs args)
        {
            UpdateAnimationParameters(args.Time);
            base.OnUpdateFrame(args);
        }

        private void UpdateAnimationParameters(double deltaTime)
        {
            // Definimos el tiempo total de animación
            float totalTime = 5.0f;  // 5 segundos para dar una vuelta completa

            // Incrementa el parámetro de interpolación basado en el tiempo
            interpolationParameter += (float)(deltaTime / totalTime);

            // Vuelve a 0 cuando llega a 1 para generar un bucle
            if (interpolationParameter > 1.0f)
                interpolationParameter -= 1.0f;

            // Aplica las transformaciones usando la interpolación lineal
            Matrix4 translationMatrix = Matrix4.CreateTranslation(InterpolateTranslation());
            Matrix4 rotationMatrix = Matrix4.CreateRotationZ(InterpolateRotation());
            Matrix4 scaleMatrix = Matrix4.CreateScale(InterpolateScale());

            // Combina las transformaciones en una matriz de modelo
            modelMatrix = translationMatrix * rotationMatrix * scaleMatrix;

            // Imprime información útil para depuración
            Console.WriteLine("Model Matrix: " + modelMatrix);
            Console.WriteLine("Rotation: " + InterpolateRotation());
            Console.WriteLine("Translation: " + InterpolateTranslation());
            Console.WriteLine("Scale: " + InterpolateScale());
        }

        protected override void OnRenderFrame(FrameEventArgs args)
        {
            GL.Clear(ClearBufferMask.ColorBufferBit);

            GL.UseProgram(this.shaderProgramHandle);
            GL.BindVertexArray(this.vertexArrayHandle);

            // Aplica la matriz de modelo al shader
            GL.UniformMatrix4(20, false, ref modelMatrix);

            // Dibuja el triángulo
            GL.DrawArrays(PrimitiveType.TriangleFan, 0, 3);

            this.Context.SwapBuffers();
            base.OnRenderFrame(args);
        }

    }
}

But my triangle is not moving

enter image description here

I tried printing InterpolateTranslation, InterpolateRotation, and InterpolateScale functions to see what was happening, and what I got was that the values are printed in an infinite loop.

What am I doing wrong?

0

There are 0 best solutions below