OpenGL:顶点数组与 glBegin()
Posted
技术标签:
【中文标题】OpenGL:顶点数组与 glBegin()【英文标题】:OpenGL: vertexArray vs glBegin() 【发布时间】:2016-11-13 22:58:01 【问题描述】:我正在关注一些关于 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);
【问题讨论】:
着色器呢? 我在其他地方设置了着色器,我很确定它们可以正常工作,因为它们还决定了可绘制的 glBegin 部分的颜色 @Slugger:不可能编写一个可以同时使用 bothglVertex*
命令和 glVertexAttribPointer
命令的着色器。至少,并非不依赖 NVIDIA 的非标准行为。所以我想看看你的着色器。
我刚刚添加了着色器代码。抱歉回复晚了,我今天一整天都在大学
【参考方案1】:
你的网格类析构函数很可能是罪魁祸首:
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。。 p>
【讨论】:
以上是关于OpenGL:顶点数组与 glBegin()的主要内容,如果未能解决你的问题,请参考以下文章