I am working on a 2D game and I'm looking for a simple way to mirror an image (player should look left instead of right).
I have seen some posts about rotation and transformation but it looks way too complicated...
Is there a simple way to do this without having to duplicate all the assets for the player animations?
Thank you guys in advance!
2D image mirroring
Re: 2D image mirroring
Oh... forgot to say I am using this to render the character:
rect<s32> sprite(currentFrame * size.X, 0, (currentFrame + 1) * size.X - 1, size.Y - 1);
driver->draw2DImage(image, position, sprite, 0, SColor(255, 255, 255, 255), true);
rect<s32> sprite(currentFrame * size.X, 0, (currentFrame + 1) * size.X - 1, size.Y - 1);
driver->draw2DImage(image, position, sprite, 0, SColor(255, 255, 255, 255), true);
-
- Competition winner
- Posts: 1123
- Joined: Sun Jun 10, 2007 11:14 pm
Re: 2D image mirroring
I have no idea if this would actually work, but how about flipping the coordinates of the source rect?
Re: 2D image mirroring
Tried that.
Didn't work.
Thanks anyway
Didn't work.
Thanks anyway
Re: 2D image mirroring
I finally solved this issue using some code from Lonesome Ducky:
http://irrlicht.sourceforge.net/forum/v ... 8&start=15
My idea was to use negative scale values in order to flip the image.
Initially it didn't work. But after some trial an error, accidentally I figured that if the image is flipped (either horizontally or vertically) the triangles must be drawn in the opposite direction.
We do this by reordering the indices of the vertices.
So instead of:
irr::u16 indices[6] = { 0, 1, 2, 3, 2, 1 };
I do:
irr::u16 indices[6] = { 0, 2, 1, 3, 1, 2 };
But if the image is not flipped in any axis, or it is flipped in both axes, then the indices stay as in the original version.
If there's anybody interested, I can post the complete final code.
http://irrlicht.sourceforge.net/forum/v ... 8&start=15
My idea was to use negative scale values in order to flip the image.
Initially it didn't work. But after some trial an error, accidentally I figured that if the image is flipped (either horizontally or vertically) the triangles must be drawn in the opposite direction.
We do this by reordering the indices of the vertices.
So instead of:
irr::u16 indices[6] = { 0, 1, 2, 3, 2, 1 };
I do:
irr::u16 indices[6] = { 0, 2, 1, 3, 1, 2 };
But if the image is not flipped in any axis, or it is flipped in both axes, then the indices stay as in the original version.
If there's anybody interested, I can post the complete final code.
Re: 2D image mirroring
I'd like do use your cod on a project of mine, can you send to me or disponibilize it here.
thanks in advance.
thanks in advance.
Re: 2D image mirroring
Here's my code.
However, I realized I used an old version of the code in the link of my previous post.
You may want to check that link. Use the updated code, and simply add this:
Code: Select all
void Animation::draw2DImage(IVideoDriver *driver, ITexture* texture,
rect<s32> sourceRect,
position2d<s32> position,
position2d<s32> rotationPoint,
f32 rotation,
vector2df scale,
bool useAlphaChannel,
SColor color)
{
SMaterial material;
// Store and clear the projection matrix
matrix4 oldProjMat = driver->getTransform(ETS_PROJECTION);
driver->setTransform(ETS_PROJECTION,matrix4());
// Store and clear the view matrix
matrix4 oldViewMat = driver->getTransform(ETS_VIEW);
driver->setTransform(ETS_VIEW,matrix4());
// Find the positions of corners
vector2df corner[4];
corner[0] = vector2df((f32)position.X, (f32)position.Y);
corner[1] = vector2df((f32)position.X + sourceRect.getWidth() * scale.X, (f32)position.Y);
corner[2] = vector2df((f32)position.X, (f32)position.Y + sourceRect.getHeight() * scale.Y);
corner[3] = vector2df((f32)position.X + sourceRect.getWidth() * scale.X, (f32)position.Y + sourceRect.getHeight() * scale.Y);
// Rotate corners
if (rotation != 0.0f)
{
for (int x = 0; x < 4; x++)
{
corner[x].rotateBy(rotation, vector2df((f32)rotationPoint.X, (f32)rotationPoint.Y));
}
}
// Find the uv coordinates of the sourceRect
vector2df uvCorner[4];
uvCorner[0] = vector2df((f32)sourceRect.UpperLeftCorner.X, (f32)sourceRect.UpperLeftCorner.Y);
uvCorner[1] = vector2df((f32)sourceRect.LowerRightCorner.X, (f32)sourceRect.UpperLeftCorner.Y);
uvCorner[2] = vector2df((f32)sourceRect.UpperLeftCorner.X, (f32)sourceRect.LowerRightCorner.Y);
uvCorner[3] = vector2df((f32)sourceRect.LowerRightCorner.X, (f32)sourceRect.LowerRightCorner.Y);
for (int x = 0; x < 4; x++)
{
f32 uvX = uvCorner[x].X / (f32)texture->getSize().Width;
f32 uvY = uvCorner[x].Y / (f32)texture->getSize().Height;
uvCorner[x] = vector2df(uvX, uvY);
}
// Vertices for the image
S3DVertex vertices[4];
u16 indices[6] = { 0, 1, 2, 3, 2, 1 }; // original & double flip
if((scale.X > 0.0f && scale.Y < 0.0f) || (scale.X < 0.0f && scale.Y > 0.0f))
{
indices[1] = 2;
indices[2] = 1;
indices[4] = 1;
indices[5] = 2;
}
//u16 indices[6] = { 0, 2, 1, 3, 1, 2 }; // single flip
// Convert pixels to world coordinates
f32 screenWidth = (f32)driver->getScreenSize().Width;
f32 screenHeight = (f32)driver->getScreenSize().Height;
for (int x = 0; x < 4; x++)
{
f32 screenPosX = ((corner[x].X / screenWidth) - 0.5f) * 2.0f;
f32 screenPosY = ((corner[x].Y / screenHeight) - 0.5f) * (-2.0f);
vertices[x].Pos = vector3df(screenPosX, screenPosY,1);
vertices[x].TCoords = uvCorner[x];
vertices[x].Color = color;
}
material.Lighting = false;
material.ZWriteEnable = false;
material.TextureLayer[0].Texture = texture;
//material.TextureLayer[0].TextureWrap = ETC_CLAMP;
if (useAlphaChannel)
material.MaterialType = EMT_TRANSPARENT_ALPHA_CHANNEL;
else
material.MaterialType = EMT_SOLID;
driver->setMaterial(material);
driver->drawIndexedTriangleList(&vertices[0], 4, &indices[0], 2);
// Restore projection and view matrices
driver->setTransform(ETS_PROJECTION, oldProjMat);
driver->setTransform(ETS_VIEW, oldViewMat);
}
You may want to check that link. Use the updated code, and simply add this:
Code: Select all
if((scale.X > 0.0f && scale.Y < 0.0f) || (scale.X < 0.0f && scale.Y > 0.0f))
{
indices[1] = 2;
indices[2] = 1;
indices[4] = 1;
indices[5] = 2;
}
Re: 2D image mirroring
thankyou very much, i am going to use it right now