2D image rotation?
2D image rotation?
Hello,
What is the best and easiest way to rotate and or scale a 2D image?
I want to create a HUD and need to rotate some images on the fly.
What is the best and easiest way to rotate and or scale a 2D image?
I want to create a HUD and need to rotate some images on the fly.
Yes. You can create plane and set texture. You can rotate plane, zooming is also will be a piece of cake if you use perspective camera. You should draw this UI after your main "smgr->drawAll()" call, to make UI to be always on top of 3d objects.RdR wrote:is there a good alternative when only using Irrilcht?
Last edited by greenya on Mon Apr 11, 2011 1:42 am, edited 1 time in total.
Thanks for your comment, but do you have a simple example?greenya wrote:Yes. You can create plane and set texture. You can rotate place, zooming is also will be a piece of cake if you use perspective camera. You should draw this UI after your main "smgr->drawAll()" call, to make UI to be always on top of 3d objects.RdR wrote:is there a good alternative when only using Irrilcht?
I believe this is under the zlib license.
Code: Select all
// draw2DImage source from Lonesome Ducky
void draw2DImage(irr::video::IVideoDriver *driver, irr::video::ITexture* texture,
irr::core::rect<irr::s32> sourceRect, irr::core::position2d<irr::s32> position,
irr::core::position2d<irr::s32> rotationPoint, irr::f32 rotation, irr::core::vector2df scale,
bool useAlphaChannel, irr::video::SColor color)
{
irr::video::SMaterial material;
// Store and clear the projection matrix
irr::core::matrix4 oldProjMat = driver->getTransform(irr::video::ETS_PROJECTION);
driver->setTransform(irr::video::ETS_PROJECTION,irr::core::matrix4());
// Store and clear the view matrix
irr::core::matrix4 oldViewMat = driver->getTransform(irr::video::ETS_VIEW);
driver->setTransform(irr::video::ETS_VIEW,irr::core::matrix4());
// Find the positions of corners
irr::core::vector2df corner[4];
corner[0] = irr::core::vector2df(position.X,position.Y);
corner[1] = irr::core::vector2df(position.X+sourceRect.getWidth()*scale.X,position.Y);
corner[2] = irr::core::vector2df(position.X,position.Y+sourceRect.getHeight()*scale.Y);
corner[3] = irr::core::vector2df(position.X+sourceRect.getWidth()*scale.X,position.Y+sourceRect.getHeight()*scale.Y);
// Rotate corners
if (rotation != 0.0f)
for (int x = 0; x < 4; x++)
corner[x].rotateBy(rotation,irr::core::vector2df(rotationPoint.X, rotationPoint.Y));
// Find the uv coordinates of the sourceRect
irr::core::vector2df uvCorner[4];
uvCorner[0] = irr::core::vector2df(sourceRect.UpperLeftCorner.X,sourceRect.UpperLeftCorner.Y);
uvCorner[1] = irr::core::vector2df(sourceRect.LowerRightCorner.X,sourceRect.UpperLeftCorner.Y);
uvCorner[2] = irr::core::vector2df(sourceRect.UpperLeftCorner.X,sourceRect.LowerRightCorner.Y);
uvCorner[3] = irr::core::vector2df(sourceRect.LowerRightCorner.X,sourceRect.LowerRightCorner.Y);
for (int x = 0; x < 4; x++) {
float uvX = uvCorner[x].X/(float)texture->getSize().Width;
float uvY = uvCorner[x].Y/(float)texture->getSize().Height;
uvCorner[x] = irr::core::vector2df(uvX,uvY);
}
// Vertices for the image
irr::video::S3DVertex vertices[4];
irr::u16 indices[6] = { 0, 1, 2, 3 ,2 ,1 };
// Convert pixels to world coordinates
float screenWidth = driver->getScreenSize().Width;
float screenHeight = driver->getScreenSize().Height;
for (int x = 0; x < 4; x++) {
float screenPosX = ((corner[x].X/screenWidth)-0.5f)*2.0f;
float screenPosY = ((corner[x].Y/screenHeight)-0.5f)*-2.0f;
vertices[x].Pos = irr::core::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.
//material.TextureLayer[0].TextureWrapU = irr::video::ETC_CLAMP;
//material.TextureLayer[0].TextureWrapV = irr::video::ETC_CLAMP;
if (useAlphaChannel)
material.MaterialType = irr::video::EMT_TRANSPARENT_ALPHA_CHANNEL;
else
material.MaterialType = irr::video::EMT_SOLID;
driver->setMaterial(material);
driver->drawIndexedTriangleList(&vertices[0],4,&indices[0],2);
// Restore projection and view matrices
driver->setTransform(irr::video::ETS_PROJECTION,oldProjMat);
driver->setTransform(irr::video::ETS_VIEW,oldViewMat);
}
Thanks cobra, I used this function instead because the above function had a weird problem aswell.
Somehow it looks like its behind everything in the world.
Here some screenshots:
If I look a bit up, so there is nothing between de camera and the image it looks good:
If I draw a normal 2D image using driver->draw2DImage() ( which I cant rotate ), everything works fine.[/url]
Somehow it looks like its behind everything in the world.
Here some screenshots:
If I look a bit up, so there is nothing between de camera and the image it looks good:
If I draw a normal 2D image using driver->draw2DImage() ( which I cant rotate ), everything works fine.[/url]
-
- Posts: 758
- Joined: Mon Mar 31, 2008 3:32 pm
- Location: Bulgaria
I am, else the other 2D images won't be visible right?shadowslair wrote:You need to draw the turret image after drawing the terrain. If you need to draw another turret over this one, you need to draw it after etc. In this case the draw call sequence matters.
I'm drawing all the 2D images (not visible in this screenshot) after the terrain, and everything is displayed correctly except the one which i'm trying to rotate (with the above function)
Edit:
The right image is using the standard draw2Image() method, they are both drawed at the same time (same method)
-
- Competition winner
- Posts: 1123
- Joined: Sun Jun 10, 2007 11:14 pm
Sorry for the very late reply, but you should make it completely disregard the zbuffer. Here's the updated code:
Code: Select all
void draw2DImage(irr::video::IVideoDriver *driver, irr::video::ITexture* texture , irr::core::rect<irr::s32> sourceRect, irr::core::position2d<irr::s32> position, irr::core::position2d<irr::s32> rotationPoint, irr::f32 rotation, irr::core::vector2df scale, bool useAlphaChannel, irr::video::SColor color) {
irr::video::SMaterial material;
// Store and clear the projection matrix
irr::core::matrix4 oldProjMat = driver->getTransform(irr::video::ETS_PROJECTION);
driver->setTransform(irr::video::ETS_PROJECTION,irr::core::matrix4());
// Store and clear the view matrix
irr::core::matrix4 oldViewMat = driver->getTransform(irr::video::ETS_VIEW);
driver->setTransform(irr::video::ETS_VIEW,irr::core::matrix4());
// Find the positions of corners
irr::core::vector2df corner[4];
corner[0] = irr::core::vector2df(position.X,position.Y);
corner[1] = irr::core::vector2df(position.X+sourceRect.getWidth()*scale.X,position.Y);
corner[2] = irr::core::vector2df(position.X,position.Y+sourceRect.getHeight()*scale.Y);
corner[3] = irr::core::vector2df(position.X+sourceRect.getWidth()*scale.X,position.Y+sourceRect.getHeight()*scale.Y);
// Rotate corners
if (rotation != 0.0f)
for (int x = 0; x < 4; x++)
corner[x].rotateBy(rotation,irr::core::vector2df(rotationPoint.X, rotationPoint.Y));
// Find the uv coordinates of the sourceRect
irr::core::vector2df uvCorner[4];
uvCorner[0] = irr::core::vector2df(sourceRect.UpperLeftCorner.X,sourceRect.UpperLeftCorner.Y);
uvCorner[1] = irr::core::vector2df(sourceRect.LowerRightCorner.X,sourceRect.UpperLeftCorner.Y);
uvCorner[2] = irr::core::vector2df(sourceRect.UpperLeftCorner.X,sourceRect.LowerRightCorner.Y);
uvCorner[3] = irr::core::vector2df(sourceRect.LowerRightCorner.X,sourceRect.LowerRightCorner.Y);
for (int x = 0; x < 4; x++) {
float uvX = uvCorner[x].X/(float)texture->getSize().Width;
float uvY = uvCorner[x].Y/(float)texture->getSize().Height;
uvCorner[x] = irr::core::vector2df(uvX,uvY);
}
// Vertices for the image
irr::video::S3DVertex vertices[4];
irr::u16 indices[6] = { 0, 1, 2, 3 ,2 ,1 };
// Convert pixels to world coordinates
float screenWidth = driver->getScreenSize().Width;
float screenHeight = driver->getScreenSize().Height;
for (int x = 0; x < 4; x++) {
float screenPosX = ((corner[x].X/screenWidth)-0.5f)*2.0f;
float screenPosY = ((corner[x].Y/screenHeight)-0.5f)*-2.0f;
vertices[x].Pos = irr::core::vector3df(screenPosX,screenPosY,1);
vertices[x].TCoords = uvCorner[x];
vertices[x].Color = color;
}
material.Lighting = false;
material.ZWriteEnable = false;
material.ZBuffer = false;
material.TextureLayer[0].Texture = texture;
material.MaterialTypeParam = irr::video::pack_texureBlendFunc(irr::video::EBF_SRC_ALPHA, irr::video::EBF_ONE_MINUS_SRC_ALPHA, irr::video::EMFN_MODULATE_1X, irr::video::EAS_TEXTURE | irr::video::EAS_VERTEX_COLOR);
if (useAlphaChannel)
material.MaterialType = irr::video::EMT_ONETEXTURE_BLEND;
else
material.MaterialType = irr::video::EMT_SOLID;
driver->setMaterial(material);
driver->drawIndexedTriangleList(&vertices[0],4,&indices[0],2);
// Restore projection and view matrices
driver->setTransform(irr::video::ETS_PROJECTION,oldProjMat);
driver->setTransform(irr::video::ETS_VIEW,oldViewMat);
}