Hi there Folks,
Here's a new piece of code that needs some of your valuable assistance and fixing.
The Aim is to have an image ( for this example a solid filled box is used ) wobble in both directions. Based upon the method used in Blitz Basic, where you would use DrawImageRect which I have added, you'll see it in the listing as a sub called DrawBufferRect.
Individually do a sin / cos on the x and y's and using directly drawing from the box1 image buffer and screenbuffer works. For this Double Wobble I have used temporary buffers to deal with updating the shape changing.
I then found I was having crashes with doing this, and came up with the idea of having the temporary storage buffer bigger than the box's one, and then in the UpdateWobbleWobble, centering it all to avoid the problem with boundary checks. As you'lll see from the code below, the centering isnt quite right, everything to the left is wiggling, but to the right is a solid line down the side.
'
' eXpErImEnTaL
' Wobble Wobble V1.0
' (c) Clyde Radcliffe / Gravity 2009
'
Option explicit
Const As Single PI=3.14159265
Const As Single D2R=PI/180.0
#Include once "tinyptc.bi"
Type gfxbuffer
wwidth as integer
height as integer
pixels as uinteger pointer
End Type
Declare Sub ClearBuffer ( ByVal buffer As gfxbuffer Pointer, ByVal col As UInteger=0)
Declare Sub ClearBuffers( ByVal buffer1 As gfxbuffer Pointer,_
ByVal buffer2 As gfxbuffer Pointer,_
ByVal Col As UInteger=0 )
Declare Sub DrawBuffer( ByVal PosX As Integer,_
ByVal PosY As Integer,_
ByVal Buffer As gfxbuffer Pointer )
Declare Sub DrawBufferRect( ByVal PosX As Integer,_
ByVal PosY As Integer,_
ByVal RectX As Integer,_
ByVal RectY As Integer,_
ByVal RectWWidth As Integer,_
ByVal RectHeight As Integer,_
ByVal Buffer As gfxbuffer Pointer,_
ByVal Dest As gfxbuffer Pointer )
Declare Sub RunWobbleWobble()
Declare Sub UpdateWobbleWobble( ByVal PosX As Integer,_
ByVal PosY As Integer,_
ByVal Mult As Integer,_
ByVal Size As Integer,_
ByVal Angle As Integer,_
ByVal Source As gfxbuffer Pointer,_
ByVal Buffer1 As gfxbuffer Pointer,_
ByVal Buffer2 As gfxbuffer Pointer )
Declare Function CreateBox( ByVal WWidth As Integer,_
ByVal Height As Integer,_
ByVal Col As UInteger=0 ) As gfxbuffer pointer
Declare Function CreateBuffer( ByVal WWidth As Integer,_
ByVal Height As Integer) As gfxbuffer pointer
Declare Function graphics( ByVal Title As String,_
ByVal WWidth As Integer,_
byval Height As Integer ) As gfxbuffer pointer
Dim Shared As gfxbuffer Pointer ScreenBuffer, Box1, BoxTemp1, BoxTemp2
ScreenBuffer=Graphics("Wobble Wobble",640,480)
Box1 =CreateBox ( 64, 64, &HFFFFFF )
BoxTemp1=CreateBuffer( 64*4, 64*4 )
BoxTemp2=CreateBuffer( 64*4, 64*4 )
RunWobbleWobble()
Sub RunWobbleWobble()
Dim As Integer WobAng
Dim Key As String
While Key<>Chr(27)
UpdateWobbleWobble( 0, 0, 1, 32, WobAng, Box1, BoxTemp1, BoxTemp2 )
DrawBuffer( 120, 120, BoxTemp2 )
PTC_Update @ScreenBuffer->Pixels[0]
WobAng+=2 : if WobAng>360 then WobAng=WobAng-360
Key=Inkey
ClearBuffer( ScreenBuffer )
ClearBuffers( BoxTemp1,_
BoxTemp2 )
Wend
End Sub
Sub clearbuffer( Byval buffer As gfxbuffer Pointer,_
ByVal Col As UInteger=0 )
Dim As UInteger Pointer pixel=buffer->pixels
Dim As UInteger Pointer last=pixel+(buffer->WWidth*buffer->Height)
while pixel<last
*pixel=col
pixel+=1
wend
End Sub
Sub clearbuffers( Byval buffer1 As gfxbuffer Pointer,_
ByVal buffer2 As gfxbuffer Pointer,_
ByVal Col As UInteger=0 )
Dim As UInteger Pointer pixel1=buffer1->Pixels, pixel2=buffer2->Pixels
Dim As UInteger Pointer last=pixel1+(buffer1->WWidth*buffer1->Height)
while pixel1<last
*pixel1=col
*pixel2=col
pixel1+=1
pixel2+=1
wend
End Sub
Sub UpdateWobbleWobble( ByVal PosX As Integer,_
ByVal PosY As Integer,_
ByVal Mult As Integer,_
ByVal Size As Integer,_
ByVal Angle As Integer,_
ByVal Source As gfxbuffer Pointer,_ )
ByVal Buffer1 As gfxbuffer Pointer,_)
ByVal Buffer2 As gfxbuffer Pointer )
Dim As Integer x,y
Dim As Integer CX, CY
'
' This works fine.
'
For y=0 to Source->Height-1
CX=( Source->Height\2 ) - (PosX+Cos(( Angle+y*Mult ) * ( D2R )) * ( Size-y*Size\Source->Height ) )'/ 2 )
DrawBufferRect( cx+PosX,_'+Cos( ( Angle+y*Mult ) * (PI/180) )*( Size-y*Size\Source->Height ),_
PosY+y,_
0,_
y,_
Source->WWidth,_
1,_
Source,_
Buffer1)
Next
'
' This is whats up??
'
For x=0 To Source->WWidth-1
CY=( Source->WWidth\2 ) - (PosY+Cos(( Angle+x*Mult ) * ( D2R )) * ( Size-x*Size\Source->WWidth ) )'/ 2 )
DrawBufferRect( PosX+x,_
cy+POsY,_'PosY+Sin( ( Angle+x*Mult ) * (PI/180) )*( Size-x*Size\Source->WWidth ),_
x,_
0,_
1,_
Source->Height,_
Buffer1,_
Buffer2)
Next
End Sub
Function CreateBox( ByVal WWidth As Integer,_
ByVal Height As Integer,_
ByVal Col As UInteger=0 ) As gfxbuffer Pointer
Dim buffer As gfxbuffer Pointer=CreateBuffer(WWidth,Height)
Dim As Integer x,y
For y=0 To Height-1
For x=0 To WWidth-1
Buffer->Pixels[ x+y*WWidth ]=Col
Next
Next
Return Buffer
End Function
Sub DrawBuffer( ByVal PosX As Integer, ByVal PosY As Integer, ByVal Buffer As gfxbuffer Pointer )
Dim As Integer x,y
For y=0 To Buffer->Height-1
For x=0 To Buffer->WWidth-1
ScreenBuffer->Pixels[ (x+PosX)+(y+PosY) * ScreenBuffer->WWidth ]=Buffer->Pixels[ x+y*Buffer->WWidth ]
Next
Next
End Sub
Sub DrawBufferRect( ByVal PosX As Integer,_
ByVal PosY As Integer,_
ByVal RectX As Integer,_
ByVal RectY As Integer,_
ByVal RectWWidth As Integer,_
ByVal RectHeight As Integer,_
ByVal Buffer As gfxBuffer Pointer,_
ByVal Dest As gfxBuffer Pointer )
Dim As Integer x,y
For y=0 to rectheight-1
For x=0 To rectwwidth-1
Dest->Pixels[ ( x+PosX ) + ( y+PosY ) * Dest->WWidth ]=Buffer->Pixels[ ( x+RectX ) + ( y+RectY ) * Buffer->WWidth ]
Next
Next
End Sub
Function CreateBuffer( ByVal WWidth As Integer, ByVal Height As Integer) As gfxbuffer pointer
Dim As gfxbuffer Pointer Buffer=Callocate( Len(gfxbuffer)+Len(UInteger)*WWidth*Height)
Buffer->WWidth=WWidth
Buffer->Height=Height
Buffer->Pixels=Cast( UInteger Pointer, Cast( Byte Pointer, buffer )+Len( gfxbuffer ))
Return Buffer
End function
Function graphics( Byval Title As String, ByVal WWidth As Integer, ByVal Height As Integer ) As gfxbuffer Pointer
ptc_open( Title, WWidth, Height )
Return createbuffer(WWidth,Height)
End Function
Big thanks for you help in correcting it and cheers,
Clyde.
Hey Clyde,
I had a play with this, and got it to work as you expect.
'
' This is whats up??
'
For x=0 To Source->WWidth-1 + 70
I just added +70 to the line above, and it works fine.
Nice effect.
Ah ok will try that out! :)
Cheers buddy*2 :D
Yay! That does in fact work, but however only in that configuration. Trying different box sizes. So still a tad stuck on this.
Cheers for any clues,
Clyde.
If it crashes when you change it Clyde you are certainly drawing off the screen.
As for fixing it, there are several different methods you could use to achieve the effect with different levels of accuracy and performance and cheating.
The cheating method is to precalculate one complete pass of either the x or y wave so that you only have to sine the resulting image one way.
Or.. make a cheap linear texture mapping routine and divide the picture up into a grid and map it onto a sine grid (could look shit if your grid is low res).
You could look at Tetra's water effect source that you used in your Brimstone demo to study how he implimented the gel map, you could use that code to achieve the flag effect you want too.
If you're still stuck on Saturday when I have a little time I'll see what I can code for you :)
Thanks for your reply; and I'd love to see what you can come up with over the weekend - If the method above wont work. I would like to get the approach I am using with the DrawImageRect to work firstly, as its driving me nuts at the moment. :D
Cheers,
Clyde.
Ok, well if you are determined to do it that way, what you need is a routine that draws slices of pictures, please could you post here if you don't fix it by Friday and I'll make something that does the job for you :)
Will do dude, and much appreciated.
actually http://www.dbfinteractive.com/gravity/demos/GVY-Brimstone.zip (http://www.dbfinteractive.com/gravity/demos/GVY-Brimstone.zip) returns a 404
Here it is Moroboshisan, I attached it to this post.
:) 10x
Has anybody had problems running the brimstone demo? For some reason just quits out my machine (running Vista!).
DrewPee
It runs ok on my computer (Vista Home Premium, 32bit)
Runs great here on XP,too. What a great demo. Love it!
on my pc brimstone demo took a huge amount of time to start, but it finally runs quite fine! really nice water effect tho! thumb up!!
Quote from: Clyde on February 03, 2009
Yay! That does in fact work, but however only in that configuration. Trying different box sizes. So still a tad stuck on this.
Cheers for any clues,
Clyde.
Have you got this working yet?
Your original box changes size when "wobbled" into buffer1. You then need to use these new dimensions when performing the second wobble into buffer2. At the moment you are using the original box size when performing the second wobble.
Regarding the crashes, as Shockwave points out, you are most likely drawing outside the bounds of one of these buffers. If the sin and cos wobble functions are known, you could figure out how big your buffers need to be and centre your drawing within them.
Thanks Voltage dude, and thankyou for your interest buddy.
I have got this working now. And what you've mentioned above is something that I wasn't thinking too straight on. It's amazing what a new day and a fresh mind for thinking can do. I have an added excuse too, I havent been trying to code for for about 3 even 4 monhs.
What im a little fuzzy wuzzy on, is how to get the exact buffer sizes; at the moment I think I have a method that will only work for one type of sine, and thats to use the Size of the sinewave added to the width and height of the box buffer. I may have sussed it completely, will have to experiment somemore.
Cheers and thanks for your interest dude,
Clyde.
My pleasure.
Regarding getting the exact size of the buffers.... You would only need to prepare a buffer that is big enough. I mean, the only no no, is a buffer that is too small. So exactness is not really required. A rough estimate on size +20% or something similar might work.
Its a bit cludgy I know, and it would be the most optimized method, but it would work.
Besides, based on the quality of your other work, and the fact that you got this algorithm this far, I'm sure you'll sort it out.
Let us know how it goes.