gpuray_glsl
changeset 4:2ed3da7dc0bc
broken
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 10 Nov 2014 01:26:00 +0200 |
parents | 297dbc5080c4 |
children | 000017955721 |
files | gpuray_glsl.vcxproj gpuray_glsl.vcxproj.filters sdr/rt.glsl src/cone.cc src/gpuscene.cc src/gpuscene.h src/rend.cc src/scene_load.cc |
diffstat | 8 files changed, 249 insertions(+), 6 deletions(-) [+] |
line diff
1.1 --- a/gpuray_glsl.vcxproj Sun Nov 09 20:13:33 2014 +0200 1.2 +++ b/gpuray_glsl.vcxproj Mon Nov 10 01:26:00 2014 +0200 1.3 @@ -96,6 +96,7 @@ 1.4 <ClCompile Include="imago\modules.c" /> 1.5 <ClCompile Include="src\box.cc" /> 1.6 <ClCompile Include="src\camera.cc" /> 1.7 + <ClCompile Include="src\cone.cc" /> 1.8 <ClCompile Include="src\glsdr.c" /> 1.9 <ClCompile Include="src\gpuscene.cc" /> 1.10 <ClCompile Include="src\image.cc" /> 1.11 @@ -127,6 +128,7 @@ 1.12 <ClInclude Include="imago\imago2.h" /> 1.13 <ClInclude Include="src\box.h" /> 1.14 <ClInclude Include="src\camera.h" /> 1.15 + <ClInclude Include="src\cone.h" /> 1.16 <ClInclude Include="src\glsdr.h" /> 1.17 <ClInclude Include="src\gpuscene.h" /> 1.18 <ClInclude Include="src\image.h" />
2.1 --- a/gpuray_glsl.vcxproj.filters Sun Nov 09 20:13:33 2014 +0200 2.2 +++ b/gpuray_glsl.vcxproj.filters Mon Nov 10 01:26:00 2014 +0200 2.3 @@ -124,6 +124,9 @@ 2.4 <ClCompile Include="imago\modules.c"> 2.5 <Filter>imago</Filter> 2.6 </ClCompile> 2.7 + <ClCompile Include="src\cone.cc"> 2.8 + <Filter>src</Filter> 2.9 + </ClCompile> 2.10 </ItemGroup> 2.11 <ItemGroup> 2.12 <ClInclude Include="src\box.h"> 2.13 @@ -210,6 +213,9 @@ 2.14 <ClInclude Include="imago\imago2.h"> 2.15 <Filter>imago</Filter> 2.16 </ClInclude> 2.17 + <ClInclude Include="src\cone.h"> 2.18 + <Filter>src</Filter> 2.19 + </ClInclude> 2.20 </ItemGroup> 2.21 <ItemGroup> 2.22 <None Include="vmath\matrix.inl">
3.1 --- a/sdr/rt.glsl Sun Nov 09 20:13:33 2014 +0200 3.2 +++ b/sdr/rt.glsl Mon Nov 10 01:26:00 2014 +0200 3.3 @@ -46,6 +46,13 @@ 3.4 struct Material mat; 3.5 }; 3.6 3.7 +struct Cone { 3.8 + float index; 3.9 + float angle; 3.10 + float start, end; 3.11 + struct Material mat; 3.12 +}; 3.13 + 3.14 struct Light { 3.15 vec3 pos, color; 3.16 }; 3.17 @@ -55,6 +62,7 @@ 3.18 bool sphere_intersect(in Sphere sph, in Ray ray, out HitPoint pt); 3.19 bool plane_intersect(in Plane plane, in Ray ray, out HitPoint pt); 3.20 bool box_intersect(in Box box, in Ray ray, out HitPoint pt); 3.21 +bool cone_intersect(in Cone cone, in Ray ray, out HitPoint pt); 3.22 vec3 transform(in vec3 v, in mat4 inv_xform); 3.23 Ray transform(in Ray ray, in mat4 xform, in mat4 inv_xform); 3.24 Ray get_primary_ray(); 3.25 @@ -62,11 +70,12 @@ 3.26 Sphere read_sphere(in float idx); 3.27 Plane read_plane(in float idx); 3.28 Box read_box(in float idx); 3.29 +Cone read_cone(in float idx); 3.30 Material read_material(in sampler2D tex, in float ty); 3.31 void read_xform(in float idx, out mat4 xform, out mat4 inv_xform); 3.32 3.33 uniform sampler2D tex_raydir; 3.34 -uniform sampler2D tex_spheres, tex_planes, tex_boxes; 3.35 +uniform sampler2D tex_spheres, tex_planes, tex_boxes, tex_cones; 3.36 uniform sampler2D tex_megatex; 3.37 uniform sampler2D tex_xforms; 3.38 uniform samplerCube tex_env; 3.39 @@ -75,8 +84,8 @@ 3.40 uniform Light lights[8]; 3.41 uniform int num_lights; 3.42 3.43 -int num_spheres, num_planes, num_boxes; 3.44 -float sph_tex_sz, plane_tex_sz, box_tex_sz, xform_tex_sz; 3.45 +int num_spheres, num_planes, num_boxes, num_cones; 3.46 +float sph_tex_sz, plane_tex_sz, box_tex_sz, cone_tex_sz, xform_tex_sz; 3.47 3.48 #ifdef INIT_EVERYTHING 3.49 Material default_material; 3.50 @@ -108,6 +117,10 @@ 3.51 num_boxes = int(desc.x); 3.52 box_tex_sz = desc.y; 3.53 3.54 + desc = texture2D(tex_cones, vec2(0.0, 0.0)); 3.55 + num_cones = int(desc.x); 3.56 + cone_tex_sz = desc.y; 3.57 + 3.58 xform_tex_sz = texture2D(tex_xforms, vec2(0.0, 0.0)).x; 3.59 3.60 3.61 @@ -215,6 +228,16 @@ 3.62 } 3.63 } 3.64 3.65 + for(int i=0; i<num_cones; i++) { 3.66 + Cone cone = read_cone(i); 3.67 + 3.68 + HitPoint tmphit; 3.69 + if(cone_intersect(cone, ray, tmphit) && tmphit.dist < hit.dist) { 3.70 + hit = tmphit; 3.71 + found = true; 3.72 + } 3.73 + } 3.74 + 3.75 return found; 3.76 } 3.77 3.78 @@ -419,6 +442,77 @@ 3.79 return false; 3.80 } 3.81 3.82 +bool cone_intersect(in Cone cone, in Ray inray, out HitPoint pt) 3.83 +{ 3.84 +#ifdef USE_XFORM 3.85 + mat4 xform, inv_xform; 3.86 + read_xform(cone.index, xform, inv_xform); 3.87 + 3.88 + Ray ray = transform(inray, inv_xform, xform); 3.89 +#else 3.90 + Ray ray = inray; 3.91 +#endif 3.92 + 3.93 +#ifdef INIT_EVERYTHING 3.94 + pt.dist = 0.0; 3.95 + pt.pos = pt.normal = vec3(0.0, 0.0, 0.0); 3.96 + pt.mat = default_material; 3.97 + pt.texcoord = vec2(0.0, 0.0); 3.98 +#endif 3.99 + 3.100 + float slope = 2.0 * cone.angle / M_PI; 3.101 + 3.102 + float a = SQ(ray.dir.x) - SQ(slope * ray.dir.y) + SQ(ray.dir.z); 3.103 + float b = 2.0 * ray.origin.x * ray.dir.x - 2.0 * SQ(slope) * ray.origin.y * ray.dir.y + 3.104 + 2.0 * ray.origin.z * ray.dir.z; 3.105 + float c = SQ(ray.origin.x) - SQ(slope * ray.origin.y) + SQ(ray.origin.z); 3.106 + 3.107 + float discr = b * b - 4.0 * a * c; 3.108 + if(discr < EPSILON) 3.109 + return false; 3.110 + 3.111 + float sqrt_discr = sqrt(discr); 3.112 + float t0 = (-b + sqrt_discr) / (2.0 * a); 3.113 + float t1 = (-b - sqrt_discr) / (2.0 * a); 3.114 + 3.115 + if(t0 < EPSILON) 3.116 + t0 = t1; 3.117 + if(t1 < EPSILON) 3.118 + t1 = t0; 3.119 + 3.120 + float t = min(t0, t1); 3.121 + if(t < EPSILON) 3.122 + return false; 3.123 + 3.124 + // fill the HitPoint structure 3.125 + pt.dist = t; 3.126 + pt.pos = ray.origin + ray.dir * t; 3.127 + 3.128 + if(pt.pos.y < cone.start || pt.pos.y >= cone.end) { 3.129 + return false; 3.130 + } 3.131 + 3.132 + float radius = pt.pos.y * slope; 3.133 + pt.normal = vec3(pt.pos.x, 0.0, pt.pos.z) / radius; 3.134 + 3.135 + float ny = sin(cone.angle); 3.136 + float xzlen = sqrt(1.0 - ny * ny); 3.137 + pt.normal.x *= xzlen; 3.138 + pt.normal.y = ny; 3.139 + pt.normal.z *= xzlen; 3.140 + 3.141 + pt.mat = cone.mat; 3.142 + 3.143 + pt.texcoord.x = 0.5 * atan(pt.normal.z, pt.normal.x) / M_PI + 0.5; 3.144 + pt.texcoord.y = (pt.pos.y - cone.start) / (cone.end - cone.start); 3.145 + 3.146 +#ifdef USE_XFORM 3.147 + pt.pos = (xform * vec4(pt.pos, 1.0)).xyz; 3.148 + pt.normal = normalize(transform(pt.normal, xform)); 3.149 +#endif 3.150 + return true; 3.151 +} 3.152 + 3.153 vec3 transform(in vec3 v, in mat4 xform) 3.154 { 3.155 return mat3(xform) * v; 3.156 @@ -489,6 +583,22 @@ 3.157 return box; 3.158 } 3.159 3.160 +Cone read_cone(in float idx) 3.161 +{ 3.162 + Cone cone; 3.163 + float ty = (idx + 1.0) / cone_tex_sz; 3.164 + 3.165 + cone.index = texture2D(tex_cones, vec2(ITEM(0), ty)).x; 3.166 + 3.167 + vec4 texel = texture2D(tex_cones, vec2(ITEM(1), ty)); 3.168 + cone.angle = texel.x; 3.169 + cone.start = texel.y; 3.170 + cone.end = texel.z; 3.171 + 3.172 + cone.mat = read_material(tex_cones, ty); 3.173 + return cone; 3.174 +} 3.175 + 3.176 void read_xform(in float idx, out mat4 xform, out mat4 inv_xform) 3.177 { 3.178 float ty = (idx + 1.0) / xform_tex_sz;
4.1 --- a/src/cone.cc Sun Nov 09 20:13:33 2014 +0200 4.2 +++ b/src/cone.cc Mon Nov 10 01:26:00 2014 +0200 4.3 @@ -65,10 +65,20 @@ 4.4 pt->dist = t; 4.5 pt->pos = ray.origin + ray.dir * t; 4.6 4.7 - pt->normal.z = sin(angle); 4.8 + if(pt->pos.y < ymin || pt->pos.y >= ymax) { 4.9 + return false; 4.10 + } 4.11 4.12 - //pt->normal = (pt->pos - pos) / radius; TODO continue here 4.13 + float radius = pt->pos.y * slope; 4.14 + pt->normal = Vector3(pt->pos.x, 0.0, pt->pos.z) / radius; 4.15 + 4.16 + float ny = sin(angle); 4.17 + float xzlen = sqrt(1.0 - ny * ny); 4.18 + pt->normal.x *= xzlen; 4.19 + pt->normal.y = ny; 4.20 + pt->normal.z *= xzlen; 4.21 4.22 pt->pos.transform(xform); 4.23 pt->normal.transform(dir_xform); 4.24 + return true; 4.25 }
5.1 --- a/src/gpuscene.cc Sun Nov 09 20:13:33 2014 +0200 5.2 +++ b/src/gpuscene.cc Mon Nov 10 01:26:00 2014 +0200 5.3 @@ -35,10 +35,12 @@ 5.4 Sphere *sph; 5.5 Plane *plane; 5.6 Box *box; 5.7 + Cone *cone; 5.8 5.9 std::vector<Sphere*> spheres; 5.10 std::vector<Plane*> planes; 5.11 std::vector<Box*> boxes; 5.12 + std::vector<Cone*> cones; 5.13 5.14 // collect all objects into the different type-specific arrays 5.15 for(auto obj : objects) { 5.16 @@ -51,6 +53,9 @@ 5.17 } else if((box = dynamic_cast<Box*>(obj))) { 5.18 boxes.push_back(box); 5.19 5.20 + } else if((cone = dynamic_cast<Cone*>(obj))) { 5.21 + cones.push_back(cone); 5.22 + 5.23 } else { 5.24 fprintf(stderr, "skipping object of unknown type: %s\n", obj->get_name()); 5.25 } 5.26 @@ -59,6 +64,7 @@ 5.27 create_sphere_texture(spheres); 5.28 create_plane_texture(planes); 5.29 create_box_texture(boxes); 5.30 + create_cone_texture(cones); 5.31 5.32 create_env_texture(); 5.33 create_xform_texture(); 5.34 @@ -194,6 +200,38 @@ 5.35 delete [] pixels; 5.36 } 5.37 5.38 +void GPUScene::create_cone_texture(const std::vector<Cone*> &cones) 5.39 +{ 5.40 + int xsz = OBJ_LINE_WIDTH; 5.41 + int ysz = (int)cones.size() + 1; 5.42 + int tex_ysz = next_pow2(ysz); 5.43 + 5.44 + Vector4 *pixels = new Vector4[xsz * tex_ysz]; 5.45 + 5.46 + pixels[0].x = (float)ysz; 5.47 + pixels[0].y = (float)tex_ysz; 5.48 + 5.49 + Vector4 *pixptr = pixels + xsz; 5.50 + 5.51 + for(size_t i=0; i<cones.size(); i++) { 5.52 + pixptr[0].x = object_index(cones[i]); 5.53 + 5.54 + pixptr[1].x = cones[i]->angle; 5.55 + pixptr[1].y = cones[i]->ymin; 5.56 + pixptr[1].z = cones[i]->ymax; 5.57 + pixptr[1].w = 0.0; 5.58 + 5.59 + copy_material(pixptr, &cones[i]->material); 5.60 + pixptr += OBJ_LINE_WIDTH; 5.61 + } 5.62 + 5.63 + glBindTexture(GL_TEXTURE_2D, textures[TEX_SPHERE]); 5.64 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, xsz, tex_ysz, 0, GL_RGBA, GL_FLOAT, pixels); 5.65 + 5.66 + delete [] pixels; 5.67 +} 5.68 + 5.69 + 5.70 void GPUScene::create_megatexture() 5.71 { 5.72 // at least a 1x1 dummy white texture
6.1 --- a/src/gpuscene.h Sun Nov 09 20:13:33 2014 +0200 6.2 +++ b/src/gpuscene.h Mon Nov 10 01:26:00 2014 +0200 6.3 @@ -6,10 +6,11 @@ 6.4 #include "sphere.h" 6.5 #include "plane.h" 6.6 #include "box.h" 6.7 +#include "cone.h" 6.8 6.9 class GPUScene : public Scene { 6.10 public: 6.11 - enum { TEX_SPHERE, TEX_PLANE, TEX_BOX, TEX_TEXTURE, TEX_ENV, TEX_XFORM, NUM_TEXTURES }; 6.12 + enum { TEX_SPHERE, TEX_PLANE, TEX_BOX, TEX_CONE, TEX_TEXTURE, TEX_ENV, TEX_XFORM, NUM_TEXTURES }; 6.13 6.14 private: 6.15 unsigned int textures[NUM_TEXTURES]; 6.16 @@ -20,6 +21,7 @@ 6.17 void create_sphere_texture(const std::vector<Sphere*> &spheres); 6.18 void create_plane_texture(const std::vector<Plane*> &planes); 6.19 void create_box_texture(const std::vector<Box*> &box); 6.20 + void create_cone_texture(const std::vector<Cone*> &cones); 6.21 void create_megatexture(); 6.22 void create_env_texture(); 6.23 void create_xform_texture();
7.1 --- a/src/rend.cc Sun Nov 09 20:13:33 2014 +0200 7.2 +++ b/src/rend.cc Mon Nov 10 01:26:00 2014 +0200 7.3 @@ -1,4 +1,6 @@ 7.4 +#include <stdio.h> 7.5 #include <assert.h> 7.6 +#include <algorithm> 7.7 #include "scene.h" 7.8 #include "image.h" 7.9 #include "rend.h" 7.10 @@ -10,6 +12,7 @@ 7.11 TEX_SPHERES, 7.12 TEX_PLANES, 7.13 TEX_BOXES, 7.14 + TEX_CONES, 7.15 TEX_TEXTURES, 7.16 TEX_ENV, 7.17 TEX_XFORM, 7.18 @@ -31,6 +34,14 @@ 7.19 { 7.20 scn = s; 7.21 7.22 + int max_tex_units; 7.23 + glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &max_tex_units); 7.24 + printf("maximum texture units: %d\n", max_tex_units); 7.25 + if(NUM_SDR_TEXTURES > max_tex_units) { 7.26 + fprintf(stderr, "not enough texture units available!\n"); 7.27 + return false; 7.28 + } 7.29 + 7.30 glGenTextures(1, textures + TEX_RAYDIR); 7.31 glBindTexture(GL_TEXTURE_2D, textures[TEX_RAYDIR]); 7.32 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 7.33 @@ -46,6 +57,7 @@ 7.34 textures[TEX_SPHERES] = s->get_texture(GPUScene::TEX_SPHERE); 7.35 textures[TEX_PLANES] = s->get_texture(GPUScene::TEX_PLANE); 7.36 textures[TEX_BOXES] = s->get_texture(GPUScene::TEX_BOX); 7.37 + textures[TEX_CONES] = s->get_texture(GPUScene::TEX_CONE); 7.38 textures[TEX_TEXTURES] = s->get_texture(GPUScene::TEX_TEXTURE); 7.39 textures[TEX_ENV] = s->get_texture(GPUScene::TEX_ENV); 7.40 textures[TEX_XFORM] = s->get_texture(GPUScene::TEX_XFORM); 7.41 @@ -74,6 +86,7 @@ 7.42 set_uniform_int(sdr, "tex_spheres", TEX_SPHERES); 7.43 set_uniform_int(sdr, "tex_planes", TEX_PLANES); 7.44 set_uniform_int(sdr, "tex_boxes", TEX_BOXES); 7.45 + set_uniform_int(sdr, "tex_cones", TEX_CONES); 7.46 set_uniform_int(sdr, "tex_megatex", TEX_TEXTURES); 7.47 set_uniform_int(sdr, "tex_env", TEX_ENV); 7.48 set_uniform_int(sdr, "tex_xforms", TEX_XFORM);
8.1 --- a/src/scene_load.cc Sun Nov 09 20:13:33 2014 +0200 8.2 +++ b/src/scene_load.cc Mon Nov 10 01:26:00 2014 +0200 8.3 @@ -5,6 +5,7 @@ 8.4 #include "sphere.h" 8.5 #include "plane.h" 8.6 #include "box.h" 8.7 +#include "cone.h" 8.8 #include "light.h" 8.9 #include "camera.h" 8.10 #include "texture.h" 8.11 @@ -13,6 +14,7 @@ 8.12 static Object *parse_sphere(char **argv, const std::map<std::string, Material> &materials); 8.13 static Object *parse_plane(char **argv, const std::map<std::string, Material> &materials); 8.14 static Object *parse_box(char **argv, const std::map<std::string, Material> &materials); 8.15 +static Object *parse_cone(char **argv, const std::map<std::string, Material> &materials); 8.16 static Light *parse_light(char **argv); 8.17 static Camera *parse_camera(char **argv); 8.18 static bool parse_env(char **argv, Scene *scn); 8.19 @@ -77,6 +79,14 @@ 8.20 } 8.21 scn->add_object(obj); 8.22 8.23 + } else if(strstr(line, "cone") == line) { 8.24 + char *args = strip_space(line + strlen("cone")); 8.25 + Object *obj = parse_cone(split_args(args), materials); 8.26 + if(!obj) { 8.27 + goto err; 8.28 + } 8.29 + scn->add_object(obj); 8.30 + 8.31 } else if(strstr(line, "light") == line) { 8.32 char *args = strip_space(line + strlen("light")); 8.33 Light *lt = parse_light(split_args(args)); 8.34 @@ -153,6 +163,7 @@ 8.35 const Sphere *sph; 8.36 const Plane *plane; 8.37 const Box *box; 8.38 + const Cone *cone; 8.39 if((sph = dynamic_cast<const Sphere*>(obj))) { 8.40 fprintf(fp, "sphere -material %s", name); 8.41 fprintf(fp, " -center %.3f %.3f %.3f", sph->pos.x, sph->pos.y, sph->pos.z); 8.42 @@ -165,6 +176,10 @@ 8.43 fprintf(fp, "box -material %s", name); 8.44 fprintf(fp, " -min %.3f %.3f %.3f", box->min.x, box->min.y, box->min.z); 8.45 fprintf(fp, " -max %.3f %.3f %.3f\n", box->max.x, box->max.y, box->max.z); 8.46 + } else if((cone = dynamic_cast<const Cone*>(obj))) { 8.47 + fprintf(fp, "cone -material %s", name); 8.48 + fprintf(fp, " -angle %g", RAD_TO_DEG(cone->angle)); 8.49 + fprintf(fp, " -start %g -end %g\n", cone->ymin, cone->ymax); 8.50 } 8.51 } 8.52 8.53 @@ -374,6 +389,53 @@ 8.54 return box; 8.55 } 8.56 8.57 +static Object *parse_cone(char **argv, const std::map<std::string, Material> &materials) 8.58 +{ 8.59 + char *endp; 8.60 + Cone *cone = new Cone; 8.61 + 8.62 + for(int i=0; argv[i]; i++) { 8.63 + if(strcmp(argv[i], "-name") == 0) { 8.64 + cone->set_name(argv[++i]); 8.65 + 8.66 + } else if(strcmp(argv[i], "-angle") == 0) { 8.67 + cone->angle = DEG_TO_RAD(strtod(argv[++i], &endp)); 8.68 + if(endp == argv[i]) { 8.69 + fprintf(stderr, "failed to parse cone angle\n"); 8.70 + return 0; 8.71 + } 8.72 + 8.73 + } else if(strcmp(argv[i], "-start") == 0) { 8.74 + cone->ymin = strtod(argv[++i], &endp); 8.75 + if(endp == argv[i]) { 8.76 + fprintf(stderr, "failed to parse cone start\n"); 8.77 + return 0; 8.78 + } 8.79 + 8.80 + } else if(strcmp(argv[i], "-end") == 0) { 8.81 + cone->ymax = strtod(argv[++i], &endp); 8.82 + if(endp == argv[i]) { 8.83 + fprintf(stderr, "failed to parse cone end\n"); 8.84 + return 0; 8.85 + } 8.86 + 8.87 + } else if(strcmp(argv[i], "-material") == 0) { 8.88 + auto it = materials.find(argv[++i]); 8.89 + if(it == materials.end()) { 8.90 + fprintf(stderr, "material %s not found\n", argv[i]); 8.91 + return 0; 8.92 + } 8.93 + 8.94 + cone->material = it->second; 8.95 + } else { 8.96 + fprintf(stderr, "invalid box option: %s\n", argv[i]); 8.97 + return 0; 8.98 + } 8.99 + } 8.100 + 8.101 + return cone; 8.102 +} 8.103 + 8.104 static Light *parse_light(char **argv) 8.105 { 8.106 Light *lt = new Light;