diff options
| author | Simon Robertshaw <simon@hardwired.org.uk> | 2011-07-18 22:58:08 (GMT) |
|---|---|---|
| committer | Simon Robertshaw <simon@hardwired.org.uk> | 2011-07-18 22:58:08 (GMT) |
| commit | 68404608f69a03546b91b4e1fe800abf48a88e74 (patch) | |
| tree | af8db7f2b4cdf591e231a55a41f1c4c18cb528b4 /src | |
| parent | 0fbe6e2d3fbe045e0db233c27bacc3b370b08753 (diff) | |
| download | powder-68404608f69a03546b91b4e1fe800abf48a88e74.zip powder-68404608f69a03546b91b4e1fe800abf48a88e74.tar.gz | |
Lensing effect for gravity, adds 3 new gravity maps (full resolution, linear interpolation for faux accuracy), old ones should be removed in time.
Diffstat (limited to 'src')
| -rw-r--r-- | src/air.c | 37 | ||||
| -rw-r--r-- | src/graphics.c | 38 | ||||
| -rw-r--r-- | src/main.c | 63 |
3 files changed, 123 insertions, 15 deletions
@@ -7,12 +7,20 @@ float kernel[9]; float gravmap[YRES/CELL][XRES/CELL]; //Maps to be used by the main thread float gravx[YRES/CELL][XRES/CELL]; float gravy[YRES/CELL][XRES/CELL]; +float gravp[YRES/CELL][XRES/CELL]; +float *gravpf; +float *gravyf; +float *gravxf; unsigned gravmask[YRES/CELL][XRES/CELL]; float th_ogravmap[YRES/CELL][XRES/CELL]; // Maps to be processed by the gravity thread float th_gravmap[YRES/CELL][XRES/CELL]; float th_gravx[YRES/CELL][XRES/CELL]; float th_gravy[YRES/CELL][XRES/CELL]; +float th_gravp[YRES/CELL][XRES/CELL]; +float *th_gravpf; +float *th_gravyf; +float *th_gravxf; float vx[YRES/CELL][XRES/CELL], ovx[YRES/CELL][XRES/CELL]; float vy[YRES/CELL][XRES/CELL], ovy[YRES/CELL][XRES/CELL]; @@ -119,6 +127,31 @@ void update_airh(void) } memcpy(hv, ohv, sizeof(hv)); } +void bilinear_interpolation(float *src, float *dst, int sw, int sh, int rw, int rh) +{ + int y, x, fxceil, fyceil; + float fx, fy, fyc, fxc; + double intp; + float tr, tl, br, bl; + //Bilinear interpolation for upscaling + for (y=0; y<rh; y++) + for (x=0; x<rw; x++) + { + fx = ((float)x)*((float)sw)/((float)rw); + fy = ((float)y)*((float)sh)/((float)rh); + fxc = modf(fx, &intp); + fyc = modf(fy, &intp); + fxceil = (int)ceil(fx); + fyceil = (int)ceil(fy); + if (fxceil>=sw) fxceil = sw-1; + if (fyceil>=sh) fyceil = sh-1; + tr = src[sw*(int)floor(fy)+fxceil]; + tl = src[sw*(int)floor(fy)+(int)floor(fx)]; + br = src[sw*fyceil+fxceil]; + bl = src[sw*fyceil+(int)floor(fx)]; + dst[rw*y+x] = ((tl*(1.0f-fxc))+(tr*(fxc)))*(1.0f-fyc) + ((bl*(1.0f-fxc))+(br*(fxc)))*(fyc); + } +} void update_grav(void) { @@ -164,11 +197,15 @@ void update_grav(void) #endif th_gravx[y][x] += M_GRAV * val * (j - x) / pow(distance, 3); th_gravy[y][x] += M_GRAV * val * (i - y) / pow(distance, 3); + th_gravp[y][x] += M_GRAV * val / pow(distance, 2); } } } } } + bilinear_interpolation(th_gravy, th_gravyf, XRES/CELL, YRES/CELL, XRES, YRES); + bilinear_interpolation(th_gravx, th_gravxf, XRES/CELL, YRES/CELL, XRES, YRES); + bilinear_interpolation(th_gravp, th_gravpf, XRES/CELL, YRES/CELL, XRES, YRES); fin: memcpy(th_ogravmap, th_gravmap, sizeof(th_gravmap)); memset(th_gravmap, 0, sizeof(th_gravmap)); diff --git a/src/graphics.c b/src/graphics.c index 3f36097..1d9438e 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -3355,7 +3355,6 @@ void draw_parts(pixel *vid) #ifdef OpenGL glFlush (); #endif - } void draw_walls(pixel *vid) { @@ -3747,9 +3746,40 @@ void render_signs(pixel *vid_buf) } } -void render_fire(pixel *dst) +void render_gravlensing(pixel *src, pixel * dst) +{ + int nx, ny, rx, ry, gx, gy, bx, by; + for(nx = 0; nx < XRES; nx++) + { + for(ny = 0; ny < YRES; ny++) + { + rx = nx-(gravxf[(ny*XRES)+nx]*0.5f); + ry = ny-(gravyf[(ny*XRES)+nx]*0.5f); + gx = nx-(gravxf[(ny*XRES)+nx]*0.75f); + gy = ny-(gravyf[(ny*XRES)+nx]*0.75f); + bx = nx-(gravxf[(ny*XRES)+nx]); + by = ny-(gravyf[(ny*XRES)+nx]); + if(rx > 0 && rx < XRES && ry > 0 && ry < YRES && gx > 0 && gx < XRES && gy > 0 && gy < YRES && bx > 0 && bx < XRES && by > 0 && by < YRES) + addpixel(dst, nx, ny, PIXR(src[ry*(XRES+BARSIZE)+rx]), PIXG(src[gy*(XRES+BARSIZE)+gx]), PIXB(src[by*(XRES+BARSIZE)+bx]), 255); + /*rx = nx+(gravxf[(ny*XRES)+nx]*0.5f); + ry = ny+(gravyf[(ny*XRES)+nx]*0.5f); + gx = nx+(gravxf[(ny*XRES)+nx]*0.75f); + gy = ny+(gravyf[(ny*XRES)+nx]*0.75f); + bx = nx+(gravxf[(ny*XRES)+nx]); + by = ny+(gravyf[(ny*XRES)+nx]); + if(rx > 0 && rx < XRES && ry > 0 && ry < YRES && gravp[ny/CELL][nx/CELL]*0.5f > -8.0f) + addpixel(dst, rx, ry, PIXR(src[ry*(XRES+BARSIZE)+rx]), 0, 0, 255); + if(gx > 0 && gx < XRES && gy > 0 && gy < YRES && gravp[ny/CELL][nx/CELL]*0.75f > -8.0f) + addpixel(dst, gx, gy, 0, PIXG(src[ry*(XRES+BARSIZE)+rx]), 0, 255); + if(bx > 0 && bx < XRES && by > 0 && by < YRES && gravp[ny/CELL][nx/CELL] > -8.0f) + addpixel(dst, bx, by, 0, 0, PIXB(src[ry*(XRES+BARSIZE)+rx]), 255);*/ + } + } +} + +void render_fire(pixel *vid) { - int i,j,x,y,r,g,b; + int i,j,x,y,r,g,b,nx,ny; for (j=0; j<YRES/CELL; j++) for (i=0; i<XRES/CELL; i++) { @@ -3759,7 +3789,7 @@ void render_fire(pixel *dst) if (r || g || b) for (y=-CELL+1; y<2*CELL; y++) for (x=-CELL+1; x<2*CELL; x++) - addpixel(dst, i*CELL+x, j*CELL+y, r, g, b, fire_alpha[y+CELL][x+CELL]); + addpixel(vid, i*CELL+x, j*CELL+y, r, g, b, fire_alpha[y+CELL][x+CELL]); for (y=-1; y<2; y++) for (x=-1; x<2; x++) if (i+x>=0 && j+y>=0 && i+x<XRES/CELL && j+y<YRES/CELL && (x || y)) @@ -1543,6 +1543,8 @@ int main(int argc, char *argv[]) #else int main(int argc, char *argv[]) { + pixel *part_vbuf; //Extra video buffer + pixel *part_vbuf_store; int hud_enable = 1; int active_menu = 0; #ifdef BETA @@ -1580,7 +1582,18 @@ int main(int argc, char *argv[]) pthread_win32_thread_attach_np(); #endif vid_buf = calloc((XRES+BARSIZE)*(YRES+MENUSIZE), PIXELSIZE); + part_vbuf = calloc((XRES+BARSIZE)*(YRES+MENUSIZE), PIXELSIZE); //Extra video buffer + part_vbuf_store = part_vbuf; pers_bg = calloc((XRES+BARSIZE)*YRES, PIXELSIZE); + + //Allocate full size Gravmaps + th_gravyf = calloc(XRES*YRES, sizeof(float)); + th_gravxf = calloc(XRES*YRES, sizeof(float)); + th_gravpf = calloc(XRES*YRES, sizeof(float)); + gravyf = calloc(XRES*YRES, sizeof(float)); + gravxf = calloc(XRES*YRES, sizeof(float)); + gravpf = calloc(XRES*YRES, sizeof(float)); + GSPEED = 1; /* Set 16-bit stereo audio at 22Khz */ @@ -1784,6 +1797,15 @@ int main(int argc, char *argv[]) #ifdef OpenGL ClearScreen(); #else + + if(cmode==CM_FANCY) + { + part_vbuf = part_vbuf_store; + memset(vid_buf, 0, (XRES+BARSIZE)*YRES*PIXELSIZE); + } else { + part_vbuf = vid_buf; + } + if(gravwl_timeout) { if(gravwl_timeout==1) @@ -1792,16 +1814,16 @@ int main(int argc, char *argv[]) } if (cmode==CM_VEL || cmode==CM_PRESS || cmode==CM_CRACK || (cmode==CM_HEAT && aheat_enable))//air only gets drawn in these modes { - draw_air(vid_buf); + draw_air(part_vbuf); } else if (cmode==CM_PERS)//save background for persistent, then clear { - memcpy(vid_buf, pers_bg, (XRES+BARSIZE)*YRES*PIXELSIZE); - memset(vid_buf+((XRES+BARSIZE)*YRES), 0, ((XRES+BARSIZE)*YRES*PIXELSIZE)-((XRES+BARSIZE)*YRES*PIXELSIZE)); - } + memcpy(part_vbuf, pers_bg, (XRES+BARSIZE)*YRES*PIXELSIZE); + memset(part_vbuf+((XRES+BARSIZE)*YRES), 0, ((XRES+BARSIZE)*YRES*PIXELSIZE)-((XRES+BARSIZE)*YRES*PIXELSIZE)); +} else //clear screen every frame { - memset(vid_buf, 0, (XRES+BARSIZE)*YRES*PIXELSIZE); + memset(part_vbuf, 0, (XRES+BARSIZE)*YRES*PIXELSIZE); } #endif @@ -1817,11 +1839,11 @@ int main(int argc, char *argv[]) if(ngrav_enable && drawgrav_enable) draw_grav(vid_buf); - draw_walls(vid_buf); - update_particles(vid_buf); //update everything - draw_parts(vid_buf); //draw particles + draw_walls(part_vbuf); + update_particles(part_vbuf); //update everything + draw_parts(part_vbuf); //draw particles if(sl == WL_GRAV+100 || sr == WL_GRAV+100) - draw_grav_zones(vid_buf); + draw_grav_zones(part_vbuf); if(ngrav_enable){ pthread_mutex_lock(&gravmutex); @@ -1831,6 +1853,22 @@ int main(int argc, char *argv[]) memcpy(th_gravmap, gravmap, sizeof(gravmap)); //Move our current gravmap to be processed other thread memcpy(gravy, th_gravy, sizeof(gravy)); //Hmm, Gravy memcpy(gravx, th_gravx, sizeof(gravx)); //Move the processed velocity maps to be used + memcpy(gravp, th_gravp, sizeof(gravp)); + + //Switch the full size gravmaps, we don't really need the two above any more + float *tmpf; + tmpf = gravyf; + gravyf = th_gravyf; + th_gravyf = tmpf; + + tmpf = gravxf; + gravxf = th_gravxf; + th_gravxf = tmpf; + + tmpf = gravpf; + gravpf = th_gravpf; + th_gravpf = tmpf; + if (!sys_pause||framerender){ //Only update if not paused grav_ready = 0; //Tell the other thread that we're ready for it to continue pthread_cond_signal(&gravcv); @@ -1863,9 +1901,12 @@ int main(int argc, char *argv[]) fire_fc = (fire_fc+1) % 3; } if (cmode==CM_FIRE||cmode==CM_BLOB||cmode==CM_FANCY) - render_fire(vid_buf); + render_fire(part_vbuf); - render_signs(vid_buf); + render_signs(part_vbuf); + + if(cmode==CM_FANCY) + render_gravlensing(part_vbuf, vid_buf); memset(vid_buf+((XRES+BARSIZE)*YRES), 0, (PIXELSIZE*(XRES+BARSIZE))*MENUSIZE);//clear menu areas clearrect(vid_buf, XRES-1, 0, BARSIZE+1, YRES); |
