Radial Gradient?

Blitz3D Forums/Blitz3D Programming/Radial Gradient?

I'm trying to make a radial gradient to use as a texture for my game character shadow. I want to be able to pass a number to a function to make the gradient using the number of given colours. For example CreateGradient (5) would make a gradient with 5 steps, CreateGradient (100) would make a gradient with 100 etc

Only needs to be black and white. And the gradient needs to always fill the whole 256 x 256 texture with 2d drawing commands only. Something like this:



Could somebody please help me out?

Thanks

have a loop that draws ovals, start with a big white one, then for each smaller one, drop the color value by 1, draw all these to an image buffer then save the result as a bmp file. That should sort ya. If I wasn't at work I'd code it and poast the code. But I think browsing the forums from work is cheeky enough as it is :-P

Function Ovals (Shades)

Local Col,Pos#,Wid,A

For A = 0 To 255
	Col	= 255-A
	Pos	= A*0.5
	Wid	= 255-A
	Color Col,Col,Col
	Oval Pos,Pos,Wid,Wid,True
Next

End Function

How could I adjust this function to use the shades parameter? I want the darkest shade to always be black, and the lightest to always be white. I need the function to work out the shades in between...

Look for bezier curves algo :o) That gives you a function to go between numbers smoothly. And can easily be used for the RGB numbers.

This thread shows a 4 point curve to interpolate the RBG numbers:

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

Maybe this would help? (Sorry that link is for a 4 point curve)

http://efg2.com/Lab/Graphics/Jean-YvesQueinecBezierCurves.htm

Question. How would your function know what colours to use?

Thanks :) I'll have a look at the bezier curves...

My function ^ should only need a number of shades, I want only black to white so no need for colours. The number of shades should be the number of steps from black to white.

I know it seems like such a simple thing to do but I just can't work it out :(

Oh well, if it's only black to white that should be easy enough for the steps. Limme see...

This should work for ya :o)
What usually happens now is someone comes along with 2 lines of code that do the same thing ;o)

Graphics 800,600
SetBuffer BackBuffer()

Global start_R = 0
Global start_G = 0
Global start_B = 0

Global end_R = 255
Global end_G = 255
Global end_B = 255

Global steps = 64
Global size# = 512 ; texture size


For loop = 0 To (size/2)

	stage_percent# = 1.0/steps ; get the number between 0 and 1, that step will be set against1
	percent# = loop/(size/2) ; get the percentage of the loop completed (0 to 1 basically)
	
	temp = Int(percent / stage_percent) ; count number of steps done so far.
	
	temp1# = temp ; make the temp variable into a float number
	temp1# = temp1/steps ; round number between 0 and 1 so to work out color information
	
	temp_r# = (end_R - start_R) * temp1
	temp_g# = (end_G - start_G) * temp1
	temp_b# = (end_B - start_B) * temp1
	Color temp_r,temp_g,temp_b

	Oval loop,loop,size-(loop*2),size-(loop*2)
	Flip

Next


Oh and btw, the flip is only so you can see the progress. Actually for my benefit so i could see if it was working properly :o)

If you need it to write alpha information, gimme a shout.

Doesn't have to be bezier curves neccessarily IMHO. Simply say something like:

Graphics 640,480,32,2
SetBuffer BackBuffer()


;usage: blob x,y,w,h,levels of grey

blob 0,0,256,256,16



While KeyDown(1)=0
 Color 255,255,255
 Rect 0,0,100,20,1
 Color 0,0,0
 Text 0,0,Hex$(ReadPixel(MouseX(),MouseY() And $ffffff))
 Flip
Wend
WaitKey()




Function blob(x,y,w,h,shades)
 Color 255,255,255
 Rect x,y,w,h,1

 x_factor#=w/256.0
 y_factor#=h/256.0

 mystep#=256.0/(shades)
 mystep2#=256.0/(shades-1)
 bri=0
 ra_0=0

 While bri<256
  ra=255-ra_0
  If ra<0 Then ra=0
  If ra>255 Then ra=255

  bri2=255-bri
  If bri2<0 Then bri2=0
  If bri2>255 Then bri2=255
  Color bri2,bri2,bri2
  Oval x+(((w/2))-(ra/2)*x_factor),   y+(((h/2))-(ra/2)*y_factor),  ra*x_factor, ra*y_factor,1
  bri=bri+mystep2
  ra_0=ra_0+ mystep
 Wend
End Function



Oops - Ross was faster.

Wow, thanks a lot guys :)

I spent the last couple of days trying to do this. Should've stayed in school :s

:c)

In this thread http://www.blitzbasic.com/Community/posts.php?topic=77155#863163

I created a little function that returns a radial texture like that.

Function CreateStar(Size)
	; Create texture
	I = CreateImage(Size,Size)
	T = CreateTexture(Size,Size)
	LockBuffer ImageBuffer(i)
	
	S = Size / 2
	For x=-S To S
	For y=-S To S
		r# = ((x*x)+(y*y))
		If r < s Then
			c# = 255.0 - ((255.0 / s) * r)
			argb=(c Or (c Shl 8) Or (c Shl 16) Or ($ff000000))
			WritePixelFast x + s,y + s,argb,ImageBuffer(i)
		EndIf
	Next
	Next
	
	UnlockBuffer ImageBuffer(i)
	CopyRect 0,0,size,size,0,0,ImageBuffer(i),TextureBuffer(t)
	FreeImage i
	Return t
End Function
So you'd just do something like
ShadowTex = CreateStar(256)
And then you've got your texture.

If you want to add the banded look simply add a snap size to the c# variable in the code.
c# = Floor(c/bands) * bands
Obviously pass the bands variable into the function.

Job done. And I would suspect, although this it unproven, but it'll be approximately a shed load faster than using ovals.

:P

Ovals for erm... prime minister

For what it's worth, not much considering Rob's code is better (added some scene code to show the final result and added in alpha based on the darkness of the pixels):

Graphics3D 800,600
SetBuffer BackBuffer()


Global steps = 255
Global size# = 256 ; texture size

Global texture = CreateTexture(size,size,2)

Global image = CreateImage(size,size)

gradiant_color(texture,steps,0,0,0,255,255,255)
set_alpha(texture)

;set up a little scene to see the texture on a sprite

Global sprite = CreateSprite()
EntityTexture sprite,texture
Global camera = CreateCamera()
PositionEntity camera,0,0,-10

Global cube = CreateCube()
EntityColor cube,255,255,0
PositionEntity cube,0,1,5

While Not KeyHit(1)

	TurnEntity cube,1,1,1

	UpdateWorld
	RenderWorld
	DrawImage image,0,0
	Flip
Wend
End

Function gradiant_color(texture,steps,start_R,start_G,start_B,end_R,end_G,end_B)

	Local size# = TextureWidth(texture)
	Local percent#
	Local temp1#
	Local temp%
	
	SetBuffer TextureBuffer(texture)
	For loop = 0 To (size/2)-1
	
		stage_percent# = 1.0/steps ; get the number between 0 and 1, that step will be set against1
		percent# = loop/(size/2) ; get the percentage of the loop completed (0 to 1 basically)
		
		temp = Int(percent / stage_percent) ; count number of steps done so far.
		
		temp1# = temp ; make the temp variable into a float number
		temp1# = temp1/steps ; round number between 0 and 1 so to work out color information
		
		temp_r# = (end_R - start_R) * temp1
		temp_g# = (end_G - start_G) * temp1
		temp_b# = (end_B - start_B) * temp1
		Color temp_r,temp_g,temp_b
	
		Oval loop,loop,size-(loop*2),size-(loop*2)
	
	Next
	SetBuffer BackBuffer()
End Function



Function set_alpha(texture)

	LockBuffer TextureBuffer(texture)

	For loop=0 To TextureWidth(texture)-1
		For loop1=0 To TextureHeight(texture)-1
			RGB1=ReadPixelFast(loop,loop1,TextureBuffer(texture)) ; read the RGB value from the texture
			r=(RGB1 And $FF0000)Shr 16;separate out the red
			g=(RGB1 And $FF00) Shr 8;green
			b=RGB1 And $FF;and blue parts of the color
			a=(RGB1 And $FF000000)Shr 24 ; extract the alpha

			a=r

			newrgb= (a Shl 24) Or (r Shl 16) Or (g Shl 8) Or b ; combine the ARGB back into one value

			WritePixelFast(loop,loop1,newrgb,TextureBuffer(texture)); write back to the texture
		Next
	Next
	UnlockBuffer TextureBuffer(texture)
End Function


I've just updated my code, so now it really draws the ovals from rgb 0 to FFFFFF. It's ugly code, but hey, it works :P

Thank you for all the help :D

How would I go about making a swirl/spiral effect, instead of a circle?

use some sin/cos offsets from the center.