我正在尝试在英特尔GPU上运行Piccante图像处理库。该库使用OpenGL着色器在图像上应用过滤器。根据它的文档,这个库使用的是OpenGL 4.0,所以我不得不做一个小的修改,以便让它在OpenGL 3.3上下文中运行,这是由英特尔Mesa 10.3驱动程序支持的。
当创建着色器时,我更改了以下行(在buffer_op.hpp中):prefix += glw::version("330"); // before glw::version("400")
在此修改后,我的程序仍然可以在nVidia GPU上完美地工作,即使将OpenGL上下文初始化为OpenGL 3.3 (Core Profile)。
在英特尔GPU上,该程序部分工作。它似乎工作良好,只要图像是单通道。当图像是RGB时,绘图现在不再工作,我的图像最终是黑色的。
我已经追踪到(quad.hpp)中的以下行:
void Render()
{
glBindVertexArray(vao); // (I checked that vao is not 0 here)
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // glGetError() = 1286 (GL_INVALID_OPERATION)
glBindVertexArray(0);
}
这是顶点数组对象和顶点缓冲区对象的初始化:
float *data = new float[8];
data[0] = -halfSizeX;
data[1] = halfSizeY;
data[2] = -halfSizeX;
data[3] = -halfSizeY;
data[4] = halfSizeX;
data[5] = halfSizeY;
data[6] = halfSizeX;
data[7] = -halfSizeY;
//Init VBO
glGenBuffers(1, &vbo[0]);
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), data, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//Init VAO
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBindVertexArray(0);
glDisableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
这是生成的片段着色器我试图运行:
#version 330
uniform sampler2D u_tex_1;
uniform vec4 u_val_0;
uniform vec4 u_val_1;
in vec2 v_tex_coord;
out vec4 f_color;
void main(void) {
ivec2 coords = ivec2(gl_FragCoord.xy);
vec4 ret = u_val_0;
f_color = ret;
}
我检查了顶点着色器和片段着色器编译和链接成功。这是否意味着着色器应该与GLSL 3.3兼容,问题不在着色器内,而是在其他地方?
什么可能导致程序在RGB图像上失败,而它在单通道图像上工作良好?
当上下文初始化为OpenGL 3.3时,什么可能导致程序在英特尔Mesa 10.3驱动程序上失败,而在nVidia驱动程序上工作良好?
在渲染时,似乎有很多原因可能导致GL_INVALID_OPERATION。为了追踪错误,我还需要检查哪些东西?
非常感谢您的帮助!
我一直在与Piccante库的作者Francesco Banterle交谈,他指出了以下几点:
关于英特尔驱动程序,问题是由于这些驱动程序做的事实不能自动对齐缓冲区,所以我可能不得不强制使用三种颜色通道设置为RGBA而不是RGB
当加载RGB纹理时,我将内部格式从GL_RGB32F更改为GL_RGBA32F:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0,
GL_RGB, GL_FLOAT, data); // before GL_RGB32F
这似乎解决了英特尔驱动程序的问题。