diff options
Diffstat (limited to 'examples/fast_tilemap/main.lua')
| -rw-r--r-- | examples/fast_tilemap/main.lua | 103 |
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 |
