glUseProgram 不影响渲染状态
glUseProgram unaffecting the rendering state
我正在使用 ubuntu 13 上的 GL 编写一个基本的视图管理器,并使用 nvidia ION2 编写 eeepc(使用 bumblebee 项目的 optimus)。我有一个XML文件,当系统启动时,从中创建着色器(如插件)并将其添加到字典中。一旦这些被编译和链接并准备好使用,包装器函数就会使用一个包装器函数根据传递的程序名称选择适当的着色器程序。
void ShadingProgramManager::useProgram(const std::string& program){
GLuint id = getProgramId(program);
glUseProgram(id);
if(GL_INVALID_VALUE == glGetError() || GL_INVALID_OPERATION == glGetError()){
printf("Problem Loading Shader Program");
return;
}
printf("%s is in use", program.c_str());
}
其中 getProgramId 只是查看预先创建的字典并返回着色器程序的 id。
当我渲染对象时,我通过调用以下命令来使用程序:
ShadingProgramManager::getInstance()->useProgram('vc');
"VC"由以下着色器组成
顶点着色器 - vc.vert
#version 330
layout(location = 0) in vec3 position;
layout(location = 1) in vec4 color;
out vec4 vertcolor;
void main(){
vertcolor = color;
gl_Position = vec4(position, 1.0); //I've tried setting this as position * 10 also for any apparent changes on screen, but nothing changes
}
片段着色器 - vc.frag:
#version 330
in vec4 vertcolor;
out vec4 outputcolor;
void main(){
outputcolor = vertcolor;
}
我的顶点缓冲区交错为:
VertexColor vertices[] =
{
{-1.0, -1.0, 0.0, 1.0, 1.0, 1.0, 1.0}, /*first 3 floats for pos, 4 for color */
{ 1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 1.0},
{ 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0},
{-1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0},
};
索引缓冲区为:
GLuint indices[] =
{
0, 1, 2,
0, 2, 3,
};
顶点颜色定义为:
class VertexColor{
GLfloat x;
GLfloat y;
GLfloat z;
GLfloat r;
GLfloat g;
GLfloat b;
GLfloat a;
/** some constants as below **/
};
const int VertexColor::OFFSET_POSITION =0;
const int VertexColor::OFFSET_COLOR =12;
const int VertexColor::SIZE_POSITION =3;
const int VertexColor::SIZE_COLOR =4;
const int VertexColor::STRIDE =28;
然后我使用以下代码来呈现四边形:
ShadingProgramManager::getInstance()->useProgram('vc');
glBindBuffer(GL_ARRAY_BUFFER, &vb);
glBufferData(GL_ARRAY_BUFFER, size_of_vertices_array, vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, &ib);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size_of_indices_array, indices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glVertexAttribArrayPointer(0, VertexColor::SIZE_POSITION, GL_FLOAT, GL_FALSE, VertexColor::STRIDE, (GLvoid*)VertexColor::OFFSET_POSITION);
glVertexAttribArrayPointer(1, VertexColor::SIZE_COLOR, GL_FLOAT, GL_FALSE, VertexColor::STRIDE, (GLvoid*)VertexColor::OFFSET_COLOR);
glDrawElements(GL_TRIANGLES, size_of_indices, GL_UNSIGNED_INT, 0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
但是,我只看到一个白色的四边形。我怀疑是固定的函数管道生效。
即使我删除了对 glUseProgram(id) 的调用或使用 glUseProgram(0),我仍然得到相同的结果。我还尝试将顶点着色器中的位置乘以 10.0,但对屏幕没有影响。我相信着色器也在编译和链接。当我更改为使用 glUseProgram(40) 或任何无效数字时,我会收到必要的错误消息,但除此之外,我只看到一个白色单位正方形!
很抱歉这篇突兀的长帖子,但我被这个难住了......无论我对顶点着色器或碎片着色器进行什么更改,我都会得到一个白色单位正方形。我怀疑 GL 默认为 FFP,并且由于某种原因,我的着色器程序没有生效。我希望这是一个菜鸟错误,但任何指示将不胜感激。
PS:没有编译错误,所以请原谅代码中的任何语法错误。我已经在上面输入了完整的代码。
更新:我已经按照Andon,Dinesh和Spektre的建议在对glVertexAttribArrayPointer 的调用中添加了最后一个参数,我之前错过了,但仍然相同的结果。
看这一行
glVertexAttribArrayPointer(1, VertexColor::SIZE_COLOR, GL_FLOAT, GL_FALSE, VertexColor::STRIDE);
其中 是指向的指针 指定数组中第一个通用顶点属性的第一个组件的偏移量。在顶点数组中,颜色数据从第 4 位开始。您必须指定颜色数据的第一个分量的起始位置。初始指针值为 0,因此程序从第一个位置读取颜色数据到第 4 个位置,这不是颜色数据。但它可以正确读取顶点数据,因为程序将顶点数据从第一个位置读取到第三个位置,这是正确的值。这样你只能看到白色的四边形。
问题解决了。
是的,这是一个菜鸟错误,但您的所有评论都帮助我再次浏览了整个代码。我从重做FFP的所有内容开始,然后转向PFP。 所以这是错误:
我错过了在为着色器程序创建的字典中输入glAttachShader(pid, sid)
,因此当程序生效时,顶点着色器和碎片着色器从未被应用。
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- Constexpr替代了新的放置方式,可以让内存中的对象保持未初始化状态
- 我不断收到 [错误] ID 返回 1 退出状态错误,但看不到问题所在
- OSX MetalKit CVMetalTextureCacheCreateTextureFromImage失败,状态:
- 为什么擦除方法会影响结束方法
- std::future_error:无关联状态
- 内联如何影响模块接口中的成员函数
- 如何避免LED在循环状态变化中闪烁?
- 为什么返回类型的'const'限定符对标有 __forceinline/内联的函数没有影响?
- 在容量内调整矢量大小时的性能影响
- boost 是否有按特殊类型值编码状态"compact optional"?
- 重载运算符的范围是什么?它是否会影响作为类成员的集合的插入函数?
- 为什么系统函数总是在C++中返回已转移的退出状态?
- C++ 中的编译错误:未定义对"主"的引用 collect2:错误:ld 返回 1 个退出状态
- 未达到的情况会影响开关外壳性能
- 当可输入框在窗口中处于活动状态时获得通知的任何方法
- 检查两个节点在子节点上是否具有相同状态的更优雅的方法
- opengl Idempotent状态变化的影响
- C++在保存受用户输入影响的变量的状态时使用临时变量或类变量
- glUseProgram 不影响渲染状态