OpenGL“Hello Triangle”导致黑色窗口,版本问题?

时间:2016-07-11 07:59:12

标签: opengl

我正在尝试运行Anton Gerdelan的教程“hello triangle”中的代码,我基本上只是将其复制粘贴到QtCreator中。

我包括:GL / glew.h,GLFW / glfw3.h,stdio.h。

int main () {
// start GL context and O/S window using the GLFW helper library
if (!glfwInit ()) {
  fprintf (stderr, "ERROR: could not start GLFW3\n");
  return 1;
}

GLFWwindow* window = glfwCreateWindow (640, 480, "Hello Triangle", NULL, NULL);
if (!window) {
  fprintf (stderr, "ERROR: could not open window with GLFW3\n");
  glfwTerminate();
  return 1;
}
glfwMakeContextCurrent (window);

// start GLEW extension handler
glewExperimental = GL_TRUE;
glewInit ();

// get version info
const GLubyte* renderer = glGetString (GL_RENDERER); // get renderer string
const GLubyte* version = glGetString (GL_VERSION); // version as a string
printf ("Renderer: %s\n", renderer);
printf ("OpenGL version supported %s\n", version);

// tell GL to only draw onto a pixel if the shape is closer to the viewer
glEnable (GL_DEPTH_TEST); // enable depth-testing
glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as   "closer"

float points[] = {
0.0f,  0.5f,  0.0f,
0.5f, -0.5f,  0.0f,
-0.5f, -0.5f,  0.0f
};


GLuint vbo = 0;
glGenBuffers (1, &vbo);
glBindBuffer (GL_ARRAY_BUFFER, vbo);
glBufferData (GL_ARRAY_BUFFER, 9 * sizeof (float), points, GL_STATIC_DRAW);

GLuint vao = 0;
glGenVertexArrays (1, &vao);
glBindVertexArray (vao);
glEnableVertexAttribArray (0);
glBindBuffer (GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL);

const char* vertex_shader =
"#version 120\n"
"in vec3 vp;"
"void main () {"
"  gl_Position = vec4 (vp, 1.0);"
"}";

const char* fragment_shader =
"#version 120\n"
"out vec4 frag_colour;"
"void main () {"
"  frag_colour = vec4 (0.5, 0.0, 0.5, 1.0);"
"}";

 GLuint vs = glCreateShader (GL_VERTEX_SHADER);
glShaderSource (vs, 1, &vertex_shader, NULL);
glCompileShader (vs);
GLuint fs = glCreateShader (GL_FRAGMENT_SHADER);
glShaderSource (fs, 1, &fragment_shader, NULL);
glCompileShader (fs);

GLuint shader_programme = glCreateProgram ();
glAttachShader (shader_programme, fs);
glAttachShader (shader_programme, vs);
glLinkProgram (shader_programme);

while (!glfwWindowShouldClose (window)) {
// wipe the drawing surface clear
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram (shader_programme);

glBindVertexArray (vao);
// draw points 0-3 from the currently bound VAO with current in-use shader
glDrawArrays (GL_TRIANGLES, 0, 3);
// update other events like input handling
glfwPollEvents ();
// put the stuff we've been drawing onto the display
glfwSwapBuffers (window);
}

// close GL context and any other GLFW resources
glfwTerminate();
return 0;
}

阅读了旧的类似主题Black screen on Anton's OpenGL Hello Triangle Tutorial后,我按照建议将着色器中的#version从400改为120,因为程序告诉我:

Renderer: Mesa DRI Intel(R) G41 
OpenGL version supported 2.1 Mesa 11.2.0

然而,我仍然得到一个空的黑色窗口。 我用它来找出错误的位置:

if (glGetError() == GL_NO_ERROR) {
    qDebug() << "no errors";
}
else {
    qDebug() << "errors" ;
}

显然它在glUseProgram(shader_programme)中;

我该怎么办?我的GPU是否太弱而无法运行此代码或我做错了什么?

感谢您的帮助,

Lauriane。

编辑:

我添加了以下调试:

GLuint shader_programme = glCreateProgram ();
glAttachShader (shader_programme, vs);
glAttachShader (shader_programme, fs);
glLinkProgram (shader_programme);


GLint isCompiled ;
glGetShaderiv(shader_programme, GL_COMPILE_STATUS, &isCompiled);
if (isCompiled == GL_FALSE)
{
    qDebug() << "not compiled" ;
    GLint maxLength = 0;
    glGetShaderiv(shader_programme, GL_INFO_LOG_LENGTH, &maxLength);
    qDebug() << maxLength ;
    // The maxLength includes the NULL character
    std::vector<GLchar> errorLog(maxLength);
    glGetShaderInfoLog(shader_programme, maxLength, &maxLength, &errorLog[0]);

 }

 GLint isLinked ;
glGetProgramiv( shader_programme, GL_LINK_STATUS, &isLinked); ;
if (isLinked == GL_FALSE) {
    qDebug() << "not linked" ;
    GLint maxLength2 = 0;
    glGetShaderiv(shader_programme, GL_INFO_LOG_LENGTH, &maxLength2);
    qDebug() << maxLength2 ;
    // The maxLength includes the NULL character
    std::vector<GLchar> errorLog(maxLength2);
    glGetShaderInfoLog(shader_programme, maxLength2, &maxLength2, &errorLog[0]);
 }

返回“未链接”,0。

GLint success;
glGetProgramiv(shader_programme, GL_LINK_STATUS, &success);
if(!success)
{
    GLchar infoLog[512];
    glGetProgramInfoLog(shader_programme, 512, NULL, infoLog);
    qDebug() << infoLog ;
}

返回:错误:与未编译的shadererror链接:与未编译的着色器链接。

由于主题是一团糟(因为我),我想回忆一下,当我将着色器更改为以下版本时,它可以正常工作:

const char* vertex_shader =
"#version 120\n"
"attribute vec3 vp;"
"void main () {"
"  gl_Position = vec4 (vp, 1.0);"
"}";

const char* fragment_shader =
"#version 120\n"
"void main () {"
" gl_FragColor = vec4 (0.5, 0.0, 0.5, 1.0);"
"}";

这让我觉得它可能是兼容性问题......

编辑编辑: 在BDL的建议中,我意识到我的调试是无意义的,并将其更改为:

GLint isCompiled ;
glGetShaderiv(vs, GL_COMPILE_STATUS, &isCompiled);
if (isCompiled == GL_FALSE)
{
    qDebug() << "vs not compiled" ;
    GLint maxLength = 0;
    glGetShaderiv(vs, GL_INFO_LOG_LENGTH, &maxLength);
    GLchar errorLog[maxLength];
    glGetShaderInfoLog(vs, maxLength, NULL, errorLog);
    qDebug() << errorLog ;
}

glGetShaderiv(fs, GL_COMPILE_STATUS, &isCompiled);
if (isCompiled == GL_FALSE)
{
    qDebug() << "fs not compiled" ;
    GLint maxLength = 0;
    glGetShaderiv(fs, GL_INFO_LOG_LENGTH, &maxLength);
    GLchar errorLog[maxLength];
    glGetShaderInfoLog(fs, maxLength, NULL, errorLog);
    qDebug() << errorLog ;
}

输出结果为:

vs not compiled
0:1(10): error: GLSL 2.10 is not supported. Supported versions are: 1.10, 1.20, and 1.00 ES

fs not compiled
0:1(10): error: GLSL 2.10 is not supported. Supported versions are: 1.10, 1.20, and 1.00 ES

我要求版本2.1感谢glWindowHint(这是我可以拥有的最大值而不启用打开窗口)并设置#version 210。

当我要求1.2版并设置#version 120时,我收到错误:     vs未编译     0:2(1):错误:in' qualifier in declaration of vp'仅对GLSL 1.20中的函数参数有效     fs没有编译     0:2(1):错误:out' qualifier in declaration of frag_colour'仅对GLSL 1.20中的函数参数有效

这导致我用“属性”等将我的着色器更改为旧语法。我越来越相信我不能在这台非常便宜的计算机上运行新的OpenGL但是如果你们说我可以信任你。

1 个答案:

答案 0 :(得分:1)

vs not compiled
0:1(10): error: GLSL 2.10 is not supported. Supported versions are: 1.10, 1.20, and 1.00 ES

That error message is quite clear. You should be aware the GLSL 2.10 does not even exist. OpenGL 2.1 comes with GLSL version 1.20, so that is what you should use. The mapping between GLSL version and GL version is a bit uninituitive for historical reasons. Have a look at this answer for details.

When I ask for version 1.2

First of all, you can't do that either. Asking for specific versions was introduced in GL 3.x. Asking for GL 2.1 or asking for 1.2 does not make a difference, you get the same as you would get when not asking for a specific version at all. And that will typically be the highest supported GL version in compatibility profile. In practice, that means you most likely get up to 2.1 on implementations not supporting the compatibility profile, or just the highest version supported by your GPU, even up to the recent 4.5 on nvidia's or AMD's proprietary drivers. You might have a look at this answer for further details.

and set #version 120, I get the error:

vs not compiled 0:2(1): error: in' qualifier in declaration ofvp' only valid for function parameters in GLSL 1.20 fs not compiled 0:2(1): error: out' qualifier in declaration offrag_colour' only valid for function parameters in GLSL 1.20

This error message is also quite clear. As @HolyBlackCat already pointed out in the comments, you cannot use the generic in and out syntax in GLSL 1.20; that syntax was introduced in GLSL 1.30 / OpenGL 3.0 (with the introduction of the geometry shader as a thrid programmable stage). You cannot just take some GLSL >= 1.30 code, change the version back to GLSL 1.20, and just hope that it will work.