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