fix texture loading
[cltracer.git] / interactive.c
blob1d748bc5c23e92a8f2960fe8a5f539233dbbcb0f
1 /*
2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation, either version 3 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 * Copyright (C) 2010 Pavel Herrmann (morpheus.ibis@gmail.com)
19 #include "shared.h"
20 #include "conf.h"
21 #include "ocl.h"
22 #include "interactive.h"
23 #include <GL/freeglut.h>
24 #include <CL/cl.h>
25 #include <CL/cl_gl.h>
26 #include <GL/glx.h>
27 #include <stdio.h>
28 #include <math.h>
30 #define STEP 0.5f
32 void glGenBuffers(GLsizei, GLuint*);
33 void glBindBuffer(GLenum,GLuint);
34 void glDeleteBuffers(GLsizei, GLuint*);
35 void glBufferData(GLenum, GLsizeiptr, const GLvoid *, GLenum);
38 GLuint gl_out;
39 GLuint gl_pbo;
40 cl_mem cl_pbo;
41 int change=1;
44 extern cl_context ctx;
45 extern cl_command_queue cq;
46 extern cl_platform_id pid;
47 extern cl_device_id device;
48 extern cl_mem pixels;
49 extern cl_kernel tools_copytex_kern;
50 extern cl_event trace;
51 extern cl_event shade;
52 extern size_t gwsize[2];
53 extern size_t imgsize[2];
57 int opencl_prepare_gl()
59 error = clGetPlatformIDs(1,&pid,NULL); ERRCHECK
60 error = clGetDeviceIDs(pid,CL_DEVICE_TYPE_GPU,1,&device,NULL); ERRCHECK
61 cl_context_properties ctxprop[] =
63 CL_GL_CONTEXT_KHR, (cl_context_properties)glXGetCurrentContext(),
64 CL_GLX_DISPLAY_KHR, (cl_context_properties)glXGetCurrentDisplay(),
65 CL_CONTEXT_PLATFORM, (cl_context_properties)pid,
68 ctx = clCreateContext(ctxprop,1,&device,NULL,NULL,&error); ERRCHECK
69 cq = clCreateCommandQueue(ctx, device,0,&error); ERRCHECK
70 return 0;
71 cleanup:
72 return error;
75 int copy_texture(int2 curtile)
77 glFinish();
78 gwsize[0]=tilesize[0];
79 gwsize[1]=tilesize[1];
80 cl_int rowlen = tilesize[0]*tiles.x;
81 error=clEnqueueAcquireGLObjects(cq,1,&cl_pbo,0,NULL,&shade); ERRCHECK
82 error=clSetKernelArg(tools_copytex_kern,0,sizeof(cl_mem),&pixels); ERRCHECK
83 error=clSetKernelArg(tools_copytex_kern,1,sizeof(cl_int2),&curtile); ERRCHECK
84 error=clSetKernelArg(tools_copytex_kern,2,sizeof(cl_int),&rowlen); ERRCHECK
85 error=clSetKernelArg(tools_copytex_kern,3,sizeof(cl_mem),&cl_pbo); ERRCHECK
86 error=clEnqueueNDRangeKernel(cq,tools_copytex_kern,2,NULL,gwsize,lwsize,1,&shade,&trace); ERRCHECK
87 error=clWaitForEvents(1,&trace); ERRCHECK
88 error=clEnqueueReleaseGLObjects(cq,1,&cl_pbo,1,&trace,&shade); ERRCHECK
89 error=clWaitForEvents(1,&shade); ERRCHECK
90 error=clFinish(cq); ERRCHECK
91 printf("image-to-pbo complete\n");
92 glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, gl_pbo);
93 glBindTexture(GL_TEXTURE_2D,gl_out);
94 glTexSubImage2D(GL_TEXTURE_2D,0,tilesize[0]*curtile.x,tilesize[1]*curtile.y,tilesize[0],tilesize[1],GL_RGBA,GL_UNSIGNED_BYTE,NULL);
95 return 0;
96 cleanup:
97 return error;
102 void gl_display(void)
104 if (change)
106 cl_int2 curtile;
107 for (curtile.y=0; curtile.y<tiles.y; curtile.y++)
109 for (curtile.x=0; curtile.x<tiles.x; curtile.x++)
111 opencl_display(curtile);
112 copy_texture(curtile);
115 change=0;
118 glClear(GL_COLOR_BUFFER_BIT);
119 glEnable(GL_TEXTURE_2D);
120 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
121 glBindTexture(GL_TEXTURE_2D,gl_out);
123 glBegin(GL_QUADS);
124 glTexCoord2i(0,0);
125 glVertex2i(0,0);
126 glTexCoord2i(0,1);
127 glVertex2i(0,1);
128 glTexCoord2i(1,1);
129 glVertex2i(1,1);
130 glTexCoord2i(1,0);
131 glVertex2i(1,0);
132 glEnd();
133 glBindTexture(GL_TEXTURE_2D,0);
135 glFlush();
136 glFinish();
137 glutSwapBuffers();
141 void normalize (float3 * vec)
143 float len = sqrt(vec->x*vec->x + vec->y*vec->y + vec->z*vec->z);
144 vec->x/=len;
145 vec->y/=len;
146 vec->z/=len;
149 void gl_key(unsigned char c, int x, int y)
151 float3 sidevector;
152 float3 forvector;
153 float3 upvector=current_frame->upvector;
156 forvector.x=current_frame->lookat.x - current_frame->eyepoint.x;
157 forvector.y=current_frame->lookat.y - current_frame->eyepoint.y;
158 forvector.z=current_frame->lookat.z - current_frame->eyepoint.z;
160 sidevector.x=upvector.y*forvector.z - upvector.z*forvector.y;
161 sidevector.y=upvector.z*forvector.x - upvector.x*forvector.z;
162 sidevector.z=upvector.x*forvector.y - upvector.y*forvector.x;
165 forvector.x=upvector.z*sidevector.y - upvector.y*sidevector.z;
166 forvector.y=upvector.x*sidevector.z - upvector.z*sidevector.x;
167 forvector.z=upvector.y*sidevector.x - upvector.x*sidevector.y;
170 normalize(&sidevector);
171 normalize(&forvector);
172 normalize(&upvector);
174 switch (c)
176 case 'q':
177 glutLeaveMainLoop();
178 return;
179 case 'w':
180 current_frame->lookat.x+=STEP*forvector.x;
181 current_frame->lookat.y+=STEP*forvector.y;
182 current_frame->lookat.z+=STEP*forvector.z;
183 current_frame->eyepoint.x+=STEP*forvector.x;
184 current_frame->eyepoint.y+=STEP*forvector.y;
185 current_frame->eyepoint.z+=STEP*forvector.z;
186 break;
187 case 's':
188 current_frame->lookat.x+=STEP*forvector.x;
189 current_frame->lookat.y+=STEP*forvector.y;
190 current_frame->lookat.z+=STEP*forvector.z;
191 current_frame->eyepoint.x-=STEP*forvector.x;
192 current_frame->eyepoint.y-=STEP*forvector.y;
193 current_frame->eyepoint.z-=STEP*forvector.z;
194 break;
195 case 'a':
196 current_frame->eyepoint.x+=STEP*sidevector.x;
197 current_frame->eyepoint.y+=STEP*sidevector.y;
198 current_frame->eyepoint.z+=STEP*sidevector.z;
199 case 'z':
200 current_frame->lookat.x+=STEP*sidevector.x;
201 current_frame->lookat.y+=STEP*sidevector.y;
202 current_frame->lookat.z+=STEP*sidevector.z;
203 break;
204 case 'd':
205 current_frame->eyepoint.x-=STEP*sidevector.x;
206 current_frame->eyepoint.y-=STEP*sidevector.y;
207 current_frame->eyepoint.z-=STEP*sidevector.z;
208 case 'x':
209 current_frame->lookat.x-=STEP*sidevector.x;
210 current_frame->lookat.y-=STEP*sidevector.y;
211 current_frame->lookat.z-=STEP*sidevector.z;
212 break;
213 case 'e':
214 current_frame->lookat.x+=STEP*upvector.x;
215 current_frame->lookat.y+=STEP*upvector.y;
216 current_frame->lookat.z+=STEP*upvector.z;
217 current_frame->eyepoint.x+=STEP*upvector.x;
218 current_frame->eyepoint.y+=STEP*upvector.y;
219 current_frame->eyepoint.z+=STEP*upvector.z;
220 break;
221 case 'c':
222 current_frame->lookat.x-=STEP*upvector.x;
223 current_frame->lookat.y-=STEP*upvector.y;
224 current_frame->lookat.z-=STEP*upvector.z;
225 current_frame->eyepoint.x-=STEP*upvector.x;
226 current_frame->eyepoint.y-=STEP*upvector.y;
227 current_frame->eyepoint.z-=STEP*upvector.z;
228 break;
229 default:
230 return;
232 change=1;
233 glutPostRedisplay();
237 void gl_timer(int i)
239 glutPostRedisplay();
240 glutTimerFunc(100,gl_timer,i);
244 void interactive_run(int * argc, char** argv )
246 glutInit(argc,argv);
247 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
248 glutInitWindowSize(imgsize[0], imgsize[1]);
249 glutCreateWindow("clTracer");
251 error=opencl_prepare_gl(); ERRCHECK
252 error=prepare_buffers_kernels(); ERRCHECK
254 glutDisplayFunc(gl_display);
255 glutKeyboardFunc(gl_key);
256 glutTimerFunc(100,gl_timer,0);
257 glViewport(0, 0, imgsize[0],imgsize[1]);
258 glMatrixMode(GL_PROJECTION);
259 glLoadIdentity();
260 glOrtho(0,1,0,1,0,100);
261 glClearColor(0.0f,0.0f,0.0f,0.0f);
262 glGenTextures(1, &gl_out);
263 glBindTexture(GL_TEXTURE_2D,gl_out);
264 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
265 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
266 glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,imgsize[0],imgsize[1],0,GL_RGBA,GL_UNSIGNED_BYTE,NULL);
267 glBindTexture(GL_TEXTURE_2D,0);
268 glGenBuffers(1, &gl_pbo);
269 glBindBuffer(GL_ARRAY_BUFFER,gl_pbo);
270 glBufferData(GL_ARRAY_BUFFER,tilesize[0]*tilesize[1]*sizeof(cl_uchar4), NULL, GL_DYNAMIC_DRAW);
272 glBindBuffer(GL_ARRAY_BUFFER,0);
273 glFinish();
275 cl_pbo=clCreateFromGLBuffer(ctx, CL_MEM_READ_WRITE,gl_pbo,&error); ERRCHECK;
276 error=clFinish(cq); ERRCHECK
278 glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
279 glutMainLoop();
281 cleanup:
282 if (cl_pbo!=NULL)
284 clReleaseMemObject(cl_pbo);
285 cl_pbo=NULL;
287 glDeleteBuffers(1,&gl_pbo);
288 glDeleteBuffers(1,&gl_out);