132001f49Smrg/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */ 232001f49Smrg/* 332001f49Smrg Copyright (c) 2013 Kristóf Ralovich 432001f49Smrg 532001f49Smrg Permission is hereby granted, free of charge, to any person obtaining a copy 632001f49Smrg of this software and associated documentation files (the "Software"), to deal 732001f49Smrg in the Software without restriction, including without limitation the rights 832001f49Smrg to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 932001f49Smrg copies of the Software, and to permit persons to whom the Software is 1032001f49Smrg furnished to do so, subject to the following conditions: 1132001f49Smrg 1232001f49Smrg The above copyright notice and this permission notice shall be included in 1332001f49Smrg all copies or substantial portions of the Software. 1432001f49Smrg 1532001f49Smrg THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1632001f49Smrg IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1732001f49Smrg FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1832001f49Smrg AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1932001f49Smrg LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 2032001f49Smrg OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 2132001f49Smrg THE SOFTWARE. 2232001f49Smrg*/ 2332001f49Smrg 2432001f49Smrg// Simplified version of the algorithm described in 2532001f49Smrg// K. Ralovich, M. Magdics: Recursive Ray Tracing in Geometry Shader, 2632001f49Smrg// Proceedings of the Fifth Hungarian Conference on Computer Graphics and 2732001f49Smrg// Geometry, Budapest, Hungary, 26 Jan 2010. 2832001f49Smrg 2932001f49Smrg#include <stdio.h> 3032001f49Smrg#include <stdlib.h> 3132001f49Smrg#include <GL/glew.h> 3232001f49Smrg#include "glut_wrap.h" 3332001f49Smrg#include "shaderutil.h" 3432001f49Smrg#include <math.h> 3532001f49Smrg#include <stddef.h> // offsetof 3632001f49Smrg 3732001f49Smrg// TODO: port to piglit too 3832001f49Smrg 3932001f49Smrg#define STRINGIFY_(x) #x 4032001f49Smrg#define STRINGIFY(x) STRINGIFY_(x) 4132001f49Smrg#define S__LINE__ STRINGIFY(__LINE__) 4232001f49Smrg 4332001f49Smrgstatic const float INF=9999.9F; 4432001f49Smrg 4532001f49Smrgstatic int Win; 4632001f49Smrgstatic int WinWidth = 256, WinHeight = 256; 4732001f49Smrgstatic GLboolean mouseGrabbed = GL_FALSE; 4832001f49Smrg 4932001f49Smrgstatic GLuint vertShader; 5032001f49Smrgstatic GLuint geomShader; 5132001f49Smrgstatic GLuint fragShader; 5232001f49Smrgstatic GLuint program; 5332001f49Smrg 5432001f49Smrgstatic GLuint pgQuery; 5532001f49Smrg 5632001f49Smrgstatic GLuint dst; 5732001f49Smrgstatic GLuint eyeRaysAsPoints; 5832001f49Smrg 5932001f49Smrgint posAttribLoc; 6032001f49Smrgint orig_tAttribLoc; 6132001f49Smrgint dir_idxAttribLoc; 6232001f49Smrgint uv_stateAttribLoc; 6332001f49Smrgint posVaryingLoc; 6432001f49Smrgint orig_tVaryingLoc; 6532001f49Smrgint dir_idxVaryingLoc; 6632001f49Smrgint uv_stateVaryingLoc; 6732001f49Smrgsize_t nRayGens=3; 6832001f49Smrg 6932001f49Smrgfloat rot[9] = {1,0,0, 0,1,0, 0,0,1}; 7032001f49Smrg 7132001f49Smrgstatic const char* vsSource = 7232001f49Smrg" \n" 7332001f49Smrg"#version 150 core \n" 7432001f49Smrg"#line " S__LINE__ "\n" 7532001f49Smrg"#define SHADOWS \n" 7632001f49Smrg"#define RECURSION \n" 7732001f49Smrg" \n" 7832001f49Smrg"const float INF=9999.9; \n" 7932001f49Smrg"const float EPSILON = 0.00001; \n" 8032001f49Smrg" \n" 8132001f49Smrg"uniform vec3 cameraPos; \n" 8232001f49Smrg"uniform mat3 rot3; \n" 8332001f49Smrg"uniform vec3 lightPos; \n" 8432001f49Smrg"uniform vec4 backgroundColor; \n" 8532001f49Smrg"uniform int emitNoMore; \n" 8632001f49Smrg" \n" 8732001f49Smrg"in vec4 pos; \n" 8832001f49Smrg"in vec4 orig_t; \n" 8932001f49Smrg"in vec4 dir_idx; \n" 9032001f49Smrg"in vec4 uv_state; \n" 9132001f49Smrg"// uv_state.z = state \n" 9232001f49Smrg"// uv_state.w = type (ray generation) \n" 9332001f49Smrg" \n" 9432001f49Smrg"//int state // inFB \n" 9532001f49Smrg"// 0: generation of ray dirs needed \n" 9632001f49Smrg"// 1: do not generate ray dirs, keep in GS, intersect, not in FB\n" 9732001f49Smrg"// 3: cull in next GS, already in FB \n" 9832001f49Smrg"//int type // isShadow \n" 9932001f49Smrg"// -1: not shadow ray, reflected \n" 10032001f49Smrg"// 0: not shadow ray, eye ray \n" 10132001f49Smrg"// 1: shadow ray \n" 10232001f49Smrg" \n" 10332001f49Smrg"out vec4 orig_t1; \n" 10432001f49Smrg"out vec4 dir_idx1; \n" 10532001f49Smrg"out vec4 uv_state1; \n" 10632001f49Smrg" \n" 10732001f49Smrg" \n" 10832001f49Smrg"//----------------------------------------------------------------\n" 10932001f49Smrg" \n" 11032001f49Smrg"struct Ray \n" 11132001f49Smrg"{ \n" 11232001f49Smrg" vec3 orig; \n" 11332001f49Smrg" vec3 dir; \n" 11432001f49Smrg"}; \n" 11532001f49Smrg" \n" 11632001f49Smrg"struct Sphere \n" 11732001f49Smrg"{ \n" 11832001f49Smrg" vec3 c; \n" 11932001f49Smrg" float r; \n" 12032001f49Smrg"}; \n" 12132001f49Smrg" \n" 12232001f49Smrg"struct Isec \n" 12332001f49Smrg"{ \n" 12432001f49Smrg" float t; \n" 12532001f49Smrg" int idx; \n" 12632001f49Smrg" \n" 12732001f49Smrg" vec3 hit; \n" 12832001f49Smrg" vec3 n; \n" 12932001f49Smrg"}; \n" 13032001f49Smrg" \n" 13132001f49Smrg"const Sphere spheres0 = Sphere( vec3(0.0,0.0,-1.0), 0.5 ); \n" 13232001f49Smrg"const Sphere spheres1 = Sphere( vec3(-3.0,0.0,-1.0), 1.5 ); \n" 13332001f49Smrg"const Sphere spheres2 = Sphere( vec3(0.0,3.0,-1.0), 0.5 ); \n" 13432001f49Smrg"const Sphere spheres3 = Sphere( vec3(2.0,0.0,-1.0), 1.0 ); \n" 13532001f49Smrg"const Sphere spheres4 = Sphere( vec3(0.0,-11.0,-1.0), 10.0 ); \n" 13632001f49Smrg"const int nSpheres = 5; \n" 13732001f49Smrg"const Sphere spheres[5]=Sphere[5](spheres0, spheres1, spheres2, spheres3, spheres4);\n" 13832001f49Smrg" \n" 13932001f49Smrg"Isec \n" 14032001f49Smrg"lookupNormal(const in Ray ray, in Isec isec) \n" 14132001f49Smrg"{ \n" 14232001f49Smrg" Sphere sph=spheres[isec.idx]; \n" 14332001f49Smrg" vec3 c = sph.c; \n" 14432001f49Smrg" float r = sph.r; \n" 14532001f49Smrg" isec.hit = ray.orig + ray.dir * isec.t; \n" 14632001f49Smrg" isec.n = (isec.hit - c) / r; \n" 14732001f49Smrg" return isec; \n" 14832001f49Smrg"} \n" 14932001f49Smrg" \n" 15032001f49Smrg"void \n" 15132001f49Smrg"intersect(const in Ray ray, \n" 15232001f49Smrg" const in Sphere sph, \n" 15332001f49Smrg" const in int idx, \n" 15432001f49Smrg" inout Isec isec) \n" 15532001f49Smrg"{ \n" 15632001f49Smrg" // Project both o and the sphere to the plane perpendicular to d\n" 15732001f49Smrg" // and containing c. Let x be the point where the ray intersects\n" 15832001f49Smrg" // the plane. If |x-c| < r, the ray intersects the sphere. \n" 15932001f49Smrg" vec3 o = ray.orig; \n" 16032001f49Smrg" vec3 d = ray.dir; \n" 16132001f49Smrg" vec3 n = -d; \n" 16232001f49Smrg" vec3 c = sph.c; \n" 16332001f49Smrg" float r = sph.r; \n" 16432001f49Smrg" float t = dot(c-o,n)/dot(n,d);//ray parameter for point x \n" 16532001f49Smrg" vec3 x = o+d*t; \n" 16632001f49Smrg" float e = length(x-c); \n" 16732001f49Smrg" if (e > r) \n" 16832001f49Smrg" { \n" 16932001f49Smrg" // no intersection \n" 17032001f49Smrg" return; \n" 17132001f49Smrg" } \n" 17232001f49Smrg" \n" 17332001f49Smrg" // Apply Pythagorean theorem on the (intersection,x,c) triangle \n" 17432001f49Smrg" // to get the distance between c and the intersection. \n" 17532001f49Smrg" float f = sqrt(r*r - e*e); \n" 17632001f49Smrg" float dist = t - f; \n" 17732001f49Smrg" if (dist < 0.0) \n" 17832001f49Smrg" { \n" 17932001f49Smrg" // inside the sphere \n" 18032001f49Smrg" return; \n" 18132001f49Smrg" } \n" 18232001f49Smrg" \n" 18332001f49Smrg" if (dist < EPSILON) \n" 18432001f49Smrg" return; \n" 18532001f49Smrg" \n" 18632001f49Smrg" if (dist > isec.t) \n" 18732001f49Smrg" return; \n" 18832001f49Smrg" \n" 18932001f49Smrg" isec.t = dist; \n" 19032001f49Smrg" isec.idx = idx; \n" 19132001f49Smrg"} \n" 19232001f49Smrg" \n" 19332001f49Smrg"Isec\n" 19432001f49Smrg"intersect_spheres(const in Ray ray,\n" 19532001f49Smrg" const in float max_t /*= INF*/)\n" 19632001f49Smrg"{\n" 19732001f49Smrg" Isec nearest;\n" 19832001f49Smrg" nearest.t = max_t;\n" 19932001f49Smrg" nearest.idx = -1;\n" 20032001f49Smrg"\n" 20132001f49Smrg" intersect(ray, spheres0, 0, nearest);\n" 20232001f49Smrg" intersect(ray, spheres1, 1, nearest);\n" 20332001f49Smrg" intersect(ray, spheres2, 2, nearest);\n" 20432001f49Smrg" intersect(ray, spheres3, 3, nearest);\n" 20532001f49Smrg" intersect(ray, spheres4, 4, nearest); \n" 20632001f49Smrg" \n" 20732001f49Smrg" return nearest; \n" 20832001f49Smrg"} \n" 20932001f49Smrg" \n" 21032001f49Smrg" \n" 21132001f49Smrg" \n" 21232001f49Smrg"//---------------------------------------------------------------------\n" 21332001f49Smrg" \n" 21432001f49Smrg" \n" 21532001f49Smrg" \n" 21632001f49Smrg" \n" 21732001f49Smrg"void \n" 21832001f49Smrg"main() \n" 21932001f49Smrg"{ \n" 22032001f49Smrg" //inVS(); \n" 22132001f49Smrg" Ray ray = Ray(orig_t.xyz, dir_idx.xyz); \n" 22232001f49Smrg" Isec isec = Isec(orig_t.w, int(dir_idx.w), vec3(0,0,0), vec3(0,0,0)); \n" 22332001f49Smrg" int state = int(uv_state.z); \n" 22432001f49Smrg" int type = int(uv_state.w); \n" 22532001f49Smrg" \n" 22632001f49Smrg" if (state == 0) \n" 22732001f49Smrg" { \n" 22832001f49Smrg" // generate eye rays\n" 22932001f49Smrg" ray = Ray(cameraPos, normalize(vec3(pos.x, pos.y, -1.0) * rot3)); \n" 23032001f49Smrg" isec.t = INF;\n" 23132001f49Smrg" isec.idx = -1;\n" 23232001f49Smrg" state = 1;\n" 23332001f49Smrg" type = 0; \n" 23432001f49Smrg" isec = intersect_spheres(ray, isec.t); \n" 23532001f49Smrg" } \n" 23632001f49Smrg"#if defined(SHADOWS) || defined(RECURSION) \n" 23732001f49Smrg" else if (state == 1) \n" 23832001f49Smrg" { \n" 23932001f49Smrg" isec = intersect_spheres(ray, isec.t); \n" 24032001f49Smrg" } \n" 24132001f49Smrg"#endif \n" 24232001f49Smrg" //else state == 3 \n" 24332001f49Smrg" \n" 24432001f49Smrg" //outVS(); \n" 24532001f49Smrg" gl_Position = pos; \n" 24632001f49Smrg" orig_t1.xyz = ray.orig; \n" 24732001f49Smrg" orig_t1.w = isec.t; \n" 24832001f49Smrg" dir_idx1.xyz = ray.dir; \n" 24932001f49Smrg" dir_idx1.w = float(isec.idx); \n" 25032001f49Smrg" uv_state1.z = float(state); \n" 25132001f49Smrg" uv_state1.w = float(type); \n" 25232001f49Smrg"}\n"; 25332001f49Smrg 25432001f49Smrg 25532001f49Smrgstatic const char* gsSource = 25632001f49Smrg"#version 150 core \n" 25732001f49Smrg"#line " S__LINE__ "\n" 25832001f49Smrg"layout(points) in; \n" 25932001f49Smrg"layout(points, max_vertices = 3) out; \n" 26032001f49Smrg" \n" 26132001f49Smrg"#define SHADOWS \n" 26232001f49Smrg"#define RECURSION \n" 26332001f49Smrg" \n" 26432001f49Smrg"const float INF=9999.9; \n" 26532001f49Smrg"const float EPSILON = 0.00001; \n" 26632001f49Smrg" \n" 26732001f49Smrg"uniform vec3 cameraPos; \n" 26832001f49Smrg"uniform mat3 rot3; \n" 26932001f49Smrg"uniform vec3 lightPos; \n" 27032001f49Smrg"uniform vec4 backgroundColor; \n" 27132001f49Smrg"uniform int emitNoMore; \n" 27232001f49Smrg" \n" 27332001f49Smrg" \n" 27432001f49Smrg"//-----------------------------------------------------------------------\n" 27532001f49Smrg" \n" 27632001f49Smrg"struct Ray \n" 27732001f49Smrg"{ \n" 27832001f49Smrg" vec3 orig; \n" 27932001f49Smrg" vec3 dir; \n" 28032001f49Smrg"}; \n" 28132001f49Smrg" \n" 28232001f49Smrg"struct Sphere \n" 28332001f49Smrg"{ \n" 28432001f49Smrg" vec3 c; \n" 28532001f49Smrg" float r; \n" 28632001f49Smrg"}; \n" 28732001f49Smrg" \n" 28832001f49Smrg"struct Isec \n" 28932001f49Smrg"{ \n" 29032001f49Smrg" float t; \n" 29132001f49Smrg" int idx; \n" 29232001f49Smrg" \n" 29332001f49Smrg" vec3 hit; \n" 29432001f49Smrg" vec3 n; \n" 29532001f49Smrg"}; \n" 29632001f49Smrg" \n" 29732001f49Smrg"const Sphere spheres0 = Sphere( vec3(0.0,0.0,-1.0), 0.5 );\n" 29832001f49Smrg"const Sphere spheres1 = Sphere( vec3(-3.0,0.0,-1.0), 1.5 );\n" 29932001f49Smrg"const Sphere spheres2 = Sphere( vec3(0.0,3.0,-1.0), 0.5 );\n" 30032001f49Smrg"const Sphere spheres3 = Sphere( vec3(2.0,0.0,-1.0), 1.0 );\n" 30132001f49Smrg"const Sphere spheres4 = Sphere( vec3(0.0,-11.0,-1.0), 10.0 );\n" 30232001f49Smrg"const int nSpheres = 5;\n" 30332001f49Smrg"const Sphere spheres[5]=Sphere[5](spheres0, spheres1, spheres2, spheres3, spheres4);\n" 30432001f49Smrg" \n" 30532001f49Smrg"Isec \n" 30632001f49Smrg"lookupNormal(const in Ray ray, in Isec isec) \n" 30732001f49Smrg"{ \n" 30832001f49Smrg" Sphere sph=spheres[isec.idx]; \n" 30932001f49Smrg" vec3 c = sph.c; \n" 31032001f49Smrg" float r = sph.r; \n" 31132001f49Smrg" isec.hit = ray.orig + ray.dir * isec.t; \n" 31232001f49Smrg" isec.n = (isec.hit - c) / r; \n" 31332001f49Smrg" return isec; \n" 31432001f49Smrg"} \n" 31532001f49Smrg" \n" 31632001f49Smrg"in vec4 orig_t1[1]; \n" 31732001f49Smrg"in vec4 dir_idx1[1]; \n" 31832001f49Smrg"in vec4 uv_state1[1]; \n" 31932001f49Smrg" \n" 32032001f49Smrg"out vec4 orig_t2; \n" 32132001f49Smrg"out vec4 dir_idx2; \n" 32232001f49Smrg"out vec4 uv_state2; \n" 32332001f49Smrg" \n" 32432001f49Smrg" \n" 32532001f49Smrg"void \n" 32632001f49Smrg"main() \n" 32732001f49Smrg"{ \n" 32832001f49Smrg" //inGS(); \n" 32932001f49Smrg" Ray ray = Ray(orig_t1[0].xyz, dir_idx1[0].xyz); \n" 33032001f49Smrg" Isec isec = Isec(orig_t1[0].w, int(dir_idx1[0].w), vec3(0,0,0), vec3(0,0,0)); \n" 33132001f49Smrg" int state = int(uv_state1[0].z); \n" 33232001f49Smrg" int type = int(uv_state1[0].w); \n" 33332001f49Smrg" \n" 33432001f49Smrg" if (state > 1) \n" 33532001f49Smrg" return; \n" 33632001f49Smrg" \n" 33732001f49Smrg" if (isec.idx == -1) \n" 33832001f49Smrg" return; \n" 33932001f49Smrg" \n" 34032001f49Smrg" // emitPassThrough(); \n" 34132001f49Smrg" gl_Position = gl_in[0].gl_Position; \n" 34232001f49Smrg" orig_t2 = orig_t1[0]; \n" 34332001f49Smrg" dir_idx2 = dir_idx1[0]; \n" 34432001f49Smrg" uv_state2.xyw= uv_state1[0].xyw; \n" 34532001f49Smrg" uv_state2.z = 3.0; /*state*/ \n" 34632001f49Smrg" EmitVertex(); \n" 34732001f49Smrg" EndPrimitive(); \n" 34832001f49Smrg" \n" 34932001f49Smrg" if (type != 0 || emitNoMore>0) \n" 35032001f49Smrg" return; \n" 35132001f49Smrg" \n" 35232001f49Smrg"#if defined(SHADOWS) || defined(RECURSION)\n" 35332001f49Smrg" isec = lookupNormal(ray, isec);\n" 35432001f49Smrg" vec3 hitN = isec.n;\n" 35532001f49Smrg" vec3 hitP = ray.orig + ray.dir*isec.t + hitN*EPSILON;\n" 35632001f49Smrg"#endif \n" 35732001f49Smrg"#ifdef SHADOWS \n" 35832001f49Smrg" vec3 toLight = lightPos - hitP;\n" 35932001f49Smrg" float lightDist = length(toLight);\n" 36032001f49Smrg" Ray shadowRay = Ray(hitP, toLight/lightDist);\n" 36132001f49Smrg" Isec shadowHit = Isec(lightDist, -1, vec3(0,0,0), vec3(0,0,0));\n" 36232001f49Smrg" state = 1; \n" 36332001f49Smrg" type = 1; \n" 36432001f49Smrg" \n" 36532001f49Smrg" //emitShadowRay(); \n" 36632001f49Smrg" gl_Position = gl_in[0].gl_Position; \n" 36732001f49Smrg" orig_t2.xyz = shadowRay.orig; \n" 36832001f49Smrg" orig_t2.w = shadowHit.t; \n" 36932001f49Smrg" dir_idx2.xyz = shadowRay.dir; \n" 37032001f49Smrg" dir_idx2.w = float(shadowHit.idx); \n" 37132001f49Smrg" uv_state2.z = float(state); \n" 37232001f49Smrg" uv_state2.w = float(type); \n" 37332001f49Smrg" EmitVertex(); \n" 37432001f49Smrg" EndPrimitive(); \n" 37532001f49Smrg"#endif \n" 37632001f49Smrg"#ifdef RECURSION \n" 37732001f49Smrg" Ray reflRay = Ray(hitP, reflect(ray.dir, hitN));\n" 37832001f49Smrg" Isec reflHit = Isec(INF, -1, vec3(0,0,0), vec3(0,0,0));\n" 37932001f49Smrg" state = 1; // intersect in next pass, FS discard in this pass\n" 38032001f49Smrg" type = -1; \n" 38132001f49Smrg" \n" 38232001f49Smrg" //emitReflRay(); \n" 38332001f49Smrg" gl_Position = gl_in[0].gl_Position; \n" 38432001f49Smrg" orig_t2.xyz = reflRay.orig; \n" 38532001f49Smrg" orig_t2.w = reflHit.t; \n" 38632001f49Smrg" dir_idx2.xyz = reflRay.dir; \n" 38732001f49Smrg" dir_idx2.w = float(reflHit.idx); \n" 38832001f49Smrg" uv_state2.z = float(state); \n" 38932001f49Smrg" uv_state2.w = float(type); \n" 39032001f49Smrg" EmitVertex(); \n" 39132001f49Smrg" EndPrimitive(); \n" 39232001f49Smrg"#endif\n" 39332001f49Smrg"}\n"; 39432001f49Smrg 39532001f49Smrgstatic const char* fsSource = 39632001f49Smrg"#version 150 core \n" 39732001f49Smrg"#line " S__LINE__ "\n" 39832001f49Smrg" \n" 39932001f49Smrg"#define SHADOWS \n" 40032001f49Smrg"#define RECURSION \n" 40132001f49Smrg" \n" 40232001f49Smrg"const float INF=9999.9; \n" 40332001f49Smrg"const float EPSILON = 0.00001; \n" 40432001f49Smrg" \n" 40532001f49Smrg"uniform vec3 cameraPos; \n" 40632001f49Smrg"uniform mat3 rot3; \n" 40732001f49Smrg"uniform vec3 lightPos; \n" 40832001f49Smrg"uniform vec4 backgroundColor; \n" 40932001f49Smrg"uniform int emitNoMore; \n" 41032001f49Smrg" \n" 41132001f49Smrg"out vec4 frag_color; \n" 41232001f49Smrg" \n" 41332001f49Smrg"//-----------------------------------------------------------------------\n" 41432001f49Smrg" \n" 41532001f49Smrg"struct Ray\n" 41632001f49Smrg"{\n" 41732001f49Smrg" vec3 orig;\n" 41832001f49Smrg" vec3 dir;\n" 41932001f49Smrg"};\n" 42032001f49Smrg"\n" 42132001f49Smrg"struct Sphere\n" 42232001f49Smrg"{\n" 42332001f49Smrg" vec3 c;\n" 42432001f49Smrg" float r;\n" 42532001f49Smrg"};\n" 42632001f49Smrg"\n" 42732001f49Smrg"struct Isec\n" 42832001f49Smrg"{\n" 42932001f49Smrg" float t;\n" 43032001f49Smrg" int idx;\n" 43132001f49Smrg"\n" 43232001f49Smrg" vec3 hit;\n" 43332001f49Smrg" vec3 n;\n" 43432001f49Smrg"};\n" 43532001f49Smrg"\n" 43632001f49Smrg"const Sphere spheres0 = Sphere( vec3(0.0,0.0,-1.0), 0.5 );\n" 43732001f49Smrg"const Sphere spheres1 = Sphere( vec3(-3.0,0.0,-1.0), 1.5 );\n" 43832001f49Smrg"const Sphere spheres2 = Sphere( vec3(0.0,3.0,-1.0), 0.5 );\n" 43932001f49Smrg"const Sphere spheres3 = Sphere( vec3(2.0,0.0,-1.0), 1.0 );\n" 44032001f49Smrg"const Sphere spheres4 = Sphere( vec3(0.0,-11.0,-1.0), 10.0 );\n" 44132001f49Smrg"const int nSpheres = 5;\n" 44232001f49Smrg"const Sphere spheres[5]=Sphere[5](spheres0, spheres1, spheres2, spheres3, spheres4);\n" 44332001f49Smrg"\n" 44432001f49Smrg"Isec\n" 44532001f49Smrg"lookupNormal(const in Ray ray, in Isec isec)\n" 44632001f49Smrg"{\n" 44732001f49Smrg" Sphere sph=spheres[isec.idx];\n" 44832001f49Smrg" vec3 c = sph.c;\n" 44932001f49Smrg" float r = sph.r;\n" 45032001f49Smrg" isec.hit = ray.orig + ray.dir * isec.t;\n" 45132001f49Smrg" isec.n = (isec.hit - c) / r;\n" 45232001f49Smrg" return isec;\n" 45332001f49Smrg"}\n" 45432001f49Smrg"\n" 45532001f49Smrg"in vec4 orig_t2;\n" 45632001f49Smrg"in vec4 dir_idx2;\n" 45732001f49Smrg"in vec4 uv_state2;\n" 45832001f49Smrg"\n" 45932001f49Smrg"vec3\n" 46032001f49Smrg"idx2color(const in int idx)\n" 46132001f49Smrg"{\n" 46232001f49Smrg" vec3 diff;\n" 46332001f49Smrg" if (idx == 0)\n" 46432001f49Smrg" diff = vec3(1.0, 0.0, 0.0);\n" 46532001f49Smrg" else if (idx == 1)\n" 46632001f49Smrg" diff = vec3(0.0, 1.0, 0.0);\n" 46732001f49Smrg" else if (idx == 2)\n" 46832001f49Smrg" diff = vec3(0.0, 0.0, 1.0);\n" 46932001f49Smrg" else if (idx == 3)\n" 47032001f49Smrg" diff = vec3(1.0, 1.0, 0.0);\n" 47132001f49Smrg" else if (idx == 4)\n" 47232001f49Smrg" diff = vec3(0.7, 0.7, 0.7);\n" 47332001f49Smrg" return diff;\n" 47432001f49Smrg"}\n" 47532001f49Smrg"\n" 47632001f49Smrg"\n" 47732001f49Smrg"void\n" 47832001f49Smrg"main()\n" 47932001f49Smrg"{\n" 48032001f49Smrg" Ray ray = Ray(orig_t2.xyz, dir_idx2.xyz);\n" 48132001f49Smrg" Isec isec = Isec(orig_t2.w, int(dir_idx2.w), vec3(0,0,0), vec3(0,0,0));\n" 48232001f49Smrg" int state = int(uv_state2.z);\n" 48332001f49Smrg" int type = int(uv_state2.w);\n" 48432001f49Smrg"\n" 48532001f49Smrg" if (state < 3)\n" 48632001f49Smrg" {\n" 48732001f49Smrg" discard;\n" 48832001f49Smrg" }\n" 48932001f49Smrg"\n" 49032001f49Smrg"\n" 49132001f49Smrg" if (type == 0)\n" 49232001f49Smrg" {\n" 49332001f49Smrg" Ray eyeRay = ray;\n" 49432001f49Smrg" Isec eyeHit = isec;\n" 49532001f49Smrg" if (eyeHit.idx == -1)\n" 49632001f49Smrg" {\n" 49732001f49Smrg" frag_color = vec4(backgroundColor.rgb, 0.0);\n" 49832001f49Smrg" return;\n" 49932001f49Smrg" }\n" 50032001f49Smrg" vec3 eyeHitPosition = eyeRay.orig + eyeRay.dir * eyeHit.t;\n" 50132001f49Smrg" vec3 lightVec = lightPos - eyeHitPosition;\n" 50232001f49Smrg" eyeHit = lookupNormal(eyeRay, eyeHit);\n" 50332001f49Smrg" vec3 N = eyeHit.n;\n" 50432001f49Smrg" vec3 L = normalize(lightVec); \n" 50532001f49Smrg" float NdotL = max(dot(N, L), 0.0); \n" 50632001f49Smrg" vec3 diffuse = idx2color(eyeHit.idx); // material color of the visible point\n" 50732001f49Smrg" frag_color = vec4(diffuse * NdotL, 1.0); \n" 50832001f49Smrg" return; \n" 50932001f49Smrg" } \n" 51032001f49Smrg"#ifdef SHADOWS \n" 51132001f49Smrg" if (type > 0) \n" 51232001f49Smrg" { \n" 51332001f49Smrg" Isec shadowHit = isec; \n" 51432001f49Smrg" if (shadowHit.idx == -1) \n" 51532001f49Smrg" { \n" 51632001f49Smrg" discard; \n" 51732001f49Smrg" } \n" 51832001f49Smrg" frag_color = vec4(-1,-1,-1, 0.0); \n" 51932001f49Smrg" return; \n" 52032001f49Smrg" } \n" 52132001f49Smrg"#endif \n" 52232001f49Smrg"#ifdef RECURSION \n" 52332001f49Smrg" // else type < 0 \n" 52432001f49Smrg" { \n" 52532001f49Smrg" Ray reflRay = ray; \n" 52632001f49Smrg" Isec reflHit = isec; \n" 52732001f49Smrg" if (reflHit.idx == -1) \n" 52832001f49Smrg" { \n" 52932001f49Smrg" discard; \n" 53032001f49Smrg" } \n" 53132001f49Smrg" vec3 reflHitPosition = reflRay.orig + reflRay.dir * reflHit.t;\n" 53232001f49Smrg" vec3 lightVec = lightPos - reflHitPosition; \n" 53332001f49Smrg" reflHit = lookupNormal(reflRay, reflHit); \n" 53432001f49Smrg" vec3 N = reflHit.n; \n" 53532001f49Smrg" vec3 L = normalize(lightVec); \n" 53632001f49Smrg" float NdotL = max(dot(N, L), 0.0); \n" 53732001f49Smrg" vec3 diffuse = idx2color(reflHit.idx); \n" 53832001f49Smrg" frag_color = vec4(diffuse * NdotL * 0.25, 1.0); // material color of the visible point\n" 53932001f49Smrg" return; \n" 54032001f49Smrg" } \n" 54132001f49Smrg"#endif \n" 54232001f49Smrg"} \n"; 54332001f49Smrg 54432001f49Smrgstruct vec4 54532001f49Smrg{ 54632001f49Smrg union { 54732001f49Smrg float _[4]; 54832001f49Smrg struct { float x,y,z,w; }; 54932001f49Smrg }; 55032001f49Smrg vec4(float a, float b, float c, float d) : x(a), y(b), z(c), w(d) {} 55132001f49Smrg}; 55232001f49Smrg 55332001f49Smrgstruct GSRay 55432001f49Smrg{ 55532001f49Smrg vec4 pos; 55632001f49Smrg vec4 orig_t; 55732001f49Smrg vec4 dir_idx; 55832001f49Smrg vec4 uv_state; 55932001f49Smrg}; 56032001f49Smrg 56132001f49Smrgstatic float 56232001f49Smrgdeg2rad(const float degree) 56332001f49Smrg{ 56432001f49Smrg return( degree * 0.017453292519943295769236907684886F); 56532001f49Smrg} 56632001f49Smrg 56732001f49Smrgstatic void 56832001f49Smrgrotate_xy(float* mat3, const float degreesAroundX, const float degreesAroundY) 56932001f49Smrg{ 57032001f49Smrg const float radX = deg2rad(degreesAroundX); 57132001f49Smrg const float c1 = cosf(radX); 57232001f49Smrg const float s1 = sinf(radX); 57332001f49Smrg const float radY = deg2rad(degreesAroundY); 57432001f49Smrg const float c2 = cosf(radY); 57532001f49Smrg const float s2 = sinf(radY); 57632001f49Smrg mat3[0] = c2; mat3[3] = 0.0F; mat3[6] = s2; 57732001f49Smrg mat3[1] = s1*s2; mat3[4] = c1; mat3[7] = -s1*c2; 57832001f49Smrg mat3[2] = -c1*s2;mat3[5] = s1; mat3[8] = c1*c2; 57932001f49Smrg} 58032001f49Smrg 58132001f49Smrgstatic void 58232001f49Smrgidentity(float* mat3) 58332001f49Smrg{ 58432001f49Smrg mat3[0] = 1.0F; mat3[3] = 0.0F; mat3[6] = 0.0F; 58532001f49Smrg mat3[1] = 0.0F; mat3[4] = 1.0F; mat3[7] = 0.0F; 58632001f49Smrg mat3[2] = 0.0F; mat3[5] = 0.0F; mat3[8] = 1.0F; 58732001f49Smrg} 58832001f49Smrg 58932001f49Smrgstatic void 59032001f49SmrgDraw(void) 59132001f49Smrg{ 59232001f49Smrg glClearColor( 0.2, 0.5, 0.3, 0.0 ); 59332001f49Smrg glClearDepth(0.11F); 59432001f49Smrg glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 59532001f49Smrg 59632001f49Smrg glDisable(GL_DEPTH_TEST); 59732001f49Smrg glEnable(GL_CULL_FACE); 59832001f49Smrg 59932001f49Smrg glUseProgram(program); 60032001f49Smrg 60132001f49Smrg glUniformMatrix3fv(glGetUniformLocation(program, "rot3"), 1, 0, rot); 60232001f49Smrg 60332001f49Smrg //gs.gs->getVertexAttribLocation("pos", gs.posAttribLoc); 60432001f49Smrg //gs.gs->getVertexAttribLocation("orig_t", gs.orig_tAttribLoc); 60532001f49Smrg //gs.gs->getVertexAttribLocation("dir_idx", gs.dir_idxAttribLoc); 60632001f49Smrg //gs.gs->getVertexAttribLocation("uv_state", gs.uv_stateAttribLoc); 60732001f49Smrg posAttribLoc = glGetAttribLocation(program, "pos"); 60832001f49Smrg orig_tAttribLoc = glGetAttribLocation(program, "orig_t"); 60932001f49Smrg dir_idxAttribLoc = glGetAttribLocation(program, "dir_idx"); 61032001f49Smrg uv_stateAttribLoc = glGetAttribLocation(program, "uv_state"); 61132001f49Smrg 61232001f49Smrg glBindFragDataLocation(program, 0, "frag_color"); 61332001f49Smrg 61432001f49Smrg ////printf("%d\n", i); 61532001f49Smrg //gs.fpwQuery->beginQuery(); 61632001f49Smrg //gs.pgQuery->beginQuery(); 61732001f49Smrg glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, dst); 61832001f49Smrg glBeginQuery(GL_PRIMITIVES_GENERATED, pgQuery); 61932001f49Smrg glBeginTransformFeedback(GL_POINTS); 62032001f49Smrg //gs.eyeRaysAsPoints->bindAs(ARRAY); 62132001f49Smrg glBindBuffer(GL_ARRAY_BUFFER, eyeRaysAsPoints); 62232001f49Smrg { 62332001f49Smrg glEnableVertexAttribArray(posAttribLoc); 62432001f49Smrg glVertexAttribPointer(posAttribLoc, 4, GL_FLOAT, GL_FALSE, 62532001f49Smrg sizeof(GSRay), (void*)offsetof(GSRay, pos)); 62632001f49Smrg 62732001f49Smrg glEnableVertexAttribArray(orig_tAttribLoc); 62832001f49Smrg glVertexAttribPointer(orig_tAttribLoc, 4, GL_FLOAT, GL_FALSE, 62932001f49Smrg sizeof(GSRay), (void*)offsetof(GSRay, orig_t)); 63032001f49Smrg 63132001f49Smrg glEnableVertexAttribArray(dir_idxAttribLoc); 63232001f49Smrg glVertexAttribPointer(dir_idxAttribLoc, 4, GL_FLOAT, GL_FALSE, 63332001f49Smrg sizeof(GSRay), (void*)offsetof(GSRay, dir_idx)); 63432001f49Smrg 63532001f49Smrg glEnableVertexAttribArray(uv_stateAttribLoc); 63632001f49Smrg glVertexAttribPointer(uv_stateAttribLoc, 4, GL_FLOAT, GL_FALSE, 63732001f49Smrg sizeof(GSRay), (void*)offsetof(GSRay, uv_state)); 63832001f49Smrg 63932001f49Smrg //if (getShadows() || getMaxRecursion() > 0) 64032001f49Smrg //gs.gs->set_uniform("emitNoMore", 1, 0); 64132001f49Smrg glUniform1i(glGetUniformLocation(program, "emitNoMore"), 0); 64232001f49Smrg 64332001f49Smrg //glEnable(GL_RASTERIZER_DISCARD); 64432001f49Smrg glDrawArrays(GL_POINTS, 0, WinWidth*WinHeight); 64532001f49Smrg //glDisable(GL_RASTERIZER_DISCARD); 64632001f49Smrg 64732001f49Smrg glDisableVertexAttribArray(uv_stateAttribLoc); 64832001f49Smrg 64932001f49Smrg glDisableVertexAttribArray(dir_idxAttribLoc); 65032001f49Smrg 65132001f49Smrg glDisableVertexAttribArray(orig_tAttribLoc); 65232001f49Smrg 65332001f49Smrg glDisableVertexAttribArray(posAttribLoc); 65432001f49Smrg } 65532001f49Smrg //gs.eyeRaysAsPoints->unbindAs(ARRAY); 65632001f49Smrg glBindBuffer(GL_ARRAY_BUFFER, 0); 65732001f49Smrg glEndTransformFeedback(); 65832001f49Smrg //gs.pgQuery->endQuery(); 65932001f49Smrg glEndQuery(GL_PRIMITIVES_GENERATED); 66032001f49Smrg //gs.fpwQuery->endQuery(); 66132001f49Smrg 66232001f49Smrg ////psoLog(LOG_RAW) << "1st: " << gs.fpwQuery->getQueryResult() << ", " << gs.pgQuery->getQueryResult() << "\n"; 66332001f49Smrg 66432001f49Smrg 66532001f49Smrg ////swap(src, dst); 66632001f49Smrg glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0); 66732001f49Smrg 66832001f49Smrg ////clear(); 66932001f49Smrg 67032001f49Smrg ////fpwQuery->beginQuery(); 67132001f49Smrg ////pgQuery->beginQuery(); 67232001f49Smrg //// With GL_ARB_color_buffer_float we can use negative color values 67332001f49Smrg //// and disable clamping with ClampColorARB. This might be better for 67432001f49Smrg //// compositing the pixels in shadow. 67532001f49Smrg glEnable(GL_BLEND); 67632001f49Smrg glBlendEquationSeparate(GL_FUNC_ADD, GL_MAX); // modeRGB, modeA 67732001f49Smrg glBlendFuncSeparate(GL_ONE, GL_SRC_ALPHA, // srcRGB, dstRGB 67832001f49Smrg GL_ONE, GL_ONE); // arcA, dstA 67932001f49Smrg //gs.dst->bindAs(ARRAY); 68032001f49Smrg glBindBuffer(GL_ARRAY_BUFFER, dst); 68132001f49Smrg { 68232001f49Smrg glEnableVertexAttribArray(posAttribLoc); 68332001f49Smrg glVertexAttribPointer(posAttribLoc, 4, GL_FLOAT, GL_FALSE, 68432001f49Smrg sizeof(GSRay), (void*)offsetof(GSRay, pos)); 68532001f49Smrg 68632001f49Smrg glEnableVertexAttribArray(orig_tAttribLoc); 68732001f49Smrg glVertexAttribPointer(orig_tAttribLoc, 4, GL_FLOAT, GL_FALSE, 68832001f49Smrg sizeof(GSRay), (void*)offsetof(GSRay, orig_t)); 68932001f49Smrg 69032001f49Smrg glEnableVertexAttribArray(dir_idxAttribLoc); 69132001f49Smrg glVertexAttribPointer(dir_idxAttribLoc, 4, GL_FLOAT, GL_FALSE, 69232001f49Smrg sizeof(GSRay), (void*)offsetof(GSRay, dir_idx)); 69332001f49Smrg 69432001f49Smrg glEnableVertexAttribArray(uv_stateAttribLoc); 69532001f49Smrg glVertexAttribPointer(uv_stateAttribLoc, 4, GL_FLOAT, GL_FALSE, 69632001f49Smrg sizeof(GSRay), (void*)offsetof(GSRay, uv_state)); 69732001f49Smrg 69832001f49Smrg //if (getShadows() || getMaxRecursion() > 0) 69932001f49Smrg //gs.gs->set_uniform("emitNoMore", 1, 1); 70032001f49Smrg glUniform1i(glGetUniformLocation(program, "emitNoMore"), 1); 70132001f49Smrg //GLint fpw = gs.fpwQuery->getQueryResult(); 70232001f49Smrg //GLint pg = gs.pgQuery->getQueryResult(); 70332001f49Smrg GLint pg; 70432001f49Smrg glGetQueryObjectiv(pgQuery, GL_QUERY_RESULT, &pg); 70532001f49Smrg //pso_runtime_check(fpw == pg); 70632001f49Smrg glDrawArrays(GL_POINTS, 0, pg); 70732001f49Smrg 70832001f49Smrg glDisableVertexAttribArray(uv_stateAttribLoc); 70932001f49Smrg 71032001f49Smrg glDisableVertexAttribArray(dir_idxAttribLoc); 71132001f49Smrg 71232001f49Smrg glDisableVertexAttribArray(orig_tAttribLoc); 71332001f49Smrg 71432001f49Smrg glDisableVertexAttribArray(posAttribLoc); 71532001f49Smrg } 71632001f49Smrg //gs.dst->unbindAs(ARRAY); 71732001f49Smrg glBindBuffer(GL_ARRAY_BUFFER, 0); 71832001f49Smrg glDisable(GL_BLEND); 71932001f49Smrg ////pgQuery->endQuery(); 72032001f49Smrg ////fpwQuery->endQuery(); 72132001f49Smrg 72232001f49Smrg ////psoLog(LOG_RAW) << "2nd: " << fpwQuery->getQueryResult() << ", " << pgQuery->getQueryResult() << "\n\n"; 72332001f49Smrg ////pso_runtime_check(fpwQuery->getQueryResult() == pgQuery->getQueryResult()); 72432001f49Smrg 72532001f49Smrg ////swap(src, dst); 72632001f49Smrg ////for(;;); 72732001f49Smrg 72832001f49Smrg glUseProgram(0); 72932001f49Smrg 73032001f49Smrg glDisable(GL_CULL_FACE); 73132001f49Smrg 73232001f49Smrg////////////////////////////////////////////////////////////////////// 73332001f49Smrg 73432001f49Smrg glutSwapBuffers(); 73532001f49Smrg 73632001f49Smrg { 73732001f49Smrg static int frames = 0; 73832001f49Smrg static int t0 = 0; 73932001f49Smrg static int t1 = 0; 74032001f49Smrg float dt; 74132001f49Smrg frames++; 74232001f49Smrg t1 = glutGet(GLUT_ELAPSED_TIME); 74332001f49Smrg dt = (float)(t1-t0)/1000.0F; 74432001f49Smrg if (dt >= 5.0F) 74532001f49Smrg { 74632001f49Smrg float fps = (float)frames / dt; 74732001f49Smrg printf("%f FPS (%d frames in %f seconds)\n", fps, frames, dt); 74832001f49Smrg frames = 0; 74932001f49Smrg t0 = t1; 75032001f49Smrg } 75132001f49Smrg } 75232001f49Smrg} 75332001f49Smrg 75432001f49Smrg 75532001f49Smrgstatic void 75632001f49SmrgReshape(int width, int height) 75732001f49Smrg{ 75832001f49Smrg WinWidth = width; 75932001f49Smrg WinHeight = height; 76032001f49Smrg glViewport(0, 0, width, height); 76132001f49Smrg 76232001f49Smrg { 76332001f49Smrg size_t nElem = WinWidth*WinHeight*nRayGens; 76432001f49Smrg glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, dst); 76532001f49Smrg glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, nElem*sizeof(GSRay), 0, GL_STREAM_DRAW); 76632001f49Smrg GSRay* d = (GSRay*)glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_WRITE); 76732001f49Smrg for (size_t i = 0; i < nElem; i++) 76832001f49Smrg { 76932001f49Smrg d[i].dir_idx = vec4(0.0F, 0.0F, 0.0F, -1.0F); 77032001f49Smrg } 77132001f49Smrg glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 77232001f49Smrg glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0); 77332001f49Smrg //printf("Ping-pong VBO size 2x%d Kbytes.\n", (int)nElem*sizeof(GSRay)/1024); 77432001f49Smrg } 77532001f49Smrg 77632001f49Smrg { 77732001f49Smrg glBindBuffer(GL_ARRAY_BUFFER, eyeRaysAsPoints); 77832001f49Smrg glBufferData(GL_ARRAY_BUFFER, WinWidth*WinHeight*sizeof(GSRay), 0, GL_STATIC_DRAW); 77932001f49Smrg GSRay* d = (GSRay*)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE); 78032001f49Smrg const float w = 0.5F * WinWidth; 78132001f49Smrg const float h = 0.5F * WinHeight; 78232001f49Smrg for (int y = 0; y < WinHeight; y++) 78332001f49Smrg { 78432001f49Smrg for (int x = 0; x < WinWidth; x++) 78532001f49Smrg { 78632001f49Smrg unsigned int i = y*WinWidth+x; 78732001f49Smrg const float posx = x / w - 1.0F; 78832001f49Smrg const float posy = y / h - 1.0F; 78932001f49Smrg d[i].pos = vec4(posx, posy, 0.5F, 1.0F); 79032001f49Smrg d[i].orig_t = vec4(0.0F, 0.0F, 0.0F, INF); 79132001f49Smrg d[i].dir_idx = vec4(0.0F, 0.0F, 0.0F, -0.0F); 79232001f49Smrg d[i].uv_state = vec4(0, 0, 0, 0); 79332001f49Smrg } 79432001f49Smrg } 79532001f49Smrg glUnmapBuffer(GL_ARRAY_BUFFER); 79632001f49Smrg glBindBuffer(GL_ARRAY_BUFFER, 0); 79732001f49Smrg } 79832001f49Smrg} 79932001f49Smrg 80032001f49Smrg 80132001f49Smrgstatic void 80232001f49SmrgKey(unsigned char key, int x, int y) 80332001f49Smrg{ 80432001f49Smrg if (key == 27) 80532001f49Smrg { 80632001f49Smrg glutDestroyWindow(Win); 80732001f49Smrg exit(0); 80832001f49Smrg } 80932001f49Smrg glutPostRedisplay(); 81032001f49Smrg} 81132001f49Smrg 81232001f49Smrg 81332001f49Smrgstatic void 81432001f49Smrgdrag(int x, int y) 81532001f49Smrg{ 81632001f49Smrg float scale = 1.5F; 81732001f49Smrg if (mouseGrabbed) 81832001f49Smrg { 81932001f49Smrg static GLfloat xRot = 0, yRot = 0; 82032001f49Smrg xRot = (float)(x - WinWidth/2) / scale; 82132001f49Smrg yRot = (float)(y - WinHeight/2) / scale; 82232001f49Smrg identity(rot); 82332001f49Smrg rotate_xy(rot, yRot, xRot); 82432001f49Smrg glutPostRedisplay(); 82532001f49Smrg } 82632001f49Smrg} 82732001f49Smrg 82832001f49Smrg 82932001f49Smrgstatic void 83032001f49Smrgmouse(int button, int state, int x, int y) 83132001f49Smrg{ 83232001f49Smrg mouseGrabbed = (state == GLUT_DOWN); 83332001f49Smrg} 83432001f49Smrg 83532001f49Smrg 83632001f49Smrgstatic void 83732001f49SmrgInit(void) 83832001f49Smrg{ 83932001f49Smrg glDisable(GL_DEPTH_TEST); 84032001f49Smrg 84132001f49Smrg if (!ShadersSupported()) 84232001f49Smrg { 84332001f49Smrg fprintf(stderr, "Shaders are not supported!\n"); 84432001f49Smrg exit(-1); 84532001f49Smrg } 84632001f49Smrg 84732001f49Smrg if (!GLEW_VERSION_3_2) 84832001f49Smrg { 84932001f49Smrg fprintf(stderr, "OpenGL 3.2 (needed for transform feedback and " 85032001f49Smrg "geometry shaders) not supported!\n"); 85132001f49Smrg exit(-1); 85232001f49Smrg } 85332001f49Smrg 85432001f49Smrg vertShader = CompileShaderText(GL_VERTEX_SHADER, vsSource); 85532001f49Smrg geomShader = CompileShaderText(GL_GEOMETRY_SHADER_ARB, gsSource); 85632001f49Smrg fragShader = CompileShaderText(GL_FRAGMENT_SHADER, fsSource); 85732001f49Smrg program = LinkShaders3(vertShader, geomShader, fragShader); 85832001f49Smrg 85932001f49Smrg const char *varyings[] = { 86032001f49Smrg "gl_Position", 86132001f49Smrg "orig_t2", 86232001f49Smrg "dir_idx2", 86332001f49Smrg "uv_state2" 86432001f49Smrg }; 86532001f49Smrg // I think it will be a performance win to use multiple buffer objects to write to 86632001f49Smrg // instead of using the interleaved mode. 86732001f49Smrg glTransformFeedbackVaryings(program, 4, varyings, GL_INTERLEAVED_ATTRIBS); 86832001f49Smrg glLinkProgram(program); 86932001f49Smrg 87032001f49Smrg if (glGetError() != 0) 87132001f49Smrg { 87232001f49Smrg fprintf(stderr, "Shaders were not loaded!\n"); 87332001f49Smrg exit(-1); 87432001f49Smrg } 87532001f49Smrg 87632001f49Smrg if (!glIsShader(vertShader)) 87732001f49Smrg { 87832001f49Smrg fprintf(stderr, "Vertex shader failed!\n"); 87932001f49Smrg exit(-1); 88032001f49Smrg } 88132001f49Smrg 88232001f49Smrg if (!glIsShader(geomShader)) 88332001f49Smrg { 88432001f49Smrg fprintf(stderr, "Geometry shader failed!\n"); 88532001f49Smrg exit(-1); 88632001f49Smrg } 88732001f49Smrg 88832001f49Smrg if (!glIsShader(fragShader)) 88932001f49Smrg { 89032001f49Smrg fprintf(stderr, "Fragment shader failed!\n"); 89132001f49Smrg exit(-1); 89232001f49Smrg } 89332001f49Smrg 89432001f49Smrg if (!glIsProgram(program)) 89532001f49Smrg { 89632001f49Smrg fprintf(stderr, "Shader program failed!\n"); 89732001f49Smrg exit(-1); 89832001f49Smrg } 89932001f49Smrg 90032001f49Smrg glUseProgram(program); 90132001f49Smrg glUniform3f(glGetUniformLocation(program, "cameraPos"), 0,3,5); 90232001f49Smrg glUniform4f(glGetUniformLocation(program, "backgroundColor"), 0,0,0,1); 90332001f49Smrg glUniform1i(glGetUniformLocation(program, "emitNoMore"), 1); 90432001f49Smrg glUniform3f(glGetUniformLocation(program, "lightPos"), 0,8,1); 90532001f49Smrg glUseProgram(0); 90632001f49Smrg 90732001f49Smrg printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); 90832001f49Smrg 90932001f49Smrg glGenQueries(1, &pgQuery); 91032001f49Smrg glGenBuffers(1, &dst); 91132001f49Smrg glGenBuffers(1, &eyeRaysAsPoints); 91232001f49Smrg 91332001f49Smrg GLuint vao; 91432001f49Smrg glGenVertexArrays(1, &vao); 91532001f49Smrg glBindVertexArray(vao); 91632001f49Smrg 91732001f49Smrg printf("\nESC = exit demo\nleft mouse + drag = rotate camera\n\n"); 91832001f49Smrg} 91932001f49Smrg 92032001f49Smrg 92132001f49Smrgint 92232001f49Smrgmain(int argc, char *argv[]) 92332001f49Smrg{ 92432001f49Smrg glutInitWindowSize(WinWidth, WinHeight); 92532001f49Smrg glutInit(&argc, argv); 92632001f49Smrg 92732001f49Smrg#ifdef HAVE_FREEGLUT 92832001f49Smrg glutInitContextVersion(3, 2); 92932001f49Smrg glutInitContextProfile(GLUT_CORE_PROFILE); 93032001f49Smrg glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); 93132001f49Smrg#elif defined __APPLE__ 93232001f49Smrg glutInitDisplayMode(GLUT_3_2_CORE_PROFILE | GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); 93332001f49Smrg#else 93432001f49Smrg glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); 93532001f49Smrg#endif 93632001f49Smrg Win = glutCreateWindow(argv[0]); 93732001f49Smrg 93832001f49Smrg // glewInit requires glewExperimentel set to true for core profiles. 93932001f49Smrg // Depending on the glew version it also generates GL_INVALID_ENUM. 94032001f49Smrg glewExperimental = GL_TRUE; 94132001f49Smrg glewInit(); 94232001f49Smrg glGetError(); 94332001f49Smrg 94432001f49Smrg glutReshapeFunc(Reshape); 94532001f49Smrg glutKeyboardFunc(Key); 94632001f49Smrg glutDisplayFunc(Draw); 94732001f49Smrg glutIdleFunc(Draw); 94832001f49Smrg glutMouseFunc(mouse); 94932001f49Smrg glutMotionFunc(drag); 95032001f49Smrg Init(); 95132001f49Smrg Reshape(WinWidth, WinHeight ); // fix crash under nvidia driver, as Reshape() not being called before rendering, and thus the BO-s were not created 95232001f49Smrg glutMainLoop(); 95332001f49Smrg glutDestroyWindow(Win); 95432001f49Smrg return 0; 95532001f49Smrg} 95632001f49Smrg 957