Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Can't draw a triangle on OpenGL

I followed LearnOpenGL guide and in the final part, when it was supposed to be drawing the triangle, it just didn’t.

There’s no compile or runtime errors, I just get the empty window. Since I’m a beginner I don’t know how to track the problem, like checking whatever is inside my buffers.

My main file:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

#include <stdio.h>
#include <stdlib.h>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include "shader.h"

#define ASSERT(x, str) if (!(x)) {printf(str); exit(1);}
#define WIDTH  800
#define HEIGHT 800

typedef unsigned int uint;
typedef uint8_t u8;
typedef uint16_t u16;
typedef int8_t i8;
typedef int16_t i16;
typedef int32_t i32;
typedef float f32;
typedef double f64;

// ---

typedef struct {
  GLFWwindow* window;
} Canvas;

Canvas canvas;

f32 vertices[] = {
  0.25, 0.25, 0,
  0.75, 0.25, 0,
  0.50, 0.75, 0
};

// ---

void processInput(GLFWwindow* window) {
  if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
    glfwSetWindowShouldClose(window, 1);
}

int main() {
  // Start OpenGL
  glfwInit();
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

  // Create a window
  canvas.window = glfwCreateWindow(WIDTH, HEIGHT, "", NULL, NULL);
  ASSERT(canvas.window, "Failed to create a window");
  glfwMakeContextCurrent(canvas.window);
  ASSERT(gladLoadGLLoader((GLADloadproc)glfwGetProcAddress), "Failed loading glad");
  glViewport(0, 0, WIDTH, HEIGHT);

  // Bind VBO and insert vertices into it
  uint VBO;
  glGenBuffers(1, &VBO);
  glBindBuffer(GL_ARRAY_BUFFER, VBO);
  glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

  // Compile vertex shader
  uint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
  glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL);
  glCompileShader(vertex_shader);

  i32 success;
  glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success);
  ASSERT(success, "Error compiling vertex shader");

  // Compile vertex shader
  uint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
  glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL);
  glCompileShader(fragment_shader);

  glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success);
  ASSERT(success, "Error compiling fragment shader");

  // Create shader program
  uint shader_program = glCreateProgram();
  glAttachShader(shader_program, vertex_shader);
  glAttachShader(shader_program, fragment_shader);
  glLinkProgram(shader_program);
  glDeleteShader(vertex_shader);
  glDeleteShader(fragment_shader);

  glGetProgramiv(shader_program, GL_LINK_STATUS, &success);
  ASSERT(success, "Error linking shaders");
  
  glUseProgram(shader_program);

  // Link vertex
  glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(f32), (void*) 0);
  glEnableVertexAttribArray(0);

  // Create VAO
  uint VAO;
  glGenVertexArrays(1, &VAO);
  glBindVertexArray(VAO);

  glDrawArrays(GL_TRIANGLES, 0, 3);
  glfwSwapBuffers(canvas.window);




  // Just a test area where I placed every necessary stuff
  glBindVertexArray(VAO);
  glBindBuffer(GL_ARRAY_BUFFER, VBO);
  glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
  glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(f32), (void*) 0);
  glEnableVertexAttribArray(0);
  glUseProgram(shader_program);
  glBindVertexArray(VAO);
  glDrawArrays(GL_TRIANGLES, 0, 3);
  






  // Main loop
  while(!glfwWindowShouldClose(canvas.window)) {
    processInput(canvas.window);
    glfwPollEvents();    
  }

  glfwTerminate();
  return 0;
}

My shaders:

const char* vertex_shader_source = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;"
"void main() {"
"   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1);"
"}\0";

const char* fragment_shader_source = "#version 330 core\n"
"out vec4 color;"
"void main() {"
"   color = vec4(1, 1, 1, 1);"
"}\0";

I just hope this is something really dumb instead of a problem with that glad (glad is a black-box for me)

>Solution :

You have to generate and bind the VAO (glGenVertexArrays, glBindVertexArray) before specifying the vertices with glVertexAttribPointer. When defining an array of generic vertex attribute data with glVertexAttribPointer, the corresponding buffer object and vertex array object must be bound. glVertexAttribPointer stores the ID of the buffer bound to the GL_ARRAY_BUFFER target in the state vector of the vertex array object that is currently bound.

uint VBO;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

uint VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);

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

When drawing the mesh, it is sufficient to bind the VAO with the vertex specification of the mesh:

glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading