summaryrefslogtreecommitdiff
path: root/examples/fast_tilemap/main.lua
blob: 4ba209cdfa3d33250581c4a584595af62bb49ae8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
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, ( Vector3:temp( pos.x + v.x, pos.y + v.y, 0 ) ):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