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
2X scaling
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
- thatshelby
- Prole
- Posts: 5
- Joined: Wed Feb 08, 2012 12:19 am
- Jasoco
- Inner party member
- Posts: 3727
- Joined: Mon Jun 22, 2009 9:35 am
- Location: Pennsylvania, USA
- Contact:
Re: 2X scaling
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:
When you draw:
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.
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")
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)
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.
Last edited by Jasoco on Wed Feb 08, 2012 4:44 am, edited 1 time in total.
- Taehl
- Dreaming in associative arrays
- Posts: 1025
- Joined: Mon Jan 11, 2010 5:07 am
- Location: CA, USA
- Contact:
Re: 2X scaling
You just need to (Image):setFilter("nearest", "nearest").
Earliest Love2D supporter who can't Love anymore. Let me disable pixel shaders if I don't use them, dammit!
Lenovo Thinkpad X60 Tablet, built like a tank. But not fancy enough for Love2D 0.10.0+.
Lenovo Thinkpad X60 Tablet, built like a tank. But not fancy enough for Love2D 0.10.0+.
- Jasoco
- Inner party member
- Posts: 3727
- Joined: Mon Jun 22, 2009 9:35 am
- Location: Pennsylvania, USA
- Contact:
Re: 2X scaling
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.
- thatshelby
- Prole
- Posts: 5
- Joined: Wed Feb 08, 2012 12:19 am
Re: 2X scaling
Thanks for the replies.
I get an error:
Here is my main.lua source:
I am using love 0.7.2.
Please help!
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!
- Jasoco
- Inner party member
- Posts: 3727
- Joined: Mon Jun 22, 2009 9:35 am
- Location: Pennsylvania, USA
- Contact:
Re: 2X scaling
Does your computer even support framebuffers I wonder. Your only choice might be to just go the other route.
- thatshelby
- Prole
- Posts: 5
- Joined: Wed Feb 08, 2012 12:19 am
Re: 2X scaling
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.
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
It's a lowercase 'b'. So:
https://love2d.org/wiki/love.graphics.newFramebuffer
Code: Select all
love.graphics.newFramebuffer() -- Good
love.graphics.newFrameBuffer() -- Bad
- Jasoco
- Inner party member
- Posts: 3727
- Joined: Mon Jun 22, 2009 9:35 am
- Location: Pennsylvania, USA
- Contact:
Re: 2X scaling
Good catch. Try that. Lua and Löve are case-sensitive with commands like this.
Re: 2X scaling
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:
(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)
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
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)
Who is online
Users browsing this forum: Google [Bot] and 3 guests