我正在关注OpenGL上的一些教程,并且遇到了问题。我构造了一个名为Mesh的类,该类在其构造函数中采用一个顶点数组并生成顶点数组,以进行绘制。问题是我什么也没看见。这是界面:

class Mesh
{
public:
    Mesh(Vertex * vertices, size_t numVertices);
    virtual ~Mesh();

    void Draw();
private:
    enum    {       POSITION_VB, NUM_BUFFERS    };

    GLuint m_vertexArrayObject;
    GLuint m_vertexArrayBuffers;
    size_t m_drawCount;
};


这是实现

#include "mesh.h"

Mesh::Mesh(Vertex *vertices, size_t numVertices)
{
    m_drawCount = numVertices;

    glGenVertexArrays(1, &m_vertexArrayObject);
    glBindVertexArray(m_vertexArrayObject);

    glGenBuffers(NUM_BUFFERS, &m_vertexArrayBuffers);
    glBindBuffer(GL_ARRAY_BUFFER, m_vertexArrayBuffers);
    glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(vertices[0]), vertices, GL_STATIC_DRAW);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glBindVertexArray(0);
}

void Mesh::Draw()
{
    glBindVertexArray(m_vertexArrayObject);
    glDrawArrays(GL_TRIANGLES, 0, m_drawCount);
    glBindVertexArray(0);
}

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


Vertex类型是一个简单的类,看起来像

class Vertex {
public:
    Vertex(glm::vec3 const & pos)   {   this->pos = pos;}
private:
    glm::vec3 pos;
};


如果我将Mesh::Draw()的实现更改为

glBegin(GL_TRIANGLES);
glVertex3f(-1.0f, -0.25f, 0.0f);    //triangle first vertex
glVertex3f(-0.5f, -0.25f, 0.0f);    //triangle second vertex
glVertex3f(-0.75f, 0.25f, 0.0f);    //triangle third vertex
glEnd();                            //end drawing of triangles


我正在屏幕上打印一个三角形。我的问题是:这是否必然意味着Mesh成员函数的实现中存在错误,如果存在,任何人都可以发现它吗?我以为也许glBegin方法绕过了vertexarray方法无法绕过的代码中的其他错误。我将不胜感激。另外,如果需要,我可以发布其他代码!

着色器代码:

#version 120

void main()
{
    gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0);
}

最佳答案

更有可能归咎于您的Mesh类析构函数:

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


您有一个隐式副本构造函数,该副本构造函数在需要复制Mesh时对类成员进行逐字节复制。该逐字节复制包括OpenGL管理的资源的名称(m_vertexArrayObject),这意味着您现在有两个不同的对象引用同一资源。

这些副本之一一旦超出范围,它将删除仍由原始对象引用的VAO。

解决此问题的最简单方法是禁用复制构造函数(C ++ 11为此提供了新语法),然后在需要进行复制时都会出现编译器错误。

private:
    Mesh (const Mesh& original); // Copy ctor is inaccessible.


如果确实要支持共享同一“顶点数组对象”的多个Mesh对象,则将需要添加引用计数,并且仅在引用计数达到0时释放VAO。

关于c++ - OpenGL:vertexArray与glBegin(),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40579757/

10-12 01:03