clray
diff src/clray.cc @ 3:88ac4eb2d18a
added OpenGL display of the framebuffer
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 13 Jul 2010 03:38:29 +0300 |
parents | 41d6253492ad |
children | deaf85acf6af |
line diff
1.1 --- a/src/clray.cc Mon Jul 12 10:38:07 2010 +0300 1.2 +++ b/src/clray.cc Tue Jul 13 03:38:29 2010 +0300 1.3 @@ -1,94 +1,126 @@ 1.4 #include <stdio.h> 1.5 +#include <stdlib.h> 1.6 #include <string.h> 1.7 -#include <math.h> 1.8 #include <errno.h> 1.9 -#include <assert.h> 1.10 -#include "ocl.h" 1.11 +#ifndef __APPLE__ 1.12 +#include <GL/glut.h> 1.13 +#else 1.14 +#include <GLUT/glut.h> 1.15 +#endif 1.16 +#include "rt.h" 1.17 1.18 -struct RendInfo { 1.19 - int xsz, ysz; 1.20 - int num_sph; 1.21 - int max_iter; 1.22 -} __attribute__((packed)); 1.23 - 1.24 -struct Sphere { 1.25 - cl_float4 pos; 1.26 - cl_float radius; 1.27 - 1.28 - cl_float4 color; 1.29 -} __attribute__((packed)); 1.30 - 1.31 -struct Ray { 1.32 - cl_float4 origin, dir; 1.33 -} __attribute__((packed)); 1.34 - 1.35 - 1.36 -Ray get_primary_ray(int x, int y, int w, int h, float vfov_deg); 1.37 +void cleanup(); 1.38 +void disp(); 1.39 +void reshape(int x, int y); 1.40 +void keyb(unsigned char key, int x, int y); 1.41 +void mouse(int bn, int status, int x, int y); 1.42 +void motion(int x, int y); 1.43 bool write_ppm(const char *fname, float *fb, int xsz, int ysz); 1.44 1.45 -int main() 1.46 +static float *fb; 1.47 +static int xsz, ysz; 1.48 +static bool need_update = true; 1.49 + 1.50 +int main(int argc, char **argv) 1.51 { 1.52 - const int xsz = 800; 1.53 - const int ysz = 600; 1.54 + glutInitWindowSize(800, 600); 1.55 + glutInit(&argc, argv); 1.56 + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); 1.57 + glutCreateWindow("OpenCL Raytracer"); 1.58 1.59 - Sphere sphlist[] = { 1.60 - {{0, 0, 10, 1}, 1.0, {1, 0, 0, 1}} 1.61 - }; 1.62 - RendInfo rinf = {xsz, ysz, sizeof sphlist / sizeof *sphlist, 6}; 1.63 - Ray *prim_rays = new Ray[xsz * ysz]; 1.64 - float *fb = new float[xsz * ysz * 4]; 1.65 + xsz = glutGet(GLUT_WINDOW_WIDTH); 1.66 + ysz = glutGet(GLUT_WINDOW_HEIGHT); 1.67 1.68 - /* calculate primary rays */ 1.69 - for(int i=0; i<ysz; i++) { 1.70 - for(int j=0; j<xsz; j++) { 1.71 - prim_rays[i * xsz + j] = get_primary_ray(j, i, xsz, ysz, 45.0); 1.72 - } 1.73 - } 1.74 + glutDisplayFunc(disp); 1.75 + glutReshapeFunc(reshape); 1.76 + glutKeyboardFunc(keyb); 1.77 + glutMouseFunc(mouse); 1.78 + glutMotionFunc(motion); 1.79 1.80 - /* setup opencl */ 1.81 - CLProgram prog("render"); 1.82 - if(!prog.load("rt.cl")) { 1.83 + fb = new float[xsz * ysz * 4]; 1.84 + if(!init_renderer(xsz, ysz, fb)) { 1.85 return 1; 1.86 } 1.87 + atexit(cleanup); 1.88 1.89 - prog.set_arg_buffer(0, ARG_WR, xsz * ysz * 4 * sizeof(float), fb); 1.90 - prog.set_arg_buffer(1, ARG_RD, sizeof rinf, &rinf); 1.91 - prog.set_arg_buffer(2, ARG_RD, sizeof sphlist, sphlist); 1.92 - prog.set_arg_buffer(3, ARG_RD, xsz * ysz * sizeof *prim_rays, prim_rays); 1.93 + /*glGenTextures(1, &tex); 1.94 + glBindTexture(GL_TEXTURE_2D, tex);*/ 1.95 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); 1.96 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); 1.97 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1.98 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1.99 + glTexImage2D(GL_TEXTURE_2D, 0, 4, xsz, ysz, 0, GL_RGBA, GL_FLOAT, 0); 1.100 1.101 - if(!prog.run(1, xsz * ysz)) { 1.102 - return 1; 1.103 - } 1.104 - 1.105 - CLMemBuffer *mbuf = prog.get_arg_buffer(0); 1.106 - map_mem_buffer(mbuf, MAP_RD); 1.107 - if(!write_ppm("out.ppm", fb, xsz, ysz)) { 1.108 - return 1; 1.109 - } 1.110 - unmap_mem_buffer(mbuf); 1.111 - 1.112 - delete [] fb; 1.113 - delete [] prim_rays; 1.114 - 1.115 + glutMainLoop(); 1.116 return 0; 1.117 } 1.118 1.119 -Ray get_primary_ray(int x, int y, int w, int h, float vfov_deg) 1.120 +void cleanup() 1.121 { 1.122 - float vfov = M_PI * vfov_deg / 180.0; 1.123 - float aspect = (float)w / (float)h; 1.124 + delete [] fb; 1.125 + destroy_renderer(); 1.126 +} 1.127 1.128 - float ysz = 2.0; 1.129 - float xsz = aspect * ysz; 1.130 +void disp() 1.131 +{ 1.132 + if(need_update) { 1.133 + render(); 1.134 + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, xsz, ysz, GL_RGBA, GL_FLOAT, fb); 1.135 + need_update = false; 1.136 + } 1.137 1.138 - float px = ((float)x / (float)w) * xsz - xsz / 2.0; 1.139 - float py = 1.0 - ((float)y / (float)h) * ysz; 1.140 - float pz = 1.0 / tan(0.5 * vfov); 1.141 + glEnable(GL_TEXTURE_2D); 1.142 1.143 - pz *= 1000.0; 1.144 + glBegin(GL_QUADS); 1.145 + glTexCoord2f(0, 1); glVertex2f(-1, -1); 1.146 + glTexCoord2f(1, 1); glVertex2f(1, -1); 1.147 + glTexCoord2f(1, 0); glVertex2f(1, 1); 1.148 + glTexCoord2f(0, 0); glVertex2f(-1, 1); 1.149 + glEnd(); 1.150 1.151 - Ray ray = {{0, 0, 0, 1}, {px, py, pz, 1}}; 1.152 - return ray; 1.153 + glDisable(GL_TEXTURE_2D); 1.154 + 1.155 + glutSwapBuffers(); 1.156 +} 1.157 + 1.158 +void reshape(int x, int y) 1.159 +{ 1.160 + glViewport(0, 0, x, y); 1.161 + 1.162 + /* reallocate the framebuffer */ 1.163 + /*delete [] fb; 1.164 + fb = new float[x * y * 4]; 1.165 + set_framebuffer(fb, x, y);*/ 1.166 +} 1.167 + 1.168 +void keyb(unsigned char key, int x, int y) 1.169 +{ 1.170 + switch(key) { 1.171 + case 27: 1.172 + exit(0); 1.173 + 1.174 + case 's': 1.175 + if(write_ppm("shot.ppm", fb, xsz, ysz)) { 1.176 + printf("captured screenshot shot.ppm\n"); 1.177 + } 1.178 + break; 1.179 + 1.180 + case 'r': 1.181 + need_update = true; 1.182 + glutPostRedisplay(); 1.183 + break; 1.184 + 1.185 + default: 1.186 + break; 1.187 + } 1.188 +} 1.189 + 1.190 +void mouse(int bn, int state, int x, int y) 1.191 +{ 1.192 +} 1.193 + 1.194 +void motion(int x, int y) 1.195 +{ 1.196 } 1.197 1.198 bool write_ppm(const char *fname, float *fb, int xsz, int ysz)