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