From 41a7a40ecf71613c6cb3f7823491c45d9c9c63e0 Mon Sep 17 00:00:00 2001 From: ubq323 Date: Thu, 23 Feb 2023 11:53:10 +0000 Subject: implement new rendering system using gpu instancing this has extremely better performance on my machine also, player is circle now --- client/drawing2.lua | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 client/drawing2.lua (limited to 'client/drawing2.lua') diff --git a/client/drawing2.lua b/client/drawing2.lua new file mode 100644 index 0000000..e09d7dc --- /dev/null +++ b/client/drawing2.lua @@ -0,0 +1,144 @@ +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) + shader:send("zoom",camera.zoom) + love.graphics.setShader(shader) + + 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() + + set_imesh(ch.imesh) + love.graphics.drawInstanced(shape_mesh, count, tl.x, tl.y) + end + end + + love.graphics.setShader() +end + + + + +return {draw_map=draw_map} -- cgit v1.2.3