Fix the text scene node placing in viewports. The problem was, that the calculation took the absolute viewport dimension into account, while rendering into the viewport requires the screenwidth to be taken. Hence, the text was usually misplaced. The collision method can still be used for this mixed mode calculation (get screen coordinate during viewport rendering, use it for full screen rendering), but requires an additional parameter.
Software drivers don't support 2d rendering into viewports, so they still fail to properly position text (or other 2d things) into a viewport. git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@3489 dfc29bdd-3216-0410-991c-e03cc46cb475master
parent
eff82803d3
commit
014272f2c1
|
@ -93,6 +93,10 @@ namespace scene
|
|||
into 2d.
|
||||
\param camera: Camera to be used. If null, the currently active
|
||||
camera is used.
|
||||
\param useViewPort: Calculate screen coordinates relative to
|
||||
the current view port. Please note that unless the driver does
|
||||
not take care of the view port, it is usually best to get the
|
||||
result in absolute screen coordinates (flag=false).
|
||||
\return 2d screen coordinates which a object in the 3d world
|
||||
would have if it would be rendered to the screen. If the 3d
|
||||
position is behind the camera, it is set to (-1000,-1000). In
|
||||
|
@ -100,7 +104,7 @@ namespace scene
|
|||
method for drawing a decorator over a 3d object, it will be
|
||||
clipped by the screen borders. */
|
||||
virtual core::position2d<s32> getScreenCoordinatesFrom3DPosition(
|
||||
const core::vector3df& pos, ICameraSceneNode* camera=0) = 0;
|
||||
const core::vector3df& pos, ICameraSceneNode* camera=0, bool useViewPort=false) = 0;
|
||||
|
||||
//! Gets the scene node, which is currently visible under the given screencoordinates, viewed from the currently active camera.
|
||||
/** The collision tests are done using a bounding box for each
|
||||
|
|
|
@ -874,7 +874,7 @@ core::line3d<f32> CSceneCollisionManager::getRayFromScreenCoordinates(
|
|||
|
||||
//! Calculates 2d screen position from a 3d position.
|
||||
core::position2d<s32> CSceneCollisionManager::getScreenCoordinatesFrom3DPosition(
|
||||
const core::vector3df & pos3d, ICameraSceneNode* camera)
|
||||
const core::vector3df & pos3d, ICameraSceneNode* camera, bool useViewPort)
|
||||
{
|
||||
if (!SceneManager || !Driver)
|
||||
return core::position2d<s32>(-1000,-1000);
|
||||
|
@ -885,8 +885,11 @@ core::position2d<s32> CSceneCollisionManager::getScreenCoordinatesFrom3DPosition
|
|||
if (!camera)
|
||||
return core::position2d<s32>(-1000,-1000);
|
||||
|
||||
const core::rect<s32>& viewPort = Driver->getViewPort();
|
||||
core::dimension2d<u32> dim(viewPort.getWidth(), viewPort.getHeight());
|
||||
core::dimension2d<u32> dim;
|
||||
if (useViewPort)
|
||||
dim.set(Driver->getViewPort().getWidth(), Driver->getViewPort().getHeight());
|
||||
else
|
||||
dim=(Driver->getScreenSize());
|
||||
|
||||
dim.Width /= 2;
|
||||
dim.Height /= 2;
|
||||
|
@ -905,7 +908,7 @@ core::position2d<s32> CSceneCollisionManager::getScreenCoordinatesFrom3DPosition
|
|||
core::reciprocal(transformedPos[3]);
|
||||
|
||||
return core::position2d<s32>(
|
||||
core::round32(dim.Width * transformedPos[0] * zDiv) + dim.Width,
|
||||
dim.Width + core::round32(dim.Width * (transformedPos[0] * zDiv)),
|
||||
dim.Height - core::round32(dim.Height * (transformedPos[1] * zDiv)));
|
||||
}
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ namespace scene
|
|||
|
||||
//! Calculates 2d screen position from a 3d position.
|
||||
virtual core::position2d<s32> getScreenCoordinatesFrom3DPosition(
|
||||
const core::vector3df & pos, ICameraSceneNode* camera=0);
|
||||
const core::vector3df & pos, ICameraSceneNode* camera=0, bool useViewPort=false);
|
||||
|
||||
//! Gets the scene node and nearest collision point for a ray based on
|
||||
//! the nodes' id bitmasks, bounding boxes and triangle selectors.
|
||||
|
|
|
@ -783,7 +783,6 @@ void CBurningVideoDriver::setViewPort(const core::rect<s32>& area)
|
|||
|
||||
Transformation [ ETS_CLIPSCALE ].buildNDCToDCMatrix ( ViewPort, 1 );
|
||||
|
||||
|
||||
if (CurrentShader)
|
||||
CurrentShader->setRenderTarget(RenderTargetSurface, ViewPort);
|
||||
}
|
||||
|
@ -2225,9 +2224,24 @@ void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core
|
|||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// 2d methods don't use viewPort
|
||||
core::position2di dest = destPos;
|
||||
core::recti clip=ViewPort;
|
||||
if (ViewPort.getSize().Width != ScreenSize.Width)
|
||||
{
|
||||
dest.X=ViewPort.UpperLeftCorner.X+core::round32(destPos.X*ViewPort.getWidth()/(f32)ScreenSize.Width);
|
||||
dest.Y=ViewPort.UpperLeftCorner.Y+core::round32(destPos.Y*ViewPort.getHeight()/(f32)ScreenSize.Height);
|
||||
if (clipRect)
|
||||
{
|
||||
clip.constrainTo(*clipRect);
|
||||
}
|
||||
clipRect = &clip;
|
||||
}
|
||||
#endif
|
||||
if (useAlphaChannelOfTexture)
|
||||
((CSoftwareTexture2*)texture)->getImage()->copyToWithAlpha(
|
||||
BackBuffer, destPos, sourceRect, color, clipRect);
|
||||
BackBuffer, destPos, sourceRect, color, clipRect);
|
||||
else
|
||||
((CSoftwareTexture2*)texture)->getImage()->copyTo(
|
||||
BackBuffer, destPos, sourceRect, clipRect);
|
||||
|
|
|
@ -90,7 +90,6 @@ int main(int argumentCount, char * arguments[])
|
|||
TEST(b3dAnimation);
|
||||
TEST(burningsVideo);
|
||||
TEST(cursorSetVisible);
|
||||
TEST(drawRectOutline);
|
||||
TEST(flyCircleAnimator);
|
||||
TEST(md2Animation);
|
||||
TEST(testGeometryCreator);
|
||||
|
@ -100,6 +99,7 @@ int main(int argumentCount, char * arguments[])
|
|||
// all driver checks
|
||||
TEST(videoDriver);
|
||||
TEST(drawPixel);
|
||||
TEST(drawRectOutline);
|
||||
TEST(guiDisabledMenu);
|
||||
TEST(makeColorKeyTexture);
|
||||
TEST(renderTargetTexture);
|
||||
|
@ -110,7 +110,7 @@ int main(int argumentCount, char * arguments[])
|
|||
TEST(draw2DImage);
|
||||
TEST(lights);
|
||||
TEST(twodmaterial);
|
||||
// TEST(viewPort);
|
||||
TEST(viewPort);
|
||||
TEST(mrt);
|
||||
// TODO: Needs to be fixed first.
|
||||
// TEST(projectionMatrix);
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 8.3 KiB |
Binary file not shown.
After Width: | Height: | Size: 7.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 5.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 8.2 KiB |
|
@ -81,6 +81,7 @@
|
|||
<Unit filename="transparentMaterials.cpp" />
|
||||
<Unit filename="vectorPositionDimension2d.cpp" />
|
||||
<Unit filename="videoDriver.cpp" />
|
||||
<Unit filename="viewPort.cpp" />
|
||||
<Unit filename="writeImageToFile.cpp" />
|
||||
<Unit filename="zipReader.cpp" />
|
||||
<Extensions>
|
||||
|
|
|
@ -141,6 +141,7 @@
|
|||
<ClCompile Include="transparentMaterials.cpp" />
|
||||
<ClCompile Include="vectorPositionDimension2d.cpp" />
|
||||
<ClCompile Include="videoDriver.cpp" />
|
||||
<ClCompile Include="viewPort.cpp" />
|
||||
<ClCompile Include="writeImageToFile.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -340,6 +340,10 @@
|
|||
RelativePath=".\videoDriver.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\viewPort.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\writeImageToFile.cpp"
|
||||
>
|
||||
|
|
|
@ -411,6 +411,10 @@
|
|||
RelativePath=".\videoDriver.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\viewPort.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\writeImageToFile.cpp"
|
||||
>
|
||||
|
|
|
@ -35,6 +35,8 @@ static bool renderAndLoad(video::E_DRIVER_TYPE driverType)
|
|||
|
||||
bool result = takeScreenshotAndCompareAgainstReference(driver, "-textureRenderStates.png", 100);
|
||||
|
||||
device->closeDevice();
|
||||
device->run();
|
||||
device->drop();
|
||||
|
||||
return result;
|
||||
|
@ -81,6 +83,8 @@ static bool renderAndRemove(video::E_DRIVER_TYPE driverType)
|
|||
smgr->drawAll();
|
||||
driver->endScene();
|
||||
|
||||
device->closeDevice();
|
||||
device->run();
|
||||
device->drop();
|
||||
|
||||
return true;
|
||||
|
@ -129,6 +133,8 @@ static bool testTextureMatrixInMixedScenes(video::E_DRIVER_TYPE driverType)
|
|||
|
||||
bool result = takeScreenshotAndCompareAgainstReference(driver, "-textureMatrixInMixedScenes.png", 99.8f);
|
||||
|
||||
device->closeDevice();
|
||||
device->run();
|
||||
device->drop();
|
||||
|
||||
return result;
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
// Copyright (C) 2008-2009 Colin MacDonald
|
||||
// No rights reserved: this software is in the public domain.
|
||||
|
||||
#include "testUtils.h"
|
||||
|
||||
using namespace irr;
|
||||
using namespace core;
|
||||
using namespace scene;
|
||||
using namespace video;
|
||||
using namespace io;
|
||||
using namespace gui;
|
||||
|
||||
//! Tests view ports and text rendering.
|
||||
/** The result should be as follows: We have three times the same image, a billboard with a cube and the text in front.
|
||||
They are replicated three times, one centered in the screen without viewport, one in the upper left (qurter screen) and
|
||||
one on the right (half screen). The latter is stretched due to the changed aspect ratio.
|
||||
The two viewport scenes get the texture drawn over the center as well, using draw2dimage. This should mark the proper
|
||||
image position with the top left corner of the texture.
|
||||
Finally, each scene has a checkbox drawn at the left side, vertically centered. This will show whether GUI elements adhere
|
||||
to viewports as well. */
|
||||
static bool viewPortText(E_DRIVER_TYPE driverType)
|
||||
{
|
||||
IrrlichtDevice *device = createDevice( driverType, dimension2d<u32>(160, 120), 32);
|
||||
if (!device)
|
||||
return true; // Treat a failure to create a driver as benign; this saves a lot of #ifdefs
|
||||
|
||||
IVideoDriver* driver = device->getVideoDriver();
|
||||
ISceneManager * smgr = device->getSceneManager();
|
||||
IGUIEnvironment* env = smgr->getGUIEnvironment();
|
||||
env->addCheckBox(true, core::recti(10,60,28,82));
|
||||
|
||||
IBillboardSceneNode * bnode = smgr->addBillboardSceneNode(0,dimension2d<f32>(32,32),core::vector3df(0,0,10));
|
||||
bnode->setMaterialFlag(video::EMF_LIGHTING, false);
|
||||
bnode->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
|
||||
bnode->setMaterialTexture(0, driver->getTexture("../media/fire.bmp"));
|
||||
|
||||
smgr->addTextSceneNode(device->getGUIEnvironment()->getBuiltInFont(), L"TEST", video::SColor(255,255,255,255), 0);
|
||||
smgr->addCubeSceneNode();
|
||||
smgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0));
|
||||
|
||||
driver->beginScene(true, true, SColor(255,100,101,140));
|
||||
smgr->drawAll();
|
||||
env->drawAll();
|
||||
driver->setViewPort(rect<s32>(0,0,160/2,120/2));
|
||||
smgr->drawAll();
|
||||
env->drawAll();
|
||||
driver->draw2DImage(driver->getTexture("../media/fire.bmp"), core::vector2di(160/2,120/2));
|
||||
driver->setViewPort(rect<s32>(160/2,0,160,120));
|
||||
smgr->drawAll();
|
||||
env->drawAll();
|
||||
driver->draw2DImage(driver->getTexture("../media/fire.bmp"), core::vector2di(160/2,120/2));
|
||||
driver->endScene();
|
||||
|
||||
bool result = takeScreenshotAndCompareAgainstReference(driver, "-viewPortText.png", 99.8f);
|
||||
|
||||
device->drop();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool viewPort(void)
|
||||
{
|
||||
bool passed = true;
|
||||
|
||||
logTestString("Check OpenGL driver\n");
|
||||
passed &= viewPortText(EDT_OPENGL);
|
||||
// TODO: software driver and burnings don't use view port for
|
||||
// 2d rendering, so result is pretty wrong.
|
||||
logTestString("Check Software driver\n");
|
||||
passed &= viewPortText(EDT_SOFTWARE);
|
||||
logTestString("Check Burning's Video driver\n");
|
||||
passed &= viewPortText(EDT_BURNINGSVIDEO);
|
||||
logTestString("Check Direct3D9 driver\n");
|
||||
passed &= viewPortText(EDT_DIRECT3D9);
|
||||
logTestString("Check Direct3D8 driver\n");
|
||||
passed &= viewPortText(EDT_DIRECT3D8);
|
||||
|
||||
return passed;
|
||||
}
|
||||
|
Loading…
Reference in New Issue