Проблемы C++/OpenGL VAO

#define GLEW_STATIC
#include <GL\glew.h>
#include <GLFW\glfw3.h>
#include <GL\glew.h>
#include <glm.hpp>
#include <iostream>
#include <fstream>
#include <string>

#define WIDTH 800
#define HEIGHT 600
#define TITLE "Dynamic"

GLFWwindow* window;
int vaoID;

float vertices[] = {-0.5f, 0.5f, 0, -0.5f, -0.5f, 0,    0.5f, 0.5f, 0,  0.5f, 0.5f, 0,  -0.5f, -0.5f,   0,  0.5f, -0.5f, 0};

void loadToVAO(float vertices[]);

void update() {
    loadToVAO(vertices);
    while (!glfwWindowShouldClose(window)) {
        glfwPollEvents();
        glClear(GL_COLOR_BUFFER_BIT);
        glClearColor(1, 0, 0, 1);
        glDrawArrays(GL_TRIANGLES, 0, 6);
        glfwSwapBuffers(window);
    }
}

int main() {
    if (!glfwInit())
        std::cout << "Couldn't initialize GLFW!" << std::endl;

    window = glfwCreateWindow(WIDTH, HEIGHT, TITLE, NULL, NULL);
    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);

    if (GLEW_OK != glewInit())
        std::cout << "GLEW fucked up!" << std::endl;

    std::cout << "Your GL version: " << glGetString(GL_VERSION) << std::endl;
    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);
    update();
}



void loadShaders() {

}

void loadToVAO(float vertices[]) {
    GLuint vboID;
    GLuint vaoID;
    glGenBuffers(1, &vboID);
    glBindBuffer(GL_ARRAY_BUFFER, vboID);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices) * 8, vertices, GL_STATIC_DRAW);
    glGenVertexArrays(1, &vaoID);
    glBindVertexArray(vaoID);
    std::cout << vaoID << std::endl;
    glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
    glEnableVertexAttribArray(0);
}

Это мой код для создания и рендеринга VAO, который содержит VBO с позициями вершин. Но, к сожалению, это не работает. Он рисует треугольник вместо четырехугольника. Но когда я помещаю код функции loadToVAO в функцию обновления перед циклом while, он работает.


person Max    schedule 23.12.2016    source источник


Ответы (1)


Оператор sizeof всегда возвращает размер базового типа. Когда вы копируете содержимое loadToVAO в функцию обновления, sizeof(vertices) в основном равно sizeof(float[18]), что является общим размером массива.

Но внутри loadToVAO sizeof(vertices) принимает параметр функции vertices в качестве входных данных, а не глобальную переменную. Поскольку параметры массива неопределенного размера в C++ рассматриваются как точки одного типа, мы имеем здесь:

sizeof(vertices) == sizeof(float[]) == sizeof(float*)

это размер указателя (4 или 8), а не размер данных.

Чтобы решить эту проблему, вы можете также передать размер массива функции, что является способом C. Более современный способ — использовать std::array или std::vector для хранения данных в первую очередь.

Редактировать: при втором взгляде я увидел, что вы использовали sizeof(vertices) * 8 в первую очередь. Я не совсем уверен, откуда берется 8, так как у вас нет ни 8 элементов, ни числа с плавающей точкой не имеют размера 8 байтов.

person BDL    schedule 23.12.2016
comment
Спасибо большое, теперь работает. 8 имеет отношение к размеру байта - person Max; 23.12.2016
comment
Рад, что смог помочь. Если это решило вашу проблему, не забудьте принять ответ :) - person BDL; 24.12.2016