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 属性偏移未按预期工作的主要内容,如果未能解决你的问题,请参考以下文章