目前我正在尝试使用 GtkGLArea
小部件。类似问题的答案似乎都与这种情况无关。
glClear()
可以很好地设置背景颜色,但实际上绘制三角形数组却不行。
根据 this教程,下面的代码应该可以工作。
编辑: 21/5/2015:添加了着色器,仍然得到相同的结果。新代码如下
这是 main.c
和 SConstruct
,因此您可以使用 scons 进行构建:
已解决:标题下的工作代码解决方案:main.c相同的 SConstruct 文件可用于构建示例
主.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <glib.h>
#include <gdk/gdkx.h>
#include <epoxy/glx.h>
#include <epoxy/gl.h>
#include <gtk/gtk.h>
#include <gtk/gtkglarea.h>
#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;
}
构建
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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <glib.h>
#include <gdk/gdkx.h>
#include <epoxy/glx.h>
#include <epoxy/gl.h>
#include <gtk/gtk.h>
#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;
}
最佳答案
您似乎没有任何着色器。你需要一个 fragment和 vertex着色器。
这里有一个关于如何编写和使用它们的教程:https://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/loading.php
关于c - glDrawArrays 不工作。在 GTK3 中使用 GtkGLArea,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30337845/