【问题标题】:glBufferData with an array of verticies that have 3 floats (x, y and z) eachglBufferData 具有一个顶点数组,每个顶点有 3 个浮点数(x、y 和 z)
【发布时间】:2016-08-14 18:51:22
【问题描述】:

目前我正在尝试通过网格类绘制三角形。为此,我首先初始化 glew 并调用 Window 类的 Window.initializeGraphics 方法,然后创建一个顶点数组并传递给我的 Mesh.addVerticies 方法。每个顶点有 3 个浮点数,x、y 和 z。然后我在主游戏循环的每个滴答声中调用 Mesh.draw 方法。

initializeGraphics 方法:

void Window::initializeGraphics()
{
    glClearColor(0, 0, 0, 0);

    glFrontFace(GL_CW);
    glCullFace(GL_BACK);
    glEnable(GL_CULL_FACE);
    glEnable(GL_DEPTH_TEST);

    glEnable(GL_FRAMEBUFFER_SRGB);
}

创建网格:

    m_Mesh = Mesh();

    Vertex data[] = { Vertex(vec3(-1, -1, 0)),
                      Vertex(vec3(1, -1, 0)),
                      Vertex(vec3(0,  1, 0)) };

    m_Mesh.addVerticies(data);

网头:

#include "vertex.h"
#include <GLEW\glew>
class Mesh
{
private:
    GLuint m_Vbo;
    int m_Size;
public:
    Mesh();
    void addVerticies(Vertex verticies[]);
    void draw();
};

网格 C++ 文件:

#include "mesh.h"
Mesh::Mesh()
{
    glGenBuffers(1, &m_Vbo);
}

void Mesh::addVerticies(Vertex verticies[])
{
    m_Size = (sizeof(verticies) / sizeof(*verticies));

    glBindBuffer(GL_ARRAY_BUFFER, m_Vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(verticies), verticies, GL_STATIC_DRAW);
}

void Mesh::draw()
{
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, m_Vbo);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * 4, 0);
    glDrawArrays(GL_TRIANGLES, 0, m_Size);
    glDisableVertexAttribArray(0);
}

顶点标题:

#include "vec3.h"
struct Vertex
{   
    union
    {
        vec3 pos;
        struct 
        {
            float x, y, z;
        };
    };
    Vertex(vec3 pos_);
};

顶点 C++ 文件:

#Include "vertex.h"
Vertex::Vertex(vec3 pos_)
{
    pos = pos_;
}

渲染方法:

void MainComponent::render()
{
    m_Window.clear();

    m_Mesh.draw();

    m_Window.update();
}
//m_Window.update();
void Window::update() 
{
    glfwSwapBuffers(m_GLFWWindow);
    glfwPollEvents();
}
//m_Window.clear();
void Window::clear()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

问题是,屏幕上没有出现三角形。我究竟做错了什么 ?我几乎还是一个 C++ 新手,这是我第一次编写 OpenGl,所以它可能是我一直忽略的非常基本的东西。

提前感谢您的努力。

-肖恩

【问题讨论】:

  • glBufferData(GL_ARRAY_BUFFER, sizeof(verticies), verticies, GL_STATIC_DRAW)。检查 sizeof(vertices) 的值是否正确。另外,着色器代码在哪里?
  • @PedroDavid 也不需要解决这个问题,谢谢。但我找到了它没有渲染的原因。

标签: c++ opengl


【解决方案1】:

哇,等一下!这里还有其他真正的错误。

void Mesh::addVerticies(Vertex verticies[])
{
    // This gives the wrong answer!
    m_Size = (sizeof(verticies) / sizeof(*verticies));

m_Size 的计算完全错误。这是因为verticies 是一个指针,而不是一个数组。它看起来像一个数组,它被声明为Vertex verticies[],但由于 C++ 的一个怪癖(同样适用于 C),参数衰减为一个指针。所以它最终是这样的:

void Mesh::addVerticies(Vertex *verticies)

如您所见,sizeof(verticies) 在典型的 64 位系统上始终为 8,因为您获得的只是指针的大小,而不是数组的大小。

我们可以通过使用模板捕获数组的大小来解决这个问题:

template <std::size_t N>
void addVertices(Vertex (&vertices)[N]) {
    addVertices(vertices, N);
}

void addVertices(Vertex *vertices, std::size_t count) {
    m_Size = count;

    glBindBuffer(GL_ARRAY_BUFFER, m_Vbo);
    glBufferData(
        GL_ARRAY_BUFFER,
        sizeof(*vertices) * count,
        vertices,
        GL_STATIC_DRAW);
}

因为我们使用了对数组Vertex (&amp;vertices)[N]的引用,而不是直接使用数组Vertex vertices[N],所以参数不会衰减为指针。

【讨论】:

  • 感谢我在发布问题后不久就注意到了。我现在使用m_Size = sizeof(*verticies) / sizeof(verticies);,这似乎也可以解决。
  • @SeanO'Hanlon:这是不正确的。 sizeof(*verticies) / sizeof(verticies) 没有给出正确答案,因为 verticies 是一个指针,所以无论数组有多大,你总是会得到相同的结果。
  • 我有点困惑我应该如何实现这个。你介意解释一下吗?
  • 基本上,如果x 是您传递给函数的数组,sizeof(*x) 不会给您想要的答案。因此,您需要将数组的大小作为函数参数传递,或者使用其他技巧(如模板)为您完成。 C++ 充满了像这样的小缺陷,这使得该语言在没有任何实际好处的情况下更难使用。
  • 我将如何实现template &lt;std::size_t N&gt; void addVertices(Vertex (&amp;vertices)[N]) { addVertices(vertices, N); } 部分?
【解决方案2】:

我觉得自己像个彻头彻尾的白痴……屏幕上出现了一个顶点。我想我会收工的:/

【讨论】:

  • 顺便说一句,剪辑不应该是这样工作的。如果多边形中的一个顶点是“屏幕外”(在查看体积之外),则剩余部分仍会被填充。
  • 不是当剩下的两个在底部角落并且缺少的一个在它们下方时
猜你喜欢
  • 2020-08-09
  • 1970-01-01
  • 1970-01-01
  • 2021-01-23
  • 2016-11-23
  • 1970-01-01
  • 1970-01-01
  • 2019-09-03
  • 1970-01-01
相关资源
最近更新 更多