~ubuntu-branches/ubuntu/jaunty/gtkgl2/jaunty

« back to all changes in this revision

Viewing changes to examples/viewlw.c

  • Committer: Bazaar Package Importer
  • Author(s): Marcelo E. Magallon
  • Date: 2003-05-11 19:47:24 UTC
  • Revision ID: james.westby@ubuntu.com-20030511194724-8ps3cvawx0n99kl8
Tags: upstream-1.99.0
Import upstream version 1.99.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
 * Copyright (C) 1998 Janne L�f <jlof@mail.student.oulu.fi>
 
3
 *
 
4
 * This library is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU Library General Public
 
6
 * License as published by the Free Software Foundation; either
 
7
 * version 2 of the License, or (at your option) any later version.
 
8
 *
 
9
 * This library is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
12
 * Library General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU Library General Public
 
15
 * License along with this library; if not, write to the Free
 
16
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
17
 */
 
18
 
 
19
 
 
20
#include <math.h>
 
21
#include <gtk/gtk.h>
 
22
#include <gtkgl/gtkglarea.h>
 
23
#include <GL/gl.h>
 
24
#include <GL/glu.h>
 
25
 
 
26
 
 
27
#include "trackball.h"
 
28
#include "lw.h"
 
29
 
 
30
 
 
31
#define VIEW_ASPECT 1.3
 
32
 
 
33
char help_text[] = "Usage: viewlw [OPTION]... [FILE]...\n"
 
34
                   "View LightWave 3D objects.\n"
 
35
                   "\n"
 
36
                   "Options:\n"
 
37
                   "  --help                            display help\n"
 
38
                   "\n"
 
39
                   "In the program:\n"
 
40
                   "  Mouse button 1 + drag             spin (virtual trackball)\n"
 
41
                   "  Mouse button 2 + drag             zoom\n"
 
42
                   "  Mouse button 3                    popup menu\n"
 
43
                   "\n";
 
44
 
 
45
 
 
46
 
 
47
 
 
48
/* information needed to display lightwave mesh */
 
49
typedef struct {
 
50
  gint do_init;         /* true if initgl not yet called */
 
51
  lwObject *lwobject;   /* lightwave object mesh */
 
52
  float beginx,beginy;  /* position of mouse */
 
53
  float quat[4];        /* orientation of object */
 
54
  float zoom;           /* field of view in degrees */
 
55
 
 
56
} mesh_info;
 
57
 
 
58
 
 
59
void select_lwobject(void);
 
60
gint show_lwobject(char *lwobject_name);
 
61
 
 
62
 
 
63
 
 
64
 
 
65
void initgl(void)
 
66
{
 
67
  GLfloat light0_pos[4]   = { -50.0, 50.0, 0.0, 0.0 };
 
68
  GLfloat light0_color[4] = { .6, .6, .6, 1.0 }; /* white light */
 
69
  GLfloat light1_pos[4]   = {  50.0, 50.0, 0.0, 0.0 };
 
70
  GLfloat light1_color[4] = { .4, .4, 1, 1.0 };  /* cold blue light */
 
71
 
 
72
  /* remove back faces */
 
73
  glDisable(GL_CULL_FACE);
 
74
  glEnable(GL_DEPTH_TEST);
 
75
  
 
76
  /* speedups */
 
77
  glEnable(GL_DITHER);
 
78
  glShadeModel(GL_SMOOTH);
 
79
  glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
 
80
  glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
 
81
 
 
82
  /* light */
 
83
  glLightfv(GL_LIGHT0, GL_POSITION, light0_pos);
 
84
  glLightfv(GL_LIGHT0, GL_DIFFUSE,  light0_color);  
 
85
  glLightfv(GL_LIGHT1, GL_POSITION, light1_pos);
 
86
  glLightfv(GL_LIGHT1, GL_DIFFUSE,  light1_color);
 
87
  glEnable(GL_LIGHT0);
 
88
  glEnable(GL_LIGHT1);
 
89
  glEnable(GL_LIGHTING);
 
90
    
 
91
  glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
 
92
  glEnable(GL_COLOR_MATERIAL);  
 
93
}
 
94
 
 
95
gint glarea_expose(GtkWidget *widget, GdkEventExpose *event)
 
96
{
 
97
  GLfloat m[4][4];
 
98
 
 
99
  GtkGLArea *glarea = GTK_GL_AREA(widget);
 
100
  mesh_info *info = (mesh_info*)gtk_object_get_data(GTK_OBJECT(widget), "mesh_info");
 
101
 
 
102
  /* draw only last expose */
 
103
  if (event->count > 0) {
 
104
    return TRUE;
 
105
  }
 
106
 
 
107
  /* OpenGL calls can be done only if make_current returns true */
 
108
  if (gtk_gl_area_make_current(glarea)) {
 
109
    /* basic initialization */
 
110
    if (info->do_init == TRUE) {
 
111
      initgl();
 
112
      info->do_init = FALSE;
 
113
    }
 
114
 
 
115
    /* view */
 
116
    glMatrixMode(GL_PROJECTION);
 
117
    glLoadIdentity();
 
118
    gluPerspective(info->zoom, VIEW_ASPECT, 1,100);
 
119
    glMatrixMode(GL_MODELVIEW);
 
120
 
 
121
    /* draw object */
 
122
    glClearColor(.3,.4,.6,1);
 
123
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
 
124
 
 
125
    glLoadIdentity();
 
126
    glTranslatef(0,0,-30);
 
127
    build_rotmatrix(m,info->quat);
 
128
    glMultMatrixf(&m[0][0]);
 
129
 
 
130
    lw_object_show(info->lwobject);
 
131
 
 
132
    /* swap backbuffer to front */
 
133
    gtk_gl_area_swapbuffers(glarea);
 
134
  }
 
135
 
 
136
  return TRUE;
 
137
}
 
138
 
 
139
gint glarea_configure(GtkWidget *widget, GdkEventConfigure *event)
 
140
{
 
141
  /* OpenGL calls can be done only if make_current returns true */
 
142
  if (gtk_gl_area_make_current(GTK_GL_AREA(widget))) {
 
143
    glViewport(0,0, widget->allocation.width, widget->allocation.height);
 
144
  }
 
145
  return TRUE;
 
146
}
 
147
 
 
148
gint glarea_destroy(GtkWidget *widget)
 
149
{
 
150
  /* delete mesh info */
 
151
  mesh_info *info = (mesh_info*)gtk_object_get_data(GTK_OBJECT(widget),"mesh_info");
 
152
  if (info) {
 
153
    lw_object_free(info->lwobject);
 
154
    g_free(info);
 
155
  }
 
156
  return TRUE;
 
157
}
 
158
 
 
159
gint glarea_button_press(GtkWidget *widget, GdkEventButton *event)
 
160
{
 
161
  mesh_info *info = (mesh_info*)gtk_object_get_data(GTK_OBJECT(widget), "mesh_info");
 
162
  if (event->button == 1) {
 
163
    /* beginning of drag, reset mouse position */
 
164
    info->beginx = event->x;
 
165
    info->beginy = event->y;
 
166
    return TRUE;
 
167
  }
 
168
  return FALSE;
 
169
}
 
170
 
 
171
gint glarea_motion_notify(GtkWidget *widget, GdkEventMotion *event)
 
172
{
 
173
  int x, y;
 
174
  GdkRectangle area;
 
175
  GdkModifierType state;
 
176
  mesh_info *info = (mesh_info*)gtk_object_get_data(GTK_OBJECT(widget), "mesh_info");
 
177
 
 
178
  if (event->is_hint) {
 
179
    /* fix this! */
 
180
#if !defined(WIN32)
 
181
    gdk_window_get_pointer(event->window, &x, &y, &state);
 
182
#endif
 
183
  } else {
 
184
    x = event->x;
 
185
    y = event->y;
 
186
    state = event->state;
 
187
  }
 
188
  
 
189
  area.x = 0;
 
190
  area.y = 0;
 
191
  area.width  = widget->allocation.width;
 
192
  area.height = widget->allocation.height;
 
193
 
 
194
  if (state & GDK_BUTTON1_MASK) {
 
195
    /* drag in progress, simulate trackball */
 
196
    float spin_quat[4];
 
197
    trackball(spin_quat,
 
198
              (2.0*info->beginx -       area.width) / area.width,
 
199
              (     area.height - 2.0*info->beginy) / area.height,
 
200
              (           2.0*x -       area.width) / area.width,
 
201
              (     area.height -            2.0*y) / area.height);
 
202
    add_quats(spin_quat, info->quat, info->quat);
 
203
    /* orientation has changed, redraw mesh */
 
204
    gtk_widget_draw(widget, &area);
 
205
  }
 
206
 
 
207
  if (state & GDK_BUTTON2_MASK) {
 
208
    /* zooming drag */
 
209
    info->zoom += ((y - info->beginy) / area.height) * 40;
 
210
    if (info->zoom < 5) info->zoom = 5;
 
211
    if (info->zoom > 120) info->zoom = 120;
 
212
    /* zoom has changed, redraw mesh */
 
213
    gtk_widget_draw(widget, &area);
 
214
  }
 
215
  info->beginx = x;
 
216
  info->beginy = y;
 
217
 
 
218
  return TRUE;
 
219
}
 
220
 
 
221
 
 
222
 
 
223
 
 
224
 
 
225
gint popup_menu_handler(GtkWidget *widget, GdkEventButton *event)
 
226
{
 
227
  if (event->button == 3) {
 
228
    gtk_menu_popup(GTK_MENU(widget), NULL, NULL, NULL, NULL,
 
229
                   event->button, event->time);
 
230
    return TRUE;
 
231
  }
 
232
  return FALSE;
 
233
}
 
234
void popup_menu_detacher(GtkWidget *attach_widget,GtkMenu *menu)
 
235
{
 
236
}
 
237
void create_popup_menu(GtkWidget *widget)
 
238
{
 
239
  GtkWidget *menu          = gtk_menu_new();
 
240
  GtkWidget *open_item     = gtk_menu_item_new_with_label("Open");
 
241
  GtkWidget *quit_item     = gtk_menu_item_new_with_label("Quit");
 
242
  GtkWidget *quit_all_item = gtk_menu_item_new_with_label("Quit All");
 
243
 
 
244
  gtk_menu_append(GTK_MENU(menu), open_item);
 
245
  gtk_menu_append(GTK_MENU(menu), quit_item);
 
246
  gtk_menu_append(GTK_MENU(menu), quit_all_item);
 
247
 
 
248
  gtk_widget_show(open_item);
 
249
  gtk_widget_show(quit_item);
 
250
  gtk_widget_show(quit_all_item);
 
251
 
 
252
  gtk_menu_attach_to_widget(GTK_MENU(menu),GTK_WIDGET(widget),popup_menu_detacher);
 
253
  gtk_signal_connect_object(GTK_OBJECT(widget), "destroy",
 
254
                            GTK_SIGNAL_FUNC(gtk_menu_detach), GTK_OBJECT(menu));
 
255
 
 
256
 gtk_signal_connect_object(GTK_OBJECT(widget), "button_press_event",
 
257
                            GTK_SIGNAL_FUNC(popup_menu_handler), GTK_OBJECT(menu));
 
258
 
 
259
 
 
260
  gtk_signal_connect(GTK_OBJECT(open_item), "activate",
 
261
                     GTK_SIGNAL_FUNC(select_lwobject), NULL);
 
262
 
 
263
  gtk_signal_connect_object(GTK_OBJECT(quit_item), "activate",
 
264
                            GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(widget));
 
265
 
 
266
  gtk_signal_connect(GTK_OBJECT(quit_all_item), "activate",
 
267
                     GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
 
268
}
 
269
 
 
270
 
 
271
 
 
272
gint window_count = 0; /* number of windows on screen */
 
273
gint window_destroy(GtkWidget *widget)
 
274
{
 
275
  /* if this was last window quit */
 
276
  if (--window_count == 0)
 
277
    gtk_main_quit();
 
278
  return TRUE;
 
279
}
 
280
 
 
281
 
 
282
 
 
283
gint show_lwobject(char *lwobject_name)
 
284
{
 
285
  GtkWidget *window, *glarea;
 
286
  mesh_info *info;
 
287
  lwObject *lwobject;
 
288
 
 
289
  /* read lightwave object */
 
290
  if (!lw_is_lwobject(lwobject_name)) {
 
291
    g_print("%s is not a LightWave 3D object\n", lwobject_name);
 
292
    return FALSE;
 
293
  }
 
294
  lwobject = lw_object_read(lwobject_name);
 
295
  if (lwobject == NULL) {
 
296
    g_print("Can't read LightWave 3D object %s\n", lwobject_name);
 
297
    return FALSE;
 
298
  }
 
299
  lw_object_scale(lwobject, 10.0 / lw_object_radius(lwobject));
 
300
 
 
301
 
 
302
  /* create new OpenGL widget */
 
303
  glarea = gtk_gl_area_new_vargs(NULL, /* no sharing */
 
304
                                 GDK_GL_RGBA,
 
305
                                 GDK_GL_RED_SIZE,1,
 
306
                                 GDK_GL_GREEN_SIZE,1,
 
307
                                 GDK_GL_BLUE_SIZE,1,
 
308
                                 GDK_GL_DEPTH_SIZE,1,
 
309
                                 GDK_GL_DOUBLEBUFFER,
 
310
                                 GDK_GL_NONE);  /* last argument must be GDK_GL_NONE */
 
311
  if (glarea == NULL) {
 
312
    lw_object_free(lwobject);
 
313
    g_print("Can't create GtkGLArea widget\n");
 
314
    return FALSE;
 
315
  }
 
316
  /* set up events and signals for OpenGL widget */
 
317
  gtk_widget_set_events(glarea,
 
318
                        GDK_EXPOSURE_MASK|
 
319
                        GDK_BUTTON_PRESS_MASK|
 
320
                        GDK_BUTTON_RELEASE_MASK|
 
321
                        GDK_POINTER_MOTION_MASK|
 
322
                        GDK_POINTER_MOTION_HINT_MASK);
 
323
  gtk_signal_connect (GTK_OBJECT(glarea), "expose_event",
 
324
                      GTK_SIGNAL_FUNC(glarea_expose), NULL);
 
325
  gtk_signal_connect (GTK_OBJECT(glarea), "motion_notify_event",
 
326
                      GTK_SIGNAL_FUNC(glarea_motion_notify), NULL);
 
327
  gtk_signal_connect (GTK_OBJECT(glarea), "button_press_event",
 
328
                      GTK_SIGNAL_FUNC(glarea_button_press), NULL);
 
329
  gtk_signal_connect (GTK_OBJECT(glarea), "configure_event",
 
330
                      GTK_SIGNAL_FUNC(glarea_configure), NULL);
 
331
  gtk_signal_connect (GTK_OBJECT(glarea), "destroy",
 
332
                      GTK_SIGNAL_FUNC (glarea_destroy), NULL);
 
333
 
 
334
  gtk_widget_set_usize(glarea, 200,200/VIEW_ASPECT); /* minimum size */
 
335
 
 
336
  /* set up mesh info */
 
337
  info = (mesh_info*)g_malloc(sizeof(mesh_info));
 
338
  info->do_init = TRUE;
 
339
  info->lwobject = lwobject;
 
340
  info->beginx = 0;
 
341
  info->beginy = 0;
 
342
  info->zoom   = 45;
 
343
  trackball(info->quat , 0.0, 0.0, 0.0, 0.0);
 
344
  gtk_object_set_data(GTK_OBJECT(glarea), "mesh_info", info);
 
345
 
 
346
 
 
347
  /* create new top level window */
 
348
  window = gtk_window_new( GTK_WINDOW_TOPLEVEL);
 
349
  gtk_window_set_title(GTK_WINDOW(window), lwobject_name);
 
350
  gtk_container_set_border_width(GTK_CONTAINER(window), 10);
 
351
  create_popup_menu(window); /* add popup menu to window */
 
352
  gtk_signal_connect (GTK_OBJECT(window), "destroy",
 
353
                      GTK_SIGNAL_FUNC(window_destroy), NULL);
 
354
  window_count++;
 
355
 
 
356
  /* destroy this window when exiting from gtk_main() */
 
357
  gtk_quit_add_destroy(1, GTK_OBJECT(window));
 
358
 
 
359
 
 
360
  /* put glarea into window and show it all */
 
361
  gtk_container_add(GTK_CONTAINER(window), glarea);
 
362
 
 
363
  gtk_widget_show(glarea);
 
364
  gtk_widget_show(window);
 
365
 
 
366
  return TRUE;
 
367
}
 
368
 
 
369
 
 
370
 
 
371
gint filew_ok(GtkWidget *widget, GtkWidget *filew)
 
372
{
 
373
  if (show_lwobject(gtk_file_selection_get_filename(GTK_FILE_SELECTION(filew))) == TRUE)
 
374
    gtk_widget_destroy(filew);
 
375
  return TRUE;
 
376
}
 
377
 
 
378
void select_lwobject()
 
379
{
 
380
  GtkWidget *filew = gtk_file_selection_new("Select LightWave 3D object");
 
381
 
 
382
  gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION (filew)->ok_button), "clicked",
 
383
                     GTK_SIGNAL_FUNC(filew_ok), filew);
 
384
 
 
385
  gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(filew)->cancel_button), "clicked",
 
386
                            GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(filew));
 
387
 
 
388
  gtk_signal_connect (GTK_OBJECT(filew), "destroy",
 
389
                      GTK_SIGNAL_FUNC(window_destroy), NULL);
 
390
  window_count++;
 
391
 
 
392
  gtk_widget_show(filew);
 
393
}
 
394
 
 
395
 
 
396
 
 
397
 
 
398
 
 
399
int main (int argc, char **argv)
 
400
{
 
401
  /* initialize gtk */
 
402
  gtk_init( &argc, &argv );
 
403
 
 
404
  /* Check if OpenGL (GLX extension) is supported. */
 
405
  if (gdk_gl_query() == FALSE) {
 
406
    g_print("OpenGL not supported\n");
 
407
    return 0;
 
408
  }
 
409
 
 
410
  /* help? */
 
411
  if (argc >= 2 && strcmp(argv[1],"--help")==0) {
 
412
    g_print("%s", help_text);
 
413
    return 0;
 
414
  }
 
415
 
 
416
  if (argc == 1) {
 
417
    /* no filenames, show filerequester */
 
418
    select_lwobject();
 
419
  } else {
 
420
    /* show requested files */
 
421
    int i;
 
422
    for (i=1; i<argc; i++)
 
423
      show_lwobject(argv[i]);
 
424
  }
 
425
 
 
426
  if (window_count > 0)
 
427
    gtk_main();
 
428
 
 
429
  return 0;
 
430
}