1 /*
2  *  This file is part of XForms.
3  *
4  *  XForms is free software; you can redistribute it and/or modify it
5  *  under the terms of the GNU Lesser General Public License as
6  *  published by the Free Software Foundation; either version 2.1, or
7  *  (at your option) any later version.
8  *
9  *  XForms is distributed in the hope that it will be useful, but
10  *  WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  *  Lesser General Public License for more details.
13  *
14  *  You should have received a copy of the GNU Lesser General Public
15  *  License along with XForms; see the file COPYING.  If not, write to
16  *  the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
17  *  MA 02111-1307, USA.
18  */
19 
20 
21 /*
22  * OpenGL/mesa canvas demo
23  *
24  * On most platforms, the mesa/OpenGL support is not compiled into
25  * the shared library (It it in the static library). You can compile
26  * ../FORMS/gl.c and put it in the shared library if you have mesa/OpenGL
27  *
28  * Also you might want to make a link libGL.a to libMesaGL.a
29  *
30  * T.C. Zhao and M. Overmars
31  */
32 
33 #ifdef HAVE_CONFIG_H
34 #include "config.h"
35 #endif
36 
37 #include <stdlib.h>
38 #include <GL/gl.h>
39 #include <GL/glx.h>
40 
41 #include "include/forms.h"
42 #include "gl/glcanvas.h"
43 
44 typedef struct {
45     FL_FORM   * form;
46     void      * vdata;
47     char      * cdata;
48     long        ldata;
49     FL_OBJECT * canvas;
50     FL_OBJECT * done;
51     FL_OBJECT * menu;
52     FL_OBJECT * butgrp;
53 } FD_form;
54 
55 extern FD_form * create_form_form(void);
56 
57 FD_form *ui;
58 
59 static int prim = GL_POLYGON ;
60 
61 #define v3f glVertex3f
62 
63 
64 /***************************************
65  ***************************************/
66 
67 static
draw_cube(void)68 void draw_cube( void )
69 {
70     glColor3f( 1.0, 0.0, 0.0 );
71     glBegin( prim );
72     v3f( 1.0, 1.0, 1.0 );   v3f( 1.0, -1.0, 1.0 );
73     v3f( 1.0, -1.0, -1.0 ); v3f( 1.0, 1.0, -1.0 );
74     glEnd( );
75 
76     glBegin( prim );
77     v3f( -1.0,  1.0,  1.0 );
78     v3f( -1.0,  1.0, -1.0 );
79     v3f( -1.0, -1.0, -1.0 );
80     v3f( -1.0, -1.0,  1.0 );
81     glEnd( );
82 
83     glColor3f( 0.0, 1.0, 0.0 );
84     glBegin( prim );
85     v3f(  1.0,  1.0,  1.0 );
86     v3f(  1.0,  1.0, -1.0 );
87     v3f( -1.0,  1.0, -1.0 );
88     v3f( -1.0,  1.0,  1.0 );
89     glEnd( );
90 
91     glBegin( prim );
92     v3f(  1.0, -1.0,  1.0 );
93     v3f( -1.0, -1.0,  1.0 );
94     v3f( -1.0, -1.0, -1.0 );
95     v3f(  1.0, -1.0, -1.0 );
96     glEnd( );
97 
98     glColor3f( 0.0, 0.0, 1.0 );
99     glBegin( prim );
100     v3f(  1.0,  1.0,  1.0 );
101     v3f( -1.0,  1.0,  1.0 );
102     v3f( -1.0, -1.0,  1.0 );
103     v3f(  1.0, -1.0,  1.0 );
104     glEnd( );
105 
106     glBegin( prim );
107     v3f(  1.0,  1.0, -1.0 );
108     v3f(  1.0, -1.0, -1.0 );
109     v3f( -1.0, -1.0, -1.0 );
110     v3f( -1.0,  1.0, -1.0 );
111     glEnd( );
112 }
113 
114 
115 /***************************************
116  ***************************************/
117 
118 int
idle_cb(XEvent * ev,void * data FL_UNUSED_ARG)119 idle_cb( XEvent * ev,
120          void   * data  FL_UNUSED_ARG )
121 {
122     static GLfloat xrot,
123                    yrot,
124                    zrot;
125 
126     if (    ! fl_form_is_visible( ui->form )
127          || ! fl_object_is_visible( ui->canvas ) )
128         return 0;
129 
130     fl_activate_glcanvas( ui->canvas );
131 
132     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
133 
134     glPushMatrix( );
135 
136     glRotatef( xrot, 1.0, 0.0, 0.0 );
137     glRotatef( yrot, 0.0, 1.0, 0.0 );
138     glRotatef( zrot, 0.0, 0.0, 1.0 );
139     glTranslatef( -1.0,1.2,-0.5 );
140 
141     draw_cube( );
142 
143     glPopMatrix( );
144 
145     glFinish( );
146 
147     if ( ev )
148     {
149         xrot += 10.0;
150         yrot += 7.0;
151         zrot -= 3.0;
152     }
153 
154     glXSwapBuffers( fl_display, fl_get_canvas_id( ui->canvas ) );
155 
156     return 0;
157 }
158 
159 
160 /***************************************
161  ***************************************/
162 
163 int
canvas_expose(FL_OBJECT * ob FL_UNUSED_ARG,Window win FL_UNUSED_ARG,int w,int h,XEvent * xev FL_UNUSED_ARG,void * ud FL_UNUSED_ARG)164 canvas_expose( FL_OBJECT * ob   FL_UNUSED_ARG,
165                Window      win  FL_UNUSED_ARG,
166                int         w,
167                int         h,
168                XEvent *    xev  FL_UNUSED_ARG,
169                void *      ud   FL_UNUSED_ARG )
170 {
171     glViewport( 0, 0, ( GLint ) w, ( GLint ) h );
172     glClearColor( 0.0, 0.0, 0.0, 0.0 );
173 
174     glMatrixMode( GL_PROJECTION );
175     glLoadIdentity( );
176     glFrustum( -1.0, 1.0, -1.0, 1.0, 1.0, 10.0 );
177     glTranslatef( 0.0, 0.0, -5.0 );
178 
179     glMatrixMode( GL_MODELVIEW );
180     glLoadIdentity( );
181     glCullFace( GL_BACK );
182     glEnable( GL_CULL_FACE );
183 
184     glShadeModel( GL_FLAT );
185 
186     /* refresh */
187 
188     idle_cb( 0, 0 );
189     return 0;
190 }
191 
192 
193 /***************************************
194  ***************************************/
195 
196 int
buttonpress_cb(FL_OBJECT * ob FL_UNUSED_ARG,Window win FL_UNUSED_ARG,int w FL_UNUSED_ARG,int h FL_UNUSED_ARG,XEvent * xev FL_UNUSED_ARG,void * ud FL_UNUSED_ARG)197 buttonpress_cb( FL_OBJECT * ob   FL_UNUSED_ARG,
198                 Window      win  FL_UNUSED_ARG,
199                 int         w    FL_UNUSED_ARG,
200                 int         h    FL_UNUSED_ARG,
201                 XEvent *    xev  FL_UNUSED_ARG,
202                 void *      ud   FL_UNUSED_ARG )
203 {
204    static int suspended = 0;
205 
206    suspended ^= 1;
207    fl_set_idle_callback( suspended ? 0 : idle_cb, 0 );
208 
209    return 0;
210 }
211 
212 
213 /***************************************
214  ***************************************/
215 
216 void
switch_primitive(FL_OBJECT * ob FL_UNUSED_ARG,long data FL_UNUSED_ARG)217 switch_primitive( FL_OBJECT * ob    FL_UNUSED_ARG,
218                   long        data  FL_UNUSED_ARG )
219 {
220     static int primitive[ ] = { GL_POLYGON, GL_LINE_LOOP };
221     static int i ;
222 
223     prim = primitive[ ++i % 2 ];
224 }
225 
226 
227 /* switch single/dblbuffer */
228 
229 static int sbuf[ ]= { GLX_RGBA,GLX_DEPTH_SIZE, 1,
230                       GLX_RED_SIZE,            1,
231                       GLX_GREEN_SIZE,          1,
232                       GLX_BLUE_SIZE,           1,
233                       None                        };
234 
235 static int dbuf[ ]= { GLX_RGBA,
236                       GLX_DEPTH_SIZE,
237                       1,
238                       GLX_RED_SIZE,
239                       1,
240                       GLX_GREEN_SIZE,
241                       1,
242                       GLX_BLUE_SIZE,
243                       1,
244                       /* GLX_DOUBLEBUFFER, */
245                       None};
246 
247 
248 /***************************************
249  ***************************************/
250 
251 void
buffer_cb(FL_OBJECT * ob,long data FL_UNUSED_ARG)252 buffer_cb( FL_OBJECT * ob,
253            long        data  FL_UNUSED_ARG )
254 {
255     static int is_double = 1;
256     FD_form *fdui = ob->form->fdui;
257 
258     is_double = ! is_double;
259     fl_set_object_label( ob,is_double ? "Single":"Double" );
260     fl_set_glcanvas_attributes( fdui->canvas, is_double ? dbuf : sbuf );
261 }
262 
263 
264 /***************************************
265  ***************************************/
266 
267 void
menu_cb(FL_OBJECT * ob FL_UNUSED_ARG,long data FL_UNUSED_ARG)268 menu_cb( FL_OBJECT * ob    FL_UNUSED_ARG,
269          long        data  FL_UNUSED_ARG )
270 {
271 }
272 
273 
274 /***************************************
275  ***************************************/
276 
main(int argc,char * argv[])277 int main( int    argc,
278           char * argv[ ] )
279 {
280    fl_initialize( &argc, argv, "FormDemo", 0, 0 );
281    ui = create_form_form( );
282 
283    /* fill-in form initialization code */
284 
285    fl_set_object_gravity( ui->butgrp, NorthEastGravity, NorthEastGravity );
286    fl_addto_menu( ui->menu,"Item1|Item2|Item3|Item4" );
287 
288    fl_add_canvas_handler( ui->canvas, Expose, canvas_expose, 0 );
289    fl_add_canvas_handler( ui->canvas, ButtonPress, buttonpress_cb, 0 );
290    fl_set_idle_callback( idle_cb, 0 );
291 
292    /* geometry stuff */
293 
294 //   fl_set_form_minsize( ui->form, 340, 280 );
295 
296    fl_show_form( ui->form, FL_PLACE_CENTER | FL_FREE_SIZE, FL_FULLBORDER,
297                  "OpenGL Canvas");
298 
299    while ( fl_do_forms( ) != ui->done )
300        /* empty */ ;
301 
302    fl_finish( );
303    return 0;
304 }
305 
306 
307 /***************************************
308  ***************************************/
309 
310 static void
hide_it(FL_OBJECT * ob,long data FL_UNUSED_ARG)311 hide_it( FL_OBJECT * ob,
312          long        data  FL_UNUSED_ARG )
313 {
314     if ( fl_object_is_visible( ui->canvas ) )
315     {
316         fl_hide_object( ui->canvas );
317         fl_set_object_label( ob,"Show" );
318     }
319     else
320     {
321        fl_show_object( ui->canvas );
322        fl_set_object_label( ob, "Hide" );
323     }
324 }
325 
326 
327 /***************************************
328  ***************************************/
329 
330 static void
reshow(FL_OBJECT * ob,long data FL_UNUSED_ARG)331 reshow( FL_OBJECT * ob,
332         long        data  FL_UNUSED_ARG )
333 {
334     fl_hide_form( ob->form );
335     fl_show_form( ui->form, FL_PLACE_CENTER | FL_FREE_SIZE, FL_FULLBORDER,
336                   "OpenGL Canvas" );
337 }
338 
339 
340 /***************************************
341  ***************************************/
342 
343 FD_form *
create_form_form(void)344 create_form_form( void )
345 {
346     FL_OBJECT *obj;
347     FD_form *fdui = fl_calloc( 1, sizeof *fdui);
348 
349     fdui->form = fl_bgn_form( FL_NO_BOX, 340, 280 );
350 
351     fl_add_box( FL_UP_BOX, 0, 0, 340, 280, "" );
352 
353     fdui->canvas = obj = fl_add_glcanvas( FL_NORMAL_CANVAS, 20, 45, 225, 215,
354                                           "" );
355     fl_set_object_gravity( obj, FL_NorthWest, FL_SouthEast );
356 
357     fdui->done = obj = fl_add_button( FL_NORMAL_BUTTON, 255, 230, 70, 30,
358                                       "Done");
359     fl_set_button_shortcut( obj, "Dd#d", 1 );
360     fl_set_object_gravity( obj, FL_SouthEast, FL_SouthEast );
361 
362     fdui->menu = obj = fl_add_menu( FL_PULLDOWN_MENU, 20, 15, 54, 20,
363                                     "Canvas" );
364     fl_set_object_shortcut( obj, "#CcC", 1 );
365     fl_set_object_boxtype( obj, FL_FLAT_BOX );
366     fl_set_object_lstyle( obj, FL_BOLD_STYLE );
367     fl_set_object_gravity( obj, FL_NorthWest, FL_NorthWest );
368     fl_set_object_callback( obj, menu_cb, 0 );
369 
370     fdui->butgrp = fl_bgn_group( );
371 
372     obj = fl_add_button( FL_NORMAL_BUTTON, 255, 45, 70, 30, "Poly/Line" );
373     fl_set_object_gravity( obj, FL_NorthEast, FL_NorthEast );
374     fl_set_object_callback( obj, switch_primitive, 0 );
375 
376     obj = fl_add_button( FL_NORMAL_BUTTON, 255, 75, 70, 30, "Hide" );
377     fl_set_button_shortcut( obj, "#HhH", 1 );
378     fl_set_object_callback( obj,hide_it, 0 );
379 
380     obj = fl_add_button( FL_NORMAL_BUTTON, 255, 105, 70, 30, "ReShow" );
381     fl_set_button_shortcut( obj, "#RRr", 1 );
382     fl_set_object_callback( obj, reshow, 0 );
383 
384     obj = fl_add_button( FL_NORMAL_BUTTON, 255, 135, 70, 30, "Single" );
385     fl_set_object_callback( obj, buffer_cb, 0 );
386 
387     fl_end_group( );
388 
389     fl_end_form( );
390 
391     fdui->form->fdui = fdui;
392 
393     return fdui;
394 }
395 
396 
397 /*
398  * Local variables:
399  * tab-width: 4
400  * indent-tabs-mode: nil
401  * End:
402  */
403