What It Takes To Draw A Triangle in OpenGL

AHMET ALTIOGLU
3 min readDec 7, 2023

114 lines of code. …No, literally 114 lines of code. Check it out;

#include <glad.h>
#include <glfw3.h>
#include <iostream>

const unsigned int WIDTH = 500;
const unsigned int HEIGHT = 500;

//Vertex shader source code
const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
"gl_Position = vec4(aPos.x,aPos.y,aPos.z,1.0f\n"
"}\0";

//Fragment shader source code
const char* fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
"FragColor = vec4(0.8f,0.3f,0.02f,1.0f)\n"
"}\n\0";


int main()
{
//Init GLFW
glfwInit();

//GLFW ctx settings
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

//Creating the window with glfw
GLFWwindow* window;// -> allocated on stack
window = glfwCreateWindow(WIDTH, HEIGHT, "Hello OpenGL", NULL, NULL);
if (window == NULL)
{
std::cout << "Window is null. Terminating" << std::endl;
glfwTerminate();
}

glfwMakeContextCurrent(window);
gladLoadGL();
glViewport(0, 0, WIDTH, HEIGHT);

GLfloat vertices[] =
{
-0.5f, -0.5f * float(sqrt(3)) / 3, 0.0f,
0.5f, -0.5f * float(sqrt(3)) / 3, 0.0f,
0.0f, 0.5f * float(sqrt(3)) * 2 / 3, 0.0f,
};

//Create vertex shader
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);

//Create fragment shader
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);

//Create shader program
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);

glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);

//Create VBO(Vertex Buffer Object)
GLuint VBO, VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);

//Create VAO(Vertex Array Object)
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void*)0);
glEnableVertexAttribArray(0);

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);


while (!glfwWindowShouldClose(window))
{
//Change color
glClearColor(0.7f, 1.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);

//Swap front and back buffers
glfwSwapBuffers(window);

//Poll events so that it doesn't freeze
glfwPollEvents();
}

//Clean VAO, VBO and shaderProgram
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteProgram(shaderProgram);

return 0;
}

Since we started with a joke for the first time ever in my stories, Hello guys and welcome back to the “What It Takes To Render A Triangle In OpenGL”. Before getting into it, I just want to declare that I am doing this for learning purposes only which means that this might not be the best way of rendering a triangle in OpenGL. Instead, it is the one of the basic techniques that you can use. At the end of the story, we will have something like this;

A triangle rendered using OpenGL

Without further due, let’s jump in!

In the beginning, we start by including libraries such as GLAD (for using OpenGL function pointers), GLFW (for OpenGL windowing operations). For the actual window size, we define two int constants called WIDTH and HEIGHT respectively.

Next, we define vertex and fragment shaders according to GLSL. Basically, in vertex shader; we define vertex coords for the given pirimitive whereas in fragment shader; the final colors of the pixels get calculated.

Next, we adjust GLFW ‘s settings. And, create a window pointer to hold our app’s reference during the entire application. Lastly, we make sure to terminate the app if the user exits program.

Next, since we are gonna draw a triangle, we have to specify vertices. To do so, we create an array of floats to hold vertices. After that, we create vertex and fragment shaders and their programs in the following lines. Next, in order to hold pirimitive positions, we have two units called VBO (Vertex Buffer Object) and VAO(Vertex Array Object). Next, we define an attribute pointer object and reference it to VBO. Finally, we bind buffers and call “glDrawArray” function to draw our triangle. And, we don’t forget to flush buffers at the end.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

AHMET ALTIOGLU
AHMET ALTIOGLU

Written by AHMET ALTIOGLU

I am a motivated Software Developer.

No responses yet

Write a response