OpenGL 属性偏移未按预期工作

Posted

技术标签:

【中文标题】OpenGL 属性偏移未按预期工作【英文标题】:OpenGL attribute offset not working as intended 【发布时间】:2012-11-26 02:03:08 【问题描述】:

我试图弄清楚为什么glVertexAttribPointer 中使用的偏移值没有像我预期的那样工作。

代码可在http://glbase.codeplex.com/获取

我的顶点数据是这样的:

glBase::Vector3 data1[]=
    glBase::Vector3(-0.4f,0.8f,-0.0f),  //Position
    glBase::Vector3(1.0f,0.0f,0.0f),    //Color
    glBase::Vector3(-.8f,-0.8f,-0.0f),  //Position etc
    glBase::Vector3(0.0f,1.0f,0.0f),
    glBase::Vector3(0.0f,-0.8f,-0.0f),
    glBase::Vector3(0.0f,0.0f,1.0f)
;

属性绑定是这样发生的:

program.bindVertexAttribs<float>(vbo1,0, "in_Position", 3, 6, 0);
program.bindVertexAttribs<float>(vbo1,1, "in_Color", 3, 6, 12);

bindVertexAttribs 函数定义如下:

template<typename T>
void bindVertexAttribs(const VertexBufferObject& object, GLint location,const std::string& name, unsigned int width, unsigned int stride, unsigned int offset)

    object.bind();

    glBindAttribLocation(m_ID, location, name.c_str());

    glVertexAttribPointer(location, width, GL_FLOAT, GL_FALSE, stride*sizeof(T),(GLvoid *)offset);
    glEnableVertexAttribArray(location);

此代码无法在我的机器上正确呈现(ATI 5850,12.10 驱动程序)并呈现以下内容:

如果我将属性绑定更改为:

program.bindVertexAttribs<float>(vbo1,0, "in_Position", 3, 6, 12);
program.bindVertexAttribs<float>(vbo1,1, "in_Color", 3, 6, 0);

我得到了这样的正确渲染:

这对我来说没有意义,因为位置是数据数组中的前 3 个浮点数,颜色是接下来的 3 个浮点数,然后再次定位,依此类推。我错过了什么明显的东西吗?

【问题讨论】:

请停止使用这个 glBase“库”。这是三年未触及的废弃代码。并且任何将渲染函数粘贴在 program object 中的渲染器都不应该被任何人用来做任何有价值的事情。即使是 current 也是垃圾;这不是酒,它不会随着年龄的增长而变得更好。相信我:你不需要 OpenGL 的 C++ 包装器那么糟糕 我是曾经从事这项工作的开发人员之一。我最近回来尝试更新它。 哦。好的;请从程序中解耦网格状态(即:Vertex Specification 和 Vertex Rendering)。网格和网格渲染应该独立于程序。 是的,着色器程序中的 drawArrays 只是暂时的。它将进入渲染器类。 【参考方案1】:
glBindAttribLocation(m_ID, location, name.c_str());

这无济于事;随意删除这条线,看看它做了多少。

如果m_ID 是一个链接的程序对象(如果不是,那么您的代码就更没有意义了。除非您使用VAO 来捕获您的属性数组状态),那么这个函数将没有实际效果. glBindAttribLocation 仅在链接之前工作。链接后无法更改属性绑定。所以每个使用程序的对象都需要使用 same 属性。

您应该establish a proper convention for your vertex attribute names. 当您创建任何程序时,您应该在链接之前将您的约定应用于该程序。这样,您就知道in_position 始终是属性0,例如。您不必通过毫无意义的glGetAttribLocation 调用来查找它。而且你不会被诱惑去做你在这里做的事情,这是行不通的。

【讨论】:

m_ID 是一个链接的程序对象。 glBindAttribLocation only works before linking 这就是问题所在。程序对象被链接,然后绑定被调用。谢谢! 删除 glBindAttribLocation 会导致第二个屏幕截图。您的意思是在链接之后或一般情况下调用它时什么都不做? @BarışUşaklı:根据我的回答:“glBindAttribLocation 仅在链接之前有效。” 让我感到困惑的部分是glBindAttribLocation(m_ID, location, name.c_str()); This does nothing; feel free to remove this line to see how much nothing it does. 听起来我根本不需要那个。我认为您的意思是链接程序后它什么也不做。

以上是关于OpenGL 属性偏移未按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL 纹理未按定义显示

立方体在旋转时未按预期呈现

我的 C++ OpenGL SDL 程序没有按预期工作

Vue计算属性未按预期工作[关闭]

我的OpenGL学习进阶之旅介绍一下OpenGL ES的 光栅化 : 剔除多边形偏移

我的OpenGL学习进阶之旅介绍一下OpenGL ES的 光栅化 : 剔除多边形偏移