Rotate image on a quad
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
Rotate image on a quad
Hello there LÖVE forums, I am once again asking for your knowledge and assistance.
I've been working on a game with a level editor where you can draw out polygons for the level platforms, and now I have made it so you can convert them into physics objects.
Each platform has a repeating texture, which I have managed using setWrap(), then drawing it on a quad the size of the screen, and then finally stenciling it - however my issue is that now they are physics objects, they can also rotate. Just setting r on the draw function rotates the whole quad and not just the texture, which means it no longer covers the whole screen.
Is there a good way to achieve what I want?
I've been working on a game with a level editor where you can draw out polygons for the level platforms, and now I have made it so you can convert them into physics objects.
Each platform has a repeating texture, which I have managed using setWrap(), then drawing it on a quad the size of the screen, and then finally stenciling it - however my issue is that now they are physics objects, they can also rotate. Just setting r on the draw function rotates the whole quad and not just the texture, which means it no longer covers the whole screen.
Is there a good way to achieve what I want?
Dragon
Re: Rotate image on a quad
If I understood correctly what you are describing why not just use `love.graphics.rotate` inside `love.graphics.push` ?
Here is what I mean:
Is that what you were describing?
Here you can manage the rotation of the polygon and the texture separately.
Here is what I mean:
Code: Select all
love.graphics.push()
love.graphics.translate(cx, cy)
love.graphics.rotate(polygon:getRotation())
love.graphics.translate(-cx, -cy)
love.graphics.stencil(function()
love.graphics.polygon("fill", polygon)
end, "replace", 1)
love.graphics.setStencilTest("greater", 0)
love.graphics.draw(
sprite, cx, cy, sprite_angle, 1, 1,
sprite:getWidth()/2,
sprite:getHeight()/2
)
love.graphics.setStencilTest()
love.graphics.pop()
Here you can manage the rotation of the polygon and the texture separately.
- Attachments
-
- Rotation-test.love
- (133.14 KiB) Downloaded 98 times
Re: Rotate image on a quad
Not quite - the main issue is that it needs to be a repeating texture, like so: Here is what I'm currently working with, which works untill you need to rotate the texture around a point
Code: Select all
image = love.graphics.newImage("anImage.png")
function love.draw()
wrappedDraw(image, love.graphics.getWidth()/2, love.graphics.getHeight()/2, 0)
end
function wrappedDraw(drawable, x, y, r, scale)
if not scale then
scale = 1
end
if not r then
r = 1
end
drawable:setWrap( "repeat", "repeat" )
local quad = love.graphics.newQuad( -x, -y, love.graphics.getWidth(), love.graphics.getHeight(), drawable:getWidth()*scale, drawable:getHeight()*scale )
love.graphics.draw( drawable, quad, 0+love.graphics.getWidth()/2, 0+love.graphics.getHeight()/2, 0, 1, 1, love.graphics.getWidth()/2, love.graphics.getHeight()/2)
end
Dragon
Re: Rotate image on a quad
See also: viewtopic.php?f=4&t=93939
You can use meshes for it:
So, make the round mesh and rotate it around the middle of it.
You can use meshes for it:
Code: Select all
love.window.setMode(800, 800)
W, H = love.graphics.getDimensions( )
function love.load()
local image = love.graphics.newImage('img-16.png')
image:setWrap( "repeat" )
image:setFilter("linear", "nearest")
local n = 6 -- amount of tiles
local k = 128 -- size of tile
local s = n*k -- size of screen
local vertices = {
{0, 0, 0, 0, 1,1,1},
{0, s, 0, n, 1,1,1},
{s, s, n, n, 1,1,1},
{s, 0, n, 0, 1,1,1},
}
mesh = love.graphics.newMesh( vertices, "fan")
mesh:setTexture(image)
end
Code: Select all
function love.draw()
love.graphics.draw(mesh)
end
- Attachments
-
- mesh-with-texture-01.love
- (1.13 KiB) Downloaded 92 times
Re: Rotate image on a quad
I'm still not sure I understand the problem, is it the `r` variable you forgot to `draw`?
It doesn't matter, if you can't follow darkfrei's instructions, otherwise here's what I wrote to rotate the texture:
You will notice that instead of writing:
You can simply write:
It doesn't matter, if you can't follow darkfrei's instructions, otherwise here's what I wrote to rotate the texture:
Code: Select all
function wrappedDraw(drawable, x, y, r, scale)
r = r or 0
scale = scale or 1
drawable:setWrap( "repeat", "repeat" )
local quad = love.graphics.newQuad( -x, -y, love.graphics.getWidth(), love.graphics.getHeight(), drawable:getWidth()*scale, drawable:getHeight()*scale )
love.graphics.draw( drawable, quad, 0+love.graphics.getWidth()/2, 0+love.graphics.getHeight()/2, r, 1, 1, love.graphics.getWidth()/2, love.graphics.getHeight()/2)
end
Code: Select all
if not value then
value = 1
end
Code: Select all
value = value or 1
Re: Rotate image on a quad
Ah I see! I'm unfamilar with meshes (this is the first I knew love could handle them), so I'll look into them. Is this any better than just drawing a quad big enough to fill the entire screen?
Dragon
Re: Rotate image on a quad
Oh that's very neat! Time to update all my functions...Bigfoot71 wrote: ↑Mon Jan 30, 2023 10:57 am You will notice that instead of writing:You can simply write:Code: Select all
if not value then value = 1 end
Code: Select all
value = value or 1
What I was looking for before was to just fill the whole screen, what I'm trying to avoid is drawing outside the screen area, and not leaving any undrawn area, otherwise you get these corners.
Appologies if I'm not being clear, hopefully looking more into meshes will give a solution.
Edit: Upon looking more into meshes, I'm less certain how I can use this to fix my issue if I make a mesh that matches the level polygon, wouldn't that make it difficult to set the UVs correctly?
Dragon
Re: Rotate image on a quad
Ah okay, unfortunately, mesh or not apart from extending the edges beyond the screen, I don't really see how you could do it to be honest (unless a solution escapes me at this moment)...Bobble68 wrote: ↑Mon Jan 30, 2023 11:13 amOh that's very neat! Time to update all my functions...Bigfoot71 wrote: ↑Mon Jan 30, 2023 10:57 am You will notice that instead of writing:You can simply write:Code: Select all
if not value then value = 1 end
Code: Select all
value = value or 1
What I was looking for before was to just fill the whole screen, what I'm trying to avoid is drawing outside the screen area, and not leaving any undrawn area, otherwise you get these corners.
Untitled.png
Appologies if I'm not being clear, hopefully looking more into meshes will give a solution.
Edit: Upon looking more into meshes, I'm less certain how I can use this to fix my issue if I make a mesh that matches the level polygon, wouldn't that make it difficult to set the UVs correctly?
Otherwise for the UVs it's very simple when you understand, they go from 0 to 1, where 0.0 is the origin of the image (top left for Löve or bottom left for other engines) and 1.1 is bottom right (or top right...).
Here is an example I made using a mesh:
Code: Select all
local GW, GH = love.graphics.getDimensions()
local GOX, GOY = GW/2, GH/2
local backgroundImage = love.graphics.newImage("background.jpg")
backgroundImage:setWrap("repeat", "repeat") -- Always important to call this method
local backgroundAngle = 0
-- Set a distance larger than the screen size for the vertices of the mesh
local distance = 2 * math.max(GW, GH)
-- Create an array for the texture coordinates of the mesh
-- To repeat the texture it is necessary to normalize from 0 to 1 by dividing the size of the mesh by the size of the texture
-- If we defined the corners only with 0 and 1 the texture would simply be stretched.
local meshVertices = {
{-distance, -distance, 0, 0},
{distance, -distance, GW / backgroundImage:getWidth(), 0},
{distance, distance, GW / backgroundImage:getWidth(), GH / backgroundImage:getHeight()},
{-distance, distance, 0, GH / backgroundImage:getHeight()}
}
-- Create a mesh from the array
local mesh = love.graphics.newMesh(meshVertices, "fan")
mesh:setTexture(backgroundImage)
-- We do it all --
function love.update(dt)
backgroundAngle = backgroundAngle + dt
end
function love.draw()
love.graphics.setColor(1, 1, 1)
love.graphics.draw(mesh, GOX, GOY, backgroundAngle, 1, 1, GOX, GOY)
end
- Attachments
-
- Rotation-test.love
- (7.34 KiB) Downloaded 93 times
Re: Rotate image on a quad
So,
Code: Select all
function love.load()
local image = love.graphics.newImage('img-16.png')
image:setWrap( "repeat" )
image:setFilter("linear", "nearest")
local n = 6 -- amount of tiles
local k = 128 -- size of tile
local s = n*k -- size of screen
local vertices = {
{0, 0, 0, 0, 1,1,1},
{s, 0, n, 0, 1,1,1},
{0, s, 0, n, 1,1,1},
{s, s, n, n, 1,1,1},
}
mesh = love.graphics.newMesh( vertices, "strip") -- strip, not fan!
mesh:setTexture(image)
Angle = 0
end
Code: Select all
local function rotateMesh (mesh, s, n, angle)
local u1 = n*math.cos(angle)
local u2 = n*math.sin(angle)
local v1 = n*math.sin(angle)
local v2 = -n*math.cos(angle)
mesh:setVertex(2, s, 0, u1, v1)
mesh:setVertex(3, 0, s, u2, v2)
mesh:setVertex(4, s, s, u1+u2, v1+v2)
end
function love.update(dt)
local n, s = 6, 128*6
Angle = Angle + 0.1*dt
rotateMesh (mesh, s, n, Angle)
end
Code: Select all
function love.draw()
love.graphics.draw(mesh)
end
- Attachments
-
- mesh-with-texture-02.love
- (1.34 KiB) Downloaded 84 times
Re: Rotate image on a quad
Thats nearly perfect! Only issue is it needs to be able to be rotated around a specific point, rather than just 0,0 so it doesn't shift when a physics object rotate. I tried to figure out how to do it, though I got wrong (though interesting to look at) results.darkfrei wrote: ↑Mon Jan 30, 2023 1:23 pmSo,Code: Select all
function love.load() local image = love.graphics.newImage('img-16.png') image:setWrap( "repeat" ) image:setFilter("linear", "nearest") local n = 6 -- amount of tiles local k = 128 -- size of tile local s = n*k -- size of screen local vertices = { {0, 0, 0, 0, 1,1,1}, {s, 0, n, 0, 1,1,1}, {0, s, 0, n, 1,1,1}, {s, s, n, n, 1,1,1}, } mesh = love.graphics.newMesh( vertices, "strip") -- strip, not fan! mesh:setTexture(image) Angle = 0 end
Code: Select all
local function rotateMesh (mesh, s, n, angle) local u1 = n*math.cos(angle) local u2 = n*math.sin(angle) local v1 = n*math.sin(angle) local v2 = -n*math.cos(angle) mesh:setVertex(2, s, 0, u1, v1) mesh:setVertex(3, 0, s, u2, v2) mesh:setVertex(4, s, s, u1+u2, v1+v2) end function love.update(dt) local n, s = 6, 128*6 Angle = Angle + 0.1*dt rotateMesh (mesh, s, n, Angle) end
2023-01-30T14_22_35-Untitled.pngCode: Select all
function love.draw() love.graphics.draw(mesh) end
Dragon
Who is online
Users browsing this forum: Amazon [Bot], Bing [Bot] and 4 guests