我正在YouTube上观看opengl的thechernoproject教程,并在opengl情节中编写着色器,他使用以下行定义了着色器中position属性的起始位置:
#include <boost/format.hpp>
#include <iostream>
#include <vector>
using namespace std;
string strtemplate="First:%1%, Second:%2%";
int main()
{
vector<string> v;
v.push_back("first");
v.push_back("second");
#if 0
cout<<str(boost::format(strtemplate) % v[1] % v[0])<<endl;
#else
boost::format fmter(strtemplate);
for(int i=0;i<2;++i)
{
fmter % v[i];
}
cout<<str(fmter)<<endl;
#endif
return 0;
}
但是我的问题是,为什么他需要这样做,因为肯定是他以前使用glVertexAttribPointer时是这样的:
layout(location = 0) in vec4 positions;
所以他在这里指定了如何读取包括第一个位置属性索引的缓冲区,为什么他还需要像上面一样在着色器中指定它?
您可以在视频中的23:22看到所有这些代码:https://www.youtube.com/watch?v=71BLZwRGUJE&index=7&list=PLlrATfBNZ98foTJPJ_Ev03o2oq3-GGOS2
答案 0 :(得分:4)
所以他在这里指定了如何读取包括第一个位置属性索引的缓冲区,为什么他还需要像上面一样在着色器中指定它?
准确指定着色器中的内容吗?该值是一个4元素向量吗?好吧,不要求shader属性指定的相应类型与VAO提供的类型完全相同。您可以传递integers which can get converted to floats via normalization or just "casting"。依此类推。
从示例中可以看到,着色器中指定的组件数量甚至不必与数组提供的数量匹配。您的数组为此属性发送2个组件,但是着色器需要4个组件。这就是 fine ;相应属性中的最后两个值将为0和1。
您是在说名称position
映射到属性0吗?那么,系统还如何知道从属性0读取的数组元素将进入名为position
的变量。 0对系统没有任何意义,除了索引;如果没有layout(location
部分,系统将无法确定将从数组读取的数据发送到哪里。
最后也是最重要的是……glVertexAttribPointer
修改顶点数组对象,而不是着色器。那么,如果链接程序存储在其他对象中,怎么应该知道这些东西呢?如果未在着色器中为其分配名称,您将如何写以将数组中的位置乘以矩阵?
否,该着色器中的每条信息都必须存在。这不是多余的。