The*_*mer 0 opengl macos shader objective-c
我正在尝试在我的程序中创建自己的顶点和片段着色器(这基本上是一个非常简单的程序,用VBO显示一个三角形).但是,当我尝试运行它时,我总是会看到一个没有任何显示的黑屏.我检查了编译日志,它返回没有错误.我还没有使用我自己的自定义着色器运行程序,这让我想知道我在这里做错了什么.我在OpenGL 3.2和GLSL 1.5上运行我的代码
以下是我正在尝试运行的代码
GLuint vbo;
GLfloat data[] = {0.0, 0.0, -5.0,
1.0, 0.0, -5.0,
1.0, 1.0, -5.0
};
const char *vertexShader = "\n\
#version 150\n\
\n\
layout (location=0) in vec4 position;\n\
void main()\n\
{\n\
gl_Position = position;\n\
}\n\
";
const char *fragmentShader = "\n\
#version 150\n\
\n\
out vec4 outColor;\n\
\n\
void main()\n\
{\n\
outColor = vec4(1.0, 0.0, 0.0, 1.0);\n\
}";
- (void)drawRect:(NSRect)dirtyRect
{
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glUseProgram(programId);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, sizeof(data));
glFlush();
glDisableClientState(GL_VERTEX_ARRAY);
}
-(void)reshape
{
glViewport(0, 0, w, h);
gluPerspective(45.0, //The camera angle
(double)w / (double)h, //The width-to-height ratio
1.0, //The near z clipping coordinate
200.0);
}
-(void)prepareOpenGL
{
glEnable(GL_DEPTH_TEST);
glGenBuffersARB(1, &vbo);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(data), data, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, 0, 0, 0);
vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShaderId, 1, &vertexShader, NULL);
glCompileShader(vertexShaderId);
GLint completed;
glGetShaderiv(vertexShaderId, GL_COMPILE_STATUS, &completed);
if (!completed)
{
GLint length;
GLchar *log;
glGetShaderiv(vertexShaderId, GL_INFO_LOG_LENGTH, &length);
log = (GLchar *)malloc(length);
glGetShaderInfoLog(vertexShaderId, length, &length, log);
fprintf(stderr, "Vertex compile log = '%s'\n", log);
}
fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShaderId, 1, &fragmentShader, NULL);
glCompileShader(fragmentShaderId);
GLint complete;
glGetShaderiv(fragmentShaderId, GL_COMPILE_STATUS, &complete);
if (!complete)
{
GLint length;
GLchar *log;
glGetShaderiv(fragmentShaderId, GL_INFO_LOG_LENGTH, &length);
log = (GLchar *)malloc(length);
glGetShaderInfoLog(fragmentShaderId, length, &length, log);
fprintf(stderr, "fragment compile log = '%s'\n", log);
}
programId = glCreateProgram();
glAttachShader(programId, vertexShaderId);
glAttachShader(programId, fragmentShaderId);
glLinkProgram(programId);
glUseProgram(programId);
}
Run Code Online (Sandbox Code Playgroud)
这里有几个问题.从上到下:
GLfloat data[] = {0.0, 0.0, -5.0,
1.0, 0.0, -5.0,
1.0, 1.0, -5.0
};
Run Code Online (Sandbox Code Playgroud)
此数据不可见,因为Z值超出了查看量[-1,1].尝试使用0.0代替.
#version 150\n\
\n\
layout (location=0) in vec4 position;
Run Code Online (Sandbox Code Playgroud)
layout(location=0) 在两种情况下,只适用于顶点着色器输入:
#version 150.#extension声明才能在着色器中激活它.另外,我知道一个事实,即OSX的GL 3.2支持并没有提供这个扩展.所以你需要用老式的方式来做:用glBindAttribLocation.在链接程序之前使用此功能.
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, 0);
Run Code Online (Sandbox Code Playgroud)
这不仅是不必要的,它还会对您尝试完成的操作产生主动破坏性,因为它会在您尝试渲染时导致生成OpenGL错误.
如果您使用的是通用属性,则不需要旧式属性.
glDrawArrays(GL_TRIANGLES, 0, sizeof(data));
Run Code Online (Sandbox Code Playgroud)
sizeof(data)是数组的大小(以字节为单位)data.在大多数机器上,那将是36.你没有渲染36个顶点; 你渲染三个.所以这应该是:
glDrawArrays(GL_TRIANGLES, 0, 3);
Run Code Online (Sandbox Code Playgroud)
gluPerspective(45.0, //The camera angle
(double)w / (double)h, //The width-to-height ratio
1.0, //The near z clipping coordinate
200.0);
Run Code Online (Sandbox Code Playgroud)
这不是一个完全没有意义的问题.您使用着色器进行渲染,而您没有使用内置矩阵.这什么都不做.
glGenBuffersARB(1, &vbo);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(data), data, GL_STATIC_DRAW);
Run Code Online (Sandbox Code Playgroud)
这也可能不是"问题",但也可能是.以"ARB"结尾的函数和枚举器代表OpenGL扩展.因此,您正在使用ARB_vertex_buffer_object扩展所公开的函数.
自GL 1.4以来,此扩展一直是核心.实际上,您甚至没有始终如一地使用扩展(这可能是出现问题的地方).您使用ARB扩展为您设置缓冲区的数据,但在渲染时使用核心功能.
只是抛弃ARB扩展的东西并使用核心功能.
log = (GLchar *)malloc(length);
glGetShaderInfoLog(vertexShaderId, length, &length, log);
fprintf(stderr, "Vertex compile log = '%s'\n", log);
Run Code Online (Sandbox Code Playgroud)
这不会导致错误,但是......你的呼叫在free哪里?
glLinkProgram(programId);
glUseProgram(programId);
Run Code Online (Sandbox Code Playgroud)
编译着色器或链接程序后,应始终 检查错误.
您的代码似乎是从各种来源复制粘贴在一起,形成某种科学怪人的程序.您的大部分问题源于不同的代码,这些代码与您计划使用它们的方式有所不同.你真的应该调查这些东西是如何运作的; 这样,你就不会遇到这些问题.
| 归档时间: |
|
| 查看次数: |
1753 次 |
| 最近记录: |