Basic grid shader as Godot line drawing is SLOW

This commit is contained in:
Luke Hubmayer-Werner 2020-05-23 02:52:12 +09:30
parent a1d11d6fb7
commit 292a4943a0
2 changed files with 112 additions and 36 deletions

View File

@ -1,7 +1,39 @@
[gd_scene load_steps=2 format=2] [gd_scene load_steps=4 format=2]
[ext_resource path="res://scripts/GameField.gd" type="Script" id=1] [ext_resource path="res://scripts/GameField.gd" type="Script" id=1]
[sub_resource type="Shader" id=1]
code = "shader_type canvas_item;
uniform float rows = 44.0; // Really int but don't want to recast all the time
uniform float cols = 63.0; // ^
void fragment(){
vec2 frag_pos = UV * vec2(cols, rows);
vec2 frag_marginal = fract(frag_pos+0.05);
vec2 grid_data = texture(TEXTURE, (frag_pos+0.05)/vec2(cols+1.0, rows+1.0)).rg;
COLOR = vec4(0.0);
if (frag_marginal.x < 0.1)
if (grid_data.g >= 0.99)
COLOR = vec4(1.0, 0.0, 0.0, 1.0);
else if (grid_data.g >= 0.49)
COLOR = vec4(0.0, 0.0, 1.0, 1.0);
else
COLOR = vec4(0.5, 0.5, 0.5, 1.0);
if (frag_marginal.y < 0.1)
if (grid_data.r >= 0.99)
COLOR = vec4(1.0, 0.0, 0.0, 1.0);
else if (grid_data.r >= 0.49)
COLOR = vec4(0.0, 0.0, 1.0, 1.0);
else
COLOR = vec4(0.5, 0.5, 0.5, 1.0);
}"
[sub_resource type="ShaderMaterial" id=2]
shader = SubResource( 1 )
shader_param/rows = 44.0
shader_param/cols = 63.0
[node name="Control" type="Control"] [node name="Control" type="Control"]
anchor_right = 1.0 anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
@ -23,3 +55,11 @@ script = ExtResource( 1 )
__meta__ = { __meta__ = {
"_edit_use_anchors_": false "_edit_use_anchors_": false
} }
[node name="TextureRect" type="TextureRect" parent="GameField"]
material = SubResource( 2 )
margin_top = -2.0
margin_right = 40.0
margin_bottom = 38.0
expand = true
stretch_mode = 1

View File

@ -14,13 +14,19 @@ onready var cell_numbers: ByteArray2D
const NUMBER_NONE := 255 const NUMBER_NONE := 255
onready var cell_colors: ByteArray2D onready var cell_colors: ByteArray2D
onready var corner_marks: IntArray2D onready var corner_marks: IntArray2D
var cell_image := Image.new()
var cell_texture := ImageTexture.new()
var grid_image := Image.new()
var grid_texture := ImageTexture.new()
enum UndoActions { enum UndoActions {
SET_L_RIGHT, SET_L_DOWN, SET_X_RIGHT, SET_X_DOWN, SET_L_RIGHT, SET_L_DOWN, SET_X_RIGHT, SET_X_DOWN,
CLEAR_L_RIGHT, CLEAR_L_DOWN, CLEAR_X_RIGHT, CLEAR_X_DOWN, CLEAR_L_RIGHT, CLEAR_L_DOWN, CLEAR_X_RIGHT, CLEAR_X_DOWN,
SET_COLOR SET_COLOR
} }
enum CornerMark { enum CornerMark {
L_RIGHT=1, L_DOWN=2, X_RIGHT=4, X_DOWN=8, L_RIGHT=1, X_RIGHT=2, L_DOWN=4, X_DOWN=8,
DARC_1=16, DARC_2=32, DARC_3=64, DARC_4=128, DARC_1=16, DARC_2=32, DARC_3=64, DARC_4=128,
SARC_1=256, SARC_2=512, SARC_3=1024, SARC_4=2048 SARC_1=256, SARC_2=512, SARC_3=1024, SARC_4=2048
} }
@ -60,6 +66,30 @@ func grid_corner(row, col) -> Vector2:
func to_grid_space(position: Vector2) -> Vector2: func to_grid_space(position: Vector2) -> Vector2:
return (position - grid_0)/grid_space return (position - grid_0)/grid_space
func regenerate_cell_texture() -> void:
# cell_image.create_from_data(rows, cols, false, Image.FORMAT_R8, cell_colors._array)
cell_image.create(cols, rows, false, Image.FORMAT_RGBA8)
cell_image.lock()
for row in rows:
for col in cols:
var color = COLORS[cell_colors.get_cell(row, col)]
if color != null:
cell_image.set_pixel(col, row, color)
cell_image.unlock()
cell_texture.create_from_image(cell_image, 0)
func regenerate_grid_texture() -> void:
# grid_image.create_from_data(rows, cols, false, Image.FORMAT_R8, cell_corners._array)
grid_image.create(cols+1, rows+1, false, Image.FORMAT_RGBA8)
grid_image.lock()
for row in rows+1:
for col in cols+1:
var flags = corner_marks.get_cell(row, col)
grid_image.set_pixel(col, row, Color(float(flags&3)/2.0, float((flags>>2)&3)/2.0, 0.0))
grid_image.unlock()
grid_texture.create_from_image(grid_image, 0)
$TextureRect.set_texture(grid_texture)
func _draw() -> void: func _draw() -> void:
if not READY: if not READY:
return return
@ -67,42 +97,48 @@ func _draw() -> void:
font.set_size(int(ceil(v_space-5))) font.set_size(int(ceil(v_space-5)))
# Colors # Colors
for row in rows: # for row in rows:
for col in cols: # for col in cols:
var color = COLORS[cell_colors.get_cell(row, col)] # var color = COLORS[cell_colors.get_cell(row, col)]
if color != null: # if color != null:
draw_rect(Rect2(grid_corner(row, col), Vector2(h_space, v_space)), color, true) # draw_rect(Rect2(grid_corner(row, col), Vector2(h_space, v_space)), color, true)
regenerate_cell_texture()
draw_texture_rect(cell_texture, Rect2(h0, v0, h_space*cols, v_space*rows), false)
# Lines # Lines
for row in rows: # for row in rows:
for col in cols: # for col in cols:
if corner_marks.get_flag(row, col, CornerMark.L_RIGHT): # if corner_marks.get_flag(row, col, CornerMark.L_RIGHT):
draw_line(grid_corner(row, col), grid_corner(row, col+1), Color.blue) # draw_line(grid_corner(row, col), grid_corner(row, col+1), Color.blue)
elif corner_marks.get_flag(row, col, CornerMark.X_RIGHT): # elif corner_marks.get_flag(row, col, CornerMark.X_RIGHT):
draw_line(grid_corner(row, col+0.4), grid_corner(row, col+0.6), Color.red) # draw_line(grid_corner(row, col+0.4), grid_corner(row, col+0.6), Color.red)
else: # else:
draw_line(grid_corner(row, col), grid_corner(row, col+1), Color.white) # draw_line(grid_corner(row, col), grid_corner(row, col+1), Color.white)
#
if corner_marks.get_flag(row, col, CornerMark.L_DOWN): # if corner_marks.get_flag(row, col, CornerMark.L_DOWN):
draw_line(grid_corner(row, col), grid_corner(row+1, col), Color.blue) # draw_line(grid_corner(row, col), grid_corner(row+1, col), Color.blue)
elif corner_marks.get_flag(row, col, CornerMark.X_DOWN): # elif corner_marks.get_flag(row, col, CornerMark.X_DOWN):
draw_line(grid_corner(row+0.4, col), grid_corner(row+0.6, col), Color.red) # draw_line(grid_corner(row+0.4, col), grid_corner(row+0.6, col), Color.red)
else: # else:
draw_line(grid_corner(row, col), grid_corner(row+1, col), Color.white) # draw_line(grid_corner(row, col), grid_corner(row+1, col), Color.white)
for col in cols: # for col in cols:
if corner_marks.get_flag(rows, col, CornerMark.L_RIGHT): # if corner_marks.get_flag(rows, col, CornerMark.L_RIGHT):
draw_line(grid_corner(rows, col), grid_corner(rows, col+1), Color.blue) # draw_line(grid_corner(rows, col), grid_corner(rows, col+1), Color.blue)
elif corner_marks.get_flag(rows, col, CornerMark.X_RIGHT): # elif corner_marks.get_flag(rows, col, CornerMark.X_RIGHT):
draw_line(grid_corner(rows, col+0.4), grid_corner(rows, col+0.6), Color.red) # draw_line(grid_corner(rows, col+0.4), grid_corner(rows, col+0.6), Color.red)
else: # else:
draw_line(grid_corner(rows, col), grid_corner(rows, col+1), Color.white) # draw_line(grid_corner(rows, col), grid_corner(rows, col+1), Color.white)
for row in rows: # for row in rows:
if corner_marks.get_flag(row, cols, CornerMark.L_DOWN): # if corner_marks.get_flag(row, cols, CornerMark.L_DOWN):
draw_line(grid_corner(row, cols), grid_corner(row+1, cols), Color.blue) # draw_line(grid_corner(row, cols), grid_corner(row+1, cols), Color.blue)
elif corner_marks.get_flag(row, cols, CornerMark.X_DOWN): # elif corner_marks.get_flag(row, cols, CornerMark.X_DOWN):
draw_line(grid_corner(row+0.4, cols), grid_corner(row+0.6, cols), Color.red) # draw_line(grid_corner(row+0.4, cols), grid_corner(row+0.6, cols), Color.red)
else: # else:
draw_line(grid_corner(row, cols), grid_corner(row+1, cols), Color.white) # draw_line(grid_corner(row, cols), grid_corner(row+1, cols), Color.white)
regenerate_grid_texture()
$TextureRect.margin_left = h0
$TextureRect.margin_top = v0
$TextureRect.rect_size = Vector2(h_space*cols, v_space*rows)
# Arc pencil marks # Arc pencil marks