1 #include "Renderer.h"
2
3 #include <cmath>
4 #include <iostream>
5 #include <iomanip>
6 #include <vector>
7 #include <cstdio>
8 #include <cstdlib>
9 #include "Config.h"
10 #include "Misc.h"
11
12 #include "common/tpt-rand.h"
13 #include "common/tpt-compat.h"
14
15 #include "gui/game/RenderPreset.h"
16
17 #include "simulation/Simulation.h"
18 #include "simulation/ElementGraphics.h"
19 #include "simulation/Air.h"
20 #include "simulation/Gravity.h"
21 #include "simulation/ElementClasses.h"
22
23 #ifdef LUACONSOLE
24 #include "lua/LuaScriptInterface.h"
25 #include "lua/LuaScriptHelper.h"
26 #include "lua/LuaSmartRef.h"
27 #endif
28 #include "hmap.h"
29 #ifdef OGLR
30 #include "Shaders.h"
31 #endif
32
33 #ifndef OGLI
34 #define VIDXRES WINDOWW
35 #define VIDYRES WINDOWH
36 #else
37 #define VIDXRES XRES
38 #define VIDYRES YRES
39 #endif
40
41
RenderBegin()42 void Renderer::RenderBegin()
43 {
44 #ifdef OGLI
45 #ifdef OGLR
46 draw_air();
47 draw_grav();
48 DrawWalls();
49 render_parts();
50 render_fire();
51 draw_other();
52 draw_grav_zones();
53 DrawSigns();
54
55 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prevFbo);
56 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, partsFbo);
57 glTranslated(0, MENUSIZE, 0);
58 #else
59 if(display_mode & DISPLAY_PERS)
60 {
61 std::copy(persistentVid, persistentVid+(VIDXRES*YRES), vid);
62 }
63 pixel * oldVid;
64 if(display_mode & DISPLAY_WARP)
65 {
66 oldVid = vid;
67 vid = warpVid;
68 std::fill(warpVid, warpVid+(VIDXRES*VIDYRES), 0);
69 }
70
71 draw_air();
72 draw_grav();
73 DrawWalls();
74 render_parts();
75 if(display_mode & DISPLAY_PERS)
76 {
77 int i,r,g,b;
78 for (i = 0; i < VIDXRES*YRES; i++)
79 {
80 r = PIXR(vid[i]);
81 g = PIXG(vid[i]);
82 b = PIXB(vid[i]);
83 if (r>0)
84 r--;
85 if (g>0)
86 g--;
87 if (b>0)
88 b--;
89 persistentVid[i] = PIXRGB(r,g,b);
90 }
91 }
92
93 render_fire();
94 draw_other();
95 draw_grav_zones();
96 DrawSigns();
97 if(display_mode & DISPLAY_WARP)
98 {
99 vid = oldVid;
100 }
101 #endif
102 #else
103 if(display_mode & DISPLAY_PERS)
104 {
105 std::copy(persistentVid, persistentVid+(VIDXRES*YRES), vid);
106 }
107 pixel * oldVid = NULL;
108 if(display_mode & DISPLAY_WARP)
109 {
110 oldVid = vid;
111 vid = warpVid;
112 std::fill(warpVid, warpVid+(VIDXRES*VIDYRES), 0);
113 }
114
115 draw_air();
116 draw_grav();
117 DrawWalls();
118 render_parts();
119 if(display_mode & DISPLAY_PERS)
120 {
121 int i,r,g,b;
122 for (i = 0; i < VIDXRES*YRES; i++)
123 {
124 r = PIXR(vid[i]);
125 g = PIXG(vid[i]);
126 b = PIXB(vid[i]);
127 if (r>0)
128 r--;
129 if (g>0)
130 g--;
131 if (b>0)
132 b--;
133 persistentVid[i] = PIXRGB(r,g,b);
134 }
135 }
136
137 render_fire();
138 draw_other();
139 draw_grav_zones();
140 DrawSigns();
141
142 if(display_mode & DISPLAY_WARP)
143 {
144 vid = oldVid;
145 }
146
147 FinaliseParts();
148 #endif
149 }
150
RenderEnd()151 void Renderer::RenderEnd()
152 {
153 #ifdef OGLI
154 #ifdef OGLR
155 glTranslated(0, -MENUSIZE, 0);
156 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prevFbo);
157 FinaliseParts();
158 RenderZoom();
159 #else
160 RenderZoom();
161 FinaliseParts();
162 #endif
163 #else
164 RenderZoom();
165 #endif
166 }
167
SetSample(int x,int y)168 void Renderer::SetSample(int x, int y)
169 {
170 sampleColor = GetPixel(x, y);
171 }
172
clearScreen(float alpha)173 void Renderer::clearScreen(float alpha)
174 {
175 #ifdef OGLR
176 GLint prevFbo;
177 if(alpha > 0.999f)
178 {
179 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
180 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prevFbo);
181 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, partsFbo);
182 glClear(GL_COLOR_BUFFER_BIT);
183 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prevFbo);
184 }
185 else
186 {
187 glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
188 glColor4f(1.0f, 1.0f, 1.0f, alpha);
189 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prevFbo);
190 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, partsFbo);
191 glBegin(GL_QUADS);
192 glVertex2f(0, 0);
193 glVertex2f(XRES, 0);
194 glVertex2f(XRES, YRES);
195 glVertex2f(0, YRES);
196 glEnd();
197 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prevFbo);
198 glBlendEquation(GL_FUNC_ADD);
199 }
200 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
201 glClear(GL_COLOR_BUFFER_BIT);
202 #endif
203 #ifdef OGLI
204 #ifndef OGLR
205 std::fill(vid, vid+(VIDXRES*VIDYRES), 0);
206 #endif
207 #else
208 g->Clear();
209 #endif
210 }
211 #ifdef OGLR
checkShader(GLuint shader,const char * shname)212 void Renderer::checkShader(GLuint shader, const char * shname)
213 {
214 GLint status;
215 glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
216 if (status == GL_FALSE)
217 {
218 char errorBuf[ GL_INFO_LOG_LENGTH];
219 int errLen;
220 glGetShaderInfoLog(shader, GL_INFO_LOG_LENGTH, &errLen, errorBuf);
221 fprintf(stderr, "Failed to compile %s shader:\n%s\n", shname, errorBuf);
222 exit(1);
223 }
224 }
checkProgram(GLuint program,const char * progname)225 void Renderer::checkProgram(GLuint program, const char * progname)
226 {
227 GLint status;
228 glGetProgramiv(program, GL_LINK_STATUS, &status);
229 if (status == GL_FALSE)
230 {
231 char errorBuf[ GL_INFO_LOG_LENGTH];
232 int errLen;
233 glGetShaderInfoLog(program, GL_INFO_LOG_LENGTH, &errLen, errorBuf);
234 fprintf(stderr, "Failed to link %s program:\n%s\n", progname, errorBuf);
235 exit(1);
236 }
237 }
loadShaders()238 void Renderer::loadShaders()
239 {
240 GLuint vertexShader, fragmentShader;
241
242 //Particle texture
243 vertexShader = glCreateShader(GL_VERTEX_SHADER);
244 fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
245
246 glShaderSource( vertexShader, 1, &fireVertex, NULL);
247 glShaderSource( fragmentShader, 1, &fireFragment, NULL);
248
249 glCompileShader( vertexShader );
250 checkShader(vertexShader, "FV");
251 glCompileShader( fragmentShader );
252 checkShader(fragmentShader, "FF");
253
254 fireProg = glCreateProgram();
255 glAttachShader( fireProg, vertexShader );
256 glAttachShader( fireProg, fragmentShader );
257 glLinkProgram( fireProg );
258 checkProgram(fireProg, "F");
259
260 //Lensing
261 vertexShader = glCreateShader(GL_VERTEX_SHADER);
262 fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
263
264 glShaderSource( vertexShader, 1, &lensVertex, NULL);
265 glShaderSource( fragmentShader, 1, &lensFragment, NULL);
266
267 glCompileShader( vertexShader );
268 checkShader(vertexShader, "LV");
269 glCompileShader( fragmentShader );
270 checkShader(fragmentShader, "LF");
271
272 lensProg = glCreateProgram();
273 glAttachShader( lensProg, vertexShader );
274 glAttachShader( lensProg, fragmentShader );
275 glLinkProgram( lensProg );
276 checkProgram(lensProg, "L");
277
278 //Air Velocity
279 vertexShader = glCreateShader(GL_VERTEX_SHADER);
280 fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
281
282 glShaderSource( vertexShader, 1, &airVVertex, NULL);
283 glShaderSource( fragmentShader, 1, &airVFragment, NULL);
284
285 glCompileShader( vertexShader );
286 checkShader(vertexShader, "AVX");
287 glCompileShader( fragmentShader );
288 checkShader(fragmentShader, "AVF");
289
290 airProg_Velocity = glCreateProgram();
291 glAttachShader( airProg_Velocity, vertexShader );
292 glAttachShader( airProg_Velocity, fragmentShader );
293 glLinkProgram( airProg_Velocity );
294 checkProgram(airProg_Velocity, "AV");
295
296 //Air Pressure
297 vertexShader = glCreateShader(GL_VERTEX_SHADER);
298 fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
299
300 glShaderSource( vertexShader, 1, &airPVertex, NULL);
301 glShaderSource( fragmentShader, 1, &airPFragment, NULL);
302
303 glCompileShader( vertexShader );
304 checkShader(vertexShader, "APV");
305 glCompileShader( fragmentShader );
306 checkShader(fragmentShader, "APF");
307
308 airProg_Pressure = glCreateProgram();
309 glAttachShader( airProg_Pressure, vertexShader );
310 glAttachShader( airProg_Pressure, fragmentShader );
311 glLinkProgram( airProg_Pressure );
312 checkProgram(airProg_Pressure, "AP");
313
314 //Air cracker
315 vertexShader = glCreateShader(GL_VERTEX_SHADER);
316 fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
317
318 glShaderSource( vertexShader, 1, &airCVertex, NULL);
319 glShaderSource( fragmentShader, 1, &airCFragment, NULL);
320
321 glCompileShader( vertexShader );
322 checkShader(vertexShader, "ACV");
323 glCompileShader( fragmentShader );
324 checkShader(fragmentShader, "ACF");
325
326 airProg_Cracker = glCreateProgram();
327 glAttachShader( airProg_Cracker, vertexShader );
328 glAttachShader( airProg_Cracker, fragmentShader );
329 glLinkProgram( airProg_Cracker );
330 checkProgram(airProg_Cracker, "AC");
331 }
332 #endif
333
FinaliseParts()334 void Renderer::FinaliseParts()
335 {
336 #ifdef OGLR
337 glEnable( GL_TEXTURE_2D );
338 if(display_mode & DISPLAY_WARP)
339 {
340 float xres = XRES, yres = YRES;
341 glUseProgram(lensProg);
342 glActiveTexture(GL_TEXTURE0);
343 glBindTexture(GL_TEXTURE_2D, partsFboTex);
344 glUniform1i(glGetUniformLocation(lensProg, "pTex"), 0);
345 glActiveTexture(GL_TEXTURE1);
346 glBindTexture(GL_TEXTURE_2D, partsTFX);
347 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, XRES/CELL, YRES/CELL, GL_RED, GL_FLOAT, sim->gravx);
348 glUniform1i(glGetUniformLocation(lensProg, "tfX"), 1);
349 glActiveTexture(GL_TEXTURE2);
350 glBindTexture(GL_TEXTURE_2D, partsTFY);
351 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, XRES/CELL, YRES/CELL, GL_GREEN, GL_FLOAT, sim->gravy);
352 glUniform1i(glGetUniformLocation(lensProg, "tfY"), 2);
353 glActiveTexture(GL_TEXTURE0);
354 glUniform1fv(glGetUniformLocation(lensProg, "xres"), 1, &xres);
355 glUniform1fv(glGetUniformLocation(lensProg, "yres"), 1, &yres);
356 }
357 else
358 {
359 glBindTexture(GL_TEXTURE_2D, partsFboTex);
360 glBlendFunc(GL_ONE, GL_ONE);
361 }
362
363 int sdl_scale = 1;
364 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
365 glBegin(GL_QUADS);
366 glTexCoord2d(1, 0);
367 //glVertex3f(XRES*sdl_scale, WINDOWH*sdl_scale, 1.0);
368 glVertex3f(XRES*sdl_scale, YRES*sdl_scale, 1.0);
369 glTexCoord2d(0, 0);
370 //glVertex3f(0, WINDOWH*sdl_scale, 1.0);
371 glVertex3f(0, YRES*sdl_scale, 1.0);
372 glTexCoord2d(0, 1);
373 //glVertex3f(0, MENUSIZE*sdl_scale, 1.0);
374 glVertex3f(0, 0, 1.0);
375 glTexCoord2d(1, 1);
376 //glVertex3f(XRES*sdl_scale, MENUSIZE*sdl_scale, 1.0);
377 glVertex3f(XRES*sdl_scale, 0, 1.0);
378 glEnd();
379
380 if(display_mode & DISPLAY_WARP)
381 {
382 glUseProgram(0);
383
384 }
385 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
386 glDisable( GL_TEXTURE_2D );
387 #endif
388
389 #if defined(OGLI) && !defined(OGLR)
390 if(display_mode & DISPLAY_WARP)
391 {
392 render_gravlensing(warpVid);
393 }
394 g->draw_image(vid, 0, 0, VIDXRES, VIDYRES, 255);
395 #endif
396
397 #if !defined(OGLR) && !defined(OGLI)
398 if(display_mode & DISPLAY_WARP)
399 {
400 render_gravlensing(warpVid);
401 }
402 #endif
403 }
404
RenderZoom()405 void Renderer::RenderZoom()
406 {
407 if(!zoomEnabled)
408 return;
409 #if defined(OGLR)
410 int sdl_scale = 1;
411 int origBlendSrc, origBlendDst;
412 float zcx1, zcx0, zcy1, zcy0, yfactor, xfactor, i; //X-Factor is shit, btw
413 xfactor = 1.0f/(float)XRES;
414 yfactor = 1.0f/(float)YRES;
415 yfactor*=-1.0f;
416
417 zcx1 = (zoomScopePosition.X)*xfactor;
418 zcx0 = (zoomScopePosition.X+zoomScopeSize)*xfactor;
419 zcy1 = (zoomScopePosition.Y-1)*yfactor;
420 zcy0 = ((zoomScopePosition.Y-1+zoomScopeSize))*yfactor;
421
422 glGetIntegerv(GL_BLEND_SRC, &origBlendSrc);
423 glGetIntegerv(GL_BLEND_DST, &origBlendDst);
424 glBlendFunc(GL_ONE, GL_ZERO);
425
426 glEnable( GL_TEXTURE_2D );
427 //glReadBuffer(GL_AUX0);
428 glBindTexture(GL_TEXTURE_2D, partsFboTex);
429
430 //Draw zoomed texture
431 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
432 glBegin(GL_QUADS);
433 glTexCoord2d(zcx1, zcy1);
434 glVertex2i(zoomWindowPosition.X, zoomWindowPosition.Y);
435 glTexCoord2d(zcx0, zcy1);
436 glVertex2i(zoomWindowPosition.X+(zoomScopeSize*ZFACTOR), zoomWindowPosition.Y);
437 glTexCoord2d(zcx0, zcy0);
438 glVertex2i(zoomWindowPosition.X+(zoomScopeSize*ZFACTOR), zoomWindowPosition.Y+(zoomScopeSize*ZFACTOR));
439 glTexCoord2d(zcx1, zcy0);
440 glVertex2i(zoomWindowPosition.X, zoomWindowPosition.Y+(zoomScopeSize*ZFACTOR));
441 glEnd();
442 glBindTexture(GL_TEXTURE_2D, 0);
443 glDisable( GL_TEXTURE_2D );
444
445 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
446
447 //Lines to make the pixels stand out
448 glLineWidth(sdl_scale);
449 //glEnable(GL_LINE_SMOOTH);
450 glBegin(GL_LINES);
451 glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
452 for(i = 0; i < zoomScopeSize; i++)
453 {
454 //Across
455 glVertex2i(zoomWindowPosition.X, zoomWindowPosition.Y+(i*ZFACTOR));
456 glVertex2i(zoomWindowPosition.X+(zoomScopeSize*ZFACTOR), zoomWindowPosition.Y+(i*ZFACTOR));
457
458 //Down
459 glVertex2i(zoomWindowPosition.X+(i*ZFACTOR), zoomWindowPosition.Y);
460 glVertex2i(zoomWindowPosition.X+(i*ZFACTOR), zoomWindowPosition.Y+(zoomScopeSize*ZFACTOR));
461 }
462 glEnd();
463
464 //Draw zoom window border
465 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
466 glBegin(GL_LINE_LOOP);
467 glVertex2i(zoomWindowPosition.X, zoomWindowPosition.Y);
468 glVertex2i(zoomWindowPosition.X+(zoomScopeSize*ZFACTOR), zoomWindowPosition.Y);
469 glVertex2i(zoomWindowPosition.X+(zoomScopeSize*ZFACTOR), zoomWindowPosition.Y+(zoomScopeSize*ZFACTOR));
470 glVertex2i(zoomWindowPosition.X, zoomWindowPosition.Y+(zoomScopeSize*ZFACTOR));
471 glEnd();
472 //glDisable(GL_LINE_SMOOTH);
473
474 if(zoomEnabled)
475 {
476 glEnable(GL_COLOR_LOGIC_OP);
477 //glEnable(GL_LINE_SMOOTH);
478 glLogicOp(GL_XOR);
479 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
480 glBegin(GL_LINE_LOOP);
481 glVertex2i(zoomScopePosition.X, zoomScopePosition.Y);
482 glVertex2i(zoomScopePosition.X+zoomScopeSize, zoomScopePosition.Y);
483 glVertex2i(zoomScopePosition.X+zoomScopeSize, zoomScopePosition.Y+zoomScopeSize);
484 glVertex2i(zoomScopePosition.X, zoomScopePosition.Y+zoomScopeSize);
485 /*glVertex3i((zoomScopePosition.X-1)*sdl_scale, (WINDOWH-(zoomScopePosition.Y-1))*sdl_scale, 0);
486 glVertex3i((zoomScopePosition.X-1)*sdl_scale, (WINDOWH-(zoomScopePosition.Y+zoomScopeSize))*sdl_scale, 0);
487 glVertex3i((zoomScopePosition.X+zoomScopeSize)*sdl_scale, (WINDOWH-(zoomScopePosition.Y+zoomScopeSize))*sdl_scale, 0);
488 glVertex3i((zoomScopePosition.X+zoomScopeSize)*sdl_scale, (WINDOWH-(zoomScopePosition.Y-1))*sdl_scale, 0);
489 glVertex3i((zoomScopePosition.X-1)*sdl_scale, (WINDOWH-(zoomScopePosition.Y-1))*sdl_scale, 0);*/
490 glEnd();
491 glDisable(GL_COLOR_LOGIC_OP);
492 }
493 glLineWidth(1);
494 glBlendFunc(origBlendSrc, origBlendDst);
495 #else
496 int x, y, i, j;
497 pixel pix;
498 pixel * img = vid;
499 clearrect(zoomWindowPosition.X-1, zoomWindowPosition.Y-1, zoomScopeSize*ZFACTOR+1, zoomScopeSize*ZFACTOR+1);
500 drawrect(zoomWindowPosition.X-2, zoomWindowPosition.Y-2, zoomScopeSize*ZFACTOR+3, zoomScopeSize*ZFACTOR+3, 192, 192, 192, 255);
501 drawrect(zoomWindowPosition.X-1, zoomWindowPosition.Y-1, zoomScopeSize*ZFACTOR+1, zoomScopeSize*ZFACTOR+1, 0, 0, 0, 255);
502 for (j=0; j<zoomScopeSize; j++)
503 for (i=0; i<zoomScopeSize; i++)
504 {
505 pix = img[(j+zoomScopePosition.Y)*(VIDXRES)+(i+zoomScopePosition.X)];
506 for (y=0; y<ZFACTOR-1; y++)
507 for (x=0; x<ZFACTOR-1; x++)
508 img[(j*ZFACTOR+y+zoomWindowPosition.Y)*(VIDXRES)+(i*ZFACTOR+x+zoomWindowPosition.X)] = pix;
509 }
510 if (zoomEnabled)
511 {
512 for (j=-1; j<=zoomScopeSize; j++)
513 {
514 xor_pixel(zoomScopePosition.X+j, zoomScopePosition.Y-1);
515 xor_pixel(zoomScopePosition.X+j, zoomScopePosition.Y+zoomScopeSize);
516 }
517 for (j=0; j<zoomScopeSize; j++)
518 {
519 xor_pixel(zoomScopePosition.X-1, zoomScopePosition.Y+j);
520 xor_pixel(zoomScopePosition.X+zoomScopeSize, zoomScopePosition.Y+j);
521 }
522 }
523 #endif
524 }
525
526 std::vector<wall_type> Renderer_wtypes = LoadWalls();
527
528
WallIcon(int wallID,int width,int height)529 VideoBuffer * Renderer::WallIcon(int wallID, int width, int height)
530 {
531 int i, j;
532 int wt = wallID;
533 if (wt<0 || wt>=(int)Renderer_wtypes.size())
534 return 0;
535 wall_type *wtypes = Renderer_wtypes.data();
536 pixel pc = wtypes[wt].colour;
537 pixel gc = wtypes[wt].eglow;
538 VideoBuffer * newTexture = new VideoBuffer(width, height);
539 if (wtypes[wt].drawstyle==1)
540 {
541 for (j=0; j<height; j+=2)
542 for (i=(j>>1)&1; i<width; i+=2)
543 newTexture->SetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255);
544 }
545 else if (wtypes[wt].drawstyle==2)
546 {
547 for (j=0; j<height; j+=2)
548 for (i=0; i<width; i+=2)
549 newTexture->SetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255);
550 }
551 else if (wtypes[wt].drawstyle==3)
552 {
553 for (j=0; j<height; j++)
554 for (i=0; i<width; i++)
555 newTexture->SetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255);
556 }
557 else if (wtypes[wt].drawstyle==4)
558 {
559 for (j=0; j<height; j++)
560 for (i=0; i<width; i++)
561 if(i%CELL == j%CELL)
562 newTexture->SetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255);
563 else if (i%CELL == (j%CELL)+1 || (i%CELL == 0 && j%CELL == CELL-1))
564 newTexture->SetPixel(i, j, PIXR(gc), PIXG(gc), PIXB(gc), 255);
565 else
566 newTexture->SetPixel(i, j, 0x20, 0x20, 0x20, 255);
567 }
568
569 // special rendering for some walls
570 if (wt==WL_EWALL)
571 {
572 for (j=0; j<height; j++)
573 {
574 for (i=0; i<(width/4)+j; i++)
575 {
576 if (!(i&j&1))
577 newTexture->SetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255);
578 }
579 for (; i<width; i++)
580 {
581 if (i&j&1)
582 newTexture->SetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255);
583 }
584 }
585 }
586 else if (wt==WL_WALLELEC)
587 {
588 for (j=0; j<height; j++)
589 for (i=0; i<width; i++)
590 {
591 if (!(j%2) && !(i%2))
592 newTexture->SetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255);
593 else
594 newTexture->SetPixel(i, j, 0x80, 0x80, 0x80, 255);
595 }
596 }
597 else if (wt==WL_EHOLE || wt==WL_STASIS)
598 {
599 for (j=0; j<height; j++)
600 {
601 for (i=0; i<(width/4)+j; i++)
602 {
603 if (i&j&1)
604 newTexture->SetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255);
605 }
606 for (; i<width; i++)
607 {
608 if (!(i&j&1))
609 newTexture->SetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255);
610 }
611 }
612 }
613 else if (wt == WL_ERASE)
614 {
615 for (j=0; j<height; j+=2)
616 {
617 for (i=1+(1&(j>>1)); i<width/2; i+=2)
618 {
619 newTexture->SetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255);
620 }
621 }
622 for (j=0; j<height; j++)
623 {
624 for (i=width/2; i<width; i++)
625 {
626 newTexture->SetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255);
627 }
628 }
629 for (j=3; j<(width-4)/2; j++)
630 {
631 newTexture->SetPixel(j+6, j, 0xFF, 0, 0, 255);
632 newTexture->SetPixel(j+7, j, 0xFF, 0, 0, 255);
633 newTexture->SetPixel(-j+19, j, 0xFF, 0, 0, 255);
634 newTexture->SetPixel(-j+20, j, 0xFF, 0, 0, 255);
635 }
636 }
637 else if (wt == WL_ERASEALL)
638 {
639 for (int j = 0; j < height; j++)
640 {
641 int r = 100, g = 150, b = 50;
642 int rd = 1, gd = -1, bd = -1;
643 for (int i = 0; i < width; i++)
644 {
645 r += 15*rd;
646 g += 15*gd;
647 b += 15*bd;
648 if (r > 200) rd = -1;
649 if (g > 200) gd = -1;
650 if (b > 200) bd = -1;
651 if (r < 15) rd = 1;
652 if (g < 15) gd = 1;
653 if (b < 15) bd = 1;
654 int rc = std::min(150, std::max(0, r));
655 int gc = std::min(200, std::max(0, g));
656 int bc = std::min(200, std::max(0, b));
657 newTexture->SetPixel(i, j, rc, gc, bc, 255);
658 }
659 }
660 for (int j = 3; j < (width-4)/2; j++)
661 {
662 newTexture->SetPixel(j+0, j, 0xFF, 0, 0, 255);
663 newTexture->SetPixel(j+1, j, 0xFF, 0, 0, 255);
664 newTexture->SetPixel(-j+13, j, 0xFF, 0, 0, 255);
665 newTexture->SetPixel(-j+14, j, 0xFF, 0, 0, 255);
666
667 newTexture->SetPixel(j+11, j, 0xFF, 0, 0, 255);
668 newTexture->SetPixel(j+12, j, 0xFF, 0, 0, 255);
669 newTexture->SetPixel(-j+24, j, 0xFF, 0, 0, 255);
670 newTexture->SetPixel(-j+25, j, 0xFF, 0, 0, 255);
671 }
672 }
673 else if(wt == WL_STREAM)
674 {
675 for (j=0; j<height; j++)
676 {
677 for (i=0; i<width; i++)
678 {
679 pc = i==0||i==width-1||j==0||j==height-1 ? PIXPACK(0xA0A0A0) : PIXPACK(0x000000);
680 newTexture->SetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255);
681 }
682 }
683 newTexture->AddCharacter(4, 2, 0xE00D, 255, 255, 255, 255);
684 for (i=width/3; i<width; i++)
685 {
686 newTexture->SetPixel(i, 7+(int)(3.9f*cos(i*0.3f)), 255, 255, 255, 255);
687 }
688 }
689 return newTexture;
690 }
691
DrawBlob(int x,int y,unsigned char cr,unsigned char cg,unsigned char cb)692 void Renderer::DrawBlob(int x, int y, unsigned char cr, unsigned char cg, unsigned char cb)
693 {
694 blendpixel(x+1, y, cr, cg, cb, 112);
695 blendpixel(x-1, y, cr, cg, cb, 112);
696 blendpixel(x, y+1, cr, cg, cb, 112);
697 blendpixel(x, y-1, cr, cg, cb, 112);
698
699 blendpixel(x+1, y-1, cr, cg, cb, 64);
700 blendpixel(x-1, y-1, cr, cg, cb, 64);
701 blendpixel(x+1, y+1, cr, cg, cb, 64);
702 blendpixel(x-1, y+1, cr, cg, cb, 64);
703 }
704
DrawWalls()705 void Renderer::DrawWalls()
706 {
707 #ifdef OGLR
708 // terrible OpenGL "support"
709 GLint prevFbo;
710 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prevFbo);
711 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, partsFbo);
712 glTranslated(0, MENUSIZE, 0);
713
714 for (int y = 0; y < YRES/CELL; y++)
715 for (int x = 0; x < XRES/CELL; x++)
716 if (sim->bmap[y][x])
717 {
718 unsigned char wt = sim->bmap[y][x];
719 if (wt >= UI_WALLCOUNT)
720 continue;
721 pixel pc = sim->wtypes[wt].colour;
722 pixel gc = sim->wtypes[wt].eglow;
723
724 int cr = PIXR(pc);
725 int cg = PIXG(pc);
726 int cb = PIXB(pc);
727
728 fillrect(x*CELL, y*CELL, CELL, CELL, cr, cg, cb, 255);
729 }
730
731 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prevFbo);
732 glTranslated(0, -MENUSIZE, 0);
733 #else
734 for (int y = 0; y < YRES/CELL; y++)
735 for (int x =0; x < XRES/CELL; x++)
736 if (sim->bmap[y][x])
737 {
738 unsigned char wt = sim->bmap[y][x];
739 if (wt >= UI_WALLCOUNT)
740 continue;
741 unsigned char powered = sim->emap[y][x];
742 pixel pc = PIXPACK(sim->wtypes[wt].colour);
743 pixel gc = PIXPACK(sim->wtypes[wt].eglow);
744
745 if (findingElement)
746 {
747 pc = PIXRGB(PIXR(pc)/10,PIXG(pc)/10,PIXB(pc)/10);
748 gc = PIXRGB(PIXR(gc)/10,PIXG(gc)/10,PIXB(gc)/10);
749 }
750
751 switch (sim->wtypes[wt].drawstyle)
752 {
753 case 0:
754 if (wt == WL_EWALL || wt == WL_STASIS)
755 {
756 bool reverse = wt == WL_STASIS;
757 if ((powered > 0) ^ reverse)
758 {
759 for (int j = 0; j < CELL; j++)
760 for (int i =0; i < CELL; i++)
761 if (i&j&1)
762 vid[(y*CELL+j)*(VIDXRES)+(x*CELL+i)] = pc;
763 }
764 else
765 {
766 for (int j = 0; j < CELL; j++)
767 for (int i = 0; i < CELL; i++)
768 if (!(i&j&1))
769 vid[(y*CELL+j)*(VIDXRES)+(x*CELL+i)] = pc;
770 }
771 }
772 else if (wt == WL_WALLELEC)
773 {
774 for (int j = 0; j < CELL; j++)
775 for (int i = 0; i < CELL; i++)
776 {
777 if (!((y*CELL+j)%2) && !((x*CELL+i)%2))
778 vid[(y*CELL+j)*(VIDXRES)+(x*CELL+i)] = pc;
779 else
780 vid[(y*CELL+j)*(VIDXRES)+(x*CELL+i)] = PIXPACK(0x808080);
781 }
782 }
783 else if (wt == WL_EHOLE)
784 {
785 if (powered)
786 {
787 for (int j = 0; j < CELL; j++)
788 for (int i = 0; i < CELL; i++)
789 vid[(y*CELL+j)*(VIDXRES)+(x*CELL+i)] = PIXPACK(0x242424);
790 for (int j = 0; j < CELL; j += 2)
791 for (int i = 0; i < CELL; i += 2)
792 vid[(y*CELL+j)*(VIDXRES)+(x*CELL+i)] = PIXPACK(0x000000);
793 }
794 else
795 {
796 for (int j = 0; j < CELL; j += 2)
797 for (int i =0; i < CELL; i += 2)
798 vid[(y*CELL+j)*(VIDXRES)+(x*CELL+i)] = PIXPACK(0x242424);
799 }
800 }
801 else if (wt == WL_STREAM)
802 {
803 float xf = x*CELL + CELL*0.5f;
804 float yf = y*CELL + CELL*0.5f;
805 int oldX = (int)(xf+0.5f), oldY = (int)(yf+0.5f);
806 int newX, newY;
807 float xVel = sim->vx[y][x]*0.125f, yVel = sim->vy[y][x]*0.125f;
808 // there is no velocity here, draw a streamline and continue
809 if (!xVel && !yVel)
810 {
811 drawtext(x*CELL, y*CELL-2, 0xE00D, 255, 255, 255, 128);
812 addpixel(oldX, oldY, 255, 255, 255, 255);
813 continue;
814 }
815 bool changed = false;
816 for (int t = 0; t < 1024; t++)
817 {
818 newX = (int)(xf+0.5f);
819 newY = (int)(yf+0.5f);
820 if (newX != oldX || newY != oldY)
821 {
822 changed = true;
823 oldX = newX;
824 oldY = newY;
825 }
826 if (changed && (newX<0 || newX>=XRES || newY<0 || newY>=YRES))
827 break;
828 addpixel(newX, newY, 255, 255, 255, 64);
829 // cache velocity and other checks so we aren't running them constantly
830 if (changed)
831 {
832 int wallX = newX/CELL;
833 int wallY = newY/CELL;
834 xVel = sim->vx[wallY][wallX]*0.125f;
835 yVel = sim->vy[wallY][wallX]*0.125f;
836 if (wallX != x && wallY != y && sim->bmap[wallY][wallX] == WL_STREAM)
837 break;
838 }
839 xf += xVel;
840 yf += yVel;
841 }
842 drawtext(x*CELL, y*CELL-2, 0xE00D, 255, 255, 255, 128);
843 }
844 break;
845 case 1:
846 for (int j = 0; j < CELL; j += 2)
847 for (int i = (j>>1)&1; i < CELL; i += 2)
848 vid[(y*CELL+j)*(VIDXRES)+(x*CELL+i)] = pc;
849 break;
850 case 2:
851 for (int j = 0; j < CELL; j += 2)
852 for (int i = 0; i < CELL; i += 2)
853 vid[(y*CELL+j)*(VIDXRES)+(x*CELL+i)] = pc;
854 break;
855 case 3:
856 for (int j = 0; j < CELL; j++)
857 for (int i = 0; i < CELL; i++)
858 vid[(y*CELL+j)*(VIDXRES)+(x*CELL+i)] = pc;
859 break;
860 case 4:
861 for (int j = 0; j < CELL; j++)
862 for (int i = 0; i < CELL; i++)
863 if (i == j)
864 vid[(y*CELL+j)*(VIDXRES)+(x*CELL+i)] = pc;
865 else if (i == j+1 || (i == 0 && j == CELL-1))
866 vid[(y*CELL+j)*(VIDXRES)+(x*CELL+i)] = gc;
867 else
868 vid[(y*CELL+j)*(VIDXRES)+(x*CELL+i)] = PIXPACK(0x202020);
869 break;
870 }
871
872 // when in blob view, draw some blobs...
873 if (render_mode & PMODE_BLOB)
874 {
875 switch (sim->wtypes[wt].drawstyle)
876 {
877 case 0:
878 if (wt == WL_EWALL || wt == WL_STASIS)
879 {
880 bool reverse = wt == WL_STASIS;
881 if ((powered>0) ^ reverse)
882 {
883 for (int j = 0; j < CELL; j++)
884 for (int i =0; i < CELL; i++)
885 if (i&j&1)
886 drawblob((x*CELL+i), (y*CELL+j), PIXR(pc), PIXG(pc), PIXB(pc));
887 }
888 else
889 {
890 for (int j = 0; j < CELL; j++)
891 for (int i = 0; i < CELL; i++)
892 if (!(i&j&1))
893 drawblob((x*CELL+i), (y*CELL+j), PIXR(pc), PIXG(pc), PIXB(pc));
894 }
895 }
896 else if (wt == WL_WALLELEC)
897 {
898 for (int j = 0; j < CELL; j++)
899 for (int i =0; i < CELL; i++)
900 {
901 if (!((y*CELL+j)%2) && !((x*CELL+i)%2))
902 drawblob((x*CELL+i), (y*CELL+j), PIXR(pc), PIXG(pc), PIXB(pc));
903 else
904 drawblob((x*CELL+i), (y*CELL+j), 0x80, 0x80, 0x80);
905 }
906 }
907 else if (wt == WL_EHOLE)
908 {
909 if (powered)
910 {
911 for (int j = 0; j < CELL; j++)
912 for (int i = 0; i < CELL; i++)
913 drawblob((x*CELL+i), (y*CELL+j), 0x24, 0x24, 0x24);
914 for (int j = 0; j < CELL; j += 2)
915 for (int i = 0; i < CELL; i += 2)
916 // looks bad if drawing black blobs
917 vid[(y*CELL+j)*(VIDXRES)+(x*CELL+i)] = PIXPACK(0x000000);
918 }
919 else
920 {
921 for (int j = 0; j < CELL; j += 2)
922 for (int i = 0; i < CELL; i += 2)
923 drawblob((x*CELL+i), (y*CELL+j), 0x24, 0x24, 0x24);
924 }
925 }
926 break;
927 case 1:
928 for (int j = 0; j < CELL; j += 2)
929 for (int i = (j>>1)&1; i < CELL; i += 2)
930 drawblob((x*CELL+i), (y*CELL+j), PIXR(pc), PIXG(pc), PIXB(pc));
931 break;
932 case 2:
933 for (int j = 0; j < CELL; j += 2)
934 for (int i = 0; i < CELL; i+=2)
935 drawblob((x*CELL+i), (y*CELL+j), PIXR(pc), PIXG(pc), PIXB(pc));
936 break;
937 case 3:
938 for (int j = 0; j < CELL; j++)
939 for (int i = 0; i < CELL; i++)
940 drawblob((x*CELL+i), (y*CELL+j), PIXR(pc), PIXG(pc), PIXB(pc));
941 break;
942 case 4:
943 for (int j = 0; j < CELL; j++)
944 for (int i = 0; i < CELL; i++)
945 if (i == j)
946 drawblob((x*CELL+i), (y*CELL+j), PIXR(pc), PIXG(pc), PIXB(pc));
947 else if (i == j+1 || (i == 0 && j == CELL-1))
948 vid[(y*CELL+j)*(VIDXRES)+(x*CELL+i)] = gc;
949 else
950 // looks bad if drawing black blobs
951 vid[(y*CELL+j)*(VIDXRES)+(x*CELL+i)] = PIXPACK(0x202020);
952 break;
953 }
954 }
955
956 if (sim->wtypes[wt].eglow && powered)
957 {
958 // glow if electrified
959 pixel glow = sim->wtypes[wt].eglow;
960 int alpha = 255;
961 int cr = (alpha*PIXR(glow) + (255-alpha)*fire_r[y/CELL][x/CELL]) >> 8;
962 int cg = (alpha*PIXG(glow) + (255-alpha)*fire_g[y/CELL][x/CELL]) >> 8;
963 int cb = (alpha*PIXB(glow) + (255-alpha)*fire_b[y/CELL][x/CELL]) >> 8;
964
965 if (cr > 255)
966 cr = 255;
967 if (cg > 255)
968 cg = 255;
969 if (cb > 255)
970 cb = 255;
971 fire_r[y][x] = cr;
972 fire_g[y][x] = cg;
973 fire_b[y][x] = cb;
974 }
975 }
976 #endif
977 }
978
DrawSigns()979 void Renderer::DrawSigns()
980 {
981 int x, y, w, h;
982 std::vector<sign> signs = sim->signs;
983 #ifdef OGLR
984 GLint prevFbo;
985 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prevFbo);
986 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, partsFbo);
987 glTranslated(0, MENUSIZE, 0);
988 #endif
989 for (auto ¤tSign : signs)
990 {
991 if (currentSign.text.length())
992 {
993 String text = currentSign.getDisplayText(sim, x, y, w, h);
994 clearrect(x, y, w+1, h);
995 drawrect(x, y, w+1, h, 192, 192, 192, 255);
996 drawtext(x+3, y+3, text, 255, 255, 255, 255);
997
998 if (currentSign.ju != sign::None)
999 {
1000 int x = currentSign.x;
1001 int y = currentSign.y;
1002 int dx = 1 - currentSign.ju;
1003 int dy = (currentSign.y > 18) ? -1 : 1;
1004 #ifdef OGLR
1005 glBegin(GL_LINES);
1006 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
1007 glVertex2i(x, y);
1008 glVertex2i(x+(dx*4), y+(dy*4));
1009 glEnd();
1010 #else
1011 for (int j = 0; j < 4; j++)
1012 {
1013 blendpixel(x, y, 192, 192, 192, 255);
1014 x += dx;
1015 y += dy;
1016 }
1017 #endif
1018 }
1019 }
1020 }
1021 #ifdef OGLR
1022 glTranslated(0, -MENUSIZE, 0);
1023 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prevFbo);
1024 #endif
1025 }
1026
render_gravlensing(pixel * source)1027 void Renderer::render_gravlensing(pixel * source)
1028 {
1029 #ifndef OGLR
1030 int nx, ny, rx, ry, gx, gy, bx, by, co;
1031 int r, g, b;
1032 pixel t;
1033 pixel *src = source;
1034 pixel *dst = vid;
1035 if (!dst)
1036 return;
1037 for(nx = 0; nx < XRES; nx++)
1038 {
1039 for(ny = 0; ny < YRES; ny++)
1040 {
1041 co = (ny/CELL)*(XRES/CELL)+(nx/CELL);
1042 rx = (int)(nx-sim->gravx[co]*0.75f+0.5f);
1043 ry = (int)(ny-sim->gravy[co]*0.75f+0.5f);
1044 gx = (int)(nx-sim->gravx[co]*0.875f+0.5f);
1045 gy = (int)(ny-sim->gravy[co]*0.875f+0.5f);
1046 bx = (int)(nx-sim->gravx[co]+0.5f);
1047 by = (int)(ny-sim->gravy[co]+0.5f);
1048 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)
1049 {
1050 t = dst[ny*(VIDXRES)+nx];
1051 r = PIXR(src[ry*(VIDXRES)+rx]) + PIXR(t);
1052 g = PIXG(src[gy*(VIDXRES)+gx]) + PIXG(t);
1053 b = PIXB(src[by*(VIDXRES)+bx]) + PIXB(t);
1054 if (r>255)
1055 r = 255;
1056 if (g>255)
1057 g = 255;
1058 if (b>255)
1059 b = 255;
1060 dst[ny*(VIDXRES)+nx] = PIXRGB(r,g,b);
1061 }
1062 }
1063 }
1064 #endif
1065 }
1066
render_fire()1067 void Renderer::render_fire()
1068 {
1069 #ifndef OGLR
1070 if(!(render_mode & FIREMODE))
1071 return;
1072 int i,j,x,y,r,g,b,a;
1073 for (j=0; j<YRES/CELL; j++)
1074 for (i=0; i<XRES/CELL; i++)
1075 {
1076 r = fire_r[j][i];
1077 g = fire_g[j][i];
1078 b = fire_b[j][i];
1079 if (r || g || b)
1080 for (y=-CELL; y<2*CELL; y++)
1081 for (x=-CELL; x<2*CELL; x++)
1082 {
1083 a = fire_alpha[y+CELL][x+CELL];
1084 if (findingElement)
1085 a /= 2;
1086 addpixel(i*CELL+x, j*CELL+y, r, g, b, a);
1087 }
1088 r *= 8;
1089 g *= 8;
1090 b *= 8;
1091 for (y=-1; y<2; y++)
1092 for (x=-1; x<2; x++)
1093 if ((x || y) && i+x>=0 && j+y>=0 && i+x<XRES/CELL && j+y<YRES/CELL)
1094 {
1095 r += fire_r[j+y][i+x];
1096 g += fire_g[j+y][i+x];
1097 b += fire_b[j+y][i+x];
1098 }
1099 r /= 16;
1100 g /= 16;
1101 b /= 16;
1102 fire_r[j][i] = r>4 ? r-4 : 0;
1103 fire_g[j][i] = g>4 ? g-4 : 0;
1104 fire_b[j][i] = b>4 ? b-4 : 0;
1105 }
1106 #endif
1107 }
1108
1109 float temp[CELL*3][CELL*3];
1110 float fire_alphaf[CELL*3][CELL*3];
1111 float glow_alphaf[11][11];
1112 float blur_alphaf[7][7];
prepare_alpha(int size,float intensity)1113 void Renderer::prepare_alpha(int size, float intensity)
1114 {
1115 //TODO: implement size
1116 int x,y,i,j;
1117 float multiplier = 255.0f*intensity;
1118
1119 memset(temp, 0, sizeof(temp));
1120 for (x=0; x<CELL; x++)
1121 for (y=0; y<CELL; y++)
1122 for (i=-CELL; i<CELL; i++)
1123 for (j=-CELL; j<CELL; j++)
1124 temp[y+CELL+j][x+CELL+i] += expf(-0.1f*(i*i+j*j));
1125 for (x=0; x<CELL*3; x++)
1126 for (y=0; y<CELL*3; y++)
1127 fire_alpha[y][x] = (int)(multiplier*temp[y][x]/(CELL*CELL));
1128
1129 #ifdef OGLR
1130 memset(fire_alphaf, 0, sizeof(fire_alphaf));
1131 for (x=0; x<CELL*3; x++)
1132 for (y=0; y<CELL*3; y++)
1133 {
1134 fire_alphaf[y][x] = intensity*temp[y][x]/((float)(CELL*CELL));
1135 }
1136 glEnable(GL_TEXTURE_2D);
1137 glBindTexture(GL_TEXTURE_2D, fireAlpha);
1138 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, CELL*3, CELL*3, GL_ALPHA, GL_FLOAT, fire_alphaf);
1139 glBindTexture(GL_TEXTURE_2D, 0);
1140 glDisable(GL_TEXTURE_2D);
1141
1142 memset(glow_alphaf, 0, sizeof(glow_alphaf));
1143
1144 int c = 5;
1145
1146 glow_alphaf[c][c-1] = 0.4f;
1147 glow_alphaf[c][c+1] = 0.4f;
1148 glow_alphaf[c-1][c] = 0.4f;
1149 glow_alphaf[c+1][c] = 0.4f;
1150 for (x = 1; x < 6; x++) {
1151 glow_alphaf[c][c-x] += 0.02f;
1152 glow_alphaf[c][c+x] += 0.02f;
1153 glow_alphaf[c-x][c] += 0.02f;
1154 glow_alphaf[c+x][c] += 0.02f;
1155 for (y = 1; y < 6; y++) {
1156 if(x + y > 7)
1157 continue;
1158 glow_alphaf[c+x][c-y] += 0.02f;
1159 glow_alphaf[c-x][c+y] += 0.02f;
1160 glow_alphaf[c+x][c+y] += 0.02f;
1161 glow_alphaf[c-x][c-y] += 0.02f;
1162 }
1163 }
1164
1165 glEnable(GL_TEXTURE_2D);
1166 glBindTexture(GL_TEXTURE_2D, glowAlpha);
1167 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 11, 11, GL_ALPHA, GL_FLOAT, glow_alphaf);
1168 glBindTexture(GL_TEXTURE_2D, 0);
1169 glDisable(GL_TEXTURE_2D);
1170
1171 c = 3;
1172
1173 for (x=-3; x<4; x++)
1174 {
1175 for (y=-3; y<4; y++)
1176 {
1177 if (abs(x)+abs(y) <2 && !(abs(x)==2||abs(y)==2))
1178 blur_alphaf[c+x][c-y] = 0.11f;
1179 if (abs(x)+abs(y) <=3 && abs(x)+abs(y))
1180 blur_alphaf[c+x][c-y] = 0.08f;
1181 if (abs(x)+abs(y) == 2)
1182 blur_alphaf[c+x][c-y] = 0.04f;
1183 }
1184 }
1185
1186 glEnable(GL_TEXTURE_2D);
1187 glBindTexture(GL_TEXTURE_2D, blurAlpha);
1188 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 7, 7, GL_ALPHA, GL_FLOAT, blur_alphaf);
1189 glBindTexture(GL_TEXTURE_2D, 0);
1190 glDisable(GL_TEXTURE_2D);
1191 #endif
1192 }
1193
render_parts()1194 void Renderer::render_parts()
1195 {
1196 int deca, decr, decg, decb, cola, colr, colg, colb, firea, firer, fireg, fireb, pixel_mode, q, i, t, nx, ny, x, y, caddress;
1197 int orbd[4] = {0, 0, 0, 0}, orbl[4] = {0, 0, 0, 0};
1198 float gradv, flicker;
1199 Particle * parts;
1200 Element *elements;
1201 if(!sim)
1202 return;
1203 parts = sim->parts;
1204 elements = sim->elements.data();
1205 #ifdef OGLR
1206 float fnx, fny;
1207 int cfireV = 0, cfireC = 0, cfire = 0;
1208 int csmokeV = 0, csmokeC = 0, csmoke = 0;
1209 int cblobV = 0, cblobC = 0, cblob = 0;
1210 int cblurV = 0, cblurC = 0, cblur = 0;
1211 int cglowV = 0, cglowC = 0, cglow = 0;
1212 int cflatV = 0, cflatC = 0, cflat = 0;
1213 int caddV = 0, caddC = 0, cadd = 0;
1214 int clineV = 0, clineC = 0, cline = 0;
1215 GLint origBlendSrc, origBlendDst, prevFbo;
1216
1217 glGetIntegerv(GL_BLEND_SRC, &origBlendSrc);
1218 glGetIntegerv(GL_BLEND_DST, &origBlendDst);
1219 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prevFbo);
1220 //Render to the particle FBO
1221 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, partsFbo);
1222 glTranslated(0, MENUSIZE, 0);
1223 #else
1224 if (gridSize)//draws the grid
1225 {
1226 for (ny=0; ny<YRES; ny++)
1227 for (nx=0; nx<XRES; nx++)
1228 {
1229 if (ny%(4*gridSize) == 0)
1230 blendpixel(nx, ny, 100, 100, 100, 80);
1231 if (nx%(4*gridSize) == 0 && ny%(4*gridSize) != 0)
1232 blendpixel(nx, ny, 100, 100, 100, 80);
1233 }
1234 }
1235 #endif
1236 foundElements = 0;
1237 for(i = 0; i<=sim->parts_lastActiveIndex; i++) {
1238 if (sim->parts[i].type && sim->parts[i].type >= 0 && sim->parts[i].type < PT_NUM) {
1239 t = sim->parts[i].type;
1240
1241 nx = (int)(sim->parts[i].x+0.5f);
1242 ny = (int)(sim->parts[i].y+0.5f);
1243 #ifdef OGLR
1244 fnx = sim->parts[i].x;
1245 fny = sim->parts[i].y;
1246 #endif
1247
1248 if(nx >= XRES || nx < 0 || ny >= YRES || ny < 0)
1249 continue;
1250 if(TYP(sim->photons[ny][nx]) && !(sim->elements[t].Properties & TYPE_ENERGY) && t!=PT_STKM && t!=PT_STKM2 && t!=PT_FIGH)
1251 continue;
1252
1253 //Defaults
1254 pixel_mode = 0 | PMODE_FLAT;
1255 cola = 255;
1256 colr = PIXR(elements[t].Colour);
1257 colg = PIXG(elements[t].Colour);
1258 colb = PIXB(elements[t].Colour);
1259 firer = fireg = fireb = firea = 0;
1260
1261 deca = (sim->parts[i].dcolour>>24)&0xFF;
1262 decr = (sim->parts[i].dcolour>>16)&0xFF;
1263 decg = (sim->parts[i].dcolour>>8)&0xFF;
1264 decb = (sim->parts[i].dcolour)&0xFF;
1265
1266 if(decorations_enable && blackDecorations)
1267 {
1268 if(deca < 250 || decr > 5 || decg > 5 || decb > 5)
1269 deca = 0;
1270 else
1271 {
1272 deca = 255;
1273 decr = decg = decb = 0;
1274 }
1275 }
1276
1277 {
1278 if (graphicscache[t].isready)
1279 {
1280 pixel_mode = graphicscache[t].pixel_mode;
1281 cola = graphicscache[t].cola;
1282 colr = graphicscache[t].colr;
1283 colg = graphicscache[t].colg;
1284 colb = graphicscache[t].colb;
1285 firea = graphicscache[t].firea;
1286 firer = graphicscache[t].firer;
1287 fireg = graphicscache[t].fireg;
1288 fireb = graphicscache[t].fireb;
1289 }
1290 else if(!(colour_mode & COLOUR_BASC))
1291 {
1292 if (elements[t].Graphics)
1293 {
1294 #if !defined(RENDERER) && defined(LUACONSOLE)
1295 if (lua_gr_func[t])
1296 {
1297 if (luacon_graphicsReplacement(this, &(sim->parts[i]), nx, ny, &pixel_mode, &cola, &colr, &colg, &colb, &firea, &firer, &fireg, &fireb, i))
1298 {
1299 graphicscache[t].isready = 1;
1300 graphicscache[t].pixel_mode = pixel_mode;
1301 graphicscache[t].cola = cola;
1302 graphicscache[t].colr = colr;
1303 graphicscache[t].colg = colg;
1304 graphicscache[t].colb = colb;
1305 graphicscache[t].firea = firea;
1306 graphicscache[t].firer = firer;
1307 graphicscache[t].fireg = fireg;
1308 graphicscache[t].fireb = fireb;
1309 }
1310 }
1311 else 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
1312 #else
1313 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
1314 #endif
1315 {
1316 graphicscache[t].isready = 1;
1317 graphicscache[t].pixel_mode = pixel_mode;
1318 graphicscache[t].cola = cola;
1319 graphicscache[t].colr = colr;
1320 graphicscache[t].colg = colg;
1321 graphicscache[t].colb = colb;
1322 graphicscache[t].firea = firea;
1323 graphicscache[t].firer = firer;
1324 graphicscache[t].fireg = fireg;
1325 graphicscache[t].fireb = fireb;
1326 }
1327 }
1328 else
1329 {
1330 graphicscache[t].isready = 1;
1331 graphicscache[t].pixel_mode = pixel_mode;
1332 graphicscache[t].cola = cola;
1333 graphicscache[t].colr = colr;
1334 graphicscache[t].colg = colg;
1335 graphicscache[t].colb = colb;
1336 graphicscache[t].firea = firea;
1337 graphicscache[t].firer = firer;
1338 graphicscache[t].fireg = fireg;
1339 graphicscache[t].fireb = fireb;
1340 }
1341 }
1342 if((elements[t].Properties & PROP_HOT_GLOW) && sim->parts[i].temp>(elements[t].HighTemperature-800.0f))
1343 {
1344 gradv = 3.1415/(2*elements[t].HighTemperature-(elements[t].HighTemperature-800.0f));
1345 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);
1346 colr += sin(gradv*caddress) * 226;;
1347 colg += sin(gradv*caddress*4.55 +3.14) * 34;
1348 colb += sin(gradv*caddress*2.22 +3.14) * 64;
1349 }
1350
1351 if((pixel_mode & FIRE_ADD) && !(render_mode & FIRE_ADD))
1352 pixel_mode |= PMODE_GLOW;
1353 if((pixel_mode & FIRE_BLEND) && !(render_mode & FIRE_BLEND))
1354 pixel_mode |= PMODE_BLUR;
1355 if((pixel_mode & PMODE_BLUR) && !(render_mode & PMODE_BLUR))
1356 pixel_mode |= PMODE_FLAT;
1357 if((pixel_mode & PMODE_GLOW) && !(render_mode & PMODE_GLOW))
1358 pixel_mode |= PMODE_BLEND;
1359 if (render_mode & PMODE_BLOB)
1360 pixel_mode |= PMODE_BLOB;
1361
1362 pixel_mode &= render_mode;
1363
1364 //Alter colour based on display mode
1365 if(colour_mode & COLOUR_HEAT)
1366 {
1367 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);
1368 firea = 255;
1369 firer = colr = color_data[caddress];
1370 fireg = colg = color_data[caddress+1];
1371 fireb = colb = color_data[caddress+2];
1372 cola = 255;
1373 if(pixel_mode & (FIREMODE | PMODE_GLOW))
1374 pixel_mode = (pixel_mode & ~(FIREMODE|PMODE_GLOW)) | PMODE_BLUR;
1375 else if ((pixel_mode & (PMODE_BLEND | PMODE_ADD)) == (PMODE_BLEND | PMODE_ADD))
1376 pixel_mode = (pixel_mode & ~(PMODE_BLEND|PMODE_ADD)) | PMODE_FLAT;
1377 else if (!pixel_mode)
1378 pixel_mode |= PMODE_FLAT;
1379 }
1380 else if(colour_mode & COLOUR_LIFE)
1381 {
1382 gradv = 0.4f;
1383 if (!(sim->parts[i].life<5))
1384 q = sqrt((float)sim->parts[i].life);
1385 else
1386 q = sim->parts[i].life;
1387 colr = colg = colb = sin(gradv*q) * 100 + 128;
1388 cola = 255;
1389 if(pixel_mode & (FIREMODE | PMODE_GLOW))
1390 pixel_mode = (pixel_mode & ~(FIREMODE|PMODE_GLOW)) | PMODE_BLUR;
1391 else if ((pixel_mode & (PMODE_BLEND | PMODE_ADD)) == (PMODE_BLEND | PMODE_ADD))
1392 pixel_mode = (pixel_mode & ~(PMODE_BLEND|PMODE_ADD)) | PMODE_FLAT;
1393 else if (!pixel_mode)
1394 pixel_mode |= PMODE_FLAT;
1395 }
1396 else if(colour_mode & COLOUR_BASC)
1397 {
1398 colr = PIXR(elements[t].Colour);
1399 colg = PIXG(elements[t].Colour);
1400 colb = PIXB(elements[t].Colour);
1401 pixel_mode = PMODE_FLAT;
1402 }
1403
1404 //Apply decoration colour
1405 if(!(colour_mode & ~COLOUR_GRAD) && decorations_enable && deca)
1406 {
1407 deca++;
1408 if(!(pixel_mode & NO_DECO))
1409 {
1410 colr = (deca*decr + (256-deca)*colr) >> 8;
1411 colg = (deca*decg + (256-deca)*colg) >> 8;
1412 colb = (deca*decb + (256-deca)*colb) >> 8;
1413 }
1414
1415 if(pixel_mode & DECO_FIRE)
1416 {
1417 firer = (deca*decr + (256-deca)*firer) >> 8;
1418 fireg = (deca*decg + (256-deca)*fireg) >> 8;
1419 fireb = (deca*decb + (256-deca)*fireb) >> 8;
1420 }
1421 }
1422
1423 if (findingElement)
1424 {
1425 if (TYP(findingElement) == parts[i].type &&
1426 (parts[i].type != PT_LIFE || (ID(findingElement) == parts[i].ctype)))
1427 {
1428 colr = firer = 255;
1429 colg = fireg = colb = fireb = 0;
1430 foundElements++;
1431 }
1432 else
1433 {
1434 colr /= 10;
1435 colg /= 10;
1436 colb /= 10;
1437 firer /= 5;
1438 fireg /= 5;
1439 fireb /= 5;
1440 }
1441 }
1442
1443 if (colour_mode & COLOUR_GRAD)
1444 {
1445 float frequency = 0.05;
1446 int q = sim->parts[i].temp-40;
1447 colr = sin(frequency*q) * 16 + colr;
1448 colg = sin(frequency*q) * 16 + colg;
1449 colb = sin(frequency*q) * 16 + colb;
1450 if(pixel_mode & (FIREMODE | PMODE_GLOW)) pixel_mode = (pixel_mode & ~(FIREMODE|PMODE_GLOW)) | PMODE_BLUR;
1451 }
1452
1453 #ifndef OGLR
1454 //All colours are now set, check ranges
1455 if(colr>255) colr = 255;
1456 else if(colr<0) colr = 0;
1457 if(colg>255) colg = 255;
1458 else if(colg<0) colg = 0;
1459 if(colb>255) colb = 255;
1460 else if(colb<0) colb = 0;
1461 if(cola>255) cola = 255;
1462 else if(cola<0) cola = 0;
1463
1464 if(firer>255) firer = 255;
1465 else if(firer<0) firer = 0;
1466 if(fireg>255) fireg = 255;
1467 else if(fireg<0) fireg = 0;
1468 if(fireb>255) fireb = 255;
1469 else if(fireb<0) fireb = 0;
1470 if(firea>255) firea = 255;
1471 else if(firea<0) firea = 0;
1472 #endif
1473
1474 //Pixel rendering
1475 if (pixel_mode & EFFECT_LINES)
1476 {
1477 if (t==PT_SOAP)
1478 {
1479 if ((parts[i].ctype&3) == 3 && parts[i].tmp >= 0 && parts[i].tmp < NPART)
1480 draw_line(nx, ny, (int)(parts[parts[i].tmp].x+0.5f), (int)(parts[parts[i].tmp].y+0.5f), colr, colg, colb, cola);
1481 }
1482 }
1483 if(pixel_mode & PSPEC_STICKMAN)
1484 {
1485 int legr, legg, legb;
1486 playerst *cplayer;
1487 if(t==PT_STKM)
1488 cplayer = &sim->player;
1489 else if(t==PT_STKM2)
1490 cplayer = &sim->player2;
1491 else if (t==PT_FIGH && sim->parts[i].tmp >= 0 && sim->parts[i].tmp < MAX_FIGHTERS)
1492 cplayer = &sim->fighters[(unsigned char)sim->parts[i].tmp];
1493 else
1494 continue;
1495
1496 if (mousePos.X>(nx-3) && mousePos.X<(nx+3) && mousePos.Y<(ny+3) && mousePos.Y>(ny-3)) //If mouse is in the head
1497 {
1498 String hp = String::Build(Format::Width(sim->parts[i].life, 3));
1499 drawtext(mousePos.X-8-2*(sim->parts[i].life<100)-2*(sim->parts[i].life<10), mousePos.Y-12, hp, 255, 255, 255, 255);
1500 }
1501
1502 if (findingElement == t)
1503 {
1504 colr = 255;
1505 colg = colb = 0;
1506 }
1507 else if (colour_mode != COLOUR_HEAT)
1508 {
1509 if (cplayer->fan)
1510 {
1511 colr = PIXR(0x8080FF);
1512 colg = PIXG(0x8080FF);
1513 colb = PIXB(0x8080FF);
1514 }
1515 else if (cplayer->elem < PT_NUM && cplayer->elem > 0)
1516 {
1517 colr = PIXR(elements[cplayer->elem].Colour);
1518 colg = PIXG(elements[cplayer->elem].Colour);
1519 colb = PIXB(elements[cplayer->elem].Colour);
1520 }
1521 else
1522 {
1523 colr = 0x80;
1524 colg = 0x80;
1525 colb = 0xFF;
1526 }
1527 }
1528
1529 #ifdef OGLR
1530 glColor4f(((float)colr)/255.0f, ((float)colg)/255.0f, ((float)colb)/255.0f, 1.0f);
1531 glBegin(GL_LINE_STRIP);
1532 if(t==PT_FIGH)
1533 {
1534 glVertex2f(fnx, fny+2);
1535 glVertex2f(fnx+2, fny);
1536 glVertex2f(fnx, fny-2);
1537 glVertex2f(fnx-2, fny);
1538 glVertex2f(fnx, fny+2);
1539 }
1540 else
1541 {
1542 glVertex2f(fnx-2, fny-2);
1543 glVertex2f(fnx+2, fny-2);
1544 glVertex2f(fnx+2, fny+2);
1545 glVertex2f(fnx-2, fny+2);
1546 glVertex2f(fnx-2, fny-2);
1547 }
1548 glEnd();
1549 glBegin(GL_LINES);
1550
1551 if (colour_mode!=COLOUR_HEAT)
1552 {
1553 if (t==PT_STKM2)
1554 glColor4f(100.0f/255.0f, 100.0f/255.0f, 1.0f, 1.0f);
1555 else
1556 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
1557 }
1558
1559 glVertex2f(nx, ny+3);
1560 glVertex2f(cplayer->legs[0], cplayer->legs[1]);
1561
1562 glVertex2f(cplayer->legs[0], cplayer->legs[1]);
1563 glVertex2f(cplayer->legs[4], cplayer->legs[5]);
1564
1565 glVertex2f(nx, ny+3);
1566 glVertex2f(cplayer->legs[8], cplayer->legs[9]);
1567
1568 glVertex2f(cplayer->legs[8], cplayer->legs[9]);
1569 glVertex2f(cplayer->legs[12], cplayer->legs[13]);
1570 glEnd();
1571 #else
1572 if (findingElement && findingElement == t)
1573 {
1574 legr = 255;
1575 legg = legb = 0;
1576 }
1577 else if (colour_mode==COLOUR_HEAT)
1578 {
1579 legr = colr;
1580 legg = colg;
1581 legb = colb;
1582 }
1583 else if (t==PT_STKM2)
1584 {
1585 legr = 100;
1586 legg = 100;
1587 legb = 255;
1588 }
1589 else
1590 {
1591 legr = 255;
1592 legg = 255;
1593 legb = 255;
1594 }
1595
1596 if (findingElement && findingElement != t)
1597 {
1598 colr /= 10;
1599 colg /= 10;
1600 colb /= 10;
1601 legr /= 10;
1602 legg /= 10;
1603 legb /= 10;
1604 }
1605
1606 //head
1607 if(t==PT_FIGH)
1608 {
1609 draw_line(nx, ny+2, nx+2, ny, colr, colg, colb, 255);
1610 draw_line(nx+2, ny, nx, ny-2, colr, colg, colb, 255);
1611 draw_line(nx, ny-2, nx-2, ny, colr, colg, colb, 255);
1612 draw_line(nx-2, ny, nx, ny+2, colr, colg, colb, 255);
1613 }
1614 else
1615 {
1616 draw_line(nx-2, ny+2, nx+2, ny+2, colr, colg, colb, 255);
1617 draw_line(nx-2, ny-2, nx+2, ny-2, colr, colg, colb, 255);
1618 draw_line(nx-2, ny-2, nx-2, ny+2, colr, colg, colb, 255);
1619 draw_line(nx+2, ny-2, nx+2, ny+2, colr, colg, colb, 255);
1620 }
1621 //legs
1622 draw_line(nx, ny+3, cplayer->legs[0], cplayer->legs[1], legr, legg, legb, 255);
1623 draw_line(cplayer->legs[0], cplayer->legs[1], cplayer->legs[4], cplayer->legs[5], legr, legg, legb, 255);
1624 draw_line(nx, ny+3, cplayer->legs[8], cplayer->legs[9], legr, legg, legb, 255);
1625 draw_line(cplayer->legs[8], cplayer->legs[9], cplayer->legs[12], cplayer->legs[13], legr, legg, legb, 255);
1626 if (cplayer->rocketBoots)
1627 {
1628 for (int leg=0; leg<2; leg++)
1629 {
1630 int nx = cplayer->legs[leg*8+4], ny = cplayer->legs[leg*8+5];
1631 int colr = 255, colg = 0, colb = 255;
1632 if (((int)(cplayer->comm)&0x04) == 0x04 || (((int)(cplayer->comm)&0x01) == 0x01 && leg==0) || (((int)(cplayer->comm)&0x02) == 0x02 && leg==1))
1633 blendpixel(nx, ny, 0, 255, 0, 255);
1634 else
1635 blendpixel(nx, ny, 255, 0, 0, 255);
1636 blendpixel(nx+1, ny, colr, colg, colb, 223);
1637 blendpixel(nx-1, ny, colr, colg, colb, 223);
1638 blendpixel(nx, ny+1, colr, colg, colb, 223);
1639 blendpixel(nx, ny-1, colr, colg, colb, 223);
1640
1641 blendpixel(nx+1, ny-1, colr, colg, colb, 112);
1642 blendpixel(nx-1, ny-1, colr, colg, colb, 112);
1643 blendpixel(nx+1, ny+1, colr, colg, colb, 112);
1644 blendpixel(nx-1, ny+1, colr, colg, colb, 112);
1645 }
1646 }
1647 #endif
1648 }
1649 if(pixel_mode & PMODE_FLAT)
1650 {
1651 #ifdef OGLR
1652 flatV[cflatV++] = nx;
1653 flatV[cflatV++] = ny;
1654 flatC[cflatC++] = ((float)colr)/255.0f;
1655 flatC[cflatC++] = ((float)colg)/255.0f;
1656 flatC[cflatC++] = ((float)colb)/255.0f;
1657 flatC[cflatC++] = 1.0f;
1658 cflat++;
1659 #else
1660 vid[ny*(VIDXRES)+nx] = PIXRGB(colr,colg,colb);
1661 #endif
1662 }
1663 if(pixel_mode & PMODE_BLEND)
1664 {
1665 #ifdef OGLR
1666 flatV[cflatV++] = nx;
1667 flatV[cflatV++] = ny;
1668 flatC[cflatC++] = ((float)colr)/255.0f;
1669 flatC[cflatC++] = ((float)colg)/255.0f;
1670 flatC[cflatC++] = ((float)colb)/255.0f;
1671 flatC[cflatC++] = ((float)cola)/255.0f;
1672 cflat++;
1673 #else
1674 blendpixel(nx, ny, colr, colg, colb, cola);
1675 #endif
1676 }
1677 if(pixel_mode & PMODE_ADD)
1678 {
1679 #ifdef OGLR
1680 addV[caddV++] = nx;
1681 addV[caddV++] = ny;
1682 addC[caddC++] = ((float)colr)/255.0f;
1683 addC[caddC++] = ((float)colg)/255.0f;
1684 addC[caddC++] = ((float)colb)/255.0f;
1685 addC[caddC++] = ((float)cola)/255.0f;
1686 cadd++;
1687 #else
1688 addpixel(nx, ny, colr, colg, colb, cola);
1689 #endif
1690 }
1691 if(pixel_mode & PMODE_BLOB)
1692 {
1693 #ifdef OGLR
1694 blobV[cblobV++] = nx;
1695 blobV[cblobV++] = ny;
1696 blobC[cblobC++] = ((float)colr)/255.0f;
1697 blobC[cblobC++] = ((float)colg)/255.0f;
1698 blobC[cblobC++] = ((float)colb)/255.0f;
1699 blobC[cblobC++] = 1.0f;
1700 cblob++;
1701 #else
1702 vid[ny*(VIDXRES)+nx] = PIXRGB(colr,colg,colb);
1703
1704 blendpixel(nx+1, ny, colr, colg, colb, 223);
1705 blendpixel(nx-1, ny, colr, colg, colb, 223);
1706 blendpixel(nx, ny+1, colr, colg, colb, 223);
1707 blendpixel(nx, ny-1, colr, colg, colb, 223);
1708
1709 blendpixel(nx+1, ny-1, colr, colg, colb, 112);
1710 blendpixel(nx-1, ny-1, colr, colg, colb, 112);
1711 blendpixel(nx+1, ny+1, colr, colg, colb, 112);
1712 blendpixel(nx-1, ny+1, colr, colg, colb, 112);
1713 #endif
1714 }
1715 if(pixel_mode & PMODE_GLOW)
1716 {
1717 int cola1 = (5*cola)/255;
1718 #ifdef OGLR
1719 glowV[cglowV++] = nx;
1720 glowV[cglowV++] = ny;
1721 glowC[cglowC++] = ((float)colr)/255.0f;
1722 glowC[cglowC++] = ((float)colg)/255.0f;
1723 glowC[cglowC++] = ((float)colb)/255.0f;
1724 glowC[cglowC++] = 1.0f;
1725 cglow++;
1726 #else
1727 addpixel(nx, ny, colr, colg, colb, (192*cola)/255);
1728 addpixel(nx+1, ny, colr, colg, colb, (96*cola)/255);
1729 addpixel(nx-1, ny, colr, colg, colb, (96*cola)/255);
1730 addpixel(nx, ny+1, colr, colg, colb, (96*cola)/255);
1731 addpixel(nx, ny-1, colr, colg, colb, (96*cola)/255);
1732
1733 for (x = 1; x < 6; x++) {
1734 addpixel(nx, ny-x, colr, colg, colb, cola1);
1735 addpixel(nx, ny+x, colr, colg, colb, cola1);
1736 addpixel(nx-x, ny, colr, colg, colb, cola1);
1737 addpixel(nx+x, ny, colr, colg, colb, cola1);
1738 for (y = 1; y < 6; y++) {
1739 if(x + y > 7)
1740 continue;
1741 addpixel(nx+x, ny-y, colr, colg, colb, cola1);
1742 addpixel(nx-x, ny+y, colr, colg, colb, cola1);
1743 addpixel(nx+x, ny+y, colr, colg, colb, cola1);
1744 addpixel(nx-x, ny-y, colr, colg, colb, cola1);
1745 }
1746 }
1747 #endif
1748 }
1749 if(pixel_mode & PMODE_BLUR)
1750 {
1751 #ifdef OGLR
1752 blurV[cblurV++] = nx;
1753 blurV[cblurV++] = ny;
1754 blurC[cblurC++] = ((float)colr)/255.0f;
1755 blurC[cblurC++] = ((float)colg)/255.0f;
1756 blurC[cblurC++] = ((float)colb)/255.0f;
1757 blurC[cblurC++] = 1.0f;
1758 cblur++;
1759 #else
1760 for (x=-3; x<4; x++)
1761 {
1762 for (y=-3; y<4; y++)
1763 {
1764 if (abs(x)+abs(y) <2 && !(abs(x)==2||abs(y)==2))
1765 blendpixel(x+nx, y+ny, colr, colg, colb, 30);
1766 if (abs(x)+abs(y) <=3 && abs(x)+abs(y))
1767 blendpixel(x+nx, y+ny, colr, colg, colb, 20);
1768 if (abs(x)+abs(y) == 2)
1769 blendpixel(x+nx, y+ny, colr, colg, colb, 10);
1770 }
1771 }
1772 #endif
1773 }
1774 if(pixel_mode & PMODE_SPARK)
1775 {
1776 flicker = random_gen()%20;
1777 #ifdef OGLR
1778 //Oh god, this is awful
1779 lineC[clineC++] = ((float)colr)/255.0f;
1780 lineC[clineC++] = ((float)colg)/255.0f;
1781 lineC[clineC++] = ((float)colb)/255.0f;
1782 lineC[clineC++] = 0.0f;
1783 lineV[clineV++] = fnx-5;
1784 lineV[clineV++] = fny;
1785 cline++;
1786
1787 lineC[clineC++] = ((float)colr)/255.0f;
1788 lineC[clineC++] = ((float)colg)/255.0f;
1789 lineC[clineC++] = ((float)colb)/255.0f;
1790 lineC[clineC++] = 1.0f - ((float)flicker)/30;
1791 lineV[clineV++] = fnx;
1792 lineV[clineV++] = fny;
1793 cline++;
1794
1795 lineC[clineC++] = ((float)colr)/255.0f;
1796 lineC[clineC++] = ((float)colg)/255.0f;
1797 lineC[clineC++] = ((float)colb)/255.0f;
1798 lineC[clineC++] = 0.0f;
1799 lineV[clineV++] = fnx+5;
1800 lineV[clineV++] = fny;
1801 cline++;
1802
1803 lineC[clineC++] = ((float)colr)/255.0f;
1804 lineC[clineC++] = ((float)colg)/255.0f;
1805 lineC[clineC++] = ((float)colb)/255.0f;
1806 lineC[clineC++] = 0.0f;
1807 lineV[clineV++] = fnx;
1808 lineV[clineV++] = fny-5;
1809 cline++;
1810
1811 lineC[clineC++] = ((float)colr)/255.0f;
1812 lineC[clineC++] = ((float)colg)/255.0f;
1813 lineC[clineC++] = ((float)colb)/255.0f;
1814 lineC[clineC++] = 1.0f - ((float)flicker)/30;
1815 lineV[clineV++] = fnx;
1816 lineV[clineV++] = fny;
1817 cline++;
1818
1819 lineC[clineC++] = ((float)colr)/255.0f;
1820 lineC[clineC++] = ((float)colg)/255.0f;
1821 lineC[clineC++] = ((float)colb)/255.0f;
1822 lineC[clineC++] = 0.0f;
1823 lineV[clineV++] = fnx;
1824 lineV[clineV++] = fny+5;
1825 cline++;
1826 #else
1827 gradv = 4*sim->parts[i].life + flicker;
1828 for (x = 0; gradv>0.5; x++) {
1829 addpixel(nx+x, ny, colr, colg, colb, gradv);
1830 addpixel(nx-x, ny, colr, colg, colb, gradv);
1831
1832 addpixel(nx, ny+x, colr, colg, colb, gradv);
1833 addpixel(nx, ny-x, colr, colg, colb, gradv);
1834 gradv = gradv/1.5f;
1835 }
1836 #endif
1837 }
1838 if(pixel_mode & PMODE_FLARE)
1839 {
1840 flicker = random_gen()%20;
1841 #ifdef OGLR
1842 //Oh god, this is awful
1843 lineC[clineC++] = ((float)colr)/255.0f;
1844 lineC[clineC++] = ((float)colg)/255.0f;
1845 lineC[clineC++] = ((float)colb)/255.0f;
1846 lineC[clineC++] = 0.0f;
1847 lineV[clineV++] = fnx-10;
1848 lineV[clineV++] = fny;
1849 cline++;
1850
1851 lineC[clineC++] = ((float)colr)/255.0f;
1852 lineC[clineC++] = ((float)colg)/255.0f;
1853 lineC[clineC++] = ((float)colb)/255.0f;
1854 lineC[clineC++] = 1.0f - ((float)flicker)/40;
1855 lineV[clineV++] = fnx;
1856 lineV[clineV++] = fny;
1857 cline++;
1858
1859 lineC[clineC++] = ((float)colr)/255.0f;
1860 lineC[clineC++] = ((float)colg)/255.0f;
1861 lineC[clineC++] = ((float)colb)/255.0f;
1862 lineC[clineC++] = 0.0f;
1863 lineV[clineV++] = fnx+10;
1864 lineV[clineV++] = fny;
1865 cline++;
1866
1867 lineC[clineC++] = ((float)colr)/255.0f;
1868 lineC[clineC++] = ((float)colg)/255.0f;
1869 lineC[clineC++] = ((float)colb)/255.0f;
1870 lineC[clineC++] = 0.0f;
1871 lineV[clineV++] = fnx;
1872 lineV[clineV++] = fny-10;
1873 cline++;
1874
1875 lineC[clineC++] = ((float)colr)/255.0f;
1876 lineC[clineC++] = ((float)colg)/255.0f;
1877 lineC[clineC++] = ((float)colb)/255.0f;
1878 lineC[clineC++] = 1.0f - ((float)flicker)/30;
1879 lineV[clineV++] = fnx;
1880 lineV[clineV++] = fny;
1881 cline++;
1882
1883 lineC[clineC++] = ((float)colr)/255.0f;
1884 lineC[clineC++] = ((float)colg)/255.0f;
1885 lineC[clineC++] = ((float)colb)/255.0f;
1886 lineC[clineC++] = 0.0f;
1887 lineV[clineV++] = fnx;
1888 lineV[clineV++] = fny+10;
1889 cline++;
1890 #else
1891 gradv = flicker + fabs(parts[i].vx)*17 + fabs(sim->parts[i].vy)*17;
1892 blendpixel(nx, ny, colr, colg, colb, (gradv*4)>255?255:(gradv*4) );
1893 blendpixel(nx+1, ny, colr, colg, colb, (gradv*2)>255?255:(gradv*2) );
1894 blendpixel(nx-1, ny, colr, colg, colb, (gradv*2)>255?255:(gradv*2) );
1895 blendpixel(nx, ny+1, colr, colg, colb, (gradv*2)>255?255:(gradv*2) );
1896 blendpixel(nx, ny-1, colr, colg, colb, (gradv*2)>255?255:(gradv*2) );
1897 if (gradv>255) gradv=255;
1898 blendpixel(nx+1, ny-1, colr, colg, colb, gradv);
1899 blendpixel(nx-1, ny-1, colr, colg, colb, gradv);
1900 blendpixel(nx+1, ny+1, colr, colg, colb, gradv);
1901 blendpixel(nx-1, ny+1, colr, colg, colb, gradv);
1902 for (x = 1; gradv>0.5; x++) {
1903 addpixel(nx+x, ny, colr, colg, colb, gradv);
1904 addpixel(nx-x, ny, colr, colg, colb, gradv);
1905 addpixel(nx, ny+x, colr, colg, colb, gradv);
1906 addpixel(nx, ny-x, colr, colg, colb, gradv);
1907 gradv = gradv/1.2f;
1908 }
1909 #endif
1910 }
1911 if(pixel_mode & PMODE_LFLARE)
1912 {
1913 flicker = random_gen()%20;
1914 #ifdef OGLR
1915 //Oh god, this is awful
1916 lineC[clineC++] = ((float)colr)/255.0f;
1917 lineC[clineC++] = ((float)colg)/255.0f;
1918 lineC[clineC++] = ((float)colb)/255.0f;
1919 lineC[clineC++] = 0.0f;
1920 lineV[clineV++] = fnx-70;
1921 lineV[clineV++] = fny;
1922 cline++;
1923
1924 lineC[clineC++] = ((float)colr)/255.0f;
1925 lineC[clineC++] = ((float)colg)/255.0f;
1926 lineC[clineC++] = ((float)colb)/255.0f;
1927 lineC[clineC++] = 1.0f - ((float)flicker)/30;
1928 lineV[clineV++] = fnx;
1929 lineV[clineV++] = fny;
1930 cline++;
1931
1932 lineC[clineC++] = ((float)colr)/255.0f;
1933 lineC[clineC++] = ((float)colg)/255.0f;
1934 lineC[clineC++] = ((float)colb)/255.0f;
1935 lineC[clineC++] = 0.0f;
1936 lineV[clineV++] = fnx+70;
1937 lineV[clineV++] = fny;
1938 cline++;
1939
1940 lineC[clineC++] = ((float)colr)/255.0f;
1941 lineC[clineC++] = ((float)colg)/255.0f;
1942 lineC[clineC++] = ((float)colb)/255.0f;
1943 lineC[clineC++] = 0.0f;
1944 lineV[clineV++] = fnx;
1945 lineV[clineV++] = fny-70;
1946 cline++;
1947
1948 lineC[clineC++] = ((float)colr)/255.0f;
1949 lineC[clineC++] = ((float)colg)/255.0f;
1950 lineC[clineC++] = ((float)colb)/255.0f;
1951 lineC[clineC++] = 1.0f - ((float)flicker)/50;
1952 lineV[clineV++] = fnx;
1953 lineV[clineV++] = fny;
1954 cline++;
1955
1956 lineC[clineC++] = ((float)colr)/255.0f;
1957 lineC[clineC++] = ((float)colg)/255.0f;
1958 lineC[clineC++] = ((float)colb)/255.0f;
1959 lineC[clineC++] = 0.0f;
1960 lineV[clineV++] = fnx;
1961 lineV[clineV++] = fny+70;
1962 cline++;
1963 #else
1964 gradv = flicker + fabs(parts[i].vx)*17 + fabs(parts[i].vy)*17;
1965 blendpixel(nx, ny, colr, colg, colb, (gradv*4)>255?255:(gradv*4) );
1966 blendpixel(nx+1, ny, colr, colg, colb, (gradv*2)>255?255:(gradv*2) );
1967 blendpixel(nx-1, ny, colr, colg, colb, (gradv*2)>255?255:(gradv*2) );
1968 blendpixel(nx, ny+1, colr, colg, colb, (gradv*2)>255?255:(gradv*2) );
1969 blendpixel(nx, ny-1, colr, colg, colb, (gradv*2)>255?255:(gradv*2) );
1970 if (gradv>255) gradv=255;
1971 blendpixel(nx+1, ny-1, colr, colg, colb, gradv);
1972 blendpixel(nx-1, ny-1, colr, colg, colb, gradv);
1973 blendpixel(nx+1, ny+1, colr, colg, colb, gradv);
1974 blendpixel(nx-1, ny+1, colr, colg, colb, gradv);
1975 for (x = 1; gradv>0.5; x++) {
1976 addpixel(nx+x, ny, colr, colg, colb, gradv);
1977 addpixel(nx-x, ny, colr, colg, colb, gradv);
1978 addpixel(nx, ny+x, colr, colg, colb, gradv);
1979 addpixel(nx, ny-x, colr, colg, colb, gradv);
1980 gradv = gradv/1.01f;
1981 }
1982 #endif
1983 }
1984 if (pixel_mode & EFFECT_GRAVIN)
1985 {
1986 int nxo = 0;
1987 int nyo = 0;
1988 int r;
1989 float drad = 0.0f;
1990 float ddist = 0.0f;
1991 sim->orbitalparts_get(parts[i].life, parts[i].ctype, orbd, orbl);
1992 for (r = 0; r < 4; r++) {
1993 ddist = ((float)orbd[r])/16.0f;
1994 drad = (M_PI * ((float)orbl[r]) / 180.0f)*1.41f;
1995 nxo = (int)(ddist*cos(drad));
1996 nyo = (int)(ddist*sin(drad));
1997 if (ny+nyo>0 && ny+nyo<YRES && nx+nxo>0 && nx+nxo<XRES && TYP(sim->pmap[ny+nyo][nx+nxo]) != PT_PRTI)
1998 addpixel(nx+nxo, ny+nyo, colr, colg, colb, 255-orbd[r]);
1999 }
2000 }
2001 if (pixel_mode & EFFECT_GRAVOUT)
2002 {
2003 int nxo = 0;
2004 int nyo = 0;
2005 int r;
2006 float drad = 0.0f;
2007 float ddist = 0.0f;
2008 sim->orbitalparts_get(parts[i].life, parts[i].ctype, orbd, orbl);
2009 for (r = 0; r < 4; r++) {
2010 ddist = ((float)orbd[r])/16.0f;
2011 drad = (M_PI * ((float)orbl[r]) / 180.0f)*1.41f;
2012 nxo = (int)(ddist*cos(drad));
2013 nyo = (int)(ddist*sin(drad));
2014 if (ny+nyo>0 && ny+nyo<YRES && nx+nxo>0 && nx+nxo<XRES && TYP(sim->pmap[ny+nyo][nx+nxo]) != PT_PRTO)
2015 addpixel(nx+nxo, ny+nyo, colr, colg, colb, 255-orbd[r]);
2016 }
2017 }
2018 if (pixel_mode & EFFECT_DBGLINES && !(display_mode&DISPLAY_PERS))
2019 {
2020 // draw lines connecting wifi/portal channels
2021 if (mousePos.X == nx && mousePos.Y == ny && i == ID(sim->pmap[ny][nx]) && debugLines)
2022 {
2023 int type = parts[i].type, tmp = (int)((parts[i].temp-73.15f)/100+1), othertmp;
2024 if (type == PT_PRTI)
2025 type = PT_PRTO;
2026 else if (type == PT_PRTO)
2027 type = PT_PRTI;
2028 for (int z = 0; z <= sim->parts_lastActiveIndex; z++)
2029 {
2030 if (parts[z].type == type)
2031 {
2032 othertmp = (int)((parts[z].temp-73.15f)/100+1);
2033 if (tmp == othertmp)
2034 xor_line(nx,ny,(int)(parts[z].x+0.5f),(int)(parts[z].y+0.5f));
2035 }
2036 }
2037 }
2038 }
2039 //Fire effects
2040 if(firea && (pixel_mode & FIRE_BLEND))
2041 {
2042 #ifdef OGLR
2043 smokeV[csmokeV++] = nx;
2044 smokeV[csmokeV++] = ny;
2045 smokeC[csmokeC++] = ((float)firer)/255.0f;
2046 smokeC[csmokeC++] = ((float)fireg)/255.0f;
2047 smokeC[csmokeC++] = ((float)fireb)/255.0f;
2048 smokeC[csmokeC++] = ((float)firea)/255.0f;
2049 csmoke++;
2050 #else
2051 firea /= 2;
2052 fire_r[ny/CELL][nx/CELL] = (firea*firer + (255-firea)*fire_r[ny/CELL][nx/CELL]) >> 8;
2053 fire_g[ny/CELL][nx/CELL] = (firea*fireg + (255-firea)*fire_g[ny/CELL][nx/CELL]) >> 8;
2054 fire_b[ny/CELL][nx/CELL] = (firea*fireb + (255-firea)*fire_b[ny/CELL][nx/CELL]) >> 8;
2055 #endif
2056 }
2057 if(firea && (pixel_mode & FIRE_ADD))
2058 {
2059 #ifdef OGLR
2060 fireV[cfireV++] = nx;
2061 fireV[cfireV++] = ny;
2062 fireC[cfireC++] = ((float)firer)/255.0f;
2063 fireC[cfireC++] = ((float)fireg)/255.0f;
2064 fireC[cfireC++] = ((float)fireb)/255.0f;
2065 fireC[cfireC++] = ((float)firea)/255.0f;
2066 cfire++;
2067 #else
2068 firea /= 8;
2069 firer = ((firea*firer) >> 8) + fire_r[ny/CELL][nx/CELL];
2070 fireg = ((firea*fireg) >> 8) + fire_g[ny/CELL][nx/CELL];
2071 fireb = ((firea*fireb) >> 8) + fire_b[ny/CELL][nx/CELL];
2072
2073 if(firer>255)
2074 firer = 255;
2075 if(fireg>255)
2076 fireg = 255;
2077 if(fireb>255)
2078 fireb = 255;
2079
2080 fire_r[ny/CELL][nx/CELL] = firer;
2081 fire_g[ny/CELL][nx/CELL] = fireg;
2082 fire_b[ny/CELL][nx/CELL] = fireb;
2083 #endif
2084 }
2085 if(firea && (pixel_mode & FIRE_SPARK))
2086 {
2087 #ifdef OGLR
2088 smokeV[csmokeV++] = nx;
2089 smokeV[csmokeV++] = ny;
2090 smokeC[csmokeC++] = ((float)firer)/255.0f;
2091 smokeC[csmokeC++] = ((float)fireg)/255.0f;
2092 smokeC[csmokeC++] = ((float)fireb)/255.0f;
2093 smokeC[csmokeC++] = ((float)firea)/255.0f;
2094 csmoke++;
2095 #else
2096 firea /= 4;
2097 fire_r[ny/CELL][nx/CELL] = (firea*firer + (255-firea)*fire_r[ny/CELL][nx/CELL]) >> 8;
2098 fire_g[ny/CELL][nx/CELL] = (firea*fireg + (255-firea)*fire_g[ny/CELL][nx/CELL]) >> 8;
2099 fire_b[ny/CELL][nx/CELL] = (firea*fireb + (255-firea)*fire_b[ny/CELL][nx/CELL]) >> 8;
2100 #endif
2101 }
2102 }
2103 }
2104 }
2105 #ifdef OGLR
2106
2107 //Go into array mode
2108 glEnableClientState(GL_COLOR_ARRAY);
2109 glEnableClientState(GL_VERTEX_ARRAY);
2110
2111 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2112
2113 if(cflat)
2114 {
2115 // -- BEGIN FLAT -- //
2116 //Set point size (size of fire texture)
2117 glPointSize(1.0f);
2118
2119 glColorPointer(4, GL_FLOAT, 0, &flatC[0]);
2120 glVertexPointer(2, GL_INT, 0, &flatV[0]);
2121
2122 glDrawArrays(GL_POINTS, 0, cflat);
2123
2124 //Clear some stuff we set
2125 // -- END FLAT -- //
2126 }
2127
2128 if(cblob)
2129 {
2130 // -- BEGIN BLOB -- //
2131 glEnable( GL_POINT_SMOOTH ); //Blobs!
2132 glPointSize(2.5f);
2133
2134 glColorPointer(4, GL_FLOAT, 0, &blobC[0]);
2135 glVertexPointer(2, GL_INT, 0, &blobV[0]);
2136
2137 glDrawArrays(GL_POINTS, 0, cblob);
2138
2139 //Clear some stuff we set
2140 glDisable( GL_POINT_SMOOTH );
2141 // -- END BLOB -- //
2142 }
2143
2144 if(cglow || cblur)
2145 {
2146 // -- BEGIN GLOW -- //
2147 //Start and prepare fire program
2148 glEnable(GL_TEXTURE_2D);
2149 glUseProgram(fireProg);
2150 glActiveTexture(GL_TEXTURE0);
2151 glBindTexture(GL_TEXTURE_2D, glowAlpha);
2152 glUniform1i(glGetUniformLocation(fireProg, "fireAlpha"), 0);
2153
2154 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2155
2156 //Make sure we can use texture coords on points
2157 glEnable(GL_POINT_SPRITE);
2158 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
2159 glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
2160
2161 //Set point size (size of fire texture)
2162 glPointSize(11.0f);
2163
2164 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
2165
2166 if(cglow)
2167 {
2168 glColorPointer(4, GL_FLOAT, 0, &glowC[0]);
2169 glVertexPointer(2, GL_INT, 0, &glowV[0]);
2170
2171 glDrawArrays(GL_POINTS, 0, cglow);
2172 }
2173
2174 glPointSize(7.0f);
2175
2176 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2177
2178 if(cblur)
2179 {
2180 glBindTexture(GL_TEXTURE_2D, blurAlpha);
2181
2182 glColorPointer(4, GL_FLOAT, 0, &blurC[0]);
2183 glVertexPointer(2, GL_INT, 0, &blurV[0]);
2184
2185 glDrawArrays(GL_POINTS, 0, cblur);
2186 }
2187
2188 //Clear some stuff we set
2189 glDisable(GL_POINT_SPRITE);
2190 glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
2191 glUseProgram(0);
2192 glBindTexture(GL_TEXTURE_2D, 0);
2193 glDisable(GL_TEXTURE_2D);
2194 // -- END GLOW -- //
2195 }
2196
2197 if(cadd)
2198 {
2199 // -- BEGIN ADD -- //
2200 //Set point size (size of fire texture)
2201 glPointSize(1.0f);
2202
2203 glColorPointer(4, GL_FLOAT, 0, &addC[0]);
2204 glVertexPointer(2, GL_INT, 0, &addV[0]);
2205
2206 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
2207 glDrawArrays(GL_POINTS, 0, cadd);
2208 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2209 //Clear some stuff we set
2210 // -- END ADD -- //
2211 }
2212
2213 if(cline)
2214 {
2215 // -- BEGIN LINES -- //
2216 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
2217 glEnable( GL_LINE_SMOOTH );
2218 glColorPointer(4, GL_FLOAT, 0, &lineC[0]);
2219 glVertexPointer(2, GL_FLOAT, 0, &lineV[0]);
2220
2221 glDrawArrays(GL_LINE_STRIP, 0, cline);
2222
2223 //Clear some stuff we set
2224 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2225 glDisable(GL_LINE_SMOOTH);
2226 // -- END LINES -- //
2227 }
2228
2229 if(cfire || csmoke)
2230 {
2231 // -- BEGIN FIRE -- //
2232 //Start and prepare fire program
2233 glEnable(GL_TEXTURE_2D);
2234 glUseProgram(fireProg);
2235 //glActiveTexture(GL_TEXTURE0);
2236 glBindTexture(GL_TEXTURE_2D, fireAlpha);
2237 glUniform1i(glGetUniformLocation(fireProg, "fireAlpha"), 0);
2238
2239 //Make sure we can use texture coords on points
2240 glEnable(GL_POINT_SPRITE);
2241 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
2242 glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
2243
2244 //Set point size (size of fire texture)
2245 glPointSize(CELL*3);
2246
2247 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
2248
2249 if(cfire)
2250 {
2251 glColorPointer(4, GL_FLOAT, 0, &fireC[0]);
2252 glVertexPointer(2, GL_INT, 0, &fireV[0]);
2253
2254 glDrawArrays(GL_POINTS, 0, cfire);
2255 }
2256
2257 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2258
2259 if(csmoke)
2260 {
2261 glColorPointer(4, GL_FLOAT, 0, &smokeC[0]);
2262 glVertexPointer(2, GL_INT, 0, &smokeV[0]);
2263
2264 glDrawArrays(GL_POINTS, 0, csmoke);
2265 }
2266
2267 //Clear some stuff we set
2268 glDisable(GL_POINT_SPRITE);
2269 glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
2270 glUseProgram(0);
2271 glBindTexture(GL_TEXTURE_2D, 0);
2272 glDisable(GL_TEXTURE_2D);
2273 // -- END FIRE -- //
2274 }
2275
2276 glDisableClientState(GL_COLOR_ARRAY);
2277 glDisableClientState(GL_VERTEX_ARRAY);
2278
2279 //Reset FBO
2280 glTranslated(0, -MENUSIZE, 0);
2281 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prevFbo);
2282
2283 glBlendFunc(origBlendSrc, origBlendDst);
2284 #endif
2285 }
2286
draw_other()2287 void Renderer::draw_other() // EMP effect
2288 {
2289 int i, j;
2290 int emp_decor = sim->emp_decor;
2291 if (emp_decor>40) emp_decor = 40;
2292 if (emp_decor<0) emp_decor = 0;
2293 if (!(render_mode & EFFECT)) // not in nothing mode
2294 return;
2295 if (emp_decor>0)
2296 {
2297 #ifdef OGLR
2298 GLint prevFbo;
2299 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prevFbo);
2300 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, partsFbo);
2301 glTranslated(0, MENUSIZE, 0);
2302 float femp_decor = ((float)emp_decor)/255.0f;
2303 /*int r=emp_decor*2.5, g=100+emp_decor*1.5, b=255;
2304 int a=(1.0*emp_decor/110)*255;
2305 if (r>255) r=255;
2306 if (g>255) g=255;
2307 if (b>255) g=255;
2308 if (a>255) a=255;*/
2309 glBegin(GL_QUADS);
2310 glColor4f(femp_decor*2.5f, 0.4f+femp_decor*1.5f, 1.0f+femp_decor*1.5f, femp_decor/0.44f);
2311 glVertex2f(0, MENUSIZE);
2312 glVertex2f(XRES, MENUSIZE);
2313 glVertex2f(XRES, WINDOWH);
2314 glVertex2f(0, WINDOWH);
2315 glEnd();
2316 glTranslated(0, -MENUSIZE, 0);
2317 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prevFbo);
2318 #else
2319 int r=emp_decor*2.5, g=100+emp_decor*1.5, b=255;
2320 int a=(1.0*emp_decor/110)*255;
2321 if (r>255) r=255;
2322 if (g>255) g=255;
2323 if (b>255) g=255;
2324 if (a>255) a=255;
2325 for (j=0; j<YRES; j++)
2326 for (i=0; i<XRES; i++)
2327 {
2328 blendpixel(i, j, r, g, b, a);
2329 }
2330 #endif
2331 }
2332 }
2333
draw_grav()2334 void Renderer::draw_grav()
2335 {
2336 int x, y, i, ca;
2337 float nx, ny, dist;
2338
2339 if(!gravityFieldEnabled)
2340 return;
2341
2342 for (y=0; y<YRES/CELL; y++)
2343 {
2344 for (x=0; x<XRES/CELL; x++)
2345 {
2346 ca = y*(XRES/CELL)+x;
2347 if(fabsf(sim->gravx[ca]) <= 0.001f && fabsf(sim->gravy[ca]) <= 0.001f)
2348 continue;
2349 nx = x*CELL;
2350 ny = y*CELL;
2351 dist = fabsf(sim->gravy[ca])+fabsf(sim->gravx[ca]);
2352 for(i = 0; i < 4; i++)
2353 {
2354 nx -= sim->gravx[ca]*0.5f;
2355 ny -= sim->gravy[ca]*0.5f;
2356 addpixel((int)(nx+0.5f), (int)(ny+0.5f), 255, 255, 255, (int)(dist*20.0f));
2357 }
2358 }
2359 }
2360 }
2361
draw_air()2362 void Renderer::draw_air()
2363 {
2364 if(!sim->aheat_enable && (display_mode & DISPLAY_AIRH))
2365 return;
2366 #ifndef OGLR
2367 if(!(display_mode & DISPLAY_AIR))
2368 return;
2369 int x, y, i, j;
2370 float (*pv)[XRES/CELL] = sim->air->pv;
2371 float (*hv)[XRES/CELL] = sim->air->hv;
2372 float (*vx)[XRES/CELL] = sim->air->vx;
2373 float (*vy)[XRES/CELL] = sim->air->vy;
2374 pixel c = 0;
2375 for (y=0; y<YRES/CELL; y++)
2376 for (x=0; x<XRES/CELL; x++)
2377 {
2378 if (display_mode & DISPLAY_AIRP)
2379 {
2380 if (pv[y][x] > 0.0f)
2381 c = PIXRGB(clamp_flt(pv[y][x], 0.0f, 8.0f), 0, 0);//positive pressure is red!
2382 else
2383 c = PIXRGB(0, 0, clamp_flt(-pv[y][x], 0.0f, 8.0f));//negative pressure is blue!
2384 }
2385 else if (display_mode & DISPLAY_AIRV)
2386 {
2387 c = PIXRGB(clamp_flt(fabsf(vx[y][x]), 0.0f, 8.0f),//vx adds red
2388 clamp_flt(pv[y][x], 0.0f, 8.0f),//pressure adds green
2389 clamp_flt(fabsf(vy[y][x]), 0.0f, 8.0f));//vy adds blue
2390 }
2391 else if (display_mode & DISPLAY_AIRH)
2392 {
2393 float ttemp = hv[y][x]+(-MIN_TEMP);
2394 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);
2395 c = PIXRGB((int)(color_data[caddress]*0.7f), (int)(color_data[caddress+1]*0.7f), (int)(color_data[caddress+2]*0.7f));
2396 //c = PIXRGB(clamp_flt(fabsf(vx[y][x]), 0.0f, 8.0f),//vx adds red
2397 // clamp_flt(hv[y][x], 0.0f, 1600.0f),//heat adds green
2398 // clamp_flt(fabsf(vy[y][x]), 0.0f, 8.0f));//vy adds blue
2399 }
2400 else if (display_mode & DISPLAY_AIRC)
2401 {
2402 int r;
2403 int g;
2404 int b;
2405 // velocity adds grey
2406 r = clamp_flt(fabsf(vx[y][x]), 0.0f, 24.0f) + clamp_flt(fabsf(vy[y][x]), 0.0f, 20.0f);
2407 g = clamp_flt(fabsf(vx[y][x]), 0.0f, 20.0f) + clamp_flt(fabsf(vy[y][x]), 0.0f, 24.0f);
2408 b = clamp_flt(fabsf(vx[y][x]), 0.0f, 24.0f) + clamp_flt(fabsf(vy[y][x]), 0.0f, 20.0f);
2409 if (pv[y][x] > 0.0f)
2410 {
2411 r += clamp_flt(pv[y][x], 0.0f, 16.0f);//pressure adds red!
2412 if (r>255)
2413 r=255;
2414 if (g>255)
2415 g=255;
2416 if (b>255)
2417 b=255;
2418 c = PIXRGB(r, g, b);
2419 }
2420 else
2421 {
2422 b += clamp_flt(-pv[y][x], 0.0f, 16.0f);//pressure adds blue!
2423 if (r>255)
2424 r=255;
2425 if (g>255)
2426 g=255;
2427 if (b>255)
2428 b=255;
2429 c = PIXRGB(r, g, b);
2430 }
2431 }
2432 if (findingElement)
2433 c = PIXRGB(PIXR(c)/10,PIXG(c)/10,PIXB(c)/10);
2434 for (j=0; j<CELL; j++)//draws the colors
2435 for (i=0; i<CELL; i++)
2436 vid[(x*CELL+i) + (y*CELL+j)*(VIDXRES)] = c;
2437 }
2438 #else
2439 int sdl_scale = 1;
2440 GLuint airProg;
2441 GLint prevFbo;
2442 if(display_mode & DISPLAY_AIRC)
2443 {
2444 airProg = airProg_Cracker;
2445 }
2446 else if(display_mode & DISPLAY_AIRV)
2447 {
2448 airProg = airProg_Velocity;
2449 }
2450 else if(display_mode & DISPLAY_AIRP)
2451 {
2452 airProg = airProg_Pressure;
2453 }
2454 else
2455 {
2456 return;
2457 }
2458
2459 glEnable( GL_TEXTURE_2D );
2460 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prevFbo);
2461 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, partsFbo);
2462 glTranslated(0, MENUSIZE, 0);
2463
2464 glUseProgram(airProg);
2465
2466 glActiveTexture(GL_TEXTURE0);
2467 glBindTexture(GL_TEXTURE_2D, airVX);
2468 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, XRES/CELL, YRES/CELL, GL_RED, GL_FLOAT, sim->air->vx);
2469 glUniform1i(glGetUniformLocation(airProg, "airX"), 0);
2470 glActiveTexture(GL_TEXTURE1);
2471 glBindTexture(GL_TEXTURE_2D, airVY);
2472 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, XRES/CELL, YRES/CELL, GL_GREEN, GL_FLOAT, sim->air->vy);
2473 glUniform1i(glGetUniformLocation(airProg, "airY"), 1);
2474 glActiveTexture(GL_TEXTURE2);
2475 glBindTexture(GL_TEXTURE_2D, airPV);
2476 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, XRES/CELL, YRES/CELL, GL_BLUE, GL_FLOAT, sim->air->pv);
2477 glUniform1i(glGetUniformLocation(airProg, "airP"), 2);
2478 glActiveTexture(GL_TEXTURE0);
2479
2480 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
2481 glBegin(GL_QUADS);
2482 glTexCoord2d(1, 1);
2483 glVertex3f(XRES*sdl_scale, YRES*sdl_scale, 1.0);
2484 glTexCoord2d(0, 1);
2485 glVertex3f(0, YRES*sdl_scale, 1.0);
2486 glTexCoord2d(0, 0);
2487 glVertex3f(0, 0, 1.0);
2488 glTexCoord2d(1, 0);
2489 glVertex3f(XRES*sdl_scale, 0, 1.0);
2490 glEnd();
2491
2492 glUseProgram(0);
2493 glBindTexture(GL_TEXTURE_2D, 0);
2494 glTranslated(0, -MENUSIZE, 0);
2495 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prevFbo);
2496 glDisable( GL_TEXTURE_2D );
2497 #endif
2498 }
2499
draw_grav_zones()2500 void Renderer::draw_grav_zones()
2501 {
2502 if(!gravityZonesEnabled)
2503 return;
2504
2505 int x, y, i, j;
2506 for (y=0; y<YRES/CELL; y++)
2507 {
2508 for (x=0; x<XRES/CELL; x++)
2509 {
2510 if(sim->grav->gravmask[y*(XRES/CELL)+x])
2511 {
2512 for (j=0; j<CELL; j++)//draws the colors
2513 for (i=0; i<CELL; i++)
2514 if(i == j)
2515 blendpixel(x*CELL+i, y*CELL+j, 255, 200, 0, 120);
2516 else
2517 blendpixel(x*CELL+i, y*CELL+j, 32, 32, 32, 120);
2518 }
2519 }
2520 }
2521 }
2522
drawblob(int x,int y,unsigned char cr,unsigned char cg,unsigned char cb)2523 void Renderer::drawblob(int x, int y, unsigned char cr, unsigned char cg, unsigned char cb)
2524 {
2525 blendpixel(x+1, y, cr, cg, cb, 112);
2526 blendpixel(x-1, y, cr, cg, cb, 112);
2527 blendpixel(x, y+1, cr, cg, cb, 112);
2528 blendpixel(x, y-1, cr, cg, cb, 112);
2529
2530 blendpixel(x+1, y-1, cr, cg, cb, 64);
2531 blendpixel(x-1, y-1, cr, cg, cb, 64);
2532 blendpixel(x+1, y+1, cr, cg, cb, 64);
2533 blendpixel(x-1, y+1, cr, cg, cb, 64);
2534 }
2535
GetPixel(int x,int y)2536 pixel Renderer::GetPixel(int x, int y)
2537 {
2538 if (x<0 || y<0 || x>=VIDXRES || y>=VIDYRES)
2539 return 0;
2540 #ifdef OGLR
2541 return 0;
2542 #else
2543 return vid[(y*VIDXRES)+x];
2544 #endif
2545 }
2546
Renderer(Graphics * g,Simulation * sim)2547 Renderer::Renderer(Graphics * g, Simulation * sim):
2548 sim(NULL),
2549 g(NULL),
2550 render_mode(0),
2551 colour_mode(0),
2552 display_mode(0),
2553 gravityZonesEnabled(false),
2554 gravityFieldEnabled(false),
2555 decorations_enable(1),
2556 blackDecorations(false),
2557 debugLines(false),
2558 sampleColor(0xFFFFFFFF),
2559 findingElement(0),
2560 foundElements(0),
2561 mousePos(0, 0),
2562 zoomWindowPosition(0, 0),
2563 zoomScopePosition(0, 0),
2564 zoomScopeSize(32),
2565 zoomEnabled(false),
2566 ZFACTOR(8),
2567 gridSize(0)
2568 {
2569 this->g = g;
2570 this->sim = sim;
2571 #if !defined(OGLR)
2572 #if defined(OGLI)
2573 vid = new pixel[VIDXRES*VIDYRES];
2574 #else
2575 vid = g->vid;
2576 #endif
2577 persistentVid = new pixel[VIDXRES*YRES];
2578 warpVid = new pixel[VIDXRES*VIDYRES];
2579 #endif
2580
2581 memset(fire_r, 0, sizeof(fire_r));
2582 memset(fire_g, 0, sizeof(fire_g));
2583 memset(fire_b, 0, sizeof(fire_b));
2584
2585 //Set defauly display modes
2586 ResetModes();
2587
2588 //Render mode presets. Possibly load from config in future?
2589 renderModePresets.push_back({
2590 "Alternative Velocity Display",
2591 { RENDER_EFFE, RENDER_BASC },
2592 { DISPLAY_AIRC },
2593 0
2594 });
2595 renderModePresets.push_back({
2596 "Velocity Display",
2597 { RENDER_EFFE, RENDER_BASC },
2598 { DISPLAY_AIRV },
2599 0
2600 });
2601 renderModePresets.push_back({
2602 "Pressure Display",
2603 { RENDER_EFFE, RENDER_BASC },
2604 { DISPLAY_AIRP },
2605 0
2606 });
2607 renderModePresets.push_back({
2608 "Persistent Display",
2609 { RENDER_EFFE, RENDER_BASC },
2610 { DISPLAY_PERS },
2611 0
2612 });
2613 renderModePresets.push_back({
2614 "Fire Display",
2615 { RENDER_FIRE, RENDER_SPRK, RENDER_EFFE, RENDER_BASC },
2616 { },
2617 0
2618 });
2619 renderModePresets.push_back({
2620 "Blob Display",
2621 { RENDER_FIRE, RENDER_SPRK, RENDER_EFFE, RENDER_BLOB },
2622 { },
2623 0
2624 });
2625 renderModePresets.push_back({
2626 "Heat Display",
2627 { RENDER_BASC },
2628 { DISPLAY_AIRH },
2629 COLOUR_HEAT
2630 });
2631 renderModePresets.push_back({
2632 "Fancy Display",
2633 { RENDER_FIRE, RENDER_SPRK, RENDER_GLOW, RENDER_BLUR, RENDER_EFFE, RENDER_BASC },
2634 { DISPLAY_WARP },
2635 0
2636 });
2637 renderModePresets.push_back({
2638 "Nothing Display",
2639 { RENDER_BASC },
2640 { },
2641 0
2642 });
2643 renderModePresets.push_back({
2644 "Heat Gradient Display",
2645 { RENDER_BASC },
2646 { },
2647 COLOUR_GRAD
2648 });
2649 renderModePresets.push_back({
2650 "Life Gradient Display",
2651 { RENDER_BASC },
2652 { },
2653 COLOUR_LIFE
2654 });
2655
2656 //Prepare the graphics cache
2657 graphicscache = new gcache_item[PT_NUM];
2658 std::fill(&graphicscache[0], &graphicscache[PT_NUM], gcache_item());
2659
2660 int fireColoursCount = 4;
2661 pixel fireColours[] = {PIXPACK(0xAF9F0F), PIXPACK(0xDFBF6F), PIXPACK(0x60300F), PIXPACK(0x000000)};
2662 float fireColoursPoints[] = {1.0f, 0.9f, 0.5f, 0.0f};
2663
2664 int plasmaColoursCount = 5;
2665 pixel plasmaColours[] = {PIXPACK(0xAFFFFF), PIXPACK(0xAFFFFF), PIXPACK(0x301060), PIXPACK(0x301040), PIXPACK(0x000000)};
2666 float plasmaColoursPoints[] = {1.0f, 0.9f, 0.5f, 0.25, 0.0f};
2667
2668 flm_data = Graphics::GenerateGradient(fireColours, fireColoursPoints, fireColoursCount, 200);
2669 plasma_data = Graphics::GenerateGradient(plasmaColours, plasmaColoursPoints, plasmaColoursCount, 200);
2670
2671 #ifdef OGLR
2672 //FBO Texture
2673 glEnable(GL_TEXTURE_2D);
2674 glGenTextures(1, &partsFboTex);
2675 glBindTexture(GL_TEXTURE_2D, partsFboTex);
2676 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, XRES, YRES, 0, GL_RGBA, GL_FLOAT, NULL);
2677 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
2678 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
2679
2680 //FBO
2681 glGenFramebuffers(1, &partsFbo);
2682 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, partsFbo);
2683 glEnable(GL_BLEND);
2684 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, partsFboTex, 0);
2685 glBindTexture(GL_TEXTURE_2D, 0);
2686 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); // Reset framebuffer binding
2687 glDisable(GL_TEXTURE_2D);
2688
2689 //Texture for air to be drawn
2690 glEnable(GL_TEXTURE_2D);
2691 glGenTextures(1, &airBuf);
2692 glBindTexture(GL_TEXTURE_2D, airBuf);
2693 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, XRES/CELL, YRES/CELL, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
2694
2695 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
2696 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
2697
2698 glBindTexture(GL_TEXTURE_2D, 0);
2699 glDisable(GL_TEXTURE_2D);
2700
2701 //Zoom texture
2702 glEnable(GL_TEXTURE_2D);
2703 glGenTextures(1, &zoomTex);
2704 glBindTexture(GL_TEXTURE_2D, zoomTex);
2705 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
2706
2707 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
2708 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
2709
2710 glBindTexture(GL_TEXTURE_2D, 0);
2711 glDisable(GL_TEXTURE_2D);
2712
2713 //Texture for velocity maps for gravity
2714 glEnable(GL_TEXTURE_2D);
2715 glGenTextures(1, &partsTFX);
2716 glBindTexture(GL_TEXTURE_2D, partsTFX);
2717 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, XRES/CELL, YRES/CELL, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
2718
2719 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
2720 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
2721
2722 glBindTexture(GL_TEXTURE_2D, 0);
2723 glGenTextures(1, &partsTFY);
2724 glBindTexture(GL_TEXTURE_2D, partsTFY);
2725 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, XRES/CELL, YRES/CELL, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
2726
2727 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
2728 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
2729
2730 glBindTexture(GL_TEXTURE_2D, 0);
2731 glDisable(GL_TEXTURE_2D);
2732
2733 //Texture for velocity maps for air
2734 //TODO: Combine all air maps into 3D array or structs
2735 glEnable(GL_TEXTURE_2D);
2736 glGenTextures(1, &airVX);
2737 glBindTexture(GL_TEXTURE_2D, airVX);
2738 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, XRES/CELL, YRES/CELL, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
2739
2740 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
2741 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
2742
2743 glBindTexture(GL_TEXTURE_2D, 0);
2744 glGenTextures(1, &airVY);
2745 glBindTexture(GL_TEXTURE_2D, airVY);
2746 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, XRES/CELL, YRES/CELL, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
2747
2748 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
2749 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
2750
2751 glBindTexture(GL_TEXTURE_2D, 0);
2752 glGenTextures(1, &airPV);
2753 glBindTexture(GL_TEXTURE_2D, airPV);
2754 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, XRES/CELL, YRES/CELL, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
2755
2756 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
2757 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
2758
2759 glBindTexture(GL_TEXTURE_2D, 0);
2760 glDisable(GL_TEXTURE_2D);
2761
2762 //Fire alpha texture
2763 glEnable(GL_TEXTURE_2D);
2764 glGenTextures(1, &fireAlpha);
2765 glBindTexture(GL_TEXTURE_2D, fireAlpha);
2766 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, CELL*3, CELL*3, 0, GL_ALPHA, GL_FLOAT, NULL);
2767
2768 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
2769 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
2770
2771 glBindTexture(GL_TEXTURE_2D, 0);
2772 glDisable(GL_TEXTURE_2D);
2773
2774 //Glow alpha texture
2775 glEnable(GL_TEXTURE_2D);
2776 glGenTextures(1, &glowAlpha);
2777 glBindTexture(GL_TEXTURE_2D, glowAlpha);
2778 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 11, 11, 0, GL_ALPHA, GL_FLOAT, NULL);
2779
2780 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
2781 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
2782
2783 glBindTexture(GL_TEXTURE_2D, 0);
2784 glDisable(GL_TEXTURE_2D);
2785
2786
2787 //Blur Alpha texture
2788 glEnable(GL_TEXTURE_2D);
2789 glGenTextures(1, &blurAlpha);
2790 glBindTexture(GL_TEXTURE_2D, blurAlpha);
2791 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 7, 7, 0, GL_ALPHA, GL_FLOAT, NULL);
2792
2793 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
2794 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
2795
2796 glBindTexture(GL_TEXTURE_2D, 0);
2797 glDisable(GL_TEXTURE_2D);
2798
2799 //Temptexture
2800 glEnable(GL_TEXTURE_2D);
2801 glGenTextures(1, &textTexture);
2802 glBindTexture(GL_TEXTURE_2D, textTexture);
2803
2804 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
2805 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
2806 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2807 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2808
2809 glBindTexture(GL_TEXTURE_2D, 0);
2810 glDisable(GL_TEXTURE_2D);
2811
2812 loadShaders();
2813 #endif
2814 prepare_alpha(CELL, 1.0f);
2815 }
2816
CompileRenderMode()2817 void Renderer::CompileRenderMode()
2818 {
2819 int old_render_mode = render_mode;
2820 render_mode = 0;
2821 for (size_t i = 0; i < render_modes.size(); i++)
2822 render_mode |= render_modes[i];
2823
2824 //If firemode is removed, clear the fire display
2825 if(!(render_mode & FIREMODE) && (old_render_mode & FIREMODE))
2826 {
2827 ClearAccumulation();
2828 }
2829 }
2830
ClearAccumulation()2831 void Renderer::ClearAccumulation()
2832 {
2833 std::fill(fire_r[0]+0, fire_r[(YRES/CELL)-1]+((XRES/CELL)-1), 0);
2834 std::fill(fire_g[0]+0, fire_g[(YRES/CELL)-1]+((XRES/CELL)-1), 0);
2835 std::fill(fire_b[0]+0, fire_b[(YRES/CELL)-1]+((XRES/CELL)-1), 0);
2836 #ifndef OGLR
2837 std::fill(persistentVid, persistentVid+(VIDXRES*YRES), 0);
2838 #endif
2839 }
2840
AddRenderMode(unsigned int mode)2841 void Renderer::AddRenderMode(unsigned int mode)
2842 {
2843 for (size_t i = 0; i < render_modes.size(); i++)
2844 {
2845 if(render_modes[i] == mode)
2846 {
2847 return;
2848 }
2849 }
2850 render_modes.push_back(mode);
2851 CompileRenderMode();
2852 }
2853
RemoveRenderMode(unsigned int mode)2854 void Renderer::RemoveRenderMode(unsigned int mode)
2855 {
2856 for (size_t i = 0; i < render_modes.size(); i++)
2857 {
2858 if(render_modes[i] == mode)
2859 {
2860 render_modes.erase(render_modes.begin() + i);
2861 i = 0;
2862 }
2863 }
2864 CompileRenderMode();
2865 }
2866
SetRenderMode(std::vector<unsigned int> render)2867 void Renderer::SetRenderMode(std::vector<unsigned int> render)
2868 {
2869 render_modes = render;
2870 CompileRenderMode();
2871 }
2872
GetRenderMode()2873 std::vector<unsigned int> Renderer::GetRenderMode()
2874 {
2875 return render_modes;
2876 }
2877
CompileDisplayMode()2878 void Renderer::CompileDisplayMode()
2879 {
2880 int old_display_mode = display_mode;
2881 display_mode = 0;
2882 for (size_t i = 0; i < display_modes.size(); i++)
2883 display_mode |= display_modes[i];
2884 if (!(display_mode & DISPLAY_PERS) && (old_display_mode & DISPLAY_PERS))
2885 {
2886 ClearAccumulation();
2887 }
2888 }
2889
AddDisplayMode(unsigned int mode)2890 void Renderer::AddDisplayMode(unsigned int mode)
2891 {
2892 for (size_t i = 0; i < display_modes.size(); i++)
2893 {
2894 if (display_modes[i] == mode)
2895 {
2896 return;
2897 }
2898 if (display_modes[i] & DISPLAY_AIR)
2899 {
2900 display_modes.erase(display_modes.begin()+i);
2901 }
2902 }
2903 display_modes.push_back(mode);
2904 CompileDisplayMode();
2905 }
2906
RemoveDisplayMode(unsigned int mode)2907 void Renderer::RemoveDisplayMode(unsigned int mode)
2908 {
2909 for (size_t i = 0; i < display_modes.size(); i++)
2910 {
2911 if (display_modes[i] == mode)
2912 {
2913 display_modes.erase(display_modes.begin() + i);
2914 i = 0;
2915 }
2916 }
2917 CompileDisplayMode();
2918 }
2919
SetDisplayMode(std::vector<unsigned int> display)2920 void Renderer::SetDisplayMode(std::vector<unsigned int> display)
2921 {
2922 display_modes = display;
2923 CompileDisplayMode();
2924 }
2925
GetDisplayMode()2926 std::vector<unsigned int> Renderer::GetDisplayMode()
2927 {
2928 return display_modes;
2929 }
2930
SetColourMode(unsigned int mode)2931 void Renderer::SetColourMode(unsigned int mode)
2932 {
2933 colour_mode = mode;
2934 }
2935
GetColourMode()2936 unsigned int Renderer::GetColourMode()
2937 {
2938 return colour_mode;
2939 }
2940
ResetModes()2941 void Renderer::ResetModes()
2942 {
2943 SetRenderMode({ RENDER_BASC, RENDER_FIRE, RENDER_SPRK });
2944 SetDisplayMode({ });
2945 SetColourMode(COLOUR_DEFAULT);
2946 }
2947
DumpFrame()2948 VideoBuffer Renderer::DumpFrame()
2949 {
2950 #ifdef OGLR
2951 #elif defined(OGLI)
2952 VideoBuffer newBuffer(XRES, YRES);
2953 std::copy(vid, vid+(XRES*YRES), newBuffer.Buffer);
2954 return newBuffer;
2955 #else
2956 VideoBuffer newBuffer(XRES, YRES);
2957 for(int y = 0; y < YRES; y++)
2958 {
2959 std::copy(vid+(y*WINDOWW), vid+(y*WINDOWW)+XRES, newBuffer.Buffer+(y*XRES));
2960 }
2961 return newBuffer;
2962 #endif
2963 }
2964
~Renderer()2965 Renderer::~Renderer()
2966 {
2967 #if !defined(OGLR)
2968 #if defined(OGLI)
2969 delete[] vid;
2970 #endif
2971 delete[] persistentVid;
2972 delete[] warpVid;
2973 #endif
2974 delete[] graphicscache;
2975 free(flm_data);
2976 free(plasma_data);
2977 }
2978
2979 #define PIXELMETHODS_CLASS Renderer
2980
2981 #ifdef OGLR
2982 #include "OpenGLDrawMethods.inl"
2983 #else
2984 #include "RasterDrawMethods.inl"
2985 #endif
2986
2987 #undef PIXELMETHODS_CLASS
2988