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