奇怪的行为使用VAO(OpenGL 4.0)

我想用VAO显示一个简单的纹理猴子网格。 这里是渲染部分的代码,首先没有VAO看看我在找什么结果。

Texture *pTexture = meshList[idx]->GetSubMaterial()->getTexture(); VertexBuffer *pVBO = meshList[idx]->GetVertexBuffer(); pVBO->Lock(); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, OFFSET_BUFFER(0)); if (pTexture) { glEnableVertexAttribArray(1); glActiveTexture(GL_TEXTURE0); pTexture->Lock(); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, OFFSET_BUFFER(pVBO->GetVerticesByteSize(VERTEX_POSITION))); } glEnableVertexAttribArray(2); glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, OFFSET_BUFFER( (pVBO->GetVerticesByteSize(VERTEX_POSITION) + pVBO->GetVerticesByteSize(VERTEX_TEXTURE)))); pVBO->Unlock(); glDrawArrays(GL_TRIANGLES, 0, meshList[idx]->GetVertexBuffer()->GetBufferSize()); 

这里是输出:

在这里输入图像说明

正如你所看到的,纹理映射是正确的。

现在我想把上面的代码实现到VAO中。 所以我将它置换到主循环之前(所以不在我的渲染系统中)并将其复制到我的Mesh类(模型类)的初始化中。

这里是Mesh类的头(只是看这个类的组成,属性等等):

 class Mesh : public Resource { public: Mesh(void); Mesh(std::string const &other); Mesh(Mesh const &mesh); virtual ~Mesh(void); public: Mesh &operator=(Mesh const &other); void Create(std::string const &filename); void Create(OBJVertexImage *pVertexImg, OBJFaceImage *pFaceImg); void AttachVertexBuffer(VertexBuffer *pVertexBuffer); void AttachSubMaterial(SubMaterial *pSubMaterial); std::string const &GetUseMtlName(void) const; virtual std::string const &GetName(void) const; VertexBuffer *GetVertexBuffer(void); SubMaterial *GetSubMaterial(void) const; VertexArray *GetVertexArray(void) const; void prepareMeshRendering(void); //The VAO initialization is here !!! virtual void Release(void); private: VertexArray *m_pVertexArray; VertexBuffer *m_pVertexBuffer; SubMaterial *m_pMaterial; std::string m_UseMtlName; std::string m_Name; }; 

VAO初始化是用“prepareMeshRendering”方法写的。 当然,当我的网格已经加载(纹理和顶点缓冲区加载)时,我会调用这个方法。 顶点缓冲区尊重以下模式:

 [[all_position_vertices][all_texture_vertices][all_normal_vertices]]. 

这里是这个函数的内容:

 this->m_pVertexArray->Lock(); { this->m_pVertexBuffer->Lock(); { glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, OFFSET_BUFFER(0)); if (this->m_pMaterial->getTexture()) { glEnableVertexAttribArray(1); glActiveTexture(GL_TEXTURE0); this->m_pMaterial->getTexture()->Lock(); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, OFFSET_BUFFER(this->m_pVertexBuffer->GetVerticesByteSize(VERTEX_POSITION))); } glEnableVertexAttribArray(2); glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, OFFSET_BUFFER( this->m_pVertexBuffer->GetVerticesByteSize(VERTEX_POSITION) + this->m_pVertexBuffer->GetVerticesByteSize(VERTEX_TEXTURE))); } this->m_pVertexBuffer->Unlock(); } this->m_pVertexArray->Unlock(); 

纹理绑定代码封装在Texture类中,如下所示:

 void Texture::Lock(void) const { glBindTexture(GL_TEXTURE_2D, &this->m_Handle); } 

这与VAO绑定的概念相同,但是这次是在VertexArray类中。

渲染部分(比以前更简单):

 VertexArray *pVertexArray = meshList[idx]->GetVertexArray(); pVertexArray->Lock(); glDrawArrays(GL_TRIANGLES, 0, meshList[idx]->GetVertexBuffer()->GetBufferSize()); pVertexArray->Unlock(); 

而输出:

在这里输入图像说明

我检查了。 在这两个版本中:

  • 3个缓冲区的字节大小(位置,纹理和法线)是相同的(所以偏移更正)。

  • 纹理句柄是相同的(这里是1)

所以我不知道发生了什么事 这种显示通常在纹理未绑定或通道不正确时出现。 但在这里,在这两种情况下,我精确的通道和纹理句柄是一样的。 我会疯了! 我想我忘了一些东西,但是找不到错误。

有人可以帮我吗?

提前感谢您的帮助!

在绘图代码中我看不到任何glActiveTexture或glBindTexture调用。 据我所知,VAO只处理顶点属性。 您必须确保正确的纹理单元处于活动状态,并将您的纹理绑定到您的绘图例程中。