Page 1 of 1

Sprite 3D small deformation... is it a fault?

Posted: Wed Jan 07, 2004 1:49 pm
by Psychophanta
Could be a Engine3D.dll small bug?
If try next example, in my screen appears sprite a little bit deformed when near X=0 or Y=0.
It can be noticed when X (or Y) coordenate is from 26 to 32:

Code: Select all

If InitMouse()=0 Or InitSprite()=0 Or InitSprite3D()=0 Or InitKeyboard()=0
  MessageRequester("Error","Can't open DirectX",0)
  End
EndIf
#bitplanes=32:#RX=1024:#RY=768
#BallsDiameter=76
If OpenScreen(#RX,#RY,#bitplanes,"Balls")=0:End:EndIf
CreateSprite(0,#BallsDiameter,#BallsDiameter,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(0))
BackColor(0,0,0):Circle(#BallsDiameter/2,#BallsDiameter/2,#BallsDiameter/2,$9dfe00)
StopDrawing()
CreateSprite3D(0,0):ZoomSprite3D(0,#BallsDiameter,#BallsDiameter)
CentreX=SpriteWidth(0)/2:CentreY=SpriteHeight(0)/2;<-centro de Objeto1

Repeat
  ExamineKeyboard()
  ExamineMouse()
  ClearScreen(0,0,0)
  Start3D()
  mousex=MouseX():mousey=MouseY()
  DisplaySprite3D(0,mousex-#BallsDiameter/2,mousey-#BallsDiameter/2,255)
  Stop3D()
  StartDrawing(ScreenOutput())
  Locate(200,200):DrawText("X = "+Str(mousex)+" ; Y = "+Str(mousey))
  StopDrawing()
  FlipBuffers()
Until KeyboardPushed(#PB_Key_All)
CloseScreen()
End

Posted: Wed Jan 07, 2004 2:03 pm
by Danilo
Sprite3D have nothing to do with the 3D-Engine.

But you are right anyway, looks like there is an clipping problem.
Its that the Sprite is 1 pixel smaller painted in Width and Height.

Posted: Thu Jan 08, 2004 9:23 pm
by chris_b
The Sprite3D seems to be created 1 pixel too big.

Here is a version of your code without the ZoomSprite3D() command, and using a box instead of a ball to illustrate the problem more clearly:

Code: Select all

If InitMouse()=0 Or InitSprite()=0 Or InitSprite3D()=0 Or InitKeyboard()=0 
  MessageRequester("Error","Can't open DirectX",0) 
  End 
EndIf 
#bitplanes=16:#RX=640:#RY=480 
#BallsDiameter=128 

If OpenScreen(#RX,#RY,#bitplanes,"Balls")=0:End:EndIf 
CreateSprite(1,#BallsDiameter,#BallsDiameter,#PB_Sprite_Texture) 
CreateSprite3D(1,1)
StartDrawing(SpriteOutput(1)) 
Line(0,0,#BallsDiameter,0,RGB(255,255,0))
Line(0,#BallsDiameter-1,#BallsDiameter,0,RGB(255,255,0))
Line(0,0,0,#BallsDiameter,RGB(255,255,0))
Line(#BallsDiameter-1,0,0,#BallsDiameter,RGB(255,255,0))
StopDrawing()

;RotateSprite3D(1, 0, 0)

Repeat 
  ExamineKeyboard() 
  ExamineMouse() 
  mousex=MouseX():mousey=MouseY()
  ClearScreen(0,0,64) 
  DisplaySprite(1,128,128)
  Start3D() 
 
  DisplaySprite3D(1,mousex-#BallsDiameter/2,mousey-#BallsDiameter/2,255) 
  Stop3D() 
  StartDrawing(ScreenOutput()) 
  StopDrawing() 
  FlipBuffers() 
  
Until KeyboardPushed(#PB_Key_Escape) 
CloseScreen() 
End
The ordinary sprite which is drawn on the screen is the correct size (128x128 pixels) but the sprite3d is 129x129 pixels.

Also, the RotateSprite3D(1, 0, 0) seems wrong to me, shouldn't this reset the sprite3d to it's original size and have no rotation?

Posted: Thu Jan 08, 2004 11:33 pm
by Psychophanta
Mmmh, your example doesn't show the same problem, i guess.

I thing that when you create a 3D sprite, you must always Zoom it to the desired size, because to adjust it. Just zooming it, the problem is vanished.
I mean adding this after creating the Sprite:

Code: Select all

ZoomSprite3D(1,#BallsDiameter,#BallsDiameter) 
Also, the RotateSprite3D(1, 0, 0) seems wrong to me, shouldn't this reset the sprite3d to it's original size and have no rotation?
You are right! But Sprite 3D is supposed to be a 3D textured image, but not very exact 2D lines, i guess... :?

Posted: Fri Jan 09, 2004 12:50 am
by chris_b
Psychophanta wrote:Mmmh, your example doesn't show the same problem, i guess.

I thing that when you create a 3D sprite, you must always Zoom it to the desired size, because to adjust it. Just zooming it, the problem is vanished.
The problem isn't vanished for me: if I add the ZoomSprite3D(1,#BallsDiameter,#BallsDiameter) line to my code like you suggest, then I see the clipping/deformation problem that you originally desscribed - ie. the right edge and bottom edges of my box dissappear when the sprite overlaps the left and top of the screen respectively.

And if I remove the ZoomSprite3D() function from your code, your clipping/deformation problem dissappears but the ball has a duplicate line added to the top and left of the sprite - like with my box example.

That is why I think these are two facets of the same underlying problem - I think that the problem of your deformed balls is somehow connected to the problem of a sprite3d being created at the wrong size.

Anyway, even if this is two different problems it would be nice if sprite3d worked correctly - many cool things are possible with PureBasic's sprite3d functions so it would be a shame if it can't be fixed.

Posted: Fri Jan 09, 2004 10:42 am
by Psychophanta
The problem isn't vanished for me: if I add the ZoomSprite3D(1,#BallsDiameter,#BallsDiameter) line to my code like you suggest, then I see the clipping/deformation problem that you originally desscribed - ie. the right edge and bottom edges of my box dissappear when the sprite overlaps the left and top of the screen respectively.
Oh! i have not this problem with your example, i see always the entire square :o
And if I remove the ZoomSprite3D() function from your code, your clipping/deformation problem dissappears but the ball has a duplicate line added to the top and left of the sprite - like with my box example.
Samething happens here, but i think this is normal if Sprite is not zoomed.

AL

Posted: Fri Jan 09, 2004 7:43 pm
by chris_b
Psychophanta wrote:Oh! i have not this problem with your example, i see always the entire square
Maybe your graphics card resizes the 129x129 sprite3d to 128x128 differently to mine. But I think it is still a problem that the sprite3d is created 1 pixel too large in the first place - shouldn't need to use ZoomSprite3D() to make it the "correct" size.

What happens with my box if you use #BallsDiameter=76 like in your original example?

Posted: Fri Jan 09, 2004 11:01 pm
by Psychophanta
What happens with my box if you use #BallsDiameter=76 like in your original example?
Exactly the same, but squares smaller.
Tested with and without ZoomSprite3D(1,#BallsDiameter,#BallsDiameter), and with and without RotateSprite3D(1, 0, 0).
Here the same behaviour than with #BallsDiameter=128.

Posted: Sat Jan 10, 2004 2:44 am
by chris_b
Thanks to Danilo's cool sprite3D functions I managed to make a solution (well it works for me anyway). Here is a version of your original code, please try it and let me know if it works on your system also:

Code: Select all

#bitplanes=32:#RX=1024:#RY=768 
#BallsDiameter=76 

Structure D3DTLVERTEX
  StructureUnion      ; Screen coordinates
    sx.f
    dvSX.f
  EndStructureUnion
  StructureUnion
    sy.f
    dvSY.f
  EndStructureUnion
  StructureUnion
    sz.f
    dvSZ.f
  EndStructureUnion
  StructureUnion      ; Reciprocal of homogeneous w
    rhw.f
    dvRHW.f
  EndStructureUnion
  StructureUnion      ; Vertex color
    color.l
    dcColor.l
  EndStructureUnion
  StructureUnion      ; Specular component of vertex
    specular.l
    dcSpecular.l
  EndStructureUnion
  StructureUnion      ; Texture coordinates
    tu.f
    dvTU.f
  EndStructureUnion
  StructureUnion
    tv.f
    dvTV.f
  EndStructureUnion
EndStructure

Structure PB_Sprite3D
  Texture.l
  Vertice.D3DTLVERTEX[4]
  Width.w
  Height.w
EndStructure

Procedure Sprite3DTextureFix(sprite)

  *p.PB_Sprite3D
  !extrn _PB_Sprite3D_ObjectsArea
  !MOV  dword EBX,[_PB_Sprite3D_ObjectsArea]
  !MOV  dword EAX,136
  !MUL  dword [ESP]
  !ADD  dword EBX,EAX
  !MOV  dword [ESP+4],EBX

ushift.f=0.001
vshift.f=0.001

For n=0 To 3
*p\vertice[n]\tu=*p\vertice[n]\tu+ushift
*p\vertice[n]\tv=*p\vertice[n]\tv+vshift
Next

EndProcedure

If InitMouse()=0 Or InitSprite()=0 Or InitSprite3D()=0 Or InitKeyboard()=0 
  MessageRequester("Error","Can't open DirectX",0) 
  End 
EndIf 

If OpenScreen(#RX,#RY,#bitplanes,"Balls")=0:End:EndIf 
CreateSprite(0,#BallsDiameter,#BallsDiameter,#PB_Sprite_Texture) 
StartDrawing(SpriteOutput(0)) 
BackColor(0,0,0):Circle(#BallsDiameter/2,#BallsDiameter/2,#BallsDiameter/2,$9dfe00) 
StopDrawing() 
CreateSprite3D(0,0)
Sprite3DTextureFix(0)
ZoomSprite3D(0,#BallsDiameter,#BallsDiameter) 
CentreX=SpriteWidth(0)/2:CentreY=SpriteHeight(0)/2;<-centro de Objeto1 

Repeat 
  ExamineKeyboard() 
  ExamineMouse() 
  ClearScreen(0,0,0) 
  Start3D() 
  mousex=MouseX():mousey=MouseY() 
  DisplaySprite3D(0,mousex-#BallsDiameter/2,mousey-#BallsDiameter/2,255) 
  Stop3D() 
  StartDrawing(ScreenOutput()) 
  Locate(200,200):DrawText("X = "+Str(mousex)+" ; Y = "+Str(mousey)) 
  StopDrawing() 
  FlipBuffers() 
Until KeyboardPushed(#PB_Key_All) 
CloseScreen() 
End
My "solution" was to shift the texture on the sprite by a very small amount (0.001) - this amount was arrived at mainly by trial and error so it may not work for all situations (I don't really understand why it works at all :? ), but maybe it will help towards fixing the problem properly.

Posted: Sat Jan 10, 2004 11:03 am
by Psychophanta
Yes! your example works now here, no deformation.
ThanX :)