/* * Renderer.cpp * * Created on: Jan 7, 2012 * Author: Simon */ #include #include #include "Config.h" #include "Renderer.h" #include "Graphics.h" #include "simulation/Elements.h" #include "simulation/ElementFunctions.h" #include "simulation/ElementGraphics.h" #include "simulation/Air.h" extern "C" { #include "hmap.h" } void Renderer::RenderZoom() { if(!zoomEnabled) return; #ifdef OGLR int origBlendSrc, origBlendDst; float zcx1, zcx0, zcy1, zcy0, yfactor, xfactor, i; //X-Factor is shit, btw xfactor = 1.0f/(float)XRES; yfactor = 1.0f/(float)YRES; zcx0 = (zoom_x)*xfactor; zcx1 = (zoom_x+ZSIZE)*xfactor; zcy0 = (zoom_y)*yfactor; zcy1 = ((zoom_y+ZSIZE))*yfactor; glGetIntegerv(GL_BLEND_SRC, &origBlendSrc); glGetIntegerv(GL_BLEND_DST, &origBlendDst); glBlendFunc(GL_ONE, GL_ZERO); glEnable( GL_TEXTURE_2D ); //glReadBuffer(GL_AUX0); glBindTexture(GL_TEXTURE_2D, partsFboTex); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glBegin(GL_QUADS); glTexCoord2d(zcx1, zcy1); glVertex3f((zoom_wx+ZSIZE*ZFACTOR)*sdl_scale, (YRES+MENUSIZE-(zoom_wy+ZSIZE*ZFACTOR))*sdl_scale, 1.0); glTexCoord2d(zcx0, zcy1); glVertex3f(zoom_wx*sdl_scale, (YRES+MENUSIZE-(zoom_wy+ZSIZE*ZFACTOR))*sdl_scale, 1.0); glTexCoord2d(zcx0, zcy0); glVertex3f(zoom_wx*sdl_scale, (YRES+MENUSIZE-zoom_wy)*sdl_scale, 1.0); glTexCoord2d(zcx1, zcy0); glVertex3f((zoom_wx+ZSIZE*ZFACTOR)*sdl_scale, (YRES+MENUSIZE-zoom_wy)*sdl_scale, 1.0); glEnd(); glBindTexture(GL_TEXTURE_2D, 0); glDisable( GL_TEXTURE_2D ); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glLineWidth(sdl_scale); glEnable(GL_LINE_SMOOTH); glBegin(GL_LINES); glColor4f(0.0f, 0.0f, 0.0f, 1.0f); for(i = 0; i < ZSIZE; i++) { glVertex2f((zoom_wx+ZSIZE*ZFACTOR)*sdl_scale, (YRES+MENUSIZE-(zoom_wy+ZSIZE*ZFACTOR)+i*ZFACTOR)*sdl_scale); glVertex2f(zoom_wx*sdl_scale, (YRES+MENUSIZE-(zoom_wy+ZSIZE*ZFACTOR)+i*ZFACTOR)*sdl_scale); glVertex2f((zoom_wx+i*ZFACTOR)*sdl_scale, (YRES+MENUSIZE-(zoom_wy+ZSIZE*ZFACTOR))*sdl_scale); glVertex2f((zoom_wx+i*ZFACTOR)*sdl_scale, (YRES+MENUSIZE-zoom_wy)*sdl_scale); } glEnd(); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glBegin(GL_LINE_STRIP); glVertex3i((zoom_wx-1)*sdl_scale, (YRES+MENUSIZE-zoom_wy)*sdl_scale, 0); glVertex3i((zoom_wx-1)*sdl_scale, (YRES+MENUSIZE-(zoom_wy+ZSIZE*ZFACTOR))*sdl_scale, 0); glVertex3i((zoom_wx+ZSIZE*ZFACTOR)*sdl_scale, (YRES+MENUSIZE-(zoom_wy+ZSIZE*ZFACTOR))*sdl_scale, 0); glVertex3i((zoom_wx+ZSIZE*ZFACTOR)*sdl_scale, (YRES+MENUSIZE-zoom_wy)*sdl_scale, 0); glVertex3i((zoom_wx-1)*sdl_scale, (YRES+MENUSIZE-zoom_wy)*sdl_scale, 0); glEnd(); glDisable(GL_LINE_SMOOTH); glDisable(GL_LINE_SMOOTH); if(zoom_en) { glEnable(GL_COLOR_LOGIC_OP); //glEnable(GL_LINE_SMOOTH); glLogicOp(GL_XOR); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glBegin(GL_LINE_STRIP); glVertex3i((zoom_x-1)*sdl_scale, (YRES+MENUSIZE-(zoom_y-1))*sdl_scale, 0); glVertex3i((zoom_x-1)*sdl_scale, (YRES+MENUSIZE-(zoom_y+ZSIZE))*sdl_scale, 0); glVertex3i((zoom_x+ZSIZE)*sdl_scale, (YRES+MENUSIZE-(zoom_y+ZSIZE))*sdl_scale, 0); glVertex3i((zoom_x+ZSIZE)*sdl_scale, (YRES+MENUSIZE-(zoom_y-1))*sdl_scale, 0); glVertex3i((zoom_x-1)*sdl_scale, (YRES+MENUSIZE-(zoom_y-1))*sdl_scale, 0); glEnd(); glDisable(GL_COLOR_LOGIC_OP); } glLineWidth(1); glBlendFunc(origBlendSrc, origBlendDst); #else int x, y, i, j; pixel pix; pixel * img = g->vid; g->drawrect(zoomWindowPosition.X-2, zoomWindowPosition.Y-2, zoomScopeSize*ZFACTOR+2, zoomScopeSize*ZFACTOR+2, 192, 192, 192, 255); g->drawrect(zoomWindowPosition.X-1, zoomWindowPosition.Y-1, zoomScopeSize*ZFACTOR, zoomScopeSize*ZFACTOR, 0, 0, 0, 255); g->clearrect(zoomWindowPosition.X, zoomWindowPosition.Y, zoomScopeSize*ZFACTOR, zoomScopeSize*ZFACTOR); for (j=0; jxor_pixel(zoomScopePosition.X+j, zoomScopePosition.Y-1); g->xor_pixel(zoomScopePosition.X+j, zoomScopePosition.Y+zoomScopeSize); } for (j=0; jxor_pixel(zoomScopePosition.X-1, zoomScopePosition.Y+j); g->xor_pixel(zoomScopePosition.X+zoomScopeSize, zoomScopePosition.Y+j); } } #endif } void Renderer::DrawWalls() { int x, y, i, j, cr, cg, cb; unsigned char wt; pixel pc; pixel gc; unsigned char (*bmap)[XRES/CELL] = sim->bmap; unsigned char (*emap)[XRES/CELL] = sim->emap; wall_type *wtypes = sim->wtypes; pixel * vid = g->vid; for (y=0; y=UI_WALLCOUNT) continue; pc = wtypes[wt].colour; gc = wtypes[wt].eglow; // standard wall patterns if (wtypes[wt].drawstyle==1) { for (j=0; j>1)&1; i>1)&1; idrawblob((x*CELL+i), (y*CELL+j), PIXR(pc), PIXG(pc), PIXB(pc)); } else if (wtypes[wt].drawstyle==2) { for (j=0; jdrawblob((x*CELL+i), (y*CELL+j), PIXR(pc), PIXG(pc), PIXB(pc)); } else if (wtypes[wt].drawstyle==3) { for (j=0; jdrawblob((x*CELL+i), (y*CELL+j), PIXR(pc), PIXG(pc), PIXB(pc)); } else if (wtypes[wt].drawstyle==4) { for (j=0; jdrawblob((x*CELL+i), (y*CELL+j), PIXR(pc), PIXG(pc), PIXB(pc)); else if (i == j+1 || (i == 0 && j == CELL-1)) g->drawblob((x*CELL+i), (y*CELL+j), PIXR(gc), PIXG(gc), PIXB(gc)); else g->drawblob((x*CELL+i), (y*CELL+j), 0x20, 0x20, 0x20); } if (bmap[y][x]==WL_EWALL) { if (emap[y][x]) { for (j=0; jdrawblob((x*CELL+i), (y*CELL+j), 0x80, 0x80, 0x80); } else { for (j=0; jdrawblob((x*CELL+i), (y*CELL+j), 0x80, 0x80, 0x80); } } else if (bmap[y][x]==WL_WALLELEC) { for (j=0; jdrawblob((x*CELL+i), (y*CELL+j), PIXR(pc), PIXG(pc), PIXB(pc)); else g->drawblob((x*CELL+i), (y*CELL+j), 0x80, 0x80, 0x80); } } else if (bmap[y][x]==WL_EHOLE) { if (emap[y][x]) { for (j=0; jdrawblob((x*CELL+i), (y*CELL+j), 0x24, 0x24, 0x24); for (j=0; jdrawblob((x*CELL+i), (y*CELL+j), 0x24, 0x24, 0x24); } } } if (wtypes[wt].eglow && emap[y][x]) { // glow if electrified pc = wtypes[wt].eglow; cr = fire_r[y][x] + PIXR(pc); if (cr > 255) cr = 255; fire_r[y][x] = cr; cg = fire_g[y][x] + PIXG(pc); if (cg > 255) cg = 255; fire_g[y][x] = cg; cb = fire_b[y][x] + PIXB(pc); if (cb > 255) cb = 255; fire_b[y][x] = cb; } } } void Renderer::get_sign_pos(int i, int *x0, int *y0, int *w, int *h) { sign *signs = sim->signs; //Changing width if sign have special content if (strcmp(signs[i].text, "{p}")==0) *w = Graphics::textwidth("Pressure: -000.00"); if (strcmp(signs[i].text, "{t}")==0) *w = Graphics::textwidth("Temp: 0000.00"); if (sregexp(signs[i].text, "^{c:[0-9]*|.*}$")==0) { int sldr, startm; char buff[256]; memset(buff, 0, sizeof(buff)); for (sldr=3; signs[i].text[sldr-1] != '|'; sldr++) startm = sldr + 1; sldr = startm; while (signs[i].text[sldr] != '}') { buff[sldr - startm] = signs[i].text[sldr]; sldr++; } *w = Graphics::textwidth(buff) + 5; } //Ususal width if (strcmp(signs[i].text, "{p}") && strcmp(signs[i].text, "{t}") && sregexp(signs[i].text, "^{c:[0-9]*|.*}$")) *w = Graphics::textwidth(signs[i].text) + 5; *h = 14; *x0 = (signs[i].ju == 2) ? signs[i].x - *w : (signs[i].ju == 1) ? signs[i].x - *w/2 : signs[i].x; *y0 = (signs[i].y > 18) ? signs[i].y - 18 : signs[i].y + 4; } void Renderer::DrawSigns() { int i, j, x, y, w, h, dx, dy,mx,my,b=1,bq; sign *signs = sim->signs; for (i=0; iclearrect(x, y, w, h); g->drawrect(x, y, w, h, 192, 192, 192, 255); //Displaying special information if (strcmp(signs[i].text, "{p}")==0) { sprintf(buff, "Pressure: %3.2f", sim->pv[signs[i].y/CELL][signs[i].x/CELL]); //...pressure g->drawtext(x+3, y+3, buff, 255, 255, 255, 255); } if (strcmp(signs[i].text, "{t}")==0) { if (sim->pmap[signs[i].y][signs[i].x]) sprintf(buff, "Temp: %4.2f", sim->parts[sim->pmap[signs[i].y][signs[i].x]>>8].temp-273.15); //...tempirature else sprintf(buff, "Temp: 0.00"); //...tempirature g->drawtext(x+3, y+3, buff, 255, 255, 255, 255); } if (sregexp(signs[i].text, "^{c:[0-9]*|.*}$")==0) { int sldr, startm; memset(buff, 0, sizeof(buff)); for (sldr=3; signs[i].text[sldr-1] != '|'; sldr++) startm = sldr + 1; sldr = startm; while (signs[i].text[sldr] != '}') { buff[sldr - startm] = signs[i].text[sldr]; sldr++; } g->drawtext(x+3, y+3, buff, 0, 191, 255, 255); } //Usual text if (strcmp(signs[i].text, "{p}") && strcmp(signs[i].text, "{t}") && sregexp(signs[i].text, "^{c:[0-9]*|.*}$")) g->drawtext(x+3, y+3, signs[i].text, 255, 255, 255, 255); x = signs[i].x; y = signs[i].y; dx = 1 - signs[i].ju; dy = (signs[i].y > 18) ? -1 : 1; for (j=0; j<4; j++) { g->drawpixel(x, y, 192, 192, 192, 255); x+=dx; y+=dy; } /*if (MSIGN==i) { bq = b; b = SDL_GetMouseState(&mx, &my); mx /= sdl_scale; my /= sdl_scale; signs[i].x = mx; signs[i].y = my; }*/ } } void Renderer::render_gravlensing() { int nx, ny, rx, ry, gx, gy, bx, by, co; int r, g, b; pixel t; pixel *src = this->g->vid; pixel *dst = this->g->vid; for(nx = 0; nx < XRES; nx++) { for(ny = 0; ny < YRES; ny++) { co = (ny/CELL)*(XRES/CELL)+(nx/CELL); rx = (int)(nx-sim->gravx[co]*0.75f+0.5f); ry = (int)(ny-sim->gravy[co]*0.75f+0.5f); gx = (int)(nx-sim->gravx[co]*0.875f+0.5f); gy = (int)(ny-sim->gravy[co]*0.875f+0.5f); bx = (int)(nx-sim->gravx[co]+0.5f); by = (int)(ny-sim->gravy[co]+0.5f); 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) { t = dst[ny*(XRES+BARSIZE)+nx]; r = PIXR(src[ry*(XRES+BARSIZE)+rx]) + PIXR(t); g = PIXG(src[gy*(XRES+BARSIZE)+gx]) + PIXG(t); b = PIXB(src[by*(XRES+BARSIZE)+bx]) + PIXB(t); if (r>255) r = 255; if (g>255) g = 255; if (b>255) b = 255; dst[ny*(XRES+BARSIZE)+nx] = PIXRGB(r,g,b); // 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 Renderer::render_fire() { int i,j,x,y,r,g,b,nx,ny; for (j=0; jg->addpixel(i*CELL+x, j*CELL+y, r, g, b, fire_alpha[y+CELL][x+CELL]); r *= 8; g *= 8; b *= 8; for (y=-1; y<2; y++) for (x=-1; x<2; x++) if ((x || y) && i+x>=0 && j+y>=0 && i+x4 ? r-4 : 0; fire_g[j][i] = g>4 ? g-4 : 0; fire_b[j][i] = b>4 ? b-4 : 0; } } void Renderer::prepare_alpha(int size, float intensity) { //TODO: implement size int x,y,i,j,c; float multiplier = 255.0f*intensity; float temp[CELL*3][CELL*3]; float fire_alphaf[CELL*3][CELL*3]; float glow_alphaf[11][11]; float blur_alphaf[7][7]; memset(temp, 0, sizeof(temp)); for (x=0; x 7) continue; glow_alphaf[c+x][c-y] += 0.02f; glow_alphaf[c-x][c+y] += 0.02f; glow_alphaf[c+x][c+y] += 0.02f; glow_alphaf[c-x][c-y] += 0.02f; } } glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, glowAlpha); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 11, 11, GL_ALPHA, GL_FLOAT, glow_alphaf); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); c = 3; for (x=-3; x<4; x++) { for (y=-3; y<4; y++) { if (abs(x)+abs(y) <2 && !(abs(x)==2||abs(y)==2)) blur_alphaf[c+x][c-y] = 0.11f; if (abs(x)+abs(y) <=3 && abs(x)+abs(y)) blur_alphaf[c+x][c-y] = 0.08f; if (abs(x)+abs(y) == 2) blur_alphaf[c+x][c-y] = 0.04f; } } glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, blurAlpha); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 7, 7, GL_ALPHA, GL_FLOAT, blur_alphaf); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); #endif } void Renderer::render_parts() { int deca, decr, decg, decb, cola, colr, colg, colb, firea, firer, fireg, fireb, pixel_mode, q, i, t, nx, ny, x, y, caddress; int orbd[4] = {0, 0, 0, 0}, orbl[4] = {0, 0, 0, 0}; float gradv, flicker, fnx, fny; Particle * parts; part_transition *ptransitions; part_type *ptypes; if(!sim) return; parts = sim->parts; ptransitions = sim->ptransitions; ptypes = sim->ptypes; #ifdef OGLR int cfireV = 0, cfireC = 0, cfire = 0; int csmokeV = 0, csmokeC = 0, csmoke = 0; int cblobV = 0, cblobC = 0, cblob = 0; int cblurV = 0, cblurC = 0, cblur = 0; int cglowV = 0, cglowC = 0, cglow = 0; int cflatV = 0, cflatC = 0, cflat = 0; int caddV = 0, caddC = 0, cadd = 0; int clineV = 0, clineC = 0, cline = 0; GLuint origBlendSrc, origBlendDst; glGetIntegerv(GL_BLEND_SRC, &origBlendSrc); glGetIntegerv(GL_BLEND_DST, &origBlendDst); //Render to the particle FBO glBindFramebuffer(GL_DRAW_FRAMEBUFFER, partsFbo); #else /*if (GRID_MODE)//draws the grid { for (ny=0; nyparts_lastActiveIndex; i++) { if (sim->parts[i].type) { t = sim->parts[i].type; nx = (int)(sim->parts[i].x+0.5f); ny = (int)(sim->parts[i].y+0.5f); fnx = sim->parts[i].x; fny = sim->parts[i].y; if((sim->photons[ny][nx]&0xFF) && !(ptypes[t].properties & TYPE_ENERGY)) continue; //Defaults pixel_mode = 0 | PMODE_FLAT; cola = 255; colr = PIXR(ptypes[t].pcolors); colg = PIXG(ptypes[t].pcolors); colb = PIXB(ptypes[t].pcolors); firea = 0; deca = (sim->parts[i].dcolour>>24)&0xFF; decr = (sim->parts[i].dcolour>>16)&0xFF; decg = (sim->parts[i].dcolour>>8)&0xFF; decb = (sim->parts[i].dcolour)&0xFF; /*if(display_mode == RENDER_NONE) { if(decorations_enable) { colr = (deca*decr + (255-deca)*colr) >> 8; colg = (deca*decg + (255-deca)*colg) >> 8; colb = (deca*decb + (255-deca)*colb) >> 8; } #ifdef OGLR flatV[cflatV++] = nx; flatV[cflatV++] = ny; flatC[cflatC++] = ((float)colr)/255.0f; flatC[cflatC++] = ((float)colg)/255.0f; flatC[cflatC++] = ((float)colb)/255.0f; flatC[cflatC++] = 1.0f; cflat++; #else vid[ny*(XRES+BARSIZE)+nx] = PIXRGB(colr,colg,colb); #endif } else*/ { if (graphicscache[t].isready) { pixel_mode = graphicscache[t].pixel_mode; cola = graphicscache[t].cola; colr = graphicscache[t].colr; colg = graphicscache[t].colg; colb = graphicscache[t].colb; firea = graphicscache[t].firea; firer = graphicscache[t].firer; fireg = graphicscache[t].fireg; fireb = graphicscache[t].fireb; } else { if (ptypes[t].graphics_func) { if ((*(ptypes[t].graphics_func))(this, &(sim->parts[i]), nx, ny, &pixel_mode, &cola, &colr, &colg, &colb, &firea, &firer, &fireg, &fireb)) //That's a lot of args, a struct might be better { graphicscache[t].isready = 1; graphicscache[t].pixel_mode = pixel_mode; graphicscache[t].cola = cola; graphicscache[t].colr = colr; graphicscache[t].colg = colg; graphicscache[t].colb = colb; graphicscache[t].firea = firea; graphicscache[t].firer = firer; graphicscache[t].fireg = fireg; graphicscache[t].fireb = fireb; } } else { if(graphics_DEFAULT(this, &(sim->parts[i]), nx, ny, &pixel_mode, &cola, &colr, &colg, &colb, &firea, &firer, &fireg, &fireb)) { graphicscache[t].isready = 1; graphicscache[t].pixel_mode = pixel_mode; graphicscache[t].cola = cola; graphicscache[t].colr = colr; graphicscache[t].colg = colg; graphicscache[t].colb = colb; graphicscache[t].firea = firea; graphicscache[t].firer = firer; graphicscache[t].fireg = fireg; graphicscache[t].fireb = fireb; } } } if((ptypes[t].properties & PROP_HOT_GLOW) && sim->parts[i].temp>(ptransitions[t].thv-800.0f)) { gradv = 3.1415/(2*ptransitions[t].thv-(ptransitions[t].thv-800.0f)); caddress = (sim->parts[i].temp>ptransitions[t].thv)?ptransitions[t].thv-(ptransitions[t].thv-800.0f):sim->parts[i].temp-(ptransitions[t].thv-800.0f); colr += sin(gradv*caddress) * 226;; colg += sin(gradv*caddress*4.55 +3.14) * 34; colb += sin(gradv*caddress*2.22 +3.14) * 64; } if((pixel_mode & FIRE_ADD) && !(render_mode & FIRE_ADD)) pixel_mode |= PMODE_GLOW; if((pixel_mode & FIRE_BLEND) && !(render_mode & FIRE_BLEND)) pixel_mode |= PMODE_BLUR; if((pixel_mode & PMODE_BLUR) && !(render_mode & PMODE_BLUR)) pixel_mode |= PMODE_FLAT; if((pixel_mode & PMODE_GLOW) && !(render_mode & PMODE_GLOW)) pixel_mode |= PMODE_FLAT; if (render_mode & PMODE_BLOB) pixel_mode |= PMODE_BLOB; pixel_mode &= render_mode; //Alter colour based on display mode if(colour_mode & COLOUR_HEAT) { caddress = restrict_flt((int)( restrict_flt((float)(sim->parts[i].temp+(-MIN_TEMP)), 0.0f, MAX_TEMP+(-MIN_TEMP)) / ((MAX_TEMP+(-MIN_TEMP))/1024) ) *3, 0.0f, (1024.0f*3)-3); firea = 255; firer = colr = (unsigned char)color_data[caddress]; fireg = colg = (unsigned char)color_data[caddress+1]; fireb = colb = (unsigned char)color_data[caddress+2]; cola = 255; if(pixel_mode & (FIREMODE | PMODE_GLOW)) pixel_mode = (pixel_mode & ~(FIREMODE|PMODE_GLOW)) | PMODE_BLUR; } else if(colour_mode & COLOUR_LIFE) { gradv = 0.4f; if (!(sim->parts[i].life<5)) q = sqrt(sim->parts[i].life); else q = sim->parts[i].life; colr = colg = colb = sin(gradv*q) * 100 + 128; cola = 255; if(pixel_mode & (FIREMODE | PMODE_GLOW)) pixel_mode = (pixel_mode & ~(FIREMODE|PMODE_GLOW)) | PMODE_BLUR; } else if (colour_mode & COLOUR_GRAD) { float frequency = 0.05; int q = sim->parts[i].temp-40; colr = sin(frequency*q) * 16 + colr; colg = sin(frequency*q) * 16 + colg; colb = sin(frequency*q) * 16 + colb; if(pixel_mode & (FIREMODE | PMODE_GLOW)) pixel_mode = (pixel_mode & ~(FIREMODE|PMODE_GLOW)) | PMODE_BLUR; } //Apply decoration colour if(!colour_mode) { if(!(pixel_mode & NO_DECO) && decorations_enable) { colr = (deca*decr + (255-deca)*colr) >> 8; colg = (deca*decg + (255-deca)*colg) >> 8; colb = (deca*decb + (255-deca)*colb) >> 8; } if((pixel_mode & DECO_FIRE) && decorations_enable) { firer = (deca*decr + (255-deca)*firer) >> 8; fireg = (deca*decg + (255-deca)*fireg) >> 8; fireb = (deca*decb + (255-deca)*fireb) >> 8; } } #ifndef OGLR //All colours are now set, check ranges if(colr>255) colr = 255; else if(colr<0) colr = 0; if(colg>255) colg = 255; else if(colg<0) colg = 0; if(colb>255) colb = 255; else if(colb<0) colb = 0; if(cola>255) cola = 255; else if(cola<0) cola = 0; #endif //Pixel rendering if(pixel_mode & PSPEC_STICKMAN) { char buff[20]; //Buffer for HP int s; int legr, legg, legb; playerst *cplayer; if(t==PT_STKM) cplayer = &sim->player; else if(t==PT_STKM2) cplayer = &sim->player2; else if(t==PT_FIGH) cplayer = &sim->fighters[(unsigned char)sim->parts[i].tmp]; else continue; /* if (mousex>(nx-3) && mousex<(nx+3) && mousey<(ny+3) && mousey>(ny-3)) //If mous is in the head { sprintf(buff, "%3d", sim->parts[i].life); //Show HP g->drawtext(mousex-8-2*(sim->parts[i].life<100)-2*(sim->parts[i].life<10), mousey-12, buff, 255, 255, 255, 255); }*/ if (colour_mode!=COLOUR_HEAT) { if (cplayer->elemelem].pcolors); colg = PIXG(ptypes[cplayer->elem].pcolors); colb = PIXB(ptypes[cplayer->elem].pcolors); } else { colr = 0x80; colg = 0x80; colb = 0xFF; } } #ifdef OGLR glColor4f(((float)colr)/255.0f, ((float)colg)/255.0f, ((float)colb)/255.0f, 1.0f); glBegin(GL_LINE_STRIP); if(t==PT_FIGH) { glVertex2f(fnx, fny+2); glVertex2f(fnx+2, fny); glVertex2f(fnx, fny-2); glVertex2f(fnx-2, fny); glVertex2f(fnx, fny+2); } else { glVertex2f(fnx-2, fny-2); glVertex2f(fnx+2, fny-2); glVertex2f(fnx+2, fny+2); glVertex2f(fnx-2, fny+2); glVertex2f(fnx-2, fny-2); } glEnd(); glBegin(GL_LINES); if (colour_mode!=COLOUR_HEAT) { if (t==PT_STKM2) glColor4f(100.0f/255.0f, 100.0f/255.0f, 1.0f, 1.0f); else glColor4f(1.0f, 1.0f, 1.0f, 1.0f); } glVertex2f(nx, ny+3); glVertex2f(cplayer->legs[0], cplayer->legs[1]); glVertex2f(cplayer->legs[0], cplayer->legs[1]); glVertex2f(cplayer->legs[4], cplayer->legs[5]); glVertex2f(nx, ny+3); glVertex2f(cplayer->legs[8], cplayer->legs[9]); glVertex2f(cplayer->legs[8], cplayer->legs[9]); glVertex2f(cplayer->legs[12], cplayer->legs[13]); glEnd(); #else s = XRES+BARSIZE; if (t==PT_STKM2) { legr = 100; legg = 100; legb = 255; } else { legr = 255; legg = 255; legb = 255; } if (colour_mode==COLOUR_HEAT) { legr = colr; legg = colg; legb = colb; } //head if(t==PT_FIGH) { g->draw_line(nx, ny+2, nx+2, ny, colr, colg, colb, s); g->draw_line(nx+2, ny, nx, ny-2, colr, colg, colb, s); g->draw_line(nx, ny-2, nx-2, ny, colr, colg, colb, s); g->draw_line(nx-2, ny, nx, ny+2, colr, colg, colb, s); } else { g->draw_line(nx-2, ny+2, nx+2, ny+2, colr, colg, colb, s); g->draw_line(nx-2, ny-2, nx+2, ny-2, colr, colg, colb, s); g->draw_line(nx-2, ny-2, nx-2, ny+2, colr, colg, colb, s); g->draw_line(nx+2, ny-2, nx+2, ny+2, colr, colg, colb, s); } //legs g->draw_line(nx, ny+3, cplayer->legs[0], cplayer->legs[1], legr, legg, legb, s); g->draw_line(cplayer->legs[0], cplayer->legs[1], cplayer->legs[4], cplayer->legs[5], legr, legg, legb, s); g->draw_line(nx, ny+3, cplayer->legs[8], cplayer->legs[9], legr, legg, legb, s); g->draw_line(cplayer->legs[8], cplayer->legs[9], cplayer->legs[12], cplayer->legs[13], legr, legg, legb, s); #endif } if(pixel_mode & PMODE_FLAT) { #ifdef OGLR flatV[cflatV++] = nx; flatV[cflatV++] = ny; flatC[cflatC++] = ((float)colr)/255.0f; flatC[cflatC++] = ((float)colg)/255.0f; flatC[cflatC++] = ((float)colb)/255.0f; flatC[cflatC++] = 1.0f; cflat++; #else g->vid[ny*(XRES+BARSIZE)+nx] = PIXRGB(colr,colg,colb); #endif } if(pixel_mode & PMODE_BLEND) { #ifdef OGLR flatV[cflatV++] = nx; flatV[cflatV++] = ny; flatC[cflatC++] = ((float)colr)/255.0f; flatC[cflatC++] = ((float)colg)/255.0f; flatC[cflatC++] = ((float)colb)/255.0f; flatC[cflatC++] = ((float)cola)/255.0f; cflat++; #else g->blendpixel(nx, ny, colr, colg, colb, cola); #endif } if(pixel_mode & PMODE_ADD) { #ifdef OGLR addV[caddV++] = nx; addV[caddV++] = ny; addC[caddC++] = ((float)colr)/255.0f; addC[caddC++] = ((float)colg)/255.0f; addC[caddC++] = ((float)colb)/255.0f; addC[caddC++] = ((float)cola)/255.0f; cadd++; #else g->addpixel(nx, ny, colr, colg, colb, cola); #endif } if(pixel_mode & PMODE_BLOB) { #ifdef OGLR blobV[cblobV++] = nx; blobV[cblobV++] = ny; blobC[cblobC++] = ((float)colr)/255.0f; blobC[cblobC++] = ((float)colg)/255.0f; blobC[cblobC++] = ((float)colb)/255.0f; blobC[cblobC++] = 1.0f; cblob++; #else g->vid[ny*(XRES+BARSIZE)+nx] = PIXRGB(colr,colg,colb); g->blendpixel(nx+1, ny, colr, colg, colb, 223); g->blendpixel(nx-1, ny, colr, colg, colb, 223); g->blendpixel(nx, ny+1, colr, colg, colb, 223); g->blendpixel(nx, ny-1, colr, colg, colb, 223); g->blendpixel(nx+1, ny-1, colr, colg, colb, 112); g->blendpixel(nx-1, ny-1, colr, colg, colb, 112); g->blendpixel(nx+1, ny+1, colr, colg, colb, 112); g->blendpixel(nx-1, ny+1, colr, colg, colb, 112); #endif } if(pixel_mode & PMODE_GLOW) { #ifdef OGLR glowV[cglowV++] = nx; glowV[cglowV++] = ny; glowC[cglowC++] = ((float)colr)/255.0f; glowC[cglowC++] = ((float)colg)/255.0f; glowC[cglowC++] = ((float)colb)/255.0f; glowC[cglowC++] = 1.0f; cglow++; #else g->addpixel(nx, ny, colr, colg, colb, 192); g->addpixel(nx+1, ny, colr, colg, colb, 96); g->addpixel(nx-1, ny, colr, colg, colb, 96); g->addpixel(nx, ny+1, colr, colg, colb, 96); g->addpixel(nx, ny-1, colr, colg, colb, 96); for (x = 1; x < 6; x++) { g->addpixel(nx, ny-x, colr, colg, colb, 5); g->addpixel(nx, ny+x, colr, colg, colb, 5); g->addpixel(nx-x, ny, colr, colg, colb, 5); g->addpixel(nx+x, ny, colr, colg, colb, 5); for (y = 1; y < 6; y++) { if(x + y > 7) continue; g->addpixel(nx+x, ny-y, colr, colg, colb, 5); g->addpixel(nx-x, ny+y, colr, colg, colb, 5); g->addpixel(nx+x, ny+y, colr, colg, colb, 5); g->addpixel(nx-x, ny-y, colr, colg, colb, 5); } } #endif } if(pixel_mode & PMODE_BLUR) { #ifdef OGLR blurV[cblurV++] = nx; blurV[cblurV++] = ny; blurC[cblurC++] = ((float)colr)/255.0f; blurC[cblurC++] = ((float)colg)/255.0f; blurC[cblurC++] = ((float)colb)/255.0f; blurC[cblurC++] = 1.0f; cblur++; #else for (x=-3; x<4; x++) { for (y=-3; y<4; y++) { if (abs(x)+abs(y) <2 && !(abs(x)==2||abs(y)==2)) g->blendpixel(x+nx, y+ny, colr, colg, colb, 30); if (abs(x)+abs(y) <=3 && abs(x)+abs(y)) g->blendpixel(x+nx, y+ny, colr, colg, colb, 20); if (abs(x)+abs(y) == 2) g->blendpixel(x+nx, y+ny, colr, colg, colb, 10); } } #endif } if(pixel_mode & PMODE_SPARK) { flicker = rand()%20; #ifdef OGLR //Oh god, this is awful lineC[clineC++] = ((float)colr)/255.0f; lineC[clineC++] = ((float)colg)/255.0f; lineC[clineC++] = ((float)colb)/255.0f; lineC[clineC++] = 0.0f; lineV[clineV++] = fnx-5; lineV[clineV++] = fny; cline++; lineC[clineC++] = ((float)colr)/255.0f; lineC[clineC++] = ((float)colg)/255.0f; lineC[clineC++] = ((float)colb)/255.0f; lineC[clineC++] = 1.0f - ((float)flicker)/30; lineV[clineV++] = fnx; lineV[clineV++] = fny; cline++; lineC[clineC++] = ((float)colr)/255.0f; lineC[clineC++] = ((float)colg)/255.0f; lineC[clineC++] = ((float)colb)/255.0f; lineC[clineC++] = 0.0f; lineV[clineV++] = fnx+5; lineV[clineV++] = fny; cline++; lineC[clineC++] = ((float)colr)/255.0f; lineC[clineC++] = ((float)colg)/255.0f; lineC[clineC++] = ((float)colb)/255.0f; lineC[clineC++] = 0.0f; lineV[clineV++] = fnx; lineV[clineV++] = fny-5; cline++; lineC[clineC++] = ((float)colr)/255.0f; lineC[clineC++] = ((float)colg)/255.0f; lineC[clineC++] = ((float)colb)/255.0f; lineC[clineC++] = 1.0f - ((float)flicker)/30; lineV[clineV++] = fnx; lineV[clineV++] = fny; cline++; lineC[clineC++] = ((float)colr)/255.0f; lineC[clineC++] = ((float)colg)/255.0f; lineC[clineC++] = ((float)colb)/255.0f; lineC[clineC++] = 0.0f; lineV[clineV++] = fnx; lineV[clineV++] = fny+5; cline++; #else gradv = 4*sim->parts[i].life + flicker; for (x = 0; gradv>0.5; x++) { g->addpixel(nx+x, ny, colr, colg, colb, gradv); g->addpixel(nx-x, ny, colr, colg, colb, gradv); g->addpixel(nx, ny+x, colr, colg, colb, gradv); g->addpixel(nx, ny-x, colr, colg, colb, gradv); gradv = gradv/1.5f; } #endif } if(pixel_mode & PMODE_FLARE) { flicker = rand()%20; #ifdef OGLR //Oh god, this is awful lineC[clineC++] = ((float)colr)/255.0f; lineC[clineC++] = ((float)colg)/255.0f; lineC[clineC++] = ((float)colb)/255.0f; lineC[clineC++] = 0.0f; lineV[clineV++] = fnx-10; lineV[clineV++] = fny; cline++; lineC[clineC++] = ((float)colr)/255.0f; lineC[clineC++] = ((float)colg)/255.0f; lineC[clineC++] = ((float)colb)/255.0f; lineC[clineC++] = 1.0f - ((float)flicker)/40; lineV[clineV++] = fnx; lineV[clineV++] = fny; cline++; lineC[clineC++] = ((float)colr)/255.0f; lineC[clineC++] = ((float)colg)/255.0f; lineC[clineC++] = ((float)colb)/255.0f; lineC[clineC++] = 0.0f; lineV[clineV++] = fnx+10; lineV[clineV++] = fny; cline++; lineC[clineC++] = ((float)colr)/255.0f; lineC[clineC++] = ((float)colg)/255.0f; lineC[clineC++] = ((float)colb)/255.0f; lineC[clineC++] = 0.0f; lineV[clineV++] = fnx; lineV[clineV++] = fny-10; cline++; lineC[clineC++] = ((float)colr)/255.0f; lineC[clineC++] = ((float)colg)/255.0f; lineC[clineC++] = ((float)colb)/255.0f; lineC[clineC++] = 1.0f - ((float)flicker)/30; lineV[clineV++] = fnx; lineV[clineV++] = fny; cline++; lineC[clineC++] = ((float)colr)/255.0f; lineC[clineC++] = ((float)colg)/255.0f; lineC[clineC++] = ((float)colb)/255.0f; lineC[clineC++] = 0.0f; lineV[clineV++] = fnx; lineV[clineV++] = fny+10; cline++; #else gradv = flicker + fabs(parts[i].vx)*17 + fabs(sim->parts[i].vy)*17; g->blendpixel(nx, ny, colr, colg, colb, (gradv*4)>255?255:(gradv*4) ); g->blendpixel(nx+1, ny, colr, colg, colb, (gradv*2)>255?255:(gradv*2) ); g->blendpixel(nx-1, ny, colr, colg, colb, (gradv*2)>255?255:(gradv*2) ); g->blendpixel(nx, ny+1, colr, colg, colb, (gradv*2)>255?255:(gradv*2) ); g->blendpixel(nx, ny-1, colr, colg, colb, (gradv*2)>255?255:(gradv*2) ); if (gradv>255) gradv=255; g->blendpixel(nx+1, ny-1, colr, colg, colb, gradv); g->blendpixel(nx-1, ny-1, colr, colg, colb, gradv); g->blendpixel(nx+1, ny+1, colr, colg, colb, gradv); g->blendpixel(nx-1, ny+1, colr, colg, colb, gradv); for (x = 1; gradv>0.5; x++) { g->addpixel(nx+x, ny, colr, colg, colb, gradv); g->addpixel(nx-x, ny, colr, colg, colb, gradv); g->addpixel(nx, ny+x, colr, colg, colb, gradv); g->addpixel(nx, ny-x, colr, colg, colb, gradv); gradv = gradv/1.2f; } #endif } if(pixel_mode & PMODE_LFLARE) { flicker = rand()%20; #ifdef OGLR //Oh god, this is awful lineC[clineC++] = ((float)colr)/255.0f; lineC[clineC++] = ((float)colg)/255.0f; lineC[clineC++] = ((float)colb)/255.0f; lineC[clineC++] = 0.0f; lineV[clineV++] = fnx-70; lineV[clineV++] = fny; cline++; lineC[clineC++] = ((float)colr)/255.0f; lineC[clineC++] = ((float)colg)/255.0f; lineC[clineC++] = ((float)colb)/255.0f; lineC[clineC++] = 1.0f - ((float)flicker)/30; lineV[clineV++] = fnx; lineV[clineV++] = fny; cline++; lineC[clineC++] = ((float)colr)/255.0f; lineC[clineC++] = ((float)colg)/255.0f; lineC[clineC++] = ((float)colb)/255.0f; lineC[clineC++] = 0.0f; lineV[clineV++] = fnx+70; lineV[clineV++] = fny; cline++; lineC[clineC++] = ((float)colr)/255.0f; lineC[clineC++] = ((float)colg)/255.0f; lineC[clineC++] = ((float)colb)/255.0f; lineC[clineC++] = 0.0f; lineV[clineV++] = fnx; lineV[clineV++] = fny-70; cline++; lineC[clineC++] = ((float)colr)/255.0f; lineC[clineC++] = ((float)colg)/255.0f; lineC[clineC++] = ((float)colb)/255.0f; lineC[clineC++] = 1.0f - ((float)flicker)/50; lineV[clineV++] = fnx; lineV[clineV++] = fny; cline++; lineC[clineC++] = ((float)colr)/255.0f; lineC[clineC++] = ((float)colg)/255.0f; lineC[clineC++] = ((float)colb)/255.0f; lineC[clineC++] = 0.0f; lineV[clineV++] = fnx; lineV[clineV++] = fny+70; cline++; #else gradv = flicker + fabs(parts[i].vx)*17 + fabs(parts[i].vy)*17; g->blendpixel(nx, ny, colr, colg, colb, (gradv*4)>255?255:(gradv*4) ); g->blendpixel(nx+1, ny, colr, colg, colb, (gradv*2)>255?255:(gradv*2) ); g->blendpixel(nx-1, ny, colr, colg, colb, (gradv*2)>255?255:(gradv*2) ); g->blendpixel(nx, ny+1, colr, colg, colb, (gradv*2)>255?255:(gradv*2) ); g->blendpixel(nx, ny-1, colr, colg, colb, (gradv*2)>255?255:(gradv*2) ); if (gradv>255) gradv=255; g->blendpixel(nx+1, ny-1, colr, colg, colb, gradv); g->blendpixel(nx-1, ny-1, colr, colg, colb, gradv); g->blendpixel(nx+1, ny+1, colr, colg, colb, gradv); g->blendpixel(nx-1, ny+1, colr, colg, colb, gradv); for (x = 1; gradv>0.5; x++) { g->addpixel(nx+x, ny, colr, colg, colb, gradv); g->addpixel(nx-x, ny, colr, colg, colb, gradv); g->addpixel(nx, ny+x, colr, colg, colb, gradv); g->addpixel(nx, ny-x, colr, colg, colb, gradv); gradv = gradv/1.01f; } #endif } if (pixel_mode & EFFECT_GRAVIN) { int nxo = 0; int nyo = 0; int r; int fire_rv = 0; float drad = 0.0f; float ddist = 0.0f; sim->orbitalparts_get(parts[i].life, parts[i].ctype, orbd, orbl); for (r = 0; r < 4; r++) { ddist = ((float)orbd[r])/16.0f; drad = (M_PI * ((float)orbl[r]) / 180.0f)*1.41f; nxo = ddist*cos(drad); nyo = ddist*sin(drad); if (ny+nyo>0 && ny+nyo0 && nx+nxoaddpixel(nx+nxo, ny+nyo, colr, colg, colb, 255-orbd[r]); } } if (pixel_mode & EFFECT_GRAVOUT) { int nxo = 0; int nyo = 0; int r; int fire_bv = 0; float drad = 0.0f; float ddist = 0.0f; sim->orbitalparts_get(parts[i].life, parts[i].ctype, orbd, orbl); for (r = 0; r < 4; r++) { ddist = ((float)orbd[r])/16.0f; drad = (M_PI * ((float)orbl[r]) / 180.0f)*1.41f; nxo = ddist*cos(drad); nyo = ddist*sin(drad); if (ny+nyo>0 && ny+nyo0 && nx+nxoaddpixel(nx+nxo, ny+nyo, colr, colg, colb, 255-orbd[r]); } } //Fire effects if(firea && (pixel_mode & FIRE_BLEND)) { #ifdef OGLR smokeV[csmokeV++] = nx; smokeV[csmokeV++] = ny; smokeC[csmokeC++] = ((float)firer)/255.0f; smokeC[csmokeC++] = ((float)fireg)/255.0f; smokeC[csmokeC++] = ((float)fireb)/255.0f; smokeC[csmokeC++] = ((float)firea)/255.0f; csmoke++; #else firea /= 2; fire_r[ny/CELL][nx/CELL] = (firea*firer + (255-firea)*fire_r[ny/CELL][nx/CELL]) >> 8; fire_g[ny/CELL][nx/CELL] = (firea*fireg + (255-firea)*fire_g[ny/CELL][nx/CELL]) >> 8; fire_b[ny/CELL][nx/CELL] = (firea*fireb + (255-firea)*fire_b[ny/CELL][nx/CELL]) >> 8; #endif } if(firea && (pixel_mode & FIRE_ADD)) { #ifdef OGLR fireV[cfireV++] = nx; fireV[cfireV++] = ny; fireC[cfireC++] = ((float)firer)/255.0f; fireC[cfireC++] = ((float)fireg)/255.0f; fireC[cfireC++] = ((float)fireb)/255.0f; fireC[cfireC++] = ((float)firea)/255.0f; cfire++; #else firea /= 8; firer = ((firea*firer) >> 8) + fire_r[ny/CELL][nx/CELL]; fireg = ((firea*fireg) >> 8) + fire_g[ny/CELL][nx/CELL]; fireb = ((firea*fireb) >> 8) + fire_b[ny/CELL][nx/CELL]; if(firer>255) firer = 255; if(fireg>255) fireg = 255; if(fireb>255) fireb = 255; fire_r[ny/CELL][nx/CELL] = firer; fire_g[ny/CELL][nx/CELL] = fireg; fire_b[ny/CELL][nx/CELL] = fireb; #endif } } } } #ifdef OGLR //Go into array mode glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if(cflat) { // -- BEGIN FLAT -- // //Set point size (size of fire texture) glPointSize(1.0f); glColorPointer(4, GL_FLOAT, 0, &flatC[0]); glVertexPointer(2, GL_INT, 0, &flatV[0]); glDrawArrays(GL_POINTS, 0, cflat); //Clear some stuff we set // -- END FLAT -- // } if(cblob) { // -- BEGIN BLOB -- // glEnable( GL_POINT_SMOOTH ); //Blobs! glPointSize(2.5f); glColorPointer(4, GL_FLOAT, 0, &blobC[0]); glVertexPointer(2, GL_INT, 0, &blobV[0]); glDrawArrays(GL_POINTS, 0, cblob); //Clear some stuff we set glDisable( GL_POINT_SMOOTH ); // -- END BLOB -- // } if(cglow || cblur) { // -- BEGIN GLOW -- // //Start and prepare fire program glEnable(GL_TEXTURE_2D); glUseProgram(fireProg); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, glowAlpha); glUniform1i(glGetUniformLocation(fireProg, "fireAlpha"), 0); glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); //Make sure we can use texture coords on points glEnable(GL_POINT_SPRITE); glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); //Set point size (size of fire texture) glPointSize(11.0f); glBlendFunc(GL_SRC_ALPHA, GL_ONE); if(cglow) { glColorPointer(4, GL_FLOAT, 0, &glowC[0]); glVertexPointer(2, GL_INT, 0, &glowV[0]); glDrawArrays(GL_POINTS, 0, cglow); } glPointSize(7.0f); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if(cblur) { glBindTexture(GL_TEXTURE_2D, blurAlpha); glColorPointer(4, GL_FLOAT, 0, &blurC[0]); glVertexPointer(2, GL_INT, 0, &blurV[0]); glDrawArrays(GL_POINTS, 0, cblur); } //Clear some stuff we set glDisable(GL_POINT_SPRITE); glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); glUseProgram(0); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); // -- END GLOW -- // } if(cadd) { // -- BEGIN ADD -- // //Set point size (size of fire texture) glPointSize(1.0f); glColorPointer(4, GL_FLOAT, 0, &addC[0]); glVertexPointer(2, GL_INT, 0, &addV[0]); glBlendFunc(GL_SRC_ALPHA, GL_ONE); glDrawArrays(GL_POINTS, 0, cadd); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //Clear some stuff we set // -- END ADD -- // } if(cline) { // -- BEGIN LINES -- // glBlendFunc(GL_SRC_ALPHA, GL_ONE); glEnable( GL_LINE_SMOOTH ); glColorPointer(4, GL_FLOAT, 0, &lineC[0]); glVertexPointer(2, GL_FLOAT, 0, &lineV[0]); glDrawArrays(GL_LINE_STRIP, 0, cline); //Clear some stuff we set glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_LINE_SMOOTH); // -- END LINES -- // } if(cfire || csmoke) { // -- BEGIN FIRE -- // //Start and prepare fire program glEnable(GL_TEXTURE_2D); glUseProgram(fireProg); //glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, fireAlpha); glUniform1i(glGetUniformLocation(fireProg, "fireAlpha"), 0); //Make sure we can use texture coords on points glEnable(GL_POINT_SPRITE); glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); //Set point size (size of fire texture) glPointSize(CELL*3); glBlendFunc(GL_SRC_ALPHA, GL_ONE); if(cfire) { glColorPointer(4, GL_FLOAT, 0, &fireC[0]); glVertexPointer(2, GL_INT, 0, &fireV[0]); glDrawArrays(GL_POINTS, 0, cfire); } glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if(csmoke) { glColorPointer(4, GL_FLOAT, 0, &smokeC[0]); glVertexPointer(2, GL_INT, 0, &smokeV[0]); glDrawArrays(GL_POINTS, 0, csmoke); } //Clear some stuff we set glDisable(GL_POINT_SPRITE); glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); glUseProgram(0); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); // -- END FIRE -- // } glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); //Reset FBO glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); //Drawing the FBO onto the screen sounds like a cool idea now glBlendFunc(origBlendSrc, origBlendDst); #endif } void Renderer::draw_other() // EMP effect { int i, j; //if (emp_decor>0 && !sys_pause) emp_decor-=emp_decor/25+2; TODO: Render should render only, do not change simulation state if (emp_decor>40) emp_decor=40; if (emp_decor<0) emp_decor = 0; if (!(display_mode & DISPLAY_EFFE)) // no in nothing mode return; if (emp_decor>0) { #ifdef OGLR float femp_decor = ((float)emp_decor)/255.0f; /*int r=emp_decor*2.5, g=100+emp_decor*1.5, b=255; int a=(1.0*emp_decor/110)*255; if (r>255) r=255; if (g>255) g=255; if (b>255) g=255; if (a>255) a=255;*/ glBegin(GL_QUADS); glColor4f(femp_decor*2.5f, 0.4f+femp_decor*1.5f, 1.0f+femp_decor*1.5f, femp_decor/0.44f); glVertex2f(0, MENUSIZE); glVertex2f(XRES, MENUSIZE); glVertex2f(XRES, YRES+MENUSIZE); glVertex2f(0, YRES+MENUSIZE); glEnd(); #else int r=emp_decor*2.5, g=100+emp_decor*1.5, b=255; int a=(1.0*emp_decor/110)*255; if (r>255) r=255; if (g>255) g=255; if (b>255) g=255; if (a>255) a=255; for (j=0; jg->drawpixel(i, j, r, g, b, a); } #endif } } void Renderer::draw_grav() { int x, y, i, ca; float nx, ny, dist; for (y=0; ygravx[ca]) <= 0.001f && fabsf(sim->gravy[ca]) <= 0.001f) continue; nx = x*CELL; ny = y*CELL; dist = fabsf(sim->gravy[ca])+fabsf(sim->gravx[ca]); for(i = 0; i < 4; i++) { nx -= sim->gravx[ca]*0.5f; ny -= sim->gravy[ca]*0.5f; g->addpixel((int)(nx+0.5f), (int)(ny+0.5f), 255, 255, 255, (int)(dist*20.0f)); } } } } void Renderer::draw_air() { #ifndef OGLR int x, y, i, j; float (*pv)[XRES/CELL] = sim->air->pv; float (*hv)[XRES/CELL] = sim->air->hv; float (*vx)[XRES/CELL] = sim->air->vx; float (*vy)[XRES/CELL] = sim->air->vy; pixel c; for (y=0; y 0.0f) c = PIXRGB(clamp_flt(pv[y][x], 0.0f, 8.0f), 0, 0);//positive pressure is red! else c = PIXRGB(0, 0, clamp_flt(-pv[y][x], 0.0f, 8.0f));//negative pressure is blue! } else if (display_mode & DISPLAY_AIRV) { c = PIXRGB(clamp_flt(fabsf(vx[y][x]), 0.0f, 8.0f),//vx adds red clamp_flt(pv[y][x], 0.0f, 8.0f),//pressure adds green clamp_flt(fabsf(vy[y][x]), 0.0f, 8.0f));//vy adds blue } else if (display_mode & DISPLAY_AIRH) { float ttemp = hv[y][x]+(-MIN_TEMP); int caddress = restrict_flt((int)( restrict_flt(ttemp, 0.0f, MAX_TEMP+(-MIN_TEMP)) / ((MAX_TEMP+(-MIN_TEMP))/1024) ) *3, 0.0f, (1024.0f*3)-3); c = PIXRGB((int)((unsigned char)color_data[caddress]*0.7f), (int)((unsigned char)color_data[caddress+1]*0.7f), (int)((unsigned char)color_data[caddress+2]*0.7f)); //c = PIXRGB(clamp_flt(fabsf(vx[y][x]), 0.0f, 8.0f),//vx adds red // clamp_flt(hv[y][x], 0.0f, 1600.0f),//heat adds green // clamp_flt(fabsf(vy[y][x]), 0.0f, 8.0f));//vy adds blue } else if (display_mode & DISPLAY_AIRC) { int r; int g; int b; // velocity adds grey r = clamp_flt(fabsf(vx[y][x]), 0.0f, 24.0f) + clamp_flt(fabsf(vy[y][x]), 0.0f, 20.0f); g = clamp_flt(fabsf(vx[y][x]), 0.0f, 20.0f) + clamp_flt(fabsf(vy[y][x]), 0.0f, 24.0f); b = clamp_flt(fabsf(vx[y][x]), 0.0f, 24.0f) + clamp_flt(fabsf(vy[y][x]), 0.0f, 20.0f); if (pv[y][x] > 0.0f) { r += clamp_flt(pv[y][x], 0.0f, 16.0f);//pressure adds red! if (r>255) r=255; if (g>255) g=255; if (b>255) b=255; c = PIXRGB(r, g, b); } else { b += clamp_flt(-pv[y][x], 0.0f, 16.0f);//pressure adds blue! if (r>255) r=255; if (g>255) g=255; if (b>255) b=255; c = PIXRGB(r, g, b); } } for (j=0; jvid[(x*CELL+i) + (y*CELL+j)*(XRES+BARSIZE)] = c; } #else GLuint airProg; if(display_mode & DISPLAY_AIRC) { airProg = airProg_Cracker; } else if(display_mode & DISPLAY_AIRV) { airProg = airProg_Velocity; } else if(display_mode & DISPLAY_AIRP) { airProg = airProg_Pressure; } else { return; } glEnable( GL_TEXTURE_2D ); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, partsFbo); glUseProgram(airProg); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, airVX); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, XRES/CELL, YRES/CELL, GL_RED, GL_FLOAT, vx); glUniform1i(glGetUniformLocation(airProg, "airX"), 0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, airVY); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, XRES/CELL, YRES/CELL, GL_GREEN, GL_FLOAT, vy); glUniform1i(glGetUniformLocation(airProg, "airY"), 1); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, airPV); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, XRES/CELL, YRES/CELL, GL_BLUE, GL_FLOAT, pv); glUniform1i(glGetUniformLocation(airProg, "airP"), 2); glActiveTexture(GL_TEXTURE0); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glBegin(GL_QUADS); glTexCoord2d(1, 1); glVertex3f(XRES*sdl_scale, YRES*sdl_scale, 1.0); glTexCoord2d(0, 1); glVertex3f(0, YRES*sdl_scale, 1.0); glTexCoord2d(0, 0); glVertex3f(0, 0, 1.0); glTexCoord2d(1, 0); glVertex3f(XRES*sdl_scale, 0, 1.0); glEnd(); glUseProgram(0); glBindTexture(GL_TEXTURE_2D, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glDisable( GL_TEXTURE_2D ); #endif } void Renderer::draw_grav_zones() { int x, y, i, j; for (y=0; ygravmask[y*(XRES/CELL)+x]) { for (j=0; jdrawpixel(x*CELL+i, y*CELL+j, 255, 200, 0, 120); else g->drawpixel(x*CELL+i, y*CELL+j, 32, 32, 32, 120); } } } } Renderer::Renderer(Graphics * g, Simulation * sim): sim(NULL), g(NULL), zoomWindowPosition(0, 0), zoomScopePosition(0, 0), zoomScopeSize(10), ZFACTOR(8), zoomEnabled(false), decorations_enable(1) { this->g = g; this->sim = sim; memset(fire_r, 0, sizeof(fire_r)); memset(fire_g, 0, sizeof(fire_g)); memset(fire_b, 0, sizeof(fire_b)); prepare_alpha(CELL, 1.0f); //Set defauly display modes SetColourMode(COLOUR_DEFAULT); AddRenderMode(RENDER_BASC); AddRenderMode(RENDER_FIRE); //Prepare the graphics cache graphicscache = (gcache_item *)malloc(sizeof(gcache_item)*PT_NUM); memset(graphicscache, 0, sizeof(gcache_item)*PT_NUM); int fireColoursCount = 4; pixel fireColours[] = {PIXPACK(0xAF9F0F), PIXPACK(0xDFBF6F), PIXPACK(0x60300F), PIXPACK(0x000000)}; float fireColoursPoints[] = {1.0f, 0.9f, 0.5f, 0.0f}; int plasmaColoursCount = 5; pixel plasmaColours[] = {PIXPACK(0xAFFFFF), PIXPACK(0xAFFFFF), PIXPACK(0x301060), PIXPACK(0x301040), PIXPACK(0x000000)}; float plasmaColoursPoints[] = {1.0f, 0.9f, 0.5f, 0.25, 0.0f}; flm_data = Graphics::GenerateGradient(fireColours, fireColoursPoints, fireColoursCount, 200); plasma_data = Graphics::GenerateGradient(plasmaColours, plasmaColoursPoints, plasmaColoursCount, 200); } void Renderer::CompileRenderMode() { render_mode = 0; for(int i = 0; i < render_modes.size(); i++) render_mode |= render_modes[i]; } void Renderer::AddRenderMode(unsigned int mode) { for(int i = 0; i < render_modes.size(); i++) { if(render_modes[i] == mode) { return; } } render_modes.push_back(mode); CompileRenderMode(); } void Renderer::RemoveRenderMode(unsigned int mode) { for(int i = 0; i < render_modes.size(); i++) { if(render_modes[i] == mode) { render_modes.erase(render_modes.begin() + i); i = 0; } } CompileRenderMode(); } void Renderer::SetRenderMode(std::vector render) { render_modes = render; CompileRenderMode(); } std::vector Renderer::GetRenderMode() { return render_modes; } void Renderer::CompileDisplayMode() { display_mode = 0; for(int i = 0; i < display_modes.size(); i++) display_mode |= display_modes[i]; } void Renderer::AddDisplayMode(unsigned int mode) { for(int i = 0; i < display_modes.size(); i++) { if(display_modes[i] == mode) { return; } } display_modes.push_back(mode); CompileDisplayMode(); } void Renderer::RemoveDisplayMode(unsigned int mode) { for(int i = 0; i < display_modes.size(); i++) { if(display_modes[i] == mode) { display_modes.erase(display_modes.begin() + i); i = 0; } } CompileDisplayMode(); } void Renderer::SetDisplayMode(std::vector display) { display_modes = display; CompileDisplayMode(); } std::vector Renderer::GetDisplayMode() { return display_modes; } void Renderer::SetColourMode(unsigned int mode) { colour_mode = mode; } unsigned int Renderer::GetColourMode() { return colour_mode; } Renderer::~Renderer() { free(graphicscache); free(flm_data); free(plasma_data); }