Lazyfoo SDL2/GLSL代码仅在OS X上显示黑屏

use*_*454 1 opengl macos sdl glsl sdl-2

滚动到底部解决方案

我见过几个类似的问题(是最接近的),但还没有找到答案.我有一些代码可以在Windows和Linux上成功运行,但是当我在OS X(10.9,Mavericks)上运行时,我只是得到一个黑屏.

我正在直接复制Lazyfoo的第51个SDL2教程,在这里找到(源代码位于页面底部).

我对他的代码所做的唯一更改是修复某些包含:

#include <SDL.h> ==> #include <SDL2/SDL.h>
#include <gl\glew.h> ==> #include <GL/glew.h>
#include <SDL_opengl.h> ==> #include <SDL2/SDL_opengl.h>
#include <gl\glu.h> ==> #include <OpenGL/glu.h>
Run Code Online (Sandbox Code Playgroud)

我用g ++编译程序,我下了brew(4.9)

g++ 51_SDL_and_modern_opengl.cpp -lSDL2 -lGLEW -framework OpenGL
Run Code Online (Sandbox Code Playgroud)

我对这个问题有几个怀疑:

  1. 我正在使用SDL2(从brew下载)的OpenGL标题.我也有GLEW的brew,但我使用Apple的默认glu.
  2. 我的OS X版本无法处理OpenGL 3.3,或者它想要3.2

至于第二个,glGetString(GL_VERSION)和glGetString(GL_SHADING_LANGUAGE_VERSION)的输出是:

GL版本:3.3 NVIDIA-8.24.16 310.90.9.05f01

GLSL版本:3.30

我尝试将SDL调用中的次要版本切换为2,但这并没有解决它.我也尝试将版本更改为#version 330而不是#version 140,但仍然没有.

没什么我的意思是我得到一个黑屏,但程序编译.为了记录,我对该样本的期望是白色方块.Lazyfoo有一个教程(前一个,编号50),他使用OpenGL 2.1绘制白色方块,并且该代码在Apple机器上按预期运行.

任何帮助表示赞赏.我正在辩论要求Lazyfoo自己,但这似乎是他现在正在努力的事情.

回答

感谢Reto Koradi的答案 - 显然核心配置文件需要使用Vertex Array Objects.我通过改变从第180行开始的代码(以及添加全局VAO GLuint)来实现它:

//Create VAO
glGenVertexArrays(1, &gVAO);
glBindVertexArray(gVAO);

//Create 2 buffers (position, indices)
GLuint buffers[2];
glGenBuffers(2, buffers);   

//Create VBO
glBindBuffer( GL_ARRAY_BUFFER, buffers[0]);
glBufferData( GL_ARRAY_BUFFER, 2 * 4 * sizeof(GLfloat), vertexData, GL_STATIC_DRAW );
glEnableVertexAttribArray( gVertexPos2DLocation );
glVertexAttribPointer( gVertexPos2DLocation, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), NULL );

//Create IBO
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
glBufferData( GL_ELEMENT_ARRAY_BUFFER, 4 * sizeof(GLuint), indexData, GL_STATIC_DRAW );

glBindVertexArray(0);
Run Code Online (Sandbox Code Playgroud)

Ret*_*adi 5

您尝试使用的教程已损坏.它使用Core Profile创建一个OpenGL上下文(好!),但代码与Core Profile不兼容(糟糕!).

在核心配置文件中,您需要使用顶点阵列对象(VAO).在进行任何其他顶点状态设置调用之前,在代码的早期添加这些调用:

GLuint vaoId = 0;
glGenVertexArrays(1, &vaoId);
glBindVertexArray(vaoId);
Run Code Online (Sandbox Code Playgroud)

这应该至少让你起步并运行.为了更漂亮使用VAOs,你应该围绕移动代码,并像电话glEnableVertexAttribArray()glVertexAttribPointer()安装过程中只有一次,而VAO必然.他们设定的州将在VAO中进行跟踪.然后每次绘制时,只需再次绑定VAO即可设置所有状态.

最好的方法实际上可能是找到更好的教程.