~ubuntu-branches/ubuntu/oneiric/mesa-demos/oneiric

« back to all changes in this revision

Viewing changes to src/glsl/vsraytrace.c

  • Committer: Bazaar Package Importer
  • Author(s): Christopher James Halse Rogers
  • Date: 2010-09-27 16:18:27 UTC
  • Revision ID: james.westby@ubuntu.com-20100927161827-1yfgolc1oy9sjhi8
Tags: upstream-8.0.1
ImportĀ upstreamĀ versionĀ 8.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- mode: c; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; coding: utf-8-unix -*- */
 
2
/*
 
3
  Copyright (c) 2010 KristĆ³f Ralovich
 
4
 
 
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
 
6
  of this software and associated documentation files (the "Software"), to deal
 
7
  in the Software without restriction, including without limitation the rights
 
8
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
9
  copies of the Software, and to permit persons to whom the Software is
 
10
  furnished to do so, subject to the following conditions:
 
11
 
 
12
  The above copyright notice and this permission notice shall be included in
 
13
  all copies or substantial portions of the Software.
 
14
 
 
15
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
16
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
17
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
18
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
21
  THE SOFTWARE.
 
22
*/
 
23
 
 
24
 
 
25
#include <stdio.h>
 
26
#include <stdlib.h>
 
27
#include <GL/glew.h>
 
28
#include <GL/glut.h>
 
29
#include "shaderutil.h"
 
30
#include <math.h>
 
31
 
 
32
static int Win;
 
33
static int WinWidth = 256, WinHeight = 256;
 
34
static GLboolean mouseGrabbed = GL_FALSE;
 
35
static GLuint vertShader;
 
36
static GLuint program;
 
37
float rot[9] = {1,0,0,  0,1,0,   0,0,1};
 
38
 
 
39
static const char* vsSource =
 
40
  "const float INF     = 9999.9;                                       \n"
 
41
  "const float EPSILON = 0.00001;                                      \n"
 
42
  "const vec3 lightPos = vec3(0.0, 8.0, 1.0);                          \n"
 
43
  "const vec4 backgroundColor = vec4(0.2,0.3,0.4,1);                   \n"
 
44
  "                                                                    \n"
 
45
  "uniform mat3 rot;                                                   \n"
 
46
  "                                                                    \n"
 
47
  "struct Ray                                                          \n"
 
48
  "{                                                                   \n"
 
49
  "vec3 orig;                                                          \n"
 
50
  "vec3 dir;                                                           \n"
 
51
  "};                                                                  \n"
 
52
  "                                                                    \n"
 
53
  "struct Sphere                                                       \n"
 
54
  "{                                                                   \n"
 
55
  "  vec3 c;                                                           \n"
 
56
  "  float r;                                                          \n"
 
57
  "};                                                                  \n"
 
58
  "                                                                    \n"
 
59
  "struct Isec                                                         \n"
 
60
  "{                                                                   \n"
 
61
  "  float t;                                                          \n"
 
62
  "  int idx;                                                          \n"
 
63
  "  vec3 hit;                                                         \n"
 
64
  "  vec3 n;                                                           \n"
 
65
  "};                                                                  \n"
 
66
  "                                                                    \n"
 
67
#ifdef __APPLE__
 
68
  "Sphere spheres0 = Sphere( vec3(0.0,0.0,-1.0), 0.5 );                \n"
 
69
  "Sphere spheres1 = Sphere( vec3(-3.0,0.0,-1.0), 1.5 );               \n"
 
70
  "Sphere spheres2 = Sphere( vec3(0.0,3.0,-1.0), 0.5 );                \n"
 
71
  "Sphere spheres3 = Sphere( vec3(2.0,0.0,-1.0), 1.0 );                \n"
 
72
#else
 
73
  "const Sphere spheres0 = Sphere( vec3(0.0,0.0,-1.0), 0.5 );          \n"
 
74
  "const Sphere spheres1 = Sphere( vec3(-3.0,0.0,-1.0), 1.5 );         \n"
 
75
  "const Sphere spheres2 = Sphere( vec3(0.0,3.0,-1.0), 0.5 );          \n"
 
76
  "const Sphere spheres3 = Sphere( vec3(2.0,0.0,-1.0), 1.0 );          \n"
 
77
#endif
 
78
  "                                                                    \n"
 
79
  "// Mesa intel gen4 generates \"unsupported IR in fragment shader 13\" for\n"
 
80
  "// sqrt, let's work around.                                         \n"
 
81
  "float                                                               \n"
 
82
  "sqrt_hack(float f2)                                                 \n"
 
83
  "{                                                                   \n"
 
84
  "  vec3 v = vec3(f2,0.0,0.0);                                        \n"
 
85
  "  return length(v);                                                 \n"
 
86
  "}                                                                   \n"
 
87
  "                                                                    \n"
 
88
  "void                                                                \n"
 
89
  "intersect(const in Ray ray,                                         \n"
 
90
  "          const in Sphere sph,                                      \n"
 
91
  "          const in int idx,                                         \n"
 
92
  "          inout Isec isec)                                          \n"
 
93
  "{                                                                   \n"
 
94
  "  // Project both o and the sphere to the plane perpendicular to d  \n"
 
95
  "  // and containing c. Let x be the point where the ray intersects  \n"
 
96
  "  // the plane. If |x-c| < r, the ray intersects the sphere.        \n"
 
97
  "  vec3 o = ray.orig;                                                \n"
 
98
  "  vec3 d = ray.dir;                                                 \n"
 
99
  "  vec3 n = -d;                                                      \n"
 
100
  "  vec3 c = sph.c;                                                   \n"
 
101
  "  float r = sph.r;                                                  \n"
 
102
  "  float t = dot(c-o,n)/dot(n,d);                                    \n"
 
103
  "  vec3 x = o+d*t;                                                   \n"
 
104
  "  float e = length(x-c);                                            \n"
 
105
  "  if(e > r)                                                         \n"
 
106
  "  {                                                                 \n"
 
107
  "    // no intersection                                              \n"
 
108
  "    return;                                                         \n"
 
109
  "  }                                                                 \n"
 
110
  "                                                                    \n"
 
111
  "  // Apply Pythagorean theorem on the (intersection,x,c) triangle   \n"
 
112
  "  // to get the distance between c and the intersection.            \n"
 
113
  "#define BUGGY_INTEL_GEN4_GLSL 1                                     \n"
 
114
  "#ifndef BUGGY_INTEL_GEN4_GLSL                                       \n"
 
115
  "  float f = sqrt(r*r - e*e);                                        \n"
 
116
  "#else                                                               \n"
 
117
  "  float f = sqrt_hack(r*r - e*e);                                   \n"
 
118
  "#endif                                                              \n"
 
119
  "  float dist = t - f;                                               \n"
 
120
  "  if(dist < 0.0)                                                    \n"
 
121
  "  {                                                                 \n"
 
122
  "    // inside the sphere                                            \n"
 
123
  "    return;                                                         \n"
 
124
  "  }                                                                 \n"
 
125
  "                                                                    \n"
 
126
  "  if(dist < EPSILON)                                                \n"
 
127
  "    return;                                                         \n"
 
128
  "                                                                    \n"
 
129
  "  if(dist > isec.t)                                                 \n"
 
130
  "    return;                                                         \n"
 
131
  "                                                                    \n"
 
132
  "  isec.t = dist;                                                    \n"
 
133
  "  isec.idx = idx;                                                   \n"
 
134
  "                                                                    \n"
 
135
  "  isec.hit  = ray.orig + ray.dir * isec.t;                          \n"
 
136
  "  isec.n = (isec.hit - c) / r;                                      \n"
 
137
  "}                                                                   \n"
 
138
  "                                                                    \n"
 
139
  "Isec                                                                \n"
 
140
  "intersect(const in Ray ray,                                         \n"
 
141
  "          const in float max_t /*= INF*/)                           \n"
 
142
  "{                                                                   \n"
 
143
  "  Isec nearest;                                                     \n"
 
144
  "  nearest.t = max_t;                                                \n"
 
145
  "  nearest.idx = -1;                                                 \n"
 
146
  "                                                                    \n"
 
147
  "  intersect(ray, spheres0, 0, nearest);                             \n"
 
148
  "  intersect(ray, spheres1, 1, nearest);                             \n"
 
149
  "  intersect(ray, spheres2, 2, nearest);                             \n"
 
150
  "  intersect(ray, spheres3, 3, nearest);                             \n"
 
151
  "                                                                    \n"
 
152
  "  return nearest;                                                   \n"
 
153
  "}                                                                   \n"
 
154
  "                                                                    \n"
 
155
  "vec4                                                                \n"
 
156
  "idx2color(const in int idx)                                         \n"
 
157
  "{                                                                   \n"
 
158
  "  vec4 diff;                                                        \n"
 
159
  "  if(idx == 0)                                                      \n"
 
160
  "    diff = vec4(1.0, 0.0, 0.0, 0.0);                                \n"
 
161
  "  else if(idx == 1)                                                 \n"
 
162
  "    diff = vec4(0.0, 1.0, 0.0, 0.0);                                \n"
 
163
  "  else if(idx == 2)                                                 \n"
 
164
  "    diff = vec4(0.0, 0.0, 1.0, 0.0);                                \n"
 
165
  "  else if(idx == 3)                                                 \n"
 
166
  "    diff = vec4(1.0, 1.0, 0.0, 0.0);                                \n"
 
167
  "  return diff;                                                      \n"
 
168
  "}                                                                   \n"
 
169
  "                                                                    \n"
 
170
  "vec4                                                                \n"
 
171
  "trace0(const in Ray ray)                                            \n"
 
172
  "{                                                                   \n"
 
173
  "  Isec isec = intersect(ray, INF);                                  \n"
 
174
  "                                                                    \n"
 
175
  "  if(isec.idx == -1)                                                \n"
 
176
  "  {                                                                 \n"
 
177
  "    return backgroundColor;                                         \n"
 
178
  "  }                                                                 \n"
 
179
  "                                                                    \n"
 
180
  "  vec4 diff = idx2color(isec.idx);                                  \n"
 
181
  "                                                                    \n"
 
182
  "  vec3 N = isec.n;                                                  \n"
 
183
  "  vec3 L = normalize(lightPos-isec.hit);                            \n"
 
184
  "  vec3 camera_dir = normalize(ray.orig - isec.hit);                 \n"
 
185
  "  return dot(N,L)*diff + pow(                                       \n"
 
186
  "    clamp(dot(reflect(-L,N),camera_dir),0.0,1.0),16.0);             \n"
 
187
  "}                                                                   \n"
 
188
  "                                                                    \n"
 
189
  "vec4                                                                \n"
 
190
  "trace1(const in Ray ray)                                            \n"
 
191
  "{                                                                   \n"
 
192
  "  Isec isec = intersect(ray, INF);                                  \n"
 
193
  "                                                                    \n"
 
194
  "  if(isec.idx == -1)                                                \n"
 
195
  "  {                                                                 \n"
 
196
  "    return backgroundColor;                                         \n"
 
197
  "  }                                                                 \n"
 
198
  "                                                                    \n"
 
199
  "  Ray reflRay = Ray(isec.hit, reflect(ray.dir, isec.n));            \n"
 
200
  "                                                                    \n"
 
201
  "  vec4 reflCol = trace0(reflRay);                                   \n"
 
202
  "                                                                    \n"
 
203
  "  vec4 diff = idx2color(isec.idx) + reflCol;                        \n"
 
204
  "                                                                    \n"
 
205
  "  vec3 N = isec.n;                                                  \n"
 
206
  "  vec3 L = normalize(lightPos-isec.hit);                            \n"
 
207
  "  vec3 camera_dir = normalize(ray.orig - isec.hit);                 \n"
 
208
  "  return dot(N,L)*diff + pow(                                       \n"
 
209
  "    clamp(dot(reflect(-L,N),camera_dir),0.0,1.0),16.0);             \n"
 
210
  "}                                                                   \n"
 
211
  "                                                                    \n"
 
212
  "void main()                                                         \n"
 
213
  "{                                                                   \n"
 
214
  "  const vec3 cameraPos = vec3(0,0,3);                               \n"
 
215
  "  vec3 rayDir = normalize(vec3(gl_Vertex.x, gl_Vertex.y, -1.0) * rot);\n"
 
216
  "  Ray ray = Ray(cameraPos, rayDir);                                 \n"
 
217
  "  gl_Position = gl_Vertex;                                          \n"
 
218
  "  gl_FrontColor = trace1(ray);                                      \n"
 
219
  "}\n";
 
220
 
 
221
 
 
222
static
 
223
float
 
224
deg2rad(const float degree)
 
225
{
 
226
  return( degree * 0.017453292519943295769236907684886F);
 
227
}
 
228
 
 
229
static void
 
230
rotate_xy(float* mat3, const float degreesAroundX, const float degreesAroundY)
 
231
{
 
232
  const float rad1 = deg2rad(degreesAroundX);
 
233
  const float c1 = cosf(rad1);
 
234
  const float s1 = sinf(rad1);
 
235
  const float rad2 = deg2rad(degreesAroundY);
 
236
  const float c2 = cosf(rad2);
 
237
  const float s2 = sinf(rad2);
 
238
  mat3[0] = c2;    mat3[3] = 0.0F; mat3[6] = s2;
 
239
  mat3[1] = s1*s2; mat3[4] = c1;   mat3[7] = -s1*c2;
 
240
  mat3[2] = -c1*s2;mat3[5] = s1;   mat3[8] = c1*c2;
 
241
}
 
242
 
 
243
static void
 
244
identity(float* mat3)
 
245
{
 
246
  mat3[0] = 1.0F; mat3[3] = 0.0F; mat3[6] = 0.0F;
 
247
  mat3[1] = 0.0F; mat3[4] = 1.0F; mat3[7] = 0.0F;
 
248
  mat3[2] = 0.0F; mat3[5] = 0.0F; mat3[8] = 1.0F;
 
249
}
 
250
 
 
251
static void
 
252
Draw(void)
 
253
{
 
254
  const float w = 0.5F * WinWidth;
 
255
  const float h = 0.5F * WinHeight;
 
256
  int x,y;
 
257
 
 
258
  GLint location = glGetUniformLocation(program, "rot");
 
259
 
 
260
  glUseProgram(program);
 
261
  glUniformMatrix3fv(location, 1, 0, rot);
 
262
  glBegin(GL_POINTS);
 
263
  for(y = 0; y < WinHeight; y++)
 
264
  {
 
265
    for(x = 0; x < WinWidth; x++)
 
266
    {
 
267
      const float posx = x / w - 1.0F;
 
268
      const float posy = y / h - 1.0F;
 
269
      glVertex2f(posx, posy);
 
270
    }
 
271
  }
 
272
  glEnd();
 
273
  glUseProgram(0);
 
274
 
 
275
  glutSwapBuffers();
 
276
 
 
277
  {
 
278
    static int frames = 0;
 
279
    static int t0 = 0;
 
280
    static int t1 = 0;
 
281
    float dt;
 
282
    frames++;
 
283
    t1 = glutGet(GLUT_ELAPSED_TIME);
 
284
    dt = (float)(t1-t0)/1000.0F;
 
285
    if (dt >= 5.0F)
 
286
    {
 
287
      float fps = (float)frames / dt;
 
288
      printf("%f FPS (%d frames in %f seconds)\n", fps, frames, dt);
 
289
      frames = 0;
 
290
      t0 = t1;
 
291
    }
 
292
  }
 
293
}
 
294
 
 
295
 
 
296
static void
 
297
Reshape(int width, int height)
 
298
{
 
299
  WinWidth = width;
 
300
  WinHeight = height;
 
301
  glViewport(0, 0, width, height);
 
302
  glMatrixMode(GL_PROJECTION);
 
303
  glLoadIdentity();
 
304
  glMatrixMode(GL_MODELVIEW);
 
305
  glLoadIdentity();
 
306
}
 
307
 
 
308
 
 
309
static void
 
310
Key(unsigned char key, int x, int y)
 
311
{
 
312
  if(key == 27)
 
313
  {
 
314
    glutDestroyWindow(Win);
 
315
    exit(0);
 
316
  }
 
317
  glutPostRedisplay();
 
318
}
 
319
 
 
320
 
 
321
static
 
322
void
 
323
drag(int x, int y)
 
324
{
 
325
  float scale = 1.5F;
 
326
  if(mouseGrabbed)
 
327
  {
 
328
    static GLfloat xRot = 0, yRot = 0;
 
329
    xRot = (float)(x - WinWidth/2) / scale;
 
330
    yRot = (float)(y - WinHeight/2) / scale;
 
331
    identity(rot);
 
332
    rotate_xy(rot, yRot, xRot);
 
333
    glutPostRedisplay();
 
334
  }
 
335
}
 
336
 
 
337
 
 
338
static
 
339
void
 
340
mouse(int button, int state, int x, int y)
 
341
{
 
342
  mouseGrabbed = (state == GLUT_DOWN);
 
343
}
 
344
 
 
345
 
 
346
static void
 
347
Init(void)
 
348
{
 
349
  glDisable(GL_DEPTH_TEST);
 
350
 
 
351
  if(!ShadersSupported())
 
352
  {
 
353
    fprintf(stderr, "Shaders are not supported!\n");
 
354
    exit(-1);
 
355
  }
 
356
 
 
357
  vertShader = CompileShaderText(GL_VERTEX_SHADER, vsSource);
 
358
  program = LinkShaders(vertShader, 0);
 
359
  glUseProgram(0);
 
360
 
 
361
  if(glGetError() != 0)
 
362
  {
 
363
    fprintf(stderr, "Shaders were not loaded!\n");
 
364
    exit(-1);
 
365
  }
 
366
 
 
367
  if(!glIsShader(vertShader))
 
368
  {
 
369
    fprintf(stderr, "Vertex shader failed!\n");
 
370
    exit(-1);
 
371
  }
 
372
 
 
373
  if(!glIsProgram(program))
 
374
  {
 
375
    fprintf(stderr, "Shader program failed!\n");
 
376
    exit(-1);
 
377
  }
 
378
 
 
379
  printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
 
380
}
 
381
 
 
382
 
 
383
int
 
384
main(int argc, char *argv[])
 
385
{
 
386
  glutInitWindowSize(WinWidth, WinHeight);
 
387
  glutInit(&argc, argv);
 
388
  glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
 
389
  Win = glutCreateWindow(argv[0]);
 
390
  glewInit();
 
391
  glutReshapeFunc(Reshape);
 
392
  glutKeyboardFunc(Key);
 
393
  glutDisplayFunc(Draw);
 
394
  glutIdleFunc(Draw);
 
395
  glutMouseFunc(mouse);
 
396
  glutMotionFunc(drag);
 
397
  Init();
 
398
  glutMainLoop();
 
399
  return 0;
 
400
}
 
401