从带有 GLSL 1.2 的 OpenGL 2.1 切换到带有 GLSL 1.5 版的 OpenGL 3.3 会破坏我的代码
Switching from OpenGL 2.1 with GLSL 1.2 to OpenGL 3.3 with GLSL version 1.5 breaks my code
我正在尝试将我的 OpenGL 版本从 OpenGL 2.1 切换到 OpenGL 3.3。最小可重现的 OpenGL 3.3 代码如下:
#include <stdio.h>
#include <SDL2/SDL.h>
#include <GL/glew.h>
static const GLuint WIDTH = 512;
static const GLuint HEIGHT = 512;
static const GLchar* vertex_shader_source =
"#version 330\n"
"in vec2 coord2d;\n"
"void main() {\n"
" gl_Position = vec4(coord2d, 0.0, 1.0);\n"
"}\n";
static const GLchar* fragment_shader_source =
"#version 330\n"
"out vec4 color;\n"
"void main() {\n"
" color = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n";
static GLfloat vertices[] = {
0.0, 0.8,
-0.8, -0.8,
0.8, -0.8,
};
GLuint common_get_shader_program(
const char *vertex_shader_source,
const char *fragment_shader_source
) {
GLchar *log = NULL;
GLint log_length, success;
GLuint fragment_shader, program, vertex_shader;
/* Vertex shader */
vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL);
glCompileShader(vertex_shader);
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success);
glGetShaderiv(vertex_shader, GL_INFO_LOG_LENGTH, &log_length);
log = (char*) malloc(log_length);
if (log_length > 0) {
glGetShaderInfoLog(vertex_shader, log_length, NULL, log);
printf("vertex shader log:\n\n%s\n", log);
}
if (!success) {
printf("vertex shader compile error\n");
exit(EXIT_FAILURE);
}
/* Fragment shader */
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL);
glCompileShader(fragment_shader);
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success);
glGetShaderiv(fragment_shader, GL_INFO_LOG_LENGTH, &log_length);
if (log_length > 0) {
log = (char*)realloc(log, log_length);
glGetShaderInfoLog(fragment_shader, log_length, NULL, log);
printf("fragment shader log:\n\n%s\n", log);
}
if (!success) {
printf("fragment shader compile error\n");
exit(EXIT_FAILURE);
}
/* Link shaders */
program = glCreateProgram();
glAttachShader(program, vertex_shader);
glAttachShader(program, fragment_shader);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &success);
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length);
if (log_length > 0) {
log = (char*)realloc(log, log_length);
glGetProgramInfoLog(program, log_length, NULL, log);
printf("shader link log:\n\n%s\n", log);
}
if (!success) {
printf("shader link error");
exit(EXIT_FAILURE);
}
/* Cleanup. */
free(log);
glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader);
return program;
}
int main(void) {
GLint attribute_coord2d;
GLuint program, vbo;
SDL_Event event;
SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO);
SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute (SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute (SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_Window *window;
SDL_GLContext gl_context;
window = SDL_CreateWindow(__FILE__, 0, 0,
WIDTH, HEIGHT, SDL_WINDOW_OPENGL);
gl_context = SDL_GL_CreateContext(window);
glewInit();
/* Shader setup. */
program = common_get_shader_program(vertex_shader_source, fragment_shader_source);
attribute_coord2d = glGetAttribLocation(program, "coord2d");
/* Buffer setup. */
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(attribute_coord2d, 2, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
/* Global draw state */
glUseProgram(program);
glViewport(0, 0, WIDTH, HEIGHT);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
/* Main loop. */
while (1) {
glClear(GL_COLOR_BUFFER_BIT);
glEnableVertexAttribArray(attribute_coord2d);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(attribute_coord2d);
SDL_GL_SwapWindow(window);
if (SDL_PollEvent(&event) && event.type == SDL_QUIT)
break;
}
/* Cleanup. */
glDeleteBuffers(1, &vbo);
glDeleteProgram(program);
SDL_GL_DeleteContext(gl_context);
SDL_DestroyWindow(window);
SDL_Quit();
return EXIT_SUCCESS;
}
没有编译时错误和运行时错误,但它只是呈现一个空白屏幕。但是,当我将 vertex_shader_source
更改为
"#version 120\n"
"attribute vec2 coord2d;\n"
"void main() {\n"
" gl_Position = vec4(coord2d, 0.0, 1.0);\n"
"}\n";
fragment_shader_source
至
"#version 120\n"
"void main() {\n"
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n";
并注释掉行
SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute (SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute (SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
代码有效,我得到了预期的输出。
感觉 OpenGL 3.3 版本的代码应该可以工作,特别是考虑到两个代码片段之间的差异很小。我还检查以确保使用 glGetBufferSubData
正确设置了顶点缓冲区。据我所知,它设置正确。
我能想到的只有两种可能
- 关于顶点着色器 and/or 片段着色器源代码,我有些不明白。
- 我的构建过程有问题。 IE。库丢失或未链接。
关于第二种可能性,我在 Mac OSX 上使用 XCode,这些是我链接的库。
谁能帮我找出问题所在?
There are no compile time errors and no runtime errors, but it only renders a blank screen. However, when I change...
在核心模式下你必须有一个命名的Vertex Array Object,因为默认的顶点数组对象“0”是无效的。
So do you mean I need to add something like glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
? I just tried that, and I get "EXC_BAD_ACCESS (code=1, address=0x0)"
glGenVertexArrays
自 OpenGL 3.0 版起可用。如果支持顶点数组对象,可以通过 glewGetExtension("GL_ARB_vertex_array_object")
.
检查
Glew 可以通过以下方式启用其他扩展:
glewExperimental = GL_TRUE;
glewInit();
GLEW obtains information on the supported extensions from the graphics driver. Experimental or pre-release drivers, however, might not report every available extension through the standard mechanism, in which case GLEW will report it unsupported. To circumvent this situation, the glewExperimental
global switch can be turned on by setting it to GL_TRUE
before calling glewInit()
, which ensures that all extensions with valid entry points will be exposed.
我正在尝试将我的 OpenGL 版本从 OpenGL 2.1 切换到 OpenGL 3.3。最小可重现的 OpenGL 3.3 代码如下:
#include <stdio.h>
#include <SDL2/SDL.h>
#include <GL/glew.h>
static const GLuint WIDTH = 512;
static const GLuint HEIGHT = 512;
static const GLchar* vertex_shader_source =
"#version 330\n"
"in vec2 coord2d;\n"
"void main() {\n"
" gl_Position = vec4(coord2d, 0.0, 1.0);\n"
"}\n";
static const GLchar* fragment_shader_source =
"#version 330\n"
"out vec4 color;\n"
"void main() {\n"
" color = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n";
static GLfloat vertices[] = {
0.0, 0.8,
-0.8, -0.8,
0.8, -0.8,
};
GLuint common_get_shader_program(
const char *vertex_shader_source,
const char *fragment_shader_source
) {
GLchar *log = NULL;
GLint log_length, success;
GLuint fragment_shader, program, vertex_shader;
/* Vertex shader */
vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL);
glCompileShader(vertex_shader);
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success);
glGetShaderiv(vertex_shader, GL_INFO_LOG_LENGTH, &log_length);
log = (char*) malloc(log_length);
if (log_length > 0) {
glGetShaderInfoLog(vertex_shader, log_length, NULL, log);
printf("vertex shader log:\n\n%s\n", log);
}
if (!success) {
printf("vertex shader compile error\n");
exit(EXIT_FAILURE);
}
/* Fragment shader */
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL);
glCompileShader(fragment_shader);
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success);
glGetShaderiv(fragment_shader, GL_INFO_LOG_LENGTH, &log_length);
if (log_length > 0) {
log = (char*)realloc(log, log_length);
glGetShaderInfoLog(fragment_shader, log_length, NULL, log);
printf("fragment shader log:\n\n%s\n", log);
}
if (!success) {
printf("fragment shader compile error\n");
exit(EXIT_FAILURE);
}
/* Link shaders */
program = glCreateProgram();
glAttachShader(program, vertex_shader);
glAttachShader(program, fragment_shader);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &success);
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length);
if (log_length > 0) {
log = (char*)realloc(log, log_length);
glGetProgramInfoLog(program, log_length, NULL, log);
printf("shader link log:\n\n%s\n", log);
}
if (!success) {
printf("shader link error");
exit(EXIT_FAILURE);
}
/* Cleanup. */
free(log);
glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader);
return program;
}
int main(void) {
GLint attribute_coord2d;
GLuint program, vbo;
SDL_Event event;
SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO);
SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute (SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute (SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_Window *window;
SDL_GLContext gl_context;
window = SDL_CreateWindow(__FILE__, 0, 0,
WIDTH, HEIGHT, SDL_WINDOW_OPENGL);
gl_context = SDL_GL_CreateContext(window);
glewInit();
/* Shader setup. */
program = common_get_shader_program(vertex_shader_source, fragment_shader_source);
attribute_coord2d = glGetAttribLocation(program, "coord2d");
/* Buffer setup. */
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(attribute_coord2d, 2, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
/* Global draw state */
glUseProgram(program);
glViewport(0, 0, WIDTH, HEIGHT);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
/* Main loop. */
while (1) {
glClear(GL_COLOR_BUFFER_BIT);
glEnableVertexAttribArray(attribute_coord2d);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(attribute_coord2d);
SDL_GL_SwapWindow(window);
if (SDL_PollEvent(&event) && event.type == SDL_QUIT)
break;
}
/* Cleanup. */
glDeleteBuffers(1, &vbo);
glDeleteProgram(program);
SDL_GL_DeleteContext(gl_context);
SDL_DestroyWindow(window);
SDL_Quit();
return EXIT_SUCCESS;
}
没有编译时错误和运行时错误,但它只是呈现一个空白屏幕。但是,当我将 vertex_shader_source
更改为
"#version 120\n"
"attribute vec2 coord2d;\n"
"void main() {\n"
" gl_Position = vec4(coord2d, 0.0, 1.0);\n"
"}\n";
fragment_shader_source
至
"#version 120\n"
"void main() {\n"
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n";
并注释掉行
SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute (SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute (SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
代码有效,我得到了预期的输出。
感觉 OpenGL 3.3 版本的代码应该可以工作,特别是考虑到两个代码片段之间的差异很小。我还检查以确保使用 glGetBufferSubData
正确设置了顶点缓冲区。据我所知,它设置正确。
我能想到的只有两种可能
- 关于顶点着色器 and/or 片段着色器源代码,我有些不明白。
- 我的构建过程有问题。 IE。库丢失或未链接。
关于第二种可能性,我在 Mac OSX 上使用 XCode,这些是我链接的库。
谁能帮我找出问题所在?
There are no compile time errors and no runtime errors, but it only renders a blank screen. However, when I change...
在核心模式下你必须有一个命名的Vertex Array Object,因为默认的顶点数组对象“0”是无效的。
So do you mean I need to add something like
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
? I just tried that, and I get "EXC_BAD_ACCESS (code=1, address=0x0)"
glGenVertexArrays
自 OpenGL 3.0 版起可用。如果支持顶点数组对象,可以通过 glewGetExtension("GL_ARB_vertex_array_object")
.
Glew 可以通过以下方式启用其他扩展:
glewExperimental = GL_TRUE;
glewInit();
GLEW obtains information on the supported extensions from the graphics driver. Experimental or pre-release drivers, however, might not report every available extension through the standard mechanism, in which case GLEW will report it unsupported. To circumvent this situation, the
glewExperimental
global switch can be turned on by setting it toGL_TRUE
before callingglewInit()
, which ensures that all extensions with valid entry points will be exposed.