/* * Renderer.cpp * * Created on: Jan 7, 2012 * Author: Simon */ #include #include #include #include #include #include "Config.h" #include "Renderer.h" #include "Graphics.h" #include "simulation/Elements.h" #include "simulation/ElementGraphics.h" #include "simulation/Air.h" extern "C" { #include "hmap.h" #ifdef OGLR #include "Shaders.h" #endif } #ifndef OGLI #define VIDXRES (XRES+BARSIZE) #define VIDYRES (YRES+MENUSIZE) #else #define VIDXRES XRES #define VIDYRES YRES #endif void Renderer::RenderBegin() { #ifndef OGLR if(display_mode & DISPLAY_PERS) { std::copy(persistentVid, persistentVid+(VIDXRES*YRES), vid); } pixel * oldVid; if(display_mode & DISPLAY_WARP) { oldVid = vid; vid = warpVid; std::fill(warpVid, warpVid+(VIDXRES*VIDYRES), 0); } #endif draw_air(); draw_grav(); render_parts(); render_fire(); #ifndef OGLR if(display_mode & DISPLAY_PERS) { int i,r,g,b; for (i = 0; i < VIDXRES*YRES; i++) { r = PIXR(vid[i]); g = PIXG(vid[i]); b = PIXB(vid[i]); if (r>0) r--; if (g>0) g--; if (b>0) b--; persistentVid[i] = PIXRGB(r,g,b); } } #endif DrawWalls(); draw_grav_zones(); DrawSigns(); #ifndef OGLR if(display_mode & DISPLAY_WARP) { vid = oldVid; } #endif #ifndef OGLR FinaliseParts(); #endif } void Renderer::RenderEnd() { RenderZoom(); #ifdef OGLR FinaliseParts(); #endif } void Renderer::clearScreen(float alpha) { #ifdef OGLR GLint prevFbo; if(alpha > 0.999f) { glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prevFbo); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, partsFbo); glClear(GL_COLOR_BUFFER_BIT); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prevFbo); } else { glBlendEquation(GL_FUNC_REVERSE_SUBTRACT); glColor4f(1.0f, 1.0f, 1.0f, alpha); glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prevFbo); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, partsFbo); glBegin(GL_QUADS); glVertex2f(0, 0); glVertex2f(XRES, 0); glVertex2f(XRES, YRES); glVertex2f(0, YRES); glEnd(); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prevFbo); glBlendEquation(GL_FUNC_ADD); } glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); #endif #ifdef OGLI #ifndef OGLR std::fill(vid, vid+(VIDXRES*VIDYRES), 0); #endif #endif } #ifdef OGLR void Renderer::checkShader(GLuint shader, char * shname) { GLint status; glGetShaderiv(shader, GL_COMPILE_STATUS, &status); if (status == GL_FALSE) { char errorBuf[ GL_INFO_LOG_LENGTH]; int errLen; glGetShaderInfoLog(shader, GL_INFO_LOG_LENGTH, &errLen, errorBuf); fprintf(stderr, "Failed to compile %s shader:\n%s\n", shname, errorBuf); exit(1); } } void Renderer::checkProgram(GLuint program, char * progname) { GLint status; glGetProgramiv(program, GL_LINK_STATUS, &status); if (status == GL_FALSE) { char errorBuf[ GL_INFO_LOG_LENGTH]; int errLen; glGetShaderInfoLog(program, GL_INFO_LOG_LENGTH, &errLen, errorBuf); fprintf(stderr, "Failed to link %s program:\n%s\n", progname, errorBuf); exit(1); } } void Renderer::loadShaders() { GLuint vertexShader, fragmentShader; //Particle texture vertexShader = glCreateShader(GL_VERTEX_SHADER); fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource( vertexShader, 1, &fireVertex, NULL); glShaderSource( fragmentShader, 1, &fireFragment, NULL); glCompileShader( vertexShader ); checkShader(vertexShader, "FV"); glCompileShader( fragmentShader ); checkShader(fragmentShader, "FF"); fireProg = glCreateProgram(); glAttachShader( fireProg, vertexShader ); glAttachShader( fireProg, fragmentShader ); glLinkProgram( fireProg ); checkProgram(fireProg, "F"); //Lensing vertexShader = glCreateShader(GL_VERTEX_SHADER); fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource( vertexShader, 1, &lensVertex, NULL); glShaderSource( fragmentShader, 1, &lensFragment, NULL); glCompileShader( vertexShader ); checkShader(vertexShader, "LV"); glCompileShader( fragmentShader ); checkShader(fragmentShader, "LF"); lensProg = glCreateProgram(); glAttachShader( lensProg, vertexShader ); glAttachShader( lensProg, fragmentShader ); glLinkProgram( lensProg ); checkProgram(lensProg, "L"); //Air Velocity vertexShader = glCreateShader(GL_VERTEX_SHADER); fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource( vertexShader, 1, &airVVertex, NULL); glShaderSource( fragmentShader, 1, &airVFragment, NULL); glCompileShader( vertexShader ); checkShader(vertexShader, "AVX"); glCompileShader( fragmentShader ); checkShader(fragmentShader, "AVF"); airProg_Velocity = glCreateProgram(); glAttachShader( airProg_Velocity, vertexShader ); glAttachShader( airProg_Velocity, fragmentShader ); glLinkProgram( airProg_Velocity ); checkProgram(airProg_Velocity, "AV"); //Air Pressure vertexShader = glCreateShader(GL_VERTEX_SHADER); fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource( vertexShader, 1, &airPVertex, NULL); glShaderSource( fragmentShader, 1, &airPFragment, NULL); glCompileShader( vertexShader ); checkShader(vertexShader, "APV"); glCompileShader( fragmentShader ); checkShader(fragmentShader, "APF"); airProg_Pressure = glCreateProgram(); glAttachShader( airProg_Pressure, vertexShader ); glAttachShader( airProg_Pressure, fragmentShader ); glLinkProgram( airProg_Pressure ); checkProgram(airProg_Pressure, "AP"); //Air cracker vertexShader = glCreateShader(GL_VERTEX_SHADER); fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource( vertexShader, 1, &airCVertex, NULL); glShaderSource( fragmentShader, 1, &airCFragment, NULL); glCompileShader( vertexShader ); checkShader(vertexShader, "ACV"); glCompileShader( fragmentShader ); checkShader(fragmentShader, "ACF"); airProg_Cracker = glCreateProgram(); glAttachShader( airProg_Cracker, vertexShader ); glAttachShader( airProg_Cracker, fragmentShader ); glLinkProgram( airProg_Cracker ); checkProgram(airProg_Cracker, "AC"); } #endif void Renderer::FinaliseParts() { #ifdef OGLR glEnable( GL_TEXTURE_2D ); if(display_mode & DISPLAY_WARP) { float xres = XRES, yres = YRES; glUseProgram(lensProg); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, partsFboTex); glUniform1i(glGetUniformLocation(lensProg, "pTex"), 0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, partsTFX); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, XRES/CELL, YRES/CELL, GL_RED, GL_FLOAT, sim->gravx); glUniform1i(glGetUniformLocation(lensProg, "tfX"), 1); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, partsTFY); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, XRES/CELL, YRES/CELL, GL_GREEN, GL_FLOAT, sim->gravy); glUniform1i(glGetUniformLocation(lensProg, "tfY"), 2); glActiveTexture(GL_TEXTURE0); glUniform1fv(glGetUniformLocation(lensProg, "xres"), 1, &xres); glUniform1fv(glGetUniformLocation(lensProg, "yres"), 1, &yres); } else { glBindTexture(GL_TEXTURE_2D, partsFboTex); glBlendFunc(GL_ONE, GL_ONE); } int sdl_scale = 1; glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glBegin(GL_QUADS); glTexCoord2d(1, 0); //glVertex3f(XRES*sdl_scale, (YRES+MENUSIZE)*sdl_scale, 1.0); glVertex3f(XRES*sdl_scale, YRES*sdl_scale, 1.0); glTexCoord2d(0, 0); //glVertex3f(0, (YRES+MENUSIZE)*sdl_scale, 1.0); glVertex3f(0, YRES*sdl_scale, 1.0); glTexCoord2d(0, 1); //glVertex3f(0, MENUSIZE*sdl_scale, 1.0); glVertex3f(0, 0, 1.0); glTexCoord2d(1, 1); //glVertex3f(XRES*sdl_scale, MENUSIZE*sdl_scale, 1.0); glVertex3f(XRES*sdl_scale, 0, 1.0); glEnd(); if(display_mode & DISPLAY_WARP) { glUseProgram(0); } glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable( GL_TEXTURE_2D ); #endif #if defined(OGLI) && !defined(OGLR) if(display_mode & DISPLAY_WARP) { render_gravlensing(warpVid); } g->draw_image(vid, 0, 0, VIDXRES, VIDYRES, 255); #endif #if !defined(OGLR) && !defined(OGLI) if(display_mode & DISPLAY_WARP) { render_gravlensing(warpVid); } #endif } void Renderer::RenderZoom() { if(!zoomEnabled) return; #if defined(OGLR) int sdl_scale = 1; 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; yfactor*=-1.0f; zcx1 = (zoomScopePosition.X)*xfactor; zcx0 = (zoomScopePosition.X+zoomScopeSize)*xfactor; zcy1 = (zoomScopePosition.Y-1)*yfactor; zcy0 = ((zoomScopePosition.Y-1+zoomScopeSize))*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); //Draw zoomed texture glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glBegin(GL_QUADS); glTexCoord2d(zcx1, zcy1); glVertex2i(zoomWindowPosition.X, zoomWindowPosition.Y); glTexCoord2d(zcx0, zcy1); glVertex2i(zoomWindowPosition.X+(zoomScopeSize*ZFACTOR), zoomWindowPosition.Y); glTexCoord2d(zcx0, zcy0); glVertex2i(zoomWindowPosition.X+(zoomScopeSize*ZFACTOR), zoomWindowPosition.Y+(zoomScopeSize*ZFACTOR)); glTexCoord2d(zcx1, zcy0); glVertex2i(zoomWindowPosition.X, zoomWindowPosition.Y+(zoomScopeSize*ZFACTOR)); glEnd(); glBindTexture(GL_TEXTURE_2D, 0); glDisable( GL_TEXTURE_2D ); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //Lines to make the pixels stand out glLineWidth(sdl_scale); //glEnable(GL_LINE_SMOOTH); glBegin(GL_LINES); glColor4f(0.0f, 0.0f, 0.0f, 1.0f); for(i = 0; i < zoomScopeSize; i++) { //Across glVertex2i(zoomWindowPosition.X, zoomWindowPosition.Y+(i*ZFACTOR)); glVertex2i(zoomWindowPosition.X+(zoomScopeSize*ZFACTOR), zoomWindowPosition.Y+(i*ZFACTOR)); //Down glVertex2i(zoomWindowPosition.X+(i*ZFACTOR), zoomWindowPosition.Y); glVertex2i(zoomWindowPosition.X+(i*ZFACTOR), zoomWindowPosition.Y+(zoomScopeSize*ZFACTOR)); } glEnd(); //Draw zoom window border glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glBegin(GL_LINE_LOOP); glVertex2i(zoomWindowPosition.X, zoomWindowPosition.Y); glVertex2i(zoomWindowPosition.X+(zoomScopeSize*ZFACTOR), zoomWindowPosition.Y); glVertex2i(zoomWindowPosition.X+(zoomScopeSize*ZFACTOR), zoomWindowPosition.Y+(zoomScopeSize*ZFACTOR)); glVertex2i(zoomWindowPosition.X, zoomWindowPosition.Y+(zoomScopeSize*ZFACTOR)); glEnd(); //glDisable(GL_LINE_SMOOTH); if(zoomEnabled) { glEnable(GL_COLOR_LOGIC_OP); //glEnable(GL_LINE_SMOOTH); glLogicOp(GL_XOR); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glBegin(GL_LINE_LOOP); glVertex2i(zoomScopePosition.X, zoomScopePosition.Y); glVertex2i(zoomScopePosition.X+zoomScopeSize, zoomScopePosition.Y); glVertex2i(zoomScopePosition.X+zoomScopeSize, zoomScopePosition.Y+zoomScopeSize); glVertex2i(zoomScopePosition.X, zoomScopePosition.Y+zoomScopeSize); /*glVertex3i((zoomScopePosition.X-1)*sdl_scale, (YRES+MENUSIZE-(zoomScopePosition.Y-1))*sdl_scale, 0); glVertex3i((zoomScopePosition.X-1)*sdl_scale, (YRES+MENUSIZE-(zoomScopePosition.Y+zoomScopeSize))*sdl_scale, 0); glVertex3i((zoomScopePosition.X+zoomScopeSize)*sdl_scale, (YRES+MENUSIZE-(zoomScopePosition.Y+zoomScopeSize))*sdl_scale, 0); glVertex3i((zoomScopePosition.X+zoomScopeSize)*sdl_scale, (YRES+MENUSIZE-(zoomScopePosition.Y-1))*sdl_scale, 0); glVertex3i((zoomScopePosition.X-1)*sdl_scale, (YRES+MENUSIZE-(zoomScopePosition.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 = vid; drawrect(zoomWindowPosition.X-2, zoomWindowPosition.Y-2, zoomScopeSize*ZFACTOR+4, zoomScopeSize*ZFACTOR+4, 192, 192, 192, 255); drawrect(zoomWindowPosition.X-1, zoomWindowPosition.Y-1, zoomScopeSize*ZFACTOR+2, zoomScopeSize*ZFACTOR+2, 0, 0, 0, 255); clearrect(zoomWindowPosition.X, zoomWindowPosition.Y, zoomScopeSize*ZFACTOR, zoomScopeSize*ZFACTOR); for (j=0; j=Renderer_wtypesCount) return 0; wall_type *wtypes = Renderer_wtypes; pixel pc = wtypes[wt].colour; pixel gc = wtypes[wt].eglow; VideoBuffer * newTexture = new VideoBuffer(width, height); if (wtypes[wt].drawstyle==1) { for (j=0; j>1)&1; iSetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255); } else if (wtypes[wt].drawstyle==2) { for (j=0; jSetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255); } else if (wtypes[wt].drawstyle==3) { for (j=0; jSetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255); } else if (wtypes[wt].drawstyle==4) { for (j=0; jSetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255); else if (i%CELL == (j%CELL)+1 || (i%CELL == 0 && j%CELL == CELL-1)) newTexture->SetPixel(i, j, PIXR(gc), PIXG(gc), PIXB(gc), 255); else newTexture->SetPixel(i, j, 0x20, 0x20, 0x20, 255); } // special rendering for some walls if (wt==WL_EWALL) { for (j=0; jSetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255); } for (; iSetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255); } } } else if (wt==WL_WALLELEC) { for (j=0; jSetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255); else newTexture->SetPixel(i, j, 0x80, 0x80, 0x80, 255); } } else if (wt==WL_EHOLE) { for (j=0; jSetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255); } for (; iSetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255); } } } else if (wt == WL_ERASE) { for (j=0; j>1)); iSetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255); } } for (j=0; jSetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255); } } for (j=3; j<(width-4)/2; j++) { newTexture->SetPixel(j+6, j, 0xFF, 0, 0, 255); newTexture->SetPixel(j+7, j, 0xFF, 0, 0, 255); newTexture->SetPixel(-j+19, j, 0xFF, 0, 0, 255); newTexture->SetPixel(-j+20, j, 0xFF, 0, 0, 255); } } else if(wt == WL_STREAM) { for (j=0; jSetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255); } } newTexture->SetCharacter(4, 2, 0x8D, 255, 255, 255, 255); for (i=width/3; iSetPixel(i, 7+(int)(3.9f*cos(i*0.3f)), 255, 255, 255, 255); } } return newTexture; } 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; for (y=0; y=UI_WALLCOUNT) continue; pc = wtypes[wt].colour; gc = wtypes[wt].eglow; #ifdef OGLR int r = (pc&0x00FF0000)>>8; int g = (pc&0x0000FF00)>>4; int b = (pc&0x000000FF)>>0; int a = 255; #endif #ifndef OGLR // standard wall patterns if (wtypes[wt].drawstyle==1) { for (j=0; j>1)&1; i=XRES || ny<0 || ny>=YRES) break; addpixel(nx, ny, 255, 255, 255, 64); i = nx/CELL; j = ny/CELL; lx += sim->vx[j][i]*0.125f; ly += sim->vy[j][i]*0.125f; if (bmap[j][i]==WL_STREAM && i!=x && j!=y) break; } drawtext(x*CELL, y*CELL-2, "\x8D", 255, 255, 255, 128); } 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; } #else this->drawrect(x*CELL,y*CELL,CELL,CELL,r,g,b,a,false); #endif } } void Renderer::DrawSigns() { int i, j, x, y, w, h, dx, dy,mx,my,b=1,bq; std::vector signs = sim->signs; #ifdef OGLR GLint prevFbo; glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prevFbo); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, partsFbo); glTranslated(0, MENUSIZE, 0); #endif for (i=0; i < signs.size(); i++) if (signs[i].text.length()) { char buff[256]; //Buffer sim->signs[i].pos(x, y, w, h); clearrect(x, y, w, h); drawrect(x, y, w, h, 192, 192, 192, 255); //Displaying special information if (signs[i].text == "{p}") { float pressure = 0.0f; if (signs[i].x>=0 && signs[i].x=0 && signs[i].ypv[signs[i].y/CELL][signs[i].x/CELL]; sprintf(buff, "Pressure: %3.2f", pressure); //...pressure drawtext(x+3, y+3, buff, 255, 255, 255, 255); } else if (signs[i].text == "{t}") { if (signs[i].x>=0 && signs[i].x=0 && signs[i].ypmap[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); //...temperature else sprintf(buff, "Temp: 0.00"); //...temperature drawtext(x+3, y+3, buff, 255, 255, 255, 255); } else if (sregexp(signs[i].text.c_str(), "^{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++; } drawtext(x+3, y+3, buff, 0, 191, 255, 255); } else { 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; #ifdef OGLR glBegin(GL_LINES); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glVertex2i(x, y); glVertex2i(x+(dx*4), y+(dy*4)); glEnd(); #else for (j=0; j<4; j++) { blendpixel(x, y, 192, 192, 192, 255); x+=dx; y+=dy; } #endif /*if (MSIGN==i) { bq = b; b = SDL_GetMouseState(&mx, &my); mx /= sdl_scale; my /= sdl_scale; signs[i].x = mx; signs[i].y = my; }*/ } #ifdef OGLR glTranslated(0, -MENUSIZE, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prevFbo); #endif } void Renderer::render_gravlensing(pixel * source) { #ifndef OGLR int nx, ny, rx, ry, gx, gy, bx, by, co; int r, g, b; pixel t; pixel *src = source; pixel *dst = 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*(VIDXRES)+nx]; r = PIXR(src[ry*(VIDXRES)+rx]) + PIXR(t); g = PIXG(src[gy*(VIDXRES)+gx]) + PIXG(t); b = PIXB(src[by*(VIDXRES)+bx]) + PIXB(t); if (r>255) r = 255; if (g>255) g = 255; if (b>255) b = 255; dst[ny*(VIDXRES)+nx] = PIXRGB(r,g,b); } } } #endif } void Renderer::render_fire() { #ifndef OGLR if(!(render_mode & FIREMODE)) return; int i,j,x,y,r,g,b,nx,ny; for (j=0; j=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; } #endif } float temp[CELL*3][CELL*3]; float fire_alphaf[CELL*3][CELL*3]; float glow_alphaf[11][11]; float blur_alphaf[7][7]; void Renderer::prepare_alpha(int size, float intensity) { //TODO: implement size int x,y,i,j,c; float multiplier = 255.0f*intensity; 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; Element *elements; if(!sim) return; parts = sim->parts; elements = sim->elements; #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; GLint origBlendSrc, origBlendDst, prevFbo; glGetIntegerv(GL_BLEND_SRC, &origBlendSrc); glGetIntegerv(GL_BLEND_DST, &origBlendDst); glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prevFbo); //Render to the particle FBO glBindFramebuffer(GL_DRAW_FRAMEBUFFER, partsFbo); glTranslated(0, MENUSIZE, 0); #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) && !(sim->elements[t].Properties & TYPE_ENERGY) && t!=PT_STKM && t!=PT_STKM2 && t!=PT_FIGH) continue; if(nx >= XRES || nx < 0 || ny >= YRES || ny < 0) continue; //Defaults pixel_mode = 0 | PMODE_FLAT; cola = 255; colr = PIXR(elements[t].Colour); colg = PIXG(elements[t].Colour); colb = PIXB(elements[t].Colour); 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 (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(!(colour_mode & COLOUR_BASC)) { if (elements[t].Graphics) { if ((*(elements[t].Graphics))(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 { 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((elements[t].Properties & PROP_HOT_GLOW) && sim->parts[i].temp>(elements[t].HighTemperature-800.0f)) { gradv = 3.1415/(2*elements[t].HighTemperature-(elements[t].HighTemperature-800.0f)); caddress = (sim->parts[i].temp>elements[t].HighTemperature)?elements[t].HighTemperature-(elements[t].HighTemperature-800.0f):sim->parts[i].temp-(elements[t].HighTemperature-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_BLEND; 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_BASC) { colr = PIXR(elements[t].Colour); colg = PIXG(elements[t].Colour); colb = PIXB(elements[t].Colour); pixel_mode = PMODE_FLAT; } //Apply decoration colour if(!(colour_mode & ~COLOUR_GRAD)) { 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; } } 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; } #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; if(firer>255) firer = 255; else if(firer<0) firer = 0; if(fireg>255) fireg = 255; else if(fireg<0) fireg = 0; if(fireb>255) fireb = 255; else if(fireb<0) fireb = 0; if(firea>255) firea = 255; else if(firea<0) firea = 0; #endif //Pixel rendering if (pixel_mode & EFFECT_LINES) { if (t==PT_SOAP) { if ((parts[i].ctype&7) == 7) draw_line(nx, ny, (int)(parts[parts[i].tmp].x+0.5f), (int)(parts[parts[i].tmp].y+0.5f), colr, colg, colb, cola); } } if(pixel_mode & PSPEC_STICKMAN) { char buff[4]; //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 (mousePosX>(nx-3) && mousePosX<(nx+3) && mousePosY<(ny+3) && mousePosY>(ny-3)) //If mouse is in the head { sprintf(buff, "%3d", sim->parts[i].life); //Show HP drawtext(mousePosX-8-2*(sim->parts[i].life<100)-2*(sim->parts[i].life<10), mousePosY-12, buff, 255, 255, 255, 255); } if (colour_mode!=COLOUR_HEAT) { if (cplayer->elemelem > 0) { colr = PIXR(elements[cplayer->elem].Colour); colg = PIXG(elements[cplayer->elem].Colour); colb = PIXB(elements[cplayer->elem].Colour); } 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 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) { draw_line(nx, ny+2, nx+2, ny, colr, colg, colb, 255); draw_line(nx+2, ny, nx, ny-2, colr, colg, colb, 255); draw_line(nx, ny-2, nx-2, ny, colr, colg, colb, 255); draw_line(nx-2, ny, nx, ny+2, colr, colg, colb, 255); } else { draw_line(nx-2, ny+2, nx+2, ny+2, colr, colg, colb, 255); draw_line(nx-2, ny-2, nx+2, ny-2, colr, colg, colb, 255); draw_line(nx-2, ny-2, nx-2, ny+2, colr, colg, colb, 255); draw_line(nx+2, ny-2, nx+2, ny+2, colr, colg, colb, 255); } //legs draw_line(nx, ny+3, cplayer->legs[0], cplayer->legs[1], legr, legg, legb, 255); draw_line(cplayer->legs[0], cplayer->legs[1], cplayer->legs[4], cplayer->legs[5], legr, legg, legb, 255); draw_line(nx, ny+3, cplayer->legs[8], cplayer->legs[9], legr, legg, legb, 255); draw_line(cplayer->legs[8], cplayer->legs[9], cplayer->legs[12], cplayer->legs[13], legr, legg, legb, 255); #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 vid[ny*(VIDXRES)+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 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 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 vid[ny*(VIDXRES)+nx] = PIXRGB(colr,colg,colb); blendpixel(nx+1, ny, colr, colg, colb, 223); blendpixel(nx-1, ny, colr, colg, colb, 223); blendpixel(nx, ny+1, colr, colg, colb, 223); blendpixel(nx, ny-1, colr, colg, colb, 223); blendpixel(nx+1, ny-1, colr, colg, colb, 112); blendpixel(nx-1, ny-1, colr, colg, colb, 112); blendpixel(nx+1, ny+1, colr, colg, colb, 112); blendpixel(nx-1, ny+1, colr, colg, colb, 112); #endif } if(pixel_mode & PMODE_GLOW) { int cola1 = (5*cola)/255; #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 addpixel(nx, ny, colr, colg, colb, (192*cola)/255); addpixel(nx+1, ny, colr, colg, colb, (96*cola)/255); addpixel(nx-1, ny, colr, colg, colb, (96*cola)/255); addpixel(nx, ny+1, colr, colg, colb, (96*cola)/255); addpixel(nx, ny-1, colr, colg, colb, (96*cola)/255); for (x = 1; x < 6; x++) { addpixel(nx, ny-x, colr, colg, colb, cola1); addpixel(nx, ny+x, colr, colg, colb, cola1); addpixel(nx-x, ny, colr, colg, colb, cola1); addpixel(nx+x, ny, colr, colg, colb, cola1); for (y = 1; y < 6; y++) { if(x + y > 7) continue; addpixel(nx+x, ny-y, colr, colg, colb, cola1); addpixel(nx-x, ny+y, colr, colg, colb, cola1); addpixel(nx+x, ny+y, colr, colg, colb, cola1); addpixel(nx-x, ny-y, colr, colg, colb, cola1); } } #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)) blendpixel(x+nx, y+ny, colr, colg, colb, 30); if (abs(x)+abs(y) <=3 && abs(x)+abs(y)) blendpixel(x+nx, y+ny, colr, colg, colb, 20); if (abs(x)+abs(y) == 2) 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++) { addpixel(nx+x, ny, colr, colg, colb, gradv); addpixel(nx-x, ny, colr, colg, colb, gradv); addpixel(nx, ny+x, colr, colg, colb, gradv); 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; blendpixel(nx, ny, colr, colg, colb, (gradv*4)>255?255:(gradv*4) ); blendpixel(nx+1, ny, colr, colg, colb, (gradv*2)>255?255:(gradv*2) ); blendpixel(nx-1, ny, colr, colg, colb, (gradv*2)>255?255:(gradv*2) ); blendpixel(nx, ny+1, colr, colg, colb, (gradv*2)>255?255:(gradv*2) ); blendpixel(nx, ny-1, colr, colg, colb, (gradv*2)>255?255:(gradv*2) ); if (gradv>255) gradv=255; blendpixel(nx+1, ny-1, colr, colg, colb, gradv); blendpixel(nx-1, ny-1, colr, colg, colb, gradv); blendpixel(nx+1, ny+1, colr, colg, colb, gradv); blendpixel(nx-1, ny+1, colr, colg, colb, gradv); for (x = 1; gradv>0.5; x++) { addpixel(nx+x, ny, colr, colg, colb, gradv); addpixel(nx-x, ny, colr, colg, colb, gradv); addpixel(nx, ny+x, colr, colg, colb, gradv); 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; blendpixel(nx, ny, colr, colg, colb, (gradv*4)>255?255:(gradv*4) ); blendpixel(nx+1, ny, colr, colg, colb, (gradv*2)>255?255:(gradv*2) ); blendpixel(nx-1, ny, colr, colg, colb, (gradv*2)>255?255:(gradv*2) ); blendpixel(nx, ny+1, colr, colg, colb, (gradv*2)>255?255:(gradv*2) ); blendpixel(nx, ny-1, colr, colg, colb, (gradv*2)>255?255:(gradv*2) ); if (gradv>255) gradv=255; blendpixel(nx+1, ny-1, colr, colg, colb, gradv); blendpixel(nx-1, ny-1, colr, colg, colb, gradv); blendpixel(nx+1, ny+1, colr, colg, colb, gradv); blendpixel(nx-1, ny+1, colr, colg, colb, gradv); for (x = 1; gradv>0.5; x++) { addpixel(nx+x, ny, colr, colg, colb, gradv); addpixel(nx-x, ny, colr, colg, colb, gradv); addpixel(nx, ny+x, colr, colg, colb, gradv); 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+nxoorbitalparts_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+nxo> 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 glTranslated(0, -MENUSIZE, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prevFbo); 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 GLint prevFbo; glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prevFbo); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, partsFbo); glTranslated(0, MENUSIZE, 0); 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(); glTranslated(0, -MENUSIZE, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prevFbo); #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; jgravx[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; addpixel((int)(nx+0.5f), (int)(ny+0.5f), 255, 255, 255, (int)(dist*20.0f)); } } } } void Renderer::draw_air() { if(!sim->aheat_enable && (display_mode & DISPLAY_AIRH)) return; #ifndef OGLR if(!(display_mode & DISPLAY_AIR)) return; 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; jair->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, sim->air->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, sim->air->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); glTranslated(0, -MENUSIZE, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prevFbo); glDisable( GL_TEXTURE_2D ); #endif } void Renderer::draw_grav_zones() { if(!gravityZonesEnabled) return; int x, y, i, j; for (y=0; ygrav->gravmask[y*(XRES/CELL)+x]) { for (j=0; jg = g; this->sim = sim; #if !defined(OGLR) #if defined(OGLI) vid = new pixel[VIDXRES*VIDYRES]; #else vid = g->vid; #endif persistentVid = new pixel[VIDXRES*YRES]; warpVid = new pixel[VIDXRES*VIDYRES]; #endif memset(fire_r, 0, sizeof(fire_r)); memset(fire_g, 0, sizeof(fire_g)); memset(fire_b, 0, sizeof(fire_b)); //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); #ifdef OGLR //FBO Texture glEnable(GL_TEXTURE_2D); glGenTextures(1, &partsFboTex); glBindTexture(GL_TEXTURE_2D, partsFboTex); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, XRES, YRES, 0, GL_RGBA, GL_FLOAT, NULL); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); //FBO glGenFramebuffers(1, &partsFbo); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, partsFbo); glEnable(GL_BLEND); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, partsFboTex, 0); glBindTexture(GL_TEXTURE_2D, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); // Reset framebuffer binding glDisable(GL_TEXTURE_2D); //Texture for air to be drawn glEnable(GL_TEXTURE_2D); glGenTextures(1, &airBuf); glBindTexture(GL_TEXTURE_2D, airBuf); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, XRES/CELL, YRES/CELL, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); //Zoom texture glEnable(GL_TEXTURE_2D); glGenTextures(1, &zoomTex); glBindTexture(GL_TEXTURE_2D, zoomTex); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); //Texture for velocity maps for gravity glEnable(GL_TEXTURE_2D); glGenTextures(1, &partsTFX); glBindTexture(GL_TEXTURE_2D, partsTFX); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, XRES/CELL, YRES/CELL, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); glGenTextures(1, &partsTFY); glBindTexture(GL_TEXTURE_2D, partsTFY); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, XRES/CELL, YRES/CELL, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); //Texture for velocity maps for air //TODO: Combine all air maps into 3D array or structs glEnable(GL_TEXTURE_2D); glGenTextures(1, &airVX); glBindTexture(GL_TEXTURE_2D, airVX); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, XRES/CELL, YRES/CELL, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); glGenTextures(1, &airVY); glBindTexture(GL_TEXTURE_2D, airVY); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, XRES/CELL, YRES/CELL, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); glGenTextures(1, &airPV); glBindTexture(GL_TEXTURE_2D, airPV); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, XRES/CELL, YRES/CELL, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); //Fire alpha texture glEnable(GL_TEXTURE_2D); glGenTextures(1, &fireAlpha); glBindTexture(GL_TEXTURE_2D, fireAlpha); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, CELL*3, CELL*3, 0, GL_ALPHA, GL_FLOAT, NULL); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); //Glow alpha texture glEnable(GL_TEXTURE_2D); glGenTextures(1, &glowAlpha); glBindTexture(GL_TEXTURE_2D, glowAlpha); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 11, 11, 0, GL_ALPHA, GL_FLOAT, NULL); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); //Blur Alpha texture glEnable(GL_TEXTURE_2D); glGenTextures(1, &blurAlpha); glBindTexture(GL_TEXTURE_2D, blurAlpha); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 7, 7, 0, GL_ALPHA, GL_FLOAT, NULL); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); loadShaders(); #endif prepare_alpha(CELL, 1.0f); } void Renderer::CompileRenderMode() { int old_render_mode = render_mode; render_mode = 0; for(int i = 0; i < render_modes.size(); i++) render_mode |= render_modes[i]; //If firemode is removed, clear the fire display if(!(render_mode & FIREMODE) && (old_render_mode & FIREMODE)) { ClearAccumulation(); } } void Renderer::ClearAccumulation() { emp_decor = 0; std::fill(fire_r[0]+0, fire_r[(YRES/CELL)-1]+((XRES/CELL)-1), 0); std::fill(fire_g[0]+0, fire_g[(YRES/CELL)-1]+((XRES/CELL)-1), 0); std::fill(fire_b[0]+0, fire_b[(YRES/CELL)-1]+((XRES/CELL)-1), 0); #ifndef OGLR std::fill(persistentVid, persistentVid+(VIDXRES*YRES), 0); #endif } 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; } if(display_modes[i] & DISPLAY_AIR) { display_modes.erase(display_modes.begin()+i); } } 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; } VideoBuffer Renderer::DumpFrame() { #ifdef OGLR #elif defined(OGLI) VideoBuffer newBuffer(XRES, YRES); std::copy(vid, vid+(XRES*YRES), newBuffer.Buffer); return newBuffer; #else VideoBuffer newBuffer(XRES, YRES); for(int y = 0; y < YRES; y++) { std::copy(vid+(y*(XRES+BARSIZE)), vid+(y*(XRES+BARSIZE))+XRES, newBuffer.Buffer+(y*XRES)); } return newBuffer; #endif } Renderer::~Renderer() { #if !defined(OGLR) #if defined(OGLI) delete[] vid; #endif delete[] persistentVid; delete[] warpVid; #endif free(graphicscache); free(flm_data); free(plasma_data); } #define PIXELMETHODS_CLASS Renderer #ifdef OGLR #include "OpenGLDrawMethods.inl" #else #include "RasterDrawMethods.inl" #endif #undef PIXELMETHODS_CLASS