Page 1 of 2

2X scaling

Posted: Wed Feb 08, 2012 3:40 am
by thatshelby
Hi,

I'm new to love2d. After some searching and keyword changing, I have no helpful results.

How can I scale the game window 2X, perfectly, using linear/nearest neighbor interpolation?



Thanks

Re: 2X scaling

Posted: Wed Feb 08, 2012 4:40 am
by Jasoco
My preferred method (Which may not be supported by every single person depending on their graphics card sadly) is to use a Canvas and Nearest Neighbor scaling. The gist of it:

You create your canvas to draw on. (In 0.7.x it's called FrameBuffer, in 0.8.x it will be called Canvas) This canvas will be the size of the drawing area. Say you want a doubled pixel game in the old style of 320x240 or 320x200. (The former is what all the cool indie kids use, the latter what old PC games actually used in VGA and CGA modes in games like DOOM and Wolfenstein.) You'd make a canvas of that size. This will be your drawing area.

When you create the canvas, use setFilter on it to make it scale nearest neighbor.

You draw all your stuff to the canvas. Then you draw the canvas to the screen scaled up 2x.

When you load:

Code: Select all

canvas = love.graphics.newCanvas(320,240)
canvas:setFilter("nearest", "nearest")
When you draw:

Code: Select all

love.graphics.setCanvas(canvas) --This sets the draw target to the canvas
--DRAW EVERYTHING
love.graphics.setCanvas() --This sets the target back to the screen
love.graphics.draw(canvas, 0, 0, 0, 2, 2)
That is the gist. Not 100% what you should do, rather you should toy around, but that helps you figure out where to look in the Wiki. Remember that Canvas is only 0.8.0, you'll need to look up Render Targets for 0.7.x. They changed the names of the stuff way too many times between 0.7 and the current 0.8.

I use a more complicated method where I can set the window size to however big I want, then scale the image until it fits while centering it to add bars to the sides so I can fullscreen and still have proper scaling without any blurring. (To make the window the actual size of a screen, set the width and/or height to ZERO. Look up love.graphics.setMode(). To calculate the scale you do screen_width / screen_height. Then to calculate centering offset you use (screen_width - (game_width * scale)) / 2 I believe.

I only use Canvas because I don't think you can use setFilter on the screen yet. So if you used love.graphics.scale() it would blur everything so I use canvases.

Re: 2X scaling

Posted: Wed Feb 08, 2012 4:43 am
by Taehl
You just need to (Image):setFilter("nearest", "nearest").

Re: 2X scaling

Posted: Wed Feb 08, 2012 5:02 am
by Jasoco
I prefer to work with the smaller game area because it's more true to real 8-bit or 16-bit graphics whereas just scaling images up results in large pixels not being aligned with the true pixel grid making it look less "genuine". Also, my method allows you to scale up to any screen size easily without having to calculate the position of onscreen elements based on the scale. Since it's a single scale calculation and everything draws properly.

Re: 2X scaling

Posted: Wed Feb 08, 2012 5:21 am
by thatshelby
Thanks for the replies.

I get an error:
Error

main.lua.9: attempt to call field 'newFrameBuffer' (a nil value)

Traceback

main.lua.9: in function 'load'
[C]: in function 'xpcall'

Here is my main.lua source:

Code: Select all

-- Scale the Screen

angle = 0;
rot = 0;

function love.load()
    image = love.graphics.newImage("player.png");
    
    framebuffer = love.graphics.newFrameBuffer(320, 240);
    framebuffer:setFilter("nearest", "nearest");
    
    x = 160;
    y = 120;
end

function love.update(dt)
    angle = math.atan2(y - love.mouse.getY(), x - love.mouse.getX()) + math.rad(180);
    rot = angle;
end

function love.draw()
    love.graphic.setRenderTarget(framebuffer);
    love.graphics.draw(image, x, y, rot, sx, sy, 16, 16);
    love.graphic.setRenderTarget();
    love.graphics.draw(framebuffer, 0, 0, 0, 2, 2)
end

I am using love 0.7.2.

Please help!

Re: 2X scaling

Posted: Wed Feb 08, 2012 5:29 am
by Jasoco
Does your computer even support framebuffers I wonder. Your only choice might be to just go the other route.

Re: 2X scaling

Posted: Wed Feb 08, 2012 5:32 am
by thatshelby
Uh oh. It might not.

I have a bad story about that. My main computer is totally unfixable as of today. So I dug out an old computer, and installed ubuntu on it. I have been trying to learn a new game engine + a new operating system on a computer that's 7, 8 years old.

:|

Re: 2X scaling

Posted: Wed Feb 08, 2012 5:49 am
by MarekkPie
It's a lowercase 'b'. So:

Code: Select all

love.graphics.newFramebuffer() -- Good
love.graphics.newFrameBuffer() -- Bad
https://love2d.org/wiki/love.graphics.newFramebuffer

Re: 2X scaling

Posted: Wed Feb 08, 2012 5:54 am
by Jasoco
Good catch. Try that. Lua and Löve are case-sensitive with commands like this.

Re: 2X scaling

Posted: Wed Feb 08, 2012 7:19 am
by hryx
Shelby, a quick and dirty way to make all images scale in linear mode is to put this snippet early in the program, before any images get loaded:

Code: Select all

local __newImage = love.graphics.newImage -- old function
function love.graphics.newImage( ... ) -- new function that sets nearest filter
	local img = __newImage( ... ) -- call old function with all arguments to this function
	img:setFilter( 'nearest', 'nearest' )
	return img
end
(Found somewhere else in the forums long ago)

Then use newImage() as usual. Then you can scale all images and the world coordinates love.graphics.scale(2), making everything zoomed to 200% with the look you want. Be careful that this filter only applies to Image types, though, not fonts or anything.

By the way, a warm welcome to you -- from a fellow TIGS kid. (I recognize you)