Page 1 of 2
Posted: Sat Sep 16, 2006 3:31 am
by chris_b
Here's an example to show what I mean (the 64x64 PNG I used can be downloaded
here)
Code: Select all
UsePNGImageDecoder()
Structure vertex
sx.f
sy.f
sz.f
rhw.f
color.l
specular.l
tu.f
tv.f
EndStructure
Structure PB_Sprite3D
Texture.l ; DirectX7 surface
Vertice.vertex[4] ; The 4 vertices for the rectangle sprite
Width.w
Height.w
EndStructure
InitSprite()
InitSprite3D()
OpenScreen(640,480,32,"example")
CatchSprite(0,?bitmap,#PB_Sprite_Texture | #PB_Sprite_AlphaBlending)
CreateSprite3D(0,0)
ZoomSprite3D(0,64,64)
CreateSprite3D(1,0)
ZoomSprite3D(1,64,64)
*sprite.PB_Sprite3D=IsSprite3D(1)
Sprite3DQuality(1)
x.f=0
Repeat
x=x+0.05
If x>576
x=0
EndIf
f.f=x-Round(x,0)
*sprite\Vertice[0]\sx=f
*sprite\Vertice[1]\sx=64+f
*sprite\Vertice[2]\sx=f
*sprite\Vertice[3]\sx=64+f
ClearScreen(RGB(0,0,64))
Start3D()
DisplaySprite3D(0,x,0,255)
DisplaySprite3D(1,Round(x,0),64,255)
Stop3D()
FlipBuffers()
Until GetAsyncKeyState_($1B)
CloseScreen()
End
DataSection
bitmap:
IncludeBinary("test.png")
EndDataSection
The top sprite jumps a whole pixel every 20 frames - the x position is rounded to the nearest pixel. The bottom sprite show how it would look with my proposed feature request - the sprite moves smoothly.
Posted: Sat Sep 16, 2006 6:16 pm
by Kale
I've never noticed that before.

Posted: Sat Sep 23, 2006 11:05 pm
by Steve Elliott
Floats and doubles are ignored for positioning? I'm about to convert some code into a PureBASIC engine I'm developing, and if this is as bad as it seems I might need to re-think my use of PureBASIC.
This has serious implications for smooth movement in games - a major priority Fred.

Posted: Fri Oct 06, 2006 4:57 pm
by Psychophanta
Steve Elliott wrote:This has serious implications for smooth movement in games - a major priority Fred.

Only when movements are slower than (DisplayedFramesPerSecond)*pixel/second.
Usually, when movements are slower than 30 pixel/second.
But i second this request, of course!
Posted: Fri Oct 06, 2006 5:52 pm
by dracflamloc
third, i wondered why my scrolling maps seemed to move kind of jerky...
Posted: Thu Nov 09, 2006 11:00 am
by Kale
Any news on this issue Fred?
Re: Sprite3D functions to accept floats
Posted: Mon Jan 15, 2007 2:15 pm
by nco2k
chris_b wrote:Presumably with both DirectX and OpenGL the various parameters for positioning, rotating and transforming Sprite3Ds will be converted to floating point values anyway - so there's no reason for Sprite3D functions not to accept floats for these parameters.
i second the request, but what about 2d sprites?? are they meant to accept floats for positioning aswell?? would be cool.
c ya,
nco2k
Posted: Mon Jan 15, 2007 2:36 pm
by Kaeru Gaman
2D sprites only consist of complete pixel.
there is no smoothing between the pixels.
according to this, 2D sprites only can positioned on full pixels,
so there is no use for float-parameters.
concerning float parameters for Sprite3D-commands:
would not only be a good idea, but its essetially.
maybe it was easier that way before PB supported Doubles,
but not it does, so the Sprite3D-Lib should be changed soon.
I think the 3D-features on Linux and on Mac support floats, too, don't they?
Re: Sprite3D functions to accept floats
Posted: Mon Nov 18, 2013 8:10 am
by skape
Very sorry to resurrect such an old thread (I couldn't find a newer one addressing this), but has this been added / changed as of PB 5.2x? It doesn't appear to be possible in the 5.20 demo. It's something that is somewhat important to me, to be able to draw sprites at non-whole number positions for smooth slow speed movement. Is there a good workaround if not? (Something mutiplatform...)
Thanks!

Re: Sprite3D functions to accept floats
Posted: Mon Nov 18, 2013 10:18 am
by Fred
You can't draw sprite at a non-whole number position as in PB the base unit is the pixel and you can't have an half pixel. Just you float if you need slow motion and it will display it slower, on pixel basis.
Re: Sprite3D functions to accept floats
Posted: Mon Nov 18, 2013 12:01 pm
by STARGÅTE
Fred wrote:You can't draw sprite at a non-whole number position as in PB the base unit is the pixel and you can't have an half pixel. Just you float if you need slow motion and it will display it slower, on pixel basis.
You
can.
TransformSprite() accept floats, so you can make move on sub pixel base, like in this example.
On top the normal DisplaySprite, on bottom the sub pixel move with TransformSprite().
Code: Select all
InitSprite()
UsePNGImageDecoder()
Enumeration
#Window
#Sprite
EndEnumeration
OpenWindow(#Window, 0, 0, 300, 300, "Sprite", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(#Window), 0, 0, WindowWidth(#Window), WindowHeight(#Window), 0, 0, 0)
SpriteQuality(#PB_Sprite_BilinearFiltering)
CreateSprite(#Sprite, 32, 32)
StartDrawing(SpriteOutput(#Sprite))
Box(10, 1, 2, 30, $FF8080)
Box(16, 1, 2, 30, $80FF80)
Box(22, 1, 2, 30, $8080FF)
Line(1, 16, 30, 1, $FFFFFF)
StopDrawing()
Define Start = ElapsedMilliseconds()
Define X.f
Repeat
Repeat
Select WindowEvent()
Case #PB_Event_CloseWindow
End
Case #Null
Break
EndSelect
ForEver
ClearScreen(0)
X = 50+(ElapsedMilliseconds()-Start)/1000
ZoomSprite(#Sprite, 32, 32)
DisplaySprite(#Sprite, X, X)
TransformSprite(#Sprite, X, X+50, X+SpriteWidth(#Sprite), X+50, X+SpriteWidth(#Sprite), X+50+SpriteHeight(#Sprite), X, X+50+SpriteHeight(#Sprite))
DisplaySprite(#Sprite, 0, 0)
FlipBuffers()
ForEver
Re: Sprite3D functions to accept floats
Posted: Mon Nov 18, 2013 12:34 pm
by Fred
Now that's interesting, always something new to learn

.
ps: on my screen it looks a bit wierd, like a bit of intensity change when being between pixels (I guess it's GFX card interpolations to emulate this)
Re: Sprite3D functions to accept floats
Posted: Mon Nov 18, 2013 2:51 pm
by STARGÅTE
Fred wrote:ps: on my screen it looks a bit wierd, like a bit of intensity change when being between pixels (I guess it's GFX card interpolations to emulate this)
This is the SpriteQuality(#PB_Sprite_BilinearFiltering), so there is a linear fitting between two texture pixels.
Bilinear means, a white sub-pixel and a black sub-pixel gets a gray full pixel (intensity change)
If you change it to #PB_Sprite_NoFiltering, you can't see this fitting.
Re: Sprite3D functions to accept floats
Posted: Mon Nov 18, 2013 3:00 pm
by luis
Fred wrote:
ps: on my screen it looks a bit wierd, like a bit of intensity change when being between pixels (I guess it's GFX card interpolations to emulate this)
It's due to the bilinear filtering. Just change SpriteQuality to #PB_Sprite_NoFiltering and this does not work anymore.
In fact it's not the same image drawn when using subpixel movement, or it would not be possible to move something composed by pixels by less than a pixel when the physical screen resolution is a pixel. The filtering change the pixels colors and give a simil-antialiased illusion of smaller movements and cause the weird effect you are seeing.
Also, if you change the sprite to this one:
Code: Select all
StartDrawing(SpriteOutput(#Sprite))
Box(0, 0, 32, 32, $FF0000)
StopDrawing()
does not work even with the filtering active.
EDIT: Well, too late

Re: Sprite3D functions to accept floats
Posted: Mon Nov 18, 2013 3:39 pm
by skape
@STARGÅTE, yep, exactly what I'm asking about. I thought that enabling bilinear filtering would do it for DisplaySprite(), but thanks for the TransformSprite() tip.
Too bad using RotateSprite() or ZoomSprite(), etc. resets the previous matrix transformations..
@Fred, yeah, I know you can send a float and it will round to the nearest pixel, but IMO this looks worse for
certain sprites (not all), than interpolating. The GFX card is basically changing the alpha of image pixels depending on "how much" they are in a physical pixel, so it actually looks good with sprites that already have an antialiased edge to them. (The GFX card is already essentially doing this when transforming image pixels to other resolutions than native.)
EDIT:
It also helps movement appear smoother at fast speeds:
With this image:
Code: Select all
InitSprite()
UsePNGImageDecoder()
Enumeration
#Window
#Sprite
EndEnumeration
OpenWindow(#Window, 0, 0, 300, 300, "Sprite", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(#Window), 0, 0, WindowWidth(#Window), WindowHeight(#Window), 0, 0, 0)
SpriteQuality(#PB_Sprite_BilinearFiltering)
;CreateSprite(#Sprite, 32, 32)
; StartDrawing(SpriteOutput(#Sprite))
; Box(10, 1, 2, 30, $FF8080)
; Box(16, 1, 2, 30, $80FF80)
; Box(22, 1, 2, 30, $8080FF)
; Line(1, 16, 30, 1, $FFFFFF)
; StopDrawing()
LoadSprite(#Sprite, "circle.png", #PB_Sprite_AlphaBlending)
Define Start = ElapsedMilliseconds()
Define X.f
Define delta.f
Repeat
Repeat
Select WindowEvent()
Case #PB_Event_CloseWindow
End
Case #Null
Break
EndSelect
ForEver
delta = (ElapsedMilliseconds() - Start)/1000
Start = ElapsedMilliseconds()
ClearScreen($FFFFFF)
X = X+9*delta
ZoomSprite(#Sprite, 32, 32)
DisplayTransparentSprite(#Sprite, X, X)
TransformSprite(#Sprite, X, X+50, X+SpriteWidth(#Sprite), X+50, X+SpriteWidth(#Sprite), X+50+SpriteHeight(#Sprite), X, X+50+SpriteHeight(#Sprite))
DisplayTransparentSprite(#Sprite, 0, 0)
FlipBuffers()
ForEver