glDrawArrays不工作。 在GTK3中使用GtkGLArea

我正在尝试使用GtkGLArea小部件。 似乎没有类似问题的答案与这种情况有关。

glClear()可以设置背景颜色很好但实际上绘制三角形数组不是。

根据本教程,下面的代码应该可行。

编辑: 21/5/2015:添加着色器,仍然得到相同的结果。 下面的新代码

这是main.cSConstruct因此您可以使用scons构建:

已解决:标题SOLUTION:main.c下的工作代码可以使用相同的SConstruct文件构建示例

main.c中

 #include  #include  #include  #include  #include  #include  #include  #include  #include  #define IGNORE_VAR(type, identifier) \ { \ type IGNORED_VARIABLE_abcd = identifier; \ identifier = IGNORED_VARIABLE_abcd; \ } const GLchar *vert_src ="\n" \ "#version 330 \n" \ " \n" \ "layout(location = 0) in vec2 in_position; \n" \ " \n" \ "void main() \n" \ "{ \n" \ " gl_Position = in_position; \n" \ "} \n"; const GLchar *frag_src ="\n" \ "void main (void) \n" \ "{ \n" \ " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); \n" \ "} \n"; GLuint gl_buffer, gl_program; static gboolean realise(GtkGLArea *area, GdkGLContext *context) { IGNORE_VAR(GdkGLContext*, context); gtk_gl_area_make_current(GTK_GL_AREA(area)); if (gtk_gl_area_get_error (GTK_GL_AREA(area)) != NULL) { printf("Failed to initialiize buffers\n"); return FALSE; } GLfloat verts[] = { +0.0f, +1.0f, -1.0f, -1.0f, +1.0f, -1.0f, }; GLuint frag_shader, vert_shader; frag_shader = glCreateShader(GL_FRAGMENT_SHADER); vert_shader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(frag_shader, 1, &frag_src, NULL); glShaderSource(vert_shader, 1, &vert_src, NULL); glCompileShader(frag_shader); glCompileShader(vert_shader); gl_program = glCreateProgram(); glAttachShader(gl_program, frag_shader); glAttachShader(gl_program, vert_shader); glLinkProgram(gl_program); glGenBuffers(1, &gl_buffer); glBindBuffer(GL_ARRAY_BUFFER, gl_buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW); return TRUE; } static gboolean render(GtkGLArea *area, GdkGLContext *context) { IGNORE_VAR(GdkGLContext*, context); IGNORE_VAR(GtkGLArea*, area); glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindBuffer(GL_ARRAY_BUFFER, gl_buffer); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); //glUseProgram(gl_program); glDrawArrays(GL_TRIANGLES, 0, 3); glDisableVertexAttribArray(0); return TRUE; } int main(int argc, char** argv) { gtk_init(&argc, &argv); GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL), *gl_area = gtk_gl_area_new(); g_signal_connect(window, "delete-event", G_CALLBACK(gtk_main_quit), NULL); g_signal_connect(gl_area, "realize", G_CALLBACK(realise), NULL); g_signal_connect(gl_area, "render", G_CALLBACK(render), NULL); gtk_container_add(GTK_CONTAINER(window), gl_area); gtk_widget_show_all(window); gtk_main(); return 0; } 

Sconstruct

 import os env = Environment(CC='gcc', CCFLAGS='--std=c11', ENV={'PATH':os.environ['PATH']}) env.Append(LIBS = ['GL', 'epoxy']) env.ParseConfig('pkg-config --cflags --libs gtk+-3.0') #env.ParseConfig('pkg-config --cflags gdkglext-1.0') env.Program(target='gl', source=['main.c']) # vim: set filetype=python: 

解决方案:main.c

 #include  #include  #include  #include  #include  #include  #include  #include  #define IGNORE_VAR(type, identifier) \ { \ type IGNORED_VARIABLE_abcd = identifier; \ identifier = IGNORED_VARIABLE_abcd; \ } const GLchar *vert_src ="\n" \ "#version 330 \n" \ "#extension GL_ARB_explicit_attrib_location: enable \n" \ " \n" \ "layout(location = 0) in vec2 in_position; \n" \ " \n" \ "void main() \n" \ "{ \n" \ " gl_Position = vec4(in_position, 0.0, 1.0); \n" \ "} \n"; const GLchar *frag_src ="\n" \ "void main (void) \n" \ "{ \n" \ " gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); \n" \ "} \n"; GLuint gl_vao, gl_buffer, gl_program; static gboolean realise(GtkGLArea *area, GdkGLContext *context) { IGNORE_VAR(GdkGLContext*, context); gtk_gl_area_make_current(GTK_GL_AREA(area)); if (gtk_gl_area_get_error (GTK_GL_AREA(area)) != NULL) { printf("Failed to initialiize buffers\n"); return FALSE; } GLfloat verts[] = { +0.0f, +1.0f, -1.0f, -1.0f, +1.0f, -1.0f, }; GLuint frag_shader, vert_shader; frag_shader = glCreateShader(GL_FRAGMENT_SHADER); vert_shader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(frag_shader, 1, &frag_src, NULL); glShaderSource(vert_shader, 1, &vert_src, NULL); glCompileShader(frag_shader); glCompileShader(vert_shader); gl_program = glCreateProgram(); glAttachShader(gl_program, frag_shader); glAttachShader(gl_program, vert_shader); glLinkProgram(gl_program); glGenVertexArrays(1, &gl_vao); glBindVertexArray(gl_vao); glGenBuffers(1, &gl_buffer); glBindBuffer(GL_ARRAY_BUFFER, gl_buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); glBindVertexArray(0); glDeleteBuffers(1, &gl_buffer); return TRUE; } static gboolean render(GtkGLArea *area, GdkGLContext *context) { IGNORE_VAR(GdkGLContext*, context); IGNORE_VAR(GtkGLArea*, area); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClearColor(0.0, 0.0, 0.0, 1.0); glUseProgram(gl_program); glBindVertexArray(gl_vao); glDrawArrays(GL_TRIANGLES, 0, 3); glBindVertexArray (0); glUseProgram (0); glFlush(); return TRUE; } int main(int argc, char** argv) { gtk_init(&argc, &argv); GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL), *gl_area = gtk_gl_area_new(); g_signal_connect(window, "delete-event", G_CALLBACK(gtk_main_quit), NULL); g_signal_connect(gl_area, "realize", G_CALLBACK(realise), NULL); g_signal_connect(gl_area, "render", G_CALLBACK(render), NULL); gtk_container_add(GTK_CONTAINER(window), gl_area); gtk_widget_show_all(window); gtk_main(); return 0; } 

您正在使用通用顶点属性。 因此你应该使用着色器。 如果您在兼容性配置文件中,则使用顶点属性0可能会被解释为内置属性“顶点位置”,但这不是给定的。 因此,如果您想“按书”操作,则必须提供着色器(或使用已弃用的内置属性)。

另请注意:不建议启用顶点属性数组并在初始化代码中设置指针。 这两者之间的OpenGL上下文可能发生任何事情,包括绑定其他顶点数组,禁用/启用(其他)顶点属性数组,设置不同的缓冲区指针等。

根据经验,任何与绘图状态直接相关的东西(即不构成一次数据初始化/加载)都属于绘图代码的相应位置。 在你的情况下

 static gboolean render(GtkGLArea *area, GdkGLContext *context) { glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //glFrontFace(GL_CW); /* added these ---> */ glBindBuffer(GL_ARRAY_BUFFER, gl_buffer); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0); /* <--- */ glDrawArrays(GL_TRIANGLES, 0, 3); //gtk_widget_get_realized(area); return TRUE; } 

从长远来看,创建不会让您感到困惑。

您似乎没有任何着色器。 你需要一个片段和顶点着色器。

这是一个关于如何编写和使用它们的教程: https : //www.opengl.org/sdk/docs/tutorials/ClockworkCoders/loading.php

您错过了VAO的创建; GTK +将创建GL核心配置文件上下文,这意味着您需要自己创建和选择VAO,否则将不使用顶点缓冲区对象。

初始化GL状态时,添加以下内容:

  /* we need to create a VAO to store the other buffers */ GLuint vao; glGenVertexArrays (1, &vao); glBindVertexArray (vao); 

在创建VBO之前。

您应该查看我的博客文章,了解如何在GTK +中使用OpenGL及其相关的示例代码 。