问题:
我有相同的 OpenGL 代码,在一台机器上运行良好,但在另一台机器上只能部分运行。
很难调试,因为问题只发生在我需要部署的机器上。在那台机器上没有崩溃、警告、错误……什么都没有。
到目前为止我尝试过的:
在我的机器上,我安装了相同的操作系统。以及与第二台机器完全相同的相同库(和相同版本)。尽管如此,代码在我的机器上运行良好,而不是在我需要部署应用程序的机器上。 BTW.,我的机器有 NVidia 卡,另一台使用 AMD。
我正在到处检查 OpenGL 中的错误(使用 glGetError),但没有找到任何东西。
我的应用程序有两个部分,一个部分使用固定管道渲染,另一个部分使用着色器。着色器渲染是其中之一中没有的部分。着色器在两台机器上都成功编译,并且其日志没有显示任何内容(使用 glGetShaderInfoLog)。
我没有其他机器(除了那2台)可以做进一步的测试,看看问题是否真的是硬件。
视频卡:
我的机器:NVidia Quadro 600 -(驱动程序版本:319.17)
部署机器:AMD FirePro W8000
重复?
代码:
我正在使用 GLFW/GLEW。
GLFW 和 GLEW 初始化
if (!glfwInit())
return;
GLFWwindow * window = glfwCreateWindow(wndWidth, wndHeight, "Window", NULL, NULL);
if (!window){
glfwTerminate();
return;
}
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK){
std::cout << "ERROR: glewInit failed!" << std::endl;
return;
}
主循环:渲染首先调用使用固定管道的渲染,然后调用使用着色器的渲染。
while (!glfwWindowShouldClose(window))
{
render();
glfwSwapBuffers(window);
glfwPollEvents();
parseEvents();
glCheckError("initWindow@MapViewer");
}
初始化VBO
glGenBuffers(3, buffers);
//Vertices
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
glBufferData(GL_ARRAY_BUFFER, num_vertices*3, attr_vertices.data(), GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
//Color
glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
glBufferData(GL_ARRAY_BUFFER, num_vertices*4, attr_colors.data(), GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);
//Size
glBindBuffer(GL_ARRAY_BUFFER, buffers[2]);
glBufferData(GL_ARRAY_BUFFER, num_vertices*1, attr_size.data(), GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, 0, 0);
着色器
std::string vertexSRC = "#version 120\n"
"attribute vec3 vertex;\n"
"attribute vec4 color;\n"
"attribute float size;\n"
"uniform mat4 matrix;\n"
"uniform vec4 bb;\n"
"uniform float size_mod;\n"
"varying vec4 vColor;\n"
"void main(void)\n"
"{\n"
" vec3 w = vec3((vertex.x-bb.x)/bb.z*2-1, (vertex.y-bb.y)/bb.w*2-1, vertex.z);\n"
" gl_Position = vec4(w, 1.0);\n"
" vColor = color;\n"
" gl_PointSize = size*size_mod;\n"
"}\n";
std::string fragmentSRC = "#version 120\n"
"varying vec4 vColor;\n"
"uniform sampler2D texture;\n"
"void main()\n"
"{\n"
" vec4 w = texture2D(texture, vec2(gl_PointCoord.x, 1.0-gl_PointCoord.y)) * vColor;\n"
" gl_FragColor = w;\n"
"}\n";
初始化着色器
vertexShader = glCreateShader(GL_VERTEX_SHADER);
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
const GLchar * vtx = vertexSRC.c_str();
const GLchar * frg = fragmentSRC.c_str();
glShaderSource(vertexShader, 1, &vtx, NULL);
glShaderSource(fragmentShader, 1, &frg, NULL);
GLint vst, fst;
glCompileShader(vertexShader);
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &vst);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &fst);
if (vst != GL_TRUE || fst != GL_TRUE){
std::cout << "ERROR compiling shaders: " << vst << " " << fst << std::endl;
return;
}
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
获取统一处理程序
glUseProgram(shaderProgram);
l_matrix = glGetUniformLocation(shaderProgram, "matrix");
l_bbLocation = glGetUniformLocation(shaderProgram, "bb");
l_texture = glGetUniformLocation(shaderProgram, "texture");
l_sizeMod = glGetUniformLocation(shaderProgram, "size_mod");
l_vertex = glGetAttribLocation(shaderProgram, "vertex");
l_color = glGetAttribLocation(shaderProgram, "color");
l_size = glGetAttribLocation(shaderProgram, "size");
渲染调用
glEnable(GL_POINT_SPRITE);
glEnable(GL_PROGRAM_POINT_SIZE);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glUseProgram(shaderProgram);
//Vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
//Color
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);
//Size
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, buffers[2]);
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, 0, 0);
glUniformMatrix4fv(l_matrix, 1, true, m);
glUniform4fv(l_bbLocation, 1, latlng_bb);
glUniform1f(l_sizeMod, GLfloat(zoom*size_mod/9.0));
//RENDER
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[face]);
glUniform1i(l_texture, 0);
glDrawArrays(GL_POINTS, 0, num_vertices);
glUseProgram(0);
//DISABLE
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glDisable(GL_POINT_SPRITE);
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glBindTexture(GL_TEXTURE_2D, 0);
欢迎任何想法、技巧、任何可以帮助我追踪问题所在的内容。
编辑0
添加了有关视频卡的更多信息。
编辑1
我只是评论了顶点着色器中的
#version 120
行,我收到了一些关于该行的警告:
0(10) : warning C7011: implicit cast from "int" to "float"
刚刚将行更改为以下内容。警告消失了,但仍然存在同样的问题。
vec3 w = vec3((vertex.x-bb.x)/bb.z*2.0-1.0, (vertex.y-bb.y)/bb.w*2.0-1.0, vertex.z);\n
我必须做两件事来解决这个问题。
首先,为了使其也能与 AMD 卡一起使用,我必须获取并使用 AttribLocation。
从此更改:
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
对此:
l_vertex = glGetAttribLocation(shaderProgram, "vertex");
glEnableVertexAttribArray(l_vertex);
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
glVertexAttribPointer(l_vertex, 3, GL_FLOAT, GL_FALSE, 0, 0);
它没有显示数据,因为大小/顶点/颜色被混合了。
此后,它在我的 Nvidia 卡上停止工作。编译着色器时没有出现任何错误。尽管如此,每次我尝试使用着色器时都会遇到错误(使用
glGetError
)。
我回去后意识到我必须从着色器中删除所有未使用的变量。