BM 1.35 - Virtual Resolution - Viewport rendering

Archives Forums/BlitzMax Bug Reports/BM 1.35 - Virtual Resolution - Viewport rendering

Armitage 1982(Posted 2009) [#1]
Hi,

There is rounding imprecisions when sizing and positioning viewport while using Virtual Resolution.

Last vertical and horizontal lines of pixels in viewport are most of the time omitted.
This has an impact on the positioning within the viewport.

I also post some missing functions compatible with the virtual feature in case you miss them.

SetGraphicsDriver GLMax2DDriver()

Graphics(640, 480)
SetVirtualResolution(1024.0, 768.0)

Local CW:Float = 250.0
Local CH:Float = 141.0

SetBlend(LIGHTBLEND)
SetAlpha(0.75)

While Not KeyHit(KEY_ESCAPE)
	
	' Press SPACE to cycle various virtual resolution
	If KeyHit(KEY_SPACE)
		Select VirtualResolutionWidth()
			Case 1280.0
				SetVirtualResolution(640.0, 480.0)
			Case 1024.0
				SetVirtualResolution(1280.0, 1024.0)
			Case 640.0
				SetVirtualResolution(800.0, 600.0)
			Case 800.0
				SetVirtualResolution(1024.0, 768.0)
		End Select
	End If
	
	If KeyHit(KEY_ENTER)
		If CW = 250.0
			CW = 320.0
			CH = 240.0
		Else
			CW = 250.0
			CH = 141.0
		End If
	EndIf
	
	Cls()

	SetColor(128, 128, 255)
	drawCamera(VirtualMouseX(), VirtualMouseY(), CW, CH)
	
	'Draw the viewport in the middle of the screen
	SetColor(128, 255, 128)
	drawCamera((VirtualResolutionWidth() - CW) / 2.0, (VirtualResolutionHeight() - CH) / 2.0, CW, CH)
	
	'Draw the viewport at 0,0
	SetColor(255, 128, 128)
	drawCamera(0.0, 0.0, CW, CH)

	SetColor(255, 255, 255)
	drawCamera(0.0, 0.0, VirtualResolutionWidth(), VirtualResolutionHeight())

	SetScale(VirtualResolutionWidth() / GraphicsWidth(), VirtualResolutionHeight() / GraphicsHeight ())
	DrawText("Press SPACE to cycle virtual resolution and ENTER to change camera size", 10.0, 10.0)
	DrawText("Virtual Resolution:" + Int(VirtualResolutionWidth()) + "x" + Int(VirtualResolutionHeight()), 10.0, 32.0)
	SetScale(1.0, 1.0)
	
	Flip()
	
Wend


Rem
bbdoc: Simply draw a viewport Camera with border line
End Rem
Function drawCamera(camX:Float, camY:Float, camWidth:Float, camHeight:Float)

	SetVirtualViewport(camX, camY, camWidth, camHeight)
	
	' Reset View Port Origin for Layer Rendering
	SetOrigin (camX, camY)

	DrawLine(0.0, 0.0, camWidth - 1.0, 0.0)
	DrawLine(0.0, 0.0, 0.0, camHeight - 1.0)
	DrawLine(0.0, camHeight - 1.0, camWidth - 1.0, camHeight - 1.0)
	DrawLine(camWidth - 1.0, 0.0, camWidth - 1.0, camHeight - 1.0)

End Function


Rem
bbdoc: Set Virtual drawing viewport
about:
The current ViewPort defines an area within the back buffer that all drawing is clipped to. Any
regions of a DrawCommand that fall outside the current Virtual ViewPort are not drawn.
End Rem
Function SetVirtualViewport(X:Int, Y:Int, Width:Int, Height:Int)
	
	Local gcw:Float = VirtualResolutionWidth() / GraphicsWidth()
	Local gch:Float = VirtualResolutionHeight() / GraphicsHeight()
	
	X:/gcw
	Y:/gch
	Width:/gcw
	Height:/gch
	
	SetViewport(X, Y, Width, Height)
	
End Function

Rem
bbdoc: Get Virtual dimensions of current Viewport.
returns: The horizontal, vertical, width and height values of the current Virtual Viewport in the variables supplied.
End Rem
Function GetVirtualViewport(X:Int Var, Y:Int Var, Width:Int Var, Height:Int Var)

	Local gcw:Float = VirtualResolutionWidth() / GraphicsWidth()
	Local gch:Float = VirtualResolutionHeight() / GraphicsHeight()

	GetViewport(X, Y, Width, Height)

	X:*gcw
	Y:*gch
	Width:*gcw
	Height:*gch
	
End Function


Rem
bbdoc: Grab an image from the back buffer with Virtual support
about:
Copies pixels from the back buffer to an image frame.

Only images created with the DYNAMICIMAGE flag can be grabbed.
End Rem
Function VirtualGrabImage(image:TImage, X:Int, Y:Int, Frame:Int = 0)

	Local gcr:Int, gcg:Int, gcb:Int
	GetMaskColor(gcr, gcg, gcb)
	
	Local gcw:Float = VirtualResolutionWidth() / GraphicsWidth()
	Local gch:Float = VirtualResolutionHeight() / GraphicsHeight()
	Local pixmap:TPixmap = _max2dDriver.GrabPixmap(X / gcw, Y / gch, image.width / gcw, image.Height / gch)
	
	If image.flags&MASKEDIMAGE 
		pixmap = MaskPixmap(pixmap, gcr, gcg, gcb)
	EndIf
	
	image.SetPixmap(Frame, pixmap)
	
End Function


It's nearly impossible to correctly draw a viewport in the middle of the screen.


skidracer(Posted 2009) [#2]
As pointed out in your other thread, you are using the number 1.0 in your code to represent 1 pixel, which it doesn't.

The viewport command is documented as using integer arguments so there is no bug in it's behavior either.