summaryrefslogtreecommitdiff
path: root/examples/fast_tilemap/main.lua
diff options
context:
space:
mode:
Diffstat (limited to 'examples/fast_tilemap/main.lua')
-rw-r--r--examples/fast_tilemap/main.lua103
1 files changed, 103 insertions, 0 deletions
diff --git a/examples/fast_tilemap/main.lua b/examples/fast_tilemap/main.lua
new file mode 100644
index 0000000..da7fdbf
--- /dev/null
+++ b/examples/fast_tilemap/main.lua
@@ -0,0 +1,103 @@
+--[[
+ We can use mesh to draw tilemap in one draw call.
+ On large maps you could devide the tilemap in sections to cull tiles that are not
+ in view.
+--]]
+
+package.path = package.path..";"..RL.GetBasePath().."../resources/lib/?.lua"
+
+Util = require( "utillib" )
+Vector2 = require( "vector2" )
+Vector3 = require( "vector3" )
+
+QUAD = {
+ VERTICES = {
+ Vector3:new( 0, 0, 0 ), Vector3:new( 0, 1, 0 ), Vector3:new( 1, 1, 0 ),
+ Vector3:new( 0, 0, 0 ), Vector3:new( 1, 1, 0 ), Vector3:new( 1, 0, 0 )
+ },
+ TEXCOORDS = {
+ Vector2:new( 0, 0 ), Vector2:new( 0, 1 ), Vector2:new( 1, 1 ),
+ Vector2:new( 0, 0 ), Vector2:new( 1, 1 ), Vector2:new( 1, 0 )
+ },
+}
+
+local res = Vector2:new( 1024, 720 )
+local winScale = 1
+local winSize = res:scale( winScale )
+local monitor = 0
+
+local tilemap = {
+ texture = nil,
+ texSize = Vector2:new(),
+ mesh = nil,
+ material = nil,
+ tileSize = 32,
+ tilecount = 0,
+}
+
+local function setTile( meshData, pos, texcoord )
+ local texelSize = Vector2:new( 1 / tilemap.texSize.x, 1 / tilemap.texSize.y )
+
+ for i, v in ipairs( QUAD.VERTICES ) do
+ table.insert( meshData.vertices, ( pos + v ):scale( tilemap.tileSize ) )
+ table.insert( meshData.texcoords, ( QUAD.TEXCOORDS[i] + texcoord ) * texelSize:scale( tilemap.tileSize ) )
+ table.insert( meshData.colors, RL.WHITE )
+ end
+
+ tilemap.tilecount = tilemap.tilecount + 1
+end
+
+local function genTilemap()
+ local meshData = { vertices = {}, texcoords = {}, colors = {} }
+ -- Ground.
+ for x = 0, winSize.x / tilemap.tileSize do
+ for y = 0, winSize.y / tilemap.tileSize do
+ setTile( meshData, Vector2:new( x, y ), Vector2:new( 4, 0 ) )
+ end
+ end
+ -- House. Will be overdrawn to ground but we don't care we are so efficient! (You should though.)
+ for x = 0, 6 do
+ for y = 0, 10 do
+ local tilePos = Vector2:new( x, y ) + Vector2:new( 8, 6 )
+
+ if ( x == 0 or x == 6 or y == 0 or y == 10 ) and y ~= 4 then
+ setTile( meshData, tilePos, Vector2:new( 0, 0 ) )
+ else
+ setTile( meshData, tilePos, Vector2:new( 1, 0 ) )
+ end
+ end
+ end
+ -- Characters. You probably would not do this, but we do it here to get some variation.
+ setTile( meshData, Vector2:new( 4, 3 ), Vector2:new( 3, 0 ) )
+ setTile( meshData, Vector2:new( 8, 4 ), Vector2:new( 3, 1 ) )
+ setTile( meshData, Vector2:new( 10, 8 ), Vector2:new( 1, 1 ) )
+
+ tilemap.mesh = RL.GenMeshCustom( meshData, false )
+end
+
+function RL.init()
+ local monitorPos = Vector2:newT( RL.GetMonitorPosition( monitor ) )
+ local monitorSize = Vector2:newT( RL.GetMonitorSize( monitor ) )
+
+ RL.SetWindowTitle( "Fast tilemap" )
+ RL.SetWindowState( RL.FLAG_WINDOW_RESIZABLE )
+ RL.SetWindowState( RL.FLAG_VSYNC_HINT )
+ RL.SetWindowSize( winSize )
+ RL.SetWindowPosition( { monitorPos.x + monitorSize.x / 2 - winSize.x / 2, monitorPos.y + monitorSize.y / 2 - winSize.y / 2 } )
+
+ local path = RL.GetBasePath().."../resources/images/tiles.png"
+
+ tilemap.texture = RL.LoadTexture( path )
+ tilemap.texSize:setT( RL.GetTextureSize( tilemap.texture ) )
+
+ tilemap.material = RL.LoadMaterialDefault()
+ RL.SetMaterialTexture( tilemap.material, RL.MATERIAL_MAP_ALBEDO, tilemap.texture )
+
+ genTilemap()
+end
+
+function RL.draw()
+ RL.ClearBackground( RL.BLACK )
+ RL.DrawMesh( tilemap.mesh, tilemap.material, RL.MatrixIdentity() )
+ RL.DrawText( "Tile count: "..tostring( tilemap.tilecount ), { 3, 3 }, 20, RL.GREEN )
+end