Terrain?

BlitzMax Modules Forums/MiniB3D/Terrain?

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

Okay, before I try anything, can somebody please explain to me why the following Blitz3D code is ten times faster than the equivalent BlitzMax + MiniB3d code when rendering a mesh? (You’ll need to provide a heightmap and a texture).

Blitz3D:

Graphics3D 800,600

SetBuffer BackBuffer()

Global Camera = CreateCamera()
PositionEntity Camera, 0, 200, -10
CameraRange Camera, 0.1, 1000.0

Local light = CreateLight(1)

Local tex = LoadTexture("tex.png")

Text 5, 5, "Loading terrain..."
Flip

Local Terrain = LoadMeshTerrain("hmap.png")

PositionEntity Terrain, 0, 0, 0
ScaleEntity Terrain, 10, 500, 10

EntityTexture Terrain, tex

Global MoveSpeed# = 5.0

Local old_ms = MilliSecs()
Local renders
Local fps

Global mxs#
Global mys#

While Not KeyHit(1)		

	Cls

	HandleInput

	RenderWorld

	renders = renders + 1

	If MilliSecs() -old_ms >= 1000
		old_ms = MilliSecs()
		fps = renders
		renders = 0
	EndIf

	Text 5, 5, "FPS: " + fps 

	Flip False

Wend

End

Function handleInput()
	
	mxs = mxs + (MouseXSpeed() / 3.0)
	mys = mys + (MouseYSpeed() / 3.0)

	RotateEntity Camera, mys, -mxs, 0

	MoveMouse GraphicsWidth() / 2, GraphicsHeight() / 2
		
	MouseXSpeed()
	MouseYSpeed()
		
	If KeyDown(200) Or KeyDown(17) Or MouseDown(2)
		MoveEntity Camera, 0.0, 0.0, MoveSpeed
	EndIf

	If KeyDown(208) Or KeyDown(31) 
		MoveEntity Camera, 0.0, 0.0, -MoveSpeed
	EndIf

	If KeyDown(32) Then MoveEntity Camera, MoveSpeed, 0.0, 0.0

	If KeyDown(30) Then MoveEntity Camera, -MoveSpeed, 0.0, 0.0
	
End Function		

;http://www.blitzbasic.com/Community/posts.php?topic=62118
Function LoadMeshTerrain(url$, parent = 0)

	Local img = LoadImage(url$)

	SetBuffer ImageBuffer(img)

	Local mesh = CreateMesh(parent)
	Local surf = CreateSurface(mesh)

	Local uscale# = 1.0 / ImageWidth(img)
	Local vscale# = 1.0 / ImageHeight(img)

	For x = 0 To ImageWidth(img) - 1
		For y = 0 To ImageHeight(img) - 1
		
			argb = ReadPixel(x, y)
			height# = (((argb Shl 16) And $FF) + ((argb Shl 8) And $FF) + (argb And $FF)) / (3.0 * 255.0)

			v = AddVertex(surf, x, height, y, x * uscale, y * vscale)
			VertexNormal surf, v, 0, 0, 0
			
		Next
	Next

	For x = 0 To ImageWidth(img) - 2
		For y = 0 To ImageHeight(img) - 2
		
			v0 = x * ImageHeight(img) + y
			v1 = v0 + 1
			v2 = v1 + ImageHeight(img)
			v3 = v0 + ImageHeight(img)
			
			t0 = AddTriangle(surf, v0, v1, v2)
			t1 = AddTriangle(surf, v0, v2, v3)

		Next
	Next

	For v = 0 To CountVertices(surf) - 1
		nx# = VertexNX(surf, v)
		ny# = VertexNY(surf, v)
		nz# = VertexNZ(surf, v)
		d# = 1.0 / Sqr(nx * nx + ny * ny + nz * nz)
		VertexNormal surf, v, nx * d, ny * d, nz * d
	Next

	UpdateNormals mesh

	SetBuffer BackBuffer()
	
	FreeImage img

	Return mesh

End Function








BlitzMax + MiniB3D:


SuperStrict

Import "c:\temp\MiniB3D-v041\minib3d.bmx"

Graphics3D 800,600

Global Camera:TCamera = CreateCamera()
PositionEntity Camera, 0, 200, -10
CameraRange Camera, 0.1, 1000.0

Local light:TLight = CreateLight(1)

Local tex:TTexture = LoadTexture("tex.png")

Text 5, 5, "Loading terrain..."
Flip

Local Terrain:TMesh = LoadTerrain("hmap.png")

PositionEntity Terrain, 0, 0, 0
ScaleEntity Terrain, 10, 500, 10

EntityTexture Terrain,tex

Global MoveSpeed:Float = 5.0

Local old_ms:Int = MilliSecs()
Local renders:Int
Local fps:Int

Global mxs:Float
Global mys:Float

While Not KeyDown(KEY_ESCAPE)		

	Cls

	HandleInput

	RenderWorld

	renders :+ 1

	If MilliSecs() -old_ms >= 1000
		old_ms = MilliSecs()
		fps = renders
		renders = 0
	EndIf

	Text 5, 5, "FPS: " + String(fps)

	Flip False

Wend

End

Function handleInput()
	
	mxs :+ (MouseXSpeed() / 3.0)
	mys :+ (MouseYSpeed() / 3.0)

	RotateEntity Camera, mys, -mxs, 0

	MoveMouse GraphicsWidth() / 2, GraphicsHeight() / 2
		
	MouseXSpeed()
	MouseYSpeed()
		
	If KeyDown(KEY_UP) Or KeyDown(KEY_W) Or MouseDown(2)
		MoveEntity Camera, 0.0, 0.0, MoveSpeed
	EndIf

	If KeyDown(KEY_DOWN) Or KeyDown(KEY_S) 
		MoveEntity Camera, 0.0, 0.0, -MoveSpeed
	EndIf

	If KeyDown(KEY_D) Then MoveEntity Camera, MoveSpeed, 0.0, 0.0

	If KeyDown(KEY_A) Then MoveEntity Camera, -MoveSpeed, 0.0, 0.0
	
EndFunction		

'http://www.blitzbasic.com/Community/posts.php?topic=62118
Function LoadTerrain:TMesh(url:Object, parent:TEntity = Null)

	Local pix:TPixmap

	If TPixmap(url)
		pix = TPixmap(url)
	Else
		pix = LoadPixmap(url)
		If pix = Null Return Null
	EndIf

	Local mesh:TMesh = CreateMesh(parent)
	Local surf:TSurface = CreateSurface(mesh, Null)

	Local uscale:Float = 1.0 / pix.width
	Local vscale:Float = 1.0 / pix.height

	For Local x:Int = 0 To pix.width - 1
		For Local y:Int = 0 To pix.height - 1
		
			Local argb:Int = pix.ReadPixel(x, y)
			Local height:Float = (((argb Shl 16) & $FF) + ((argb Shl 8) & $FF) + (argb & $FF)) / (3.0 * 255.0)

			Local v:Int = AddVertex(surf, x, height, y, x * uscale, y * vscale)
			VertexNormal surf, v, 0, 0, 0
			
		Next
	Next

	For Local x:Int = 0 To pix.width - 2
		For Local y:Int = 0 To pix.height - 2
		
			Local v0:Int = x * pix.height + y
			Local v1:Int = v0 + 1
			Local v2:Int = v1 + pix.height
			Local v3:Int = v0 + pix.height
			
			Local t0:Int = AddTriangle(surf, v0, v1, v2)
			Local t1:Int = AddTriangle(surf, v0, v2, v3)

		Next
	Next

	For Local v:Int = 0 Until CountVertices(surf)
		Local nx:Float = surf.VertexNX(v)
		Local ny:Float = surf.VertexNY(v)
		Local nz:Float = surf.VertexNZ(v)
		Local d:Float = 1.0 / Sqr(nx * nx + ny * ny + nz * nz)
		VertexNormal surf, v, nx * d, ny * d, nz * d
	Next

	UpdateNormals mesh

	Return mesh

End Function





128x128 heightmap gives me:

* Blitz3D: 700 fps approx
* BlitzMax + MiniB3D: 75 fps approx

System Specs: 1.6Ghz Centrino, 512MB ram, 128MB ATI Mobility Radeon X700

Debug and Release display the same speed difference.

Is it a DirectX vs OpenGL issue? MiniB3D’s architecture cannot handle large meshes as efficiently as Blitz3D? Am I doing something stupid?