OpenGL и GLFW3 просто рисуют треугольник, не вижу треугольника - PullRequest
1 голос
/ 14 марта 2020

Я пытаюсь нарисовать простой треугольник, но я каким-то образом могу видеть треугольник

Вот мои файлы, которые было создано окном, но нет треугольников в нем, не знаю, почему

#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.
    // ------------------------------------------------------------------

}

и этот :

#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;
}

1 Ответ

2 голосов
/ 14 марта 2020

glVertexAttribPointer и glEnableVertexAttribArray указывают и включают массив данных атрибутов вершины и задают состояния в векторе состояний текущего связанного объекта массива вершин .
Вам необходимо связать объект массива вершин (glBindVertexArray), прежде чем вы сможете указать массивы вершин:

// 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);

Обратите внимание, что перед вызовом glVertexAttribPointer, объект Vertex Array и объект Vertex Buffer должны быть связаны, поскольку glVertexAttribPointer связывает буфер, который в настоящее время связан с целью ARRAY_BUFFER, с атрибутом с указанным индексом в векторе состояния в настоящее время связаны ВАО.

...