starting a new 3d engine
[nexus3d] / src / wsys / wsys_fglut.c
1 #include <GL/freeglut.h>
2 #include "nexus3d_impl.h"
3 #include "gl/opengl.h"
4
5 static void winclose(void);
6 static void display(void);
7 static void idle(void);
8 static void reshape(int x, int y);
9 static void keydown(unsigned char key, int x, int y);
10 static void keyup(unsigned char key, int x, int y);
11 static void skeydown(int key, int x, int y);
12 static void skeyup(int key, int x, int y);
13 static void mouse(int bn, int st, int x, int y);
14 static void motion(int x, int y);
15
16 static int quit, have_idle;
17
18
19 int nex_initgfx(int xsz, int ysz, enum nex_gfxflags flags)
20 {
21         static char *fake_argv[] = {"nexus3d", 0};
22         static int fake_argc = 1;
23         unsigned int glut_flags;
24
25         if(flags & NEX_GFX_DEBUG) {
26                 nex_apicfg.gl.flags |= NEX_OPENGL_DEBUG;
27         }
28
29         glut_flags = GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_SRGB;
30         if(flags & NEX_GFX_STENCIL) {
31                 glut_flags |= GLUT_STENCIL;
32         }
33         if(flags & NEX_GFX_FSAA) {
34                 glut_flags |= GLUT_MULTISAMPLE;
35         }
36         if(flags & NEX_GFX_STEREO) {
37                 glut_flags |= GLUT_STEREO;
38         }
39
40         glutInit(&fake_argc, fake_argv);
41         glutInitWindowSize(xsz, ysz);
42         glutInitDisplayMode(glut_flags);
43
44         if(nex_apicfg.gl.flags & NEX_OPENGL_DEBUG) {
45                 glutInitContextFlags(GLUT_DEBUG);
46         }
47         if(nex_apicfg.gl.ver_major > 1) {
48                 glutInitContextVersion(3, 3);
49                 if(nex_apicfg.gl.flags & NEX_OPENGL_COMPAT) {
50                         glutInitContextProfile(GLUT_COMPATIBILITY_PROFILE);
51                 } else {
52                         glutInitContextProfile(GLUT_CORE_PROFILE);
53                 }
54         }
55
56         glutCreateWindow("nexus3d engine");
57
58         glutCloseFunc(winclose);
59         glutDisplayFunc(display);
60         glutReshapeFunc(reshape);
61         glutKeyboardFunc(keydown);
62         glutKeyboardUpFunc(keyup);
63         glutSpecialFunc(skeydown);
64         glutSpecialUpFunc(skeyup);
65         glutMouseFunc(mouse);
66         glutMotionFunc(motion);
67
68         nex_gfxflags = flags;
69         quit = 0;
70         have_idle = 0;
71
72         if(init_gl() == -1) {
73                 return -1;
74         }
75         return 0;
76 }
77
78 void nex_closegfx(void)
79 {
80 }
81
82 int nex_evloop_wait(void)
83 {
84         if(have_idle) {
85                 glutIdleFunc(0);
86                 have_idle = 0;
87         }
88
89         glutMainLoopEvent();
90         return quit ? 0 : 1;
91 }
92
93 int nex_evloop_poll(void)
94 {
95         if(!have_idle) {
96                 glutIdleFunc(idle);
97                 have_idle = 1;
98         }
99
100         glutMainLoopEvent();
101         return quit ? 0 : 1;
102 }
103
104 void nex_swap_buffers(void)
105 {
106         glutSwapBuffers();
107 }
108
109 void nex_redisplay(void)
110 {
111         glutPostRedisplay();
112 }
113
114 static void winclose(void)
115 {
116         quit = 1;
117 }
118
119 static void display(void)
120 {
121         if(nex_cb.display) {
122                 nex_cb.display(nex_cb.display_cls);
123         }
124 }
125
126 static void idle(void)
127 {
128         glutPostRedisplay();
129 }
130
131 static void reshape(int x, int y)
132 {
133         if(nex_cb.reshape) {
134                 nex_cb.reshape(x, y, nex_cb.reshape_cls);
135         }
136 }
137
138 static void keydown(unsigned char key, int x, int y)
139 {
140         if(nex_cb.key) {
141                 nex_cb.key(key, 1, nex_cb.key_cls);
142         }
143 }
144
145 static void keyup(unsigned char key, int x, int y)
146 {
147         if(nex_cb.key) {
148                 nex_cb.key(key, 0, nex_cb.key_cls);
149         }
150 }
151
152 static int translate_skey(int key)
153 {
154         switch(key) {
155         case GLUT_KEY_LEFT:
156                 return NEX_KEY_LEFT;
157         case GLUT_KEY_UP:
158                 return NEX_KEY_UP;
159         case GLUT_KEY_RIGHT:
160                 return NEX_KEY_RIGHT;
161         case GLUT_KEY_DOWN:
162                 return NEX_KEY_DOWN;
163         case GLUT_KEY_PAGE_UP:
164                 return NEX_KEY_PGUP;
165         case GLUT_KEY_PAGE_DOWN:
166                 return NEX_KEY_PGDOWN;
167         case GLUT_KEY_HOME:
168                 return NEX_KEY_HOME;
169         case GLUT_KEY_END:
170                 return NEX_KEY_END;
171         case GLUT_KEY_INSERT:
172                 return NEX_KEY_INS;
173         default:
174                 if(key >= GLUT_KEY_F1 && key <= GLUT_KEY_F12) {
175                         return NEX_KEY_F1 + (key - GLUT_KEY_F1);
176                 }
177         }
178         return -1;
179 }
180
181 static void skeydown(int key, int x, int y)
182 {
183         if(nex_cb.key && (key = translate_skey(key)) > 0) {
184                 nex_cb.key(key, 1, nex_cb.key_cls);
185         }
186 }
187
188 static void skeyup(int key, int x, int y)
189 {
190         if(nex_cb.key && (key = translate_skey(key)) > 0) {
191                 nex_cb.key(key, 0, nex_cb.key_cls);
192         }
193 }
194
195 static void mouse(int bn, int st, int x, int y)
196 {
197         if(nex_cb.mousebn) {
198                 int idx = bn - GLUT_LEFT_BUTTON;
199                 int press = bn == GLUT_DOWN;
200                 nex_cb.mousebn(idx, press, x, y, nex_cb.mousebn_cls);
201         }
202 }
203
204 static void motion(int x, int y)
205 {
206         if(nex_cb.mousemove) {
207                 nex_cb.mousemove(x, y, nex_cb.mousemove_cls);
208         }
209 }