erebus

view src/main.cc @ 21:e49f4d7ad04c

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