Next large merge from trunk, revisions 3729-3830

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@3831 dfc29bdd-3216-0410-991c-e03cc46cb475
master
hybrid 2011-06-09 07:08:47 +00:00
parent 54fa54d446
commit 7ae68647e9
122 changed files with 2698 additions and 1757 deletions

View File

@ -1,5 +1,9 @@
Changes in 1.8 (??.??.2011)
- Renamed IOSOperator::getOperationSystemVersion to getOperatingSystemVersion. Changed return type from wchar_t to core::stringc, as that's the internal representation the name is built on.
- Added IGUITabControl::insertTab, IGUITabControl::removeTab, IGUITabControl::clear and IGUITabControl::getTabAt
- Added IGUIListBox::getItemAt
- Added IGUITable::getColumnWidth
@ -262,6 +266,15 @@ The following names can be queried for the given types:
-----------------------------
Changes in 1.7.3 (??.??.2011)
- Fix crash in collada (.dae) loading
- Fix memory-leaks in example 22 MaterialViewer
- Fix array::erase which did destroy objects more than once when used with a range (thx @ RedDragCZ for reporting + testcase).
- Copy now all membervariables for CCameraSceneNode when cloning.
- ICameraSceneNode::IsOrthogonal is correctly serialized and cloned now.
- CGUIScrollBar passes unused mousemove-events now to parent element. Fixes focus-bug in ComboBox reported by REDDemon here: http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=43474&highlight=

View File

@ -322,6 +322,7 @@ int main()
node->setPosition(core::vector3df(0,-10,50));
node->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));
node->setMaterialFlag(video::EMF_LIGHTING, false);
node->setMaterialFlag(video::EMF_BLEND_OPERATION, true);
node->setMaterialType((video::E_MATERIAL_TYPE)newMaterialType2);
smgr->addTextSceneNode(gui->getBuiltInFont(),

View File

@ -75,18 +75,11 @@ int main()
smgr->setAmbientLight(video::SColor(0,60,60,60));
/*
The next is just some standard stuff: Add a user controlled camera to
the scene, disable mouse cursor, and add a test cube and let it rotate
to make the scene more interesting.
The next is just some standard stuff: Add a test cube and let it rotate
to make the scene more interesting. The user defined camera and cursor
setup is made later on, right before the render loop.
*/
// add fps camera
scene::ICameraSceneNode* fpsCamera = smgr->addCameraSceneNodeFPS();
fpsCamera->setPosition(core::vector3df(-50,50,-150));
// disable mouse cursor
device->getCursorControl()->setVisible(false);
// create test cube
scene::ISceneNode* test = smgr->addCubeSceneNode(60);
@ -145,6 +138,13 @@ int main()
text->setOverrideColor(video::SColor(100,255,255,255));
}
// add fps camera
scene::ICameraSceneNode* fpsCamera = smgr->addCameraSceneNodeFPS();
fpsCamera->setPosition(core::vector3df(-50,50,-150));
// disable mouse cursor
device->getCursorControl()->setVisible(false);
/*
Nearly finished. Now we need to draw everything. Every frame, we draw
the scene twice. Once from the fixed camera into the render target

View File

@ -311,7 +311,8 @@ public:
{
ControlAmbientColor->drop();
ControlDiffuseColor->drop();
ControlEmissiveColor->drop();
if ( ControlEmissiveColor )
ControlEmissiveColor->drop();
ControlSpecularColor->drop();
}
@ -346,7 +347,7 @@ public:
}
// Update all changed colors in the light data
void updateMaterialColors(video::SLight & lightData)
void updateLightColors(video::SLight & lightData)
{
if ( ControlAmbientColor->isDirty() )
lightData.AmbientColor = video::SColorf( ControlAmbientColor->getColor() );
@ -362,7 +363,8 @@ public:
ControlAmbientColor->resetDirty();
ControlDiffuseColor->resetDirty();
ControlSpecularColor->resetDirty();
ControlEmissiveColor->resetDirty();
if ( ControlEmissiveColor )
ControlEmissiveColor->resetDirty();
}
protected:
@ -500,6 +502,8 @@ struct SMeshNodeControl
TextureControl2->drop();
if ( ControlVertexColors )
ControlVertexColors->drop();
if ( AllColorsControl )
AllColorsControl->drop();
}
void init(scene::IMeshSceneNode* node, IrrlichtDevice * device, const core::position2d<s32> & pos, const wchar_t * description)
@ -666,6 +670,12 @@ struct SLightNodeControl
{
}
virtual ~SLightNodeControl()
{
if ( AllColorsControl )
AllColorsControl->drop();
}
void init(scene::ILightSceneNode* node, gui::IGUIEnvironment* guiEnv, const core::position2d<s32> & pos, const wchar_t * description)
{
if ( Initialized || !node || !guiEnv) // initializing twice or with invalid data not allowed
@ -683,7 +693,7 @@ struct SLightNodeControl
return;
video::SLight & lightData = SceneNode->getLightData();
AllColorsControl->updateMaterialColors(lightData);
AllColorsControl->updateLightColors(lightData);
}
protected:
@ -797,7 +807,7 @@ protected:
return false;
Device->setWindowCaption( DriverTypeNames[Config.DriverType] );
Device->setEventReceiver(this);
scene::ISceneManager* smgr = Device->getSceneManager();
video::IVideoDriver * driver = Device->getVideoDriver ();
gui::IGUIEnvironment* guiEnv = Device->getGUIEnvironment();
@ -807,7 +817,7 @@ protected:
gui::IGUIFont* font = guiEnv->getFont("../../media/fonthaettenschweiler.bmp");
if (font)
skin->setFont(font);
// remove some alpha value because it makes those menus harder to read otherwise
video::SColor col3dHighLight( skin->getColor(gui::EGDC_APP_WORKSPACE) );
col3dHighLight.setAlpha(255);
@ -818,7 +828,7 @@ protected:
// Add some textures which are useful to test material settings
createDefaultTextures(driver);
// create a menu
// create a menu
gui::IGUIContextMenu * menuBar = guiEnv->addMenu();
menuBar->addItem(L"File", -1, true, true);
@ -850,7 +860,7 @@ protected:
video::SColorf(1.0f, 1.0f, 1.0f),
100.0f);
LightControl.init(nodeLight, guiEnv, core::position2d<s32>(270,20), L"light" );
// one large cube around everything. That's mainly to make the light more obvious.
scene::IMeshSceneNode* backgroundCube = smgr->addCubeSceneNode (200.0f, 0, -1, core::vector3df(0, 0, 0),
core::vector3df(45, 0, 0),
@ -1001,6 +1011,8 @@ protected:
}
}
driver->addTexture (io::path("GRAYSCALE_A8R8G8B8"), imageA8R8G8B8);
imageA8R8G8B8->drop();
}
// Load a texture and make sure nodes know it when more textures are available.

View File

@ -115,6 +115,9 @@ namespace video
//! Support for different blend functions. Without, only ADD is available
EVDF_BLEND_OPERATIONS,
//! Support for texture coord transformation via texture matrix
EVDF_TEXTURE_MATRIX,
//! Only used for counting the elements of this enum
EVDF_COUNT
};

View File

@ -43,7 +43,7 @@ struct SAttributeReadWriteOptions
s32 Flags;
//! Optional filename
const c8* Filename;
const fschar_t* Filename;
};

View File

@ -166,8 +166,34 @@ namespace scene
/** @see bindTargetAndRotation() */
virtual bool getTargetAndRotationBinding(void) const =0;
//! Writes attributes of the camera node
virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const
{
ISceneNode::serializeAttributes(out, options);
if (!out)
return;
out->addBool ("IsOrthogonal", IsOrthogonal );
}
//! Reads attributes of the camera node
virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0)
{
ISceneNode::deserializeAttributes(in, options);
if (!in)
return;
if ( in->findAttribute("IsOrthogonal") )
IsOrthogonal = in->getAttributeAsBool("IsOrthogonal");
}
protected:
void cloneMembers(ICameraSceneNode* toCopyFrom)
{
IsOrthogonal = toCopyFrom->IsOrthogonal;
}
bool IsOrthogonal;
};

View File

@ -23,8 +23,10 @@ namespace gui
IGUITab(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle)
: IGUIElement(EGUIET_TAB, environment, parent, id, rectangle) {}
//! Returns number of tab if in tabcontrol.
/** Can be accessed later IGUITabControl::getTab() by this number. */
//! Returns zero based index of tab if in tabcontrol.
/** Can be accessed later IGUITabControl::getTab() by this number.
Note that this number can change when other tabs are inserted or removed .
*/
virtual s32 getNumber() const = 0;
//! sets if the tab should draw its background
@ -58,6 +60,16 @@ namespace gui
//! Adds a tab
virtual IGUITab* addTab(const wchar_t* caption, s32 id=-1) = 0;
//! Insert the tab at the given index
/** \return The tab on success or NULL on failure. */
virtual IGUITab* insertTab(s32 idx, const wchar_t* caption, s32 id=-1) = 0;
//! Removes a tab from the tabcontrol
virtual void removeTab(s32 idx) = 0;
//! Clears the tabcontrol removing all tabs
virtual void clear() = 0;
//! Returns amount of tabs in the tabcontrol
virtual s32 getTabCount() const = 0;
@ -80,6 +92,10 @@ namespace gui
//! Returns which tab is currently active
virtual s32 getActiveTab() const = 0;
//! get the the id of the tab at the given absolute coordinates
/** \return The id of the tab or -1 when no tab is at those coordinates*/
virtual s32 getTabAt(s32 xpos, s32 ypos) const = 0;
//! Set the height of the tabs
virtual void setTabHeight( s32 height ) = 0;

View File

@ -44,6 +44,14 @@ namespace scene
apply(scene::SVertexColorSetAlphaManipulator(alpha), mesh);
}
//! Sets the alpha vertex color value of the whole mesh to a new value.
/** \param buffer Meshbuffer on which the operation is performed.
\param alpha New alpha value. Must be a value between 0 and 255. */
void setVertexColorAlpha(IMeshBuffer* buffer, s32 alpha) const
{
apply(scene::SVertexColorSetAlphaManipulator(alpha), buffer);
}
//! Sets the colors of all vertices to one color
/** \param mesh Mesh on which the operation is performed.
\param color New color. */
@ -52,17 +60,27 @@ namespace scene
apply(scene::SVertexColorSetManipulator(color), mesh);
}
//! Sets the colors of all vertices to one color
/** \param buffer Meshbuffer on which the operation is performed.
\param color New color. */
void setVertexColors(IMeshBuffer* buffer, video::SColor color) const
{
apply(scene::SVertexColorSetManipulator(color), buffer);
}
//! Recalculates all normals of the mesh.
/** \param mesh: Mesh on which the operation is performed.
\param smooth: If the normals shall be smoothed.
\param angleWeighted: If the normals shall be smoothed in relation to their angles. More expensive, but also higher precision. */
virtual void recalculateNormals(IMesh* mesh, bool smooth = false, bool angleWeighted = false) const = 0;
virtual void recalculateNormals(IMesh* mesh, bool smooth = false,
bool angleWeighted = false) const=0;
//! Recalculates all normals of the mesh buffer.
/** \param buffer: Mesh buffer on which the operation is performed.
\param smooth: If the normals shall be smoothed.
\param angleWeighted: If the normals shall be smoothed in relation to their angles. More expensive, but also higher precision. */
virtual void recalculateNormals(IMeshBuffer* buffer, bool smooth = false, bool angleWeighted = false) const = 0;
virtual void recalculateNormals(IMeshBuffer* buffer,
bool smooth = false, bool angleWeighted = false) const=0;
//! Recalculates tangents, requires a tangent mesh
/** \param mesh Mesh on which the operation is performed.
@ -74,6 +92,16 @@ namespace scene
bool recalculateNormals=false, bool smooth=false,
bool angleWeighted=false) const=0;
//! Recalculates tangents, requires a tangent mesh buffer
/** \param buffer Meshbuffer on which the operation is performed.
\param recalculateNormals If the normals shall be recalculated, otherwise original normals of the buffer are used unchanged.
\param smooth If the normals shall be smoothed.
\param angleWeighted If the normals shall be smoothed in relation to their angles. More expensive, but also higher precision.
*/
virtual void recalculateTangents(IMeshBuffer* buffer,
bool recalculateNormals=false, bool smooth=false,
bool angleWeighted=false) const=0;
//! Scales the actual mesh, not a scene node.
/** \param mesh Mesh on which the operation is performed.
\param factor Scale factor for each axis. */
@ -136,28 +164,31 @@ namespace scene
\param m transformation matrix. */
_IRR_DEPRECATED_ virtual void transformMesh(IMesh* mesh, const core::matrix4& m) const {return transform(mesh,m);}
//! Clones a static IMesh into a modifiable SMesh.
/** All meshbuffers in the returned SMesh
are of type SMeshBuffer or SMeshBufferLightMap.
\param mesh Mesh to copy.
\return Cloned mesh. If you no longer need the
cloned mesh, you should call SMesh::drop(). See
IReferenceCounted::drop() for more information. */
virtual SMesh* createMeshCopy(IMesh* mesh) const = 0;
//! Creates a planar texture mapping on the mesh
/** \param mesh: Mesh on which the operation is performed.
\param resolution: resolution of the planar mapping. This is
the value specifying which is the relation between world space
and texture coordinate space. */
virtual void makePlanarTextureMapping(IMesh* mesh, f32 resolution=0.001f) const =0;
virtual void makePlanarTextureMapping(IMesh* mesh, f32 resolution=0.001f) const=0;
//! Creates a planar texture mapping on the meshbuffer
/** \param meshbuffer: Buffer on which the operation is performed.
\param resolution: resolution of the planar mapping. This is
the value specifying which is the relation between world space
and texture coordinate space. */
virtual void makePlanarTextureMapping(scene::IMeshBuffer* meshbuffer, f32 resolution=0.001f) const =0;
virtual void makePlanarTextureMapping(scene::IMeshBuffer* meshbuffer, f32 resolution=0.001f) const=0;
//! Creates a planar texture mapping on the buffer
/** This method is currently implemented towards the LWO planar mapping. A more general biasing might be required.
\param mesh Mesh on which the operation is performed.
\param resolutionS Resolution of the planar mapping in horizontal direction. This is the ratio between object space and texture space.
\param resolutionT Resolution of the planar mapping in vertical direction. This is the ratio between object space and texture space.
\param axis The axis along which the texture is projected. The allowed values are 0 (X), 1(Y), and 2(Z).
\param offset Vector added to the vertex positions (in object coordinates).
*/
virtual void makePlanarTextureMapping(scene::IMesh* mesh,
f32 resolutionS, f32 resolutionT,
u8 axis, const core::vector3df& offset) const=0;
//! Creates a planar texture mapping on the meshbuffer
/** This method is currently implemented towards the LWO planar mapping. A more general biasing might be required.
@ -167,7 +198,18 @@ namespace scene
\param axis The axis along which the texture is projected. The allowed values are 0 (X), 1(Y), and 2(Z).
\param offset Vector added to the vertex positions (in object coordinates).
*/
virtual void makePlanarTextureMapping(scene::IMeshBuffer* buffer, f32 resolutionS, f32 resolutionT, u8 axis, const core::vector3df& offset) const =0;
virtual void makePlanarTextureMapping(scene::IMeshBuffer* buffer,
f32 resolutionS, f32 resolutionT,
u8 axis, const core::vector3df& offset) const=0;
//! Clones a static IMesh into a modifiable SMesh.
/** All meshbuffers in the returned SMesh
are of type SMeshBuffer or SMeshBufferLightMap.
\param mesh Mesh to copy.
\return Cloned mesh. If you no longer need the
cloned mesh, you should call SMesh::drop(). See
IReferenceCounted::drop() for more information. */
virtual SMesh* createMeshCopy(IMesh* mesh) const = 0;
//! Creates a copy of the mesh, which will only consist of S3DVertexTangents vertices.
/** This is useful if you want to draw tangent space normal
@ -186,7 +228,9 @@ namespace scene
you no longer need the cloned mesh, you should call
IMesh::drop(). See IReferenceCounted::drop() for more
information. */
virtual IMesh* createMeshWithTangents(IMesh* mesh, bool recalculateNormals=false, bool smooth=false, bool angleWeighted=false, bool recalculateTangents=true) const = 0;
virtual IMesh* createMeshWithTangents(IMesh* mesh,
bool recalculateNormals=false, bool smooth=false,
bool angleWeighted=false, bool recalculateTangents=true) const=0;
//! Creates a copy of the mesh, which will only consist of S3DVertex2TCoord vertices.
/** \param mesh Input mesh

View File

@ -6,6 +6,7 @@
#define __I_OS_OPERATOR_H_INCLUDED__
#include "IReferenceCounted.h"
#include "irrString.h"
namespace irr
{
@ -14,12 +15,15 @@ namespace irr
class IOSOperator : public virtual IReferenceCounted
{
public:
//! Destructor
virtual ~IOSOperator() {}
//! Get the current operation system version as string.
virtual const core::stringc& getOperatingSystemVersion() const = 0;
//! Get the current operation system version as string.
virtual const wchar_t* getOperationSystemVersion() const = 0;
/** \deprecated Use getOperatingSystemVersion instead. This method will be removed in Irrlicht 1.9. */
_IRR_DEPRECATED_ const wchar_t* getOperationSystemVersion() const
{
return core::stringw(getOperatingSystemVersion()).c_str();
}
//! Copies text to the clipboard
virtual void copyToClipboard(const c8* text) const = 0;
@ -44,4 +48,3 @@ public:
} // end namespace
#endif

View File

@ -722,19 +722,23 @@ namespace scene
//! Adds a billboard scene node to the scene graph.
/** A billboard is like a 3d sprite: A 2d element,
which always looks to the camera. It is usually used for things like explosions, fire,
lensflares and things like that.
\param parent: Parent scene node of the billboard. Can be null. If the parent moves,
the billboard will move too.
\param position: Position of the space relative to its parent
which always looks to the camera. It is usually used for things
like explosions, fire, lensflares and things like that.
\param parent Parent scene node of the billboard. Can be null.
If the parent moves, the billboard will move too.
\param size Size of the billboard. This size is 2 dimensional
because a billboard only has width and height.
\param position Position of the space relative to its parent
where the billboard will be placed.
\param size: Size of the billboard. This size is 2 dimensional because a billboard only has
width and height.
\param id: An id of the node. This id can be used to identify the node.
\param colorTop: The color of the vertices at the top of the billboard (default: white).
\param colorBottom: The color of the vertices at the bottom of the billboard (default: white).
\param id An id of the node. This id can be used to identify
the node.
\param colorTop The color of the vertices at the top of the
billboard (default: white).
\param colorBottom The color of the vertices at the bottom of
the billboard (default: white).
\return Pointer to the billboard if successful, otherwise NULL.
This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
This pointer should not be dropped. See
IReferenceCounted::drop() for more information. */
virtual IBillboardSceneNode* addBillboardSceneNode(ISceneNode* parent = 0,
const core::dimension2d<f32>& size = core::dimension2d<f32>(10.0f, 10.0f),
const core::vector3df& position = core::vector3df(0,0,0), s32 id=-1,

View File

@ -1357,7 +1357,7 @@ namespace video
//! Make a screenshot of the last rendered frame.
/** \return An image created from the last rendered frame. */
virtual IImage* createScreenShot() =0;
virtual IImage* createScreenShot(video::ECOLOR_FORMAT format=video::ECF_UNKNOWN, video::E_RENDER_TARGET target=video::ERT_FRAME_BUFFER) =0;
//! Check if the image is already loaded.
/** Works similar to getTexture(), but does not load the texture

View File

@ -122,14 +122,6 @@
#undef _IRR_COMPILE_WITH_JOYSTICK_EVENTS_
#endif
//! Define _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_ if you want to use DirectInput for joystick handling.
/** This only applies to Windows devices, currently only supported under Win32 device.
If not defined, Windows Multimedia library is used, which offers also broad support for joystick devices. */
#define _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_
#ifdef NO_IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_
#undef _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_
#endif
//! Maximum number of texture an SMaterial can have, up to 8 are supported by Irrlicht.
#define _IRR_MATERIAL_MAX_TEXTURES_ 4
@ -151,6 +143,14 @@ headers, e.g. Summer 2004. This is a Microsoft issue, not an Irrlicht one.
*/
#if defined(_IRR_WINDOWS_API_) && (!defined(__GNUC__) || defined(IRR_COMPILE_WITH_DX9_DEV_PACK))
//! Define _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_ if you want to use DirectInput for joystick handling.
/** This only applies to Windows devices, currently only supported under Win32 device.
If not defined, Windows Multimedia library is used, which offers also broad support for joystick devices. */
#define _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_
#ifdef NO_IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_
#undef _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_
#endif
//! Only define _IRR_COMPILE_WITH_DIRECT3D_8_ if you have an appropriate DXSDK, e.g. Summer 2004
// #define _IRR_COMPILE_WITH_DIRECT3D_8_
#define _IRR_COMPILE_WITH_DIRECT3D_9_

View File

@ -540,7 +540,7 @@ namespace video
return SColorf (r * mul0 + c1.r * mul1 + c2.r * mul2,
g * mul0 + c1.g * mul1 + c2.g * mul2,
g * mul0 + c1.b * mul1 + c2.b * mul2,
b * mul0 + c1.b * mul1 + c2.b * mul2,
a * mul0 + c1.a * mul1 + c2.a * mul2);
}

View File

@ -29,6 +29,7 @@ namespace irr
Stencilbuffer(false),
Vsync(false),
AntiAlias(0),
HandleSRGB(false),
WithAlphaChannel(false),
Doublebuffer(true),
IgnoreInput(false),
@ -62,6 +63,7 @@ namespace irr
Stencilbuffer = other.Stencilbuffer;
Vsync = other.Vsync;
AntiAlias = other.AntiAlias;
HandleSRGB = other.HandleSRGB;
WithAlphaChannel = other.WithAlphaChannel;
Doublebuffer = other.Doublebuffer;
IgnoreInput = other.IgnoreInput;
@ -140,6 +142,21 @@ namespace irr
Default value: 0 - disabled */
u8 AntiAlias;
//! Flag to enable proper sRGB and linear color handling
/** In most situations, it is desireable to have the color handling in
non-linear sRGB color space, and only do the intermediate color
calculations in linear RGB space. If this flag is enabled, the device and
driver try to assure that all color input and output are color corrected
and only the internal color representation is linear. This means, that
the color output is properly gamma-adjusted to provide the brighter
colors for monitor display. And that blending and lighting give a more
natural look, due to proper conversion from non-linear colors into linear
color space for blend operations. If this flag is enabled, all texture colors
(which are usually in sRGB space) are correctly displayed. However vertex colors
and other explicitly set values have to be manually encoded in linear color space.
Default value: false. */
bool HandleSRGB;
//! Whether the main framebuffer uses an alpha channel.
/** In some situations it might be desireable to get a color
buffer with an alpha channel, e.g. when rendering into a

View File

@ -558,12 +558,12 @@ public:
for (i=index+count; i<used; ++i)
{
if (i > index+count)
if (i-count >= index+count) // not already destructed before loop
allocator.destruct(&data[i-count]);
allocator.construct(&data[i-count], data[i]); // data[i-count] = data[i];
if (i >= used-count)
if (i >= used-count) // those which are not overwritten
allocator.destruct(&data[i]);
}

View File

@ -130,8 +130,10 @@ strings
*/
#if defined(_IRR_WCHAR_FILESYSTEM)
typedef wchar_t fschar_t;
#define _IRR_TEXT(X) L##X
#else
typedef char fschar_t;
#define _IRR_TEXT(X) X
#endif
} // end namespace irr

View File

@ -213,24 +213,23 @@ public:
return Y < 0 ? 90 : 270;
// don't use getLength here to avoid precision loss with s32 vectors
f64 tmp = Y / sqrt((f64)(X*X + Y*Y));
if ( tmp > 1.0 ) // avoid floating-point trouble as sqrt(y*y) is occasionally larger y
tmp = 1.0;
tmp = atan( core::squareroot(1 - tmp*tmp) / tmp) * RADTODEG64;
// avoid floating-point trouble as sqrt(y*y) is occasionally larger than y, so clamp
const f64 tmp = core::clamp(Y / sqrt((f64)(X*X + Y*Y)), -1.0, 1.0);
const f64 angle = atan( core::squareroot(1 - tmp*tmp) / tmp) * RADTODEG64;
if (X>0 && Y>0)
return tmp + 270;
return angle + 270;
else
if (X>0 && Y<0)
return tmp + 90;
return angle + 90;
else
if (X<0 && Y<0)
return 90 - tmp;
return 90 - angle;
else
if (X<0 && Y>0)
return 270 - tmp;
return 270 - angle;
return tmp;
return angle;
}
//! Calculates the angle between this vector and another one in degree.

View File

@ -127,8 +127,8 @@ namespace scene
inline void VectorTransform(const vec3_hl in1, const f32 in2[3][4], core::vector3df& out)
{
out.X = DotProduct(in1, in2[0]) + in2[0][3];
out.Y = DotProduct(in1, in2[1]) + in2[1][3];
out.Z = DotProduct(in1, in2[2]) + in2[2][3];
out.Z = DotProduct(in1, in2[1]) + in2[1][3];
out.Y = DotProduct(in1, in2[2]) + in2[2][3];
}
static f32 BoneTransform[MAXSTUDIOBONES][3][4]; // bone transformation matrix
@ -910,7 +910,7 @@ void STextureAtlas::create(u32 border, E_TEXTURE_CLAMP texmode)
// build image
core::dimension2d<u32> dim = core::dimension2d<u32>( wsum, hsum ).getOptimalSize();
IImage* master = new CImage( format, dim );
IImage* master = new CImage(format, dim);
master->fill(0);
video::SColor col[2];
@ -1020,7 +1020,7 @@ SHalflifeHeader* CAnimatedMeshHalfLife::loadModel(io::IReadFile* file, const io:
}
}
IImage* image = new CImage( ECF_R8G8B8, core::dimension2d<u32>(tex[i].width, tex[i].height) );
IImage* image = SceneManager->getVideoDriver()->createImage(ECF_R8G8B8, core::dimension2d<u32>(tex[i].width, tex[i].height));
CColorConverter::convert8BitTo24Bit(src, (u8*)image->lock(), tex[i].width, tex[i].height, (u8*) palette, 0, false);
image->unlock();

View File

@ -146,7 +146,9 @@ namespace scene
} PACK_STRUCT;
#ifndef ZONE_H
typedef void *cache_user_t;
// NOTE: this was a void*, but that crashes on 64bit.
// I have found no mdl format desc, so not sure what it's meant to be, but s32 at least works.
typedef s32 cache_user_t;
#endif
// demand loaded sequence groups

View File

@ -1233,6 +1233,57 @@ static s32 StretchBlit(eBlitter operation,
return 1;
}
// Methods for Software drivers
//! draws a rectangle
static void drawRectangle(video::IImage* img, const core::rect<s32>& rect, const video::SColor &color)
{
Blit(color.getAlpha() == 0xFF ? BLITTER_COLOR : BLITTER_COLOR_ALPHA,
img, 0, &rect.UpperLeftCorner, 0, &rect, color.color);
}
//! draws a line from to with color
static void drawLine(video::IImage* img, const core::position2d<s32>& from,
const core::position2d<s32>& to, const video::SColor &color)
{
AbsRectangle clip;
GetClip(clip, img);
core::position2d<s32> p[2];
if (ClipLine( clip, p[0], p[1], from, to))
{
u32 alpha = extractAlpha(color.color);
switch(img->getColorFormat())
{
case video::ECF_A1R5G5B5:
if (alpha == 256)
{
RenderLine16_Decal(img, p[0], p[1], video::A8R8G8B8toA1R5G5B5(color.color));
}
else
{
RenderLine16_Blend(img, p[0], p[1], video::A8R8G8B8toA1R5G5B5(color.color), alpha >> 3);
}
break;
case video::ECF_A8R8G8B8:
if (alpha == 256)
{
RenderLine32_Decal(img, p[0], p[1], color.color);
}
else
{
RenderLine32_Blend(img, p[0], p[1], color.color, alpha);
}
break;
default:
break;
}
}
}
}
#endif

View File

@ -301,7 +301,7 @@ void CCameraSceneNode::recalculateViewArea()
//! Writes attributes of the scene node.
void CCameraSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
{
ISceneNode::serializeAttributes(out, options);
ICameraSceneNode::serializeAttributes(out, options);
out->addVector3d("Target", Target);
out->addVector3d("UpVector", UpVector);
@ -310,13 +310,13 @@ void CCameraSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeR
out->addFloat("ZNear", ZNear);
out->addFloat("ZFar", ZFar);
out->addBool("Binding", TargetAndRotationAreBound);
out->addBool("ReceiveInput", InputReceiverEnabled);
}
//! Reads attributes of the scene node.
void CCameraSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
{
ISceneNode::deserializeAttributes(in, options);
ICameraSceneNode::deserializeAttributes(in, options);
Target = in->getAttributeAsVector3d("Target");
UpVector = in->getAttributeAsVector3d("UpVector");
@ -325,6 +325,8 @@ void CCameraSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttribute
ZNear = in->getAttributeAsFloat("ZNear");
ZFar = in->getAttributeAsFloat("ZFar");
TargetAndRotationAreBound = in->getAttributeAsBool("Binding");
if ( in->findAttribute("ReceiveInput") )
InputReceiverEnabled = in->getAttributeAsBool("InputReceiverEnabled");
recalculateProjectionMatrix();
recalculateViewArea();
@ -348,6 +350,8 @@ bool CCameraSceneNode::getTargetAndRotationBinding(void) const
//! Creates a clone of this scene node and its children.
ISceneNode* CCameraSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager)
{
ICameraSceneNode::clone(newParent, newManager);
if (!newParent)
newParent = Parent;
if (!newManager)
@ -356,7 +360,19 @@ ISceneNode* CCameraSceneNode::clone(ISceneNode* newParent, ISceneManager* newMan
CCameraSceneNode* nb = new CCameraSceneNode(newParent,
newManager, ID, RelativeTranslation, Target);
nb->cloneMembers(this, newManager);
nb->ISceneNode::cloneMembers(this, newManager);
nb->ICameraSceneNode::cloneMembers(this);
nb->Target = Target;
nb->UpVector = UpVector;
nb->Fovy = Fovy;
nb->Aspect = Aspect;
nb->ZNear = ZNear;
nb->ZFar = ZFar;
nb->ViewArea = ViewArea;
nb->Affector = Affector;
nb->InputReceiverEnabled = InputReceiverEnabled;
nb->TargetAndRotationAreBound = TargetAndRotationAreBound;
if ( newParent )
nb->drop();

View File

@ -2191,7 +2191,7 @@ void CColladaFileLoader::readPolygonSection(io::IXMLReaderUTF8* reader,
}
else
{
for (u32 ind = 0; i+2 < indices.size(); ++ind)
for (u32 ind = 0; ind+2 < indices.size(); ++ind)
{
mbuffer->Indices.push_back(indices[0]);
mbuffer->Indices.push_back(indices[ind+1]);

View File

@ -79,7 +79,7 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
L"version", L"1.4.1");
Writer->writeLineBreak();
// write asset data
// write asset data
Writer->writeElement(L"asset", false);
Writer->writeLineBreak();
@ -165,92 +165,41 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
io::IAttributes* attributes = VideoDriver->createAttributesFromMaterial(
mesh->getMeshBuffer(i)->getMaterial());
u32 count = attributes->getAttributeCount();
for (u32 attridx=0; attridx<count; ++attridx)
// attributes must be written in fixed order
core::stringc str;
s32 attridx = attributes->findAttribute("Emissive");
if ( attridx >= 0 )
{
core::stringc str = attributes->getAttributeName(attridx);
if (str=="Emissive")
{
Writer->writeElement(L"emission", false);
Writer->writeLineBreak();
Writer->writeElement(L"color", false);
Writer->writeLineBreak();
writeColorAttribute(L"emission", attributes, attridx);
}
attridx = attributes->findAttribute("Ambient");
if ( attridx >= 0 )
{
writeColorAttribute(L"ambient", attributes, attridx);
}
attridx = attributes->findAttribute("Diffuse");
if ( attridx >= 0 )
{
writeColorAttribute(L"diffuse", attributes, attridx);
}
attridx = attributes->findAttribute("Specular");
if ( attridx >= 0 )
{
writeColorAttribute(L"specular", attributes, attridx);
}
attridx = attributes->findAttribute("Shininess");
if ( attridx >= 0 )
{
Writer->writeElement(L"shininess", false);
Writer->writeLineBreak();
Writer->writeElement(L"float", false);
str = attributes->getAttributeAsString(attridx);
str.replace(',',' ');
Writer->writeText(core::stringw(str.c_str()).c_str());
Writer->writeText(core::stringw(attributes->getAttributeAsString(attridx).c_str()).c_str());
Writer->writeClosingTag(L"color");
Writer->writeLineBreak();
Writer->writeClosingTag(L"emission");
Writer->writeLineBreak();
}
else
if (str=="Ambient")
{
Writer->writeElement(L"ambient", false);
Writer->writeLineBreak();
Writer->writeElement(L"color", false);
Writer->writeLineBreak();
str = attributes->getAttributeAsString(attridx);
str.replace(',',' ');
Writer->writeText(core::stringw(str.c_str()).c_str());
Writer->writeClosingTag(L"color");
Writer->writeLineBreak();
Writer->writeClosingTag(L"ambient");
Writer->writeLineBreak();
}
else
if (str=="Diffuse")
{
Writer->writeElement(L"diffuse", false);
Writer->writeLineBreak();
Writer->writeElement(L"color", false);
Writer->writeLineBreak();
str = attributes->getAttributeAsString(attridx);
str.replace(',',' ');
Writer->writeText(core::stringw(str.c_str()).c_str());
Writer->writeClosingTag(L"color");
Writer->writeLineBreak();
Writer->writeClosingTag(L"diffuse");
Writer->writeLineBreak();
}
else
if (str=="Specular")
{
Writer->writeElement(L"specular", false);
Writer->writeLineBreak();
Writer->writeElement(L"color", false);
Writer->writeLineBreak();
str = attributes->getAttributeAsString(attridx);
str.replace(',',' ');
Writer->writeText(core::stringw(str.c_str()).c_str());
Writer->writeClosingTag(L"color");
Writer->writeLineBreak();
Writer->writeClosingTag(L"specular");
Writer->writeLineBreak();
}
else
if (str=="Shininess")
{
Writer->writeElement(L"shininess", false);
Writer->writeLineBreak();
Writer->writeElement(L"float", false);
Writer->writeLineBreak();
Writer->writeText(core::stringw(attributes->getAttributeAsString(attridx).c_str()).c_str());
Writer->writeClosingTag(L"float");
Writer->writeLineBreak();
Writer->writeClosingTag(L"shininess");
Writer->writeLineBreak();
}
Writer->writeClosingTag(L"float");
Writer->writeLineBreak();
Writer->writeClosingTag(L"shininess");
Writer->writeLineBreak();
}
attributes->drop();
@ -332,14 +281,7 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
video::S3DVertex* vtx = (video::S3DVertex*)buffer->getVertices();
for (u32 j=0; j<vertexCount; ++j)
{
core::stringw str;
str += vtx[j].Pos.X;
str += " ";
str += vtx[j].Pos.Y;
str += " ";
str += vtx[j].Pos.Z;
Writer->writeText(str.c_str());
Writer->writeText(toString(vtx[j].Pos).c_str());
Writer->writeLineBreak();
}
}
@ -349,14 +291,7 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buffer->getVertices();
for (u32 j=0; j<vertexCount; ++j)
{
core::stringw str;
str += vtx[j].Pos.X;
str += " ";
str += vtx[j].Pos.Y;
str += " ";
str += vtx[j].Pos.Z;
Writer->writeText(str.c_str());
Writer->writeText(toString(vtx[j].Pos).c_str());
Writer->writeLineBreak();
}
}
@ -366,14 +301,7 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
video::S3DVertexTangents* vtx = (video::S3DVertexTangents*)buffer->getVertices();
for (u32 j=0; j<vertexCount; ++j)
{
core::stringw str;
str += vtx[j].Pos.X;
str += " ";
str += vtx[j].Pos.Y;
str += " ";
str += vtx[j].Pos.Z;
Writer->writeText(str.c_str());
Writer->writeText(toString(vtx[j].Pos).c_str());
Writer->writeLineBreak();
}
}
@ -439,12 +367,7 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
video::S3DVertex* vtx = (video::S3DVertex*)buffer->getVertices();
for (u32 j=0; j<vertexCount; ++j)
{
core::stringw str;
str += vtx[j].TCoords.X;
str += " ";
str += vtx[j].TCoords.Y;
Writer->writeText(str.c_str());
Writer->writeText(toString(vtx[j].TCoords).c_str());
Writer->writeLineBreak();
}
}
@ -454,12 +377,7 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buffer->getVertices();
for (u32 j=0; j<vertexCount; ++j)
{
core::stringw str;
str += vtx[j].TCoords.X;
str += " ";
str += vtx[j].TCoords.Y;
Writer->writeText(str.c_str());
Writer->writeText(toString(vtx[j].TCoords).c_str());
Writer->writeLineBreak();
}
}
@ -469,12 +387,7 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
video::S3DVertexTangents* vtx = (video::S3DVertexTangents*)buffer->getVertices();
for (u32 j=0; j<vertexCount; ++j)
{
core::stringw str;
str += vtx[j].TCoords.X;
str += " ";
str += vtx[j].TCoords.Y;
Writer->writeText(str.c_str());
Writer->writeText(toString(vtx[j].TCoords).c_str());
Writer->writeLineBreak();
}
}
@ -494,9 +407,9 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
L"count", vertexCountStr.c_str(), L"stride", L"2");
Writer->writeLineBreak();
Writer->writeElement(L"param", true, L"name", L"U", L"type", L"float", L"flow", L"OUT");
Writer->writeElement(L"param", true, L"name", L"U", L"type", L"float");
Writer->writeLineBreak();
Writer->writeElement(L"param", true, L"name", L"V", L"type", L"float", L"flow", L"OUT");
Writer->writeElement(L"param", true, L"name", L"V", L"type", L"float");
Writer->writeLineBreak();
Writer->writeClosingTag(L"accessor");
@ -538,14 +451,7 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
video::S3DVertex* vtx = (video::S3DVertex*)buffer->getVertices();
for (u32 j=0; j<vertexCount; ++j)
{
core::stringw str;
str += vtx[j].Normal.X;
str += " ";
str += vtx[j].Normal.Y;
str += " ";
str += vtx[j].Normal.Z;
Writer->writeText(str.c_str());
Writer->writeText(toString(vtx[j].Normal).c_str());
Writer->writeLineBreak();
}
}
@ -555,14 +461,7 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buffer->getVertices();
for (u32 j=0; j<vertexCount; ++j)
{
core::stringw str;
str += vtx[j].Normal.X;
str += " ";
str += vtx[j].Normal.Y;
str += " ";
str += vtx[j].Normal.Z;
Writer->writeText(str.c_str());
Writer->writeText(toString(vtx[j].Normal).c_str());
Writer->writeLineBreak();
}
}
@ -572,14 +471,7 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
video::S3DVertexTangents* vtx = (video::S3DVertexTangents*)buffer->getVertices();
for (u32 j=0; j<vertexCount; ++j)
{
core::stringw str;
str += vtx[j].Normal.X;
str += " ";
str += vtx[j].Normal.Y;
str += " ";
str += vtx[j].Normal.Z;
Writer->writeText(str.c_str());
Writer->writeText(toString(vtx[j].Normal).c_str());
Writer->writeLineBreak();
}
}
@ -599,11 +491,11 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
L"count", vertexCountStr.c_str(), L"stride", L"3");
Writer->writeLineBreak();
Writer->writeElement(L"param", true, L"name", L"X", L"type", L"float", L"flow", L"OUT");
Writer->writeElement(L"param", true, L"name", L"X", L"type", L"float");
Writer->writeLineBreak();
Writer->writeElement(L"param", true, L"name", L"Y", L"type", L"float", L"flow", L"OUT");
Writer->writeElement(L"param", true, L"name", L"Y", L"type", L"float");
Writer->writeLineBreak();
Writer->writeElement(L"param", true, L"name", L"Z", L"type", L"float", L"flow", L"OUT");
Writer->writeElement(L"param", true, L"name", L"Z", L"type", L"float");
Writer->writeLineBreak();
Writer->writeClosingTag(L"accessor");
@ -649,12 +541,7 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buffer->getVertices();
for (u32 j=0; j<vertexCount; ++j)
{
core::stringw str;
str += vtx[j].TCoords2.X;
str += " ";
str += vtx[j].TCoords2.Y;
Writer->writeText(str.c_str());
Writer->writeText(toString(vtx[j].TCoords2).c_str());
Writer->writeLineBreak();
}
}
@ -677,9 +564,9 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
L"count", vertexCountStr.c_str(), L"stride", L"2");
Writer->writeLineBreak();
Writer->writeElement(L"param", true, L"name", L"U", L"type", L"float", L"flow", L"OUT");
Writer->writeElement(L"param", true, L"name", L"U", L"type", L"float");
Writer->writeLineBreak();
Writer->writeElement(L"param", true, L"name", L"V", L"type", L"float", L"flow", L"OUT");
Writer->writeElement(L"param", true, L"name", L"V", L"type", L"float");
Writer->writeLineBreak();
Writer->writeClosingTag(L"accessor");
@ -715,18 +602,18 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
const u32 polyCount = buffer->getIndexCount() / 3;
core::stringw strPolyCount(polyCount);
core::stringw strMat = "#mat";
core::stringw strMat = "mat";
strMat += i;
Writer->writeElement(L"triangles", false, L"count", strPolyCount.c_str(),
L"material", strMat.c_str());
Writer->writeLineBreak();
Writer->writeElement(L"input", true, L"semantic", L"VERTEX", L"source", L"#mesh-Vtx", L"idx", L"0");
Writer->writeElement(L"input", true, L"semantic", L"VERTEX", L"source", L"#mesh-Vtx", L"offset", L"0");
Writer->writeLineBreak();
Writer->writeElement(L"input", true, L"semantic", L"TEXCOORD", L"source", L"#mesh-TexCoord0", L"idx", L"1");
Writer->writeElement(L"input", true, L"semantic", L"TEXCOORD", L"source", L"#mesh-TexCoord0", L"offset", L"1");
Writer->writeLineBreak();
Writer->writeElement(L"input", true, L"semantic", L"NORMAL", L"source", L"#mesh-Normal", L"idx", L"2");
Writer->writeElement(L"input", true, L"semantic", L"NORMAL", L"source", L"#mesh-Normal", L"offset", L"2");
Writer->writeLineBreak();
bool has2ndTexCoords = hasSecondTextureCoordinates(buffer->getVertexType());
@ -823,6 +710,49 @@ bool CColladaMeshWriter::hasSecondTextureCoordinates(video::E_VERTEX_TYPE type)
return type == video::EVT_2TCOORDS;
}
irr::core::stringw CColladaMeshWriter::toString(const irr::core::vector3df& vec) const
{
c8 tmpbuf[255];
snprintf(tmpbuf, 255, "%f %f %f", vec.X, vec.Y, vec.Z);
core::stringw str = tmpbuf;
return str;
}
irr::core::stringw CColladaMeshWriter::toString(const irr::core::vector2df& vec) const
{
c8 tmpbuf[255];
snprintf(tmpbuf, 255, "%f %f", vec.X, vec.Y);
core::stringw str = tmpbuf;
return str;
}
inline irr::core::stringw CColladaMeshWriter::toString(const irr::video::SColorf& colorf) const
{
c8 tmpbuf[255];
snprintf(tmpbuf, 255, "%f %f %f %f", colorf.getRed(), colorf.getGreen(), colorf.getBlue(), colorf.getAlpha());
core::stringw str = tmpbuf;
return str;
}
void CColladaMeshWriter::writeColorAttribute(wchar_t * parentTag, io::IAttributes* attributes, s32 attridx)
{
Writer->writeElement(parentTag, false);
Writer->writeLineBreak();
Writer->writeElement(L"color", false);
irr::core::stringw str( toString(attributes->getAttributeAsColorf(attridx)) );
Writer->writeText(str.c_str());
Writer->writeClosingTag(L"color");
Writer->writeLineBreak();
Writer->writeClosingTag(parentTag);
Writer->writeLineBreak();
}
} // end namespace
} // end namespace

View File

@ -35,9 +35,14 @@ public:
//! writes a mesh
virtual bool writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags=EMWF_NONE);
protected:
bool hasSecondTextureCoordinates(video::E_VERTEX_TYPE type) const;
inline irr::core::stringw toString(const irr::core::vector3df& vec) const;
inline irr::core::stringw toString(const irr::core::vector2df& vec) const;
inline irr::core::stringw toString(const irr::video::SColorf& colorf) const;
inline void writeColorAttribute(wchar_t * parentTag, io::IAttributes* attributes, s32 attridx);
struct SComponentGlobalStartPos
{

View File

@ -12,7 +12,6 @@
#include "os.h"
#include "S3DVertex.h"
#include "CD3D8Texture.h"
#include "CImage.h"
#include "CD3D8MaterialRenderer.h"
#include "CD3D8ShaderMaterialRenderer.h"
#include "CD3D8NormalMapRenderer.h"
@ -394,6 +393,7 @@ bool CD3D8Driver::initDriver(const core::dimension2d<u32>& screenSize,
DriverAttributes->setAttribute("MaxTextures", (s32)MaxTextureUnits);
DriverAttributes->setAttribute("MaxSupportedTextures", (s32)Caps.MaxSimultaneousTextures);
DriverAttributes->setAttribute("MaxLights", (s32)Caps.MaxActiveLights);
DriverAttributes->setAttribute("MaxAnisotropy", (s32)Caps.MaxAnisotropy);
DriverAttributes->setAttribute("MaxUserClipPlanes", (s32)Caps.MaxUserClipPlanes);
DriverAttributes->setAttribute("MaxIndices", (s32)Caps.MaxVertexIndex);
@ -607,6 +607,7 @@ bool CD3D8Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
case EVDF_COLOR_MASK:
return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_COLORWRITEENABLE) != 0;
case EVDF_BLEND_OPERATIONS:
case EVDF_TEXTURE_MATRIX:
return true;
default:
return false;
@ -790,6 +791,7 @@ bool CD3D8Driver::setRenderTarget(video::ITexture* texture,
CurrentRendertargetSize = tex->getSize();
}
Transformation3DChanged = true;
if (clearBackBuffer || clearZBuffer)
{
@ -1576,7 +1578,7 @@ void CD3D8Driver::setBasicRenderStates(const SMaterial& material, const SMateria
if (queryFeature(EVDF_BLEND_OPERATIONS) &&
(resetAllRenderstates|| lastmaterial.BlendOperation != material.BlendOperation))
{
if (EBO_NONE)
if (material.BlendOperation==EBO_NONE)
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
else
{
@ -1854,72 +1856,57 @@ void CD3D8Driver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChan
if (OverrideMaterial2DEnabled)
{
OverrideMaterial2D.Lighting=false;
OverrideMaterial2D.ZBuffer=ECFN_NEVER;
OverrideMaterial2D.ZWriteEnable=false;
setBasicRenderStates(OverrideMaterial2D, LastMaterial, false);
LastMaterial = OverrideMaterial2D;
}
// no alphaChannel without texture
alphaChannel &= texture;
if (alpha || alphaChannel)
{
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
}
else
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
if (texture)
{
setTransform(ETS_TEXTURE_0, core::IdentityMatrix);
if (alphaChannel)
// Due to the transformation change, the previous line would call a reset each frame
// but we can safely reset the variable as it was false before
Transformation3DChanged=false;
}
if (alphaChannel)
{
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
if (alpha)
{
pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE );
pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
if (alpha)
{
pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
}
else
{
pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
}
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
}
else
{
pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
if (alpha)
{
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
}
else
{
pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE );
pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
}
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
}
}
else
{
pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE );
pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
if (alpha)
{
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
}
else
{
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
}
}
@ -2252,18 +2239,23 @@ void CD3D8Driver::clearZBuffer()
//! Returns an image created from the last rendered frame.
IImage* CD3D8Driver::createScreenShot()
IImage* CD3D8Driver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target)
{
#if defined( _IRR_XBOX_PLATFORM_)
return 0;
#else
HRESULT hr;
if (target != video::ERT_FRAME_BUFFER)
return 0;
// query the screen dimensions of the current adapter
D3DDISPLAYMODE displayMode;
pID3DDevice->GetDisplayMode(&displayMode);
if (format==video::ECF_UNKNOWN)
format=video::ECF_A8R8G8B8;
// create the image surface to store the front buffer image [always A8R8G8B8]
HRESULT hr;
LPDIRECT3DSURFACE8 lpSurface;
if (FAILED(hr = pID3DDevice->CreateImageSurface(displayMode.Width, displayMode.Height, D3DFMT_A8R8G8B8, &lpSurface)))
return 0;
@ -2308,41 +2300,42 @@ IImage* CD3D8Driver::createScreenShot()
shotSize.Height = core::min_( ScreenSize.Height, (u32)(clientRect.bottom-clientRect.top) );
// this could throw, but we aren't going to worry about that case very much
IImage* newImage = new CImage(ECF_A8R8G8B8, shotSize);
IImage* newImage = createImage(format, shotSize);
// d3d pads the image, so we need to copy the correct number of bytes
u32* dP = (u32*)newImage->lock();
u8 * sP = (u8 *)lockedRect.pBits;
// If the display mode format doesn't promise anything about the Alpha value
// and it appears that it's not presenting 255, then we should manually
// set each pixel alpha value to 255.
if(D3DFMT_X8R8G8B8 == displayMode.Format && (0xFF000000 != (*dP & 0xFF000000)))
if (newImage)
{
for (u32 y = 0; y < shotSize.Height; ++y)
// d3d pads the image, so we need to copy the correct number of bytes
u32* dP = (u32*)newImage->lock();
u8 * sP = (u8 *)lockedRect.pBits;
// If the display mode format doesn't promise anything about the Alpha value
// and it appears that it's not presenting 255, then we should manually
// set each pixel alpha value to 255.
if(D3DFMT_X8R8G8B8 == displayMode.Format && (0xFF000000 != (*dP & 0xFF000000)))
{
for(u32 x = 0; x < shotSize.Width; ++x)
for (u32 y = 0; y < shotSize.Height; ++y)
{
*dP = *((u32*)sP) | 0xFF000000;
dP++;
sP += 4;
for(u32 x = 0; x < shotSize.Width; ++x)
{
newImage->setPixel(x,y,*((u32*)sP) | 0xFF000000);
sP += 4;
}
sP += lockedRect.Pitch - (4 * shotSize.Width);
}
sP += lockedRect.Pitch - (4 * shotSize.Width);
}
}
else
{
for (u32 y = 0; y < shotSize.Height; ++y)
else
{
memcpy(dP, sP, shotSize.Width * 4);
sP += lockedRect.Pitch;
dP += shotSize.Width;
for (u32 y = 0; y < shotSize.Height; ++y)
{
convertColor(sP, video::ECF_A8R8G8B8, shotSize.Width, dP, format);
sP += lockedRect.Pitch;
dP += shotSize.Width;
}
}
}
newImage->unlock();
newImage->unlock();
}
// we can unlock and release the surface
lpSurface->UnlockRect();

View File

@ -199,7 +199,7 @@ namespace video
virtual void clearZBuffer();
//! Returns an image created from the last rendered frame.
virtual IImage* createScreenShot();
virtual IImage* createScreenShot(video::ECOLOR_FORMAT format=video::ECF_UNKNOWN, video::E_RENDER_TARGET target=video::ERT_FRAME_BUFFER);
//! Set/unset a clipping plane.
//! There are at least 6 clipping planes available for the user to set at will.

View File

@ -10,7 +10,6 @@
#include "os.h"
#include "S3DVertex.h"
#include "CD3D9Texture.h"
#include "CImage.h"
#include "CD3D9MaterialRenderer.h"
#include "CD3D9ShaderMaterialRenderer.h"
#include "CD3D9NormalMapRenderer.h"
@ -29,20 +28,17 @@ namespace
}
//! constructor
CD3D9Driver::CD3D9Driver(const core::dimension2d<u32>& screenSize, HWND window,
bool fullscreen, bool stencilbuffer,
io::IFileSystem* io, bool pureSoftware)
: CNullDriver(io, screenSize), CurrentRenderMode(ERM_NONE),
CD3D9Driver::CD3D9Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io)
: CNullDriver(io, params.WindowSize), CurrentRenderMode(ERM_NONE),
ResetRenderStates(true), Transformation3DChanged(false),
StencilBuffer(stencilbuffer), AntiAliasing(0),
D3DLibrary(0), pID3D(0), pID3DDevice(0), PrevRenderTarget(0),
WindowId(0), SceneSourceRect(0),
LastVertexType((video::E_VERTEX_TYPE)-1), VendorID(0),
MaxTextureUnits(0), MaxUserClipPlanes(0), MaxMRTs(1), NumSetMRTs(1),
MaxLightDistance(0.f), LastSetLight(-1), Cached2DModeSignature(0),
MaxLightDistance(0.f), LastSetLight(-1),
ColorFormat(ECF_A8R8G8B8), DeviceLost(false),
Fullscreen(fullscreen), DriverWasReset(true), OcclusionQuerySupport(false),
AlphaToCoverageSupport(false), DisplayAdapter(0)
DriverWasReset(true), OcclusionQuerySupport(false),
AlphaToCoverageSupport(false), Params(params)
{
#ifdef _DEBUG
setDebugName("CD3D9Driver");
@ -164,15 +160,8 @@ void CD3D9Driver::createMaterialRenderers()
//! initialises the Direct3D API
bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
HWND hwnd, u32 bits, bool fullScreen, bool pureSoftware,
bool highPrecisionFPU, bool vsync, u8 antiAlias, u32 displayAdapter)
bool CD3D9Driver::initDriver(HWND hwnd, bool pureSoftware)
{
HRESULT hr;
Fullscreen = fullScreen;
CurrentDepthBufferSize = screenSize;
DisplayAdapter = displayAdapter;
if (!pID3D)
{
D3DLibrary = LoadLibrary( __TEXT("d3d9.dll") );
@ -204,7 +193,7 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
// print device information
D3DADAPTER_IDENTIFIER9 dai;
if (!FAILED(pID3D->GetAdapterIdentifier(DisplayAdapter, 0, &dai)))
if (!FAILED(pID3D->GetAdapterIdentifier(Params.DisplayAdapter, 0, &dai)))
{
char tmp[512];
@ -232,8 +221,7 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
}
D3DDISPLAYMODE d3ddm;
hr = pID3D->GetAdapterDisplayMode(DisplayAdapter, &d3ddm);
if (FAILED(hr))
if (FAILED(pID3D->GetAdapterDisplayMode(Params.DisplayAdapter, &d3ddm)))
{
os::Printer::log("Error: Could not get Adapter Display mode.", ELL_ERROR);
return false;
@ -241,19 +229,19 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
ZeroMemory(&present, sizeof(present));
present.BackBufferCount = 1;
present.EnableAutoDepthStencil = TRUE;
if (vsync)
present.BackBufferCount = 1;
present.EnableAutoDepthStencil = TRUE;
if (Params.Vsync)
present.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
else
present.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
if (fullScreen)
if (Params.Fullscreen)
{
present.BackBufferWidth = screenSize.Width;
present.BackBufferHeight = screenSize.Height;
present.BackBufferWidth = Params.WindowSize.Width;
present.BackBufferHeight = Params.WindowSize.Height;
// request 32bit mode if user specified 32 bit, added by Thomas Stuefe
if (bits == 32)
if (Params.Bits == 32)
present.BackBufferFormat = D3DFMT_X8R8G8B8;
else
present.BackBufferFormat = D3DFMT_R5G6B5;
@ -268,7 +256,7 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
present.Windowed = TRUE;
}
UINT adapter = DisplayAdapter;
UINT adapter = Params.DisplayAdapter;
D3DDEVTYPE devtype = D3DDEVTYPE_HAL;
#ifndef _IRR_D3D_NO_SHADER_DEBUGGING
devtype = D3DDEVTYPE_REF;
@ -287,36 +275,35 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
#endif
// enable anti alias if possible and desired
if (antiAlias > 0)
if (Params.AntiAlias > 0)
{
if(antiAlias > 16)
antiAlias = 16;
if (Params.AntiAlias > 32)
Params.AntiAlias = 32;
DWORD qualityLevels = 0;
while(antiAlias > 0)
while(Params.AntiAlias > 0)
{
if(SUCCEEDED(pID3D->CheckDeviceMultiSampleType(adapter,
devtype, present.BackBufferFormat, !fullScreen,
(D3DMULTISAMPLE_TYPE)antiAlias, &qualityLevels)))
devtype, present.BackBufferFormat, !Params.Fullscreen,
(D3DMULTISAMPLE_TYPE)Params.AntiAlias, &qualityLevels)))
{
present.MultiSampleType = (D3DMULTISAMPLE_TYPE)antiAlias;
present.MultiSampleType = (D3DMULTISAMPLE_TYPE)Params.AntiAlias;
present.MultiSampleQuality = qualityLevels-1;
present.SwapEffect = D3DSWAPEFFECT_DISCARD;
break;
}
--antiAlias;
--Params.AntiAlias;
}
if(antiAlias==0)
if (Params.AntiAlias==0)
{
os::Printer::log("Anti aliasing disabled because hardware/driver lacks necessary caps.", ELL_WARNING);
}
}
AntiAliasing = antiAlias;
// check stencil buffer compatibility
if (StencilBuffer)
if (Params.Stencilbuffer)
{
present.AutoDepthStencilFormat = D3DFMT_D24S8;
if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype,
@ -334,7 +321,7 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
D3DRTYPE_SURFACE, present.AutoDepthStencilFormat)))
{
os::Printer::log("Device does not support stencilbuffer, disabling stencil buffer.", ELL_WARNING);
StencilBuffer = false;
Params.Stencilbuffer = false;
}
}
}
@ -343,11 +330,11 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
present.BackBufferFormat, present.BackBufferFormat, present.AutoDepthStencilFormat)))
{
os::Printer::log("Depth-stencil format is not compatible with display format, disabling stencil buffer.", ELL_WARNING);
StencilBuffer = false;
Params.Stencilbuffer = false;
}
}
// do not use else here to cope with flag change in previous block
if (!StencilBuffer)
if (!Params.Stencilbuffer)
{
present.AutoDepthStencilFormat = D3DFMT_D32;
if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype,
@ -373,18 +360,16 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
// create device
DWORD fpuPrecision = highPrecisionFPU ? D3DCREATE_FPU_PRESERVE : 0;
DWORD fpuPrecision = Params.HighPrecisionFPU ? D3DCREATE_FPU_PRESERVE : 0;
if (pureSoftware)
{
hr = pID3D->CreateDevice(DisplayAdapter, D3DDEVTYPE_REF, hwnd,
fpuPrecision | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present, &pID3DDevice);
if (FAILED(hr))
if (FAILED(pID3D->CreateDevice(Params.DisplayAdapter, D3DDEVTYPE_REF, hwnd,
fpuPrecision | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present, &pID3DDevice)))
os::Printer::log("Was not able to create Direct3D9 software device.", ELL_ERROR);
}
else
{
hr = pID3D->CreateDevice(adapter, devtype, hwnd,
HRESULT hr = pID3D->CreateDevice(adapter, devtype, hwnd,
fpuPrecision | D3DCREATE_HARDWARE_VERTEXPROCESSING, &present, &pID3DDevice);
if(FAILED(hr))
@ -408,14 +393,16 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
// get caps
pID3DDevice->GetDeviceCaps(&Caps);
os::Printer::log("Currently available Video Memory (kB)", core::stringc(pID3DDevice->GetAvailableTextureMem()/1024).c_str());
// disable stencilbuffer if necessary
if (StencilBuffer &&
if (Params.Stencilbuffer &&
(!(Caps.StencilCaps & D3DSTENCILCAPS_DECRSAT) ||
!(Caps.StencilCaps & D3DSTENCILCAPS_INCRSAT) ||
!(Caps.StencilCaps & D3DSTENCILCAPS_KEEP)))
{
os::Printer::log("Device not able to use stencil buffer, disabling stencil buffer.", ELL_WARNING);
StencilBuffer = false;
Params.Stencilbuffer = false;
}
// set default vertex shader
@ -440,19 +427,20 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
OcclusionQuerySupport=(pID3DDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, NULL) == S_OK);
if (VendorID==0x10DE)//NVidia
AlphaToCoverageSupport = (pID3D->CheckDeviceFormat(DisplayAdapter, D3DDEVTYPE_HAL,
AlphaToCoverageSupport = (pID3D->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL,
D3DFMT_X8R8G8B8, 0,D3DRTYPE_SURFACE,
(D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C')) == S_OK);
else if (VendorID==0x1002)//ATI
AlphaToCoverageSupport = true; // TODO: Check unknown
#if 0
AlphaToCoverageSupport = (pID3D->CheckDeviceFormat(DisplayAdapter, D3DDEVTYPE_HAL,
AlphaToCoverageSupport = (pID3D->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL,
D3DFMT_X8R8G8B8, 0,D3DRTYPE_SURFACE,
(D3DFORMAT)MAKEFOURCC('A','2','M','1')) == S_OK);
#endif
DriverAttributes->setAttribute("MaxTextures", (s32)MaxTextureUnits);
DriverAttributes->setAttribute("MaxSupportedTextures", (s32)Caps.MaxSimultaneousTextures);
DriverAttributes->setAttribute("MaxLights", (s32)Caps.MaxActiveLights);
DriverAttributes->setAttribute("MaxAnisotropy", (s32)Caps.MaxAnisotropy);
DriverAttributes->setAttribute("MaxUserClipPlanes", (s32)Caps.MaxUserClipPlanes);
DriverAttributes->setAttribute("MaxMultipleRenderTargets", (s32)Caps.NumSimultaneousRTs);
@ -460,8 +448,8 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
DriverAttributes->setAttribute("MaxTextureSize", (s32)core::min_(Caps.MaxTextureHeight,Caps.MaxTextureWidth));
DriverAttributes->setAttribute("MaxTextureLODBias", 16);
DriverAttributes->setAttribute("Version", 901);
DriverAttributes->setAttribute("ShaderLanguageVersion", (s32)Caps.VertexShaderVersion*100);
DriverAttributes->setAttribute("AntiAlias", AntiAliasing);
DriverAttributes->setAttribute("ShaderLanguageVersion", (s32)(((0x00ff00 & Caps.VertexShaderVersion)>>8)*100 + (Caps.VertexShaderVersion&0xff)));
DriverAttributes->setAttribute("AntiAlias", Params.AntiAlias);
// set the renderstates
setRenderStates3DMode();
@ -537,7 +525,7 @@ bool CD3D9Driver::beginScene(bool backBuffer, bool zBuffer, SColor color,
if (zBuffer)
flags |= D3DCLEAR_ZBUFFER;
if (StencilBuffer)
if (Params.Stencilbuffer)
flags |= D3DCLEAR_STENCIL;
if (flags)
@ -582,7 +570,10 @@ bool CD3D9Driver::endScene()
sourceRectData.bottom = SceneSourceRect->LowerRightCorner.Y;
}
hr = pID3DDevice->Present(srcRct, NULL, WindowId, NULL);
IDirect3DSwapChain9* swChain;
hr = pID3DDevice->GetSwapChain(0, &swChain);
DWORD flags = (Params.HandleSRGB && (Caps.Caps3&D3DCAPS3_LINEAR_TO_SRGB_PRESENTATION))?D3DPRESENT_LINEAR_CONTENT:0;
hr = swChain->Present(srcRct, NULL, WindowId, NULL, flags);
if (SUCCEEDED(hr))
return true;
@ -630,7 +621,7 @@ bool CD3D9Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
// this but actually don't do this at all.
return false; //(Caps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP) != 0;
case EVDF_STENCIL_BUFFER:
return StencilBuffer && Caps.StencilCaps;
return Params.Stencilbuffer && Caps.StencilCaps;
case EVDF_VERTEX_SHADER_1_1:
return Caps.VertexShaderVersion >= D3DVS_VERSION(1,1);
case EVDF_VERTEX_SHADER_2_0:
@ -668,6 +659,7 @@ bool CD3D9Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
case EVDF_POLYGON_OFFSET:
return (Caps.RasterCaps & (D3DPRASTERCAPS_DEPTHBIAS|D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS)) != 0;
case EVDF_BLEND_OPERATIONS:
case EVDF_TEXTURE_MATRIX:
return true;
default:
return false;
@ -852,6 +844,7 @@ bool CD3D9Driver::setRenderTarget(video::ITexture* texture,
os::Printer::log("Error: Could not set new depth buffer.", ELL_ERROR);
}
}
Transformation3DChanged=true;
if (clearBackBuffer || clearZBuffer)
{
@ -1628,6 +1621,8 @@ void CD3D9Driver::draw2DImageBatch(const video::ITexture* texture,
if (!setActiveTexture(0, const_cast<video::ITexture*>(texture)))
return;
setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture);
const irr::u32 drawCount = core::min_<u32>(positions.size(), sourceRects.size());
core::array<S3DVertex> vtx(drawCount * 4);
@ -1726,8 +1721,6 @@ void CD3D9Driver::draw2DImageBatch(const video::ITexture* texture,
const core::rect<s32> poss(targetPos, sourceSize);
setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture);
vtx.push_back(S3DVertex((f32)poss.UpperLeftCorner.X, (f32)poss.UpperLeftCorner.Y, 0.0f,
0.0f, 0.0f, 0.0f, color,
tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y));
@ -2025,6 +2018,7 @@ bool CD3D9Driver::setRenderStates3DMode()
pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)&Matrices[ETS_PROJECTION]));
pID3DDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
pID3DDevice->SetRenderState(D3DRS_CLIPPING, TRUE);
ResetRenderStates = true;
}
@ -2096,6 +2090,10 @@ D3DTEXTUREADDRESS CD3D9Driver::getTextureWrapMode(const u8 clamp)
void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial,
bool resetAllRenderstates)
{
// This needs only to be updated onresets
if (Params.HandleSRGB && resetAllRenderstates)
pID3DDevice->SetRenderState(D3DRS_SRGBWRITEENABLE, TRUE);
if (resetAllRenderstates ||
lastmaterial.AmbientColor != material.AmbientColor ||
lastmaterial.DiffuseColor != material.DiffuseColor ||
@ -2259,7 +2257,7 @@ void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMateria
if (queryFeature(EVDF_BLEND_OPERATIONS) &&
(resetAllRenderstates|| lastmaterial.BlendOperation != material.BlendOperation))
{
if (EBO_NONE)
if (material.BlendOperation==EBO_NONE)
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
else
{
@ -2334,7 +2332,7 @@ void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMateria
}
// enable antialiasing
if (AntiAliasing)
if (Params.AntiAlias)
{
if (material.AntiAliasing & (EAAM_SIMPLE|EAAM_QUALITY))
pID3DDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
@ -2356,6 +2354,9 @@ void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMateria
// texture address mode
for (u32 st=0; st<MaxTextureUnits; ++st)
{
if (resetAllRenderstates && Params.HandleSRGB)
pID3DDevice->SetSamplerState(st, D3DSAMP_SRGBTEXTURE, TRUE);
if (resetAllRenderstates || lastmaterial.TextureLayer[st].LODBias != material.TextureLayer[st].LODBias)
{
const float tmp = material.TextureLayer[st].LODBias * 0.125f;
@ -2560,7 +2561,7 @@ void CD3D9Driver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChan
// fix everything that is wrongly set by InitMaterial2D default
pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
pID3DDevice->SetRenderState( D3DRS_STENCILENABLE, FALSE );
pID3DDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
}
pID3DDevice->SetTransform(D3DTS_WORLD, &UnitMatrixD3D9);
@ -2573,90 +2574,67 @@ void CD3D9Driver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChan
m.setTranslation(core::vector3df(-1,1,0));
pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)m.pointer()));
pID3DDevice->SetRenderState(D3DRS_CLIPPING, FALSE);
Transformation3DChanged = false;
}
if (OverrideMaterial2DEnabled)
{
OverrideMaterial2D.Lighting=false;
OverrideMaterial2D.ZBuffer=ECFN_NEVER;
OverrideMaterial2D.ZWriteEnable=false;
setBasicRenderStates(OverrideMaterial2D, LastMaterial, false);
LastMaterial = OverrideMaterial2D;
}
u32 current2DSignature = 0;
current2DSignature |= alpha ? EC2D_ALPHA : 0;
current2DSignature |= texture ? EC2D_TEXTURE : 0;
current2DSignature |= alphaChannel ? EC2D_ALPHA_CHANNEL : 0;
// no alphaChannel without texture
alphaChannel &= texture;
if(CurrentRenderMode != ERM_2D || current2DSignature != Cached2DModeSignature)
if (alpha || alphaChannel)
{
if (texture)
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
}
else
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
if (texture)
{
setTransform(ETS_TEXTURE_0, core::IdentityMatrix);
// Due to the transformation change, the previous line would call a reset each frame
// but we can safely reset the variable as it was false before
Transformation3DChanged=false;
}
if (alphaChannel)
{
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
if (alpha)
{
setTransform(ETS_TEXTURE_0, core::IdentityMatrix);
if (alphaChannel)
{
pID3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
if (alpha)
{
pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
}
else
{
pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
}
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
}
else
{
pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
if (alpha)
{
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
}
else
{
pID3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
}
}
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
}
else
{
pID3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
if (alpha)
{
pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
}
else
{
pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
}
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
}
}
else
{
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
if (alpha)
{
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
}
else
{
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
}
}
CurrentRenderMode = ERM_2D;
Cached2DModeSignature = current2DSignature;
}
@ -2767,7 +2745,7 @@ const wchar_t* CD3D9Driver::getName() const
//! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow.
void CD3D9Driver::drawStencilShadowVolume(const core::vector3df* triangles, s32 count, bool zfail)
{
if (!StencilBuffer || !count)
if (!Params.Stencilbuffer || !count)
return;
setRenderStatesStencilShadowMode(zfail);
@ -2809,7 +2787,7 @@ void CD3D9Driver::drawStencilShadowVolume(const core::vector3df* triangles, s32
void CD3D9Driver::drawStencilShadow(bool clearStencilBuffer, video::SColor leftUpEdge,
video::SColor rightUpEdge, video::SColor leftDownEdge, video::SColor rightDownEdge)
{
if (!StencilBuffer)
if (!Params.Stencilbuffer)
return;
S3DVertex vtx[4];
@ -3183,15 +3161,20 @@ void CD3D9Driver::clearZBuffer()
//! Returns an image created from the last rendered frame.
IImage* CD3D9Driver::createScreenShot()
IImage* CD3D9Driver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target)
{
HRESULT hr;
if (target != video::ERT_FRAME_BUFFER)
return 0;
// query the screen dimensions of the current adapter
D3DDISPLAYMODE displayMode;
pID3DDevice->GetDisplayMode(0, &displayMode);
if (format==video::ECF_UNKNOWN)
format=video::ECF_A8R8G8B8;
// create the image surface to store the front buffer image [always A8R8G8B8]
HRESULT hr;
LPDIRECT3DSURFACE9 lpSurface;
if (FAILED(hr = pID3DDevice->CreateOffscreenPlainSurface(displayMode.Width, displayMode.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &lpSurface, 0)))
return 0;
@ -3236,41 +3219,42 @@ IImage* CD3D9Driver::createScreenShot()
shotSize.Height = core::min_( ScreenSize.Height, (u32)(clientRect.bottom-clientRect.top) );
// this could throw, but we aren't going to worry about that case very much
IImage* newImage = new CImage(ECF_A8R8G8B8, shotSize);
IImage* newImage = createImage(format, shotSize);
// d3d pads the image, so we need to copy the correct number of bytes
u32* dP = (u32*)newImage->lock();
u8 * sP = (u8 *)lockedRect.pBits;
// If the display mode format doesn't promise anything about the Alpha value
// and it appears that it's not presenting 255, then we should manually
// set each pixel alpha value to 255.
if(D3DFMT_X8R8G8B8 == displayMode.Format && (0xFF000000 != (*dP & 0xFF000000)))
if (newImage)
{
for (u32 y = 0; y < shotSize.Height; ++y)
// d3d pads the image, so we need to copy the correct number of bytes
u32* dP = (u32*)newImage->lock();
u8 * sP = (u8 *)lockedRect.pBits;
// If the display mode format doesn't promise anything about the Alpha value
// and it appears that it's not presenting 255, then we should manually
// set each pixel alpha value to 255.
if (D3DFMT_X8R8G8B8 == displayMode.Format && (0xFF000000 != (*dP & 0xFF000000)))
{
for(u32 x = 0; x < shotSize.Width; ++x)
for (u32 y = 0; y < shotSize.Height; ++y)
{
*dP = *((u32*)sP) | 0xFF000000;
dP++;
sP += 4;
for (u32 x = 0; x < shotSize.Width; ++x)
{
newImage->setPixel(x,y,*((u32*)sP) | 0xFF000000);
sP += 4;
}
sP += lockedRect.Pitch - (4 * shotSize.Width);
}
sP += lockedRect.Pitch - (4 * shotSize.Width);
}
}
else
{
for (u32 y = 0; y < shotSize.Height; ++y)
else
{
memcpy(dP, sP, shotSize.Width * 4);
sP += lockedRect.Pitch;
dP += shotSize.Width;
for (u32 y = 0; y < shotSize.Height; ++y)
{
convertColor(sP, video::ECF_A8R8G8B8, shotSize.Width, dP, format);
sP += lockedRect.Pitch;
dP += shotSize.Width;
}
}
}
newImage->unlock();
newImage->unlock();
}
// we can unlock and release the surface
lpSurface->UnlockRect();
@ -3503,9 +3487,8 @@ IVideoDriver* createDirectX9Driver(const SIrrlichtCreationParameters& params,
io::IFileSystem* io, HWND window)
{
const bool pureSoftware = false;
CD3D9Driver* dx9 = new CD3D9Driver(params.WindowSize, window, params.Fullscreen, params.Stencilbuffer, io, pureSoftware);
if (!dx9->initDriver(params.WindowSize, window, params.Bits, params.Fullscreen, pureSoftware, params.HighPrecisionFPU,
params.Vsync, params.AntiAlias, params.DisplayAdapter))
CD3D9Driver* dx9 = new CD3D9Driver(params, io);
if (!dx9->initDriver(window, pureSoftware))
{
dx9->drop();
dx9 = 0;

View File

@ -15,6 +15,7 @@
#endif
#include "CNullDriver.h"
#include "SIrrCreationParameters.h"
#include "IMaterialRendererServices.h"
#if defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
#include "irrMath.h" // needed by borland for sqrtf define
@ -50,8 +51,7 @@ namespace video
friend class CD3D9Texture;
//! constructor
CD3D9Driver(const core::dimension2d<u32>& screenSize, HWND window, bool fullscreen,
bool stencibuffer, io::IFileSystem* io, bool pureSoftware=false);
CD3D9Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io);
//! destructor
virtual ~CD3D9Driver();
@ -191,9 +191,7 @@ namespace video
const core::vector3df& end, SColor color = SColor(255,255,255,255));
//! initialises the Direct3D API
bool initDriver(const core::dimension2d<u32>& screenSize, HWND hwnd,
u32 bits, bool fullScreen, bool pureSoftware,
bool highPrecisionFPU, bool vsync, u8 antiAlias, u32 displayAdapter);
bool initDriver(HWND hwnd, bool pureSoftware);
//! \return Returns the name of the video driver. Example: In case of the DIRECT3D8
//! driver, it would return "Direct3D8.1".
@ -280,7 +278,7 @@ namespace video
virtual void clearZBuffer();
//! Returns an image created from the last rendered frame.
virtual IImage* createScreenShot();
virtual IImage* createScreenShot(video::ECOLOR_FORMAT format=video::ECF_UNKNOWN, video::E_RENDER_TARGET target=video::ERT_FRAME_BUFFER);
//! Set/unset a clipping plane.
virtual bool setClipPlane(u32 index, const core::plane3df& plane, bool enable=false);
@ -412,8 +410,6 @@ namespace video
SMaterial Material, LastMaterial;
bool ResetRenderStates; // bool to make all renderstates be reseted if set.
bool Transformation3DChanged;
bool StencilBuffer;
u8 AntiAliasing;
const ITexture* CurrentTexture[MATERIAL_MAX_TEXTURES];
bool LastTextureMipMapsAvailable[MATERIAL_MAX_TEXTURES];
core::matrix4 Matrices[ETS_COUNT]; // matrizes of the 3d mode we need to restore when we switch back from the 2d mode.
@ -424,13 +420,14 @@ namespace video
IDirect3DSurface9* PrevRenderTarget;
core::dimension2d<u32> CurrentRendertargetSize;
core::dimension2d<u32> CurrentDepthBufferSize;
HWND WindowId;
core::rect<s32>* SceneSourceRect;
D3DCAPS9 Caps;
SIrrlichtCreationParameters Params;
E_VERTEX_TYPE LastVertexType;
SColorf AmbientLight;
@ -454,17 +451,12 @@ namespace video
EC2D_ALPHA_CHANNEL = 0x4
};
u32 Cached2DModeSignature;
ECOLOR_FORMAT ColorFormat;
D3DFORMAT D3DColorFormat;
bool DeviceLost;
bool Fullscreen;
bool DriverWasReset;
bool OcclusionQuerySupport;
bool AlphaToCoverageSupport;
u32 DisplayAdapter;
};

View File

@ -312,9 +312,9 @@ bool CD3D9Texture::createTexture(u32 flags, IImage * image)
{
LPDIRECT3D9 intf = Driver->getExposedVideoData().D3D9.D3D9;
D3DDISPLAYMODE d3ddm;
intf->GetAdapterDisplayMode(Driver->DisplayAdapter, &d3ddm);
intf->GetAdapterDisplayMode(Driver->Params.DisplayAdapter, &d3ddm);
if (D3D_OK==intf->CheckDeviceFormat(Driver->DisplayAdapter,D3DDEVTYPE_HAL,d3ddm.Format,D3DUSAGE_AUTOGENMIPMAP,D3DRTYPE_TEXTURE,format))
if (D3D_OK==intf->CheckDeviceFormat(Driver->Params.DisplayAdapter,D3DDEVTYPE_HAL,d3ddm.Format,D3DUSAGE_AUTOGENMIPMAP,D3DRTYPE_TEXTURE,format))
{
usage = D3DUSAGE_AUTOGENMIPMAP;
HardwareMipMaps = true;

View File

@ -29,7 +29,6 @@
#include "irrString.h"
#include "irrMath.h"
#include "dmfsupport.h"
#include "CImage.h"
namespace irr
{
@ -285,14 +284,14 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
if (color.getAlpha()!=255 && materiali[i].textureBlend==4)
driver->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT,true);
video::CImage *immagine= new video::CImage(video::ECF_A8R8G8B8,
video::IImage *immagine= driver->createImage(video::ECF_A8R8G8B8,
core::dimension2d<u32>(8,8));
immagine->fill(color);
tex = driver->addTexture("", immagine);
immagine->drop();
//to support transparent materials
if(color.getAlpha()!=255 && materiali[i].textureBlend==4)
if (color.getAlpha()!=255 && materiali[i].textureBlend==4)
{
mat.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
mat.MaterialTypeParam =(((f32) (color.getAlpha()-1))/255.0f);

View File

@ -129,7 +129,7 @@ IReadFile* CFileSystem::createMemoryReadFile(void* memory, s32 len,
return 0;
else
return new CMemoryFile(memory, len, fileName, deleteMemoryWhenDropped);
}
}
//! Creates an IReadFile interface for reading files inside files
@ -321,9 +321,9 @@ bool CFileSystem::changeArchivePassword(const path& filename, const core::string
{
// TODO: This should go into a path normalization method
// We need to check for directory names with trailing slash and without
const core::stringc absPath = getAbsolutePath(filename);
const core::stringc arcPath = FileArchives[idx]->getFileList()->getPath();
if ((absPath == arcPath) || ((absPath+"/") == arcPath))
const path absPath = getAbsolutePath(filename);
const path arcPath = FileArchives[idx]->getFileList()->getPath();
if ((absPath == arcPath) || ((absPath+_IRR_TEXT("/")) == arcPath))
{
if (password.size())
FileArchives[idx]->Password=password;
@ -533,7 +533,8 @@ bool CFileSystem::changeWorkingDirectoryTo(const io::path& newDirectory)
if (FileSystemType != FILESYSTEM_NATIVE)
{
WorkingDirectory[FILESYSTEM_VIRTUAL] = newDirectory;
flattenFilename(WorkingDirectory[FILESYSTEM_VIRTUAL], "");
// is this empty string constant really intended?
flattenFilename(WorkingDirectory[FILESYSTEM_VIRTUAL], _IRR_TEXT(""));
success = 1;
}
else
@ -591,7 +592,7 @@ io::path CFileSystem::getAbsolutePath(const io::path& filename) const
return io::path(fpath);
}
if (filename[filename.size()-1]=='/')
return io::path(p)+"/";
return io::path(p)+_IRR_TEXT("/");
else
return io::path(p);
#else
@ -613,7 +614,7 @@ io::path CFileSystem::getFileDir(const io::path& filename) const
if ((u32)lastSlash < filename.size())
return filename.subString(0, lastSlash);
else
return ".";
return _IRR_TEXT(".");
}
@ -666,7 +667,7 @@ io::path& CFileSystem::flattenFilename(io::path& directory, const io::path& root
{
subdir = directory.subString(lastpos, pos - lastpos + 1);
if (subdir == "../")
if (subdir == _IRR_TEXT("../"))
{
if (lastWasRealDir)
{
@ -679,11 +680,11 @@ io::path& CFileSystem::flattenFilename(io::path& directory, const io::path& root
lastWasRealDir=false;
}
}
else if (subdir == "/")
else if (subdir == _IRR_TEXT("/"))
{
dir = root;
}
else if (subdir != "./" )
else if (subdir != _IRR_TEXT("./"))
{
dir.append(subdir);
lastWasRealDir=true;
@ -699,36 +700,36 @@ io::path& CFileSystem::flattenFilename(io::path& directory, const io::path& root
//! Get the relative filename, relative to the given directory
path CFileSystem::getRelativeFilename(const path& filename, const path& directory) const
{
io::path path, file, ext;
core::splitFilename(getAbsolutePath(filename), &path, &file, &ext);
io::path path1, file, ext;
core::splitFilename(getAbsolutePath(filename), &path1, &file, &ext);
io::path path2(getAbsolutePath(directory));
core::list<io::path> list1, list2;
path.split(list1, "/\\", 2);
path2.split(list2, "/\\", 2);
path1.split(list1, _IRR_TEXT("/\\"), 2);
path2.split(list2, _IRR_TEXT("/\\"), 2);
u32 i=0;
core::list<io::path>::ConstIterator it1,it2;
it1=list1.begin();
it2=list2.begin();
for (; i<list1.size() && (*it1==*it2); ++i)
for (; i<list1.size() && i<list2.size() && (*it1==*it2); ++i)
{
++it1;
++it2;
}
path="";
path1=_IRR_TEXT("");
for (; i<list2.size(); ++i)
path += "../";
path1 += _IRR_TEXT("../");
while (it1 != list1.end())
{
path += *it1++;
path += "/";
path1 += *it1++;
path1 += _IRR_TEXT('/');
}
path += file;
path1 += file;
if (ext.size())
{
path += ".";
path += ext;
path1 += _IRR_TEXT('.');
path1 += ext;
}
return path;
return path1;
}
@ -788,7 +789,7 @@ IFileList* CFileSystem::createFileList()
r = new CFileList(Path, false, false);
r->addItem(Path + "..", 0, 0, true, 0);
r->addItem(Path + _IRR_TEXT(".."), 0, 0, true, 0);
//! We use the POSIX compliant methods instead of scandir
DIR* dirHandle=opendir(Path.c_str());
@ -835,10 +836,10 @@ IFileList* CFileSystem::createFileList()
SFileListEntry e3;
//! PWD
r->addItem(Path + ".", 0, 0, true, 0);
r->addItem(Path + _IRR_TEXT("."), 0, 0, true, 0);
//! parent
r->addItem(Path + "..", 0, 0, true, 0);
r->addItem(Path + _IRR_TEXT(".."), 0, 0, true, 0);
//! merge archives
for (u32 i=0; i < FileArchives.size(); ++i)

View File

@ -15,7 +15,6 @@
#include "IGUISpriteBank.h"
#include "IFileList.h"
#include "os.h"
#include "CImage.h"
#include "fast_atof.h"
namespace irr
@ -177,7 +176,9 @@ CGUIColorSelectDialog::~CGUIColorSelectDialog()
void CGUIColorSelectDialog::buildColorRing( const core::dimension2d<u32> & dim, s32 supersample, const video::SColor& borderColor )
{
const core::dimension2d<u32> d(dim.Width * supersample, dim.Height * supersample);
video::CImage *RawTexture = new video::CImage(video::ECF_A8R8G8B8, d);
video::IVideoDriver* driver = Environment->getVideoDriver();
video::IImage *RawTexture = driver->createImage(video::ECF_A8R8G8B8, d);
RawTexture->fill ( 0x00808080 );
@ -270,14 +271,12 @@ void CGUIColorSelectDialog::buildColorRing( const core::dimension2d<u32> & dim,
if ( supersample > 1 )
{
video::CImage * filter = new video::CImage(video::ECF_A8R8G8B8, dim );
video::IImage * filter = driver->createImage(video::ECF_A8R8G8B8, dim );
RawTexture->copyToScalingBoxFilter(filter);
RawTexture->drop();
RawTexture = filter;
}
video::IVideoDriver* driver = Environment->getVideoDriver();
bool generateMipLevels = driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
driver->setTextureCreationFlag( video::ETCF_CREATE_MIP_MAPS, false);

View File

@ -575,7 +575,11 @@ bool CGUIEnvironment::postEventFromUser(const SEvent& event)
break;
case EET_KEY_INPUT_EVENT:
{
// send focus changing event
if (Focus && Focus->OnEvent(event))
return true;
// For keys we handle the event before changing focus to give elements the chance for catching the TAB
// Send focus changing event
if (event.EventType == EET_KEY_INPUT_EVENT &&
event.KeyInput.PressedDown &&
event.KeyInput.Key == KEY_TAB)
@ -587,11 +591,7 @@ bool CGUIEnvironment::postEventFromUser(const SEvent& event)
return true;
}
}
if (Focus)
{
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
return Focus->OnEvent(event);
}
}
break;
default:

View File

@ -11,7 +11,6 @@
#include "IReadFile.h"
#include "IVideoDriver.h"
#include "IGUISpriteBank.h"
#include "CImage.h"
namespace irr
{
@ -254,7 +253,7 @@ bool CGUIFont::loadTexture(video::IImage* image, const io::path& name)
switch(image->getColorFormat())
{
case video::ECF_R5G6B5:
tmpImage = new video::CImage(video::ECF_A1R5G5B5,image->getDimension());
tmpImage = Driver->createImage(video::ECF_A1R5G5B5,image->getDimension());
image->copyTo(tmpImage);
deleteTmpImage=true;
break;
@ -262,7 +261,7 @@ bool CGUIFont::loadTexture(video::IImage* image, const io::path& name)
case video::ECF_A8R8G8B8:
break;
case video::ECF_R8G8B8:
tmpImage = new video::CImage(video::ECF_A8R8G8B8,image->getDimension());
tmpImage = Driver->createImage(video::ECF_A8R8G8B8,image->getDimension());
image->copyTo(tmpImage);
deleteTmpImage=true;
break;

View File

@ -254,10 +254,6 @@ void CGUITabControl::refreshSprites()
//! Adds a tab
IGUITab* CGUITabControl::addTab(const wchar_t* caption, s32 id)
{
IGUISkin* skin = Environment->getSkin();
if (!skin)
return 0;
CGUITab* tab = new CGUITab(Tabs.size(), Environment, this, calcTabPos(), id);
tab->setText(caption);
@ -315,6 +311,59 @@ void CGUITabControl::addTab(CGUITab* tab)
}
}
//! Insert the tab at the given index
IGUITab* CGUITabControl::insertTab(s32 idx, const wchar_t* caption, s32 id)
{
if ( idx < 0 || idx > (s32)Tabs.size() ) // idx == Tabs.size() is indeed ok here as core::array can handle that
return NULL;
CGUITab* tab = new CGUITab(idx, Environment, this, calcTabPos(), id);
tab->setText(caption);
tab->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
tab->setVisible(false);
Tabs.insert(tab, (u32)idx);
if (ActiveTab == -1)
{
ActiveTab = 0;
tab->setVisible(true);
}
for ( u32 i=(u32)idx+1; i < Tabs.size(); ++i )
{
Tabs[i]->setNumber(i);
}
recalculateScrollBar();
return tab;
}
//! Removes a tab from the tabcontrol
void CGUITabControl::removeTab(s32 idx)
{
if ( idx < 0 || idx >= (s32)Tabs.size() )
return;
Tabs[(u32)idx]->drop();
Tabs.erase((u32)idx);
for ( u32 i=(u32)idx; i < Tabs.size(); ++i )
{
Tabs[i]->setNumber(i);
}
}
//! Clears the tabcontrol removing all tabs
void CGUITabControl::clear()
{
for (u32 i=0; i<Tabs.size(); ++i)
{
if (Tabs[i])
Tabs[i]->drop();
}
Tabs.clear();
}
//! Returns amount of tabs in the tabcontrol
s32 CGUITabControl::getTabCount() const
@ -368,9 +417,15 @@ bool CGUITabControl::OnEvent(const SEvent& event)
// todo: dragging tabs around
return true;
case EMIE_LMOUSE_LEFT_UP:
if (selectTab(core::position2d<s32>(event.MouseInput.X, event.MouseInput.Y)))
{
s32 idx = getTabAt(event.MouseInput.X, event.MouseInput.Y);
if ( idx >= 0 )
{
setActiveTab(idx);
return true;
}
break;
}
default:
break;
}
@ -402,7 +457,7 @@ void CGUITabControl::scrollRight()
recalculateScrollBar();
}
s32 CGUITabControl::calcTabWidth(s32 pos, IGUIFont* font, const wchar_t* text, bool withScrollControl)
s32 CGUITabControl::calcTabWidth(s32 pos, IGUIFont* font, const wchar_t* text, bool withScrollControl) const
{
if ( !font )
return 0;
@ -477,55 +532,6 @@ bool CGUITabControl::needScrollControl(s32 startIndex, bool withScrollControl)
}
bool CGUITabControl::selectTab(core::position2d<s32> p)
{
IGUISkin* skin = Environment->getSkin();
IGUIFont* font = skin->getFont();
core::rect<s32> frameRect(AbsoluteRect);
if ( VerticalAlignment == EGUIA_UPPERLEFT )
{
frameRect.UpperLeftCorner.Y += 2;
frameRect.LowerRightCorner.Y = frameRect.UpperLeftCorner.Y + TabHeight;
}
else
{
frameRect.UpperLeftCorner.Y = frameRect.LowerRightCorner.Y - TabHeight;
}
s32 pos = frameRect.UpperLeftCorner.X + 2;
if (!frameRect.isPointInside(p))
return false;
for (s32 i=CurrentScrollTabIndex; i<(s32)Tabs.size(); ++i)
{
// get Text
const wchar_t* text = 0;
if (Tabs[i])
text = Tabs[i]->getText();
// get text length
s32 len = calcTabWidth(pos, font, text, true);
if ( ScrollControl && pos+len > UpButton->getAbsolutePosition().UpperLeftCorner.X - 2 )
return false;
frameRect.UpperLeftCorner.X = pos;
frameRect.LowerRightCorner.X = frameRect.UpperLeftCorner.X + len;
pos += len;
if (frameRect.isPointInside(p))
{
setActiveTab(i);
return true;
}
}
return false;
}
core::rect<s32> CGUITabControl::calcTabPos()
{
core::rect<s32> r;
@ -863,6 +869,54 @@ EGUI_ALIGNMENT CGUITabControl::getTabVerticalAlignment() const
}
s32 CGUITabControl::getTabAt(s32 xpos, s32 ypos) const
{
core::position2di p(xpos, ypos);
IGUISkin* skin = Environment->getSkin();
IGUIFont* font = skin->getFont();
core::rect<s32> frameRect(AbsoluteRect);
if ( VerticalAlignment == EGUIA_UPPERLEFT )
{
frameRect.UpperLeftCorner.Y += 2;
frameRect.LowerRightCorner.Y = frameRect.UpperLeftCorner.Y + TabHeight;
}
else
{
frameRect.UpperLeftCorner.Y = frameRect.LowerRightCorner.Y - TabHeight;
}
s32 pos = frameRect.UpperLeftCorner.X + 2;
if (!frameRect.isPointInside(p))
return -1;
for (s32 i=CurrentScrollTabIndex; i<(s32)Tabs.size(); ++i)
{
// get Text
const wchar_t* text = 0;
if (Tabs[i])
text = Tabs[i]->getText();
// get text length
s32 len = calcTabWidth(pos, font, text, true);
if ( ScrollControl && pos+len > UpButton->getAbsolutePosition().UpperLeftCorner.X - 2 )
return -1;
frameRect.UpperLeftCorner.X = pos;
frameRect.LowerRightCorner.X = frameRect.UpperLeftCorner.X + len;
pos += len;
if (frameRect.isPointInside(p))
{
return i;
}
}
return -1;
}
//! Returns which tab is currently active
s32 CGUITabControl::getActiveTab() const
{

View File

@ -97,6 +97,15 @@ namespace gui
//! Adds a tab that has already been created
virtual void addTab(CGUITab* tab);
//! Insert the tab at the given index
virtual IGUITab* insertTab(s32 idx, const wchar_t* caption, s32 id=-1);
//! Removes a tab from the tabcontrol
virtual void removeTab(s32 idx);
//! Clears the tabcontrol removing all tabs
virtual void clear();
//! Returns amount of tabs in the tabcontrol
virtual s32 getTabCount() const;
@ -112,6 +121,9 @@ namespace gui
//! Returns which tab is currently active
virtual s32 getActiveTab() const;
//! get the the id of the tab at the given absolute coordinates
virtual s32 getTabAt(s32 xpos, s32 ypos) const;
//! called if an event happened.
virtual bool OnEvent(const SEvent& event);
@ -156,18 +168,17 @@ namespace gui
private:
bool selectTab(core::position2d<s32> p);
void scrollLeft();
void scrollRight();
bool needScrollControl( s32 startIndex=0, bool withScrollControl=false );
s32 calcTabWidth(s32 pos, IGUIFont* font, const wchar_t* text, bool withScrollControl );
s32 calcTabWidth(s32 pos, IGUIFont* font, const wchar_t* text, bool withScrollControl ) const;
core::rect<s32> calcTabPos();
void recalculateScrollButtonPlacement();
void recalculateScrollBar();
void refreshSprites();
core::array<CGUITab*> Tabs;
core::array<CGUITab*> Tabs; // CGUITab* because we need setNumber (which is certainly not nice)
s32 ActiveTab;
bool Border;
bool FillBackground;

View File

@ -8,7 +8,6 @@
#include "SMesh.h"
#include "IMesh.h"
#include "IVideoDriver.h"
#include "CImage.h"
#include "os.h"
namespace irr
@ -265,7 +264,7 @@ IMesh* CGeometryCreator::createTerrainMesh(video::IImage* texture,
{
c8 textureName[64];
// create texture for this block
video::IImage* img = new video::CImage(texture->getColorFormat(), core::dimension2d<u32>(core::floor32(blockSize.Width*thRel.X), core::floor32(blockSize.Height*thRel.Y)));
video::IImage* img = driver->createImage(texture->getColorFormat(), core::dimension2d<u32>(core::floor32(blockSize.Width*thRel.X), core::floor32(blockSize.Height*thRel.Y)));
texture->copyTo(img, core::position2di(0,0), core::recti(
core::position2d<s32>(core::floor32(processed.X*thRel.X), core::floor32(processed.Y*thRel.Y)),
core::dimension2d<u32>(core::floor32(blockSize.Width*thRel.X), core::floor32(blockSize.Height*thRel.Y))), 0);

View File

@ -451,55 +451,5 @@ inline SColor CImage::getPixelBox( s32 x, s32 y, s32 fx, s32 fy, s32 bias ) cons
}
// Methods for Software drivers, non-virtual and not necessary to copy into other image classes
//! draws a rectangle
void CImage::drawRectangle(const core::rect<s32>& rect, const SColor &color)
{
Blit(color.getAlpha() == 0xFF ? BLITTER_COLOR : BLITTER_COLOR_ALPHA,
this, 0, &rect.UpperLeftCorner, 0, &rect, color.color);
}
//! draws a line from to with color
void CImage::drawLine(const core::position2d<s32>& from, const core::position2d<s32>& to, const SColor &color)
{
AbsRectangle clip;
GetClip( clip, this );
core::position2d<s32> p[2];
if ( ClipLine( clip, p[0], p[1], from, to ) )
{
u32 alpha = extractAlpha( color.color );
switch ( Format )
{
case ECF_A1R5G5B5:
if ( alpha == 256 )
{
RenderLine16_Decal( this, p[0], p[1], video::A8R8G8B8toA1R5G5B5( color.color ) );
}
else
{
RenderLine16_Blend( this, p[0], p[1], video::A8R8G8B8toA1R5G5B5( color.color ), alpha >> 3 );
}
break;
case ECF_A8R8G8B8:
if ( alpha == 256 )
{
RenderLine32_Decal( this, p[0], p[1], color.color );
}
else
{
RenderLine32_Blend( this, p[0], p[1], color.color, alpha );
}
break;
default:
break;
}
}
}
} // end namespace video
} // end namespace irr

View File

@ -103,12 +103,6 @@ public:
//! fills the surface with given color
virtual void fill(const SColor &color);
//! draws a rectangle
void drawRectangle(const core::rect<s32>& rect, const SColor &color);
//! draws a line from to
void drawLine(const core::position2d<s32>& from, const core::position2d<s32>& to, const SColor &color);
private:
//! assumes format and size has been set and creates the rest

View File

@ -28,21 +28,21 @@ namespace irr
namespace video
{
namespace
{
/*!
DDSDecodePixelFormat()
determines which pixel format the dds texture is in
*/
void DDSDecodePixelFormat( ddsBuffer *dds, eDDSPixelFormat *pf )
{
u32 fourCC;
/* dummy check */
if( dds == NULL || pf == NULL )
return;
/* extract fourCC */
fourCC = dds->pixelFormat.fourCC;
const u32 fourCC = dds->pixelFormat.fourCC;
/* test it */
if( fourCC == 0 )
@ -62,7 +62,6 @@ void DDSDecodePixelFormat( ddsBuffer *dds, eDDSPixelFormat *pf )
}
/*!
DDSGetInfo()
extracts relevant info from a dds texture, returns 0 on success
@ -93,7 +92,6 @@ s32 DDSGetInfo( ddsBuffer *dds, s32 *width, s32 *height, eDDSPixelFormat *pf )
}
/*!
DDSGetColorBlockColors()
extracts colors from a dds color block
@ -188,14 +186,13 @@ void DDSGetColorBlockColors( ddsColorBlock *block, ddsColor colors[ 4 ] )
}
/*
DDSDecodeColorBlock()
decodes a dds color block
fixme: make endian-safe
*/
static void DDSDecodeColorBlock( u32 *pixel, ddsColorBlock *block, s32 width, u32 colors[ 4 ] )
void DDSDecodeColorBlock( u32 *pixel, ddsColorBlock *block, s32 width, u32 colors[ 4 ] )
{
s32 r, n;
u32 bits;
@ -246,13 +243,11 @@ static void DDSDecodeColorBlock( u32 *pixel, ddsColorBlock *block, s32 width, u3
}
/*
DDSDecodeAlphaExplicit()
decodes a dds explicit alpha block
*/
static void DDSDecodeAlphaExplicit( u32 *pixel, ddsAlphaBlockExplicit *alphaBlock, s32 width, u32 alphaZero )
void DDSDecodeAlphaExplicit( u32 *pixel, ddsAlphaBlockExplicit *alphaBlock, s32 width, u32 alphaZero )
{
s32 row, pix;
u16 word;
@ -279,7 +274,6 @@ static void DDSDecodeAlphaExplicit( u32 *pixel, ddsAlphaBlockExplicit *alphaBloc
*pixel |= *((u32*) &color);
word >>= 4; /* move next bits to lowest 4 */
pixel++; /* move to next pixel in the row */
}
}
}
@ -290,16 +284,14 @@ static void DDSDecodeAlphaExplicit( u32 *pixel, ddsAlphaBlockExplicit *alphaBloc
DDSDecodeAlpha3BitLinear()
decodes interpolated alpha block
*/
static void DDSDecodeAlpha3BitLinear( u32 *pixel, ddsAlphaBlock3BitLinear *alphaBlock, s32 width, u32 alphaZero )
void DDSDecodeAlpha3BitLinear( u32 *pixel, ddsAlphaBlock3BitLinear *alphaBlock, s32 width, u32 alphaZero )
{
s32 row, pix;
u32 stuff;
u8 bits[ 4 ][ 4 ];
u16 alphas[ 8 ];
ddsColor aColors[ 4 ][ 4 ];
s32 row, pix;
u32 stuff;
u8 bits[ 4 ][ 4 ];
u16 alphas[ 8 ];
ddsColor aColors[ 4 ][ 4 ];
/* get initial alphas */
alphas[ 0 ] = alphaBlock->alpha0;
@ -397,18 +389,16 @@ static void DDSDecodeAlpha3BitLinear( u32 *pixel, ddsAlphaBlock3BitLinear *alpha
}
/*
DDSDecompressDXT1()
decompresses a dxt1 format texture
*/
s32 DDSDecompressDXT1( ddsBuffer *dds, s32 width, s32 height, u8 *pixels )
{
s32 x, y, xBlocks, yBlocks;
u32 *pixel;
ddsColorBlock *block;
ddsColor colors[ 4 ];
s32 x, y, xBlocks, yBlocks;
u32 *pixel;
ddsColorBlock *block;
ddsColor colors[ 4 ];
/* setup */
xBlocks = width / 4;
@ -418,7 +408,7 @@ s32 DDSDecompressDXT1( ddsBuffer *dds, s32 width, s32 height, u8 *pixels )
for( y = 0; y < yBlocks; y++ )
{
/* 8 bytes per block */
block = (ddsColorBlock*) ((u32) dds->data + y * xBlocks * 8);
block = (ddsColorBlock*) (dds->data + y * xBlocks * 8);
/* walk x */
for( x = 0; x < xBlocks; x++, block++ )
@ -434,7 +424,6 @@ s32 DDSDecompressDXT1( ddsBuffer *dds, s32 width, s32 height, u8 *pixels )
}
/*
DDSDecompressDXT3()
decompresses a dxt3 format texture
@ -442,12 +431,11 @@ decompresses a dxt3 format texture
s32 DDSDecompressDXT3( ddsBuffer *dds, s32 width, s32 height, u8 *pixels )
{
s32 x, y, xBlocks, yBlocks;
u32 *pixel, alphaZero;
ddsColorBlock *block;
ddsAlphaBlockExplicit *alphaBlock;
ddsColor colors[ 4 ];
s32 x, y, xBlocks, yBlocks;
u32 *pixel, alphaZero;
ddsColorBlock *block;
ddsAlphaBlockExplicit *alphaBlock;
ddsColor colors[ 4 ];
/* setup */
xBlocks = width / 4;
@ -464,7 +452,7 @@ s32 DDSDecompressDXT3( ddsBuffer *dds, s32 width, s32 height, u8 *pixels )
for( y = 0; y < yBlocks; y++ )
{
/* 8 bytes per block, 1 block for alpha, 1 block for color */
block = (ddsColorBlock*) ((u32) dds->data + y * xBlocks * 16);
block = (ddsColorBlock*) (dds->data + y * xBlocks * 16);
/* walk x */
for( x = 0; x < xBlocks; x++, block++ )
@ -490,19 +478,17 @@ s32 DDSDecompressDXT3( ddsBuffer *dds, s32 width, s32 height, u8 *pixels )
}
/*
DDSDecompressDXT5()
decompresses a dxt5 format texture
*/
s32 DDSDecompressDXT5( ddsBuffer *dds, s32 width, s32 height, u8 *pixels )
{
s32 x, y, xBlocks, yBlocks;
u32 *pixel, alphaZero;
ddsColorBlock *block;
ddsAlphaBlock3BitLinear *alphaBlock;
ddsColor colors[ 4 ];
s32 x, y, xBlocks, yBlocks;
u32 *pixel, alphaZero;
ddsColorBlock *block;
ddsAlphaBlock3BitLinear *alphaBlock;
ddsColor colors[ 4 ];
/* setup */
xBlocks = width / 4;
@ -519,7 +505,7 @@ s32 DDSDecompressDXT5( ddsBuffer *dds, s32 width, s32 height, u8 *pixels )
for( y = 0; y < yBlocks; y++ )
{
/* 8 bytes per block, 1 block for alpha, 1 block for color */
block = (ddsColorBlock*) ((u32) dds->data + y * xBlocks * 16);
block = (ddsColorBlock*) (dds->data + y * xBlocks * 16);
/* walk x */
for( x = 0; x < xBlocks; x++, block++ )
@ -545,62 +531,49 @@ s32 DDSDecompressDXT5( ddsBuffer *dds, s32 width, s32 height, u8 *pixels )
}
/*
DDSDecompressDXT2()
decompresses a dxt2 format texture (fixme: un-premultiply alpha)
*/
s32 DDSDecompressDXT2( ddsBuffer *dds, s32 width, s32 height, u8 *pixels )
{
s32 r;
/* decompress dxt3 first */
r = DDSDecompressDXT3( dds, width, height, pixels );
const s32 r = DDSDecompressDXT3( dds, width, height, pixels );
/* return to sender */
return r;
}
/*
DDSDecompressDXT4()
decompresses a dxt4 format texture (fixme: un-premultiply alpha)
*/
s32 DDSDecompressDXT4( ddsBuffer *dds, s32 width, s32 height, u8 *pixels )
{
s32 r;
/* decompress dxt5 first */
r = DDSDecompressDXT5( dds, width, height, pixels );
const s32 r = DDSDecompressDXT5( dds, width, height, pixels );
/* return to sender */
return r;
}
/*
DDSDecompressARGB8888()
decompresses an argb 8888 format texture
*/
s32 DDSDecompressARGB8888( ddsBuffer *dds, s32 width, s32 height, u8 *pixels )
{
s32 x, y;
u8 *in, *out;
/* setup */
in = dds->data;
out = pixels;
u8* in = dds->data;
u8* out = pixels;
/* walk y */
for( y = 0; y < height; y++ )
for(s32 y = 0; y < height; y++)
{
/* walk x */
for( x = 0; x < width; x++ )
for(s32 x = 0; x < width; x++)
{
*out++ = *in++;
*out++ = *in++;
@ -614,20 +587,18 @@ s32 DDSDecompressARGB8888( ddsBuffer *dds, s32 width, s32 height, u8 *pixels )
}
/*
DDSDecompress()
decompresses a dds texture into an rgba image buffer, returns 0 on success
*/
s32 DDSDecompress( ddsBuffer *dds, u8 *pixels )
{
s32 width, height, r;
eDDSPixelFormat pf;
s32 width, height;
eDDSPixelFormat pf;
/* get dds info */
r = DDSGetInfo( dds, &width, &height, &pf );
if( r )
s32 r = DDSGetInfo( dds, &width, &height, &pf );
if ( r )
return r;
/* decompress */
@ -669,6 +640,9 @@ s32 DDSDecompress( ddsBuffer *dds, u8 *pixels )
return r;
}
} // end anonymous namespace
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".tga")
bool CImageLoaderDDS::isALoadableFileExtension(const io::path& filename) const
@ -677,8 +651,6 @@ bool CImageLoaderDDS::isALoadableFileExtension(const io::path& filename) const
}
//! returns true if the file maybe is able to be loaded by this class
bool CImageLoaderDDS::isALoadableFileFormat(io::IReadFile* file) const
{
@ -691,11 +663,10 @@ bool CImageLoaderDDS::isALoadableFileFormat(io::IReadFile* file) const
s32 width, height;
eDDSPixelFormat pixelFormat;
return 0 == DDSGetInfo( &header, &width, &height, &pixelFormat);
return (0 == DDSGetInfo( &header, &width, &height, &pixelFormat));
}
//! creates a surface from the file
IImage* CImageLoaderDDS::loadImage(io::IReadFile* file) const
{
@ -727,7 +698,7 @@ IImage* CImageLoaderDDS::loadImage(io::IReadFile* file) const
}
//! creates a loader which is able to load tgas
//! creates a loader which is able to load dds images
IImageLoader* createImageLoaderDDS()
{
return new CImageLoaderDDS();
@ -738,4 +709,3 @@ IImageLoader* createImageLoaderDDS()
} // end namespace irr
#endif

View File

@ -9,13 +9,13 @@
#include "IImageLoader.h"
#define _IRR_COMPILE_WITH_DDS_LOADER_
namespace irr
{
namespace video
{
#if defined(_IRR_COMPILE_WITH_DDS_LOADER_) || defined(_IRR_COMPILE_WITH_DDS_WRITER_)
#if defined(_IRR_COMPILE_WITH_DDS_LOADER_)
// byte-align structures
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
@ -195,13 +195,6 @@ struct ddsColor
} PACK_STRUCT;
/* public functions */
s32 DDSGetInfo( ddsBuffer *dds, s32 *width, s32 *height, eDDSPixelFormat *pf );
s32 DDSDecompress( ddsBuffer *dds, u8 *pixels );
/* endian tomfoolery */
typedef union
{
@ -295,7 +288,7 @@ floatSwapUnion;
#ifdef _IRR_COMPILE_WITH_DDS_LOADER_
/*!
Surface Loader for targa images
Surface Loader for DDS images
*/
class CImageLoaderDDS : public IImageLoader
{
@ -315,7 +308,7 @@ private:
};
#endif // compiled with loader
#endif // compiled with DDS loader
} // end namespace video
} // end namespace irr

View File

@ -56,7 +56,7 @@ CIrrDeviceFB::CIrrDeviceFB(const SIrrlichtCreationParameters& params)
linuxversion += " ";
linuxversion += FBInfo.machine;
Operator = new COSOperator(linuxversion.c_str());
Operator = new COSOperator(linuxversion);
os::Printer::log(linuxversion.c_str(), ELL_INFORMATION);
// create window

View File

@ -106,7 +106,7 @@ CIrrDeviceLinux::CIrrDeviceLinux(const SIrrlichtCreationParameters& param)
linuxversion += " ";
linuxversion += LinuxInfo.machine;
Operator = new COSOperator(linuxversion.c_str(), this);
Operator = new COSOperator(linuxversion, this);
os::Printer::log(linuxversion.c_str(), ELL_INFORMATION);
// create keymap
@ -416,6 +416,11 @@ bool CIrrDeviceLinux::createWindow()
GLX_SAMPLE_BUFFERS_SGIS, 1,
GLX_SAMPLES_SGIS, CreationParams.AntiAlias, // 18,19
#endif
//#ifdef GL_ARB_framebuffer_sRGB
// GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, CreationParams.HandleSRGB,
//#elif defined(GL_EXT_framebuffer_sRGB)
// GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, CreationParams.HandleSRGB,
//#endif
GLX_STEREO, CreationParams.Stereobuffer?True:False,
None
};
@ -550,7 +555,7 @@ bool CIrrDeviceLinux::createWindow()
// attribute array for the draw buffer
int visualAttrBuffer[] =
{
GLX_RGBA, GL_TRUE,
GLX_RGBA, GLX_USE_GL,
GLX_RED_SIZE, 4,
GLX_GREEN_SIZE, 4,
GLX_BLUE_SIZE, 4,
@ -562,6 +567,11 @@ bool CIrrDeviceLinux::createWindow()
// GLX_USE_GL, which is silently ignored by glXChooseVisual
CreationParams.Doublebuffer?GLX_DOUBLEBUFFER:GLX_USE_GL, // 14
CreationParams.Stereobuffer?GLX_STEREO:GLX_USE_GL, // 15
//#ifdef GL_ARB_framebuffer_sRGB
// CreationParams.HandleSRGB?GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB:GLX_USE_GL,
//#elif defined(GL_EXT_framebuffer_sRGB)
// CreationParams.HandleSRGB?GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT:GLX_USE_GL,
//#endif
None
};
@ -618,7 +628,7 @@ bool CIrrDeviceLinux::createWindow()
}
#ifdef _DEBUG
else
os::Printer::log("Visual chosen: ", core::stringc(static_cast<u32>(visual->visualid)).c_str(), ELL_INFORMATION);
os::Printer::log("Visual chosen: ", core::stringc(static_cast<u32>(visual->visualid)).c_str(), ELL_DEBUG);
#endif
// create color map
@ -851,7 +861,8 @@ bool CIrrDeviceLinux::run()
#ifdef _IRR_COMPILE_WITH_X11_
static_cast<CCursorControl*>(CursorControl)->update();
if ( CursorControl )
static_cast<CCursorControl*>(CursorControl)->update();
if ((CreationParams.DriverType != video::EDT_NULL) && display)
{

View File

@ -94,7 +94,7 @@ CIrrDeviceSDL::CIrrDeviceSDL(const SIrrlichtCreationParameters& param)
sdlversion += ".";
sdlversion += Info.version.patch;
Operator = new COSOperator(sdlversion.c_str());
Operator = new COSOperator(sdlversion);
os::Printer::log(sdlversion.c_str(), ELL_INFORMATION);
// create keymap

View File

@ -26,12 +26,12 @@
#pragma comment(lib, "dinput8.lib")
#pragma comment(lib, "dxguid.lib")
#endif
#endif
#else
#ifdef _MSC_VER
#pragma comment(lib, "winmm.lib")
#endif
#endif
#endif
namespace irr
{
@ -919,7 +919,7 @@ CIrrDeviceWin32::CIrrDeviceWin32(const SIrrlichtCreationParameters& params)
// get windows version and create OS operator
core::stringc winversion;
getWindowsVersion(winversion);
Operator = new COSOperator(winversion.c_str());
Operator = new COSOperator(winversion);
os::Printer::log(winversion.c_str(), ELL_INFORMATION);
// get handle to exe file

View File

@ -346,7 +346,7 @@ CIrrDeviceWinCE::CIrrDeviceWinCE(const SIrrlichtCreationParameters& params)
core::stringc winversion;
getWindowsVersion(winversion);
Operator = new COSOperator(winversion.c_str());
Operator = new COSOperator(winversion);
os::Printer::log(winversion.c_str(), ELL_INFORMATION);
HINSTANCE hInstance = GetModuleHandle(0);

View File

@ -17,8 +17,6 @@
#include "SMeshBuffer.h"
#include "IReadFile.h"
#include "IAttributes.h"
#include "CImage.h"
#include "CColorConverter.h"
#include "CMY3DHelper.h"
#include "os.h"

View File

@ -6,7 +6,6 @@
// I (Nikolaus Gebhardt) did some few changes to this:
// - replaced logging calls to their os:: counterparts
// - removed some logging calls
// - enabled image dropping of CImage again, because that bug has been fixed now
// - removed setTexture path and replaced it with the directory of the mesh
// - added EAMT_MY3D file type
// - fixed a memory leak when decompressing RLE data.

View File

@ -48,29 +48,38 @@ void CMeshManipulator::flipSurfaces(scene::IMesh* mesh) const
{
IMeshBuffer* buffer = mesh->getMeshBuffer(b);
const u32 idxcnt = buffer->getIndexCount();
u16* idx = buffer->getIndices();
s32 tmp;
for (u32 i=0; i<idxcnt; i+=3)
if (buffer->getIndexType() == video::EIT_16BIT)
{
tmp = idx[i+1];
idx[i+1] = idx[i+2];
idx[i+2] = tmp;
u16* idx = buffer->getIndices();
for (u32 i=0; i<idxcnt; i+=3)
{
const u16 tmp = idx[i+1];
idx[i+1] = idx[i+2];
idx[i+2] = tmp;
}
}
else
{
u32* idx = reinterpret_cast<u32*>(buffer->getIndices());
for (u32 i=0; i<idxcnt; i+=3)
{
const u32 tmp = idx[i+1];
idx[i+1] = idx[i+2];
idx[i+2] = tmp;
}
}
}
}
//! Recalculates all normals of the mesh buffer.
/** \param buffer: Mesh buffer on which the operation is performed. */
void CMeshManipulator::recalculateNormals(IMeshBuffer* buffer, bool smooth, bool angleWeighted) const
namespace
{
template <typename T>
void recalculateNormalsT(IMeshBuffer* buffer, bool smooth, bool angleWeighted)
{
if (!buffer)
return;
const u32 vtxcnt = buffer->getVertexCount();
const u32 idxcnt = buffer->getIndexCount();
const u16* idx = buffer->getIndices();
const T* idx = reinterpret_cast<T*>(buffer->getIndices());
if (!smooth)
{
@ -90,7 +99,7 @@ void CMeshManipulator::recalculateNormals(IMeshBuffer* buffer, bool smooth, bool
u32 i;
for ( i = 0; i!= vtxcnt; ++i )
buffer->getNormal(i).set( 0.f, 0.f, 0.f );
buffer->getNormal(i).set(0.f, 0.f, 0.f);
for ( i=0; i<idxcnt; i+=3)
{
@ -111,6 +120,21 @@ void CMeshManipulator::recalculateNormals(IMeshBuffer* buffer, bool smooth, bool
buffer->getNormal(i).normalize();
}
}
}
//! Recalculates all normals of the mesh buffer.
/** \param buffer: Mesh buffer on which the operation is performed. */
void CMeshManipulator::recalculateNormals(IMeshBuffer* buffer, bool smooth, bool angleWeighted) const
{
if (!buffer)
return;
if (buffer->getIndexType()==video::EIT_16BIT)
recalculateNormalsT<u16>(buffer, smooth, angleWeighted);
else
recalculateNormalsT<u32>(buffer, smooth, angleWeighted);
}
//! Recalculates all normals of the mesh.
@ -126,168 +150,433 @@ void CMeshManipulator::recalculateNormals(scene::IMesh* mesh, bool smooth, bool
}
//! Recalculates tangents, requires a tangent mesh
namespace
{
void calculateTangents(
core::vector3df& normal,
core::vector3df& tangent,
core::vector3df& binormal,
const core::vector3df& vt1, const core::vector3df& vt2, const core::vector3df& vt3, // vertices
const core::vector2df& tc1, const core::vector2df& tc2, const core::vector2df& tc3) // texture coords
{
// choose one of them:
//#define USE_NVIDIA_GLH_VERSION // use version used by nvidia in glh headers
#define USE_IRR_VERSION
#ifdef USE_IRR_VERSION
core::vector3df v1 = vt1 - vt2;
core::vector3df v2 = vt3 - vt1;
normal = v2.crossProduct(v1);
normal.normalize();
// binormal
f32 deltaX1 = tc1.X - tc2.X;
f32 deltaX2 = tc3.X - tc1.X;
binormal = (v1 * deltaX2) - (v2 * deltaX1);
binormal.normalize();
// tangent
f32 deltaY1 = tc1.Y - tc2.Y;
f32 deltaY2 = tc3.Y - tc1.Y;
tangent = (v1 * deltaY2) - (v2 * deltaY1);
tangent.normalize();
// adjust
core::vector3df txb = tangent.crossProduct(binormal);
if (txb.dotProduct(normal) < 0.0f)
{
tangent *= -1.0f;
binormal *= -1.0f;
}
#endif // USE_IRR_VERSION
#ifdef USE_NVIDIA_GLH_VERSION
tangent.set(0,0,0);
binormal.set(0,0,0);
core::vector3df v1(vt2.X - vt1.X, tc2.X - tc1.X, tc2.Y - tc1.Y);
core::vector3df v2(vt3.X - vt1.X, tc3.X - tc1.X, tc3.Y - tc1.Y);
core::vector3df txb = v1.crossProduct(v2);
if ( !core::iszero ( txb.X ) )
{
tangent.X = -txb.Y / txb.X;
binormal.X = -txb.Z / txb.X;
}
v1.X = vt2.Y - vt1.Y;
v2.X = vt3.Y - vt1.Y;
txb = v1.crossProduct(v2);
if ( !core::iszero ( txb.X ) )
{
tangent.Y = -txb.Y / txb.X;
binormal.Y = -txb.Z / txb.X;
}
v1.X = vt2.Z - vt1.Z;
v2.X = vt3.Z - vt1.Z;
txb = v1.crossProduct(v2);
if ( !core::iszero ( txb.X ) )
{
tangent.Z = -txb.Y / txb.X;
binormal.Z = -txb.Z / txb.X;
}
tangent.normalize();
binormal.normalize();
normal = tangent.crossProduct(binormal);
normal.normalize();
binormal = tangent.crossProduct(normal);
binormal.normalize();
core::plane3d<f32> pl(vt1, vt2, vt3);
if(normal.dotProduct(pl.Normal) < 0.0f )
normal *= -1.0f;
#endif // USE_NVIDIA_GLH_VERSION
}
//! Recalculates tangents for a tangent mesh buffer
template <typename T>
void recalculateTangentsT(IMeshBuffer* buffer, bool recalculateNormals, bool smooth, bool angleWeighted)
{
if (!buffer || (buffer->getVertexType()!= video::EVT_TANGENTS))
return;
const u32 vtxCnt = buffer->getVertexCount();
const u32 idxCnt = buffer->getIndexCount();
T* idx = reinterpret_cast<T*>(buffer->getIndices());
video::S3DVertexTangents* v =
(video::S3DVertexTangents*)buffer->getVertices();
if (smooth)
{
u32 i;
for ( i = 0; i!= vtxCnt; ++i )
{
if (recalculateNormals)
v[i].Normal.set( 0.f, 0.f, 0.f );
v[i].Tangent.set( 0.f, 0.f, 0.f );
v[i].Binormal.set( 0.f, 0.f, 0.f );
}
//Each vertex gets the sum of the tangents and binormals from the faces around it
for ( i=0; i<idxCnt; i+=3)
{
// if this triangle is degenerate, skip it!
if (v[idx[i+0]].Pos == v[idx[i+1]].Pos ||
v[idx[i+0]].Pos == v[idx[i+2]].Pos ||
v[idx[i+1]].Pos == v[idx[i+2]].Pos
/*||
v[idx[i+0]].TCoords == v[idx[i+1]].TCoords ||
v[idx[i+0]].TCoords == v[idx[i+2]].TCoords ||
v[idx[i+1]].TCoords == v[idx[i+2]].TCoords */
)
continue;
//Angle-weighted normals look better, but are slightly more CPU intensive to calculate
core::vector3df weight(1.f,1.f,1.f);
if (angleWeighted)
weight = getAngleWeight(v[i+0].Pos,v[i+1].Pos,v[i+2].Pos);
core::vector3df localNormal;
core::vector3df localTangent;
core::vector3df localBinormal;
calculateTangents(
localNormal,
localTangent,
localBinormal,
v[idx[i+0]].Pos,
v[idx[i+1]].Pos,
v[idx[i+2]].Pos,
v[idx[i+0]].TCoords,
v[idx[i+1]].TCoords,
v[idx[i+2]].TCoords);
if (recalculateNormals)
v[idx[i+0]].Normal += localNormal * weight.X;
v[idx[i+0]].Tangent += localTangent * weight.X;
v[idx[i+0]].Binormal += localBinormal * weight.X;
calculateTangents(
localNormal,
localTangent,
localBinormal,
v[idx[i+1]].Pos,
v[idx[i+2]].Pos,
v[idx[i+0]].Pos,
v[idx[i+1]].TCoords,
v[idx[i+2]].TCoords,
v[idx[i+0]].TCoords);
if (recalculateNormals)
v[idx[i+1]].Normal += localNormal * weight.Y;
v[idx[i+1]].Tangent += localTangent * weight.Y;
v[idx[i+1]].Binormal += localBinormal * weight.Y;
calculateTangents(
localNormal,
localTangent,
localBinormal,
v[idx[i+2]].Pos,
v[idx[i+0]].Pos,
v[idx[i+1]].Pos,
v[idx[i+2]].TCoords,
v[idx[i+0]].TCoords,
v[idx[i+1]].TCoords);
if (recalculateNormals)
v[idx[i+2]].Normal += localNormal * weight.Z;
v[idx[i+2]].Tangent += localTangent * weight.Z;
v[idx[i+2]].Binormal += localBinormal * weight.Z;
}
// Normalize the tangents and binormals
if (recalculateNormals)
{
for ( i = 0; i!= vtxCnt; ++i )
v[i].Normal.normalize();
}
for ( i = 0; i!= vtxCnt; ++i )
{
v[i].Tangent.normalize();
v[i].Binormal.normalize();
}
}
else
{
core::vector3df localNormal;
for (u32 i=0; i<idxCnt; i+=3)
{
calculateTangents(
localNormal,
v[idx[i+0]].Tangent,
v[idx[i+0]].Binormal,
v[idx[i+0]].Pos,
v[idx[i+1]].Pos,
v[idx[i+2]].Pos,
v[idx[i+0]].TCoords,
v[idx[i+1]].TCoords,
v[idx[i+2]].TCoords);
if (recalculateNormals)
v[idx[i+0]].Normal=localNormal;
calculateTangents(
localNormal,
v[idx[i+1]].Tangent,
v[idx[i+1]].Binormal,
v[idx[i+1]].Pos,
v[idx[i+2]].Pos,
v[idx[i+0]].Pos,
v[idx[i+1]].TCoords,
v[idx[i+2]].TCoords,
v[idx[i+0]].TCoords);
if (recalculateNormals)
v[idx[i+1]].Normal=localNormal;
calculateTangents(
localNormal,
v[idx[i+2]].Tangent,
v[idx[i+2]].Binormal,
v[idx[i+2]].Pos,
v[idx[i+0]].Pos,
v[idx[i+1]].Pos,
v[idx[i+2]].TCoords,
v[idx[i+0]].TCoords,
v[idx[i+1]].TCoords);
if (recalculateNormals)
v[idx[i+2]].Normal=localNormal;
}
}
}
}
//! Recalculates tangents for a tangent mesh buffer
void CMeshManipulator::recalculateTangents(IMeshBuffer* buffer, bool recalculateNormals, bool smooth, bool angleWeighted) const
{
if (buffer && (buffer->getVertexType() == video::EVT_TANGENTS))
{
if (buffer->getIndexType() == video::EIT_16BIT)
recalculateTangentsT<u16>(buffer, recalculateNormals, smooth, angleWeighted);
else
recalculateTangentsT<u32>(buffer, recalculateNormals, smooth, angleWeighted);
}
}
//! Recalculates tangents for all tangent mesh buffers
void CMeshManipulator::recalculateTangents(IMesh* mesh, bool recalculateNormals, bool smooth, bool angleWeighted) const
{
if (!mesh || !mesh->getMeshBufferCount() || (mesh->getMeshBuffer(0)->getVertexType()!= video::EVT_TANGENTS))
if (!mesh)
return;
const u32 meshBufferCount = mesh->getMeshBufferCount();
for (u32 b=0; b<meshBufferCount; ++b)
{
IMeshBuffer* clone = mesh->getMeshBuffer(b);
const u32 vtxCnt = clone->getVertexCount();
const u32 idxCnt = clone->getIndexCount();
recalculateTangents(mesh->getMeshBuffer(b), recalculateNormals, smooth, angleWeighted);
}
}
u16* idx = clone->getIndices();
video::S3DVertexTangents* v =
(video::S3DVertexTangents*)clone->getVertices();
if (smooth)
namespace
{
//! Creates a planar texture mapping on the meshbuffer
template<typename T>
void makePlanarTextureMappingT(scene::IMeshBuffer* buffer, f32 resolution)
{
u32 idxcnt = buffer->getIndexCount();
T* idx = reinterpret_cast<T*>(buffer->getIndices());
for (u32 i=0; i<idxcnt; i+=3)
{
core::plane3df p(buffer->getPosition(idx[i+0]), buffer->getPosition(idx[i+1]), buffer->getPosition(idx[i+2]));
p.Normal.X = fabsf(p.Normal.X);
p.Normal.Y = fabsf(p.Normal.Y);
p.Normal.Z = fabsf(p.Normal.Z);
// calculate planar mapping worldspace coordinates
if (p.Normal.X > p.Normal.Y && p.Normal.X > p.Normal.Z)
{
u32 i;
for ( i = 0; i!= vtxCnt; ++i )
for (u32 o=0; o!=3; ++o)
{
if (recalculateNormals)
v[i].Normal.set( 0.f, 0.f, 0.f );
v[i].Tangent.set( 0.f, 0.f, 0.f );
v[i].Binormal.set( 0.f, 0.f, 0.f );
buffer->getTCoords(idx[i+o]).X = buffer->getPosition(idx[i+o]).Y * resolution;
buffer->getTCoords(idx[i+o]).Y = buffer->getPosition(idx[i+o]).Z * resolution;
}
//Each vertex gets the sum of the tangents and binormals from the faces around it
for ( i=0; i<idxCnt; i+=3)
}
else
if (p.Normal.Y > p.Normal.X && p.Normal.Y > p.Normal.Z)
{
for (u32 o=0; o!=3; ++o)
{
// if this triangle is degenerate, skip it!
if (v[idx[i+0]].Pos == v[idx[i+1]].Pos ||
v[idx[i+0]].Pos == v[idx[i+2]].Pos ||
v[idx[i+1]].Pos == v[idx[i+2]].Pos
/*||
v[idx[i+0]].TCoords == v[idx[i+1]].TCoords ||
v[idx[i+0]].TCoords == v[idx[i+2]].TCoords ||
v[idx[i+1]].TCoords == v[idx[i+2]].TCoords */
)
continue;
//Angle-weighted normals look better, but are slightly more CPU intensive to calculate
core::vector3df weight(1.f,1.f,1.f);
if (angleWeighted)
weight = getAngleWeight(v[i+0].Pos,v[i+1].Pos,v[i+2].Pos);
core::vector3df localNormal;
core::vector3df localTangent;
core::vector3df localBinormal;
calculateTangents(
localNormal,
localTangent,
localBinormal,
v[idx[i+0]].Pos,
v[idx[i+1]].Pos,
v[idx[i+2]].Pos,
v[idx[i+0]].TCoords,
v[idx[i+1]].TCoords,
v[idx[i+2]].TCoords);
if (recalculateNormals)
v[idx[i+0]].Normal += localNormal * weight.X;
v[idx[i+0]].Tangent += localTangent * weight.X;
v[idx[i+0]].Binormal += localBinormal * weight.X;
calculateTangents(
localNormal,
localTangent,
localBinormal,
v[idx[i+1]].Pos,
v[idx[i+2]].Pos,
v[idx[i+0]].Pos,
v[idx[i+1]].TCoords,
v[idx[i+2]].TCoords,
v[idx[i+0]].TCoords);
if (recalculateNormals)
v[idx[i+1]].Normal += localNormal * weight.Y;
v[idx[i+1]].Tangent += localTangent * weight.Y;
v[idx[i+1]].Binormal += localBinormal * weight.Y;
calculateTangents(
localNormal,
localTangent,
localBinormal,
v[idx[i+2]].Pos,
v[idx[i+0]].Pos,
v[idx[i+1]].Pos,
v[idx[i+2]].TCoords,
v[idx[i+0]].TCoords,
v[idx[i+1]].TCoords);
if (recalculateNormals)
v[idx[i+2]].Normal += localNormal * weight.Z;
v[idx[i+2]].Tangent += localTangent * weight.Z;
v[idx[i+2]].Binormal += localBinormal * weight.Z;
}
// Normalize the tangents and binormals
if (recalculateNormals)
{
for ( i = 0; i!= vtxCnt; ++i )
v[i].Normal.normalize();
}
for ( i = 0; i!= vtxCnt; ++i )
{
v[i].Tangent.normalize();
v[i].Binormal.normalize();
buffer->getTCoords(idx[i+o]).X = buffer->getPosition(idx[i+o]).X * resolution;
buffer->getTCoords(idx[i+o]).Y = buffer->getPosition(idx[i+o]).Z * resolution;
}
}
else
{
core::vector3df localNormal;
for (u32 i=0; i<idxCnt; i+=3)
for (u32 o=0; o!=3; ++o)
{
calculateTangents(
localNormal,
v[idx[i+0]].Tangent,
v[idx[i+0]].Binormal,
v[idx[i+0]].Pos,
v[idx[i+1]].Pos,
v[idx[i+2]].Pos,
v[idx[i+0]].TCoords,
v[idx[i+1]].TCoords,
v[idx[i+2]].TCoords);
if (recalculateNormals)
v[idx[i+0]].Normal=localNormal;
calculateTangents(
localNormal,
v[idx[i+1]].Tangent,
v[idx[i+1]].Binormal,
v[idx[i+1]].Pos,
v[idx[i+2]].Pos,
v[idx[i+0]].Pos,
v[idx[i+1]].TCoords,
v[idx[i+2]].TCoords,
v[idx[i+0]].TCoords);
if (recalculateNormals)
v[idx[i+1]].Normal=localNormal;
calculateTangents(
localNormal,
v[idx[i+2]].Tangent,
v[idx[i+2]].Binormal,
v[idx[i+2]].Pos,
v[idx[i+0]].Pos,
v[idx[i+1]].Pos,
v[idx[i+2]].TCoords,
v[idx[i+0]].TCoords,
v[idx[i+1]].TCoords);
if (recalculateNormals)
v[idx[i+2]].Normal=localNormal;
buffer->getTCoords(idx[i+o]).X = buffer->getPosition(idx[i+o]).X * resolution;
buffer->getTCoords(idx[i+o]).Y = buffer->getPosition(idx[i+o]).Y * resolution;
}
}
}
}
}
//! Creates a planar texture mapping on the meshbuffer
void CMeshManipulator::makePlanarTextureMapping(scene::IMeshBuffer* buffer, f32 resolution) const
{
if (!buffer)
return;
if (buffer->getIndexType()==video::EIT_16BIT)
makePlanarTextureMappingT<u16>(buffer, resolution);
else
makePlanarTextureMappingT<u32>(buffer, resolution);
}
//! Creates a planar texture mapping on the mesh
void CMeshManipulator::makePlanarTextureMapping(scene::IMesh* mesh, f32 resolution) const
{
if (!mesh)
return;
const u32 bcount = mesh->getMeshBufferCount();
for ( u32 b=0; b<bcount; ++b)
{
makePlanarTextureMapping(mesh->getMeshBuffer(b), resolution);
}
}
namespace
{
//! Creates a planar texture mapping on the meshbuffer
template <typename T>
void makePlanarTextureMappingT(scene::IMeshBuffer* buffer, f32 resolutionS, f32 resolutionT, u8 axis, const core::vector3df& offset)
{
u32 idxcnt = buffer->getIndexCount();
T* idx = reinterpret_cast<T*>(buffer->getIndices());
for (u32 i=0; i<idxcnt; i+=3)
{
// calculate planar mapping worldspace coordinates
if (axis==0)
{
for (u32 o=0; o!=3; ++o)
{
buffer->getTCoords(idx[i+o]).X = 0.5f+(buffer->getPosition(idx[i+o]).Z + offset.Z) * resolutionS;
buffer->getTCoords(idx[i+o]).Y = 0.5f-(buffer->getPosition(idx[i+o]).Y + offset.Y) * resolutionT;
}
}
else if (axis==1)
{
for (u32 o=0; o!=3; ++o)
{
buffer->getTCoords(idx[i+o]).X = 0.5f+(buffer->getPosition(idx[i+o]).X + offset.X) * resolutionS;
buffer->getTCoords(idx[i+o]).Y = 1.f-(buffer->getPosition(idx[i+o]).Z + offset.Z) * resolutionT;
}
}
else if (axis==2)
{
for (u32 o=0; o!=3; ++o)
{
buffer->getTCoords(idx[i+o]).X = 0.5f+(buffer->getPosition(idx[i+o]).X + offset.X) * resolutionS;
buffer->getTCoords(idx[i+o]).Y = 0.5f-(buffer->getPosition(idx[i+o]).Y + offset.Y) * resolutionT;
}
}
}
}
}
//! Creates a planar texture mapping on the meshbuffer
void CMeshManipulator::makePlanarTextureMapping(scene::IMeshBuffer* buffer, f32 resolutionS, f32 resolutionT, u8 axis, const core::vector3df& offset) const
{
if (!buffer)
return;
if (buffer->getIndexType()==video::EIT_16BIT)
makePlanarTextureMappingT<u16>(buffer, resolutionS, resolutionT, axis, offset);
else
makePlanarTextureMappingT<u32>(buffer, resolutionS, resolutionT, axis, offset);
}
//! Creates a planar texture mapping on the mesh
void CMeshManipulator::makePlanarTextureMapping(scene::IMesh* mesh, f32 resolutionS, f32 resolutionT, u8 axis, const core::vector3df& offset) const
{
if (!mesh)
return;
const u32 bcount = mesh->getMeshBufferCount();
for ( u32 b=0; b<bcount; ++b)
{
makePlanarTextureMapping(mesh->getMeshBuffer(b), resolutionS, resolutionT, axis, offset);
}
}
//! Clones a static IMesh into a modifyable SMesh.
// not yet 32bit
SMesh* CMeshManipulator::createMeshCopy(scene::IMesh* mesh) const
{
if (!mesh)
@ -365,101 +654,8 @@ SMesh* CMeshManipulator::createMeshCopy(scene::IMesh* mesh) const
}
//! Creates a planar texture mapping on the mesh
void CMeshManipulator::makePlanarTextureMapping(scene::IMesh* mesh, f32 resolution=0.01f) const
{
if (!mesh)
return;
const u32 bcount = mesh->getMeshBufferCount();
for ( u32 b=0; b<bcount; ++b)
{
makePlanarTextureMapping(mesh->getMeshBuffer(b), resolution);
}
}
//! Creates a planar texture mapping on the meshbuffer
void CMeshManipulator::makePlanarTextureMapping(scene::IMeshBuffer* buffer, f32 resolution) const
{
u32 idxcnt = buffer->getIndexCount();
u16* idx = buffer->getIndices();
for (u32 i=0; i<idxcnt; i+=3)
{
core::plane3df p(buffer->getPosition(idx[i+0]), buffer->getPosition(idx[i+1]), buffer->getPosition(idx[i+2]));
p.Normal.X = fabsf(p.Normal.X);
p.Normal.Y = fabsf(p.Normal.Y);
p.Normal.Z = fabsf(p.Normal.Z);
// calculate planar mapping worldspace coordinates
if (p.Normal.X > p.Normal.Y && p.Normal.X > p.Normal.Z)
{
for (u32 o=0; o!=3; ++o)
{
buffer->getTCoords(idx[i+o]).X = buffer->getPosition(idx[i+o]).Y * resolution;
buffer->getTCoords(idx[i+o]).Y = buffer->getPosition(idx[i+o]).Z * resolution;
}
}
else
if (p.Normal.Y > p.Normal.X && p.Normal.Y > p.Normal.Z)
{
for (u32 o=0; o!=3; ++o)
{
buffer->getTCoords(idx[i+o]).X = buffer->getPosition(idx[i+o]).X * resolution;
buffer->getTCoords(idx[i+o]).Y = buffer->getPosition(idx[i+o]).Z * resolution;
}
}
else
{
for (u32 o=0; o!=3; ++o)
{
buffer->getTCoords(idx[i+o]).X = buffer->getPosition(idx[i+o]).X * resolution;
buffer->getTCoords(idx[i+o]).Y = buffer->getPosition(idx[i+o]).Y * resolution;
}
}
}
}
//! Creates a planar texture mapping on the meshbuffer
void CMeshManipulator::makePlanarTextureMapping(scene::IMeshBuffer* buffer, f32 resolutionS, f32 resolutionT, u8 axis, const core::vector3df& offset) const
{
u32 idxcnt = buffer->getIndexCount();
u16* idx = buffer->getIndices();
for (u32 i=0; i<idxcnt; i+=3)
{
// calculate planar mapping worldspace coordinates
if (axis==0)
{
for (u32 o=0; o!=3; ++o)
{
buffer->getTCoords(idx[i+o]).X = 0.5f+(buffer->getPosition(idx[i+o]).Z + offset.Z) * resolutionS;
buffer->getTCoords(idx[i+o]).Y = 0.5f-(buffer->getPosition(idx[i+o]).Y + offset.Y) * resolutionT;
}
}
else if (axis==1)
{
for (u32 o=0; o!=3; ++o)
{
buffer->getTCoords(idx[i+o]).X = 0.5f+(buffer->getPosition(idx[i+o]).X + offset.X) * resolutionS;
buffer->getTCoords(idx[i+o]).Y = 1.f-(buffer->getPosition(idx[i+o]).Z + offset.Z) * resolutionT;
}
}
else if (axis==2)
{
for (u32 o=0; o!=3; ++o)
{
buffer->getTCoords(idx[i+o]).X = 0.5f+(buffer->getPosition(idx[i+o]).X + offset.X) * resolutionS;
buffer->getTCoords(idx[i+o]).Y = 0.5f-(buffer->getPosition(idx[i+o]).Y + offset.Y) * resolutionT;
}
}
}
}
//! Creates a copy of the mesh, which will only consist of unique primitives
// not yet 32bit
IMesh* CMeshManipulator::createMeshUniquePrimitives(IMesh* mesh) const
{
if (!mesh)
@ -562,7 +758,9 @@ IMesh* CMeshManipulator::createMeshUniquePrimitives(IMesh* mesh) const
return clone;
}
//! Creates a copy of a mesh, which will have identical vertices welded together
// not yet 32bit
IMesh* CMeshManipulator::createMeshWelded(IMesh *mesh, f32 tolerance) const
{
SMesh* clone = new SMesh();
@ -731,6 +929,7 @@ IMesh* CMeshManipulator::createMeshWelded(IMesh *mesh, f32 tolerance) const
//! Creates a copy of the mesh, which will only consist of S3DVertexTangents vertices.
// not yet 32bit
IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool recalculateNormals, bool smooth, bool angleWeighted, bool calculateTangents) const
{
if (!mesh)
@ -751,7 +950,7 @@ IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool recalculateNor
buffer->Material = original->getMaterial();
buffer->Vertices.reallocate(idxCnt);
buffer->Indices.set_used(idxCnt);
buffer->Indices.reallocate(idxCnt);
core::map<video::S3DVertexTangents, int> vertMap;
int vertLocation;
@ -801,7 +1000,7 @@ IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool recalculateNor
}
// create new indices
buffer->Indices[i] = vertLocation;
buffer->Indices.push_back(vertLocation);
}
buffer->recalculateBoundingBox();
@ -819,6 +1018,7 @@ IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool recalculateNor
//! Creates a copy of the mesh, which will only consist of S3DVertex2TCoords vertices.
// not yet 32bit
IMesh* CMeshManipulator::createMeshWith2TCoords(IMesh* mesh) const
{
if (!mesh)
@ -838,7 +1038,7 @@ IMesh* CMeshManipulator::createMeshWith2TCoords(IMesh* mesh) const
SMeshBufferLightMap* buffer = new SMeshBufferLightMap();
buffer->Material = original->getMaterial();
buffer->Vertices.reallocate(idxCnt);
buffer->Indices.set_used(idxCnt);
buffer->Indices.reallocate(idxCnt);
core::map<video::S3DVertex2TCoords, int> vertMap;
int vertLocation;
@ -888,7 +1088,7 @@ IMesh* CMeshManipulator::createMeshWith2TCoords(IMesh* mesh) const
}
// create new indices
buffer->Indices[i] = vertLocation;
buffer->Indices.push_back(vertLocation);
}
buffer->recalculateBoundingBox();
@ -901,7 +1101,9 @@ IMesh* CMeshManipulator::createMeshWith2TCoords(IMesh* mesh) const
return clone;
}
//! Creates a copy of the mesh, which will only consist of S3DVertex vertices.
// not yet 32bit
IMesh* CMeshManipulator::createMeshWith1TCoords(IMesh* mesh) const
{
if (!mesh)
@ -913,14 +1115,14 @@ IMesh* CMeshManipulator::createMeshWith1TCoords(IMesh* mesh) const
for (u32 b=0; b<meshBufferCount; ++b)
{
const IMeshBuffer* const original = mesh->getMeshBuffer(b);
IMeshBuffer* original = mesh->getMeshBuffer(b);
const u32 idxCnt = original->getIndexCount();
const u16* idx = original->getIndices();
SMeshBuffer* buffer = new SMeshBuffer();
buffer->Material = original->getMaterial();
buffer->Vertices.reallocate(idxCnt);
buffer->Indices.set_used(idxCnt);
buffer->Indices.reallocate(idxCnt);
core::map<video::S3DVertex, int> vertMap;
int vertLocation;
@ -969,10 +1171,9 @@ IMesh* CMeshManipulator::createMeshWith1TCoords(IMesh* mesh) const
}
// create new indices
buffer->Indices[i] = vertLocation;
buffer->Indices.push_back(vertLocation);
}
buffer->recalculateBoundingBox();
// add new buffer
clone->addMeshBuffer(buffer);
buffer->drop();
@ -983,103 +1184,6 @@ IMesh* CMeshManipulator::createMeshWith1TCoords(IMesh* mesh) const
}
void CMeshManipulator::calculateTangents(
core::vector3df& normal,
core::vector3df& tangent,
core::vector3df& binormal,
const core::vector3df& vt1, const core::vector3df& vt2, const core::vector3df& vt3, // vertices
const core::vector2df& tc1, const core::vector2df& tc2, const core::vector2df& tc3) // texture coords
{
// choose one of them:
//#define USE_NVIDIA_GLH_VERSION // use version used by nvidia in glh headers
#define USE_IRR_VERSION
#ifdef USE_IRR_VERSION
core::vector3df v1 = vt1 - vt2;
core::vector3df v2 = vt3 - vt1;
normal = v2.crossProduct(v1);
normal.normalize();
// binormal
f32 deltaX1 = tc1.X - tc2.X;
f32 deltaX2 = tc3.X - tc1.X;
binormal = (v1 * deltaX2) - (v2 * deltaX1);
binormal.normalize();
// tangent
f32 deltaY1 = tc1.Y - tc2.Y;
f32 deltaY2 = tc3.Y - tc1.Y;
tangent = (v1 * deltaY2) - (v2 * deltaY1);
tangent.normalize();
// adjust
core::vector3df txb = tangent.crossProduct(binormal);
if (txb.dotProduct(normal) < 0.0f)
{
tangent *= -1.0f;
binormal *= -1.0f;
}
#endif // USE_IRR_VERSION
#ifdef USE_NVIDIA_GLH_VERSION
tangent.set(0,0,0);
binormal.set(0,0,0);
core::vector3df v1(vt2.X - vt1.X, tc2.X - tc1.X, tc2.Y - tc1.Y);
core::vector3df v2(vt3.X - vt1.X, tc3.X - tc1.X, tc3.Y - tc1.Y);
core::vector3df txb = v1.crossProduct(v2);
if ( !core::iszero ( txb.X ) )
{
tangent.X = -txb.Y / txb.X;
binormal.X = -txb.Z / txb.X;
}
v1.X = vt2.Y - vt1.Y;
v2.X = vt3.Y - vt1.Y;
txb = v1.crossProduct(v2);
if ( !core::iszero ( txb.X ) )
{
tangent.Y = -txb.Y / txb.X;
binormal.Y = -txb.Z / txb.X;
}
v1.X = vt2.Z - vt1.Z;
v2.X = vt3.Z - vt1.Z;
txb = v1.crossProduct(v2);
if ( !core::iszero ( txb.X ) )
{
tangent.Z = -txb.Y / txb.X;
binormal.Z = -txb.Z / txb.X;
}
tangent.normalize();
binormal.normalize();
normal = tangent.crossProduct(binormal);
normal.normalize();
binormal = tangent.crossProduct(normal);
binormal.normalize();
core::plane3d<f32> pl(vt1, vt2, vt3);
if(normal.dotProduct(pl.Normal) < 0.0f )
normal *= -1.0f;
#endif // USE_NVIDIA_GLH_VERSION
}
//! Returns amount of polygons in mesh.
s32 CMeshManipulator::getPolyCount(scene::IMesh* mesh) const
{

View File

@ -43,7 +43,7 @@ public:
\param resolution: resolution of the planar mapping. This is the value
specifying which is the relation between world space and
texture coordinate space. */
virtual void makePlanarTextureMapping(scene::IMesh* mesh, f32 resolution) const;
virtual void makePlanarTextureMapping(scene::IMesh* mesh, f32 resolution=0.001f) const;
//! Creates a planar texture mapping on the meshbuffer
virtual void makePlanarTextureMapping(scene::IMeshBuffer* meshbuffer, f32 resolution=0.001f) const;
@ -51,6 +51,12 @@ public:
//! Creates a planar texture mapping on the meshbuffer
void makePlanarTextureMapping(scene::IMeshBuffer* buffer, f32 resolutionS, f32 resolutionT, u8 axis, const core::vector3df& offset) const;
//! Creates a planar texture mapping on the mesh
void makePlanarTextureMapping(scene::IMesh* mesh, f32 resolutionS, f32 resolutionT, u8 axis, const core::vector3df& offset) const;
//! Recalculates tangents, requires a tangent mesh buffer
virtual void recalculateTangents(IMeshBuffer* buffer, bool recalculateNormals=false, bool smooth=false, bool angleWeighted=false) const;
//! Recalculates tangents, requires a tangent mesh
virtual void recalculateTangents(IMesh* mesh, bool recalculateNormals=false, bool smooth=false, bool angleWeighted=false) const;
@ -77,14 +83,6 @@ public:
//! create a new AnimatedMesh and adds the mesh to it
virtual IAnimatedMesh * createAnimatedMesh(scene::IMesh* mesh,scene::E_ANIMATED_MESH_TYPE type) const;
private:
static void calculateTangents(core::vector3df& normal,
core::vector3df& tangent,
core::vector3df& binormal,
const core::vector3df& vt1, const core::vector3df& vt2, const core::vector3df& vt3,
const core::vector2df& tc1, const core::vector2df& tc2, const core::vector2df& tc3);
};
} // end namespace scene

View File

@ -2306,7 +2306,7 @@ scene::IMeshManipulator* CNullDriver::getMeshManipulator()
//! Returns an image created from the last rendered frame.
IImage* CNullDriver::createScreenShot()
IImage* CNullDriver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target)
{
return 0;
}

View File

@ -580,7 +580,7 @@ namespace video
virtual void clearZBuffer();
//! Returns an image created from the last rendered frame.
virtual IImage* createScreenShot();
virtual IImage* createScreenShot(video::ECOLOR_FORMAT format=video::ECF_UNKNOWN, video::E_RENDER_TARGET target=video::ERT_FRAME_BUFFER);
//! Writes the provided image to disk file
virtual bool writeImageToFile(IImage* image, const io::path& filename, u32 param = 0);

View File

@ -19,7 +19,6 @@
#include "SAnimatedMesh.h"
#include "SMeshBufferLightMap.h"
#include "irrString.h"
#include "CImage.h"
#include "ISceneManager.h"
namespace irr
@ -224,7 +223,7 @@ IAnimatedMesh* COCTLoader::createMesh(io::IReadFile* file)
bool oldMipMapState = SceneManager->getVideoDriver()->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
video::CImage tmpImage(video::ECF_R8G8B8, lmapsize);
video::IImage* tmpImage = SceneManager->getVideoDriver()->createImage(video::ECF_R8G8B8, lmapsize);
for (i = 1; i < (header.numLightmaps + 1); ++i)
{
core::stringc lightmapname = file->getFileName();
@ -237,7 +236,7 @@ IAnimatedMesh* COCTLoader::createMesh(io::IReadFile* file)
{
for (u32 y=0; y<lightmapHeight; ++y)
{
tmpImage.setPixel(x, y,
tmpImage->setPixel(x, y,
video::SColor(255,
lm->data[x][y][2],
lm->data[x][y][1],
@ -245,8 +244,9 @@ IAnimatedMesh* COCTLoader::createMesh(io::IReadFile* file)
}
}
lig[i] = SceneManager->getVideoDriver()->addTexture(lightmapname.c_str(), &tmpImage);
lig[i] = SceneManager->getVideoDriver()->addTexture(lightmapname.c_str(), tmpImage);
}
tmpImage->drop();
SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState);
// Free stuff

View File

@ -29,14 +29,14 @@ namespace irr
#if defined(_IRR_COMPILE_WITH_X11_DEVICE_)
// constructor linux
COSOperator::COSOperator(const c8* osversion, CIrrDeviceLinux* device)
: IrrDeviceLinux(device)
COSOperator::COSOperator(const core::stringc& osVersion, CIrrDeviceLinux* device)
: OperatingSystem(osVersion), IrrDeviceLinux(device)
{
}
#endif
// constructor
COSOperator::COSOperator(const c8* osVersion) : OperatingSystem(osVersion)
COSOperator::COSOperator(const core::stringc& osVersion) : OperatingSystem(osVersion)
{
#ifdef _DEBUG
setDebugName("COSOperator");
@ -45,9 +45,9 @@ COSOperator::COSOperator(const c8* osVersion) : OperatingSystem(osVersion)
//! returns the current operating system version as string.
const wchar_t* COSOperator::getOperationSystemVersion() const
const core::stringc& COSOperator::getOperatingSystemVersion() const
{
return OperatingSystem.c_str();
return OperatingSystem;
}

View File

@ -6,8 +6,6 @@
#define __C_OS_OPERATOR_H_INCLUDED__
#include "IOSOperator.h"
#include "irrString.h"
#include "IrrCompileConfig.h"
namespace irr
{
@ -21,12 +19,12 @@ public:
// constructor
#if defined(_IRR_COMPILE_WITH_X11_DEVICE_)
COSOperator(const c8* osversion, CIrrDeviceLinux* device);
COSOperator(const core::stringc& osversion, CIrrDeviceLinux* device);
#endif
COSOperator(const c8* osversion);
COSOperator(const core::stringc& osversion);
//! returns the current operation system version as string.
virtual const wchar_t* getOperationSystemVersion() const;
virtual const core::stringc& getOperatingSystemVersion() const;
//! copies text to the clipboard
virtual void copyToClipboard(const c8* text) const;
@ -48,7 +46,7 @@ public:
private:
core::stringw OperatingSystem;
core::stringc OperatingSystem;
#if defined(_IRR_COMPILE_WITH_X11_DEVICE_)
CIrrDeviceLinux * IrrDeviceLinux;

View File

@ -14,7 +14,6 @@
#include "COpenGLSLMaterialRenderer.h"
#include "COpenGLNormalMapRenderer.h"
#include "COpenGLParallaxMapRenderer.h"
#include "CImage.h"
#include "os.h"
#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_
@ -37,8 +36,7 @@ COpenGLDriver::COpenGLDriver(const irr::SIrrlichtCreationParameters& params,
CurrentRenderMode(ERM_NONE), ResetRenderStates(true), Transformation3DChanged(true),
AntiAlias(params.AntiAlias), RenderTargetTexture(0),
CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8),
CurrentTarget(ERT_FRAME_BUFFER),
Doublebuffer(params.Doublebuffer), Stereo(params.Stereobuffer),
CurrentTarget(ERT_FRAME_BUFFER), Params(params),
HDc(0), Window(static_cast<HWND>(params.WindowId)), Win32Device(device),
DeviceType(EIDT_WIN32)
{
@ -79,7 +77,7 @@ bool COpenGLDriver::changeRenderContext(const SExposedVideoData& videoData, CIrr
}
//! inits the open gl driver
bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDeviceWin32* device)
bool COpenGLDriver::initDriver(CIrrDeviceWin32* device)
{
// Create a window to test antialiasing support
const fschar_t* ClassName = __TEXT("GLCIrrDeviceWin32");
@ -105,11 +103,11 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
RECT clientSize;
clientSize.top = 0;
clientSize.left = 0;
clientSize.right = params.WindowSize.Width;
clientSize.bottom = params.WindowSize.Height;
clientSize.right = Params.WindowSize.Width;
clientSize.bottom = Params.WindowSize.Height;
DWORD style = WS_POPUP;
if (!params.Fullscreen)
if (!Params.Fullscreen)
style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
AdjustWindowRect(&clientSize, style, FALSE);
@ -138,17 +136,17 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
(params.Doublebuffer?PFD_DOUBLEBUFFER:0) | // Must Support Double Buffering
(params.Stereobuffer?PFD_STEREO:0), // Must Support Stereo Buffer
(Params.Doublebuffer?PFD_DOUBLEBUFFER:0) | // Must Support Double Buffering
(Params.Stereobuffer?PFD_STEREO:0), // Must Support Stereo Buffer
PFD_TYPE_RGBA, // Request An RGBA Format
params.Bits, // Select Our Color Depth
Params.Bits, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
0, // No Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
params.ZBufferBits, // Z-Buffer (Depth Buffer)
params.Stencilbuffer ? 1 : 0, // Stencil Buffer Depth
Params.ZBufferBits, // Z-Buffer (Depth Buffer)
Params.Stencilbuffer ? 1 : 0, // Stencil Buffer Depth
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
@ -161,10 +159,10 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
{
if (i == 1)
{
if (params.Stencilbuffer)
if (Params.Stencilbuffer)
{
os::Printer::log("Cannot create a GL device with stencil buffer, disabling stencil shadows.", ELL_WARNING);
params.Stencilbuffer = false;
Params.Stencilbuffer = false;
pfd.cStencilBits = 0;
}
else
@ -177,7 +175,7 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
}
if (i == 3)
{
if (params.Bits!=16)
if (Params.Bits!=16)
pfd.cDepthBits = 16;
else
continue;
@ -186,7 +184,7 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
if (i == 4)
{
// try single buffer
if (params.Doublebuffer)
if (Params.Doublebuffer)
pfd.dwFlags &= ~PFD_DOUBLEBUFFER;
else
continue;
@ -268,15 +266,15 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
f32 fAttributes[] = {0.0, 0.0};
s32 iAttributes[] =
{
WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
WGL_DRAW_TO_WINDOW_ARB,1,
WGL_SUPPORT_OPENGL_ARB,1,
WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
WGL_COLOR_BITS_ARB,(params.Bits==32) ? 24 : 15,
WGL_ALPHA_BITS_ARB,(params.Bits==32) ? 8 : 1,
WGL_DEPTH_BITS_ARB,params.ZBufferBits, // 10,11
WGL_STENCIL_BITS_ARB,(params.Stencilbuffer) ? 1 : 0,
WGL_DOUBLE_BUFFER_ARB,(params.Doublebuffer) ? GL_TRUE : GL_FALSE,
WGL_STEREO_ARB,(params.Stereobuffer) ? GL_TRUE : GL_FALSE,
WGL_COLOR_BITS_ARB,(Params.Bits==32) ? 24 : 15,
WGL_ALPHA_BITS_ARB,(Params.Bits==32) ? 8 : 1,
WGL_DEPTH_BITS_ARB,Params.ZBufferBits, // 10,11
WGL_STENCIL_BITS_ARB,Params.Stencilbuffer ? 1 : 0,
WGL_DOUBLE_BUFFER_ARB,Params.Doublebuffer ? 1 : 0,
WGL_STEREO_ARB,Params.Stereobuffer ? 1 : 0,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
#ifdef WGL_ARB_multisample
WGL_SAMPLES_ARB,AntiAlias, // 20,21
@ -288,21 +286,26 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
WGL_SAMPLES_3DFX,AntiAlias, // 20,21
WGL_SAMPLE_BUFFERS_3DFX, 1,
#endif
#if 0
#ifdef WGL_ARB_framebuffer_sRGB
WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB, GL_TRUE,
WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB, Params.HandleSRGB ? 1:0,
#elif defined(WGL_EXT_framebuffer_sRGB)
WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT, GL_TRUE,
WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT, Params.HandleSRGB ? 1:0,
#endif
#endif
0,0
// WGL_DEPTH_FLOAT_EXT, 1,
0,0,0,0
};
int iAttrSize = sizeof(iAttributes)/sizeof(int);
const bool framebuffer_srgb_supported = ((wglExtensions.find("WGL_ARB_framebuffer_sRGB") != -1) ||
(wglExtensions.find("WGL_EXT_framebuffer_sRGB") != -1));
if (!framebuffer_srgb_supported)
{
memmove(&iAttributes[24],&iAttributes[26],sizeof(int)*(iAttrSize-26));
iAttrSize -= 2;
}
if (!multi_sample_supported)
{
iAttributes[20]=0;
iAttributes[21]=0;
iAttributes[22]=0;
iAttributes[23]=0;
memmove(&iAttributes[20],&iAttributes[24],sizeof(int)*(iAttrSize-24));
iAttrSize -= 4;
}
s32 rv=0;
@ -313,7 +316,7 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
UINT numFormats=0;
const BOOL valid = wglChoosePixelFormat_ARB(HDc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
if (valid && numFormats>0)
if (valid && numFormats)
rv = pixelFormat;
else
iAttributes[21] -= 1;
@ -350,10 +353,10 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
{
if (i == 1)
{
if (params.Stencilbuffer)
if (Params.Stencilbuffer)
{
os::Printer::log("Cannot create a GL device with stencil buffer, disabling stencil shadows.", ELL_WARNING);
params.Stencilbuffer = false;
Params.Stencilbuffer = false;
pfd.cStencilBits = 0;
}
else
@ -366,7 +369,7 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
}
if (i == 3)
{
if (params.Bits!=16)
if (Params.Bits!=16)
pfd.cDepthBits = 16;
else
continue;
@ -391,6 +394,7 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
os::Printer::log("Cannot set the pixel format.", ELL_ERROR);
return false;
}
os::Printer::log("Pixel Format", core::stringc(PixelFormat).c_str(), ELL_DEBUG);
// create rendering context
#ifdef WGL_ARB_create_context
@ -446,9 +450,9 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
ColorFormat = ECF_R5G6B5;
}
genericDriverInit(params.WindowSize, params.Stencilbuffer);
genericDriverInit();
extGlSwapInterval(params.Vsync ? 1 : 0);
extGlSwapInterval(Params.Vsync ? 1 : 0);
return true;
}
@ -465,14 +469,13 @@ COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params,
CurrentRenderMode(ERM_NONE), ResetRenderStates(true), Transformation3DChanged(true),
AntiAlias(params.AntiAlias), RenderTargetTexture(0),
CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8),
CurrentTarget(ERT_FRAME_BUFFER),
Doublebuffer(params.Doublebuffer), Stereo(params.Stereobuffer),
CurrentTarget(ERT_FRAME_BUFFER), Params(params),
OSXDevice(device), DeviceType(EIDT_OSX)
{
#ifdef _DEBUG
setDebugName("COpenGLDriver");
#endif
genericDriverInit(params.WindowSize, params.Stencilbuffer);
genericDriverInit();
}
#endif
@ -488,8 +491,7 @@ COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params,
CurrentRenderMode(ERM_NONE), ResetRenderStates(true),
Transformation3DChanged(true), AntiAlias(params.AntiAlias),
RenderTargetTexture(0), CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8),
CurrentTarget(ERT_FRAME_BUFFER),
Doublebuffer(params.Doublebuffer), Stereo(params.Stereobuffer),
CurrentTarget(ERT_FRAME_BUFFER), Params(params),
X11Device(device), DeviceType(EIDT_X11)
{
#ifdef _DEBUG
@ -532,18 +534,18 @@ bool COpenGLDriver::changeRenderContext(const SExposedVideoData& videoData, CIrr
//! inits the open gl driver
bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDeviceLinux* device)
bool COpenGLDriver::initDriver(CIrrDeviceLinux* device)
{
ExposedData.OpenGLLinux.X11Context = glXGetCurrentContext();
ExposedData.OpenGLLinux.X11Display = glXGetCurrentDisplay();
ExposedData.OpenGLLinux.X11Window = (unsigned long)params.WindowId;
ExposedData.OpenGLLinux.X11Window = (unsigned long)Params.WindowId;
Drawable = glXGetCurrentDrawable();
X11Display = (Display*)ExposedData.OpenGLLinux.X11Display;
genericDriverInit(params.WindowSize, params.Stencilbuffer);
genericDriverInit();
// set vsync
extGlSwapInterval(params.Vsync ? 1 : 0);
extGlSwapInterval(Params.Vsync ? 1 : 0);
return true;
}
@ -561,15 +563,14 @@ COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params,
CurrentRenderMode(ERM_NONE), ResetRenderStates(true),
Transformation3DChanged(true), AntiAlias(params.AntiAlias),
RenderTargetTexture(0), CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8),
CurrentTarget(ERT_FRAME_BUFFER),
Doublebuffer(params.Doublebuffer), Stereo(params.Stereobuffer),
CurrentTarget(ERT_FRAME_BUFFER), Params(params),
SDLDevice(device), DeviceType(EIDT_SDL)
{
#ifdef _DEBUG
setDebugName("COpenGLDriver");
#endif
genericDriverInit(params.WindowSize, params.Stencilbuffer);
genericDriverInit();
}
#endif // _IRR_COMPILE_WITH_SDL_DEVICE_
@ -612,7 +613,7 @@ COpenGLDriver::~COpenGLDriver()
// METHODS
// -----------------------------------------------------------------------
bool COpenGLDriver::genericDriverInit(const core::dimension2d<u32>& screenSize, bool stencilBuffer)
bool COpenGLDriver::genericDriverInit()
{
Name=L"OpenGL ";
Name.append(glGetString(GL_VERSION));
@ -634,7 +635,7 @@ bool COpenGLDriver::genericDriverInit(const core::dimension2d<u32>& screenSize,
for (i=0; i<MATERIAL_MAX_TEXTURES; ++i)
CurrentTexture[i]=0;
// load extensions
initExtensions(stencilBuffer);
initExtensions(Params.Stencilbuffer);
if (queryFeature(EVDF_ARB_GLSL))
{
char buf[32];
@ -646,7 +647,7 @@ bool COpenGLDriver::genericDriverInit(const core::dimension2d<u32>& screenSize,
os::Printer::log("GLSL not available.", ELL_INFORMATION);
DriverAttributes->setAttribute("MaxTextures", MaxTextureUnits);
DriverAttributes->setAttribute("MaxSupportedTextures", MaxSupportedTextures);
// DriverAttributes->setAttribute("MaxLights", MaxLights);
DriverAttributes->setAttribute("MaxLights", MaxLights);
DriverAttributes->setAttribute("MaxAnisotropy", MaxAnisotropy);
DriverAttributes->setAttribute("MaxUserClipPlanes", MaxUserClipPlanes);
DriverAttributes->setAttribute("MaxAuxBuffers", MaxAuxBuffers);
@ -662,7 +663,7 @@ bool COpenGLDriver::genericDriverInit(const core::dimension2d<u32>& screenSize,
glPixelStorei(GL_PACK_ALIGNMENT, 1);
// Reset The Current Viewport
glViewport(0, 0, screenSize.Width, screenSize.Height);
glViewport(0, 0, Params.WindowSize.Width, Params.WindowSize.Height);
UserClipPlanes.reallocate(MaxUserClipPlanes);
for (i=0; i<MaxUserClipPlanes; ++i)
@ -678,6 +679,16 @@ bool COpenGLDriver::genericDriverInit(const core::dimension2d<u32>& screenSize,
#endif
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
Params.HandleSRGB &= ((FeatureAvailable[IRR_ARB_framebuffer_sRGB] || FeatureAvailable[IRR_EXT_framebuffer_sRGB]) &&
FeatureAvailable[IRR_EXT_texture_sRGB]);
#if defined(GL_ARB_framebuffer_sRGB)
if (Params.HandleSRGB)
glEnable(GL_FRAMEBUFFER_SRGB);
#elif defined(GL_EXT_framebuffer_sRGB)
if (Params.HandleSRGB)
glEnable(GL_FRAMEBUFFER_SRGB_EXT);
#endif
// This is a fast replacement for NORMALIZE_NORMALS
// if ((Version>101) || FeatureAvailable[IRR_EXT_rescale_normal])
// glEnable(GL_RESCALE_NORMAL_EXT);
@ -2505,6 +2516,10 @@ void COpenGLDriver::setRenderStates3DMode()
glLoadMatrixf(Matrices[ETS_PROJECTION].pointer());
ResetRenderStates = true;
#ifdef GL_EXT_clip_volume_hint
if (FeatureAvailable[IRR_EXT_clip_volume_hint])
glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, GL_NICEST);
#endif
}
if (ResetRenderStates || LastMaterial != Material)
@ -2924,7 +2939,7 @@ void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMater
if (queryFeature(EVDF_BLEND_OPERATIONS) &&
(resetAllRenderStates|| lastmaterial.BlendOperation != material.BlendOperation))
{
if (EBO_NONE)
if (material.BlendOperation==EBO_NONE)
glDisable(GL_BLEND);
else
{
@ -3159,16 +3174,22 @@ void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaCh
LastMaterial = InitMaterial2D;
}
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#ifdef GL_EXT_clip_volume_hint
if (FeatureAvailable[IRR_EXT_clip_volume_hint])
glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, GL_FASTEST);
#endif
}
if (OverrideMaterial2DEnabled)
{
OverrideMaterial2D.Lighting=false;
OverrideMaterial2D.ZBuffer=ECFN_NEVER;
OverrideMaterial2D.ZWriteEnable=false;
setBasicRenderStates(OverrideMaterial2D, LastMaterial, false);
LastMaterial = OverrideMaterial2D;
}
// no alphaChannel without texture
alphaChannel &= texture;
if (alphaChannel || alpha)
{
glEnable(GL_BLEND);
@ -3509,7 +3530,7 @@ void COpenGLDriver::drawStencilShadowVolume(const core::vector3df* triangles, s3
glVertexPointer(3,GL_FLOAT,sizeof(core::vector3df),&triangles[0]);
glStencilMask(~0);
glStencilFunc(GL_ALWAYS, 0, ~0);
glPolygonOffset(1.f,1.f);
glPolygonOffset(-1.f,-1.f);
glEnable(GL_POLYGON_OFFSET_FILL);
GLenum incr = GL_INCR;
@ -3929,16 +3950,16 @@ bool COpenGLDriver::setRenderTarget(video::E_RENDER_TARGET target, bool clearTar
return false;
}
if (Stereo && (ERT_STEREO_RIGHT_BUFFER == target))
if (Params.Stereobuffer && (ERT_STEREO_RIGHT_BUFFER == target))
{
if (Doublebuffer)
if (Params.Doublebuffer)
glDrawBuffer(GL_BACK_RIGHT);
else
glDrawBuffer(GL_FRONT_RIGHT);
}
else if (Stereo && ERT_STEREO_BOTH_BUFFERS == target)
else if (Params.Stereobuffer && ERT_STEREO_BOTH_BUFFERS == target)
{
if (Doublebuffer)
if (Params.Doublebuffer)
glDrawBuffer(GL_BACK);
else
glDrawBuffer(GL_FRONT);
@ -3949,7 +3970,7 @@ bool COpenGLDriver::setRenderTarget(video::E_RENDER_TARGET target, bool clearTar
}
else
{
if (Doublebuffer)
if (Params.Doublebuffer)
glDrawBuffer(GL_BACK_LEFT);
else
glDrawBuffer(GL_FRONT_LEFT);
@ -4016,7 +4037,7 @@ bool COpenGLDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuff
RenderTargetTexture = 0;
CurrentRendertargetSize = core::dimension2d<u32>(0,0);
CurrentTarget=ERT_FRAME_BUFFER;
glDrawBuffer(Doublebuffer?GL_BACK_LEFT:GL_FRONT_LEFT);
glDrawBuffer(Params.Doublebuffer?GL_BACK_LEFT:GL_FRONT_LEFT);
}
// we need to update the matrices due to the rendersize change.
Transformation3DChanged=true;
@ -4240,16 +4261,10 @@ void COpenGLDriver::clearZBuffer()
//! Returns an image created from the last rendered frame.
IImage* COpenGLDriver::createScreenShot()
IImage* COpenGLDriver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target)
{
IImage* newImage = new CImage(ECF_R8G8B8, ScreenSize);
u8* pixels = static_cast<u8*>(newImage->lock());
if (!pixels)
{
newImage->drop();
if (target==video::ERT_MULTI_RENDER_TEXTURES || target==video::ERT_RENDER_TEXTURE || target==video::ERT_STEREO_BOTH_BUFFERS)
return 0;
}
// allows to read pixels in top-to-bottom order
#ifdef GL_MESA_pack_invert
@ -4257,16 +4272,133 @@ IImage* COpenGLDriver::createScreenShot()
glPixelStorei(GL_PACK_INVERT_MESA, GL_TRUE);
#endif
// We want to read the front buffer to get the latest render finished.
glReadBuffer(GL_FRONT);
glReadPixels(0, 0, ScreenSize.Width, ScreenSize.Height, GL_RGB, GL_UNSIGNED_BYTE, pixels);
glReadBuffer(GL_BACK);
if (format==video::ECF_UNKNOWN)
format=getColorFormat();
GLenum fmt;
GLenum type;
switch (format)
{
case ECF_A1R5G5B5:
fmt = GL_BGRA;
type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
break;
case ECF_R5G6B5:
fmt = GL_BGR;
type = GL_UNSIGNED_SHORT_5_6_5_REV;
break;
case ECF_R8G8B8:
fmt = GL_BGR;
type = GL_UNSIGNED_BYTE;
break;
case ECF_A8R8G8B8:
fmt = GL_BGRA;
if (Version > 101)
type = GL_UNSIGNED_INT_8_8_8_8_REV;
else
type = GL_UNSIGNED_BYTE;
break;
case ECF_R16F:
if (FeatureAvailable[IRR_ARB_texture_rg])
fmt = GL_RED;
else
fmt = GL_LUMINANCE;
#ifdef GL_ARB_half_float_pixel
if (FeatureAvailable[IRR_ARB_half_float_pixel])
type = GL_HALF_FLOAT_ARB;
else
#endif
{
type = GL_FLOAT;
format = ECF_R32F;
}
break;
case ECF_G16R16F:
#ifdef GL_ARB_texture_rg
if (FeatureAvailable[IRR_ARB_texture_rg])
fmt = GL_RG;
else
#endif
fmt = GL_LUMINANCE_ALPHA;
#ifdef GL_ARB_half_float_pixel
if (FeatureAvailable[IRR_ARB_half_float_pixel])
type = GL_HALF_FLOAT_ARB;
else
#endif
{
type = GL_FLOAT;
format = ECF_G32R32F;
}
break;
case ECF_A16B16G16R16F:
fmt = GL_BGRA;
#ifdef GL_ARB_half_float_pixel
if (FeatureAvailable[IRR_ARB_half_float_pixel])
type = GL_HALF_FLOAT_ARB;
else
#endif
{
type = GL_FLOAT;
format = ECF_A32B32G32R32F;
}
break;
case ECF_R32F:
if (FeatureAvailable[IRR_ARB_texture_rg])
fmt = GL_RED;
else
fmt = GL_LUMINANCE;
type = GL_FLOAT;
break;
case ECF_G32R32F:
#ifdef GL_ARB_texture_rg
if (FeatureAvailable[IRR_ARB_texture_rg])
fmt = GL_RG;
else
#endif
fmt = GL_LUMINANCE_ALPHA;
type = GL_FLOAT;
break;
case ECF_A32B32G32R32F:
fmt = GL_BGRA;
type = GL_FLOAT;
break;
default:
fmt = GL_BGRA;
type = GL_UNSIGNED_BYTE;
break;
}
IImage* newImage = createImage(format, ScreenSize);
u8* pixels = 0;
if (newImage)
pixels = static_cast<u8*>(newImage->lock());
if (pixels)
{
GLenum tgt=GL_FRONT;
switch (target)
{
case video::ERT_FRAME_BUFFER:
break;
case video::ERT_STEREO_LEFT_BUFFER:
tgt=GL_FRONT_LEFT;
break;
case video::ERT_STEREO_RIGHT_BUFFER:
tgt=GL_FRONT_RIGHT;
break;
default:
tgt=GL_AUX0+(target-video::ERT_AUX_BUFFER0);
break;
}
glReadBuffer(tgt);
glReadPixels(0, 0, ScreenSize.Width, ScreenSize.Height, fmt, type, pixels);
glReadBuffer(GL_BACK);
}
#ifdef GL_MESA_pack_invert
if (FeatureAvailable[IRR_MESA_pack_invert])
glPixelStorei(GL_PACK_INVERT_MESA, GL_FALSE);
else
#endif
if (pixels)
{
// opengl images are horizontally flipped, so we have to fix that here.
const s32 pitch=newImage->getPitch();
@ -4275,7 +4407,15 @@ IImage* COpenGLDriver::createScreenShot()
for (u32 i=0; i < ScreenSize.Height; i += 2)
{
memcpy(tmpBuffer, pixels, pitch);
// for (u32 j=0; j<pitch; ++j)
// {
// pixels[j]=(u8)(p2[j]*255.f);
// }
memcpy(pixels, p2, pitch);
// for (u32 j=0; j<pitch; ++j)
// {
// p2[j]=(u8)(tmpBuffer[j]*255.f);
// }
memcpy(p2, tmpBuffer, pitch);
pixels += pitch;
p2 -= pitch;
@ -4283,14 +4423,15 @@ IImage* COpenGLDriver::createScreenShot()
delete [] tmpBuffer;
}
newImage->unlock();
if (testGLError())
if (newImage)
{
newImage->drop();
return 0;
newImage->unlock();
if (testGLError() || !pixels)
{
newImage->drop();
return 0;
}
}
return newImage;
}
@ -4421,7 +4562,7 @@ GLenum COpenGLDriver::primitiveTypeToGL(scene::E_PRIMITIVE_TYPE type) const
}
GLenum COpenGLDriver::getGLBlend (E_BLEND_FACTOR factor) const
GLenum COpenGLDriver::getGLBlend(E_BLEND_FACTOR factor) const
{
GLenum r = 0;
switch (factor)
@ -4462,7 +4603,7 @@ IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params,
{
#ifdef _IRR_COMPILE_WITH_OPENGL_
COpenGLDriver* ogl = new COpenGLDriver(params, io, device);
if (!ogl->initDriver(params, device))
if (!ogl->initDriver(device))
{
ogl->drop();
ogl = 0;
@ -4498,7 +4639,7 @@ IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params,
{
#ifdef _IRR_COMPILE_WITH_OPENGL_
COpenGLDriver* ogl = new COpenGLDriver(params, io, device);
if (!ogl->initDriver(params, device))
if (!ogl->initDriver(device))
{
ogl->drop();
ogl = 0;

View File

@ -33,19 +33,20 @@ namespace video
class COpenGLDriver : public CNullDriver, public IMaterialRendererServices, public COpenGLExtensionHandler
{
friend class COpenGLTexture;
public:
#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_
COpenGLDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, CIrrDeviceWin32* device);
//! inits the windows specific parts of the open gl driver
bool initDriver(SIrrlichtCreationParameters params, CIrrDeviceWin32* device);
bool initDriver(CIrrDeviceWin32* device);
bool changeRenderContext(const SExposedVideoData& videoData, CIrrDeviceWin32* device);
#endif
#ifdef _IRR_COMPILE_WITH_X11_DEVICE_
COpenGLDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, CIrrDeviceLinux* device);
//! inits the GLX specific parts of the open gl driver
bool initDriver(SIrrlichtCreationParameters params, CIrrDeviceLinux* device);
bool initDriver(CIrrDeviceLinux* device);
bool changeRenderContext(const SExposedVideoData& videoData, CIrrDeviceLinux* device);
#endif
@ -344,7 +345,7 @@ namespace video
virtual void clearZBuffer();
//! Returns an image created from the last rendered frame.
virtual IImage* createScreenShot();
virtual IImage* createScreenShot(video::ECOLOR_FORMAT format=video::ECF_UNKNOWN, video::E_RENDER_TARGET target=video::ERT_FRAME_BUFFER);
//! checks if an OpenGL error has happend and prints it
//! for performance reasons only available in debug mode
@ -392,7 +393,7 @@ namespace video
void uploadClipPlane(u32 index);
//! inits the parts of the open gl driver used on all platforms
bool genericDriverInit(const core::dimension2d<u32>& screenSize, bool stencilBuffer);
bool genericDriverInit();
//! returns a device dependent texture from a software surface (IImage)
virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData);
@ -472,8 +473,7 @@ namespace video
//! Render target type for render operations
E_RENDER_TARGET CurrentTarget;
bool Doublebuffer;
bool Stereo;
SIrrlichtCreationParameters Params;
//! All the lights that have been requested; a hardware limited
//! number of them will be used at once.

View File

@ -748,6 +748,8 @@ bool COpenGLExtensionHandler::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
case EVDF_BLEND_OPERATIONS:
return (Version>=120) || FeatureAvailable[IRR_EXT_blend_minmax] ||
FeatureAvailable[IRR_EXT_blend_subtract] || FeatureAvailable[IRR_EXT_blend_logic_op];
case EVDF_TEXTURE_MATRIX:
return true;
default:
return false;
};

View File

@ -66,6 +66,13 @@
#include "glxext.h"
#endif
#endif
#ifndef GL_ARB_shader_objects
/* GL types for program/shader text and shader object handles */
typedef char GLcharARB;
typedef unsigned int GLhandleARB;
#endif
#ifndef GL_VERSION_2_0
/* GL type for program/shader text */
typedef char GLchar;
@ -1041,7 +1048,7 @@ class COpenGLExtensionHandler
void extGlDisableIndexed(GLenum target, GLuint index);
void extGlBlendFuncIndexed(GLuint buf, GLenum src, GLenum dst);
void extGlBlendEquationIndexed(GLuint buf, GLenum mode);
void extGlProgramParameteri(GLuint program, GLenum pname, GLint value);
void extGlProgramParameteri(GLhandleARB program, GLenum pname, GLint value);
// occlusion query
void extGlGenQueries(GLsizei n, GLuint *ids);
@ -2202,7 +2209,7 @@ inline void COpenGLExtensionHandler::extGlBlendEquationIndexed(GLuint buf, GLenu
}
inline void COpenGLExtensionHandler::extGlProgramParameteri(GLuint program, GLenum pname, GLint value)
inline void COpenGLExtensionHandler::extGlProgramParameteri(GLhandleARB program, GLenum pname, GLint value)
{
#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
if (queryFeature(EVDF_GEOMETRY_SHADER))
@ -2223,6 +2230,7 @@ inline void COpenGLExtensionHandler::extGlProgramParameteri(GLuint program, GLen
#endif
}
inline void COpenGLExtensionHandler::extGlGenQueries(GLsizei n, GLuint *ids)
{
#ifdef _IRR_OPENGL_USE_EXTPOINTER_
@ -2239,6 +2247,7 @@ inline void COpenGLExtensionHandler::extGlGenQueries(GLsizei n, GLuint *ids)
#endif
}
inline void COpenGLExtensionHandler::extGlDeleteQueries(GLsizei n, const GLuint *ids)
{
#ifdef _IRR_OPENGL_USE_EXTPOINTER_

View File

@ -157,12 +157,12 @@ void COpenGLSLMaterialRenderer::init(s32& outMaterialTypeNr,
}
else
{
Driver->extGlProgramParameteri((GLuint)Program, GL_GEOMETRY_INPUT_TYPE_EXT, Driver->primitiveTypeToGL(inType));
Driver->extGlProgramParameteri((GLuint)Program, GL_GEOMETRY_OUTPUT_TYPE_EXT, Driver->primitiveTypeToGL(outType));
Driver->extGlProgramParameteri(Program, GL_GEOMETRY_INPUT_TYPE_EXT, Driver->primitiveTypeToGL(inType));
Driver->extGlProgramParameteri(Program, GL_GEOMETRY_OUTPUT_TYPE_EXT, Driver->primitiveTypeToGL(outType));
if (verticesOut==0)
Driver->extGlProgramParameteri((GLuint)Program, GL_GEOMETRY_VERTICES_OUT_EXT, Driver->MaxGeometryVerticesOut);
Driver->extGlProgramParameteri(Program, GL_GEOMETRY_VERTICES_OUT_EXT, Driver->MaxGeometryVerticesOut);
else
Driver->extGlProgramParameteri((GLuint)Program, GL_GEOMETRY_VERTICES_OUT_EXT, core::min_(verticesOut, Driver->MaxGeometryVerticesOut));
Driver->extGlProgramParameteri(Program, GL_GEOMETRY_VERTICES_OUT_EXT, core::min_(verticesOut, Driver->MaxGeometryVerticesOut));
}
#elif defined(GL_NV_geometry_program4)
if (verticesOut==0)

View File

@ -10,7 +10,6 @@
#include "COpenGLTexture.h"
#include "COpenGLDriver.h"
#include "os.h"
#include "CImage.h"
#include "CColorConverter.h"
#include "irrString.h"
@ -39,12 +38,12 @@ COpenGLTexture::COpenGLTexture(IImage* origImage, const io::path& name, void* mi
if (ImageSize==TextureSize)
{
Image = new CImage(ColorFormat, ImageSize);
Image = Driver->createImage(ColorFormat, ImageSize);
origImage->copyTo(Image);
}
else
{
Image = new CImage(ColorFormat, TextureSize);
Image = Driver->createImage(ColorFormat, TextureSize);
// scale texture
origImage->copyToScaling(Image);
}
@ -135,26 +134,31 @@ GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT
filtering = GL_LINEAR;
colorformat = GL_RGBA;
type = GL_UNSIGNED_BYTE;
GLenum internalformat = GL_RGBA;
switch(format)
{
case ECF_A1R5G5B5:
colorformat=GL_BGRA_EXT;
type=GL_UNSIGNED_SHORT_1_5_5_5_REV;
return GL_RGBA;
internalformat = GL_RGBA;
break;
case ECF_R5G6B5:
colorformat=GL_BGR;
type=GL_UNSIGNED_SHORT_5_6_5_REV;
return GL_RGB;
internalformat = GL_RGB;
break;
case ECF_R8G8B8:
colorformat=GL_BGR;
type=GL_UNSIGNED_BYTE;
return GL_RGB;
internalformat = GL_RGB;
break;
case ECF_A8R8G8B8:
colorformat=GL_BGRA_EXT;
if (Driver->Version > 101)
type=GL_UNSIGNED_INT_8_8_8_8_REV;
return GL_RGBA;
internalformat = GL_RGBA;
break;
// Floating Point texture formats. Thanks to Patryk "Nadro" Nadrowski.
case ECF_R16F:
{
@ -163,11 +167,12 @@ GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT
colorformat = GL_RED;
type = GL_FLOAT;
return GL_R16F;
internalformat = GL_R16F;
#else
return GL_RGB8;
internalformat = GL_RGB8;
#endif
}
break;
case ECF_G16R16F:
{
#ifdef GL_ARB_texture_rg
@ -175,11 +180,12 @@ GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT
colorformat = GL_RG;
type = GL_FLOAT;
return GL_RG16F;
internalformat = GL_RG16F;
#else
return GL_RGB8;
internalformat = GL_RGB8;
#endif
}
break;
case ECF_A16B16G16R16F:
{
#ifdef GL_ARB_texture_rg
@ -187,11 +193,12 @@ GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT
colorformat = GL_RGBA;
type = GL_FLOAT;
return GL_RGBA16F_ARB;
internalformat = GL_RGBA16F_ARB;
#else
return GL_RGBA8;
internalformat = GL_RGBA8;
#endif
}
break;
case ECF_R32F:
{
#ifdef GL_ARB_texture_rg
@ -199,11 +206,12 @@ GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT
colorformat = GL_RED;
type = GL_FLOAT;
return GL_R32F;
internalformat = GL_R32F;
#else
return GL_RGB8;
internalformat = GL_RGB8;
#endif
}
break;
case ECF_G32R32F:
{
#ifdef GL_ARB_texture_rg
@ -211,11 +219,12 @@ GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT
colorformat = GL_RG;
type = GL_FLOAT;
return GL_RG32F;
internalformat = GL_RG32F;
#else
return GL_RGB8;
internalformat = GL_RGB8;
#endif
}
break;
case ECF_A32B32G32R32F:
{
#ifdef GL_ARB_texture_float
@ -223,17 +232,28 @@ GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT
colorformat = GL_RGBA;
type = GL_FLOAT;
return GL_RGBA32F_ARB;
internalformat = GL_RGBA32F_ARB;
#else
return GL_RGBA8;
internalformat = GL_RGBA8;
#endif
}
break;
default:
{
os::Printer::log("Unsupported texture format", ELL_ERROR);
return GL_RGBA8;
internalformat = GL_RGBA8;
}
}
#if defined(GL_ARB_framebuffer_sRGB) || defined(GL_EXT_framebuffer_sRGB)
if (Driver->Params.HandleSRGB)
{
if (internalformat==GL_RGBA)
internalformat=GL_SRGB_ALPHA_EXT;
else if (internalformat==GL_RGB)
internalformat=GL_SRGB_EXT;
}
#endif
return internalformat;
}
@ -360,6 +380,17 @@ void* COpenGLTexture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel)
IImage* image = (mipmapLevel==0)?Image:MipImage;
ReadOnlyLock |= (mode==ETLM_READ_ONLY);
MipLevelStored = mipmapLevel;
if (!ReadOnlyLock && mipmapLevel)
{
#ifdef GL_SGIS_generate_mipmap
if (Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE))
{
// do not automatically generate and update mipmaps
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);
}
#endif
AutomaticMipmapUpdate=false;
}
// if data not available or might have changed on GPU download it
if (!image || IsRenderTarget)
@ -381,10 +412,10 @@ void* COpenGLTexture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel)
++i;
}
while (i != mipmapLevel);
MipImage = image = new CImage(ECF_A8R8G8B8, core::dimension2du(width,height));
MipImage = image = Driver->createImage(ECF_A8R8G8B8, core::dimension2du(width,height));
}
else
Image = image = new CImage(ECF_A8R8G8B8, ImageSize);
Image = image = Driver->createImage(ECF_A8R8G8B8, ImageSize);
ColorFormat = ECF_A8R8G8B8;
}
if (!image)
@ -401,34 +432,41 @@ void* COpenGLTexture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel)
glGetIntegerv(GL_TEXTURE_BINDING_2D, &tmpTexture);
glBindTexture(GL_TEXTURE_2D, TextureName);
// we need to flip textures vertical
// however, it seems that this does not hold for mipmap
// textures, for unknown reasons.
// allows to read pixels in top-to-bottom order
#ifdef GL_MESA_pack_invert
if (Driver->queryOpenGLFeature(COpenGLExtensionHandler::IRR_MESA_pack_invert))
#ifdef GL_MESA_pack_invert
if (!mipmapLevel && Driver->queryOpenGLFeature(COpenGLExtensionHandler::IRR_MESA_pack_invert))
glPixelStorei(GL_PACK_INVERT_MESA, GL_TRUE);
#endif
#endif
// download GPU data as ARGB8 to pixels;
glGetTexImage(GL_TEXTURE_2D, mipmapLevel, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels);
#ifdef GL_MESA_pack_invert
if (Driver->queryOpenGLFeature(COpenGLExtensionHandler::IRR_MESA_pack_invert))
glPixelStorei(GL_PACK_INVERT_MESA, GL_FALSE);
else
#endif
if (!mipmapLevel)
{
// opengl images are horizontally flipped, so we have to fix that here.
const s32 pitch=image->getPitch();
u8* p2 = pixels + (image->getDimension().Height - 1) * pitch;
u8* tmpBuffer = new u8[pitch];
for (u32 i=0; i < image->getDimension().Height; i += 2)
#ifdef GL_MESA_pack_invert
if (Driver->queryOpenGLFeature(COpenGLExtensionHandler::IRR_MESA_pack_invert))
glPixelStorei(GL_PACK_INVERT_MESA, GL_FALSE);
else
#endif
{
memcpy(tmpBuffer, pixels, pitch);
memcpy(pixels, p2, pitch);
memcpy(p2, tmpBuffer, pitch);
pixels += pitch;
p2 -= pitch;
// opengl images are horizontally flipped, so we have to fix that here.
const s32 pitch=image->getPitch();
u8* p2 = pixels + (image->getDimension().Height - 1) * pitch;
u8* tmpBuffer = new u8[pitch];
for (u32 i=0; i < image->getDimension().Height; i += 2)
{
memcpy(tmpBuffer, pixels, pitch);
memcpy(pixels, p2, pitch);
memcpy(p2, tmpBuffer, pitch);
pixels += pitch;
p2 -= pitch;
}
delete [] tmpBuffer;
}
delete [] tmpBuffer;
}
image->unlock();

View File

@ -8,6 +8,7 @@
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
#include "CSoftwareTexture.h"
#include "CBlit.h"
#include "os.h"
#include "S3DVertex.h"
@ -283,7 +284,7 @@ bool CSoftwareDriver::setRenderTarget(video::ITexture* texture, bool clearBackBu
ZBuffer->clear();
if (clearBackBuffer)
((video::CImage*)RenderTargetSurface)->fill( color );
RenderTargetSurface->fill(color);
}
return true;
@ -820,7 +821,7 @@ void CSoftwareDriver::draw2DLine(const core::position2d<s32>& start,
const core::position2d<s32>& end,
SColor color)
{
RenderTargetSurface->drawLine(start, end, color );
drawLine(RenderTargetSurface, start, end, color );
}
@ -844,14 +845,14 @@ void CSoftwareDriver::draw2DRectangle(SColor color, const core::rect<s32>& pos,
if(!p.isValid())
return;
RenderTargetSurface->drawRectangle(p, color);
drawRectangle(RenderTargetSurface, p, color);
}
else
{
if(!pos.isValid())
return;
RenderTargetSurface->drawRectangle(pos, color);
drawRectangle(RenderTargetSurface, pos, color);
}
}
@ -903,7 +904,7 @@ ITexture* CSoftwareDriver::addRenderTargetTexture(const core::dimension2d<u32>&
const io::path& name,
const ECOLOR_FORMAT format)
{
CImage* img = new CImage(video::ECF_A1R5G5B5, size);
IImage* img = createImage(video::ECF_A1R5G5B5, size);
ITexture* tex = new CSoftwareTexture(img, name, true);
img->drop();
addTexture(tex);
@ -921,11 +922,14 @@ void CSoftwareDriver::clearZBuffer()
//! Returns an image created from the last rendered frame.
IImage* CSoftwareDriver::createScreenShot()
IImage* CSoftwareDriver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target)
{
if (target != video::ERT_FRAME_BUFFER)
return 0;
if (BackBuffer)
{
CImage* tmp = new CImage(BackBuffer->getColorFormat(), BackBuffer->getDimension());
IImage* tmp = createImage(BackBuffer->getColorFormat(), BackBuffer->getDimension());
BackBuffer->copyTo(tmp);
return tmp;
}

View File

@ -111,7 +111,7 @@ namespace video
virtual void clearZBuffer();
//! Returns an image created from the last rendered frame.
virtual IImage* createScreenShot();
virtual IImage* createScreenShot(video::ECOLOR_FORMAT format=video::ECF_UNKNOWN, video::E_RENDER_TARGET target=video::ERT_FRAME_BUFFER);
//! Returns the maximum amount of primitives (mostly vertices) which
//! the device is able to render with one drawIndexedTriangleList

View File

@ -359,8 +359,9 @@ CBurningVideoDriver::CBurningVideoDriver(const irr::SIrrlichtCreationParameters&
DriverAttributes->setAttribute("MaxTextures", 2);
DriverAttributes->setAttribute("MaxIndices", 1<<16);
DriverAttributes->setAttribute("MaxTextureSize", 1024);
DriverAttributes->setAttribute("MaxLights", glsl::gl_MaxLights);
DriverAttributes->setAttribute("MaxTextureLODBias", 16.f);
DriverAttributes->setAttribute("Version", 45);
DriverAttributes->setAttribute("Version", 47);
// create triangle renderers
@ -2275,7 +2276,7 @@ void CBurningVideoDriver::draw2DLine(const core::position2d<s32>& start,
const core::position2d<s32>& end,
SColor color)
{
BackBuffer->drawLine(start, end, color );
drawLine(BackBuffer, start, end, color );
}
@ -2299,14 +2300,14 @@ void CBurningVideoDriver::draw2DRectangle(SColor color, const core::rect<s32>& p
if(!p.isValid())
return;
BackBuffer->drawRectangle(p, color);
drawRectangle(BackBuffer, p, color);
}
else
{
if(!pos.isValid())
return;
BackBuffer->drawRectangle(pos, color);
drawRectangle(BackBuffer, pos, color);
}
}
@ -2564,7 +2565,7 @@ const core::matrix4& CBurningVideoDriver::getTransform(E_TRANSFORMATION_STATE st
ITexture* CBurningVideoDriver::addRenderTargetTexture(const core::dimension2d<u32>& size,
const io::path& name, const ECOLOR_FORMAT format)
{
CImage* img = new CImage(BURNINGSHADER_COLOR_FORMAT, size);
IImage* img = createImage(BURNINGSHADER_COLOR_FORMAT, size);
ITexture* tex = new CSoftwareTexture2(img, name, CSoftwareTexture2::IS_RENDERTARGET );
img->drop();
addTexture(tex);
@ -2582,17 +2583,19 @@ void CBurningVideoDriver::clearZBuffer()
//! Returns an image created from the last rendered frame.
IImage* CBurningVideoDriver::createScreenShot()
IImage* CBurningVideoDriver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target)
{
if (target != video::ERT_FRAME_BUFFER)
return 0;
if (BackBuffer)
{
CImage* tmp = new CImage(BackBuffer->getColorFormat(), BackBuffer->getDimension());
IImage* tmp = createImage(BackBuffer->getColorFormat(), BackBuffer->getDimension());
BackBuffer->copyTo(tmp);
return tmp;
}
else
return 0;
}

View File

@ -136,7 +136,7 @@ namespace video
virtual void clearZBuffer();
//! Returns an image created from the last rendered frame.
virtual IImage* createScreenShot();
virtual IImage* createScreenShot(video::ECOLOR_FORMAT format=video::ECF_UNKNOWN, video::E_RENDER_TARGET target=video::ERT_FRAME_BUFFER);
//! Returns the maximum amount of primitives (mostly vertices) which
//! the device is able to render with one drawIndexedTriangleList

View File

@ -565,23 +565,23 @@ namespace scene
{
if (!IsVisible || !SceneManager->getActiveCamera())
return;
preRenderLODCalculations();
preRenderIndicesCalculations();
SceneManager->registerNodeForRendering(this);
preRenderCalculationsIfNeeded();
// Do Not call ISceneNode::OnRegisterSceneNode(), this node should have no children (luke: is this comment still true, as ISceneNode::OnRegisterSceneNode() is called?)
ISceneNode::OnRegisterSceneNode();
ForceRecalculation = false;
}
void CTerrainSceneNode::preRenderLODCalculations()
{
scene::ICameraSceneNode * camera = SceneManager->getActiveCamera();
void CTerrainSceneNode::preRenderCalculationsIfNeeded()
{
scene::ICameraSceneNode * camera = SceneManager->getActiveCamera();
if(!camera)
return;
SceneManager->registerNodeForRendering(this);
// Do Not call ISceneNode::OnRegisterSceneNode(), this node should have no children
// Determine the camera rotation, based on the camera direction.
const core::vector3df cameraPosition = camera->getAbsolutePosition();
const core::vector3df cameraRotation = core::line3d<f32>(cameraPosition, camera->getTarget()).getVector().getHorizontalAngle();
@ -607,13 +607,31 @@ namespace scene
}
}
}
//we need to redo calculations...
OldCameraPosition = cameraPosition;
OldCameraRotation = cameraRotation;
OldCameraUp = cameraUp;
OldCameraFOV = CameraFOV;
const SViewFrustum* frustum = SceneManager->getActiveCamera()->getViewFrustum();
preRenderLODCalculations();
preRenderIndicesCalculations();
}
void CTerrainSceneNode::preRenderLODCalculations()
{
scene::ICameraSceneNode * camera = SceneManager->getActiveCamera();
if(!camera)
return;
const core::vector3df cameraPosition = camera->getAbsolutePosition();
const SViewFrustum* frustum = camera->getViewFrustum();
// Determine each patches LOD based on distance from camera (and whether or not they are in
// the view frustum).

View File

@ -258,7 +258,10 @@ namespace scene
core::aabbox3df BoundingBox;
core::array<f64> LODDistanceThreshold;
};
virtual void preRenderCalculationsIfNeeded();
virtual void preRenderLODCalculations();
virtual void preRenderIndicesCalculations();

Binary file not shown.

Binary file not shown.

View File

@ -79,7 +79,7 @@
Name="VCLinkerTool"
UseLibraryDependencyInputs="true"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib opengl32.lib"
AdditionalDependencies="kernel32.lib user32.lib gdi32.lib opengl32.lib"
OutputFile="..\..\bin\Win32-visualstudio\Irrlicht.dll"
LinkIncremental="2"
SuppressStartupBanner="true"
@ -179,7 +179,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="kernel32.lib user32.lib gdi32.lib opengl32.lib winmm.lib"
AdditionalDependencies="kernel32.lib user32.lib gdi32.lib opengl32.lib"
OutputFile="..\..\bin\Win32-visualstudio\Irrlicht.dll"
LinkIncremental="1"
SuppressStartupBanner="true"
@ -285,7 +285,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib opengl32.lib winmm.lib"
AdditionalDependencies="kernel32.lib user32.lib gdi32.lib opengl32.lib"
OutputFile="..\..\bin\Win32-visualstudio\Irrlicht.dll"
LinkIncremental="1"
SuppressStartupBanner="true"
@ -640,7 +640,7 @@
Name="VCLinkerTool"
UseLibraryDependencyInputs="true"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib opengl32.lib winmm.lib"
AdditionalDependencies="kernel32.lib user32.lib gdi32.lib opengl32.lib"
OutputFile="..\..\bin\Win32-visualstudio\Irrlicht.dll"
LinkIncremental="2"
SuppressStartupBanner="true"
@ -2311,6 +2311,10 @@
<Filter
Name="Null"
>
<File
RelativePath=".\CBlit.h"
>
</File>
<File
RelativePath="CColorConverter.cpp"
>

View File

@ -632,7 +632,7 @@ bool CIrrDeviceMacOSX::createWindow()
CGLSetParameter(CGLContext,kCGLCPSwapInterval,&newSwapInterval);
if (IsSoftwareRenderer && CreationParams.DriverType != video::EDT_NULL)
{
long order = -1; // below window
GLint order = -1; // below window
CGLSetParameter(CGLContext, kCGLCPSurfaceOrder, &order);
}
}
@ -677,7 +677,7 @@ void CIrrDeviceMacOSX::createDriver()
case video::EDT_BURNINGSVIDEO:
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
VideoDriver = video::createSoftwareDriver2(CreationParams.WindowSize, CreationParams.Fullscreen, FileSystem, this);
VideoDriver = video::createBurningVideoDriver(CreationParams, FileSystem, this);
IsSoftwareRenderer = true;
#else
os::Printer::log("Burning's video driver was not compiled in.", ELL_ERROR);

View File

@ -6,12 +6,12 @@
#include "OSXClipboard.h"
#import <Cocoa/Cocoa.h>
void OSXCopyToClipboard(const char *text)
void OSXCopyToClipboard(const char *text)
{
NSString *str;
NSPasteboard *board;
NSString *str;
NSPasteboard *board;
if (text != NULL && strlen(text) > 0)
if ((text != NULL) && (strlen(text) > 0))
{
str = [NSString stringWithCString:text encoding:NSWindowsCP1252StringEncoding];
board = [NSPasteboard generalPasteboard];
@ -20,15 +20,17 @@ void OSXCopyToClipboard(const char *text)
}
}
char* OSXCopyFromClipboard()
char* OSXCopyFromClipboard()
{
NSString *str;
NSPasteboard *board;
char *result;
NSString* str;
NSPasteboard* board;
char* result;
result = NULL;
board = [NSPasteboard generalPasteboard];
str = [board stringForType:NSStringPboardType];
if (str != nil) result = (char*)[str cStringUsingEncoding:NSWindowsCP1252StringEncoding];
if (str != nil)
result = (char*)[str cStringUsingEncoding:NSWindowsCP1252StringEncoding];
return (result);
}

View File

@ -645,6 +645,16 @@ static bool draw2DImage4c(video::E_DRIVER_TYPE type)
video::IVideoDriver* driver = device->getVideoDriver();
if (!driver->queryFeature(video::EVDF_BILINEAR_FILTER))
{
device->closeDevice();
device->run();
device->drop();
return true;
}
logTestString("Testing driver %ls\n", driver->getName());
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS,true);
driver->setTextureCreationFlag(video::ETCF_OPTIMIZED_FOR_QUALITY,true);
@ -739,6 +749,16 @@ static bool addBlend2d(video::E_DRIVER_TYPE type)
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
if (!driver->queryFeature(video::EVDF_BILINEAR_FILTER))
{
device->closeDevice();
device->run();
device->drop();
return true;
}
logTestString("Testing driver %ls\n", driver->getName());
scene::IAnimatedMesh* mesh = smgr->getMesh("../media/sydney.md2");
if (!mesh)
{
@ -816,6 +836,16 @@ static bool moreFilterTests(video::E_DRIVER_TYPE type)
video::IVideoDriver* driver = device->getVideoDriver();
gui::IGUIEnvironment* gui = device->getGUIEnvironment();
if (!driver->queryFeature(video::EVDF_BILINEAR_FILTER))
{
device->closeDevice();
device->run();
device->drop();
return true;
}
logTestString("Testing driver %ls\n", driver->getName());
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
video::ITexture* tex = driver->getTexture("../media/irrlichtlogo.jpg");
gui::IGUIImage* image = gui->addImage(core::recti(0,0,64,64));
@ -857,20 +887,9 @@ static bool moreFilterTests(video::E_DRIVER_TYPE type)
bool twodmaterial()
{
bool result = addBlend2d(video::EDT_OPENGL);
result &= addBlend2d(video::EDT_DIRECT3D9);
result &= addBlend2d(video::EDT_DIRECT3D8);
result &= addBlend2d(video::EDT_BURNINGSVIDEO);
result &= moreFilterTests(video::EDT_OPENGL);
result &= moreFilterTests(video::EDT_DIRECT3D9);
result &= moreFilterTests(video::EDT_DIRECT3D8);
result &= moreFilterTests(video::EDT_BURNINGSVIDEO);
result &= draw2DImage4c(video::EDT_OPENGL);
result &= draw2DImage4c(video::EDT_DIRECT3D9);
result &= draw2DImage4c(video::EDT_DIRECT3D8);
result &= draw2DImage4c(video::EDT_BURNINGSVIDEO);
bool result = true;
TestWithAllDrivers(addBlend2d);
TestWithAllDrivers(moreFilterTests);
TestWithAllDrivers(draw2DImage4c);
return result;
}

View File

@ -25,6 +25,8 @@ static bool testLineRendering(video::E_DRIVER_TYPE type)
return true;
}
logTestString("Testing driver %ls\n", driver->getName());
scene::ISceneManager* smgr = device->getSceneManager();
scene::IAnimatedMesh* mesh = smgr->getMesh("../media/sydney.md2");
@ -62,7 +64,7 @@ static bool testLineRendering(video::E_DRIVER_TYPE type)
bool antiAliasing()
{
bool result = testLineRendering(video::EDT_OPENGL);
result &= testLineRendering(video::EDT_DIRECT3D9);
bool result = true;
TestWithAllHWDrivers(testLineRendering);
return result;
}

View File

@ -2,11 +2,11 @@
using namespace irr;
static bool testImageCreation(video::E_DRIVER_TYPE driverType)
static bool testImageCreation()
{
// create device
IrrlichtDevice *device = createDevice(driverType, core::dimension2d<u32>(160,120));
IrrlichtDevice *device = createDevice(video::EDT_SOFTWARE, core::dimension2d<u32>(160,120));
if (device == 0)
return true; // could not create selected driver.
@ -37,6 +37,6 @@ static bool testImageCreation(video::E_DRIVER_TYPE driverType)
bool createImage()
{
bool result = testImageCreation(video::EDT_SOFTWARE);
bool result = testImageCreation();
return result;
}

View File

@ -16,6 +16,15 @@ bool testWithRenderTarget(video::E_DRIVER_TYPE driverType)
video::IVideoDriver* driver = device->getVideoDriver();
if (!driver->queryFeature(video::EVDF_RENDER_TO_TARGET))
{
device->closeDevice();
device->run();
device->drop();
return true;
}
logTestString("Testing driver %ls\n", driver->getName());
video::ITexture* RenderTarget=driver->addRenderTargetTexture(core::dimension2d<u32>(64,64), "BASEMAP");
video::ITexture *tex=driver->getTexture("../media/water.jpg");
@ -53,13 +62,56 @@ bool testWithPNG(video::E_DRIVER_TYPE driverType)
video::IVideoDriver* driver = device->getVideoDriver();
logTestString("Testing driver %ls\n", driver->getName());
video::ITexture *tex=driver->getTexture("media/RedbrushAlpha-0.25.png");
driver->beginScene(true, true, video::SColor(255,40,40,255));//Backbuffer background is blue
driver->draw2DImage(tex, core::recti(0,0,160,120), core::recti(0,0,256,256), 0, 0, true);
driver->endScene();
bool result = takeScreenshotAndCompareAgainstReference(driver, "-draw2DImagePNG.png");
bool result = takeScreenshotAndCompareAgainstReference(driver, "-draw2DImagePNG.png", 98.f);
device->closeDevice();
device->run();
device->drop();
return result;
}
// draws an image and checks if the written example equals the original image
bool testExactPlacement(video::E_DRIVER_TYPE driverType)
{
// create device
IrrlichtDevice *device = createDevice(video::EDT_DIRECT3D9, core::dimension2d<u32>(160,120), 32);
if (device == 0)
return true; // could not create selected driver.
video::IVideoDriver* driver = device->getVideoDriver();
if (driver->getColorFormat() != video::ECF_A8R8G8B8 || !driver->queryFeature(video::EVDF_RENDER_TO_TARGET))
{
device->closeDevice();
device->run();
device->drop();
return true;
}
logTestString("Testing driver %ls\n", driver->getName());
video::ITexture* rt=driver->addRenderTargetTexture(core::dimension2d<u32>(32,32), "rt1");
video::ITexture *tex=driver->getTexture("../media/fireball.bmp");
driver->beginScene(true, true, video::SColor(255,40,40,255));//Backbuffer background is blue
driver->setRenderTarget(rt);
driver->draw2DImage(tex, core::recti(0,0,32,32), core::recti(0,0,64,64));
driver->setRenderTarget(0);
driver->endScene();
video::IImage* img = driver->createImage(rt, core::vector2di(), rt->getSize());
driver->writeImageToFile(img, "results/fireball.png");
bool result = binaryCompareFiles("media/fireball.png", "results/fireball.png");
device->closeDevice();
device->run();
@ -72,14 +124,9 @@ bool testWithPNG(video::E_DRIVER_TYPE driverType)
bool draw2DImage()
{
bool result = testWithRenderTarget(video::EDT_DIRECT3D9);
result &= testWithRenderTarget(video::EDT_DIRECT3D8);
result &= testWithRenderTarget(video::EDT_OPENGL);
result &= testWithRenderTarget(video::EDT_BURNINGSVIDEO);
result &= testWithRenderTarget(video::EDT_SOFTWARE);
result &= testWithPNG(video::EDT_DIRECT3D9);
result &= testWithPNG(video::EDT_OPENGL);
bool result = true;
TestWithAllDrivers(testWithRenderTarget);
TestWithAllDrivers(testExactPlacement);
TestWithAllHWDrivers(testWithPNG);
return result;
}

View File

@ -24,6 +24,8 @@ static bool lineRender(E_DRIVER_TYPE driverType)
IVideoDriver* driver = device->getVideoDriver();
ISceneManager * smgr = device->getSceneManager();
logTestString("Testing driver %ls\n", driver->getName());
// Draw a cube background so that we can check that the pixels' alpha is working.
ISceneNode * cube = smgr->addCubeSceneNode(50.f, 0, -1, vector3df(0, 0, 60));
cube->setMaterialTexture(0, driver->getTexture("../media/wall.bmp"));
@ -64,6 +66,8 @@ static bool pixelAccuracy(E_DRIVER_TYPE driverType)
IVideoDriver* driver = device->getVideoDriver();
logTestString("Testing driver %ls\n", driver->getName());
device->getSceneManager()->addCameraSceneNode();
driver->beginScene(true, true, SColor(255,100,101,140));
@ -108,30 +112,10 @@ static bool pixelAccuracy(E_DRIVER_TYPE driverType)
bool drawPixel(void)
{
bool passed = true;
bool result = true;
logTestString("Check OpenGL driver\n");
passed &= lineRender(EDT_OPENGL);
logTestString("Check Software driver\n");
passed &= lineRender(EDT_SOFTWARE);
logTestString("Check Burning's Video driver\n");
passed &= lineRender(EDT_BURNINGSVIDEO);
logTestString("Check Direct3D9 driver\n");
passed &= lineRender(EDT_DIRECT3D9);
logTestString("Check Direct3D8 driver\n");
passed &= lineRender(EDT_DIRECT3D8);
TestWithAllDrivers(lineRender);
TestWithAllDrivers(pixelAccuracy);
logTestString("Check OpenGL driver\n");
passed &= pixelAccuracy(EDT_OPENGL);
logTestString("Check Software driver\n");
passed &= pixelAccuracy(EDT_SOFTWARE);
logTestString("Check Burning's Video driver\n");
passed &= pixelAccuracy(EDT_BURNINGSVIDEO);
logTestString("Check Direct3D9 driver\n");
passed &= pixelAccuracy(EDT_DIRECT3D9);
logTestString("Check Direct3D8 driver\n");
passed &= pixelAccuracy(EDT_DIRECT3D8);
return passed;
return result;
}

View File

@ -11,6 +11,8 @@ bool testWithDriver(video::E_DRIVER_TYPE driverType)
video::IVideoDriver* driver = device->getVideoDriver();
logTestString("Testing driver %ls\n", driver->getName());
driver->beginScene(true, true, video::SColor(255,100,101,140));
core::recti r;
@ -40,10 +42,7 @@ bool testWithDriver(video::E_DRIVER_TYPE driverType)
bool drawRectOutline(void)
{
// TODO: Only OpenGL supports thick lines
bool result = testWithDriver(video::EDT_BURNINGSVIDEO);
result &= testWithDriver(video::EDT_DIRECT3D8);
result &= testWithDriver(video::EDT_DIRECT3D9);
result &= testWithDriver(video::EDT_OPENGL);
result &= testWithDriver(video::EDT_SOFTWARE);
bool result = true;
TestWithAllDrivers(testWithDriver);
return result;
}

View File

@ -14,7 +14,7 @@ using namespace gui;
bool guiDisabledMenu(void)
{
IrrlichtDevice *device = createDevice( video::EDT_OPENGL,
IrrlichtDevice *device = createDevice( video::EDT_BURNINGSVIDEO,
dimension2d<u32>(160, 40), 32);
assert(device);
if (!device)

View File

@ -94,7 +94,10 @@ static bool loadScene(void)
{
smgr->drawAll();
driver->endScene();
result = takeScreenshotAndCompareAgainstReference(driver, "-loadScene.png", 98.91f);
// we need to be very sloppy, because the animators will produce a different
// start depending on the actual loading time. 97% seems to be safe, as removing
// an object produces values around 95%
result = takeScreenshotAndCompareAgainstReference(driver, "-loadScene.png", 97.4f);
if (!result)
logTestString("Rendering the loaded scene failed.\n");
}

View File

@ -8,6 +8,60 @@
using namespace irr;
using namespace core;
core::map<int, int> countReferences;
struct SDummy
{
SDummy(int a) : x(a)
{
countReferences.insert(x,1);
}
SDummy() : x(0)
{
countReferences.insert(x,1);
}
SDummy(const SDummy& other)
{
x = other.x;
countReferences[x] = countReferences[x] + 1;
}
~SDummy()
{
countReferences[x] = countReferences[x] - 1;
}
int x;
};
static bool testErase()
{
{
core::array<SDummy> aaa;
aaa.push_back(SDummy(0));
aaa.push_back(SDummy(1));
aaa.push_back(SDummy(2));
aaa.push_back(SDummy(3));
aaa.push_back(SDummy(4));
aaa.push_back(SDummy(5));
aaa.erase(0,2);
}
for ( core::map<int,int>::Iterator it = countReferences.getIterator(); !it.atEnd(); it++ )
{
if ( it->getValue() != 0 )
{
logTestString("testErase: wrong count for %d, it's: %d\n", it->getKey(), it->getValue());
return false;
}
}
return true;
}
struct VarArray
{
core::array < int, core::irrAllocatorFast<int> > MyArray;
@ -69,6 +123,7 @@ bool testIrrArray(void)
crashTestFastAlloc();
allExpected &= testSelfAssignment();
allExpected &= testSwap();
allExpected &= testErase();
if(allExpected)
logTestString("\nAll tests passed\n");

View File

@ -20,6 +20,15 @@ static bool runTestWithDriver(E_DRIVER_TYPE driverType)
IVideoDriver* driver = device->getVideoDriver();
ISceneManager * smgr = device->getSceneManager();
logTestString("Testing driver %ls\n", driver->getName());
if (driver->getDriverAttributes().getAttributeAsInt("MaxTextures")<2)
{
device->closeDevice();
device->run();
device->drop();
return true;
}
bool result = true;
bool added = device->getFileSystem()->addFileArchive("../media/map-20kdm2.pk3");
assert(added);
@ -55,13 +64,8 @@ static bool runTestWithDriver(E_DRIVER_TYPE driverType)
bool lightMaps(void)
{
bool passed = true;
passed &= runTestWithDriver(EDT_OPENGL);
passed &= runTestWithDriver(EDT_BURNINGSVIDEO);
passed &= runTestWithDriver(EDT_DIRECT3D9);
passed &= runTestWithDriver(EDT_DIRECT3D8);
return passed;
bool result = true;
TestWithAllDrivers(runTestWithDriver);
return result;
}

View File

@ -10,34 +10,46 @@ static bool testLightTypes(video::E_DRIVER_TYPE driverType)
IrrlichtDevice *device = createDevice (driverType, core::dimension2d<u32>(128,128));
if (!device)
return true; // No error if device does not exist
// device->getSceneManager()->setAmbientLight(video::SColorf(0.3f,0.3f,0.3f));
scene::ICameraSceneNode* cam = device->getSceneManager()->addCameraSceneNode();
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
if (!driver->getDriverAttributes().getAttributeAsInt("MaxLights"))
{
device->closeDevice();
device->run();
device->drop();
return true;
}
logTestString("Testing driver %ls\n", driver->getName());
// smgr->setAmbientLight(video::SColorf(0.3f,0.3f,0.3f));
scene::ICameraSceneNode* cam = smgr->addCameraSceneNode();
cam->setPosition(core::vector3df(0,200,0));
cam->setTarget(core::vector3df());
device->getSceneManager()->addAnimatedMeshSceneNode(device->getSceneManager()->addHillPlaneMesh("plane", core::dimension2df(4,4), core::dimension2du(128,128)));
scene::ILightSceneNode* light1 = device->getSceneManager()->addLightSceneNode(0, core::vector3df(-100,30,-100));
smgr->addAnimatedMeshSceneNode(device->getSceneManager()->addHillPlaneMesh("plane", core::dimension2df(4,4), core::dimension2du(128,128)));
scene::ILightSceneNode* light1 = smgr->addLightSceneNode(0, core::vector3df(-100,30,-100));
light1->setLightType(video::ELT_POINT);
light1->setRadius(100.f);
light1->getLightData().DiffuseColor.set(0,1,1);
// device->getSceneManager()->addCubeSceneNode(10, light1)->setMaterialFlag(video::EMF_LIGHTING, false);
scene::ILightSceneNode* light2 = device->getSceneManager()->addLightSceneNode(0, core::vector3df(100,30,100));
// smgr->addCubeSceneNode(10, light1)->setMaterialFlag(video::EMF_LIGHTING, false);
scene::ILightSceneNode* light2 = smgr->addLightSceneNode(0, core::vector3df(100,30,100));
light2->setRotation(core::vector3df(90,0,0));
light2->setLightType(video::ELT_SPOT);
light2->setRadius(100.f);
light2->getLightData().DiffuseColor.set(1,0,0);
light2->getLightData().InnerCone=10.f;
light2->getLightData().OuterCone=30.f;
// device->getSceneManager()->addCubeSceneNode(10, light2)->setMaterialFlag(video::EMF_LIGHTING, false);
scene::ILightSceneNode* light3 = device->getSceneManager()->addLightSceneNode();
// smgr->addCubeSceneNode(10, light2)->setMaterialFlag(video::EMF_LIGHTING, false);
scene::ILightSceneNode* light3 = smgr->addLightSceneNode();
light3->setRotation(core::vector3df(15,0,0));
light3->setLightType(video::ELT_DIRECTIONAL);
light1->getLightData().DiffuseColor.set(0,1,0);
device->getVideoDriver()->beginScene (true, true, 0);
device->getSceneManager()->drawAll();
device->getVideoDriver()->endScene();
driver->beginScene (true, true, 0);
smgr->drawAll();
driver->endScene();
const bool result = takeScreenshotAndCompareAgainstReference(device->getVideoDriver(), "-lightType.png", 99.91f);
const bool result = takeScreenshotAndCompareAgainstReference(driver, "-lightType.png", 99.91f);
device->closeDevice();
device->run();
@ -48,14 +60,8 @@ static bool testLightTypes(video::E_DRIVER_TYPE driverType)
bool lights(void)
{
bool passed = true;
passed &= testLightTypes(video::EDT_OPENGL);
bool result = true;
// no lights in sw renderer
// passed &= testLightTypes(video::EDT_SOFTWARE);
passed &= testLightTypes(video::EDT_BURNINGSVIDEO);
passed &= testLightTypes(video::EDT_DIRECT3D9);
passed &= testLightTypes(video::EDT_DIRECT3D8);
return passed;
TestWithAllDrivers(testLightTypes);
return result;
}

View File

@ -92,6 +92,8 @@ int main(int argumentCount, char * arguments[])
TEST(createImage);
TEST(cursorSetVisible);
TEST(flyCircleAnimator);
TEST(guiDisabledMenu);
TEST(makeColorKeyTexture);
TEST(md2Animation);
TEST(meshTransform);
TEST(skinnedMesh);
@ -100,10 +102,9 @@ int main(int argumentCount, char * arguments[])
TEST(ioScene);
// all driver checks
TEST(videoDriver);
TEST(screenshot);
TEST(drawPixel);
TEST(drawRectOutline);
TEST(guiDisabledMenu);
TEST(makeColorKeyTexture);
TEST(material);
TEST(renderTargetTexture);
TEST(textureFeatures);
@ -138,9 +139,9 @@ int main(int argumentCount, char * arguments[])
{
for (unsigned int i=0; i<tests.size(); ++i)
{
printf("%3d: %s\n", i, tests[i].testName);
logTestString("%3d: %s\n", i, tests[i].testName);
}
printf("\n");
logTestString("\n");
return 0;
}

View File

@ -61,7 +61,7 @@ static bool polygonOffset(video::E_DRIVER_TYPE type)
bool material()
{
bool result = polygonOffset(video::EDT_OPENGL);
result &= polygonOffset(video::EDT_DIRECT3D9);
bool result = true;
TestWithAllDrivers(polygonOffset);
return result;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 740 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 812 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 917 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 408 B

After

Width:  |  Height:  |  Size: 333 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 742 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

BIN
tests/media/fireball.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 974 B

Some files were not shown because too many files have changed in this diff Show More