rev |
line source |
nuclear@0
|
1 #include <stdio.h>
|
nuclear@3
|
2 #include <stdlib.h>
|
nuclear@2
|
3 #include <string.h>
|
nuclear@2
|
4 #include <errno.h>
|
nuclear@3
|
5 #ifndef __APPLE__
|
nuclear@3
|
6 #include <GL/glut.h>
|
nuclear@3
|
7 #else
|
nuclear@3
|
8 #include <GLUT/glut.h>
|
nuclear@3
|
9 #endif
|
nuclear@3
|
10 #include "rt.h"
|
nuclear@0
|
11
|
nuclear@3
|
12 void cleanup();
|
nuclear@3
|
13 void disp();
|
nuclear@3
|
14 void reshape(int x, int y);
|
nuclear@3
|
15 void keyb(unsigned char key, int x, int y);
|
nuclear@3
|
16 void mouse(int bn, int status, int x, int y);
|
nuclear@3
|
17 void motion(int x, int y);
|
nuclear@2
|
18 bool write_ppm(const char *fname, float *fb, int xsz, int ysz);
|
nuclear@2
|
19
|
nuclear@3
|
20 static float *fb;
|
nuclear@3
|
21 static int xsz, ysz;
|
nuclear@3
|
22 static bool need_update = true;
|
nuclear@3
|
23
|
nuclear@3
|
24 int main(int argc, char **argv)
|
nuclear@0
|
25 {
|
nuclear@3
|
26 glutInitWindowSize(800, 600);
|
nuclear@3
|
27 glutInit(&argc, argv);
|
nuclear@3
|
28 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
|
nuclear@3
|
29 glutCreateWindow("OpenCL Raytracer");
|
nuclear@0
|
30
|
nuclear@3
|
31 xsz = glutGet(GLUT_WINDOW_WIDTH);
|
nuclear@3
|
32 ysz = glutGet(GLUT_WINDOW_HEIGHT);
|
nuclear@2
|
33
|
nuclear@3
|
34 glutDisplayFunc(disp);
|
nuclear@3
|
35 glutReshapeFunc(reshape);
|
nuclear@3
|
36 glutKeyboardFunc(keyb);
|
nuclear@3
|
37 glutMouseFunc(mouse);
|
nuclear@3
|
38 glutMotionFunc(motion);
|
nuclear@0
|
39
|
nuclear@3
|
40 fb = new float[xsz * ysz * 4];
|
nuclear@3
|
41 if(!init_renderer(xsz, ysz, fb)) {
|
nuclear@0
|
42 return 1;
|
nuclear@0
|
43 }
|
nuclear@3
|
44 atexit(cleanup);
|
nuclear@0
|
45
|
nuclear@3
|
46 /*glGenTextures(1, &tex);
|
nuclear@3
|
47 glBindTexture(GL_TEXTURE_2D, tex);*/
|
nuclear@3
|
48 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
nuclear@3
|
49 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
nuclear@3
|
50 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
nuclear@3
|
51 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
nuclear@3
|
52 glTexImage2D(GL_TEXTURE_2D, 0, 4, xsz, ysz, 0, GL_RGBA, GL_FLOAT, 0);
|
nuclear@2
|
53
|
nuclear@3
|
54 glutMainLoop();
|
nuclear@0
|
55 return 0;
|
nuclear@0
|
56 }
|
nuclear@2
|
57
|
nuclear@3
|
58 void cleanup()
|
nuclear@2
|
59 {
|
nuclear@3
|
60 delete [] fb;
|
nuclear@3
|
61 destroy_renderer();
|
nuclear@3
|
62 }
|
nuclear@2
|
63
|
nuclear@3
|
64 void disp()
|
nuclear@3
|
65 {
|
nuclear@3
|
66 if(need_update) {
|
nuclear@3
|
67 render();
|
nuclear@3
|
68 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, xsz, ysz, GL_RGBA, GL_FLOAT, fb);
|
nuclear@3
|
69 need_update = false;
|
nuclear@3
|
70 }
|
nuclear@2
|
71
|
nuclear@3
|
72 glEnable(GL_TEXTURE_2D);
|
nuclear@2
|
73
|
nuclear@3
|
74 glBegin(GL_QUADS);
|
nuclear@3
|
75 glTexCoord2f(0, 1); glVertex2f(-1, -1);
|
nuclear@3
|
76 glTexCoord2f(1, 1); glVertex2f(1, -1);
|
nuclear@3
|
77 glTexCoord2f(1, 0); glVertex2f(1, 1);
|
nuclear@3
|
78 glTexCoord2f(0, 0); glVertex2f(-1, 1);
|
nuclear@3
|
79 glEnd();
|
nuclear@2
|
80
|
nuclear@3
|
81 glDisable(GL_TEXTURE_2D);
|
nuclear@3
|
82
|
nuclear@3
|
83 glutSwapBuffers();
|
nuclear@3
|
84 }
|
nuclear@3
|
85
|
nuclear@3
|
86 void reshape(int x, int y)
|
nuclear@3
|
87 {
|
nuclear@3
|
88 glViewport(0, 0, x, y);
|
nuclear@3
|
89
|
nuclear@3
|
90 /* reallocate the framebuffer */
|
nuclear@3
|
91 /*delete [] fb;
|
nuclear@3
|
92 fb = new float[x * y * 4];
|
nuclear@3
|
93 set_framebuffer(fb, x, y);*/
|
nuclear@3
|
94 }
|
nuclear@3
|
95
|
nuclear@3
|
96 void keyb(unsigned char key, int x, int y)
|
nuclear@3
|
97 {
|
nuclear@3
|
98 switch(key) {
|
nuclear@3
|
99 case 27:
|
nuclear@3
|
100 exit(0);
|
nuclear@3
|
101
|
nuclear@3
|
102 case 's':
|
nuclear@3
|
103 if(write_ppm("shot.ppm", fb, xsz, ysz)) {
|
nuclear@3
|
104 printf("captured screenshot shot.ppm\n");
|
nuclear@3
|
105 }
|
nuclear@3
|
106 break;
|
nuclear@3
|
107
|
nuclear@3
|
108 case 'r':
|
nuclear@3
|
109 need_update = true;
|
nuclear@3
|
110 glutPostRedisplay();
|
nuclear@3
|
111 break;
|
nuclear@3
|
112
|
nuclear@3
|
113 default:
|
nuclear@3
|
114 break;
|
nuclear@3
|
115 }
|
nuclear@3
|
116 }
|
nuclear@3
|
117
|
nuclear@3
|
118 void mouse(int bn, int state, int x, int y)
|
nuclear@3
|
119 {
|
nuclear@3
|
120 }
|
nuclear@3
|
121
|
nuclear@3
|
122 void motion(int x, int y)
|
nuclear@3
|
123 {
|
nuclear@2
|
124 }
|
nuclear@2
|
125
|
nuclear@2
|
126 bool write_ppm(const char *fname, float *fb, int xsz, int ysz)
|
nuclear@2
|
127 {
|
nuclear@2
|
128 FILE *fp;
|
nuclear@2
|
129
|
nuclear@2
|
130 if(!(fp = fopen(fname, "wb"))) {
|
nuclear@2
|
131 fprintf(stderr, "write_ppm: failed to open file %s for writing: %s\n", fname, strerror(errno));
|
nuclear@2
|
132 return false;
|
nuclear@2
|
133 }
|
nuclear@2
|
134 fprintf(fp, "P6\n%d %d\n255\n", xsz, ysz);
|
nuclear@2
|
135
|
nuclear@2
|
136 for(int i=0; i<xsz * ysz * 4; i++) {
|
nuclear@2
|
137 if(i % 4 == 3) continue;
|
nuclear@2
|
138
|
nuclear@2
|
139 unsigned char c = (unsigned char)(fb[i] * 255.0);
|
nuclear@2
|
140 fputc(c, fp);
|
nuclear@2
|
141 }
|
nuclear@2
|
142 fclose(fp);
|
nuclear@2
|
143 return true;
|
nuclear@2
|
144 }
|