Search code examples
c++openglglfwglm-math

OpenGL circle doesn't show up?


I am trying to draw a circle, but for some reason it doesn't show up.

Here is my code for the circle data:

#define M_PI 3.1415926535
#define NUMBER_OF_VERTICES 16

    const float radius = 0.5f;
    std::vector<float> buffer;

    for (double i = 0; i < 2 * M_PI; i += 2 * M_PI / NUMBER_OF_VERTICES)
    {
        buffer.push_back(cos(i) * radius);
        buffer.push_back(sin(i) * radius);
        buffer.push_back(0.0f);
    }

    unsigned int circleVBO;
    glGenBuffers(1, &circleVBO);
    unsigned int circleVAO;
    glGenVertexArrays(1, &circleVAO);

    glBindVertexArray(circleVAO);
    glBindBuffer(GL_ARRAY_BUFFER, circleVBO);

    glBufferData(GL_ARRAY_BUFFER, buffer.size() * sizeof(float), buffer.data(), GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), buffer.data());
    glEnableVertexAttribArray(0);

and here is my code when I draw the circle:

glBindVertexArray(circleVAO);
glDrawArrays(GL_TRIANGLE_FAN, 0, NUMBER_OF_VERTICES);
glBindVertexArray(0);

For reference, here is the entire cpp file:

#include <glad/glad.h>
#include <glfw/glfw3.h>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

#include <vector>

#include "Shader.h"


const int windowWidth = 800;
const int windowHeight = 600;


void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);


void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
    glViewport(0, 0, width, height);
}

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


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


    // Create window
    GLFWwindow* window = glfwCreateWindow(windowWidth, windowHeight, "Learning OpenGL", NULL, NULL);
    if (!window)
    {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);


    // Initialize glad
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        std::cout << "Failed to initialize GLAD" << std::endl;
        return -1;
    }


    // Viewport
    glViewport(0, 0, windowWidth, windowHeight);


    // Window resize callback
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);


    // Shader setup
    Shader shader("./Shaders/shader.vert", "./Shaders/shader.frag");


    // Circle data setup
#define M_PI 3.1415926535
#define NUMBER_OF_VERTICES 16
    const float radius = 0.5f;
    std::vector<float> buffer;
    for (double i = 0; i < 2 * M_PI; i += 2 * M_PI / NUMBER_OF_VERTICES)
    {
        buffer.push_back(cos(i) * radius);
        buffer.push_back(sin(i) * radius);
        buffer.push_back(0.0f);
    }
    unsigned int circleVBO;
    glGenBuffers(1, &circleVBO);
    unsigned int circleVAO;
    glGenVertexArrays(1, &circleVAO);
    glBindVertexArray(circleVAO);
    glBindBuffer(GL_ARRAY_BUFFER, circleVBO);
    glBufferData(GL_ARRAY_BUFFER, buffer.size() * sizeof(float), buffer.data(), GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), buffer.data());
    glEnableVertexAttribArray(0);


    // Matrix transform
    glm::vec2 position = { 0.0f, 0.0f };
    float rotation = 0.0f;
    glm::vec2 scale = { 20.0f, 20.0f };
    glm::mat4 projection = glm::ortho(-800.0f, 800.0f, -600.0f, 600.0f, 0.1f, 100.0f);
    glm::mat4 view = glm::lookAt(glm::vec3{ 0.0f, 0.0f, 5.0f }, glm::vec3{ 0.0f, 0.0f, 0.0f }, glm::vec3{ 0.0f, 1.0f, 0.0f });
    glm::mat4 trans = glm::mat4(1.0f);
    trans = glm::translate(trans, glm::vec3(position.x, position.y, 0.0f));
    trans = glm::rotate(trans, glm::radians(rotation), glm::vec3(0.0f, 0.0f, 1.0f));
    trans = glm::scale(trans, glm::vec3(scale.x, scale.y, 1.0f));
    trans = projection * view * trans;
    shader.use();
    glUniformMatrix4fv(glGetUniformLocation(shader.ID, "transform"), 1, GL_FALSE, glm::value_ptr(trans));


    // Main loop
    while (!glfwWindowShouldClose(window))
    {
        // Input processing
        processInput(window);


        // Pre-draw
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);


        // Use shader
        shader.use();


        // Draw
        glBindVertexArray(circleVAO);
        glDrawArrays(GL_TRIANGLE_FAN, 0, NUMBER_OF_VERTICES);
        glBindVertexArray(0);


        // Post-draw
        glfwSwapBuffers(window);
        glfwPollEvents();
    }


    glfwTerminate();
    return 0;
}

In terms of running the program, the window shows up with the expected background clear color, but nothing else.


Solution

    1. The main problem is that the last argument for glVertexAttribPointer is supposed to be 0 or (void*)0.
    2. The second issue is that the radius is too small for the orthographic projection. Increasing it from 0.5f should make the circle visible.