Using EGL with GTK+

http://www.tuicool.com/articles/2iQ3Ify


Using EGL with GTK+

I recently needed to port some code from GTK+ OpenGL code from GLX to EGL and I couldn't find any examples of how to do this. So to seed the Internet here is what I found out.

This is the simplest example I could make to show how to do this. In real life you probably want to do a lot more error checking. This will only work with X11; for other systems you will need to use equivalent methods in gdk/gdkwayland.h etc. For anything modern you should probably use OpenGL ES instead of OpenGL - to do this you'll need to change the attributes to eglChooseConfig and use EGL_OPENGL_ES_API in eglBindAPI.

Compile with:

gcc -g -Wall egl.c -o egl pkg-config --cflags --libs `gtk+-3.0 gdk-x11-3.0` -lEGL -lGL


#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <EGL/egl.h>
#include <GL/gl.h>

static EGLDisplay *egl_display;
static EGLSurface *egl_surface;
static EGLContext *egl_context;

static void realize_cb (GtkWidget *widget)
{
  EGLConfig egl_config;
  EGLint n_config;
  EGLint attributes[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
              EGL_NONE };

  egl_display = eglGetDisplay ((EGLNativeDisplayType) gdk_x11_display_get_xdisplay (gtk_widget_get_display (widget)));
  eglInitialize (egl_display, NULL, NULL);
  eglChooseConfig (egl_display, attributes, &egl_config, 1, &n_config);
  eglBindAPI (EGL_OPENGL_API);
  egl_surface = eglCreateWindowSurface (egl_display, egl_config, gdk_x11_window_get_xid (gtk_widget_get_window (widget)), NULL);
  egl_context = eglCreateContext (egl_display, egl_config, EGL_NO_CONTEXT, NULL);
}

static gboolean draw_cb (GtkWidget *widget)
{
  eglMakeCurrent (egl_display, egl_surface, egl_surface, egl_context);

  glViewport (0, 0, gtk_widget_get_allocated_width (widget), gtk_widget_get_allocated_height (widget));

  glClearColor (0, 0, 0, 1);
  glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glMatrixMode (GL_PROJECTION);
  glLoadIdentity ();
  glOrtho (0, 100, 0, 100, 0, 1);

  glBegin (GL_TRIANGLES);
  glColor3f (1, 0, 0);
  glVertex2f (50, 10);
  glColor3f (0, 1, 0);
  glVertex2f (90, 90);
  glColor3f (0, 0, 1);
  glVertex2f (10, 90);
  glEnd ();

  eglSwapBuffers (egl_display, egl_surface);

  return TRUE;
}

int main (int argc, char **argv)
{
  GtkWidget *w;

  gtk_init (&argc, &argv);

  w = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_widget_set_double_buffered (GTK_WIDGET (w), FALSE);
  g_signal_connect (G_OBJECT (w), "realize", G_CALLBACK (realize_cb), NULL);
  g_signal_connect (G_OBJECT (w), "draw", G_CALLBACK (draw_cb), NULL);

  gtk_widget_show (w);

  gtk_main ();

  return 0;
}

gulong  g_signal_connect( gpointer *object,
const gchar *name,
GCallback func,
gpointer func_data );

第一个参数是要发出信号的构件,第二个参数是你想要连接的信号的名称,第三个参数是信号被捕获时所要调用的函数,第四个参数是你想传递给这个函数的数据。

第三个参数指定的函数叫做回调函数,一般为下面的形式:

void callback_func( GtkWidget *widget,
gpointer callback_data );

第一个参数是一个指向发出信号的构件的指针,第二个参数是一个指向数据的指针,就是上面 g_signal_connect() 函数的最后一个参数传进来的数据。

注意上面回调函数的声明只是一般的形式,有些构件的特殊信号会用不同的调用参数。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值