Search code examples
openglwindowglfw

opengl and GLFW3 simple triangle draw , cant see triangle


i try to paint simple triangle but i somehow can see the triangle

Here is my files the window do created but no triangals in it dont know why

#include <iostream>

#include "GLFWManager.h"
#include <stdio.h>
#include <stdlib.h>

int main()
{
    std::cout << "Hello World!\n";
    GLFWManager gLFWManager;
    gLFWManager.Init();
    GLuint vbo;
    GLuint vao;
    GLfloat vertices[] = {
                           0.0f,  0.5f,  0.0f,
                           0.5f, -0.5f,  0.0f,
                          -0.5f, -0.5f,  0.0f,
                          // second triangle
                         0.0f, -0.5f, 0.0f,  // left
                         0.9f, -0.5f, 0.0f,  // right
                         0.45f, 0.5f, 0.0f   // top 
                            };
    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(float), (void*)0);
    glEnableVertexAttribArray(0);


    // note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
   // glBindBuffer(GL_ARRAY_BUFFER, 0);
    // You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
    // VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
   // glBindVertexArray(0);


    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
    int shaderProgram = gLFWManager.createShader();
    // Set the clear color
    glClearColor(1.0f, 0.0f, 0.0f, 0.0f);


    while (!glfwWindowShouldClose(gLFWManager.window))
    {
        glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        // draw our first triangle
        glUseProgram(shaderProgram);
        glBindVertexArray(vao); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized
        glDrawArrays(GL_TRIANGLES, 0,6); // set the count to 3 since we're drawing 3 vertices
        // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
        // -------------------------------------------------------------------------------
        glfwSwapBuffers(gLFWManager.window);
        glfwPollEvents();
    }

    // optional: de-allocate all resources once they've outlived their purpose:
    // ------------------------------------------------------------------------
    glDeleteVertexArrays(1, &vao);
    glDeleteBuffers(1, &vbo);

    // glfw: terminate, clearing all previously allocated GLFW resources.
    // ------------------------------------------------------------------

}

and this one :

#include "GLFWManager.h"
#include "stdio.h"
#include "stdlib.h"



int GLFWManager::windowHight = 300;
int GLFWManager::windowWidth = 300;

void GLFWManager::errorCallback(int error, const char* description)
{
    fprintf(stderr, "Error: %s\n", description);
}

void GLFWManager::windowSizeCallbackcallback(GLFWwindow* window, int width, int height)
{
    if (width > 0 && height > 0) {
        windowHight = height;
        windowWidth = width;
    }
}

static void KeyCallback(GLFWwindow* window, int key, int, int action, int mods)
{
    switch (key)
    {
        case GLFW_KEY_ESCAPE:
        {
            if (action == GLFW_RELEASE)
            {
                glfwSetWindowShouldClose(window, GLFW_PRESS);
            }
        }
    }
}



GLFWManager::GLFWManager()
{
    window = nullptr;
}

GLFWManager::~GLFWManager()
{

}

void GLFWManager::Init()
{
    glfwSetErrorCallback(GLFWManager::errorCallback);
    if (!glfwInit())
    {
        exit(EXIT_FAILURE);
    }

    setWindowsHints();
    createWindow();

    glfwSetKeyCallback(window, KeyCallback);
    glfwSetWindowSizeCallback(window, GLFWManager::windowSizeCallbackcallback);
    const GLFWvidmode *vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
    glfwSetWindowPos(window, (vidmode->width - windowWidth) /2 , (vidmode->height - windowHight) /2);
    glfwGetFramebufferSize(window, &windowWidth, &windowHight);
    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);
    glfwShowWindow(window);
    loadGlad();



}

void GLFWManager::setWindowsHints()
{
    glfwDefaultWindowHints();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // the window will stay hidden after creation
    glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // the window will be resizable
}

void GLFWManager::createWindow()
{
    window = glfwCreateWindow(windowWidth,windowHight, "Test", NULL, NULL);
    if (!window)
    {
        exit(EXIT_FAILURE);
    }
}

void GLFWManager::loadGlad()
{
  // glad: load all OpenGL function pointers
  // ---------------------------------------
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        fprintf(stderr, "Failed to initialize GLAD");
        exit(EXIT_FAILURE);
    }
    // get version info
    const GLubyte* renderer = glGetString(GL_RENDERER); // get renderer string
    const GLubyte* version = glGetString(GL_VERSION); // version as a string
    printf("Renderer: %s\n", renderer);
    printf("OpenGL version supported %s\n", version);
}

int GLFWManager::createShader()
{
    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.0);\n"
        "}\0";
    const char* fragmentShaderSource = "#version 330 core\n"
        "out vec4 FragColor;\n"
        "void main()\n"
        "{\n"
        "   FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
        "}\n\0";
    // build and compile our shader program
    // ------------------------------------
    // vertex shader
    int vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);
    // check for shader compile errors
    int success;
    char infoLog[512];
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
    if (!success)
    {
        glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
        printf("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n %s\n ",infoLog);
    }
    // fragment shader
    int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);
    // check for shader compile errors
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
    if (!success)
    {
        glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
        printf("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n %s \n",infoLog);
    }
    // link shaders
    int shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
    // check for linking errors
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
    if (!success) {
        glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
        printf("ERROR::SHADER::PROGRAM::LINKING_FAILED\n %s \n",infoLog);
    }
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    return shaderProgram;
}

Solution

  • glVertexAttribPointer and glEnableVertexAttribArray specify and enable an array of vertex attribute data and sets states in the state vector of the currently bound Vertex Array Object.
    You have to bind the vertex array object (glBindVertexArray) before you can specify the vertex arrays:

    // Create vertex buffer object
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    
    // Create Vertex array object
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
    
    // specify array of generic vertex array data
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    

    Note, before you call glVertexAttribPointer, the Vertex Array Object and the Vertex Buffer Object have to be bound, because glVertexAttribPointer associates the buffer which is currently bound to the ARRAY_BUFFER target, to the attribute with the specified index, in the state vector of the currently bound VAO.