graphics artifacts : black lines using camerazoom

Started by RemiD, May 16, 2021, 18:49:19

Previous topic - Next topic

RemiD

hi :)

yesterday i have tested my game "hidden items searcher finder" on a laptop with Windows 10 OS.

everything worked well, except the spyglass effect (using camerazoom).
when using camerazoom, the graphics were messed up with black lines and it was impossible to see correctly the environment, (like a spyglass effect is supposed to do)

i have to ideas to create an alternative way to produce a similar zoom effect :
-method A : by positionning the camera, farer forward the player (+Z local position corresponding to zoom value)
-method B : by copyrecting a small area of the rendered scene, around the center of screen (depending on the zoom value, and stretching this captured image on a quad which fills the screen, with obviously some blur effect because of the lower resolution of the captured image, compared to the resolution of the screen)

not sure, i will post some examples soon.

RemiD

well, method A does not produce a convincing zoom/spyglasse effect, imo (compared to the original CameraZoom())...

see :

;graphics window
Global GWidth% = 640 : Global GHeight% = 360
Graphics3D(GWidth,GHeight,32,2)

hidepointer()

SeedRnd(MilliSecs())

;FONTS, IMAGES, MESHES, TEXTURES, JOINTS/BONES, ANIMATIONS, SOUNDS
;---------------------------------------------------------------------------------------

Global X20Font = LoadFont("System",20,False,False,False)

Global XCube = CreateCube() : ScaleMesh(XCube,1.0/2,1.0/2,1.0/2) : PositionMesh(XCube,0,1.0/2,0)

;---------------------------------------------------------------------------------------

;Input
Global MX%
Global MY%
Global MXDiff%
Global MYDiff%

;Origine
Global Origine = CreateCube()
ScaleMesh(Origine,0.01,0.01,0.01)
EntityColor(Origine,255,000,255)
EntityFX(Origine,1)

;Camera
Global Camera = CreateCamera()
CameraViewport(Camera,0,0,GraphicsWidth(),GraphicsHeight())
CameraRange(Camera,0.15,150)
CameraClsColor(Camera,000,000,000)

;Ghost
Global Ghost_Root
Global Ghost_RootYaw#
Global Ghost_Eyes
Global Ghost_EyesPitch#
AddGhost()

;Terrain
Terrain = CreateCube()
ScaleMesh(Terrain,100.0/2,0.1/2,100.0/2)
PositionMesh(Terrain,100.0/2,-0.1/2,100.0/2)
EntityColor(Terrain,255,255,255)
EntityFX(Terrain,1)

;Cubes
For GX% = 0 To 99 Step 1
For GZ% = 0 To 99 Step 1
  C% = Rand(1,100)
  If( C = 1 )
   Cube = CopyEntity(XCube)
   EntityColor(Cube,Rand(025,255),Rand(025,255),Rand(025,255))
   PositionEntity(Cube,GX+0.5,0,GZ+0.5,True)
  EndIf
Next
Next

;Spyglass
Global Spyglass_Image = CreateImage(GWidth,GHeight)
SetBuffer(ImageBuffer(Spyglass_Image))
ClsColor(012,012,012) :Cls()
PWidth% = GHeight : PHeight% = GHeight
PX% = GWidth/2-PWidth/2 : PY% = 0
Color(000,000,000) : Oval(PX,PY,PWidth,PHeight,True)

Global Zoom# = 1.0

Global Zoom_RenderMode% = 1

;light
DLight = CreateLight(1)
LightColor(DLight,255,255,255)
PositionEntity(DLight,50,1000,-1000,True)
RotateEntity(DLight,45,0,0,True)

AmbientLight(025,025,025)

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

Global MainLoopTimer = CreateTimer(30)

Main()

End()

Function Main()

Repeat

  MainLoopMilliStart% = MilliSecs()

  MX = MouseX() : MY = MouseY()

  MXDiff = MouseXSpeed() : MYDiff = MouseYSpeed()

UpdateGhost()

  ;update zoom
  Zoom = 1.0
  If( KeyDown(57)=1 ) ;key SPACE
   Zoom = 10.0
  EndIf

  ;update zoom_rendermode   
  If( KeyHit(56)=1 ) ;key ALT
   If( Zoom_RenderMode = 1 )
    Zoom_RenderMode = 2
   Else If( Zoom_RenderMode = 2 )
    Zoom_RenderMode = 1
   EndIf
  EndIf

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

  PositionEntity(Camera,EntityX(Ghost_Eyes,True),EntityY(Ghost_Eyes,True),EntityZ(Ghost_Eyes,True),True)
  RotateEntity(Camera,EntityPitch(Ghost_Eyes,True),EntityYaw(Ghost_Eyes,True),EntityRoll(Ghost_Eyes,True),True)

  If( Zoom_RenderMode = 1 )
   CameraZoom(Camera,Zoom)
  Else If( Zoom_RenderMode = 2 )
   CameraZoom(Camera,1.0)
   If( Zoom = 1.0 )
    MoveEntity(Camera,0,0,0)
   Else If( Zoom = 10.0 )
    MoveEntity(Camera,0,0,10.0)
   EndIf
  EndIf

  CameraViewport(Camera,0,0,GraphicsWidth(),GraphicsHeight())
  CameraClsColor(Camera,160,160,192)
  SetBuffer(BackBuffer())
  RenderWorld()
 
  If( Zoom = 1.0 )
   ;
  Else If( Zoom = 10.0 )
   DrawImage(Spyglass_Image,0,0)
  EndIf

  SetFont(X20Font) : Color(250,250,250)
  CText("Tris = "+TrisRendered(),0,0)
  CText("FPS = "+FPS,0,20)

  CText(Zoom,GWidth/2,0)
  CText(Zoom_RenderMode,GWidth/2,20)

  ;Flip(1)
  WaitTimer(MainLoopTimer)
  VWait():Flip(False)

  MainLoopMilliTime = MilliSecs() - MainLoopMilliStart
  If( MainLoopMilliTime < 1 )
   MainLoopMilliTime = 1
  EndIf

  FPS% = 1000.0/MainLoopMilliTime

Until( KeyDown(1)=1 )

End Function

Function CText(TextStr$,PX%,PY%)

Text(PX,PY,TextStr,False,False)

End Function

Function AddGhost()

Ghost_Root = CreatePivot()

Ghost_Eyes = CreatePivot()
EntityParent(Ghost_Eyes,Ghost_Root,True)

End Function

Function UpdateGhost()

MoveMouse(GraphicsWidth()/2,GraphicsHeight()/2)
Ghost_EyesPitch = Ghost_EyesPitch + Float(MYDiff)/10
If( Ghost_EyesPitch < -89 )
  Ghost_EyesPitch = -89
Else If( Ghost_EyesPitch > 89 )
  Ghost_EyesPitch = 89
EndIf
RotateEntity(Ghost_Eyes,Ghost_EyesPitch,0,0,False)
Ghost_RootYaw = Ghost_RootYaw - Float(MXDiff)/10
RotateEntity(Ghost_Root,0,Ghost_RootYaw,0,False)

If( KeyDown(42) = 0 And KeyDown(29) = 0 )
  Speed# = 0.1
Else If( KeyDown(42) = 1 And KeyDown(29) = 0 )
  Speed# = 1
Else If( KeyDown(42) = 0 And KeyDown(29) = 1 )
  Speed# = 0.01
EndIf

If( KeyDown(17)=1 )
  MoveEntity(Ghost_Root,0,0,Speed)
Else If( KeyDown(31)=1 )
  MoveEntity(Ghost_Root,0,0,-Speed)
EndIf
If( KeyDown(30)=1 )
  MoveEntity(Ghost_Root,-Speed,0,0)
Else If( KeyDown(32)=1 )
  MoveEntity(Ghost_Root,Speed,0,0)
EndIf
If( KeyDown(16)=1 )
  MoveEntity(Ghost_Root,0,-Speed,0)
Else If( KeyDown(18)=1 )
  MoveEntity(Ghost_Root,0,Speed,0)
EndIf

End Function


i am going to try with method B...

RemiD

method B behaves exactly the same as camerazoom() :D , but looks pixelated (because the texture is stretched on an area (10 times) bigger than the rendered area...


;graphics window
Global GWidth% = 640 : Global GHeight% = 360
Graphics3D(GWidth,GHeight,32,2)

SeedRnd(MilliSecs())

HidePointer()

;FONTS, IMAGES, MESHES, TEXTURES, JOINTS/BONES, ANIMATIONS, SOUNDS
;---------------------------------------------------------------------------------------

Global X20Font = LoadFont("System",20,False,False,False)

Global XCube = CreateCube() : ScaleMesh(XCube,1.0/2,1.0/2,1.0/2) : PositionMesh(XCube,0,1.0/2,0)

Global Screen_Mesh = CreateMesh()
Surface = CreateSurface(Screen_Mesh)
AddVertex(Surface,-1.0,+0.5625,0.0) : VertexTexCoords(Surface,0,(1024.0/2-Float(GWidth)/2)/1024,(1024.0/2-Float(GHeight)/2)/1024)
AddVertex(Surface,+1.0,+0.5625,0.0) : VertexTexCoords(Surface,1,(1024.0/2+Float(GWidth)/2)/1024,(1024.0/2-Float(GHeight)/2)/1024)
AddVertex(Surface,-1.0,-0.5625,0.0) : VertexTexCoords(Surface,2,(1024.0/2-Float(GWidth)/2)/1024,(1024.0/2+Float(GHeight)/2)/1024)
AddVertex(Surface,+1.0,-0.5625,0.0) : VertexTexCoords(Surface,3,(1024.0/2+Float(GWidth)/2)/1024,(1024.0/2+Float(GHeight)/2)/1024)
AddTriangle(Surface,0,1,2)
AddTriangle(Surface,2,1,3)
UpdateNormals(Screen_Mesh)
EntityColor(Screen_Mesh,255,255,255)
EntityFX(Screen_Mesh,1)

Global Screen_Tex = CreateTexture(1024,1024,1+256)
SetBuffer(TextureBuffer(Screen_Tex))
ClsColor(000,000,000) : Cls()
Color(125,125,125) : Rect(1024/2-GWidth/2,1024/2-GHeight/2,GWidth,GHeight,True)
Color(255,000,000) : Plot(1024/2-GWidth/2+1,1024/2-GHeight/2+1)
Color(000,255,000) : Plot(1024/2+GWidth/2-1,1024/2-GHeight/2+1)
Color(000,000,255) : Plot(1024/2-GWidth/2+1,1024/2+GHeight/2-1)
Color(255,255,000) : Plot(1024/2+GWidth/2-1,1024/2+GHeight/2-1)
TextureBlend(Screen_Tex,1)
EntityTexture(Screen_Mesh,Screen_Tex)

Global Screen_Scale# = 10.0
ScaleEntity(Screen_Mesh,Screen_Scale,Screen_Scale,Screen_Scale)

;---------------------------------------------------------------------------------------

;input
Global MX%
Global MY%
Global MXDiff%
Global MYDiff%

;origine
Global Origine = CreateCube()
ScaleMesh(Origine,0.01,0.01,0.01)
EntityColor(Origine,255,000,255)
EntityFX(Origine,1)

;camera
Global Camera = CreateCamera()
CameraViewport(Camera,0,0,GraphicsWidth(),GraphicsHeight())
CameraRange(Camera,0.15,150)
CameraClsColor(Camera,000,000,000)

;ghost
Global Ghost_Root
Global Ghost_RootYaw#
Global Ghost_Eyes
Global Ghost_EyesPitch#
AddGhost()

PositionEntity(Screen_Mesh,EntityX(Camera,True),EntityY(Camera,True),EntityZ(Camera,True),True)
RotateEntity(Screen_Mesh,EntityPitch(Camera,True),EntityYaw(Camera,True),EntityRoll(Camera,True),True)
MoveEntity(Screen_Mesh,0,0,+1.0)
EntityParent(Screen_Mesh,Camera,True)

;world
Global World = CreatePivot()

;terrain
Terrain = CreateCube()
ScaleMesh(Terrain,100.0/2,0.1/2,100.0/2)
PositionMesh(Terrain,100.0/2,-0.1/2,100.0/2)
EntityColor(Terrain,255,255,255)
EntityFX(Terrain,1)
EntityParent(Terrain,World,True)

;cubes
For GX% = 0 To 99 Step 1
For GZ% = 0 To 99 Step 1
  C% = Rand(1,100)
  If( C = 1 )
   Cube = CopyEntity(XCube)
   EntityColor(Cube,Rand(025,255),Rand(025,255),Rand(025,255))
   PositionEntity(Cube,GX+0.5,0,GZ+0.5,True)
   EntityParent(Cube,World,True)
  EndIf
Next
Next

;spyglass
Global Spyglass_Image = CreateImage(GWidth,GHeight)
SetBuffer(ImageBuffer(Spyglass_Image))
ClsColor(012,012,012) :Cls()
PWidth% = GHeight : PHeight% = GHeight
PX% = GWidth/2-PWidth/2 : PY% = 0
Color(000,000,000) : Oval(PX,PY,PWidth,PHeight,True)

Global Zoom# = 1.0

Global Zoom_RenderMode% = 1

;light
DLight = CreateLight(1)
LightColor(DLight,255,255,255)
PositionEntity(DLight,50,1000,-1000,True)
RotateEntity(DLight,45,0,0,True)

AmbientLight(025,025,025)

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

Global MainLoopTimer = CreateTimer(30)

Main()

End()

Function Main()

Repeat

  MainLoopMilliStart% = MilliSecs()

  MX = MouseX() : MY = MouseY()

  MXDiff = MouseXSpeed() : MYDiff = MouseYSpeed()

  UpdateGhost()

  ;update zoom
  Zoom = 1.0
  If( KeyDown(57)=1 ) ;key SPACE
   Zoom = 10.0
  EndIf

  ;update zoom_rendermode   
  If( KeyHit(45)=1 ) ;key X
   Zoom_RenderMode = Zoom_RenderMode + 1 : If( Zoom_RenderMode > 2 ) : Zoom_RenderMode = 2 : EndIf
  Else If( KeyHit(44)=1 ) ;key Z/W
   Zoom_RenderMode = Zoom_RenderMode - 1 : If( Zoom_RenderMode < 1 ) : Zoom_RenderMode = 1 : EndIf
  EndIf

  PositionEntity(Camera,EntityX(Ghost_Eyes,True),EntityY(Ghost_Eyes,True),EntityZ(Ghost_Eyes,True),True)
  RotateEntity(Camera,EntityPitch(Ghost_Eyes,True),EntityYaw(Ghost_Eyes,True),EntityRoll(Ghost_Eyes,True),True)

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

  HideEntity(Screen_Mesh)
  If( Zoom_RenderMode = 1 ) ;zoom by using camerazoom
   ShowEntity(World)
   CameraZoom(Camera,Zoom)
  Else If( Zoom_RenderMode = 2 ) ;zoom by copyrecting a small area around the center of the rendered screen, and stretching it on a screen mesh
   ShowEntity(World)
   CameraZoom(Camera,1.0)
   If( Zoom = 1.0 )
    HideEntity(Screen_Mesh)
   Else If( Zoom = 10.0 )
    HideEntity(Screen_Mesh)
    SetBuffer(BackBuffer())
    RenderWorld()
    CopyRect(0,0,GWidth,GHeight,1024/2-GWidth/2,1024/2-GHeight/2,BackBuffer(),TextureBuffer(Screen_Tex))
    HideEntity(World)
    ShowEntity(Screen_Mesh)
   EndIf
  EndIf

  CameraViewport(Camera,0,0,GraphicsWidth(),GraphicsHeight())
  CameraClsColor(Camera,160,160,192)
  SetBuffer(BackBuffer())
  RenderWorld()
 
  If( Zoom = 1.0 )
   ;
  Else If( Zoom = 10.0 )
   DrawImage(Spyglass_Image,0,0)
  EndIf

  SetFont(X20Font) : Color(250,250,250)
  CText("Tris = "+TrisRendered(),0,0)
  CText("FPS = "+FPS,0,20)

  CText(Zoom,GWidth/2,0)
  CText(Zoom_RenderMode,GWidth/2,20)
  CText(Screen_Scale,GWidth/2,40)

  ;Flip(1)
  WaitTimer(MainLoopTimer)
  VWait():Flip(False)

  MainLoopMilliTime = MilliSecs() - MainLoopMilliStart
  If( MainLoopMilliTime < 1 )
   MainLoopMilliTime = 1
  EndIf

  FPS% = 1000.0/MainLoopMilliTime

Until( KeyDown(1)=1 )

End Function

Function CText(TextStr$,PX%,PY%)

Text(PX,PY,TextStr,False,False)

End Function

Function AddGhost()

Ghost_Root = CreatePivot()

Ghost_Eyes = CreatePivot()
EntityParent(Ghost_Eyes,Ghost_Root,True)

End Function

Function UpdateGhost()

MoveMouse(GraphicsWidth()/2,GraphicsHeight()/2)
Ghost_EyesPitch = Ghost_EyesPitch + Float(MYDiff)/10
If( Ghost_EyesPitch < -89 )
  Ghost_EyesPitch = -89
Else If( Ghost_EyesPitch > 89 )
  Ghost_EyesPitch = 89
EndIf
RotateEntity(Ghost_Eyes,Ghost_EyesPitch,0,0,False)
Ghost_RootYaw = Ghost_RootYaw - Float(MXDiff)/10
RotateEntity(Ghost_Root,0,Ghost_RootYaw,0,False)

If( KeyDown(42) = 0 And KeyDown(29) = 0 )
  Speed# = 0.1
Else If( KeyDown(42) = 1 And KeyDown(29) = 0 )
  Speed# = 1
Else If( KeyDown(42) = 0 And KeyDown(29) = 1 )
  Speed# = 0.01
EndIf

If( KeyDown(17)=1 )
  MoveEntity(Ghost_Root,0,0,Speed)
Else If( KeyDown(31)=1 )
  MoveEntity(Ghost_Root,0,0,-Speed)
EndIf
If( KeyDown(30)=1 )
  MoveEntity(Ghost_Root,-Speed,0,0)
Else If( KeyDown(32)=1 )
  MoveEntity(Ghost_Root,Speed,0,0)
EndIf
If( KeyDown(16)=1 )
  MoveEntity(Ghost_Root,0,-Speed,0)
Else If( KeyDown(18)=1 )
  MoveEntity(Ghost_Root,0,Speed,0)
EndIf

End Function


camerazoom() looks better, but this is a good workaround in case of a compatibility problem with some graphics cards...