Drawing Triangle using OpenTK

In the previous posts we basically created the project template and also mainly talked about shader, vbo and vao. We are going to draw triangle using the information we have learned.
Drawing Triangle
Let's start drawing operation. Firstly, I'm going to define fields called vbo, vao and shader in App class:
    public class App
    {
        Window? window;
        int vbo, vao;
        Shader shader;
Let's create shaders folder in the project directory. After that, I will create new sub folder named triangle in this folder. This triangle folder will contain two files called vertexShader.glsl and fragmentShader.glsl. Let's start type source code of vertex shader:
#version 330 core
in vec3 aPos;

void main()
{
    gl_Position = vec4(aPos, 1.0);
}
aPos variable represent a attribute. It will take vertex position of each vertex. For now, we just take position. But, in the future we will pass another attributes like color, texture, normals, etc. gl_Position is default variable that we have to use when defining position of the vertex. After the vertex shader works for each vertex, and move to fragment shader. Meanwhile, different processes occur. You should know how to work the rendering pipeline briefly. in meaning is input for vertex shader. If we want to pass some data from vertex shader to fragment shader. We can use out for it. Let's start type source code of fragment shader:
#version 330 core

out vec4 FragColor;

void main()
{
    FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}
In this shader, we calculate color of pixel and, then output this pixel. FragColor is a default variable that we have to use for it. out meaning is output of fragment shader. We assign same color for each pixel.  vec4(red, green, blue, alpha)

After that, let's return the App class and create a new method called DrawTriangle. In this triangle firstly I create a shader object:
        public App()
        {
            ...
            DrawTriangle();
        }

        private void DrawTriangle()
        {
            shader = new Shader(
                "shaders/triangle/vertexShader.glsl",
                "shaders/triangle/fragmentShader.glsl"
            );
            ...
I created a float array named vertices that contains three 3d positions of triangle:
        private void DrawTriangle()
        {
            shader = new Shader(
                "shaders/triangle/vertexShader.glsl",
                "shaders/triangle/fragmentShader.glsl"
            );

            // three 3D positions
            float[] vertices = 
            {
                // x, y, z
                -0.5f, -0.5f, 0.0f, 
                 0.5f, -0.5f, 0.0f, 
                 0.0f,  0.5f, 0.0f
            };
            ...
Now, we need to pass this data to GPU via VBO. Firstly we will create VAO and bind it then we are going to create VBO and bind it also. After that, we will copy this data to vbo via BufferData method, and finally we will define attributes which tell OpenGL how to use this data correctly:
        private void DrawTriangle()
        {
            ...

            // three 3D positions
            float[] vertices = 
            {
                ...
            };
            GL.GenVertexArrays(1, out vao);
            GL.BindVertexArray(vao);
            // create vbo to store the data in opengl and copy data to vbo
            GL.GenBuffers(1, out vbo);
            GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
            GL.BufferData(BufferTarget.ArrayBuffer, sizeof(float) * vertices.Length, vertices, BufferUsageHint.StaticDraw);
            // tell opengl how to use the data via attributes
            int attrPosition_Position = GL.GetAttribLocation(shader.ShaderProgram, "aPos");
            GL.EnableVertexAttribArray(attrPosition_Position);
            GL.VertexAttribPointer(attrPosition_Position, 3, VertexAttribPointerType.Float, false, 0, 0);
            
            // unbind vbo
            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
            // unbind vao
            GL.BindVertexArray(0);
The last thing we need to do is drawing this triangle:
        private void Draw()
        {
            Clear();

            // draw triangle
            GL.UseProgram(shader.ShaderProgram);
            GL.BindVertexArray(vao);
            GL.DrawArrays(PrimitiveType.Triangles, 0, 3);
            GL.BindVertexArray(0);
        }
We need to activate shader program at first. After that, we will bind vao that is what we want to draw. Finally we use DrawArrays method to draw shape according to the activated vao. Our first index will be zero as start index and we will draw three vertex as triangle. We will unbind vao after draw method. After that, let's run the project:
Drawing triangle using OpenTK

No comments:

Post a Comment