Gtk 3 - 我在哪里以及如何指定主循环的内容?
Gtk 3 - where and how do I specify the contents of the main loop?
我正在尝试使用 GTK 3 编写一个简单的 'game loop'。我创建了一个 GL 上下文并试图清除它。然而,显示的 window 只有一些黑白矩形,可能是 'placeholder' 显示。显然颜色清除属于主循环内部,或者它只会执行一次,但我一直无法弄清楚如何注册我自己的主循环。我应该覆盖 gtk_main 还是完全替换它?
#include <gtk/gtk.h>
#include <GL/gl.h>
int main(int argc, char *argv[]) {
GtkWidget *win, *area;
gtk_init(&argc, &argv);
win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(win), "Hello, GNU");
gtk_window_set_position(GTK_WINDOW(win), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(win), 480, 480);
g_signal_connect(win, "destroy", G_CALLBACK(gtk_main_quit), NULL);
area = gtk_gl_area_new();
gtk_container_add(GTK_CONTAINER(win), area);
gtk_widget_show_all(win);
gtk_gl_area_make_current(GTK_GL_AREA(area));
glClearColor(1,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);
gtk_main();
return 0;
}
g_signal_connect
似乎相关,但信号似乎是特定事件,如激活、关闭等。
不确定 OpenGL 代码,但这里有一个您可以适应 OpenGL 的示例,展示了回调如何更新 GdkPixbuf。
//g++ test.cpp `pkg-config --cflags gtk+-3.0` `pkg-config --libs gtk+-3.0`
#include <gtk/gtk.h>
int width = 320, height = 240;
GdkPixbuf *pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height);
int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
guchar *pixels = gdk_pixbuf_get_pixels (pixbuf);
GtkImage *image;
inline void drawPixel (int x, int y, char red, char green, char blue)
{
*(pixels + y * rowstride + x * 3) = red;
*(pixels + y * rowstride + x * 3 + 1) = green;
*(pixels + y * rowstride + x * 3 + 2) = blue;
}
gboolean game_loop (GtkWidget *widget, GdkFrameClock *clock, gpointer data)
{
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
drawPixel(i, j, rand() % 255, rand() % 255, rand() % 255);
}
}
gtk_image_set_from_pixbuf (image, pixbuf);
return 1;
}
int main()
{
gtk_init (NULL, NULL);
GtkWidget *window, *box;
image = GTK_IMAGE (gtk_image_new());
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET(image), TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (window), box);
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
gtk_widget_add_tick_callback(window, game_loop, NULL, NULL);
gtk_widget_show_all (window);
gtk_main();
}
结果:
我正在尝试使用 GTK 3 编写一个简单的 'game loop'。我创建了一个 GL 上下文并试图清除它。然而,显示的 window 只有一些黑白矩形,可能是 'placeholder' 显示。显然颜色清除属于主循环内部,或者它只会执行一次,但我一直无法弄清楚如何注册我自己的主循环。我应该覆盖 gtk_main 还是完全替换它?
#include <gtk/gtk.h>
#include <GL/gl.h>
int main(int argc, char *argv[]) {
GtkWidget *win, *area;
gtk_init(&argc, &argv);
win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(win), "Hello, GNU");
gtk_window_set_position(GTK_WINDOW(win), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(win), 480, 480);
g_signal_connect(win, "destroy", G_CALLBACK(gtk_main_quit), NULL);
area = gtk_gl_area_new();
gtk_container_add(GTK_CONTAINER(win), area);
gtk_widget_show_all(win);
gtk_gl_area_make_current(GTK_GL_AREA(area));
glClearColor(1,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);
gtk_main();
return 0;
}
g_signal_connect
似乎相关,但信号似乎是特定事件,如激活、关闭等。
不确定 OpenGL 代码,但这里有一个您可以适应 OpenGL 的示例,展示了回调如何更新 GdkPixbuf。
//g++ test.cpp `pkg-config --cflags gtk+-3.0` `pkg-config --libs gtk+-3.0`
#include <gtk/gtk.h>
int width = 320, height = 240;
GdkPixbuf *pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height);
int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
guchar *pixels = gdk_pixbuf_get_pixels (pixbuf);
GtkImage *image;
inline void drawPixel (int x, int y, char red, char green, char blue)
{
*(pixels + y * rowstride + x * 3) = red;
*(pixels + y * rowstride + x * 3 + 1) = green;
*(pixels + y * rowstride + x * 3 + 2) = blue;
}
gboolean game_loop (GtkWidget *widget, GdkFrameClock *clock, gpointer data)
{
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
drawPixel(i, j, rand() % 255, rand() % 255, rand() % 255);
}
}
gtk_image_set_from_pixbuf (image, pixbuf);
return 1;
}
int main()
{
gtk_init (NULL, NULL);
GtkWidget *window, *box;
image = GTK_IMAGE (gtk_image_new());
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET(image), TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (window), box);
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
gtk_widget_add_tick_callback(window, game_loop, NULL, NULL);
gtk_widget_show_all (window);
gtk_main();
}
结果: