Code archives/Graphics/Fast 2D Blobby Objects/Metaballs in Max2D with OpenGL extras

This code has been declared by its author to be Public Domain code.

Download source code

Fast 2D Blobby Objects/Metaballs in Max2D with OpenGL extras by ImaginaryHuman2005
This program shows how to draw an `energy field` image using a special gradient curve, and then takes that image and renders it using LIGHTBLEND mode, to produce blobby objects. Several full-screen passes are then added using different blend modes and values to massage the visual data into something more useful. The end result is a gradient-shaded `band` which conforms to the contours of the blobby objects. This example uses some OpenGL calls but also still uses Max2D in a compatible way. This program could be used in a game or for some other application. It will be highly hardware accelerated if your OpenGL implementation supports using the GPU. It is fast!
'Blobby objects with BlitzMax using Max2D and some direct OpenGL

'Some special numbers
Local ballsize:Int=512
Local ballsizehalf:Int=ballsize/2

'Set up the display
Graphics 800,600,0
Cls

'Work out what the dividers needs to be
Local balldivider:Float
If ballsize=128 Then balldivider=64 '8x8
If ballsize=256 Then balldivider=256 '16x16
If ballsize=512 Then balldivider=1024 '32x32
Local lineardivider:Float
If ballsize=128 Then lineardivider=0.5
If ballsize=256 Then lineardivider=1
If ballsize=512 Then lineardivider=2

'Render the gradient image
For Local r:Float=1 To ballsize-1 Step 0.5
	Local level:Float=r
	level:*level
	level=level/balldivider
	SetColor level,level,level 'For blobby gradient shape
	'SetColor r/lineardivider,r/lineardivider,r/lineardivider 'For linear gradients
	DrawOval r/2,r/2,ballsize-r,ballsize-r
Next

'Turn it into an image
AutoMidHandle True
Local img:TImage=CreateImage(ballsize,ballsize,1,FILTEREDIMAGE)
GrabImage(img,0,0,0)

'Set the blend mode
SetBlend LIGHTBLEND

'Keep drawing the image until you press Escape
Repeat
	Cls
	glEnable(GL_BLEND)
	glBlendFunc(GL_SRC_ALPHA,GL_ONE)
	DrawImage img,400,300
	DrawImage img,MouseX(),MouseY()
	glBlendFunc(GL_SRC_ALPHA,GL_ONE)
	glColor4b($40,$40,$40,$40)
	DrawRect 0,0,800,600
	glBlendFunc(GL_SRC_ALPHA_SATURATE,GL_DST_COLOR)
	glColor4b(0,0,0,$FF)
	Local Counter:Int
	For Counter:Int=1 To 3
		DrawRect 0,0,800,600
	Next
	glBlendFunc(GL_ONE_MINUS_DST_COLOR,GL_ONE_MINUS_DST_COLOR)
	glColor4b($0,$0,$0,$0)
	DrawRect 0,0,800,600
	glBlendFunc(GL_DST_COLOR,GL_DST_COLOR)
	glColor4b($FF,$FF,$FF,$FF)
                SetColor $FF,$FF,$FF
	For Counter:Int=1 To 3
		DrawRect 0,0,800,600
	Next
	glDisable(GL_BLEND)
	Flip
Until KeyHit(KEY_ESCAPE)

Comments

Booticus2005
CANT.....STOP......PLAYING WITH THIS COOODE!!!! Excellent work!


Filax2005
Great !


DannyD2005
very nice.


Regular K2005
To fix this for v1.12 (demo at least) add SetGraphicsDriver(GLMax2DDriver()) above Graphics 800,600,0 and it works, to some extent.


ImaginaryHuman2007
You shouldn't be setting the Max2d driver when it's doing custom OpenGL code, you should choose the GLGraphics() driver.


Jesse2007
it works ok in windowed mode but full screen? can you or angel convert it to 100% gl graphics? That would really help some of us trying to learn OGL. I know what its doing: A grayscale image is blended with another gray scale image and causes the effect. what I am interested on is how do you integrate the images in to ogl. I am going to try to work this out myself but a little help would be appreciated.
I will post any progress.


ImaginaryHuman2007
See this thread, it contains a pure OpenGL implementation:

http://www.blitzbasic.com/Community/posts.php?topic=46378

The code may be slightly old - not sure but you might have to change to GLGraphics() to open a display.

Also the blobs that it shows initially are based on a square blob field which creates inverted blobs (which I think are cool - since I invented them).

Let me know if it works for you.


Jesse2007
thank you, I will check it out.


tesuji2011
Sorry to dig this up after so long but it's still useful.

Here's an adaptation that uses a FBO and gets away with just two render passes, one to draw the individual blobs to a texture and the other to render that texture to the screen. It does combine Max2D & OpenGL but appears to work ok (for now).




Leon Drake2011
balls are touching....


u know what that means...


Nate the Great2011
tesuji, sounds like something I was looking for but when I run it, it looks like just a bunch of rendered green circles... any idea why this is?


tesuji2011
Nate, maybe a problem with the FBO and your gfx card?

I'll try and put a up a plain grabpixmap version and or a faster opengl equivalent and see if that makes any difference.

<edit> here's a slower grabimage version that doesn't rely on FBOs. Does this work?

<edit2> gah. worked on the mac but got the same when I tried it on a PC. Determined that the grabimage wasn't including alpha even though it does on the mac. Change to Graphics 1024,768,0,0,GRAPHICS_BACKBUFFER | GRAPHICS_DEPTHBUFFER | GRAPHICS_ALPHABUFFER

Hopefully that works.





BlitzSupport2011
I get the green output with both versions, tesuji -- green balls moving over black background.

BTW It looks like you're setting Hertz to 0 in the Graphics call! I have to take that out to make it do anything...


tesuji2011
Managed to replicate the issue on a PC. Hopefully fixed now. Code edited above and seems to work, at least from here.


BlitzSupport2011
Hi tesuji, yep, both versions are working now, well done. (Just to check, still green, but shaded properly instead of being solid.)


tesuji2011
Thanks BlitzSupport.
It should look something like this :




BlitzSupport2011
Perfect, then!


Nate the Great2011
both examples work now! thanks!


Code Archives Forum