samyeyo / LuaRT

Open source Windows programming framework for Lua
https://www.luart.org
Other
285 stars 17 forks source link

Canvas:fillrect() and Canvas:clear() doesn't seem to work. #100

Closed Dismalitie closed 11 months ago

Dismalitie commented 12 months ago

I'm currently writing a simple graphical engine on LuaRT. When attempting to refresh the canvas by clearing it and setting it up for drawing, I noticed that canvas:clear() won't clear the canvas. I tried to clear the canvas using canvas:fillrect() and setting the colour to canvas.bgcolor whilst having the rectangle's size span the entire canvas, but it still won't work. I've tried a few different ways, but her is my src:

local ui = require("ui")
local canvas = require("canvas")

local win = ui.Window("rengine - scene", "fixed", 500, 500)
  win:loadicon("rengine.ico")
local dbg = ui.Window("rengine - debug", "fixed", 500, 500)
local engine = ui.Canvas(win)

engine.align = "all"

function makeCube(x, y, scale)
  if x == nil then x = engine.width/2 end
  if y == nil then y = engine.height/2 end
  if scale == nil then scale = 100 end
  engine:begin()
  engine:rect(x-(scale-math.ceil(scale/4)), y-(scale-math.ceil(scale/4)), x+(scale-math.ceil(scale/2)), y+(scale-math.ceil(scale/2)))
  engine:rect(x+(scale-math.ceil(scale/4)), y+(scale-math.ceil(scale/4)), x-(scale-math.ceil(scale/2)), y-(scale-math.ceil(scale/2)))

  engine:line(x-(scale-math.ceil(scale/4)), y-(scale-math.ceil(scale/4)), x-(scale-math.ceil(scale/2)), y-(scale-math.ceil(scale/2)))
  engine:line(x+(scale-math.ceil(scale/4)), y+(scale-math.ceil(scale/4)), x+(scale-math.ceil(scale/2)), y+(scale-math.ceil(scale/2)))
  engine:line(x-(scale-math.ceil(scale/4))+(scale+math.floor(scale/4)), y-(scale-math.ceil(scale/4)), x-(scale-math.ceil(scale/2))+(scale+math.floor(scale/4)), y-(scale-math.ceil(scale/2)))
  engine:line(x+(scale-math.ceil(scale/4))-(scale+math.floor(scale/4)), y+(scale-math.ceil(scale/4)), x+(scale-math.ceil(scale/2))-(scale+math.floor(scale/4)), y+(scale-math.ceil(scale/2)))

  engine:flip()
  --engine:clear()
  engine:fillrect(0,0,500,500, engine.bgcolor)
end

makeCube(engine.width/2, engine.height/2, 100)

win:show()

repeat
  ui.update()
until not win.visible

I don't know if I'm doing something wrong (I probably am) or I've just found some sort of edge case.

Thanks for reading!👍

samyeyo commented 12 months ago

Thank you Dismalitie for the report I will check this 👍🏻

Dismalitie commented 12 months ago

Actually, I think I just fixed it. Turns out I need to call canvas:begin() and canvas:flip() again after I have already called them to draw the cube. Then you just place canvas:clear() or canvas:fillrect() between begin and flip like this:

engine:begin()
engine:clear()
engine:flip()
samyeyo commented 12 months ago

Yes you can draw after a flip() call, but it won't be displayed. All drawing operations should start between begin() and flip() calls, so you should call clear() just after begin ()

samyeyo commented 12 months ago

As a side note, you can put the drawing operations in the onPaint() event handler that will call begin() before and flip() once the function has returned :

local ui = require("ui")
local canvas = require("canvas")

local win = ui.Window("rengine - scene", "fixed", 500, 500)
win:loadicon("rengine.ico")
local dbg = ui.Window("rengine - debug", "fixed", 500, 500)
local engine = ui.Canvas(win)

engine.align = "all"

function makeCube(x, y, scale)
  if x == nil then x = engine.width/2 end
  if y == nil then y = engine.height/2 end
  if scale == nil then scale = 100 end
  engine:rect(x-(scale-math.ceil(scale/4)), y-(scale-math.ceil(scale/4)), x+(scale-math.ceil(scale/2)), y+(scale-math.ceil(scale/2)))
  engine:rect(x+(scale-math.ceil(scale/4)), y+(scale-math.ceil(scale/4)), x-(scale-math.ceil(scale/2)), y-(scale-math.ceil(scale/2)))
  engine:line(x-(scale-math.ceil(scale/4)), y-(scale-math.ceil(scale/4)), x-(scale-math.ceil(scale/2)), y-(scale-math.ceil(scale/2)))
  engine:line(x+(scale-math.ceil(scale/4)), y+(scale-math.ceil(scale/4)), x+(scale-math.ceil(scale/2)), y+(scale-math.ceil(scale/2)))
  engine:line(x-(scale-math.ceil(scale/4))+(scale+math.floor(scale/4)), y-(scale-math.ceil(scale/4)), x-(scale-math.ceil(scale/2))+(scale+math.floor(scale/4)), y-(scale-math.ceil(scale/2)))
  engine:line(x+(scale-math.ceil(scale/4))-(scale+math.floor(scale/4)), y+(scale-math.ceil(scale/4)), x+(scale-math.ceil(scale/2))-(scale+math.floor(scale/4)), y+(scale-math.ceil(scale/2)))
end

function engine:onPaint()
    self:clear()
    makeCube(engine.width/2, engine.height/2, 100)
end

ui.run(win)