summaryrefslogtreecommitdiff
path: root/client/drawing2.lua
blob: aade7d51189d73ce36df0afc99a1ff0d0c7d31a8 (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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
local CHUNK_SIZE = require"common.constants".CHUNK_SIZE
local coords = require"common.coords"

local tau = 2*math.pi

-- funny hexagon
local vertices = {}
-- v[1] {0,0}, fill
-- v[2-7] edge, fill
-- v[8-13] inner, outline
-- v[14-19] outer, outline
local map = {}

do
	local function ix(n) return n%6 end
	local function th(n) return tau*(ix(n)+0.5)/6 end
	local cos,sin = math.cos,math.sin
	local OLWIDTH = 0.11
	local hw = OLWIDTH/2
	local ri,ro = 1-hw,1+hw
	local function ve(n,f) return {cos(th(n)),sin(th(n)), f} end
	local function vi(n,f) return {ri*cos(th(n)),ri*sin(th(n)), f} end
	local function vo(n,f) return {ro*cos(th(n)),ro*sin(th(n)), f} end
	local function apv(...)
		for _,x in ipairs({...}) do table.insert(vertices,x) end
	end
	local function apm(...)
		for _,x in ipairs({...}) do table.insert(map,x) end
	end

	vertices[1] = {0,0, 1}
	for n=0,5 do apv(ve(n,1)) end
	for n=0,5 do apv(vi(n,0)) end
	for n=0,5 do apv(vo(n,0)) end

	-- fill area
	for n=0,5 do apm(1, 2+n, 2+ix(1+n) ) end

	local function ii(n) return 8+ix(n) end
	local function oi(n) return 14+ix(n) end

	-- outline area
	for n=0,5 do
		apm( ii(n), oi(n), oi(n+1) )
		apm( ii(n), oi(n+1), ii(n+1) )
	end
end

local shape_mesh = love.graphics.newMesh({
	{"VertexPosition","float",2},
	{"fillness","float",1},
},vertices,"triangles","static")
shape_mesh:setVertexMap(map)

local function c(...) return {love.math.colorFromBytes(...)} end
-- taken from breadquest
local colors = {
	{0,0,0},
	c(255,64,64),	-- red
	c(255,128,0),	-- orange
	c(192,192,64),	-- yellow
	c(0,192,0),		-- green
	c(0,192,192),	-- teal
	c(64,64,255),	-- blue
	c(192,0,192),	-- purple
	c(128,128,128),	-- grey

	c(0xe7,0x9e,0), -- ubqorange
}

local shader = love.graphics.newShader([[
#pragma language glsl3

const mat2 hex_to_pos = mat2( sqrt(3), 0, sqrt(3)/2, 1.5);
#define CHUNK_SIZE ]]..tostring(CHUNK_SIZE)..[[.0


uniform vec3 colors[10];

uniform float zoom;

attribute float tile_type;
attribute float fillness;

varying vec4 tcol;

const float zthr0 = 2.7;
const float zthr1 = 6;
const float zthrd = zthr1-zthr0;

vec4 position(mat4 transform_projection, vec4 vertex_position)
{


	vec2 instance_pos = vec2(
		floor(love_InstanceID/CHUNK_SIZE),
		mod(love_InstanceID, CHUNK_SIZE)  );
	vertex_position.xy += hex_to_pos * instance_pos;

	float a = clamp( (zoom-zthr0)/zthrd, 0, 1);
	a = max(fillness, a);

	int tidx = int(tile_type);
	tcol = (tidx == 0) ? vec4(0.0) : vec4(fillness*colors[tidx], a);


	return transform_projection * vertex_position;
}
]],[[
#pragma language glsl3

varying vec4 tcol;
vec4 effect(vec4 color, Image tex,
	vec2 texture_coords, vec2 screen_coords)
{
	// return vec4(tcol.xyz,0.5);
	return tcol;
}
]])

shader:send("colors",unpack(colors))


local function set_imesh(im)
	shape_mesh:detachAttribute("tile_type")
	shape_mesh:attachAttribute("tile_type",im,"perinstance")
end

local function draw_map(camera,map) -- luacheck: no redefined
	shader:send("zoom",camera.zoom)
	love.graphics.setShader(shader)

	local cam_tl,cam_br = camera:extents()

	local count = CHUNK_SIZE*CHUNK_SIZE
	for _,ch in map:iter_chunks() do
		if ch then
			-- todo: skip chunks that aren't on screen, maybe
			local htl,hbr = ch.cp:extents()
			local tl = htl:to_pos()
			local br = hbr:to_pos()

			if br.x < cam_tl.x or cam_br.x < tl.x
					or br.y < cam_tl.y or cam_br.y < tl.y
				then
					-- definitely not visible on screen
					-- this does not catch every single nonvisible chunk
					goto next
			end

			set_imesh(ch.imesh)
			love.graphics.drawInstanced(shape_mesh, count, tl.x, tl.y)
		end
		::next::
	end

	love.graphics.setShader()
end




return {draw_map=draw_map}