【问题标题】:OpenGL array handover do not workOpenGL 数组切换不起作用
【发布时间】:2016-09-25 00:37:45
【问题描述】:

我正在尝试使用 OpenGL 编写一些游戏并阅读大量教程。不幸的是,我遇到了一个小问题,只是中断了我的进度。

我创建了一个“网格”类,我在其中移交了一组 GLfloats。这些浮点数包含在 VAO 和 VBO 中。 只要我在构造函数中创建数组(使用整个初始化函数),它就可以正常工作。但是,如果我想将数组作为参数移交,OpenGL 就不会绘制。我是不是忘记了什么?

这是我的主要代码:

Mesh.cpp

Mesh::Mesh(GLfloat* vertices)
{
    glGenVertexArrays(1, &m_vertexArray);
    glBindVertexArray(m_vertexArray);

        glGenBuffers(1, &m_vertexBuffer);
        glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
            glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

            glEnableVertexAttribArray(0);
            glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

    glBindVertexArray(0);
}

Mesh::~Mesh()
{
    glDeleteVertexArrays(1, &m_vertexArray);
}

void Mesh::draw()
{
    glBindVertexArray(m_vertexArray);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glBindVertexArray(0);
}

main.cpp

[...]    

GLfloat vertices[] = {
-0.5f, -0.5f, 0.0f,
 0.5f, -0.5f, 0.0f,
 0.0f,  0.5f, 0.0f,
 -1.0f, -1.0f, 0.0f,
 0.0f, -1.0f, 0.0f,
 -0.5f,  0.0f, 0.0f
};

Mesh mesh(vertices);

while (!mainWindow->isClosed())
{
    glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    shaders->bind();

    // here main functions:

    mesh.draw();

    mainWindow->update();
}

【问题讨论】:

  • 你试过动态分配数组吗?编译器可能最终将数组置于范围之外,从而在它有机会被绘制之前将其置于堆栈之外。不过只是猜测。

标签: c++ arrays opengl vertex-buffer vertex-array


【解决方案1】:

我移交了一组 GLfloats

不,您不会“移交”任何东西的数组。你传递了一个指针。指针和数组在 C++ 中是不同的东西。最重要的是,数组可以"decay" into pointers (that's what allows you to pass them to functions that take pointers), but when they do, all sizing information is lost

sizeof(vertices)GLfloat* 的大小。很可能是 4 或 8。它肯定不是你在函数调用者中拥有的数组的大小。

处理此问题的首选方法是将指针和大小传递给该函数。但是,sizeof(vertices) 将是数组中 字节 的数量,而不是数组元素的数量。

处理此问题的一种方法是通过 C++11 获取 std::vector 而不是数组:

std::vector<GLfloat> vertices = {
-0.5f, -0.5f, 0.0f,
 0.5f, -0.5f, 0.0f,
 0.0f,  0.5f, 0.0f,
 -1.0f, -1.0f, 0.0f,
 0.0f, -1.0f, 0.0f,
 -0.5f,  0.0f, 0.0f
};

Mesh mesh(vertices.data(), vertices.size());

或者,您可以使用一些巧妙的宏来计算大小:

#define ARRAY_COUNT(arr) ( sizeof(arr) / sizeof(arr[0]))

GLfloat vertices[] = {
-0.5f, -0.5f, 0.0f,
 0.5f, -0.5f, 0.0f,
 0.0f,  0.5f, 0.0f,
 -1.0f, -1.0f, 0.0f,
 0.0f, -1.0f, 0.0f,
 -0.5f,  0.0f, 0.0f
};

Mesh mesh(vertices, ARRAY_COUNT(vertices));

或者,如果您想使用更聪明的 C++11 功能:

template<typename T, size_t N>
constexpr size_t array_count(T (&arr)[N]) {return N;}

GLfloat vertices[] = {
-0.5f, -0.5f, 0.0f,
 0.5f, -0.5f, 0.0f,
 0.0f,  0.5f, 0.0f,
 -1.0f, -1.0f, 0.0f,
 0.0f, -1.0f, 0.0f,
 -0.5f,  0.0f, 0.0f
};

Mesh mesh(vertices, array_count(vertices));

或者您可以跳过中间人,使用 C++ 核心指南support library class span

Mesh::Mesh(gsl::span<GLfloat> vertices)
{
    glGenVertexArrays(1, &m_vertexArray);
    glBindVertexArray(m_vertexArray);

    glGenBuffers(1, &m_vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, vertices.size_bytes(), vertices.data(), GL_STATIC_DRAW);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

    glBindVertexArray(0);
}

GLfloat vertices[] = {
-0.5f, -0.5f, 0.0f,
 0.5f, -0.5f, 0.0f,
 0.0f,  0.5f, 0.0f,
 -1.0f, -1.0f, 0.0f,
 0.0f, -1.0f, 0.0f,
 -0.5f,  0.0f, 0.0f
};

Mesh mesh(vertices);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-03
    • 2013-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多