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