rev |
line source |
nuclear@2
|
1 #include <stdio.h>
|
nuclear@2
|
2 #include <stdlib.h>
|
nuclear@2
|
3 #include <assert.h>
|
nuclear@2
|
4 #include "opengl.h"
|
nuclear@4
|
5 #include "erebus.h"
|
nuclear@2
|
6
|
nuclear@2
|
7 static bool init();
|
nuclear@2
|
8 static void cleanup();
|
nuclear@2
|
9 static void resize_rtarget(int xsz, int ysz);
|
nuclear@2
|
10 static void update_rect(int x, int y, int xsz, int ysz, float *pixels);
|
nuclear@4
|
11 static void idle();
|
nuclear@2
|
12 static void display();
|
nuclear@2
|
13 static void reshape(int x, int y);
|
nuclear@2
|
14 static void keyb(unsigned char key, int x, int y);
|
nuclear@9
|
15 static void keyb_up(unsigned char key, int x, int y);
|
nuclear@2
|
16 static void mouse(int bn, int st, int x, int y);
|
nuclear@9
|
17 static void motion(int x, int y);
|
nuclear@9
|
18 static void sball_button(int bn, int st);
|
nuclear@9
|
19 static void sball_motion(int x, int y, int z);
|
nuclear@2
|
20 static int next_pow2(int x);
|
nuclear@2
|
21
|
nuclear@2
|
22 static int width, height, rtex_width, rtex_height;
|
nuclear@2
|
23 static unsigned int rtex;
|
nuclear@2
|
24
|
nuclear@4
|
25 static erebus *erb;
|
nuclear@4
|
26 static bool render_pending;
|
nuclear@4
|
27
|
nuclear@4
|
28
|
nuclear@2
|
29 int main(int argc, char **argv)
|
nuclear@2
|
30 {
|
nuclear@2
|
31 glutInitWindowSize(1024, 600);
|
nuclear@2
|
32 glutInit(&argc, argv);
|
nuclear@2
|
33 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
|
nuclear@2
|
34 glutCreateWindow("erebus OpenGL frontend");
|
nuclear@2
|
35
|
nuclear@2
|
36 glutDisplayFunc(display);
|
nuclear@2
|
37 glutReshapeFunc(reshape);
|
nuclear@2
|
38 glutKeyboardFunc(keyb);
|
nuclear@9
|
39 glutKeyboardUpFunc(keyb_up);
|
nuclear@2
|
40 glutMouseFunc(mouse);
|
nuclear@9
|
41 glutMotionFunc(motion);
|
nuclear@9
|
42 glutSpaceballButtonFunc(sball_button);
|
nuclear@9
|
43 glutSpaceballMotionFunc(sball_motion);
|
nuclear@2
|
44
|
nuclear@2
|
45 if(!init()) {
|
nuclear@2
|
46 return 1;
|
nuclear@2
|
47 }
|
nuclear@2
|
48 atexit(cleanup);
|
nuclear@2
|
49
|
nuclear@2
|
50 glutMainLoop();
|
nuclear@2
|
51 }
|
nuclear@2
|
52
|
nuclear@2
|
53 static bool init()
|
nuclear@2
|
54 {
|
nuclear@8
|
55 width = glutGet(GLUT_WINDOW_WIDTH) / 2;
|
nuclear@8
|
56 height = glutGet(GLUT_WINDOW_HEIGHT) / 2;
|
nuclear@5
|
57
|
nuclear@4
|
58 if(!(erb = erb_init())) {
|
nuclear@4
|
59 return false;
|
nuclear@4
|
60 }
|
nuclear@4
|
61 erb_setopti(erb, ERB_OPT_WIDTH, width);
|
nuclear@4
|
62 erb_setopti(erb, ERB_OPT_HEIGHT, height);
|
nuclear@4
|
63
|
nuclear@4
|
64 if(erb_load_scene(erb, "scene") == -1) {
|
nuclear@4
|
65 return false;
|
nuclear@4
|
66 }
|
nuclear@4
|
67
|
nuclear@4
|
68 printf("begin rendering\n");
|
nuclear@4
|
69 render_pending = true;
|
nuclear@4
|
70 glutIdleFunc(idle);
|
nuclear@4
|
71 erb_begin_frame(erb, 0);
|
nuclear@4
|
72
|
nuclear@8
|
73 glEnable(GL_TEXTURE_2D);
|
nuclear@2
|
74 return true;
|
nuclear@2
|
75 }
|
nuclear@2
|
76
|
nuclear@2
|
77 static void cleanup()
|
nuclear@2
|
78 {
|
nuclear@4
|
79 erb_destroy(erb);
|
nuclear@2
|
80 }
|
nuclear@2
|
81
|
nuclear@2
|
82 static void resize_rtarget(int xsz, int ysz)
|
nuclear@2
|
83 {
|
nuclear@2
|
84 static unsigned char *defpix;
|
nuclear@2
|
85
|
nuclear@8
|
86 width = xsz / 2;
|
nuclear@8
|
87 height = ysz / 2;
|
nuclear@2
|
88
|
nuclear@8
|
89 if(width <= rtex_width && height <= rtex_height) {
|
nuclear@2
|
90 return;
|
nuclear@2
|
91 }
|
nuclear@8
|
92 rtex_width = next_pow2(width);
|
nuclear@8
|
93 rtex_height = next_pow2(height);
|
nuclear@2
|
94
|
nuclear@2
|
95 printf("resizing framebuffer texture: %dx%d\n", rtex_width, rtex_height);
|
nuclear@2
|
96
|
nuclear@2
|
97 if(!rtex) {
|
nuclear@2
|
98 glGenTextures(1, &rtex);
|
nuclear@2
|
99 }
|
nuclear@2
|
100
|
nuclear@2
|
101 delete [] defpix;
|
nuclear@2
|
102 defpix = new unsigned char[rtex_width * rtex_height * 4];
|
nuclear@2
|
103 unsigned char *ptr = defpix;
|
nuclear@2
|
104 for(int i=0; i<rtex_height; i++) {
|
nuclear@2
|
105 for(int j=0; j<rtex_width; j++) {
|
nuclear@2
|
106 bool chess = ((i >> 4) & 1) == ((j >> 4) & 1);
|
nuclear@2
|
107
|
nuclear@2
|
108 int val = chess ? 64 : 48;
|
nuclear@2
|
109
|
nuclear@2
|
110 *ptr++ = val;
|
nuclear@2
|
111 *ptr++ = val;
|
nuclear@2
|
112 *ptr++ = val;
|
nuclear@2
|
113 *ptr++ = 255;
|
nuclear@2
|
114 }
|
nuclear@2
|
115 }
|
nuclear@2
|
116
|
nuclear@2
|
117 glBindTexture(GL_TEXTURE_2D, rtex);
|
nuclear@2
|
118 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
nuclear@2
|
119 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
nuclear@2
|
120 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, rtex_width, rtex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, defpix);
|
nuclear@2
|
121 }
|
nuclear@2
|
122
|
nuclear@2
|
123 static void update_rect(int x, int y, int xsz, int ysz, float *pixels)
|
nuclear@2
|
124 {
|
nuclear@2
|
125 glBindTexture(GL_TEXTURE_2D, rtex);
|
nuclear@2
|
126 glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, xsz, ysz, GL_RGBA, GL_FLOAT, pixels);
|
nuclear@2
|
127 }
|
nuclear@2
|
128
|
nuclear@4
|
129 static void idle()
|
nuclear@4
|
130 {
|
nuclear@4
|
131 glutPostRedisplay();
|
nuclear@4
|
132 }
|
nuclear@4
|
133
|
nuclear@2
|
134 static void display()
|
nuclear@2
|
135 {
|
nuclear@4
|
136 if(render_pending) {
|
nuclear@8
|
137 if(erb_render(erb, 64) == 0) {
|
nuclear@4
|
138 render_pending = false;
|
nuclear@4
|
139 glutIdleFunc(0);
|
nuclear@4
|
140 }
|
nuclear@4
|
141 update_rect(0, 0, width, height, erb_get_framebuffer(erb));
|
nuclear@4
|
142 }
|
nuclear@4
|
143
|
nuclear@2
|
144 float maxu = (float)width / (float)rtex_width;
|
nuclear@2
|
145 float maxv = (float)height / (float)rtex_height;
|
nuclear@2
|
146
|
nuclear@2
|
147 glBegin(GL_QUADS);
|
nuclear@2
|
148 glTexCoord2f(0, maxv); glVertex2f(-1, -1);
|
nuclear@2
|
149 glTexCoord2f(maxu, maxv); glVertex2f(1, -1);
|
nuclear@2
|
150 glTexCoord2f(maxu, 0); glVertex2f(1, 1);
|
nuclear@2
|
151 glTexCoord2f(0, 0); glVertex2f(-1, 1);
|
nuclear@2
|
152 glEnd();
|
nuclear@2
|
153
|
nuclear@2
|
154 glutSwapBuffers();
|
nuclear@2
|
155 assert(glGetError() == GL_NO_ERROR);
|
nuclear@2
|
156 }
|
nuclear@2
|
157
|
nuclear@2
|
158 static void reshape(int x, int y)
|
nuclear@2
|
159 {
|
nuclear@2
|
160 glViewport(0, 0, x, y);
|
nuclear@2
|
161 resize_rtarget(x, y);
|
nuclear@4
|
162
|
nuclear@4
|
163 erb_setopti(erb, ERB_OPT_WIDTH, width);
|
nuclear@4
|
164 erb_setopti(erb, ERB_OPT_HEIGHT, height);
|
nuclear@2
|
165 }
|
nuclear@2
|
166
|
nuclear@2
|
167 static void keyb(unsigned char key, int x, int y)
|
nuclear@2
|
168 {
|
nuclear@2
|
169 switch(key) {
|
nuclear@2
|
170 case 27:
|
nuclear@2
|
171 exit(0);
|
nuclear@4
|
172
|
nuclear@4
|
173 case ' ':
|
nuclear@4
|
174 printf("begin rendering\n");
|
nuclear@4
|
175 render_pending = true;
|
nuclear@4
|
176 glutIdleFunc(idle);
|
nuclear@4
|
177 erb_begin_frame(erb, 0);
|
nuclear@4
|
178 break;
|
nuclear@2
|
179 }
|
nuclear@9
|
180
|
nuclear@9
|
181 if(erb_input_keyboard(key, true)) {
|
nuclear@9
|
182 glutPostRedisplay();
|
nuclear@9
|
183 }
|
nuclear@9
|
184 }
|
nuclear@9
|
185
|
nuclear@9
|
186 static void keyb_up(unsigned char key, int x, int y)
|
nuclear@9
|
187 {
|
nuclear@9
|
188 if(erb_input_keyboard(key, false)) {
|
nuclear@9
|
189 glutPostRedisplay();
|
nuclear@9
|
190 }
|
nuclear@2
|
191 }
|
nuclear@2
|
192
|
nuclear@2
|
193 static void mouse(int bn, int st, int x, int y)
|
nuclear@2
|
194 {
|
nuclear@9
|
195 if(erb_input_mouse_button(bn - GLUT_LEFT_BUTTON, st == GLUT_DOWN, x, y)) {
|
nuclear@9
|
196 glutPostRedisplay();
|
nuclear@9
|
197 }
|
nuclear@9
|
198 }
|
nuclear@9
|
199
|
nuclear@9
|
200 static void motion(int x, int y)
|
nuclear@9
|
201 {
|
nuclear@9
|
202 if(erb_input_mouse_move(x, y)) {
|
nuclear@9
|
203 glutPostRedisplay();
|
nuclear@9
|
204 }
|
nuclear@9
|
205 }
|
nuclear@9
|
206
|
nuclear@9
|
207 static void sball_button(int bn, int state)
|
nuclear@9
|
208 {
|
nuclear@9
|
209 if(erb_input_6dof_button(bn, state == GLUT_DOWN)) {
|
nuclear@9
|
210 glutPostRedisplay();
|
nuclear@9
|
211 }
|
nuclear@9
|
212 }
|
nuclear@9
|
213
|
nuclear@9
|
214 static void sball_motion(int x, int y, int z)
|
nuclear@9
|
215 {
|
nuclear@9
|
216 if(erb_input_6dof_motion(x / 65536.0, y / 65536.0, z / 65536.0)) {
|
nuclear@9
|
217 glutPostRedisplay();
|
nuclear@9
|
218 }
|
nuclear@2
|
219 }
|
nuclear@2
|
220
|
nuclear@2
|
221 static int next_pow2(int x)
|
nuclear@2
|
222 {
|
nuclear@2
|
223 int res = 2;
|
nuclear@2
|
224 while(res < x) {
|
nuclear@2
|
225 res <<= 1;
|
nuclear@2
|
226 }
|
nuclear@2
|
227 return res;
|
nuclear@2
|
228 }
|