云网牛站
所在位置:首页 > Linux编程 > C源代码:Ubuntu中GTK和GLUT的共同使用

C源代码:Ubuntu中GTK和GLUT的共同使用

2018-07-21 14:35:26作者:zenny_chen稿源:linux网

想看一下在Ubuntu系统中是不是GTK和GLUT是否可以相互协作,经过初次的测试,得出的结论算是可行的,在下面也将分享C源代码,供大家参考。

 

在以下demo中,我们可以点击由GTK创建的按钮然后弹出用GLUT创建的窗口。由于GTK和GLUT是两个完全独立的库,两者均含有各自的消息循环(也就是通常所说的runloop),因此当我们点击按钮弹出GLUT窗口的时候,其实相应的都是GLUT的消息循环,GTK此时处于冻结状态。只有当我们将GLUT窗口关闭之后,GTK窗口才会被再次激活,侦听消息。

 

跟以往一样,这里先给出本次demo所需的shell文件内容,便于编译构建。

clang main.c -std=gnu11 -fblocks -lBlocksRuntime -lglut -lGL -I/usr/include/glib-2.0/ -I/usr/include/atk-1.0/ -I/usr/include/gdk-pixbuf-2.0/ -I/usr/include/cairo/ -I/usr/include/pango-1.0/ -I/usr/lib/x86_64-linux-gnu/glib-2.0/include/ -I/usr/include/gtk-3.0/ -L/usr/lib/x86_64-linux-gnu/ -lgtk-3 -lgobject-2.0 -lpangocairo-1.0 -lgio-2.0 -latk-1.0 -lgdk-3 -lglib-2.0-o gtk-glut

 

同样,如果各位使用的是GCC编译器,那么将上述的clang变为gcc,同时删除-fblocks -lBlocksRuntime这两个命令行选项。

 

下面则是C源代码:

#include <stdio.h>

#include <stdint.h>

#include <stdbool.h>

#include <stdnoreturn.h>

#include <stdatomic.h>

#include <string.h>

#include <assert.h>

#include <gtk/gtk.h>

#include <glib/gprintf.h>

#include <GL/freeglut.h>

#include <GL/gl.h>

#ifndef var

#define var __auto_type

#endif

static const GLfloat sRectVertices[] = {

// top left

-0.4f, 0.4f,

// bottom left

-0.4f, -0.4f,

// top right

0.4f, 0.4f,

// bottom right

0.4f, -0.4f

};

static const GLfloat sTriangleVertices[] = {

// top center

0.0f, 0.4f,

// bottom left

-0.4f, -0.4f,

// bottom right

0.4f, -0.4f

};

static const GLfloat sColors[] = {

// red

1.0f, 0.0f, 0.0f, 1.0f,

// green

0.0f, 1.0f, 0.0f, 1.0f,

// blue

0.0f, 0.0f, 1.0f, 1.0f,

// white

1.0f, 1.0f, 1.0f, 1.0f

};

static int sRotAngle = 0;

static void TimerHandler(int value);

static void RenderHandler(void)

{

// 以50FPS的帧率进行刷新

glutTimerFunc(20, TimerHandler, 0);

glClear(GL_COLOR_BUFFER_BIT);

// Draw rectangle

glVertexPointer(2, GL_FLOAT, 0, sRectVertices);

glColorPointer(4, GL_FLOAT, 0, sColors);

glLoadIdentity();

glTranslatef(-0.5f, 0.0f, -2.0f);

glRotatef(sRotAngle, 0.0f, 0.0f, 1.0f);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

// Draw triangle

glVertexPointer(2, GL_FLOAT, 0, sTriangleVertices);

glColorPointer(4, GL_FLOAT, 0, sColors);

glLoadIdentity();

glTranslatef(0.5f, 0.0f, -2.1f);

glRotatef(-sRotAngle, 0.0f, 0.0f, 1.0f);

glDrawArrays(GL_TRIANGLES, 0, 3);

glFlush();

glutSwapBuffers();

if(++sRotAngle == 360)

sRotAngle = 0;

}

static void TimerHandler(int value)

{

RenderHandler();

}

static int sGLUTWindow;

static int sStoredArgC;

static char **sStoredArgv;

static void GLUTWindowCloseHandler(void)

{

glutDestroyWindow(sGLUTWindow);

glutLeaveMainLoop();

}

static void ShowOpenGLWindow(GtkWidget *widget, gpointer window) 

{

if(window != NULL)

g_printf("Button clicked\n");

// 每次打开GLUT窗口前必须先调用一次glutInit函数

glutInit(&sStoredArgC, sStoredArgv);

// 当用户点击GLUT窗口时,应用不直接退出

glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);

glutCloseFunc(GLUTWindowCloseHandler);

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_MULTISAMPLE);

glutInitWindowSize(480, 480);

glutInitWindowPosition(200, 100);

sGLUTWindow = glutCreateWindow("OpenGL GLUT Window");

glutSetOption(GLUT_MULTISAMPLE, 4);

glutDisplayFunc(RenderHandler);

var vendor = (const char*)glGetString(GL_VENDOR);

var renderer = (const char*)glGetString(GL_RENDERER);

var version = (const char*)glGetString(GL_VERSION);

g_printf("The vendor is: %s\n", vendor);

g_printf("The renderer is: %s\n", renderer);

g_printf("The GL version is: %s\n", version);

glViewport(0, 0, 480, 480);

glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

glShadeModel(GL_SMOOTH);

glFrontFace(GL_CCW);

glCullFace(GL_BACK);

glEnable(GL_CULL_FACE);

glEnable(GL_MULTISAMPLE_ARB);

glEnableClientState(GL_VERTEX_ARRAY);

glEnableClientState(GL_COLOR_ARRAY);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 3.0f);

glMatrixMode(GL_MODELVIEW);

glutMainLoop();

g_printf("GLUT runloop has quit!\n");

}

int main(int argc, char *argv[])

{

// 保存argc与argv

sStoredArgC = argc;

sStoredArgv = argv;

gtk_init(&argc, &argv);

var window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

gtk_window_set_title(GTK_WINDOW(window), "GTK-GLUT");

gtk_window_set_default_size(GTK_WINDOW(window), 480, 320);

gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);

gtk_container_set_border_width(GTK_CONTAINER(window), 15);

var button = gtk_button_new_with_label("Show GLUT");

gtk_widget_set_halign(button, GTK_ALIGN_START);

gtk_widget_set_valign(button, GTK_ALIGN_START);

gtk_widget_set_tooltip_text(button, "This is a button widget");

g_signal_connect(button, "clicked", G_CALLBACK(ShowOpenGLWindow), window); 

gtk_container_add(GTK_CONTAINER(window), button);

gtk_widget_show_all(window);

g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

static_assert(sizeof(int) == 4, "Not compatible architecture!");

puts("Will enter GTK runloop...");

gtk_main();

puts("Program terminated!");

}

 

我们编译构建完此程序之后,直接在命令行输入gtk-glut这个app即可运行。我们每次点击按钮均能弹出GLUT窗口,点击关闭GLUT窗口可再次对GTK窗口中的按钮进行点击。

 

相关主题

Ubuntu下安装GTK+3的方法

精选文章
热门文章