rev |
line source |
nuclear@0
|
1 #include <stdio.h>
|
nuclear@0
|
2 #include <stdlib.h>
|
nuclear@0
|
3 #include <assert.h>
|
nuclear@0
|
4 #include <GL/glew.h>
|
nuclear@0
|
5 #include <GL/glut.h>
|
nuclear@0
|
6 #include <vmath/vmath.h>
|
nuclear@0
|
7 #include "rend.h"
|
nuclear@0
|
8
|
nuclear@0
|
9 static bool init();
|
nuclear@0
|
10 static void cleanup();
|
nuclear@0
|
11 static void display();
|
nuclear@0
|
12 static void reshape(int x, int y);
|
nuclear@0
|
13 static void keyb(unsigned char key, int x, int y);
|
nuclear@0
|
14 static void mouse(int bn, int st, int x, int y);
|
nuclear@0
|
15 static void motion(int x, int y);
|
nuclear@0
|
16 static void resize_fbtex(int xsz, int ysz);
|
nuclear@0
|
17 static void update_fbtex();
|
nuclear@0
|
18 static int next_pow2(int x);
|
nuclear@0
|
19 static float dfunc(float x, float y, float z);
|
nuclear@0
|
20
|
nuclear@0
|
21 static int pix_scale = 2;
|
nuclear@0
|
22 static int width = 640;
|
nuclear@0
|
23 static int height = 384;
|
nuclear@0
|
24 static int win_width = width * pix_scale;
|
nuclear@0
|
25 static int win_height = height * pix_scale;
|
nuclear@0
|
26
|
nuclear@0
|
27 static float *pixels;
|
nuclear@0
|
28 static unsigned int tex;
|
nuclear@0
|
29 static int tex_width, tex_height;
|
nuclear@0
|
30
|
nuclear@0
|
31 static float cam_theta, cam_phi = 25, cam_dist = 10;
|
nuclear@0
|
32
|
nuclear@0
|
33
|
nuclear@0
|
34 int main(int argc, char **argv)
|
nuclear@0
|
35 {
|
nuclear@0
|
36 glutInit(&argc, argv);
|
nuclear@0
|
37 glutInitWindowSize(win_width, win_height);
|
nuclear@0
|
38 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
|
nuclear@0
|
39 glutCreateWindow("distance field raytracer");
|
nuclear@0
|
40
|
nuclear@0
|
41 glutDisplayFunc(display);
|
nuclear@0
|
42 glutReshapeFunc(reshape);
|
nuclear@0
|
43 glutKeyboardFunc(keyb);
|
nuclear@0
|
44 glutMouseFunc(mouse);
|
nuclear@0
|
45 glutMotionFunc(motion);
|
nuclear@0
|
46
|
nuclear@0
|
47 if(!init()) {
|
nuclear@0
|
48 return 1;
|
nuclear@0
|
49 }
|
nuclear@0
|
50 atexit(cleanup);
|
nuclear@0
|
51
|
nuclear@0
|
52 glutMainLoop();
|
nuclear@0
|
53 return 0;
|
nuclear@0
|
54 }
|
nuclear@0
|
55
|
nuclear@0
|
56 static bool init()
|
nuclear@0
|
57 {
|
nuclear@0
|
58 glewInit();
|
nuclear@0
|
59
|
nuclear@0
|
60 glEnable(GL_CULL_FACE);
|
nuclear@0
|
61
|
nuclear@0
|
62 glGenTextures(1, &tex);
|
nuclear@0
|
63 glBindTexture(GL_TEXTURE_2D, tex);
|
nuclear@0
|
64 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
nuclear@0
|
65 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
nuclear@0
|
66
|
nuclear@0
|
67 glEnable(GL_TEXTURE_2D);
|
nuclear@0
|
68
|
nuclear@0
|
69 set_distance_function(dfunc);
|
nuclear@0
|
70
|
nuclear@0
|
71 return true;
|
nuclear@0
|
72 }
|
nuclear@0
|
73
|
nuclear@0
|
74 static void cleanup()
|
nuclear@0
|
75 {
|
nuclear@0
|
76 glDeleteTextures(1, &tex);
|
nuclear@0
|
77 }
|
nuclear@0
|
78
|
nuclear@0
|
79 static void display()
|
nuclear@0
|
80 {
|
nuclear@0
|
81 Matrix4x4 cmat;
|
nuclear@0
|
82 cmat.translate(Vector3(0, 0, -cam_dist));
|
nuclear@0
|
83 cmat.rotate(Vector3(1, 0, 0), DEG_TO_RAD(cam_phi));
|
nuclear@0
|
84 cmat.rotate(Vector3(0, 1, 0), DEG_TO_RAD(cam_theta));
|
nuclear@0
|
85
|
nuclear@0
|
86 set_camera_matrix(cmat);
|
nuclear@0
|
87 render();
|
nuclear@0
|
88 update_fbtex();
|
nuclear@0
|
89
|
nuclear@0
|
90 glMatrixMode(GL_TEXTURE);
|
nuclear@0
|
91 glLoadIdentity();
|
nuclear@0
|
92 glScalef((float)tex_width / (float)width, (float)tex_height / (float)height, 1);
|
nuclear@0
|
93
|
nuclear@0
|
94 glBegin(GL_QUADS);
|
nuclear@0
|
95 glTexCoord2f(0, 0); glVertex2f(-1, -1);
|
nuclear@0
|
96 glTexCoord2f(1, 0); glVertex2f(1, -1);
|
nuclear@0
|
97 glTexCoord2f(1, 1); glVertex2f(1, 1);
|
nuclear@0
|
98 glTexCoord2f(0, 1); glVertex2f(-1, 1);
|
nuclear@0
|
99 glEnd();
|
nuclear@0
|
100
|
nuclear@0
|
101 glutSwapBuffers();
|
nuclear@0
|
102 assert(glGetError() == GL_NO_ERROR);
|
nuclear@0
|
103 }
|
nuclear@0
|
104
|
nuclear@0
|
105 static void reshape(int x, int y)
|
nuclear@0
|
106 {
|
nuclear@0
|
107 static int prev_x , prev_y;
|
nuclear@0
|
108
|
nuclear@0
|
109 glViewport(0, 0, x, y);
|
nuclear@0
|
110 resize_fbtex(x, y);
|
nuclear@0
|
111
|
nuclear@0
|
112 if(x != prev_x || y != prev_y) {
|
nuclear@0
|
113 delete [] pixels;
|
nuclear@0
|
114 pixels = new float[x * y * 4];
|
nuclear@0
|
115 set_framebuffer(x, y, pixels);
|
nuclear@0
|
116 prev_x = x;
|
nuclear@0
|
117 prev_y = y;
|
nuclear@0
|
118 }
|
nuclear@0
|
119 }
|
nuclear@0
|
120
|
nuclear@0
|
121 static void resize_fbtex(int xsz, int ysz)
|
nuclear@0
|
122 {
|
nuclear@0
|
123 int txsz = next_pow2(xsz);
|
nuclear@0
|
124 int tysz = next_pow2(ysz);
|
nuclear@0
|
125
|
nuclear@0
|
126 if(txsz > tex_width || tysz > tex_height) {
|
nuclear@0
|
127 tex_width = txsz;
|
nuclear@0
|
128 tex_height = tysz;
|
nuclear@0
|
129
|
nuclear@0
|
130 glBindTexture(GL_TEXTURE_2D, tex);
|
nuclear@0
|
131 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, txsz, tysz, 0, GL_RGBA, GL_FLOAT, 0);
|
nuclear@0
|
132 }
|
nuclear@0
|
133 }
|
nuclear@0
|
134
|
nuclear@0
|
135 static void update_fbtex()
|
nuclear@0
|
136 {
|
nuclear@0
|
137 glBindTexture(GL_TEXTURE_2D, tex);
|
nuclear@0
|
138 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_FLOAT, pixels);
|
nuclear@0
|
139 }
|
nuclear@0
|
140
|
nuclear@0
|
141 static int next_pow2(int x)
|
nuclear@0
|
142 {
|
nuclear@0
|
143 --x;
|
nuclear@0
|
144 x |= x >> 1;
|
nuclear@0
|
145 x |= x >> 2;
|
nuclear@0
|
146 x |= x >> 4;
|
nuclear@0
|
147 x |= x >> 8;
|
nuclear@0
|
148 x |= x >> 16;
|
nuclear@0
|
149 return x + 1;
|
nuclear@0
|
150 }
|
nuclear@0
|
151
|
nuclear@0
|
152 static float dfunc(float x, float y, float z)
|
nuclear@0
|
153 {
|
nuclear@0
|
154 return sqrt(x*x + y*y + z*z) - 1.0;
|
nuclear@0
|
155 }
|
nuclear@0
|
156
|
nuclear@0
|
157 static void keyb(unsigned char key, int x, int y)
|
nuclear@0
|
158 {
|
nuclear@0
|
159 switch(key) {
|
nuclear@0
|
160 case 27:
|
nuclear@0
|
161 exit(0);
|
nuclear@0
|
162 }
|
nuclear@0
|
163 }
|
nuclear@0
|
164
|
nuclear@0
|
165 static int prev_x, prev_y;
|
nuclear@0
|
166 static bool bnstate[8];
|
nuclear@0
|
167
|
nuclear@0
|
168 static void mouse(int bn, int st, int x, int y)
|
nuclear@0
|
169 {
|
nuclear@0
|
170 bnstate[bn - GLUT_LEFT_BUTTON] = st == GLUT_DOWN;
|
nuclear@0
|
171 prev_x = x;
|
nuclear@0
|
172 prev_y = y;
|
nuclear@0
|
173 }
|
nuclear@0
|
174
|
nuclear@0
|
175 static void motion(int x, int y)
|
nuclear@0
|
176 {
|
nuclear@0
|
177 int dx = x - prev_x;
|
nuclear@0
|
178 int dy = y - prev_y;
|
nuclear@0
|
179 prev_x = x;
|
nuclear@0
|
180 prev_y = y;
|
nuclear@0
|
181
|
nuclear@0
|
182 if(!dx && !dy) return;
|
nuclear@0
|
183
|
nuclear@0
|
184 if(bnstate[0]) {
|
nuclear@0
|
185 cam_theta -= dx * 0.5;
|
nuclear@0
|
186 cam_phi -= dy * 0.5;
|
nuclear@0
|
187
|
nuclear@0
|
188 if(cam_phi < -90) cam_phi = -90;
|
nuclear@0
|
189 if(cam_phi > 90) cam_phi = 90;
|
nuclear@0
|
190 glutPostRedisplay();
|
nuclear@0
|
191 }
|
nuclear@0
|
192 if(bnstate[2]) {
|
nuclear@0
|
193 cam_dist += dy * 0.1;
|
nuclear@0
|
194 if(cam_dist < 0.0) cam_dist = 0.0;
|
nuclear@0
|
195 glutPostRedisplay();
|
nuclear@0
|
196 }
|
nuclear@0
|
197 }
|