【发布时间】:2018-05-24 14:34:05
【问题描述】:
我之前问过一个关于尝试在 PyGObject 中使用 GLArea 小部件的问题 (Use of the Gtk.GLArea in Pygobject GTK3)。我从来没有得到 python 版本来绘制命令,所以我想我会尝试让 c 版本更好地理解它。由于包含了 Gtk3,因此使用 Ubuntu 16,我试了一下。以下代码编译并运行,没有错误或警告,但未绘制包含的 GL_LINES 指令。真正奇怪的是改变 glClearColor 确实改变了背景,而 GL_LINES 在同一个函数中。如您所见,我正在使用 Ubuntu 包含的环氧树脂/gl 库,我相信它等同于 GL/gl。有什么想法吗?
/*to compile ->
gcc `pkg-config --cflags gtk+-3.0` -o gl_area gl_area.c `pkg-config --libs gtk+-3.0 epoxy`*/
#include <math.h>
#include <gtk/gtk.h>
#include <epoxy/gl.h>
#include <stdio.h>
gint init(GtkWidget *widget)
{
/* Setup the viewport*/
glViewport(0, 0, gtk_widget_get_allocated_width (widget),
gtk_widget_get_allocated_height(widget));
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,100, 100,0, -1,1);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
printf("ran init method\n");
return TRUE;
}
/* When widget is exposed it's contents are redrawn. */
static gboolean
render (GtkGLArea *area, GdkGLContext *context)
{
/* OpenGL functions can be called only if make_current returns true */
/* Draw simple triangle */
glClearColor(.3,.3,.3,1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor4f(1,1,1,1);
glBegin(GL_LINES);
{
glVertex2f(0,0);
glVertex2f(10000,10000);
glVertex2f(0,0);
glVertex2f(-10000,-10000);
glVertex2f(0,0);
glVertex2f(10000,-10000);
glVertex2f(0,0);
glVertex2f(-10000,10000);
}
glEnd();
printf("ran render method\n");
return TRUE;
}
/* When glarea widget size changes, viewport size is set to match the new size */
gint reshape(GtkWidget *widget, GdkEventConfigure *event)
{
/* OpenGL functions can be called if context is current */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
printf("ran rehsape method\n");
glViewport(0, 0, gtk_widget_get_allocated_width (widget),
gtk_widget_get_allocated_height(widget));
return TRUE;
}
int main(int argc, char **argv)
{
/* initialize gtk */
gtk_init(&argc, &argv);
/* Create new top level window. */
GtkWidget *window = gtk_window_new( GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "GL Area Test");
gtk_window_set_default_size (GTK_WINDOW(window),
640,
480);
gtk_container_set_border_width(GTK_CONTAINER(window), 10);
/* Quit main if got delete event */
g_signal_connect(G_OBJECT(window),
"delete-event",
G_CALLBACK(gtk_main_quit),
NULL);
/* Create new OpenGL widget. */
GtkWidget *glarea = gtk_gl_area_new ();
/* Do initialization when widget has been realized. */
g_signal_connect(glarea, "realize", G_CALLBACK(init), NULL);
/* When window is resized viewport needs to be resized also. */
g_signal_connect(glarea, "configure-event", G_CALLBACK(reshape), NULL);
/* Render signal should be sent once the context is set to current. */
g_signal_connect (glarea, "render", G_CALLBACK (render), NULL);
/* set minimum size */
gtk_widget_set_size_request(glarea, 100,100);
/* put glarea into window and show it all */
gtk_container_add(GTK_CONTAINER(window), glarea);
gtk_widget_show_all (window);
gtk_main();
return 0;
}
【问题讨论】:
-
恕我直言,可能不是错误,而是:在
glOrtho(0,100, 100,0, -1,1);之后,您再次调用glMatrixMode(GL_PROJECTION);和glLoadIdentity();。这会覆盖之前对glOrtho()的调用。 (如果我没记错的话,这就像glOrtho(-1, 1, -1, 1, -1, 1);。)但是,我假设您打算改为写glMatrixMode(GL_MODELVIEW);(第二次调用glMatrixMode())。 -
完全不相关,但您应该连接到
destroy,而不是delete-event来调用gtk_main_quit。 -
请运行
gtk-demo,看看那里的gl示例,也许你会发现你做错了什么?示例也在这里:git.gnome.org/browse/gtk+/tree/demos/gtk-demo/glarea.c