Page 1 of 3

Paint program

Posted: Tue Oct 22, 2013 1:32 pm
by iPoisonxL
Hi. I'm trying to create a paint program, and it's working well. The only current problem is that it draws over the same pixel, over, and over again if you hold down the mouse button. Therefore creating thousands of pixels, and huge lag. I'm trying to find my way around this, and since I use a table that has all the pixel positions I thought maybe I should create a function that loops through the table and detects if anything repeats? Can't seem to do it. Here's the code.

Code: Select all

table.has = function(tabl, value)
	for i,v in pairs(tabl) do
		if value == item then return true end
	end
	return false
end

table.length = function(tabl)
	local count = 0
	for i,v in pairs(tabl) do
		count = count + 1
	end
	return count
end

function love.load()
	pixels = {}
end

function love.update()
	pos = {love.mouse.getX(), love.mouse.getY()}
	if(love.mouse.isDown("r"))then
		pixels = {}
	end
	
	for i,v in ipairs(pixels) do
		if(table.has(pixels, v))then
			v = nil
		end
	end
	
	if(love.mouse.isDown("l"))then
		table.insert(pixels, pos)
	end
end

function love.draw()
	love.graphics.setColor(255,255,255)
	for i,v in ipairs(pixels) do
		love.graphics.point(v[1], v[2])
	end
	love.graphics.print(love.timer.getFPS(), 10, 10)
	love.graphics.print("Amount of pixels being drawn: "..table.length(pixels), 10, 30)
end
and here's the .love
main.love
(481 Bytes) Downloaded 414 times

Re: Paint program

Posted: Tue Oct 22, 2013 2:12 pm
by miko
iPoisonxL wrote: Hi. I'm trying to create a paint program, and it's working well.
If you were using canvases, it would work even better - attached:
main-canvas.love
(594 Bytes) Downloaded 565 times

Re: Paint program

Posted: Tue Oct 22, 2013 2:30 pm
by micha
It seem rather strange to me that you are storing the image in a table as a set of coordinates. The natural approach for me is having a table of tables (a 2d-array) of a fixed size and inserting the color of each pixel there.
If you want to save memory you can still assign nil to all empty pixels.

To make the difference clear: Your approach has a table that contains coordinates like this:

Code: Select all

{{x1,y1},{x2,y2},...}
The more natural approach has one 2d array of colors:

Code: Select all

{{c1,c2,c3,...},{c100,c101,...},...}
Drawing a pixel is changing a value inside the array instead of adding a new entry to the array.
As miko says, drawing this might be faster if you use a canvas (or imageData).

Re: Paint program

Posted: Tue Oct 22, 2013 4:04 pm
by iPoisonxL
I can't use canvases, since my OpenGL implementation doesn't support it. I have quite an old computer. Isn't there a way to delete duplicates in tables?

Re: Paint program

Posted: Tue Oct 22, 2013 4:05 pm
by Ref
Obvious, just a programming exercise - of limited value.
At best, script just not fast enough to keep up with mouse movements.
You can extend the useful number of pixels with reasonable frame rate by optimizing your code.
( Might want to limit mouse movement to screen to avoid creating points that can't be displayed. )
Canvases will permit continuous point addition without effecting frame rate but you have to remember to invert the y axes.

Edit1: Don't add duplicates to the table in the first place.
Edit2: Could improve response time by modifying love.run - only redraw screen if pixel added. Doesn't really address real problem - mouse moving too fast.

Re: Paint program

Posted: Tue Oct 22, 2013 4:08 pm
by T-Bone
Even without Canvases, using ImageData and setPixel might work depending on how you implement it.

Re: Paint program

Posted: Tue Oct 22, 2013 4:17 pm
by iPoisonxL
I'm currently trying to make a 2D Array that has every pixel in it, but I can't figure out how. I won't do it manually, because you know, 480K values is a lot.

Re: Paint program

Posted: Tue Oct 22, 2013 6:51 pm
by Ref
Just for completeness - added drawing to image data.
Converting imageData to an image limits frame rate.

Re: Paint program

Posted: Tue Oct 22, 2013 9:04 pm
by micha
iPoisonxL wrote:I'm currently trying to make a 2D Array that has every pixel in it, but I can't figure out how. I won't do it manually, because you know, 480K values is a lot.
After thinking about it for a while, probably ImageData is the best way to go. For completeness, here is how to do the 2d-array:

Code: Select all

for i = 1,width do
  pixel[i] = {}
  for j = 1,height do
    pixel[i][j] = 0
  end
end
Here you can save some memory by only assigning those pixels that are non-black (or whatever color the background is). Only create the tables for each column:

Code: Select all

for i = 1,width do
  pixel[i] = {}
end
And then insert the values, whenever needed:

Code: Select all

function someMouseClickEvent(x,y)
  pixel[x][y] = color
end

Re: Paint program

Posted: Wed Oct 23, 2013 1:40 pm
by iPoisonxL
micha wrote:

Code: Select all

for i = 1,width do
  pixel[i] = {}
  for j = 1,height do
    pixel[i][j] = 0
  end
end
could you explain this snippet to me? I'm not big on 2D arrays, haven't really been interested in them. I now realize how important they can be.