📄 logo.c
字号:
/* * logo.c: * GtkGLExt logo demo. * * written by Naofumi Yasufuku <naofumi@users.sourceforge.net> */#include <stdlib.h>#include <string.h>#include <math.h>#include <gtk/gtk.h>#include <gdk/gdkkeysyms.h>#include <gtk/gtkgl.h>#ifdef G_OS_WIN32#define WIN32_LEAN_AND_MEAN 1#include <windows.h>#endif#include <GL/gl.h>#include <GL/glu.h>#include "logo-model.h"#include "trackball.h"#define DIG_2_RAD (G_PI / 180.0)#define RAD_2_DIG (180.0 / G_PI)#define TIMEOUT_INTERVAL 10#define DEFAULT_ROT_COUNT 100#define VIEW_INIT_AXIS_X 1.0#define VIEW_INIT_AXIS_Y 0.0#define VIEW_INIT_AXIS_Z 0.0#define VIEW_INIT_ANGLE 20.0#define VIEW_SCALE_MAX 2.0#define VIEW_SCALE_MIN 0.5#define LOGO_CUBE 1#define LOGO_G_FORWARD 2#define LOGO_G_BACKWARD 3#define LOGO_T_FORWARD 4#define LOGO_T_BACKWARD 5#define LOGO_K_FORWARD 6#define LOGO_K_BACKWARD 7static float view_quat[4] = { 0.0, 0.0, 0.0, 1.0 };static float view_scale = 1.0;static float logo_quat[4] = { 0.0, 0.0, 0.0, 1.0 };static gboolean animate = TRUE;static void toggle_animation (GtkWidget *widget);static void init_logo_view (GtkWidget *widget);static voidinit_view (void){ float sine = sin (0.5 * VIEW_INIT_ANGLE * DIG_2_RAD); view_quat[0] = VIEW_INIT_AXIS_X * sine; view_quat[1] = VIEW_INIT_AXIS_Y * sine; view_quat[2] = VIEW_INIT_AXIS_Z * sine; view_quat[3] = cos (0.5 * VIEW_INIT_ANGLE * DIG_2_RAD); view_scale = 1.0;}static voidinit_logo_quat (void){ logo_quat[0] = 0.0; logo_quat[1] = 0.0; logo_quat[2] = 0.0; logo_quat[3] = 1.0;}static voidrealize (GtkWidget *widget, gpointer data){ GdkGLContext *glcontext = gtk_widget_get_gl_context (widget); GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget); static GLfloat light0_position[] = { 0.0, 0.0, 30.0, 0.0 }; static GLfloat light0_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; static GLfloat light0_specular[] = { 1.0, 1.0, 1.0, 1.0 }; static GLfloat mat_specular[] = { 0.5, 0.5, 0.5, 1.0 }; static GLfloat mat_shininess[] = { 10.0 }; static GLfloat mat_black[] = { 0.0, 0.0, 0.0, 1.0 }; static GLfloat mat_red[] = { 1.0, 0.0, 0.0, 1.0 }; static GLfloat mat_green[] = { 0.0, 1.0, 0.0, 1.0 }; static GLfloat mat_blue[] = { 0.0, 0.0, 1.0, 1.0 }; /*** OpenGL BEGIN ***/ if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) return; glClearColor (0.5, 0.5, 0.8, 1.0); glClearDepth (1.0); glLightfv (GL_LIGHT0, GL_POSITION, light0_position); glLightfv (GL_LIGHT0, GL_DIFFUSE, light0_diffuse); glLightfv (GL_LIGHT0, GL_SPECULAR, light0_specular); glEnable (GL_LIGHTING); glEnable (GL_LIGHT0); glEnable (GL_DEPTH_TEST); glEnable (GL_CULL_FACE); glShadeModel (GL_SMOOTH); glMaterialfv (GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv (GL_FRONT, GL_SHININESS, mat_shininess); /* Center black cube. */ glNewList (LOGO_CUBE, GL_COMPILE); glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_black); logo_draw_cube (); glEndList (); /* Forward "G". */ glNewList (LOGO_G_FORWARD, GL_COMPILE); glDisable (GL_CULL_FACE); glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_blue); logo_draw_g_plane (); glEnable (GL_CULL_FACE); glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_black); logo_draw_g (); glEndList (); /* Backward "G". */ glNewList (LOGO_G_BACKWARD, GL_COMPILE); glPushMatrix (); glRotatef (180.0, 1.0, 0.0, 0.0); glDisable (GL_CULL_FACE); glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_blue); logo_draw_g_plane (); glEnable (GL_CULL_FACE); glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_black); logo_draw_g (); glPopMatrix (); glEndList (); /* Forward "T". */ glNewList (LOGO_T_FORWARD, GL_COMPILE); glDisable (GL_CULL_FACE); glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_red); logo_draw_t_plane (); glEnable (GL_CULL_FACE); glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_black); logo_draw_t (); glEndList (); /* Backward "T". */ glNewList (LOGO_T_BACKWARD, GL_COMPILE); glPushMatrix (); glRotatef (180.0, 1.0, 0.0, 0.0); glDisable (GL_CULL_FACE); glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_red); logo_draw_t_plane (); glEnable (GL_CULL_FACE); glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_black); logo_draw_t (); glPopMatrix (); glEndList (); /* Forward "K". */ glNewList (LOGO_K_FORWARD, GL_COMPILE); glDisable (GL_CULL_FACE); glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_green); logo_draw_k_plane (); glEnable (GL_CULL_FACE); glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_black); logo_draw_k (); glEndList (); /* Backward "K". */ glNewList (LOGO_K_BACKWARD, GL_COMPILE); glPushMatrix (); glRotatef (180.0, 0.0, 0.0, 1.0); glDisable (GL_CULL_FACE); glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_green); logo_draw_k_plane (); glEnable (GL_CULL_FACE); glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_black); logo_draw_k (); glPopMatrix (); glEndList (); glEnable (GL_NORMALIZE); /* Init logo orientation. */ init_logo_quat (); /* Init view. */ init_view (); gdk_gl_drawable_gl_end (gldrawable); /*** OpenGL END ***/}static gbooleanconfigure_event (GtkWidget *widget, GdkEventConfigure *event, gpointer data){ GdkGLContext *glcontext = gtk_widget_get_gl_context (widget); GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget); GLfloat w = widget->allocation.width; GLfloat h = widget->allocation.height; GLfloat aspect; /*** OpenGL BEGIN ***/ if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) return FALSE; glViewport (0, 0, w, h); glMatrixMode (GL_PROJECTION); glLoadIdentity (); if (w > h) { aspect = w / h; glFrustum (-aspect, aspect, -1.0, 1.0, 2.0, 60.0); } else { aspect = h / w; glFrustum (-1.0, 1.0, -aspect, aspect, 2.0, 60.0); } glMatrixMode (GL_MODELVIEW); gdk_gl_drawable_gl_end (gldrawable); /*** OpenGL END ***/ return TRUE;}static float axis_x[3] = { 1.0, 0.0, 0.0 };static float axis_y[3] = { 0.0, 1.0, 0.0 };static float axis_z[3] = { 0.0, 0.0, 1.0 };/* Logo rotation mode. */typedef struct _RotMode{ float *axis; float sign;} RotMode;static RotMode rot_mode[] = { { axis_x, 1.0 }, { axis_y, 1.0 }, { axis_x, 1.0 }, { axis_z, 1.0 }, { axis_x, 1.0 }, { axis_y, -1.0 }, { axis_x, 1.0 }, { axis_z, -1.0 }, { NULL, 0.0 } /* terminator */};static int rot_count = DEFAULT_ROT_COUNT;static int mode = 0;static int counter = 0;static gbooleanexpose_event (GtkWidget *widget, GdkEventExpose *event, gpointer data){ GdkGLContext *glcontext = gtk_widget_get_gl_context (widget); GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget); float d_quat[4]; float m[4][4]; if (animate) { if (counter == rot_count) { if (rot_mode[++mode].axis == NULL) mode = 0; counter = 0; } axis_to_quat (rot_mode[mode].axis, rot_mode[mode].sign * G_PI_2 / rot_count, d_quat); add_quats (d_quat, logo_quat, logo_quat); counter++; } /*** OpenGL BEGIN ***/ if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) return FALSE; glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity (); /* View transformation. */ glTranslatef (0.0, 0.0, -30.0); glScalef (view_scale, view_scale, view_scale); build_rotmatrix (m, view_quat); glMultMatrixf (&m[0][0]); /* Logo model. */ glPushMatrix (); build_rotmatrix (m, logo_quat); glMultMatrixf (&m[0][0]); glRotatef (90.0, 1.0, 0.0, 0.0); glCallList (LOGO_CUBE); glCallList (LOGO_G_FORWARD); glCallList (LOGO_G_BACKWARD); glCallList (LOGO_T_FORWARD); glCallList (LOGO_T_BACKWARD); glCallList (LOGO_K_FORWARD); glCallList (LOGO_K_BACKWARD); glPopMatrix (); /* Swap buffers. */ if (gdk_gl_drawable_is_double_buffered (gldrawable)) gdk_gl_drawable_swap_buffers (gldrawable); else glFlush (); gdk_gl_drawable_gl_end (gldrawable); /*** OpenGL END ***/ return TRUE;}static float begin_x = 0.0;static float begin_y = 0.0;static gbooleanbutton_press_event (GtkWidget *widget, GdkEventButton *event, GtkWidget *menu){ begin_x = event->x; begin_y = event->y; return FALSE;}static gbooleanmotion_notify_event (GtkWidget *widget, GdkEventMotion *event, gpointer data){ float w = widget->allocation.width; float h = widget->allocation.height; float x = event->x; float y = event->y; float d_quat[4]; gboolean redraw = FALSE; /* Rotation. */ if (event->state & GDK_BUTTON1_MASK) { trackball (d_quat, (2.0 * begin_x - w) / w, (h - 2.0 * begin_y) / h, (2.0 * x - w) / w, (h - 2.0 * y) / h); add_quats (d_quat, view_quat, view_quat); redraw = TRUE; } /* Scaling. */ if (event->state & GDK_BUTTON2_MASK) { view_scale = view_scale * (1.0 + (y - begin_y) / h); if (view_scale > VIEW_SCALE_MAX) view_scale = VIEW_SCALE_MAX; else if (view_scale < VIEW_SCALE_MIN) view_scale = VIEW_SCALE_MIN; redraw = TRUE; } begin_x = x; begin_y = y; if (redraw && !animate) gdk_window_invalidate_rect (widget->window, &widget->allocation, FALSE); return TRUE;}static gbooleankey_press_event (GtkWidget *widget, GdkEventKey *event, gpointer data){ switch (event->keyval)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -