Home > Blockchain >  Trying to draw a square with two triangles in OpenGL but I'm only getting a black screen
Trying to draw a square with two triangles in OpenGL but I'm only getting a black screen

Time:03-27

As the title says, I'm trying to draw a square from two triangles for class. I've tried everything I can think of but I cannot figure out why it just displays a black screen. Here is my code so far. I have the project and libraries set up correctly. I've looked over it a dozen times and can't seem to find the issue.

#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>


static unsigned int CompileShader(unsigned int type, const std::string& source) {
    unsigned int id = glCreateShader(type);
    const char* src = source.c_str();
    glShaderSource(id, 1, &src, nullptr);
    glCompileShader(id);

    return id;
}

static unsigned int CreateShader(const std::string& vrtxShader, const std::string& fragShader) {
    unsigned int program = glCreateProgram();
    //compile shaders
    unsigned int vs = CompileShader(GL_VERTEX_SHADER, vrtxShader);
    unsigned int fs = CompileShader(GL_FRAGMENT_SHADER, fragShader);

    //attach shaders to program 
    glAttachShader(program, vs);
    glAttachShader(program, fs);
    glLinkProgram(program);
    
    //delete shaders 
    glDeleteShader(vs);
    glDeleteShader(fs);

    return program;
}



int main(void)
{
    GLFWwindow* window;

    /* Initialize the library */
    if (!glfwInit())
        return -1;

    //sets up GLFW
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    

    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow(640, 480, "Module 3", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }

    /* Make the window's context current */
    glfwMakeContextCurrent(window);
    
    //Initialize GLEW 
    if (glewInit() != GLEW_OK)
        std::cout << "Error!" << std::endl;

    float vertPositions[] = {
        // index 0
       -0.5f, -0.5f, 0.0f,
       1.0f, 0.0f, 0.0f,

       // index 1
       -5.0f, 0.5f, 0.0f,
       0.0f, 0.0f, 1.0f,

       // index 2
       0.5f, -0.5f, 0.0f,
       0.0f, 1.0f, 0.0f,

       // index 3
       0.5f, 0.5f, 0.0f,
       1.0f, 0.0f, 0.0f,

    

    };

    float indices[] = { 0, 1, 2, 1, 2, 3 };

    //creates vertex buffer object
    unsigned int vbo;
    unsigned int ebo;
    glGenBuffers(1, &vbo);
    glGenBuffers(1, &ebo);

    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);

    glBufferData(GL_ARRAY_BUFFER, sizeof(vertPositions), vertPositions, GL_STATIC_DRAW);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);


    //attribute location and layout to gpu. 
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (const void*)0);
    

    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (const void*)(3 * sizeof(float)));
    

    // Vertex Shader Program Source Code
    std::string vertexShaderSource = "#version 440 core\n"
        "layout (location = 0) in vec4 aPos;\n"
        "layout (location = 1) in vec4 aColor;\n"
        "out vec4 colorOut;\n"
        "void main()\n"
        "{\n"
        "   gl_Position = aPos;\n"
        "   colorOut = aColor;\n"
        "}\n\0";


    // Fragment Shader Program Source Code
    std::string fragmentShaderSource = "#version 440 core\n"
        "in vec4 colorOut;\n"
        "out vec4 fragColor;\n"
        "void main()\n"
        "{\n"
        "fragColor = colorOut;\n"
        "}\n\0";
    
    unsigned int shader = CreateShader(vertexShaderSource, fragmentShaderSource);
    glUseProgram(shader);
   


    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window))
    {
        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT);

        //draw the shapes 
        
        glDrawElements(GL_TRIANGLES, 6, GL_FLOAT, nullptr);

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

        /* Poll for and process events */
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}

CodePudding user response:

Why using a core profile OpenGL Context (GLFW_OPENGL_CORE_PROFILE) it is mandatory to create a Vertex Array Object. There is no default VAO when using a core profile.

e.g.:

unsigned int vao, vbo, ebo;

glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

glGenBuffers(1, &vbo);
glGenBuffers(1, &ebo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertPositions), vertPositions, GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (const void*)0);    
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (const void*)(3 * sizeof(float)));

Further more the type of the indices must be integral. e.g:

unsigned int indices[] = { 0, 1, 2, 1, 2, 3 };
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
  • Related