Ooops
September 24, 2021, 10:18:42

Author Topic: help : error somewhere to position a quad precisely at MouseX,MouseY  (Read 453 times)

Offline RemiD

  • Hero Member
  • *****
  • Posts: 1282
hi !

i am trying to create a code example for our friend "RonTek" at blitzcoder.org

the goal is to be able to create / position a textured rectangle mesh like a rectangle image.

i have almost managed to do it, but there is an error somewhere and the rectangle mesh is positioned with some "lag". i wonder if this is due to a mistake in my code or because of float precision ?

if somebody can take a look :
Code: [Select]
;IElement (rectangle+text made / drawn with a image) vs QElement (rectangle+text made / positionned with a textured mesh)
;by RemiD (2021/03/14)
;there is an error somewhere which produces a "lag" when positioning the QElement...

Global GWidth% = 800
Global GHeight% = 600
Graphics3D(GWidth,GHeight,32,2)

Global Cam = CreateCamera()
CameraViewport(Cam,0,0,GWidth,GHeight)
CameraRange(Cam,0.09,99)

Shape = CreateCube() : ScaleMesh(Shape,1.0/2,1.0/2,1.0/2)
PositionEntity(Shape,0,0,0,True)

DLight = CreateLight(1) : LightColor(DLight,220,220,220)
PositionEntity(DLight,0,1000,-1000,True) : RotateEntity(DLight,45,0,0,True)
AmbientLight(025,025,025)

Arial16Font = LoadFont("Arial",16,True,False,False)
SetFont(Arial16Font)

;IElements list (rects made using images)
Global IElementsCount%
Dim IElement_Image(10)
Dim IElement_PWidth%(10)
Dim IElement_PHeight%(10)

;create a IElement
IStr$ = "test text on IElement (image)" : IWidth% = 10+StringWidth(IStr)+10 : IHeight% = 10+StringHeight(IStr)+10
DebugLog(IWidth)
DebugLog(IHeight)
I% = CreateIElement(IWidth,IHeight,220,220,120,IStr,030,030,030)

;QElements list (rects made using meshes + textures)
Global QElementsCount%
Dim QElement_Mesh(10)
Dim QElement_PWidth%(10)
Dim QElement_PHeight%(10)
;Dim QElement_Tex(10)

;create a QElement
QStr$ = "test text on QElement (textured mesh)" : QWidth% = 10+StringWidth(QStr)+10 : QHeight% = 10+StringHeight(QStr)+10
DebugLog(QWidth)
DebugLog(QHeight)
I% = CreateQElement(QWidth,QHeight,220,120,220,QStr,030,030,030)

PositionEntity(Cam,0,1.65,-5,True)

MoveMouse(GWidth/2,GHeight/2)

Repeat

 MX% = MouseX() : MY% = MouseY()

 TurnEntity(Shape,0,1,0)

 If( KeyDown(30)=1 )
  TurnEntity(Cam,0,+1,0)
 Else If( KeyDown(32)=1 )
  TurnEntity(Cam,0,-1,0)
 EndIf
 If( KeyDown(16)=1 )
  TurnEntity(Cam,+1,0,0)
 Else If( KeyDown(18)=1 )
  TurnEntity(Cam,-1,0,0)
 EndIf
 If( KeyDown(17)=1 )
  MoveEntity(Cam,0,0,+0.1)
 Else If( KeyDown(31)=1 )
  MoveEntity(Cam,0,0,-0.1)
 EndIf

 I% = 1
 DrawQElement(I,MX,MY+QElement_PHeight(I)/2+10) ;since a QElement is a mesh+texture, update position before renderworld
 ;PositionEntity(QElement_Mesh(I),0,1.5,0,True)

 WireFrame(False)
 If( KeyDown(2)=1 )
  WireFrame(True)
 EndIf

 SetBuffer(BackBuffer())
 RenderWorld()

 I% = 1
 DrawIElement(I,MX-IElement_PWidth(I)/2,MY-IElement_PHeight(I)-10) ;since a IElement is a image, update position / draw after renderworld

 Flip(1)

Until( KeyDown(1)=1 )

End

Function CreateIElement%(PWidth%,PHeight%,BackgroundR%=180,BackgroundG%=180,BackgroundB%=180,TextStr$,TextR%=030,TextG%=030,TextB%=030) ;return IElement index

 IElementsCount = IElementsCount + 1 : I% = IElementsCount

 IElement_PWidth(I) = PWidth : IElement_PHeight(I) = PHeight
 IElement_Image(I) = CreateImage(PWidth,PHeight)
 SetBuffer(ImageBuffer(IElement_Image(I)))
  Color(BackgroundR,BackgroundG,BackgroundB) : Rect(0,0,PWidth,PHeight,True)
  Color(TextR,TextG,TextB) : Text(10,10,TextStr)

 Return I

End Function

Function DrawIElement(I%,PX%,PY%)

 DrawImage(IElement_Image(I),PX,PY)

End Function

Function CreateQElement(PWidth%,PHeight%,BackgroundR%=180,BackgroundG%=180,BackgroundB%=180,TextStr$,TextR%=030,TextG%=030,TextB%=030) ;return QElement index

 QElementsCount = QElementsCount + 1 : I% = QElementsCount

 QElement_PWidth(I) = PWidth : QElement_PHeight(I) = PHeight

 XRatio# = 1.0 : YRatio# = Float(GHeight)/GWidth ;to correct the distortion since graphicswidth is usualy larger than graphicsheight...

 QElement_Mesh(I) = CreateMesh()
 Surface = CreateSurface(QElement_Mesh(I))
 AddVertex(Surface,-Float(PWidth)/Float(GWidth)*XRatio,+Float(PHeight)/Float(GHeight)*YRatio,1.0) : VertexTexCoords(Surface,0,Float(0)/256,Float(0)/64)
 AddVertex(Surface,+Float(PWidth)/Float(GWidth)*XRatio,+Float(PHeight)/Float(GHeight)*YRatio,1.0) : VertexTexCoords(Surface,1,Float(PWidth)/256,Float(0)/64)
 AddVertex(Surface,-Float(PWidth)/Float(GWidth)*XRatio,-Float(PHeight)/Float(GHeight)*YRatio,1.0) : VertexTexCoords(Surface,2,Float(0)/256,Float(PHeight)/64)
 AddVertex(Surface,+Float(PWidth)/Float(GWidth)*XRatio,-Float(PHeight)/Float(GHeight)*YRatio,1.0) : VertexTexCoords(Surface,3,Float(PWidth)/256,Float(PHeight)/64)
 AddTriangle(Surface,0,1,2)
 AddTriangle(Surface,2,1,3)
 ;UpdateNormals(QElement_Mesh(I))

 ;the texture must have its width and height power of 2 (16,32,64,128,256,512,1024,2048, etc...)
 ;for simplication i use a bigger texture than the area the text + margins will fill
 ;if you plan to draw many QElements, it would be better to use only 1 surface and 1 big texture for all QElements...
 QTex = CreateTexture(256,64,1+16+32)
 SetBuffer(TextureBuffer(QTex))
  Color(BackgroundR,BackgroundG,BackgroundB) : Rect(0,0,PWidth,PHeight,True)
  Color(TextR,TextG,TextB) : Text(10,10,TextStr)

 EntityFX(QElement_Mesh(I),1) ;Fx fullbright
 EntityTexture(QElement_Mesh(I),QTex)
 ;EntityOrder(QElement_Mesh(I),-999) ;-999 drawn after (on top of) everything else, +999 drawn before (below of) everything else

 Return I

End Function

Function DrawQElement(I%,PX%,PY%)

 XRatio# = 1.0 : YRatio# = Float(GHeight)/GWidth : Dist# = YRatio/10
 PositionEntity(QElement_Mesh(I),EntityX(Cam,True),EntityY(Cam,True),EntityZ(Cam,True),True)
 RotateEntity(QElement_Mesh(I),EntityPitch(Cam,True),EntityYaw(Cam,True),EntityRoll(Cam,True),True)
 MoveEntity(QElement_Mesh(I),-XRatio,+YRatio,Dist)
 OffsetX# = +Float(PX)/Float(GWidth)*2*XRatio : OffsetY# = -Float(PY)/Float(GHeight)*2*YRatio
 MoveEntity(QElement_Mesh(I),OffsetX,OffsetY,0)

End Function

thanks!
« Last Edit: March 14, 2021, 12:49:42 by RemiD »
DualCore AMD E-450, 1646 MHz - 6 Go DDR3 1333 SDRAM - AMD Radeon HD 6320 Graphics (384 Mo) - Windows 7 Home Premium - DirectX 11.0

Offline STEVIE G

  • Hero Member
  • *****
  • Posts: 608
To get the correct scaling, the easiest way is to initially put a plane in front of the camera, make it pickable and camera pick at 0,0 and 1,1 and the  scale is the diff between the two picks.. You can use this for scaling and position. Simple.

Offline RemiD

  • Hero Member
  • *****
  • Posts: 1282
Quote
To get the correct scaling, the easiest way is to initially put a plane in front of the camera, make it pickable and camera pick at 0,0 and 1,1 and the  scale is the diff between the two picks.. You can use this for scaling and position.
good idea, i am going to try, thanks

you position the plane at 0,0,+1 ? or ?
DualCore AMD E-450, 1646 MHz - 6 Go DDR3 1333 SDRAM - AMD Radeon HD 6320 Graphics (384 Mo) - Windows 7 Home Premium - DirectX 11.0

Offline STEVIE G

  • Hero Member
  • *****
  • Posts: 608
Quote
To get the correct scaling, the easiest way is to initially put a plane in front of the camera, make it pickable and camera pick at 0,0 and 1,1 and the  scale is the diff between the two picks.. You can use this for scaling and position.
good idea, i am going to try, thanks

you position the plane at 0,0,+1 ? or ?

Aye if your min camera range is 1. Remember to rotate it on pitch axis to face camera.  ;D

Offline peteswansen

  • Jr. Member
  • **
  • Posts: 68
why don't you just use a "cube" with a very small depth?  So much easier to move and rotate or turn...

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal