Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Bloobs!

This thread is locked; no one can reply to it. rss feed Print
 1   2   3 
Bloobs!
Johan Peitz
Member #9
April 2000
avatar

Here's a cool demo style effect I coded which I believe is called "bloobs". I did not invent the technique, just so you know. :) It's basically additive lightning. Anyway, I like the result and I wanted to share. Demo and src attached.

{"name":"bloob.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/8\/e\/8edc6f8cdf17defe98cca2142ac89253.png","w":458,"h":344,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/8\/e\/8edc6f8cdf17defe98cca2142ac89253"}bloob.png

--
johan peitz :: things I made

fox
Member #1,615
November 2001
avatar

wow, nice effect. and the stretching makes it look even better (I wish that was true for all graphics:P)
I think I'll try to find a place for that in my current project...
thanks for sharing

Steve Terry
Member #1,989
March 2002
avatar

Not bad, I see that effect a lot with compos, nice to see it done in software though, all the ones I see are pure OpenGL :)

___________________________________
[ Facebook ]
Microsoft is not the Borg collective. The Borg collective has got proper networking. - planetspace.de
Bill Gates is in fact Shawn Hargreaves' ßî+çh. - Gideon Weems

da_flo
Member #1,907
February 2002
avatar

The effect is quite cool, but I have some remarks about the code itself :

I have managed to compile it under linux, but I had to make some changes in the code :
- You are including winalleg.h whereas your code doesn't use any windows-specific code. Well, you might not care because you seem to only code for windows, but I think it should be pointed out anyway...
- I had to include math.h in order to make it work, because it otherwise uses the sin & cos function built in allegro, which return 'fix' and tus giving compile errors with gcc.

Well, one might think this is nitpicking, but I hope this could be useful ;)
( Of course, I must consider what a great coder and game maker you are, so I feel a bit ashamed to point out such things :-[ )

Marcello
Member #1,860
January 2002
avatar

Great coders don't concern themselves with silly things like that. ;)

Marcello

Gnatinator
Member #2,330
May 2002
avatar

woah peitz! that is elite! ;D

Sirocco
Member #88
April 2000
avatar

The scene called, they want their effect back ;)

-->
Graphic file formats used to fascinate me, but now I find them rather satanic.

Billybob
Member #3,136
January 2003

Quote:

You are including winalleg.h whereas your code doesn't use any windows-specific code. Well, you might not care because you seem to only code for windows, but I think it should be pointed out anyway...

Don't get Johan wrong, he's just trying to deter Linux users who are incapable of properly editting sourecode. I commend him for this.

Quote:

- I had to include math.h in order to make it work, because it otherwise uses the sin & cos function built in allegro, which return 'fix' and tus giving compile errors with gcc.

I didn't have that problem, shrugs

da_flo
Member #1,907
February 2002
avatar

Yeah I knew these remarks were quite silly... But I just felt like posting them :-/

My apologizes to our great Johan Peitz, great among the great... :D

Sirocco
Member #88
April 2000
avatar

Quote:

I had to include math.h in order to make it work, because it otherwise uses the sin & cos function built in allegro, which return 'fix' and tus giving compile errors with gcc.

I may be wrong, but I believe this depends on which flavor of GCC you are using (DJGPP, Ming, etc). Regardless, it might be better to skirt the issue entirely and include math.h.

-->
Graphic file formats used to fascinate me, but now I find them rather satanic.

Kris Allen
Member #4,639
May 2004
avatar

very blooby, congrats ;D

...Johan your code style is almost identical to mine! :o

- Kris

Richard Phipps
Member #1,632
November 2001
avatar

DemoHack!

Ahh.. I'm feeling nostalgia for the ST/Amiga Vectorball demos. :)

X-G
Member #856
December 2000
avatar

So... are bloobs and blits related in any way? ;D

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

Oscar Giner
Member #2,207
April 2002
avatar

Very nice :) And very fast. I also did some blob effects, but mine was quite slower (not that there's a difference in a decent computer).

Quote:

It's basically additive lightning

Then it's a similar effect to blobs. With blobs, you sum the squares of intensities, so you get an attraction effect. This and that you use a lookup table (good idea, btw, I'll try it, too) explain the speed boost in your demo :)

I attach mine. The effect is not as spectacular as yours, but if you run the blobs_inv.exe one, the effect is cool :) You can move one of the blobs (the big one) with the mouse.

If you want to compile it yourself, the only difference between the two exes is the call to bs.draw() at the end of main, if the last parameter is true or false.

Billybob
Member #3,136
January 2003

both EXEs crashed for me oscar.

Oscar Giner
Member #2,207
April 2002
avatar

Does your card support 640x480x16? I don't do any error checking, so if the call to set_gfx_mode fails... crash! I don't see any other reason that would crash on your computer but not on mine (but I'm in win98 :o).

[edit]
Make sure to execute in from explorer or a dos box, so it uses the alleg41.dll shipped and not the one you may have in windows folder (4.1 dll's are incompatible).

Billybob
Member #3,136
January 2003

Works extracted from the zip, my bad.

Anyway, as I mentioned in the Asteriods thread in the Game concepts, blobs are good for modelling certain things, asteriods for example. With enough blobs you can create organic structures that don't look too terribly blobby. Blobs are good for trees that have that kind of fused truck look (2+ trucks fused together).

Taken to the extreme and with some nasty-good physiscs you could very well simulate rain and water with them as well.

Not to mention some neato ghost-through-wall effects :P

Johan Peitz
Member #9
April 2000
avatar

Heh, glad you like it!

da_flo: You're right. winalleg.h is not supposed to be there. I tried something and forgot to remove it. ::)

Oscar: I think the main speed boosts I get is from the lookup table. I was fairly slow before that. But also, I'm running 8bit in 320x240 which is always fast and nice to work in. :) Your inverse version looks really cool. Like cells or some other organisms.

--
johan peitz :: things I made

flares
Member #3,463
April 2003
avatar

can you make it into a screen saver, seems like i can starred at it all day, also it reminds me of the mac OS X screen saver, lots of graphic joy.

[nonnus29]Plus the api is crap ... I'd rather chew broken glass then code with those.

Peter Hull
Member #1,136
March 2001

da_flo: stick to your guns, man, I had exactly the same problems as you. Thanks for the fix!

I saw a very 'jumpy' effect - was this intended? Look at this bit of code

// move blobs
 for(i=0;i<MAX_BLOOBS;i++) {
  b<i>->x = 160 - b<i>->bmp->w / 2 + w * cos(tick + i * 3) + w * cos(tick/3 - i * 7);
  b<i>->y = 120 - b<i>->bmp->h / 2 + h * sin(tick/9 - i * 5) + h * sin(tick + i * 3);
 }

'tick' is an integer that gets incremented 100 times per second. But, sin and cos wrap round every 2*pi (approx 6) so the bloob will oscillate very rapidly indeed.

imo it looks better if you put make tick a float (line 44) and put tick+=0.1 (line 95)

Maybe I just like my bloobs more chilled out that Johan ;)

Pete

Billybob
Member #3,136
January 2003

Don't forget to divide by a float if you do that peter. And probably multiply by a float too, but I'm not sure if multiply will cast it out to integer like division does.

Peter Hull
Member #1,136
March 2001

WH: we're all friends here; a little implicit up-conversion can be excused, I hope. ;)

Actually, several warnings are detected but none because of that:

[iBook:~/Downloads/bloobs Folder/src] peterhull% g++ *.cpp `allegro-config --libs` -O2 -W -Wall
CBloob.cpp: In member function `CBloob::CBloob(int, int, int)':
CBloob.cpp:17: warning: unused variable `int a'
CBloob.cpp:17: warning: unused variable `int b'
main.cpp: In function `int _mangled_main(int, char**)':
main.cpp:51: warning: `text_mode' is deprecated (declared at 
   /usr/local/include/allegro/alcompat.h:167)
main.cpp:57: warning: missing initializer for member `RGB::filler'
main.cpp:113: warning: `textprintf' is deprecated (declared at 
   /usr/local/include/allegro/alcompat.h:189)
main.cpp:42: warning: unused parameter `int argc'
main.cpp:42: warning: unused parameter `char**argv'

Pete

Johan Peitz
Member #9
April 2000
avatar

Hah, I had no idea this piece of code would get so much attention. :) The movement of the bloobs is a hack I simply adjusted until I got a nice effect. (Btw, I don't get tha jump on my screen.) As for the unused variables... I ripped out some code from the CBloob class and probably forgot some variables in there. It's part of the old Hellcarrier code.

I tried to make it a screensaver, but I couldn't get it to exit normally by just moving the mouse or hitting a key. Do I have to put that in manually or does windows handle it?

--
johan peitz :: things I made

Billybob
Member #3,136
January 2003

scrsave.c says:

#SelectExpand
1/* ______ ___ ___ 2 * /\ _ \ /_ \ /_ \ 3 * \ \ \L\ \//\ \ //\ \ __ __ _ __ ___ 4 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `/\`'__/ __`\ 5 * \ \ /\ \ _\ _ _\ _/\ __//\ \L\ \ \ //\ \L\ \ 6 * \ _\ _/____/____\ ____\ ____ \ _\\ ____/ 7 * /_//_//____//____//____//___L\ /_/ /___/ 8 * /____/ 9 * _/__/ 10 * 11 * Example program showing how to write a Windows screensaver. This 12 * uses a fullscreen DirectX mode when activated normally, or the 13 * GDI interface functions when it is running in preview mode from 14 * inside the Windows screensaver selection dialog. 15 * 16 * Compile this like a normal executable, but rename the output 17 * program to have a .scr extension, and then copy it into your 18 * windows directory. 19 * 20 * By Shawn Hargreaves. 21 * 22 * See readme.txt for copyright information. 23 */ 24 25 26#include <time.h> 27 28#include "allegro.h" 29#include "winalleg.h" 30 31 32 33BITMAP *buf; 34 35int xline; 36int yline; 37 38 39typedef struct BOUNCER 40{ 41 float x, y; 42 float dx, dy; 43} BOUNCER; 44 45 46#define NUM_BOUNCERS 3 47 48BOUNCER bouncer[NUM_BOUNCERS]; 49 50 51 52/* initialises our graphical effect */ 53void ss_init(void) 54{ 55 int i; 56 57 xline = 0; 58 yline = 0; 59 60 srand(time(NULL)); 61 62 for (i=0; i<NUM_BOUNCERS; i++) { 63 bouncer<i>.x = rand() % buf->w; 64 bouncer<i>.y = rand() % buf->h; 65 66 bouncer<i>.dx = 0.5 + (rand() & 255) / 256.0; 67 bouncer<i>.dy = 0.5 + (rand() & 255) / 256.0; 68 69 if ((rand() & 255) < 128) 70 bouncer<i>.dx *= -1; 71 72 if ((rand() & 255) < 128) 73 bouncer<i>.dy *= -1; 74 } 75} 76 77 78 79/* animates the graphical effect */ 80void ss_update(void) 81{ 82 int i; 83 84 xline++; 85 if (xline > buf->w) 86 xline = 0; 87 88 yline++; 89 if (yline > buf->h) 90 yline = 0; 91 92 for (i=0; i<NUM_BOUNCERS; i++) { 93 bouncer<i>.x += bouncer<i>.dx; 94 bouncer<i>.y += bouncer<i>.dy; 95 96 if ((bouncer<i>.x < 0) || (bouncer<i>.x > buf->w)) 97 bouncer<i>.dx *= -1; 98 99 if ((bouncer<i>.y < 0) || (bouncer<i>.y > buf->h)) 100 bouncer<i>.dy *= -1; 101 } 102} 103 104 105 106/* draws the graphical effect */ 107void ss_draw(void) 108{ 109 clear_bitmap(buf); 110 111 line(buf, 0, 0, buf->w, buf->h, makecol(0, 0, 255)); 112 line(buf, buf->w, 0, 0, buf->h, makecol(0, 0, 255)); 113 114 vline(buf, xline, 0, buf->h, makecol(255, 0, 0)); 115 hline(buf, 0, yline, buf->w, makecol(0, 255, 0)); 116 117 text_mode(-1); 118 119 textout_centre(buf, font, "Allegro", bouncer[0].x, bouncer[0].y, makecol(0, 128, 255)); 120 textout_centre(buf, font, "Screensaver", bouncer[1].x, bouncer[1].y, makecol(255, 128, 0)); 121 textout_centre(buf, font, "<insert cool effect here>", bouncer[2].x, bouncer[2].y, makecol(255, 255, 255)); 122} 123 124 125 126/* shuts down the graphical effect */ 127void ss_exit(void) 128{ 129} 130 131 132 133/* dialog procedure for the settings dialog */ 134BOOL CALLBACK settings_dlg_proc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 135{ 136 switch (uMsg) { 137 138 case WM_COMMAND: 139 switch (HIWORD(wParam)) { 140 141 case BN_CLICKED: 142 EndDialog(hwndDlg, 0); 143 return 1; 144 } 145 break; 146 } 147 148 return 0; 149} 150 151 152 153/* the settings dialog function */ 154int do_settings(HANDLE hInstance, HANDLE hPrevInstance, HWND hParentWnd) 155{ 156 DialogBox(hInstance, "ID_CONFIG_DLG", hParentWnd, settings_dlg_proc); 157 158 return 0; 159} 160 161 162 163/* the password dialog function */ 164int do_password(HANDLE hInstance, HANDLE hPrevInstance, HWND hParentWnd) 165{ 166 MessageBox(hParentWnd, "Sorry, this screensaver doesn't implement the password stuff", "Allegro Screensaver", MB_OK); 167 168 return 0; 169} 170 171 172 173/* window procedure for the screensaver preview */ 174LRESULT CALLBACK preview_wnd_proc(HWND hwnd, UINT message, UINT wParam, LONG lParam) 175{ 176 PAINTSTRUCT ps; 177 HDC hdc; 178 179 switch (message) { 180 181 case WM_CREATE: 182 SetTimer(hwnd, 1, 15, NULL); 183 return 0; 184 185 case WM_TIMER: 186 ss_update(); 187 InvalidateRect(hwnd, NULL, FALSE); 188 return 0; 189 190 case WM_PAINT: 191 hdc = BeginPaint(hwnd, &ps); 192 ss_draw(); 193 set_palette_to_hdc(hdc, _current_palette); 194 draw_to_hdc(hdc, buf, 0, 0); 195 EndPaint(hwnd, &ps); 196 return 0; 197 198 case WM_DESTROY: 199 KillTimer(hwnd, 1); 200 PostQuitMessage(0); 201 return 0; 202 } 203 204 return DefWindowProc(hwnd, message, wParam, lParam); 205} 206 207 208 209/* the screensaver preview function */ 210int do_preview(HANDLE hInstance, HANDLE hPrevInstance, HWND hParentWnd) 211{ 212 WNDCLASS wndclass; 213 HWND hwnd; 214 MSG msg; 215 RECT rc; 216 217 if (!hPrevInstance) { 218 wndclass.style = CS_HREDRAW | CS_VREDRAW; 219 wndclass.lpfnWndProc = preview_wnd_proc; 220 wndclass.cbClsExtra = 0; 221 wndclass.cbWndExtra = 0; 222 wndclass.hInstance = hInstance; 223 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); 224 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); 225 wndclass.hbrBackground = NULL; 226 wndclass.lpszMenuName = NULL; 227 wndclass.lpszClassName = "sspreview"; 228 229 RegisterClass(&wndclass); 230 } 231 232 if (hParentWnd) 233 GetClientRect(hParentWnd, &rc); 234 else 235 rc.right = rc.bottom = 256; 236 237 install_allegro(SYSTEM_NONE, &errno, atexit); 238 set_palette(default_palette); 239 set_gdi_color_format(); 240 241 buf = create_bitmap(rc.right, rc.bottom); 242 243 ss_init(); 244 ss_update(); 245 246 hwnd = CreateWindow("sspreview", NULL, WS_CHILD, 247 0, 0, rc.right, rc.bottom, 248 hParentWnd, NULL, hInstance, NULL); 249 250 ShowWindow(hwnd, SW_SHOW); 251 UpdateWindow(hwnd); 252 253 while (GetMessage(&msg, NULL, 0, 0)) { 254 TranslateMessage(&msg); 255 DispatchMessage(&msg); 256 } 257 258 ss_exit(); 259 destroy_bitmap(buf); 260 261 return msg.wParam; 262} 263 264 265 266/* display switch callback */ 267static int foreground = TRUE; 268 269static void dispsw_callback(void) 270{ 271 foreground = FALSE; 272} 273 274 275/* run the saver normally, in fullscreen mode */ 276int do_saver(HANDLE hInstance, HANDLE hPrevInstance, HWND hParentWnd) 277{ 278 HANDLE scrsaver_mutex; 279 int mx, my, t; 280 281 /* prevent multiple instances from running */ 282 scrsaver_mutex = CreateMutex(NULL, TRUE, "Allegro screensaver"); 283 284 if (!scrsaver_mutex || (GetLastError() == ERROR_ALREADY_EXISTS)) 285 return -1; 286 287 allegro_init(); 288 install_keyboard(); 289 install_mouse(); 290 install_timer(); 291 292 /* try to set a fullscreen mode */ 293 if (set_gfx_mode(GFX_DIRECTX_ACCEL, 640, 480, 0, 0) != 0) 294 if (set_gfx_mode(GFX_DIRECTX_SOFT, 640, 480, 0, 0) != 0) 295 if (set_gfx_mode(GFX_DIRECTX_SAFE, 640, 480, 0, 0) != 0) { 296 ReleaseMutex(scrsaver_mutex); 297 return -1; 298 } 299 300 set_display_switch_mode(SWITCH_BACKAMNESIA); /* not SWITCH_AMNESIA */ 301 set_display_switch_callback(SWITCH_OUT, dispsw_callback); 302 303 buf = create_bitmap(SCREEN_W, SCREEN_H); 304 305 ss_init(); 306 ss_update(); 307 308 mx = mouse_x; 309 my = mouse_y; 310 311 t = retrace_count; 312 313 while (foreground && (!keypressed()) && (!mouse_b) && (mouse_x == mx) && (mouse_y == my)) { 314 while (t < retrace_count) { 315 ss_update(); 316 t++; 317 } 318 319 ss_draw(); 320 blit(buf, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H); 321 322 poll_mouse(); 323 } 324 325 ss_exit(); 326 destroy_bitmap(buf); 327 328 ReleaseMutex(scrsaver_mutex); 329 return 0; 330} 331 332 333 334/* the main program body */ 335int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow) 336{ 337 HWND hwnd; 338 char *args; 339 340 args = lpszCmdParam; 341 342 if ((args[0] == '-') || (args[0] == '/')) 343 args++; 344 345 if ((args[0]) && ((args[1] == ' ') || (args[1] == ':'))) 346 hwnd = (HWND)atoi(args+2); 347 else 348 hwnd = GetActiveWindow(); 349 350 switch (utolower(args[0])) { 351 352 case 'c': 353 return do_settings(hInstance, hPrevInstance, hwnd); 354 355 case 'a': 356 return do_password(hInstance, hPrevInstance, hwnd); 357 358 case 'p': 359 return do_preview(hInstance, hPrevInstance, hwnd); 360 361 case 's': 362 return do_saver(hInstance, hPrevInstance, hwnd); 363 } 364 365 return 0; 366}

Marcello
Member #1,860
January 2002
avatar

Am I the only one who keeps misreading this topic title?

Marcello

 1   2   3 


Go to: