bloboland
changeset 4:9021a906c5d3
lots of stuff
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 18 Dec 2012 06:13:09 +0200 |
parents | a39c301cdcce |
children | 2f4406cc341e |
files | sdr/bloboray.p.glsl src/game.cc src/level.cc src/level.h src/main.cc src/opt.cc src/opt.h src/renderer.cc src/renderer.h src/texture.cc src/texture.h |
diffstat | 11 files changed, 329 insertions(+), 30 deletions(-) [+] |
line diff
1.1 --- a/sdr/bloboray.p.glsl Sun Dec 16 14:24:16 2012 +0200 1.2 +++ b/sdr/bloboray.p.glsl Tue Dec 18 06:13:09 2012 +0200 1.3 @@ -12,32 +12,60 @@ 1.4 float t0, t1; 1.5 vec3 pos, normal; 1.6 vec4 color; 1.7 + vec3 refl; 1.8 }; 1.9 1.10 vec3 shade(Ray ray, HitPoint hit); 1.11 -HitPoint intersect_voxels(Ray ray); 1.12 +vec3 sky(Ray ray); 1.13 +HitPoint ray_march(Ray ray); 1.14 +float eval_blobs(vec3 pt); 1.15 +vec3 calc_blob_normal(vec3 pt); 1.16 HitPoint intersect_aabb(Ray ray, AABBox aabb); 1.17 Ray get_primary_ray(float x, float y); 1.18 +float luminance(vec3 col); 1.19 +float fresnel(float r, float cosa); 1.20 +vec3 get_blob(int i); 1.21 1.22 -#define RAY_STEP 0.001 1.23 +#define BLOB_THRESHOLD 0.5 1.24 +#define BLOB_SCALE (1.0 / 4.0) 1.25 +#define MAX_ITER 1 1.26 + 1.27 +#define RAY_STEP (0.75 / volsize.z) 1.28 1.29 #define FOV camprop.x 1.30 #define ASPECT camprop.y 1.31 uniform vec4 camprop; 1.32 uniform vec3 volsize; 1.33 uniform sampler3D voltex; 1.34 +uniform vec3 worldsize; 1.35 1.36 -//const vec3 worldsize = vec3(4.0, 4.0, 2.0); 1.37 -const vec3 worldsize = vec3(1.0, 1.0, 0.5); 1.38 +uniform sampler1D blobtex; 1.39 +uniform int num_blobs; 1.40 1.41 void main() 1.42 { 1.43 Ray ray = get_primary_ray(gl_TexCoord[0].x, gl_TexCoord[0].y); 1.44 1.45 + HitPoint hit; 1.46 vec3 color = vec3(0.0, 0.0, 0.0); 1.47 - HitPoint hit = intersect_voxels(ray); 1.48 - if(hit.hit) { 1.49 - color = shade(ray, hit); 1.50 + vec3 power = vec3(1.0, 1.0, 1.0); 1.51 + 1.52 + for(int i=0; i<=MAX_ITER; i++) { 1.53 + hit = ray_march(ray); 1.54 + if(hit.hit) { 1.55 + color += shade(ray, hit) * power; 1.56 + } else { 1.57 + color += sky(ray) * power; 1.58 + break; 1.59 + } 1.60 + 1.61 + ray.origin = hit.pos + hit.normal * RAY_STEP; 1.62 + ray.dir = reflect(ray.dir, hit.normal); 1.63 + power *= hit.refl; 1.64 + 1.65 + if(luminance(power) < 0.075) { 1.66 + break; 1.67 + } 1.68 } 1.69 1.70 gl_FragColor = vec4(color, 1.0); 1.71 @@ -55,9 +83,30 @@ 1.72 float ndoth = max(dot(hit.normal, hvec), 0.0); 1.73 1.74 vec3 diffuse = hit.color.xyz * ndotl; 1.75 - vec3 specular = vec3(0.4, 0.4, 0.4) * pow(ndoth, 60.0); 1.76 + vec3 specular = hit.refl * pow(ndoth, 60.0); 1.77 1.78 - return diffuse + specular; 1.79 + vec3 color = diffuse + specular; 1.80 + 1.81 + float fog = 0.0;//smoothstep(4.0, 8.0, hit.t0); 1.82 + 1.83 + //const float fog_density = 0.18; 1.84 + //float fog = exp(-fog_density * fog_density * hit.t0 * hit.t0); 1.85 + //fog = clamp(fog, 0.0, 1.0); 1.86 + 1.87 + return mix(color, sky(ray), fog); 1.88 +} 1.89 + 1.90 +#define M_PI 3.141592653 1.91 + 1.92 +vec3 sky(Ray ray) 1.93 +{ 1.94 + const vec3 horiz = vec3(0.64, 0.70, 0.76); 1.95 + const vec3 zenith = vec3(0.65, 0.82, 0.94); 1.96 + 1.97 + float angle = acos(ray.dir.y); 1.98 + float t = 1.0 - angle / (M_PI / 2.0); 1.99 + 1.100 + return mix(horiz, zenith, smoothstep(-0.2, 0.2, t)); 1.101 } 1.102 1.103 vec4 fetch_voxel(vec3 pt) 1.104 @@ -68,7 +117,7 @@ 1.105 1.106 vec3 calc_voxel_normal(vec3 pt) 1.107 { 1.108 - vec3 offs = 1.8 / volsize; 1.109 + vec3 offs = 6.0 / volsize; 1.110 float dfdx = fetch_voxel(pt + vec3(offs.x, 0.0, 0.0)).w - fetch_voxel(pt - vec3(offs.x, 0.0, 0.0)).w; 1.111 float dfdy = fetch_voxel(pt + vec3(0.0, offs.y, 0.0)).w - fetch_voxel(pt - vec3(0.0, offs.y, 0.0)).w; 1.112 float dfdz = fetch_voxel(pt + vec3(0.0, 0.0, offs.z)).w - fetch_voxel(pt - vec3(0.0, 0.0, offs.z)).w; 1.113 @@ -76,12 +125,17 @@ 1.114 return -normalize(vec3(dfdx, dfdy, dfdz)); 1.115 } 1.116 1.117 -HitPoint intersect_voxels(Ray ray) 1.118 +HitPoint ray_march(Ray ray) 1.119 { 1.120 HitPoint hit; 1.121 //AABBox aabb = AABBox(vec3(-1.0, -1.0, -1.0), vec3(1.0, 1.0, 1.0)); 1.122 AABBox aabb = AABBox(-worldsize.xzy, worldsize.xzy); 1.123 1.124 + hit.hit = false; 1.125 + hit.t0 = hit.t1 = 0.0; 1.126 + hit.pos = hit.normal = vec3(0.0, 0.0, 0.0); 1.127 + hit.color = vec4(1.0, 1.0, 1.0, 1.0); 1.128 + 1.129 1.130 hit = intersect_aabb(ray, aabb); 1.131 if(!hit.hit) { 1.132 @@ -96,14 +150,25 @@ 1.133 1.134 while(dist < end_dist) { 1.135 vec3 pt = ray.origin + ray.dir * dist; 1.136 + 1.137 + // first try evaluating the blob field at this point 1.138 + float blob = eval_blobs(pt); 1.139 + if(blob >= BLOB_THRESHOLD) { 1.140 + hit.t0 = dist; 1.141 + hit.pos = pt; 1.142 + hit.normal = calc_blob_normal(pt); 1.143 + hit.color = vec4(0.0, 0.0, 0.0, 1.0); 1.144 + hit.refl = vec3(1.0, 0.9, 0.75); 1.145 + return hit; 1.146 + } 1.147 + 1.148 vec4 voxel = fetch_voxel(pt.xzy); 1.149 - 1.150 - 1.151 if(voxel.a > 0.5) { 1.152 hit.t0 = dist; 1.153 hit.pos = pt; 1.154 hit.normal = calc_voxel_normal(pt.xzy).xzy; 1.155 hit.color = voxel; 1.156 + hit.refl = vec3(0.0, 0.0, 0.0); 1.157 return hit; 1.158 } 1.159 1.160 @@ -114,24 +179,48 @@ 1.161 return hit; 1.162 } 1.163 1.164 +float eval_blobs(vec3 pt) 1.165 +{ 1.166 + float val = 0.0; 1.167 + 1.168 + for(int i=0; i<num_blobs; i++) { 1.169 + float dist = length(pt - get_blob(i)); 1.170 + val += (dist * dist * (3.0 - 2.0 * dist)); 1.171 + } 1.172 + return val; 1.173 +} 1.174 + 1.175 +vec3 calc_blob_normal(vec3 pt) 1.176 +{ 1.177 + const float offs = 0.01; 1.178 + vec3 grad; 1.179 + grad.x = eval_blobs(pt + vec3(offs, 0.0, 0.0)) - eval_blobs(pt - vec3(offs, 0.0, 0.0)); 1.180 + grad.y = eval_blobs(pt + vec3(0.0, offs, 0.0)) - eval_blobs(pt - vec3(0.0, offs, 0.0)); 1.181 + grad.z = eval_blobs(pt + vec3(0.0, 0.0, offs)) - eval_blobs(pt - vec3(0.0, 0.0, offs)); 1.182 + 1.183 + return -normalize(grad); 1.184 +} 1.185 + 1.186 HitPoint intersect_aabb(Ray ray, AABBox aabb) 1.187 { 1.188 HitPoint res; 1.189 1.190 + res.pos = res.normal = vec3(0.0, 0.0, 0.0); 1.191 + res.color = vec4(1.0, 1.0, 1.0, 1.0); 1.192 + res.refl = vec3(0.0, 0.0, 0.0); 1.193 + 1.194 vec3 invR = 1.0 / ray.dir; 1.195 - vec3 tbot = invR * (aabb.vmin - ray.origin); 1.196 - vec3 ttop = invR * (aabb.vmax - ray.origin); 1.197 - vec3 tmin = min(ttop, tbot); 1.198 - vec3 tmax = max(ttop, tbot); 1.199 - vec2 t = max(tmin.xx, tmin.yz); 1.200 - float t0 = max(t.x, t.y); 1.201 - t = min(tmax.xx, tmax.yz); 1.202 - float t1 = min(t.x, t.y); 1.203 + vec3 tbot = invR * (aabb.vmin - ray.origin); 1.204 + vec3 ttop = invR * (aabb.vmax - ray.origin); 1.205 + vec3 tmin = min(ttop, tbot); 1.206 + vec3 tmax = max(ttop, tbot); 1.207 + vec2 t = max(tmin.xx, tmin.yz); 1.208 + res.t0 = max(t.x, t.y); 1.209 + t = min(tmax.xx, tmax.yz); 1.210 + res.t1 = min(t.x, t.y); 1.211 1.212 - if(t0 <= t1) { 1.213 + if(res.t0 <= res.t1) { 1.214 res.hit = true; 1.215 - res.t0 = t0; 1.216 - res.t1 = t1; 1.217 } else { 1.218 res.hit = false; 1.219 } 1.220 @@ -150,3 +239,24 @@ 1.221 ray.dir = gl_NormalMatrix * normalize(dir); 1.222 return ray; 1.223 } 1.224 + 1.225 +float luminance(vec3 col) 1.226 +{ 1.227 + //const vec3 fact = vec3(0.2126, 0.7152, 0.0722); 1.228 + //return dot(col, fact); 1.229 + return (col.x + col.y + col.z) / 3.0; 1.230 +} 1.231 + 1.232 +float fresnel(float r, float cosa) 1.233 +{ 1.234 + float inv_cosa = 1.0 - cosa; 1.235 + float inv_cosa_sq = inv_cosa * inv_cosa; 1.236 + 1.237 + return r + (1.0 - r) * inv_cosa_sq * inv_cosa_sq * inv_cosa; 1.238 +} 1.239 + 1.240 +vec3 get_blob(int i) 1.241 +{ 1.242 + float tc = float(i) / float(num_blobs); 1.243 + return texture1D(blobtex, tc).xyz; 1.244 +}
2.1 --- a/src/game.cc Sun Dec 16 14:24:16 2012 +0200 2.2 +++ b/src/game.cc Tue Dec 18 06:13:09 2012 +0200 2.3 @@ -20,6 +20,9 @@ 2.4 static Renderer *rend; 2.5 static FpsCamera cam; 2.6 2.7 +static const float fog_color[] = {0.76, 0.64, 0.91, 1.0}; 2.8 +static Vector3 gravity; 2.9 + 2.10 bool game_init() 2.11 { 2.12 printf("initializing OpenGL state\n"); 2.13 @@ -33,6 +36,7 @@ 2.14 2.15 printf("generating level\n"); 2.16 level = new Level; 2.17 + level->world_size = Vector3(8, 8, 4); 2.18 level->generate(); 2.19 2.20 printf("initializing renderer\n"); 2.21 @@ -44,6 +48,11 @@ 2.22 cam.input_move(0, 2, 2); 2.23 cam.input_rotate(0, M_PI / 5, 0); 2.24 2.25 + glClearColor(fog_color[0], fog_color[1], fog_color[2], 1.0); 2.26 + glFogfv(GL_FOG_COLOR, fog_color); 2.27 + 2.28 + gravity = Vector3(0, -0.01, 0); 2.29 + 2.30 return true; 2.31 } 2.32 2.33 @@ -73,6 +82,18 @@ 2.34 } 2.35 2.36 cam.input_move(dx, 0, dy); 2.37 + 2.38 + for(size_t i=0; i<level->blobs.size(); i++) { 2.39 + Blob *b = &level->blobs[i]; 2.40 + 2.41 + b->velocity += gravity * dt; 2.42 + Vector3 npos = b->pos + b->velocity * dt; 2.43 + 2.44 + Vector3 normal; 2.45 + if(level->collision(b->pos, npos, &npos, &normal)) { 2.46 + b->velocity = b->velocity.reflection(normal); 2.47 + } 2.48 + } 2.49 } 2.50 2.51 void game_render() 2.52 @@ -81,6 +102,7 @@ 2.53 2.54 if(opt.stereo) { 2.55 glDrawBuffer(GL_BACK_LEFT); 2.56 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 2.57 2.58 glMatrixMode(GL_PROJECTION); 2.59 glLoadIdentity(); 2.60 @@ -92,6 +114,7 @@ 2.61 rend->render(); 2.62 2.63 glDrawBuffer(GL_BACK_RIGHT); 2.64 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 2.65 2.66 glMatrixMode(GL_PROJECTION); 2.67 glLoadIdentity(); 2.68 @@ -102,6 +125,8 @@ 2.69 2.70 rend->render(); 2.71 } else { 2.72 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 2.73 + 2.74 glMatrixMode(GL_PROJECTION); 2.75 glLoadIdentity(); 2.76 proj_matrix(0);
3.1 --- a/src/level.cc Sun Dec 16 14:24:16 2012 +0200 3.2 +++ b/src/level.cc Tue Dec 18 06:13:09 2012 +0200 3.3 @@ -5,6 +5,7 @@ 3.4 Level::Level() 3.5 { 3.6 terrain = 0; 3.7 + world_size = Vector3(1, 1, 1); 3.8 } 3.9 3.10 Level::~Level() 3.11 @@ -19,7 +20,7 @@ 3.12 float valley = nx * nx + ny * ny; 3.13 3.14 float s = opt.gen_noise_scale; 3.15 - float noise = 0.2 * fbm2(x * s, y * s, 3) * (valley + 0.25); 3.16 + float noise = 0.2 * fbm2(x * s, y * s, 4) * (valley + 0.25); 3.17 float grad = 0.75 - z + noise + valley * 0.4; 3.18 3.19 return grad; 3.20 @@ -56,7 +57,7 @@ 3.21 } else if(z < 0.8) { 3.22 if(alpha < 0.56) { 3.23 // grass 3.24 - voxel = Vector4(0.68, 0.95, 0.38); 3.25 + voxel = Vector4(0.49, 0.72, 0.48); 3.26 } else { 3.27 // mud 3.28 voxel = Vector4(0.57, 0.43, 0.29, 1); 3.29 @@ -68,6 +69,14 @@ 3.30 } 3.31 } 3.32 } 3.33 + 3.34 + // generate some blobs 3.35 + for(int i=0; i<opt.gen_num_blobs; i++) { 3.36 + Blob b; 3.37 + b.pos = Vector3(frand(1.0) - 0.5, 10.0, frand(1.0) - 0.5); 3.38 + b.velocity = Vector3(0, 0, 0); 3.39 + blobs.push_back(b); 3.40 + } 3.41 } 3.42 3.43 bool Level::load(const char *fname) 3.44 @@ -79,3 +88,50 @@ 3.45 { 3.46 return false; 3.47 } 3.48 + 3.49 +#define CLAMP(x, a, b) ((x) < (a) ? (a) : ((x) > (b) ? (b) : (x))) 3.50 + 3.51 +const Vector4 &Level::get_voxel(const Vector3 &pos) const 3.52 +{ 3.53 + Vector3 p = pos / world_size + Vector3(0.5, 0.5, 0.5); 3.54 + 3.55 + int xsz = terrain->get_size(0); 3.56 + int ysz = terrain->get_size(1); 3.57 + int zsz = terrain->get_size(2); 3.58 + 3.59 + int i = (int)(p.x * xsz); 3.60 + int j = (int)(p.y * ysz); 3.61 + int k = (int)(p.z * zsz); 3.62 + 3.63 + return terrain->get_voxel(CLAMP(i, 0, xsz - 1), CLAMP(j, 0, ysz - 1), CLAMP(k, 0, zsz - 1)); 3.64 +} 3.65 + 3.66 +Vector3 Level::calc_normal(const Vector3 &pos) const 3.67 +{ 3.68 + int xsz = terrain->get_size(0); 3.69 + int ysz = terrain->get_size(1); 3.70 + int zsz = terrain->get_size(2); 3.71 + 3.72 + float dx = world_size.x / (float)xsz; 3.73 + float dy = world_size.y / (float)ysz; 3.74 + float dz = world_size.z / (float)zsz; 3.75 + 3.76 + float dfdx = get_voxel(pos + Vector3(dx, 0, 0)).w - get_voxel(pos - Vector3(dx, 0, 0)).w; 3.77 + float dfdy = get_voxel(pos + Vector3(0, dy, 0)).w - get_voxel(pos - Vector3(0, dy, 0)).w; 3.78 + float dfdz = get_voxel(pos + Vector3(0, 0, dz)).w - get_voxel(pos - Vector3(0, 0, dz)).w; 3.79 + 3.80 + return Vector3(dfdx, dfdy, dfdz); 3.81 +} 3.82 + 3.83 +bool Level::collision(const Vector3 &pos0, const Vector3 &pos1, Vector3 *outpos, Vector3 *outnorm) const 3.84 +{ 3.85 + Vector4 vox0 = get_voxel(pos0); 3.86 + Vector4 vox1 = get_voxel(pos1); 3.87 + 3.88 + if(vox0.w < 0.5 && vox1.w >= 0.5) { 3.89 + *outpos = lerp(pos0, pos1, 0.5); // TODO 3.90 + *outnorm = calc_normal(*outpos); 3.91 + return true; 3.92 + } 3.93 + return false; 3.94 +}
4.1 --- a/src/level.h Sun Dec 16 14:24:16 2012 +0200 4.2 +++ b/src/level.h Tue Dec 18 06:13:09 2012 +0200 4.3 @@ -4,10 +4,17 @@ 4.4 #include <vector> 4.5 #include "volume.h" 4.6 4.7 +struct Blob { 4.8 + Vector3 pos; 4.9 + Vector3 velocity; 4.10 +}; 4.11 + 4.12 class Level { 4.13 public: 4.14 Volume *terrain; 4.15 - std::vector<Vector3> blobs; 4.16 + std::vector<Blob> blobs; 4.17 + 4.18 + Vector3 world_size; 4.19 4.20 Level(); 4.21 ~Level(); 4.22 @@ -16,6 +23,11 @@ 4.23 4.24 bool load(const char *fname); 4.25 bool save(const char *fname) const; 4.26 + 4.27 + const Vector4 &get_voxel(const Vector3 &pos) const; 4.28 + Vector3 calc_normal(const Vector3 &pos) const; 4.29 + 4.30 + bool collision(const Vector3 &pos0, const Vector3 &pos1, Vector3 *outpos, Vector3 *outnorm) const; 4.31 }; 4.32 4.33 #endif // LEVEL_H_
5.1 --- a/src/main.cc Sun Dec 16 14:24:16 2012 +0200 5.2 +++ b/src/main.cc Tue Dec 18 06:13:09 2012 +0200 5.3 @@ -63,7 +63,6 @@ 5.4 game_iter((msec - prev_msec) / 1000.0); 5.5 prev_msec = msec; 5.6 5.7 - 5.8 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 5.9 5.10 game_render();
6.1 --- a/src/opt.cc Sun Dec 16 14:24:16 2012 +0200 6.2 +++ b/src/opt.cc Tue Dec 18 06:13:09 2012 +0200 6.3 @@ -15,6 +15,7 @@ 6.4 opt.world_size[2] = 64; 6.5 6.6 opt.gen_noise_scale = 1.0f; 6.7 + opt.gen_num_blobs = 10; 6.8 } 6.9 6.10 bool parse_opt(int argc, char **argv) 6.11 @@ -40,6 +41,13 @@ 6.12 fprintf(stderr, "-genscale must be followed by a scaling factor\n"); 6.13 return false; 6.14 } 6.15 + } else if(strcmp(argv[i], "-blobs") == 0) { 6.16 + char *endp; 6.17 + opt.gen_num_blobs = strtol(argv[++i], &endp, 10); 6.18 + if(endp == argv[i]) { 6.19 + fprintf(stderr, "-blobs must be followed by the number of blobs\n"); 6.20 + return false; 6.21 + } 6.22 } else if(strcmp(argv[i], "-stereo") == 0) { 6.23 opt.stereo = true; 6.24 } else {
7.1 --- a/src/opt.h Sun Dec 16 14:24:16 2012 +0200 7.2 +++ b/src/opt.h Tue Dec 18 06:13:09 2012 +0200 7.3 @@ -8,6 +8,7 @@ 7.4 // initial parameters when generating new worlds 7.5 int world_size[3]; 7.6 float gen_noise_scale; 7.7 + int gen_num_blobs; 7.8 }; 7.9 7.10 extern Options opt;
8.1 --- a/src/renderer.cc Sun Dec 16 14:24:16 2012 +0200 8.2 +++ b/src/renderer.cc Tue Dec 18 06:13:09 2012 +0200 8.3 @@ -4,6 +4,7 @@ 8.4 8.5 Renderer::Renderer() 8.6 { 8.7 + blobtex = 0; 8.8 leveltex = 0; 8.9 sdrprog = 0; 8.10 8.11 @@ -29,6 +30,10 @@ 8.12 leveltex = new Texture3D; 8.13 leveltex->create(vol->get_size(0), vol->get_size(1), vol->get_size(2)); 8.14 8.15 + blobtex = new Texture1D; 8.16 + blobtex->create(level->blobs.size()); 8.17 + blobtex->set_filtering(GL_NEAREST); 8.18 + 8.19 this->level = level; 8.20 8.21 return true; 8.22 @@ -57,11 +62,19 @@ 8.23 void Renderer::render() const 8.24 { 8.25 leveltex->update((float*)level->terrain->get_data_ptr()); 8.26 - bind_texture(leveltex); 8.27 + ((Renderer*)this)->update_blobtex(); 8.28 8.29 + bind_texture(leveltex, 0); 8.30 + bind_texture(blobtex, 1); 8.31 + 8.32 + set_uniform_float3(sdrprog, "worldsize", level->world_size.x, level->world_size.y, 8.33 + level->world_size.z); 8.34 set_uniform_float3(sdrprog, "volsize", level->terrain->get_size(0), 8.35 level->terrain->get_size(1), level->terrain->get_size(2)); 8.36 set_uniform_float4(sdrprog, "camprop", fov, aspect, 0, 0); 8.37 + 8.38 + set_uniform_int(sdrprog, "voltex", 0); 8.39 + set_uniform_int(sdrprog, "blobtex", 1); 8.40 bind_program(sdrprog); 8.41 8.42 glBegin(GL_QUADS); 8.43 @@ -76,7 +89,8 @@ 8.44 glEnd(); 8.45 8.46 bind_program(0); 8.47 - bind_texture(0); 8.48 + bind_texture(0, 1); 8.49 + bind_texture(0, 0); 8.50 8.51 /*glEnable(GL_COLOR_MATERIAL); 8.52 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); 8.53 @@ -147,3 +161,20 @@ 8.54 glVertex3f(pos.x - sz, pos.y - sz, pos.z + sz); 8.55 8.56 } 8.57 + 8.58 +void Renderer::update_blobtex() 8.59 +{ 8.60 + int nblobs = (int)level->blobs.size(); 8.61 + 8.62 + float *data = (float*)alloca(nblobs * 4 * sizeof *data); 8.63 + float *dptr = data; 8.64 + 8.65 + for(int i=0; i<nblobs; i++) { 8.66 + *dptr++ = level->blobs[i].pos.x; 8.67 + *dptr++ = level->blobs[i].pos.y; 8.68 + *dptr++ = level->blobs[i].pos.z; 8.69 + *dptr++ = 1.0; 8.70 + } 8.71 + 8.72 + blobtex->update(data); 8.73 +}
9.1 --- a/src/renderer.h Sun Dec 16 14:24:16 2012 +0200 9.2 +++ b/src/renderer.h Tue Dec 18 06:13:09 2012 +0200 9.3 @@ -7,11 +7,14 @@ 9.4 class Renderer { 9.5 private: 9.6 Level *level; 9.7 + Texture1D *blobtex; 9.8 Texture3D *leveltex; 9.9 unsigned int sdrprog; 9.10 9.11 float fov, aspect; 9.12 9.13 + void update_blobtex(); 9.14 + 9.15 public: 9.16 Renderer(); 9.17 ~Renderer();
10.1 --- a/src/texture.cc Sun Dec 16 14:24:16 2012 +0200 10.2 +++ b/src/texture.cc Tue Dec 18 06:13:09 2012 +0200 10.3 @@ -38,11 +38,53 @@ 10.4 } 10.5 } 10.6 10.7 +void Texture::set_filtering(unsigned int min_filter, unsigned int mag_filter) 10.8 +{ 10.9 + if(mag_filter == 0) { 10.10 + mag_filter = min_filter; 10.11 + } 10.12 + 10.13 + glBindTexture(type, tex); 10.14 + glTexParameteri(type, GL_TEXTURE_MIN_FILTER, min_filter); 10.15 + glTexParameteri(type, GL_TEXTURE_MAG_FILTER, mag_filter); 10.16 +} 10.17 + 10.18 +void Texture::set_wrapping(unsigned int wrap) 10.19 +{ 10.20 + glBindTexture(type, tex); 10.21 + glTexParameteri(type, GL_TEXTURE_WRAP_S, wrap); 10.22 + glTexParameteri(type, GL_TEXTURE_WRAP_T, wrap); 10.23 + glTexParameteri(type, GL_TEXTURE_WRAP_R, wrap); 10.24 +} 10.25 + 10.26 int Texture::get_size(int idx) const 10.27 { 10.28 return idx >= 0 && idx < 3 ? size[idx] : 0; 10.29 } 10.30 10.31 +Texture1D::Texture1D() 10.32 +{ 10.33 + type = GL_TEXTURE_1D; 10.34 + 10.35 + glBindTexture(type, tex); 10.36 + glTexParameteri(type, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 10.37 + glTexParameteri(type, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 10.38 +} 10.39 + 10.40 +void Texture1D::create(int sz, float *data) 10.41 +{ 10.42 + glBindTexture(type, tex); 10.43 + glTexImage1D(type, 0, GL_RGBA, sz, 0, GL_RGBA, GL_FLOAT, data); 10.44 + 10.45 + size[0] = sz; 10.46 +} 10.47 + 10.48 +void Texture1D::update(float *data) 10.49 +{ 10.50 + glBindTexture(type, tex); 10.51 + glTexSubImage1D(type, 0, 0, size[0], GL_RGBA, GL_FLOAT, data); 10.52 +} 10.53 + 10.54 Texture2D::Texture2D() 10.55 { 10.56 type = GL_TEXTURE_2D;
11.1 --- a/src/texture.h Sun Dec 16 14:24:16 2012 +0200 11.2 +++ b/src/texture.h Tue Dec 18 06:13:09 2012 +0200 11.3 @@ -12,6 +12,9 @@ 11.4 Texture(); 11.5 virtual ~Texture(); 11.6 11.7 + virtual void set_filtering(unsigned int min_filter, unsigned int mag_filter = 0); 11.8 + virtual void set_wrapping(unsigned int wrap); 11.9 + 11.10 virtual int get_size(int idx) const; 11.11 11.12 virtual void update(float *data) = 0; 11.13 @@ -21,6 +24,15 @@ 11.14 11.15 void bind_texture(const Texture *tex, int texunit = 0); 11.16 11.17 +class Texture1D : public Texture { 11.18 +public: 11.19 + Texture1D(); 11.20 + 11.21 + void create(int sz, float *data = 0); 11.22 + 11.23 + void update(float *data); 11.24 +}; 11.25 + 11.26 class Texture2D : public Texture { 11.27 public: 11.28 Texture2D();