![](/img/trans.png)
[英]Not able to draw something on screen with OpenGL 2.1 and GLSL 1.2
[英]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
正确设置了顶点缓冲区。 据我所知,它的设置正确。
我能想到的仅有的两种可能性是
关于第二种可能性,我在Mac OSX上使用XCode,这些是我要链接的库。
谁能帮助我找出问题所在?
没有编译时错误,也没有运行时错误,但仅呈现空白屏幕。 但是,当我改变...
在核心模式下,您必须具有一个命名的“ 顶点数组对象” ,因为默认的顶点数组对象“ 0”无效。
所以您是说我需要添加类似
glGenVertexArrays(1, &vao);
类的东西glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
? 我只是尝试过,然后得到“ EXC_BAD_ACCESS(代码= 1,地址= 0x0)”
从OpenGL 3.0版本开始提供glGenVertexArrays
。 如果支持顶点数组对象,则可以通过glewGetExtension("GL_ARB_vertex_array_object")
进行检查。
Glew可以通过以下方式启用其他扩展:
glewExperimental = GL_TRUE;
glewInit();
请参阅GLEW文档 :
GLEW从图形驱动程序获取有关支持的扩展的信息。 但是,实验或预发行版驱动程序可能不会通过标准机制报告所有可用扩展,在这种情况下,GLEW将报告不支持的扩展。 为了避免这种情况,可以在调用
glewInit()
之前将glewExperimental
全局开关设置为GL_TRUE
,以将其打开,以确保所有带有有效入口点的扩展都被公开。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.