Page 1 of 1

Canvas Drawing Issue?

Posted: Wed Mar 13, 2013 10:57 pm
by equalsP
I am trying to make a minimap for an isometric style map (think age of empires). I want to do this by drawing a pixel color representation of the map in a canvas and then scale the canvas to be the correct isometric sizing. I can do this with no problem but I was getting overlay draw issues. I looked around the internet and didn't really find an alternate way I could do this, or at least the canvas method is the most straight forward to me. I then decided to test it on linux (i have a dual boot in hopes of switching) and it works fine.

This is what I get. Seems to work how I imagine it on ubuntu, but not on windows. I changed the minimap background to white to see if I got the right colors, but it doesn't.
K9zAsMp.png
K9zAsMp.png (88.7 KiB) Viewed 228 times
Here is the code for creating the canvas

Code: Select all

function hud:buildminimap()
	-- create a minimap

	self.minimap = love.graphics.newCanvas(self.worldlink.dimensions.y,self.worldlink.dimensions.x)
	self.minimap:setFilter('nearest','nearest')

	oldcolor = { love.graphics.getColor() }

	local colorz = { 
		{ 0,  0,0 },
		{ 0,230,0 },
		{ 0,180,0 },
		{ 255,0,0 },
		{ 0,0,230 }
	}

        -- makes the background rectangle
	love.graphics.setColor(0,0,0)
	self.minimap:renderTo(function() love.graphics.rectangle('fill',0,0,self.worldlink.dimensions.y,self.worldlink.dimensions.x) end)
	
        -- draws the points on the background, this are a 1:1 with the map grid
        for ix = 1, self.worldlink.dimensions.x do
		for iy = 1, self.worldlink.dimensions.y do
			love.graphics.setColor(colorz[self.worldlink.map[ix][iy]])
			self.minimap:renderTo(function() love.graphics.point(iy,ix) end)
		end
	end

	-- scales the minimap
	local angledwidth = self.minimap:getWidth()*math.cos(configuration.hud.minimap.rotationangle) + 
                                      self.minimap:getHeight()*math.cos(configuration.hud.minimap.rotationangle)
	local angledheight = self.minimap:getWidth()*math.sin(configuration.hud.minimap.rotationangle) + 
                                       self.minimap:getHeight()*math.sin(configuration.hud.minimap.rotationangle)
        local scalefactors = { 	configuration.hud.minimap.size.width / angledwidth,
						configuration.hud.minimap.size.height / angledheight }

        -- this section rotates and scales the big pixel map to the right height and width based on the minimap size in the window
	local tempcanvas = love.graphics.newCanvas(configuration.hud.minimap.size.width,configuration.hud.minimap.size.height)

	love.graphics.setColor(0,0,0)
	tempcanvas:renderTo( function() 
                       love.graphics.rectangle('fill',0,0,configuration.hud.minimap.size.width,configuration.hud.minimap.size.height) 
        end)
	love.graphics.setColor(255,255,255,255)
	
        -- this rotates the map 45 degrees and scales it
        tempcanvas:renderTo( function() 
		love.graphics.draw(	self.minimap,
							0,
							0 + configuration.hud.minimap.size.width*math.cos(configuration.hud.minimap.rotationangle)/2,
							-configuration.hud.minimap.rotationangle,
							math.min(unpack(scalefactors)),
							math.min(unpack(scalefactors))
						)
	end)

	self.minimap = tempcanvas
and then the draw code

Code: Select all


	-- drawing the minimap (the bottom one)
	love.graphics.setColor(255,255,255,255)
	love.graphics.draw(self.minimap,
							0 + configuration.hud.minimap.padding.left,
							self.minimapdrawpos.y ,
							0,
							1,
							1/2
						)

        -- the top one
	love.graphics.draw(self.minimap,0,0)

I am missing something about how the renderTo() works or how to draw the canvases? I feel like this is a huge roadblock for this project.

Thanks for the help. I am hoping I am just using the code wrong and it isn't a problem with love.

Re: Canvas Drawing Issue?

Posted: Thu Mar 14, 2013 12:54 am
by Boolsheet
It seems the OpenGL function that love.graphics.point uses can produce different images from graphics driver to graphics driver. You also should offset the coordinates by 0.5 so the center of the point is actually in the middle of a pixel.

I would recommend to use one of the other functions to create the tiles on the minimap (love.graphics.rectangle or love.graphics.polygon). This should give the image you're expecting on all implementations.

Your loop that draws the tiles creates a function over and over again. That is somewhat inefficient. Consider using love.graphics.setCanvas instead to set the Canvas before the loop and then unset it after again. renderTo is very similar, but does the setting and unsetting of the canvas for you before and after it calls the passed function. I prefer setCanvas over renderTo.

Code: Select all

love.graphics.setCanvas(self.minimap)
for ix = 1, self.worldlink.dimensions.x do
	for iy = 1, self.worldlink.dimensions.y do
		love.graphics.setColor(colorz[self.worldlink.map[ix][iy]])
		love.graphics.rectangle("fill", ix - 1, iy - 1, 1, 1)
	end
end
love.graphics.setCanvas()

Re: Canvas Drawing Issue?

Posted: Thu Mar 14, 2013 1:10 am
by equalsP
Whoh, awesome. That works. I guess it draws it between pixels so then it tries to smooth it and makes it a different opacity (like when making a pixel between pixels in photoshop). I'll switch to rectangles. I was thinking it was less efficient then drawing a point, but this drawing only happens once, and probably doesn't effect it as much seeing that it makes it cross-platform.

I'm still learning the ropes for lua so I wasn't too sure how using the function() was different from setCanvas() performance-wise. But now that you mention it I should probably use the setCanvas method.

Thanks for the help.