[SOLVED] Centering Game Window in Fullscreen

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Zorochase
Prole
Posts: 21
Joined: Sun May 21, 2017 10:40 pm
Contact:

[SOLVED] Centering Game Window in Fullscreen

Post by Zorochase »

Hello,
My game has a resizable window. All graphics are rescaled when the window is resized. This works fine in windowed mode, and it even works in fullscreen mode, the only problem being that when in fullscreen mode, the window is drawn to the top left corner of my screen. How can I get the game's window to sit in the center of the screen when in fullscreen mode? The amount of black space around the game window should be determined by the scale of the window.
Last edited by Zorochase on Sun Oct 15, 2017 11:04 pm, edited 1 time in total.
"I am a tomato. My favorite food is tomatoes. Tomatoes are the best. I eat them everyday. I love to hear them scream."
User avatar
zorg
Party member
Posts: 3436
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Centering Game Window in Fullscreen

Post by zorg »

It is determined like that, but the origin will always be the top-left corner;
You need to offset everything by half of the black space around your screen (depending on how you're scaling things, either on one or on both axes);you can do this with rendering to a canvas, or without, using love.graphics.translate.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: Centering Game Window in Fullscreen

Post by grump »

Zorochase wrote: Sun Oct 15, 2017 1:37 amHow can I get the game's window to sit in the center of the screen when in fullscreen mode? The amount of black space around the game window should be determined by the scale of the window.
I presume that your window is a canvas?

Code: Select all

local function scaleToScreen(canvas, ignoreAspect)
	local width, height = canvas:getWidth(), canvas:getHeight()
	local screenWidth, screenHeight = love.window.getMode()
	if ignoreAspect then
		return 0, 0, screenWidth / width, screenHeight / height
	end

	local scale = screenWidth / screenHeight > width / height and screenHeight / height or screenWidth / width
	local x, y = (screenWidth - width * scale) * .5, (screenHeight - height * scale) * .5
	return math.floor(x), math.floor(y), scale, scale
end
This function takes a canvas and returns screen coordinates and scaling factors you can use to render the canvas to the screen. Set ignoreAspect to true to get fullscreen scaling. Set it to nil or false to preserve the aspect ratio of the canvas and center it on the screen. Aspect preserving scaling fills the smaller dimension of the screen and centers the canvas in the other dimension ("letterboxing").

How to use it:

Code: Select all

local function love.load()
	canvas = love.graphics.newCanvas(canvasWidth, canvasHeight)
	canvasX, canvasY, canvasSX, canvasSY = scaleToScreen(canvas)
end

local function love.draw()
	love.graphics.draw(canvas, canvasX, canvasY, 0, canvasSX, canvasSY)
end

function love.resize()
	canvasX, canvasY, canvasSX, canvasSY = scaleToScreen(canvas)
end
Edit: I just realized you may not want to scale the canvas to screen size, but just center it without resizing. In that case, ignore the code above and do this:

Code: Select all

love.draw()
	local w, h = love.window.getMode()
	local x, y = math.floor((w - canvas:getWidth()) * 0.5), math.floor((h - canvas:getHeight()) * 0.5)
	love.graphics.draw(canvas, x, y)
end
You have to take care of the situation when the screen is smaller than the window, though.
Zorochase
Prole
Posts: 21
Joined: Sun May 21, 2017 10:40 pm
Contact:

Re: Centering Game Window in Fullscreen

Post by Zorochase »

grump wrote: Sun Oct 15, 2017 3:49 pm
Zorochase wrote: Sun Oct 15, 2017 1:37 amHow can I get the game's window to sit in the center of the screen when in fullscreen mode? The amount of black space around the game window should be determined by the scale of the window.
I presume that your window is a canvas?

Code: Select all

local function scaleToScreen(canvas, ignoreAspect)
	local width, height = canvas:getWidth(), canvas:getHeight()
	local screenWidth, screenHeight = love.window.getMode()
	if ignoreAspect then
		return 0, 0, screenWidth / width, screenHeight / height
	end

	local scale = screenWidth / screenHeight > width / height and screenHeight / height or screenWidth / width
	local x, y = (screenWidth - width * scale) * .5, (screenHeight - height * scale) * .5
	return math.floor(x), math.floor(y), scale, scale
end
This function takes a canvas and returns screen coordinates and scaling factors you can use to render the canvas to the screen. Set ignoreAspect to true to get fullscreen scaling. Set it to nil or false to preserve the aspect ratio of the canvas and center it on the screen. Aspect preserving scaling fills the smaller dimension of the screen and centers the canvas in the other dimension ("letterboxing").

How to use it:

Code: Select all

local function love.load()
	canvas = love.graphics.newCanvas(canvasWidth, canvasHeight)
	canvasX, canvasY, canvasSX, canvasSY = scaleToScreen(canvas)
end

local function love.draw()
	love.graphics.draw(canvas, canvasX, canvasY, 0, canvasSX, canvasSY)
end

function love.resize()
	canvasX, canvasY, canvasSX, canvasSY = scaleToScreen(canvas)
end
Edit: I just realized you may not want to scale the canvas to screen size, but just center it without resizing. In that case, ignore the code above and do this:

Code: Select all

love.draw()
	local w, h = love.window.getMode()
	local x, y = math.floor((w - canvas:getWidth()) * 0.5), math.floor((h - canvas:getHeight()) * 0.5)
	love.graphics.draw(canvas, x, y)
end
You have to take care of the situation when the screen is smaller than the window, though.
Thanks for the response! I probably should have been more clear in my first post; I am drawing to a canvas that is 416x256 pixels, and the graphics should be pixel-perfect. What you provided does work... sort of. No matter whether I'm in fullscreen or windowed mode (I want the player to be able to choose their mode, obviously), the canvas is centered ONLY when it's at 1x scale. The larger the scale, the farther towards the bottom-right corner and out of the window the canvas is pushed. How do I make sure the canvas is ALWAYS in the middle of the window, no matter the scale?
"I am a tomato. My favorite food is tomatoes. Tomatoes are the best. I eat them everyday. I love to hear them scream."
User avatar
zorg
Party member
Posts: 3436
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Centering Game Window in Fullscreen

Post by zorg »

Math.
416x256 is your internal canvas size,
if you want pixel-perfectness, then you can only upscale to integer multiples on both axes, 1x1, 2x2, 3x3, etc;
let's say your screen/window resolution is 800x600,
800-416=384 pixels are the horizontal difference,
600-256=344 pixels are the vertical difference;
since you want to center things, then you need to divide half of both on the two sides of your internal canvas, though that only means that you need to translate the canvas by half of the horizontal and vertical sides.
In addition, if the screen/window sizes are bigger than your internal canvas resolution, then you do need to scale up by that much;
you can calculate all that together with the following:

Code: Select all

-- cx,cy are the internal canvas dimensions
-- wx,wy are the screen/window dimensions
-- tx,ty are the translation variables in pixels
-- sx,sy are the scaling multipliers
local sx, sy = math.floor(wx/cx), math.floor(wy/cy)
local tx, ty = wx%cx/2, wy%cy/2
Also, since people weren't stupid when they defined screen resolutions, all of them are even numbers, meaning you can always divide them by 2 at least once, so you won't get half-off issues with centering stuff.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: Centering Game Window in Fullscreen

Post by grump »

How about this:

Code: Select all

function love.draw()
	local scale = 1.5 -- or whatever
	local w, h = love.window.getMode()
	local x, y = math.floor((w - canvas:getWidth() * scale) * 0.5), math.floor((h - canvas:getHeight() * scale) * 0.5)
	love.graphics.draw(canvas, x, y, 0, scale, scale)
end
User avatar
zorg
Party member
Posts: 3436
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Centering Game Window in Fullscreen

Post by zorg »

grump wrote: Sun Oct 15, 2017 9:52 pm How about this:
<code>
Looks good except that 1.5 ain't an integer, so it'll never be pixel-perfect, and that that value should also be automatically inferred from the minima of the screen/window widths and heights (i did miss this one out from my post, oops)... in other words:

Code: Select all

function love.draw()
	local w, h = love.window.getMode()
	local cw,ch = canvas:getDimensions()
	local scale = math.floor(math.min(w/cw, h/ch)) -- if the window is smaller than the internal canvas size, then that'd be a problem though, since the scale would be zero...
	local tx, ty = math.floor((w - cw * scale) * 0.5), math.floor((h - ch * scale) * 0.5)
	love.graphics.draw(canvas, tx, ty, 0, scale, scale)
end
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: Centering Game Window in Fullscreen

Post by grump »

Yeah, that's basically the first solution I have posted above. But if I understand the problem correctly, OP does not want automatic scaling to fit the window, he wants to resize the canvas manually.
Zorochase
Prole
Posts: 21
Joined: Sun May 21, 2017 10:40 pm
Contact:

Re: Centering Game Window in Fullscreen

Post by Zorochase »

I should also mention that when in windowed mode, the window size should match the canvas size, for example, when the canvas is at 1x scale, the window is 416x256 pixels; 2x scale, 832x512, etc.. I also already have two scale variables (SX and SY) that are saved as a part of the game's settings, so when the game is closed and later reopened, the previous window/canvas size is retained.

Here's what I had originally:

Code: Select all

function love.load()
	WW, WH = 416, 256
	canvas = LG.newCanvas(416, 256)
	LW.setMode(WW * ST.sx, WH * ST.sy) -- LW and LG are shortcuts
end

function love.draw()
	LG.push()
	LG.setCanvas(canvas)
	LG.clear()
	STM:draw() -- draw method for my state manager; this is what is being drawn
	LG.setCanvas()
	LG.scale(ST.sx, ST.sy)
	LG.draw(canvas)
	LG.pop()
end
Last edited by Zorochase on Sun Oct 15, 2017 10:56 pm, edited 1 time in total.
"I am a tomato. My favorite food is tomatoes. Tomatoes are the best. I eat them everyday. I love to hear them scream."
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: Centering Game Window in Fullscreen

Post by grump »

I don't think that's relevant. The code works in that case too. Next time please start with posting some code that shows the actual problem, because this guessing game and your gradual revealing of requirements gets old real fast.
Post Reply

Who is online

Users browsing this forum: No registered users and 65 guests