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:
BlitzMax + MiniB3D:
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?
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?