Merging r6405 through r6424 from trunk to ogl-es branch

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@6425 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
cutealien 2022-09-22 21:55:03 +00:00
parent ddc14ea87e
commit 07f17647d2
46 changed files with 589 additions and 463 deletions

View File

@ -11,6 +11,8 @@ Changes in ogl-es (not yet released - will be merged with trunk at some point)
-------------------------- --------------------------
Changes in 1.9 (not yet released) Changes in 1.9 (not yet released)
- Fix MouseButtonStates for mouse events in CIrrDeviceSDL when middle or right button are released.
- CGUIContextMenu no longer marks EMIE_MOUSE_MOVED as handled
- core::array::linear_search and linear_reverse_search can now work with any types as long as corresponding operator== is implemented. - core::array::linear_search and linear_reverse_search can now work with any types as long as corresponding operator== is implemented.
- Add checks for sane image sizes in some image loaders (so far: bmp, jpg, tga, png). - Add checks for sane image sizes in some image loaders (so far: bmp, jpg, tga, png).
Thanks @sfan5 for the original patch (got modified a bit): https://github.com/minetest/irrlicht/commit/dbd39120e7ed8c0c97e48e2df62347627f3c1d42 Thanks @sfan5 for the original patch (got modified a bit): https://github.com/minetest/irrlicht/commit/dbd39120e7ed8c0c97e48e2df62347627f3c1d42
@ -383,6 +385,7 @@ Changes in 1.9 (not yet released)
-------------------------- --------------------------
Changes in 1.8.6 Changes in 1.8.6
- Avoid warning about stringop-overflow in string<T>::subString when compiling in release with newer gcc
- Update library zlib to 1.2.11 (from 1.2.8) - Update library zlib to 1.2.11 (from 1.2.8)
- Update library bzip2 to 1.0.8 (from 1.0.6) - Update library bzip2 to 1.0.8 (from 1.0.6)
- Security: Fix buffer overflow caused by malformed md2 files. Thanks @procfs for reporting (https://irrlicht.sourceforge.io/forum/viewtopic.php?f=7&t=52785) - Security: Fix buffer overflow caused by malformed md2 files. Thanks @procfs for reporting (https://irrlicht.sourceforge.io/forum/viewtopic.php?f=7&t=52785)

View File

@ -25,6 +25,7 @@ all: all_linux
# target specific settings # target specific settings
all_linux all_win32 static_win32: LDFLAGS += -L$(IrrlichtHome)/lib/$(SYSTEM) -lIrrlicht all_linux all_win32 static_win32: LDFLAGS += -L$(IrrlichtHome)/lib/$(SYSTEM) -lIrrlicht
all_linux: LDFLAGS += -L/usr/X11R6/lib$(LIBSELECT) -lGL -lEGL -lGLESv1_CM -lGLESv2 -lXxf86vm -lXext -lX11 -lXcursor all_linux: LDFLAGS += -L/usr/X11R6/lib$(LIBSELECT) -lGL -lEGL -lGLESv1_CM -lGLESv2 -lXxf86vm -lXext -lX11 -lXcursor
#all_linux: LDFLAGS += `sdl-config --libs`
all_linux clean_linux: SYSTEM=Linux all_linux clean_linux: SYSTEM=Linux
all_win32 clean_win32 static_win32: SYSTEM=Win32-gcc all_win32 clean_win32 static_win32: SYSTEM=Win32-gcc
all_win32 clean_win32 static_win32: SUF=.exe all_win32 clean_win32 static_win32: SUF=.exe

View File

@ -25,6 +25,7 @@ all: all_linux
# target specific settings # target specific settings
all_linux all_win32 static_win32: LDFLAGS += -L$(IrrlichtHome)/lib/$(SYSTEM) -lIrrlicht all_linux all_win32 static_win32: LDFLAGS += -L$(IrrlichtHome)/lib/$(SYSTEM) -lIrrlicht
all_linux: LDFLAGS += -L/usr/X11R6/lib$(LIBSELECT) -lGL -lEGL -lGLESv1_CM -lGLESv2 -lXxf86vm -lXext -lX11 -lXcursor all_linux: LDFLAGS += -L/usr/X11R6/lib$(LIBSELECT) -lGL -lEGL -lGLESv1_CM -lGLESv2 -lXxf86vm -lXext -lX11 -lXcursor
#all_linux: LDFLAGS += `sdl-config --libs`
all_linux clean_linux: SYSTEM=Linux all_linux clean_linux: SYSTEM=Linux
all_win32 clean_win32 static_win32: SYSTEM=Win32-gcc all_win32 clean_win32 static_win32: SYSTEM=Win32-gcc
all_win32 clean_win32 static_win32: SUF=.exe all_win32 clean_win32 static_win32: SUF=.exe

View File

@ -35,8 +35,6 @@ of the objects and camera.
*/ */
#ifdef _MSC_VER #ifdef _MSC_VER
// We'll also define this to stop MSVC complaining about sprintf().
#define _CRT_SECURE_NO_WARNINGS
#pragma comment(lib, "Irrlicht.lib") #pragma comment(lib, "Irrlicht.lib")
#endif #endif
@ -150,6 +148,7 @@ int main()
*/ */
smgr->addCameraSceneNode(); smgr->addCameraSceneNode();
int lastFPS = -1; int lastFPS = -1;
u32 lastPrimitives = 0;
u32 timeNow = device->getTimer()->getTime(); u32 timeNow = device->getTimer()->getTime();
bool nodeVisible=true; bool nodeVisible=true;
@ -190,16 +189,20 @@ int main()
driver->endScene(); driver->endScene();
int fps = driver->getFPS(); int fps = driver->getFPS();
u32 numPrimitives = driver->getPrimitiveCountDrawn();
if (lastFPS != fps) if (lastFPS != fps || lastPrimitives != numPrimitives)
{ {
core::stringw tmp(L"OcclusionQuery Example ["); core::stringw tmp(L"OcclusionQuery Example [");
tmp += driver->getName(); tmp += driver->getName();
tmp += L"] fps: "; tmp += L"] fps: ";
tmp += fps; tmp += fps;
tmp += L" polygons: ";
tmp += numPrimitives;
device->setWindowCaption(tmp.c_str()); device->setWindowCaption(tmp.c_str());
lastFPS = fps; lastFPS = fps;
lastPrimitives = numPrimitives;
} }
} }

View File

@ -36,9 +36,6 @@ shader. Therefore, we set texture size in OnSetConstants callback using
setVertexShaderConstant function. setVertexShaderConstant function.
*/ */
IrrlichtDevice* device = 0;
video::ITexture* rt = 0;
class QuadShaderCallBack : public video::IShaderConstantSetCallBack class QuadShaderCallBack : public video::IShaderConstantSetCallBack
{ {
public: public:
@ -48,22 +45,21 @@ public:
virtual void OnSetConstants(video::IMaterialRendererServices* services, virtual void OnSetConstants(video::IMaterialRendererServices* services,
s32 userData) s32 userData)
{ {
core::dimension2d<u32> size = rt->getSize();
// get texture size array
f32 textureSize[] =
{
(f32)size.Width, (f32)size.Height
};
if ( FirstUpdate ) if ( FirstUpdate )
{ {
FirstUpdate = false;
TextureSizeID = services->getVertexShaderConstantID("TextureSize"); TextureSizeID = services->getVertexShaderConstantID("TextureSize");
TextureSamplerID = services->getPixelShaderConstantID("TextureSampler"); TextureSamplerID = services->getPixelShaderConstantID("TextureSampler");
} }
// get texture size array (for our simple example HLSL just needs that to calculate pixel centers)
core::dimension2d<u32> size = services->getVideoDriver()->getCurrentRenderTargetSize();
f32 textureSize[2];
textureSize[0] = (f32)size.Width;
textureSize[1] = (f32)size.Height;
// set texture size to vertex shader // set texture size to vertex shader
services->setVertexShaderConstant(TextureSizeID, reinterpret_cast<f32*>(textureSize), 2); services->setVertexShaderConstant(TextureSizeID, textureSize, 2);
// set texture for an OpenGL driver // set texture for an OpenGL driver
s32 textureLayer = 0; s32 textureLayer = 0;
@ -143,8 +139,9 @@ public:
// set the material of screen quad // set the material of screen quad
Driver->setMaterial(Material); Driver->setMaterial(Material);
// set matrices to fit the quad to full viewport // set world matrix to fit the quad to full viewport
Driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); Driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
// view & projection not used in shader, but matter to burnings driver
Driver->setTransform(video::ETS_VIEW, core::IdentityMatrix); Driver->setTransform(video::ETS_VIEW, core::IdentityMatrix);
Driver->setTransform(video::ETS_PROJECTION, core::IdentityMatrix); Driver->setTransform(video::ETS_PROJECTION, core::IdentityMatrix);
@ -152,22 +149,10 @@ public:
Driver->drawVertexPrimitiveList(Vertices, 4, Indices, 2); Driver->drawVertexPrimitiveList(Vertices, 4, Indices, 2);
} }
//! sets a flag of material to a new value //! Access the material
virtual void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue) virtual video::SMaterial& getMaterial()
{ {
Material.setFlag(flag, newvalue); return Material;
}
//! sets the texture of the specified layer in material to the new texture.
void setMaterialTexture(u32 textureLayer, video::ITexture* texture)
{
Material.setTexture(textureLayer, texture);
}
//! sets the material type to a new material type.
virtual void setMaterialType(video::E_MATERIAL_TYPE newType)
{
Material.MaterialType = newType;
} }
private: private:
@ -190,7 +175,7 @@ int main()
return 1; return 1;
// create device // create device
device = createDevice(driverType, core::dimension2d<u32>(640, 480)); IrrlichtDevice* device = createDevice(driverType, core::dimension2d<u32>(640, 480));
if (device == 0) if (device == 0)
return 1; // could not create selected driver. return 1; // could not create selected driver.
@ -278,7 +263,7 @@ int main()
*/ */
// create render target // create render target
video::ITexture* rt = 0;
if (driver->queryFeature(video::EVDF_RENDER_TO_TARGET)) if (driver->queryFeature(video::EVDF_RENDER_TO_TARGET))
{ {
rt = driver->addRenderTargetTexture(core::dimension2d<u32>(640, 480), "RTT1"); rt = driver->addRenderTargetTexture(core::dimension2d<u32>(640, 480), "RTT1");
@ -312,13 +297,17 @@ int main()
// we create a screen quad // we create a screen quad
ScreenQuad *screenQuad = new ScreenQuad(driver); ScreenQuad *screenQuad = new ScreenQuad(driver);
video::SMaterial& screenQuadMaterial = screenQuad->getMaterial();
// turn off mip maps and bilinear filter since we do not want interpolated result // turn off mip maps and bilinear filter since we do not want interpolated results
screenQuad->setMaterialFlag(video::EMF_USE_MIP_MAPS, false); screenQuadMaterial.setFlag(video::EMF_USE_MIP_MAPS, false);
screenQuad->setMaterialFlag(video::EMF_BILINEAR_FILTER, false); screenQuadMaterial.setFlag(video::EMF_BILINEAR_FILTER, false);
// turn off depth buffer, because our full screen 2D overlay doesn't process depth
screenQuadMaterial.setFlag(video::EMF_ZBUFFER, false);
// set quad texture to RTT we just create // set quad texture to RTT we just create
screenQuad->setMaterialTexture(0, rt); screenQuadMaterial.setTexture(0, rt);
/* /*
Let's create material for the quad. Like in other example, we create material Let's create material for the quad. Like in other example, we create material
@ -351,7 +340,7 @@ int main()
} }
// set post processing material type to the quad // set post processing material type to the quad
screenQuad->setMaterialType((video::E_MATERIAL_TYPE)ppMaterialType); screenQuadMaterial.MaterialType = (video::E_MATERIAL_TYPE)ppMaterialType;
/* /*
Now draw everything. That's all. Now draw everything. That's all.

View File

@ -316,7 +316,7 @@ private:
Irrlicht internally uses textures with left-top origin and then corrects the texture-matrices in the fixed-function pipeline. Irrlicht internally uses textures with left-top origin and then corrects the texture-matrices in the fixed-function pipeline.
For shader materials it's left to the users to handle those UV-flips for the texture-matrix. For shader materials it's left to the users to handle those UV-flips for the texture-matrix.
Render target textures (RTT's) in OpenGL are rendered with left-bottom origin and Irrlicht can't change that, so all RTT textures Render target textures (RTT's) in OpenGL are rendered with left-bottom origin and Irrlicht can't change that, so all RTT textures
in memory are upside-down (unlike all other Irrlicht textures). in memory are upside-down (compared to other Irrlicht textures).
In the fixed function pipeline Irrlicht handles this by flipping the RTT's texture matrix once more and for shaders it's again In the fixed function pipeline Irrlicht handles this by flipping the RTT's texture matrix once more and for shaders it's again
left to the users to handle it. left to the users to handle it.
Cubemap textures are different from other textures in OpenGL. Each cube side has left-top as the origin. So not flipping Irrlicht textures for those would be fine. Cubemap textures are different from other textures in OpenGL. Each cube side has left-top as the origin. So not flipping Irrlicht textures for those would be fine.
@ -325,7 +325,7 @@ private:
So... the following 2 defines are two different workarounds I found. Both are ugly, which one is better in reality depends probably on the scene. So... the following 2 defines are two different workarounds I found. Both are ugly, which one is better in reality depends probably on the scene.
Only use one of those: Only use one of those:
CUBEMAP_UPSIDE_DOWN_GL_PROJECTION is relatively fast as it just changes the project matrix. The problem is that changing the projection matrix CUBEMAP_UPSIDE_DOWN_GL_PROJECTION is relatively fast as it just changes the projection matrix. The problem is that changing the projection matrix
means changing front/backside culling. So every node rendered has to flip the material flags for those. means changing front/backside culling. So every node rendered has to flip the material flags for those.
CUBEMAP_USPIDE_DOWN_RTT will change the texture memory itself and flip the image upside-down. CUBEMAP_USPIDE_DOWN_RTT will change the texture memory itself and flip the image upside-down.
@ -591,7 +591,7 @@ int main()
} }
/* Add some background which will show up in the environment maps. /* Add some background which will show up in the environment maps.
For first one we use the same textures as used in the spheres. For the first background we use the same textures as used in the spheres.
Note the difference between a skybox and a cubemap is that the skybox really uses 6 different Note the difference between a skybox and a cubemap is that the skybox really uses 6 different
textures. While the cubemap uses a single texture created from 6 images. */ textures. While the cubemap uses a single texture created from 6 images. */
eventReceiver.BackgroundSkybox = smgr->addSkyBoxSceneNode( eventReceiver.BackgroundSkybox = smgr->addSkyBoxSceneNode(
@ -639,7 +639,7 @@ int main()
#endif #endif
/* /*
Add some moving node to show the difference between static/dynamic environment maps Add a moving node to show the difference between static/dynamic environment maps
*/ */
scene::IMeshSceneNode * movingNode = smgr->addCubeSceneNode(30.f); scene::IMeshSceneNode * movingNode = smgr->addCubeSceneNode(30.f);
movingNode->getMaterial(0).Lighting = false; movingNode->getMaterial(0).Lighting = false;
@ -692,7 +692,7 @@ int main()
driver->beginScene(true, true, video::SColor(255, 127, 127, 255)); driver->beginScene(true, true, video::SColor(255, 127, 127, 255));
/* Check if we want to update the environment maps. /* Check if we want to update the environment maps.
Usually not something you'll do every frame, but either once at the star Usually not something you'll do every frame, but either once at the start
or maybe updating an environment map once in a while. or maybe updating an environment map once in a while.
*/ */
int updateCubemaps = eventReceiver.checkCubemapUpdate(); int updateCubemaps = eventReceiver.checkCubemapUpdate();
@ -704,7 +704,7 @@ int main()
{ {
/* /*
Flipping projection matrix flips front/backface culling. Flipping projection matrix flips front/backface culling.
We only have a skybox so in this case this still would be fast, with more objects it's getting more ugly. We only have a skybox so in this case it's fast, with more objects it's getting more ugly.
*/ */
smgr->getSceneNodesFromType(scene::ESNT_ANY, allNodes); smgr->getSceneNodesFromType(scene::ESNT_ANY, allNodes);
flipCullingFlags(allNodes); flipCullingFlags(allNodes);

View File

@ -176,6 +176,17 @@ namespace scene
return Vertices[i].TCoords; return Vertices[i].TCoords;
} }
//! returns color of vertex i
virtual video::SColor& getColor(u32 i) IRR_OVERRIDE
{
return Vertices[i].Color;
}
//! returns color of vertex i
virtual const video::SColor& getColor(u32 i) const IRR_OVERRIDE
{
return Vertices[i].Color;
}
//! Append the vertices and indices to the current buffer //! Append the vertices and indices to the current buffer
/** Only works for compatible types, i.e. either the same type /** Only works for compatible types, i.e. either the same type

View File

@ -121,19 +121,23 @@ namespace scene
virtual f32 getFOV() const =0; virtual f32 getFOV() const =0;
//! Sets the value of the near clipping plane. (default: 1.0f) //! Sets the value of the near clipping plane. (default: 1.0f)
/** \param zn: New z near value. */ /** Also changes projection matrix and resets IsOrthogonal flag.
\param zn: New z near value. */
virtual void setNearValue(f32 zn) =0; virtual void setNearValue(f32 zn) =0;
//! Sets the value of the far clipping plane (default: 2000.0f) //! Sets the value of the far clipping plane (default: 2000.0f)
/** \param zf: New z far value. */ /** Also changes projection matrix and resets IsOrthogonal flag.
\param zf: New z far value. */
virtual void setFarValue(f32 zf) =0; virtual void setFarValue(f32 zf) =0;
//! Sets the aspect ratio (default: 4.0f / 3.0f) //! Sets the aspect ratio (default: 4.0f / 3.0f)
/** \param aspect: New aspect ratio. */ /** Also changes projection matrix and resets IsOrthogonal flag.
\param aspect: New aspect ratio. */
virtual void setAspectRatio(f32 aspect) =0; virtual void setAspectRatio(f32 aspect) =0;
//! Sets the field of view (Default: PI / 2.5f) //! Sets the field of view (Default: PI / 2.5f)
/** \param fovy: New field of view in radians. */ /** Also changes projection matrix and resets IsOrthogonal flag.
\param fovy: New field of view in radians. */
virtual void setFOV(f32 fovy) =0; virtual void setFOV(f32 fovy) =0;
//! Get the view frustum. //! Get the view frustum.
@ -165,7 +169,10 @@ namespace scene
@see getTargetAndRotationBinding() */ @see getTargetAndRotationBinding() */
virtual void bindTargetAndRotation(bool bound) =0; virtual void bindTargetAndRotation(bool bound) =0;
//! Updates the matrices without uploading them to the driver //! Updates the view matrix and frustum without uploading the matrix to the driver.
/** You need this when you want an up-to-date camera view matrix & frustum before the render() call.
Usually you should call updateAbsolutePosition() before calling this.
Despite it's function name, the projection matrix is not touched. */
virtual void updateMatrices() = 0; virtual void updateMatrices() = 0;
//! Queries if the camera scene node's rotation and its target position are bound together. //! Queries if the camera scene node's rotation and its target position are bound together.

View File

@ -166,6 +166,18 @@ namespace scene
{ {
return getVertexBuffer()[i].Normal; return getVertexBuffer()[i].Normal;
} }
//! returns color of vertex i
virtual video::SColor& getColor(u32 i) IRR_OVERRIDE
{
return getVertexBuffer()[i].Color;
}
//! returns color of vertex i
virtual const video::SColor& getColor(u32 i) const IRR_OVERRIDE
{
return getVertexBuffer()[i].Color;
}
}; };

View File

@ -22,7 +22,10 @@ namespace scene
before or after each scene node is rendered. It is assumed that the before or after each scene node is rendered. It is assumed that the
ILightManager implementation will store any data that it wishes to ILightManager implementation will store any data that it wishes to
retain, i.e. the ISceneManager to which it is assigned, the lightList, retain, i.e. the ISceneManager to which it is assigned, the lightList,
the current render pass, and the current scene node. */ the current render pass, and the current scene node.
It can also be useful for shaders as it allows finding out the currently rendered SceneNode.
*/
class ILightManager : public IReferenceCounted class ILightManager : public IReferenceCounted
{ {
public: public:
@ -35,27 +38,27 @@ namespace scene
the light manager may modify. This reference will remain valid the light manager may modify. This reference will remain valid
until OnPostRender(). until OnPostRender().
*/ */
virtual void OnPreRender(core::array<ISceneNode*> & lightList) = 0; virtual void OnPreRender(core::array<ISceneNode*> & lightList) {};
//! Called after the last scene node is rendered. //! Called after the last scene node is rendered.
/** After this call returns, the lightList passed to OnPreRender() becomes invalid. */ /** After this call returns, the lightList passed to OnPreRender() becomes invalid. */
virtual void OnPostRender(void) = 0; virtual void OnPostRender(void) {};
//! Called before a render pass begins //! Called before a render pass begins
/** \param renderPass: the render pass that's about to begin */ /** \param renderPass: the render pass that's about to begin */
virtual void OnRenderPassPreRender(E_SCENE_NODE_RENDER_PASS renderPass) = 0; virtual void OnRenderPassPreRender(E_SCENE_NODE_RENDER_PASS renderPass) {};
//! Called after the render pass specified in OnRenderPassPreRender() ends //! Called after the render pass specified in OnRenderPassPreRender() ends
/** \param[in] renderPass: the render pass that has finished */ /** \param[in] renderPass: the render pass that has finished */
virtual void OnRenderPassPostRender(E_SCENE_NODE_RENDER_PASS renderPass) = 0; virtual void OnRenderPassPostRender(E_SCENE_NODE_RENDER_PASS renderPass) {};
//! Called before the given scene node is rendered //! Called before the given scene node is rendered
/** \param[in] node: the scene node that's about to be rendered */ /** \param[in] node: the scene node that's about to be rendered */
virtual void OnNodePreRender(ISceneNode* node) = 0; virtual void OnNodePreRender(ISceneNode* node) {};
//! Called after the the node specified in OnNodePreRender() has been rendered //! Called after the the node specified in OnNodePreRender() has been rendered
/** \param[in] node: the scene node that has just been rendered */ /** \param[in] node: the scene node that has just been rendered */
virtual void OnNodePostRender(ISceneNode* node) = 0; virtual void OnNodePostRender(ISceneNode* node) {};
}; };
} // end namespace scene } // end namespace scene
} // end namespace irr } // end namespace irr

View File

@ -119,6 +119,12 @@ namespace scene
//! returns texture coord of vertex i //! returns texture coord of vertex i
virtual core::vector2df& getTCoords(u32 i) = 0; virtual core::vector2df& getTCoords(u32 i) = 0;
//! returns color of vertex i
virtual video::SColor& getColor(u32 i) = 0;
//! returns color of vertex i
virtual const video::SColor& getColor(u32 i) const = 0;
//! Append the vertices and indices to the current buffer //! Append the vertices and indices to the current buffer
/** Only works for compatible vertex types /** Only works for compatible vertex types
and not implemented for most buffers for now. and not implemented for most buffers for now.

View File

@ -103,7 +103,9 @@ namespace scene
bool angleWeighted=false) const=0; bool angleWeighted=false) const=0;
//! Scales the actual mesh, not a scene node. //! Scales the actual mesh, not a scene node.
/** \param mesh Mesh on which the operation is performed. /** Note: When your scale are not uniform then
prefer the transform function to have correct normals.
\param mesh Mesh on which the operation is performed.
\param factor Scale factor for each axis. */ \param factor Scale factor for each axis. */
void scale(IMesh* mesh, const core::vector3df& factor) const void scale(IMesh* mesh, const core::vector3df& factor) const
{ {
@ -111,7 +113,9 @@ namespace scene
} }
//! Scales the actual meshbuffer, not a scene node. //! Scales the actual meshbuffer, not a scene node.
/** \param buffer Meshbuffer on which the operation is performed. /** Note: When your scale are not uniform then
prefer the transform function to have correct normals.
\param buffer Meshbuffer on which the operation is performed.
\param factor Scale factor for each axis. */ \param factor Scale factor for each axis. */
void scale(IMeshBuffer* buffer, const core::vector3df& factor) const void scale(IMeshBuffer* buffer, const core::vector3df& factor) const
{ {
@ -146,9 +150,12 @@ namespace scene
/** \param mesh Mesh on which the operation is performed. /** \param mesh Mesh on which the operation is performed.
\param m transformation matrix. \param m transformation matrix.
\param normalsUpdate When 0 - don't update normals. \param normalsUpdate When 0 - don't update normals.
When 1 - update normals with inverse transposed of the transformation matrix When 1 - update normals with inner 3x3 matrix of the inverse transposed of the transformation matrix
should be set when the matrix has rotation or non-uniform scaling
\param normalizeNormals When true it normalizes all normals again.
Recommended to set this when normalsUpdate is 1 and there is any scaling
*/ */
void transform(IMesh* mesh, const core::matrix4& m, u32 normalsUpdate = 0) const void transform(IMesh* mesh, const core::matrix4& m, u32 normalsUpdate = 0, bool normalizeNormals=false) const
{ {
apply(SVertexPositionTransformManipulator(m), mesh, true); apply(SVertexPositionTransformManipulator(m), mesh, true);
@ -158,18 +165,25 @@ namespace scene
if ( m.getInverse(invT) ) if ( m.getInverse(invT) )
{ {
invT = invT.getTransposed(); invT = invT.getTransposed();
apply(SVertexNormalTransformManipulator(invT), mesh, false); apply(SVertexNormalRotateScaleManipulator(invT), mesh, false);
} }
} }
if ( normalizeNormals )
{
apply(SVertexNormalizeNormalManipulator(), mesh, false);
}
} }
//! Applies a transformation to a meshbuffer //! Applies a transformation to a meshbuffer
/** \param buffer Meshbuffer on which the operation is performed. /** \param buffer Meshbuffer on which the operation is performed.
\param m transformation matrix. \param m transformation matrix.
\param normalsUpdate When 0 - don't update normals. \param normalsUpdate When 0 - don't update normals.
When 1 - update normals with inverse transposed of the transformation matrix When 1 - update normals with inner 3x3 matrix of the inverse transposed of the transformation matrix
should be set when the matrix has rotation or non-uniform scaling
\param normalizeNormals When true it normalizes all normals again.
Recommended to set this when normalsUpdate is 1 and there is any scaling
*/ */
void transform(IMeshBuffer* buffer, const core::matrix4& m, u32 normalsUpdate = 0) const void transform(IMeshBuffer* buffer, const core::matrix4& m, u32 normalsUpdate = 0, bool normalizeNormals=false) const
{ {
apply(SVertexPositionTransformManipulator(m), buffer, true); apply(SVertexPositionTransformManipulator(m), buffer, true);
@ -179,9 +193,13 @@ namespace scene
if ( m.getInverse(invT) ) if ( m.getInverse(invT) )
{ {
invT = invT.getTransposed(); invT = invT.getTransposed();
apply(SVertexNormalTransformManipulator(invT), buffer, false); apply(SVertexNormalRotateScaleManipulator(invT), buffer, false);
} }
} }
if ( normalizeNormals )
{
apply(SVertexNormalizeNormalManipulator(), buffer, false);
}
} }
//! Applies a transformation to a mesh //! Applies a transformation to a mesh
@ -239,6 +257,7 @@ namespace scene
/** This is useful if you want to draw tangent space normal /** This is useful if you want to draw tangent space normal
mapped geometry because it calculates the tangent and binormal mapped geometry because it calculates the tangent and binormal
data which is needed there. data which is needed there.
Note: Only 16-bit meshbuffers supported so far
\param mesh Input mesh \param mesh Input mesh
\param recalculateNormals The normals are recalculated if set, \param recalculateNormals The normals are recalculated if set,
otherwise the original ones are kept. Note that keeping the otherwise the original ones are kept. Note that keeping the
@ -257,7 +276,8 @@ namespace scene
bool angleWeighted=false, bool recalculateTangents=true) const=0; bool angleWeighted=false, bool recalculateTangents=true) const=0;
//! Creates a copy of the mesh, which will only consist of S3DVertex2TCoord vertices. //! Creates a copy of the mesh, which will only consist of S3DVertex2TCoord vertices.
/** \param mesh Input mesh /** Note: Only 16-bit meshbuffers supported so far
\param mesh Input mesh
\return Mesh consisting only of S3DVertex2TCoord vertices. If \return Mesh consisting only of S3DVertex2TCoord vertices. If
you no longer need the cloned mesh, you should call you no longer need the cloned mesh, you should call
IMesh::drop(). See IReferenceCounted::drop() for more IMesh::drop(). See IReferenceCounted::drop() for more
@ -265,7 +285,8 @@ namespace scene
virtual IMesh* createMeshWith2TCoords(IMesh* mesh) const = 0; virtual IMesh* createMeshWith2TCoords(IMesh* mesh) const = 0;
//! Creates a copy of the mesh, which will only consist of S3DVertex vertices. //! Creates a copy of the mesh, which will only consist of S3DVertex vertices.
/** \param mesh Input mesh /** Note: Only 16-bit meshbuffers supported so far
\param mesh Input mesh
\return Mesh consisting only of S3DVertex vertices. If \return Mesh consisting only of S3DVertex vertices. If
you no longer need the cloned mesh, you should call you no longer need the cloned mesh, you should call
IMesh::drop(). See IReferenceCounted::drop() for more IMesh::drop(). See IReferenceCounted::drop() for more
@ -273,7 +294,8 @@ namespace scene
virtual IMesh* createMeshWith1TCoords(IMesh* mesh) const = 0; virtual IMesh* createMeshWith1TCoords(IMesh* mesh) const = 0;
//! Creates a copy of a mesh with all vertices unwelded //! Creates a copy of a mesh with all vertices unwelded
/** \param mesh Input mesh /** Note: Only 16-bit meshbuffers supported so far
\param mesh Input mesh
\return Mesh consisting only of unique faces. All vertices \return Mesh consisting only of unique faces. All vertices
which were previously shared are now duplicated. If you no which were previously shared are now duplicated. If you no
longer need the cloned mesh, you should call IMesh::drop(). See longer need the cloned mesh, you should call IMesh::drop(). See
@ -281,7 +303,8 @@ namespace scene
virtual IMesh* createMeshUniquePrimitives(IMesh* mesh) const = 0; virtual IMesh* createMeshUniquePrimitives(IMesh* mesh) const = 0;
//! Creates a copy of a mesh with vertices welded //! Creates a copy of a mesh with vertices welded
/** \param mesh Input mesh /** Note: Only 16-bit meshbuffers supported so far, 32-bit buffer are cloned
\param mesh Input mesh
\param tolerance The threshold for vertex comparisons. \param tolerance The threshold for vertex comparisons.
\return Mesh without redundant vertices. If you no longer need \return Mesh without redundant vertices. If you no longer need
the cloned mesh, you should call IMesh::drop(). See the cloned mesh, you should call IMesh::drop(). See

View File

@ -171,6 +171,21 @@ namespace scene
return (*Vertices)[Indices[i]].TCoords; return (*Vertices)[Indices[i]].TCoords;
} }
//! returns color of vertex i
virtual video::SColor& getColor(u32 i) IRR_OVERRIDE
{
IRR_DEBUG_BREAK_IF(!Vertices);
return (*Vertices)[Indices[i]].Color;
}
//! returns color of vertex i
virtual const video::SColor& getColor(u32 i) const IRR_OVERRIDE
{
IRR_DEBUG_BREAK_IF(!Vertices);
return (*Vertices)[Indices[i]].Color;
}
//! append the vertices and indices to the current buffer //! append the vertices and indices to the current buffer
virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) IRR_OVERRIDE virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) IRR_OVERRIDE
{ {

View File

@ -326,6 +326,34 @@ struct SSkinMeshBuffer : public IMeshBuffer
} }
} }
//! returns color of vertex i
virtual video::SColor& getColor(u32 i) IRR_OVERRIDE
{
switch (VertexType)
{
case video::EVT_2TCOORDS:
return Vertices_2TCoords[i].Color;
case video::EVT_TANGENTS:
return Vertices_Tangents[i].Color;
default:
return Vertices_Standard[i].Color;
}
}
//! returns color of vertex i
virtual const video::SColor& getColor(u32 i) const IRR_OVERRIDE
{
switch (VertexType)
{
case video::EVT_2TCOORDS:
return Vertices_2TCoords[i].Color;
case video::EVT_TANGENTS:
return Vertices_Tangents[i].Color;
default:
return Vertices_Standard[i].Color;
}
}
//! append the vertices and indices to the current buffer //! append the vertices and indices to the current buffer
virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) IRR_OVERRIDE {} virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) IRR_OVERRIDE {}

View File

@ -277,6 +277,32 @@ namespace scene
core::matrix4 Transformation; core::matrix4 Transformation;
}; };
//! Vertex manipulator which transforms the normal of the vertex with the rotate/scale part of the given matrix (inner 3x3)
class SVertexNormalRotateScaleManipulator : public IVertexManipulator
{
public:
SVertexNormalRotateScaleManipulator(const core::matrix4& m) : Transformation(m) {}
template <typename VType>
void operator()(VType& vertex) const
{
Transformation.rotateVect(vertex.Normal);
}
private:
core::matrix4 Transformation;
};
//! Vertex manipulator which normalizes the normal of the vertex
class SVertexNormalizeNormalManipulator : public IVertexManipulator
{
public:
SVertexNormalizeNormalManipulator() {}
template <typename VType>
void operator()(VType& vertex) const
{
vertex.Normal.normalize();
}
};
//! Vertex manipulator which scales the TCoords of the vertex //! Vertex manipulator which scales the TCoords of the vertex
class SVertexTCoordsScaleManipulator : public IVertexManipulator class SVertexTCoordsScaleManipulator : public IVertexManipulator
{ {

View File

@ -947,13 +947,13 @@ public:
\param make_lower copy only lower case */ \param make_lower copy only lower case */
string<T> subString(u32 begin, s32 length, bool make_lower = false ) const string<T> subString(u32 begin, s32 length, bool make_lower = false ) const
{ {
// clamp length to maximal value
if ((length+begin) > size())
length = size()-begin;
// if start after string // if start after string
// or no proper substring length // or no proper substring length
if ((length <= 0) || (begin>=size())) if ((length <= 0) || (begin>=size()))
return string<T>(""); return string<T>("");
// clamp length to maximal value
if ((length+begin) > size())
length = size()-begin;
string<T> o; string<T> o;
o.reserve(length+1); o.reserve(length+1);

View File

@ -221,10 +221,10 @@ namespace core
//! Translate a vector by the inverse of the translation part of this matrix. //! Translate a vector by the inverse of the translation part of this matrix.
void inverseTranslateVect( vector3df& vect ) const; void inverseTranslateVect( vector3df& vect ) const;
//! Rotate a vector by the inverse of the rotation part of this matrix. //! Tranform (rotate/scale) a vector by the inverse of the rotation part this matrix
void inverseRotateVect( vector3df& vect ) const; void inverseRotateVect( vector3df& vect ) const;
//! Rotate a vector by the rotation part of this matrix. //! Transform (rotate/scale) a vector by the rotation part of this matrix.
void rotateVect( vector3df& vect ) const; void rotateVect( vector3df& vect ) const;
//! An alternate transform vector method, writing into a second vector //! An alternate transform vector method, writing into a second vector

View File

@ -28,16 +28,16 @@ CCameraSceneNode::CCameraSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 i
// set default projection // set default projection
Fovy = core::PI / 2.5f; // Field of view, in radians. Fovy = core::PI / 2.5f; // Field of view, in radians.
Aspect = 4.0f / 3.0f; // Aspect ratio.
const video::IVideoDriver* const d = mgr?mgr->getVideoDriver():0; const video::IVideoDriver* const d = mgr?mgr->getVideoDriver():0;
if (d) if (d)
{ {
if ( d->getCurrentRenderTargetSize().Height )
Aspect = (f32)d->getCurrentRenderTargetSize().Width / Aspect = (f32)d->getCurrentRenderTargetSize().Width /
(f32)d->getCurrentRenderTargetSize().Height; (f32)d->getCurrentRenderTargetSize().Height;
HasD3DStyleProjectionMatrix = d->getDriverType() != video::EDT_OPENGL; HasD3DStyleProjectionMatrix = d->getDriverType() != video::EDT_OPENGL;
} }
else
Aspect = 4.0f / 3.0f; // Aspect ratio.
ViewArea.setFarNearDistance(ZFar - ZNear); ViewArea.setFarNearDistance(ZFar - ZNear);
recalculateProjectionMatrix(); recalculateProjectionMatrix();
@ -252,6 +252,7 @@ void CCameraSceneNode::OnRegisterSceneNode()
//! render //! render
void CCameraSceneNode::render() void CCameraSceneNode::render()
{ {
updateAbsolutePosition(); // depending on that call in onAnimate is risky (might not be in SceneManager or it or it's parent might be invisible and still should render)
updateMatrices(); updateMatrices();
video::IVideoDriver* driver = SceneManager->getVideoDriver(); video::IVideoDriver* driver = SceneManager->getVideoDriver();

View File

@ -1827,7 +1827,7 @@ void CColladaMeshWriter::writeMeshGeometry(const irr::core::stringc& meshname, s
if ( buffer->getPrimitiveType() != EPT_TRIANGLES ) if ( buffer->getPrimitiveType() != EPT_TRIANGLES )
{ {
os::Printer::log("Collada writer does not support non-triangle meshbuffers. Mesh: ", meshname.c_str(), ELL_WARNING); os::Printer::log("Collada writer does not support non-triangle meshbuffers. Mesh", meshname.c_str(), ELL_WARNING);
continue; continue;
} }
@ -1865,12 +1865,16 @@ void CColladaMeshWriter::writeMeshGeometry(const irr::core::stringc& meshname, s
Writer->writeElement("p", false); Writer->writeElement("p", false);
const video::E_INDEX_TYPE iType = buffer->getIndexType();
const u16* idx16 = buffer->getIndices();
const u32* idx32 = (u32*)buffer->getIndices();
core::stringc strP; core::stringc strP;
strP.reserve(100); strP.reserve(100);
for (u32 p=0; p<polyCount; ++p) for (u32 p=0; p<polyCount; ++p)
{ {
// Irrlicht uses clockwise, Collada uses counter-clockwise to define front-face // Irrlicht uses clockwise, Collada uses counter-clockwise to define front-face
u32 irrIdx = buffer->getIndices()[(p*3) + 2]; u32 irrIdx = iType == video::EIT_16BIT ? idx16[p*3 + 2] : idx32[p*3 + 2];
strP = ""; strP = "";
strP += irrIdx + posIdx; strP += irrIdx + posIdx;
strP += " "; strP += " ";
@ -1884,7 +1888,7 @@ void CColladaMeshWriter::writeMeshGeometry(const irr::core::stringc& meshname, s
strP += " "; strP += " ";
} }
irrIdx = buffer->getIndices()[(p*3) + 1]; irrIdx = iType == video::EIT_16BIT ? idx16[p*3 + 1] : idx32[p*3 + 1];
strP += irrIdx + posIdx; strP += irrIdx + posIdx;
strP += " "; strP += " ";
strP += irrIdx + tCoordIdx; strP += irrIdx + tCoordIdx;
@ -1897,7 +1901,7 @@ void CColladaMeshWriter::writeMeshGeometry(const irr::core::stringc& meshname, s
strP += " "; strP += " ";
} }
irrIdx = buffer->getIndices()[(p*3) + 0]; irrIdx = iType == video::EIT_16BIT ? idx16[p*3] : idx32[p*3];
strP += irrIdx + posIdx; strP += irrIdx + posIdx;
strP += " "; strP += " ";
strP += irrIdx + tCoordIdx; strP += irrIdx + tCoordIdx;

View File

@ -3001,7 +3001,7 @@ bool CD3D9Driver::reset()
} }
else else
{ {
os::Printer::log("Resetting failed due to unknown reason.", core::stringc((int)hr).c_str(), ELL_WARNING); os::Printer::log("Resetting failed due to unknown reason", core::stringc((int)hr).c_str(), ELL_WARNING);
} }
return false; return false;
} }

View File

@ -339,7 +339,7 @@ bool CGUIContextMenu::OnEvent(const SEvent& event)
case EMIE_MOUSE_MOVED: case EMIE_MOUSE_MOVED:
if (Environment->hasFocus(this)) if (Environment->hasFocus(this))
highlight(core::position2d<s32>(event.MouseInput.X, event.MouseInput.Y), true); highlight(core::position2d<s32>(event.MouseInput.X, event.MouseInput.Y), true);
return true; break;
default: default:
break; break;
} }
@ -423,7 +423,7 @@ u32 CGUIContextMenu::sendClick(const core::position2d<s32>& p)
} }
//! returns true, if an element was highligted //! returns true, if an element was highlighted
bool CGUIContextMenu::highlight(const core::position2d<s32>& p, bool canOpenSubMenu) bool CGUIContextMenu::highlight(const core::position2d<s32>& p, bool canOpenSubMenu)
{ {
if (!isEnabled()) if (!isEnabled())

View File

@ -810,7 +810,7 @@ bool CGUIEnvironment::loadGUI(const io::path& filename, IGUIElement* parent)
io::IReadFile* read = FileSystem->createAndOpenFile(filename); io::IReadFile* read = FileSystem->createAndOpenFile(filename);
if (!read) if (!read)
{ {
os::Printer::log("Unable to open gui file", filename, ELL_ERROR); os::Printer::log("Unable to open GUI file", filename, ELL_ERROR);
return false; return false;
} }

View File

@ -137,7 +137,7 @@ bool CImageLoaderJPG::isALoadableFileFormat(io::IReadFile* file) const
IImage* CImageLoaderJPG::loadImage(io::IReadFile* file) const IImage* CImageLoaderJPG::loadImage(io::IReadFile* file) const
{ {
#ifndef _IRR_COMPILE_WITH_LIBJPEG_ #ifndef _IRR_COMPILE_WITH_LIBJPEG_
os::Printer::log("Can't load as not compiled with _IRR_COMPILE_WITH_LIBJPEG_:", file->getFileName(), ELL_DEBUG); os::Printer::log("Can't load as not compiled with _IRR_COMPILE_WITH_LIBJPEG_", file->getFileName(), ELL_DEBUG);
return 0; return 0;
#else #else

View File

@ -99,14 +99,14 @@ IImage* CImageLoaderPng::loadImage(io::IReadFile* file) const
// Read the first few bytes of the PNG file // Read the first few bytes of the PNG file
if( file->read(buffer, 8) != 8 ) if( file->read(buffer, 8) != 8 )
{ {
os::Printer::log("LOAD PNG: can't read file\n", file->getFileName(), ELL_ERROR); os::Printer::log("LOAD PNG: can't read file (filesize < 8)", file->getFileName(), ELL_ERROR);
return 0; return 0;
} }
// Check if it really is a PNG file // Check if it really is a PNG file
if( png_sig_cmp(buffer, 0, 8) ) if( png_sig_cmp(buffer, 0, 8) )
{ {
os::Printer::log("LOAD PNG: not really a png\n", file->getFileName(), ELL_ERROR); os::Printer::log("LOAD PNG: not really a png (wrong signature)", file->getFileName(), ELL_ERROR);
return 0; return 0;
} }
@ -115,7 +115,7 @@ IImage* CImageLoaderPng::loadImage(io::IReadFile* file) const
NULL, (png_error_ptr)png_cpexcept_error, (png_error_ptr)png_cpexcept_warn); NULL, (png_error_ptr)png_cpexcept_error, (png_error_ptr)png_cpexcept_warn);
if (!png_ptr) if (!png_ptr)
{ {
os::Printer::log("LOAD PNG: Internal PNG create read struct failure\n", file->getFileName(), ELL_ERROR); os::Printer::log("LOAD PNG: Internal PNG create read struct failure", file->getFileName(), ELL_ERROR);
return 0; return 0;
} }
@ -123,7 +123,7 @@ IImage* CImageLoaderPng::loadImage(io::IReadFile* file) const
png_infop info_ptr = png_create_info_struct(png_ptr); png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) if (!info_ptr)
{ {
os::Printer::log("LOAD PNG: Internal PNG create info struct failure\n", file->getFileName(), ELL_ERROR); os::Printer::log("LOAD PNG: Internal PNG create info struct failure", file->getFileName(), ELL_ERROR);
png_destroy_read_struct(&png_ptr, NULL, NULL); png_destroy_read_struct(&png_ptr, NULL, NULL);
return 0; return 0;
} }
@ -143,10 +143,10 @@ IImage* CImageLoaderPng::loadImage(io::IReadFile* file) const
png_read_info(png_ptr, info_ptr); // Read the info section of the png file png_read_info(png_ptr, info_ptr); // Read the info section of the png file
u32 Width; u32 Width=0;
u32 Height; u32 Height=0;
s32 BitDepth; s32 BitDepth=0;
s32 ColorType; s32 ColorType=0;
{ {
// Use temporary variables to avoid passing cast pointers // Use temporary variables to avoid passing cast pointers
png_uint_32 w,h; png_uint_32 w,h;
@ -158,9 +158,6 @@ IImage* CImageLoaderPng::loadImage(io::IReadFile* file) const
Height=h; Height=h;
} }
if (!IImage::checkDataSizeLimit((size_t)Width* Height * (BitDepth/8)))
png_cpexcept_error(png_ptr, "Image dimensions too large");
// Convert palette color to true color // Convert palette color to true color
if (ColorType==PNG_COLOR_TYPE_PALETTE) if (ColorType==PNG_COLOR_TYPE_PALETTE)
png_set_palette_to_rgb(png_ptr); png_set_palette_to_rgb(png_ptr);
@ -223,15 +220,16 @@ IImage* CImageLoaderPng::loadImage(io::IReadFile* file) const
#endif #endif
} }
ECOLOR_FORMAT colorFormat = ColorType==PNG_COLOR_TYPE_RGB_ALPHA ? ECF_A8R8G8B8 : ECF_R8G8B8;
if (!IImage::checkDataSizeLimit(IImage::getDataSizeFromFormat(colorFormat, Width, Height)))
png_cpexcept_error(png_ptr, "Image dimensions too large");
// Create the image structure to be filled by png data // Create the image structure to be filled by png data
video::IImage* image = 0; video::IImage* image = new CImage(colorFormat, core::dimension2du(Width, Height));
if (ColorType==PNG_COLOR_TYPE_RGB_ALPHA)
image = new CImage(ECF_A8R8G8B8, core::dimension2d<u32>(Width, Height));
else
image = new CImage(ECF_R8G8B8, core::dimension2d<u32>(Width, Height));
if (!image) if (!image)
{ {
os::Printer::log("LOAD PNG: Internal PNG create image struct failure\n", file->getFileName(), ELL_ERROR); os::Printer::log("LOAD PNG: Internal PNG create image struct failure", file->getFileName(), ELL_ERROR);
png_destroy_read_struct(&png_ptr, NULL, NULL); png_destroy_read_struct(&png_ptr, NULL, NULL);
return 0; return 0;
} }
@ -240,7 +238,7 @@ IImage* CImageLoaderPng::loadImage(io::IReadFile* file) const
RowPointers = new png_bytep[Height]; RowPointers = new png_bytep[Height];
if (!RowPointers) if (!RowPointers)
{ {
os::Printer::log("LOAD PNG: Internal PNG create row pointers failure\n", file->getFileName(), ELL_ERROR); os::Printer::log("LOAD PNG: Internal PNG create row pointers failure", file->getFileName(), ELL_ERROR);
png_destroy_read_struct(&png_ptr, NULL, NULL); png_destroy_read_struct(&png_ptr, NULL, NULL);
delete image; delete image;
return 0; return 0;

View File

@ -80,7 +80,7 @@ IImage* CImageLoaderPSD::loadImage(io::IReadFile* file) const
if (header.mode != 3 || header.depth != 8) if (header.mode != 3 || header.depth != 8)
{ {
os::Printer::log("Unsupported PSD color mode or depth.\n", file->getFileName(), ELL_ERROR); os::Printer::log("Unsupported PSD color mode or depth", file->getFileName(), ELL_ERROR);
return 0; return 0;
} }
@ -93,7 +93,7 @@ IImage* CImageLoaderPSD::loadImage(io::IReadFile* file) const
#endif #endif
if (!file->seek(l, true)) if (!file->seek(l, true))
{ {
os::Printer::log("Error seeking file pos to image resources.\n", file->getFileName(), ELL_ERROR); os::Printer::log("Error seeking file pos to image resources", file->getFileName(), ELL_ERROR);
return 0; return 0;
} }
@ -105,7 +105,7 @@ IImage* CImageLoaderPSD::loadImage(io::IReadFile* file) const
#endif #endif
if (!file->seek(l, true)) if (!file->seek(l, true))
{ {
os::Printer::log("Error seeking file pos to layer and mask.\n", file->getFileName(), ELL_ERROR); os::Printer::log("Error seeking file pos to layer and mask", file->getFileName(), ELL_ERROR);
return 0; return 0;
} }
@ -117,7 +117,7 @@ IImage* CImageLoaderPSD::loadImage(io::IReadFile* file) const
#endif #endif
if (!file->seek(l, true)) if (!file->seek(l, true))
{ {
os::Printer::log("Error seeking file pos to image data section.\n", file->getFileName(), ELL_ERROR); os::Printer::log("Error seeking file pos to image data section", file->getFileName(), ELL_ERROR);
return 0; return 0;
} }
@ -131,7 +131,7 @@ IImage* CImageLoaderPSD::loadImage(io::IReadFile* file) const
if (compressionType != 1 && compressionType != 0) if (compressionType != 1 && compressionType != 0)
{ {
os::Printer::log("Unsupported psd compression mode.\n", file->getFileName(), ELL_ERROR); os::Printer::log("Unsupported psd compression mode", file->getFileName(), ELL_ERROR);
return 0; return 0;
} }
@ -171,7 +171,7 @@ bool CImageLoaderPSD::readRawImageData(io::IReadFile* file, const PsdHeader& hea
{ {
if (!file->read(tmpData, sizeof(c8) * header.width * header.height)) if (!file->read(tmpData, sizeof(c8) * header.width * header.height))
{ {
os::Printer::log("Error reading color channel\n", file->getFileName(), ELL_ERROR); os::Printer::log("Error reading color channel", file->getFileName(), ELL_ERROR);
break; break;
} }
@ -247,7 +247,7 @@ bool CImageLoaderPSD::readRLEImageData(io::IReadFile* file, const PsdHeader& hea
{ {
delete [] tmpData; delete [] tmpData;
delete [] rleCount; delete [] rleCount;
os::Printer::log("Error reading rle rows\n", file->getFileName(), ELL_ERROR); os::Printer::log("Error reading rle rows", file->getFileName(), ELL_ERROR);
return false; return false;
} }
@ -263,7 +263,7 @@ bool CImageLoaderPSD::readRLEImageData(io::IReadFile* file, const PsdHeader& hea
delete [] rleCount; delete [] rleCount;
delete [] buf; delete [] buf;
delete [] tmpData; delete [] tmpData;
os::Printer::log("Error reading rle rows\n", file->getFileName(), ELL_ERROR); os::Printer::log("Error reading rle rows", file->getFileName(), ELL_ERROR);
return false; return false;
} }

View File

@ -108,7 +108,7 @@ IImage* CImageLoaderTGA::loadImage(io::IReadFile* file) const
if (!IImage::checkDataSizeLimit((size_t)header.ImageWidth* header.ImageHeight * (header.PixelDepth/8))) if (!IImage::checkDataSizeLimit((size_t)header.ImageWidth* header.ImageHeight * (header.PixelDepth/8)))
{ {
os::Printer::log("Image dimensions too large in file.", file->getFileName(), ELL_ERROR); os::Printer::log("Image dimensions too large in file", file->getFileName(), ELL_ERROR);
return 0; return 0;
} }

View File

@ -84,7 +84,7 @@ bool CImageWriterPNG::writeImage(io::IWriteFile* file, IImage* image,u32 param)
NULL, (png_error_ptr)png_cpexcept_error, (png_error_ptr)png_cpexcept_warning); NULL, (png_error_ptr)png_cpexcept_error, (png_error_ptr)png_cpexcept_warning);
if (!png_ptr) if (!png_ptr)
{ {
os::Printer::log("PNGWriter: Internal PNG create write struct failure\n", file->getFileName(), ELL_ERROR); os::Printer::log("PNGWriter: Internal PNG create write struct failure", file->getFileName(), ELL_ERROR);
return false; return false;
} }
@ -92,7 +92,7 @@ bool CImageWriterPNG::writeImage(io::IWriteFile* file, IImage* image,u32 param)
png_infop info_ptr = png_create_info_struct(png_ptr); png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) if (!info_ptr)
{ {
os::Printer::log("PNGWriter: Internal PNG create info struct failure\n", file->getFileName(), ELL_ERROR); os::Printer::log("PNGWriter: Internal PNG create info struct failure", file->getFileName(), ELL_ERROR);
png_destroy_write_struct(&png_ptr, NULL); png_destroy_write_struct(&png_ptr, NULL);
return false; return false;
} }
@ -141,7 +141,7 @@ bool CImageWriterPNG::writeImage(io::IWriteFile* file, IImage* image,u32 param)
u8* tmpImage = new u8[image->getDimension().Height*lineWidth]; u8* tmpImage = new u8[image->getDimension().Height*lineWidth];
if (!tmpImage) if (!tmpImage)
{ {
os::Printer::log("PNGWriter: Internal PNG create image failure\n", file->getFileName(), ELL_ERROR); os::Printer::log("PNGWriter: Internal PNG create image failure", file->getFileName(), ELL_ERROR);
png_destroy_write_struct(&png_ptr, &info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr);
return false; return false;
} }
@ -175,7 +175,7 @@ bool CImageWriterPNG::writeImage(io::IWriteFile* file, IImage* image,u32 param)
u8** RowPointers = new png_bytep[image->getDimension().Height]; u8** RowPointers = new png_bytep[image->getDimension().Height];
if (!RowPointers) if (!RowPointers)
{ {
os::Printer::log("PNGWriter: Internal PNG create row pointers failure\n", file->getFileName(), ELL_ERROR); os::Printer::log("PNGWriter: Internal PNG create row pointers failure", file->getFileName(), ELL_ERROR);
png_destroy_write_struct(&png_ptr, &info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr);
delete [] tmpImage; delete [] tmpImage;
return false; return false;

View File

@ -306,8 +306,8 @@ bool CIrrDeviceLinux::switchToFullscreen(bool reset)
if (bestMode != -1) if (bestMode != -1)
{ {
os::Printer::log("Starting vidmode fullscreen mode...", ELL_INFORMATION); os::Printer::log("Starting vidmode fullscreen mode...", ELL_INFORMATION);
os::Printer::log("hdisplay: ", core::stringc(modes[bestMode]->hdisplay).c_str(), ELL_INFORMATION); os::Printer::log("hdisplay", core::stringc(modes[bestMode]->hdisplay).c_str(), ELL_INFORMATION);
os::Printer::log("vdisplay: ", core::stringc(modes[bestMode]->vdisplay).c_str(), ELL_INFORMATION); os::Printer::log("vdisplay", core::stringc(modes[bestMode]->vdisplay).c_str(), ELL_INFORMATION);
XF86VidModeSwitchToMode(XDisplay, Screennr, modes[bestMode]); XF86VidModeSwitchToMode(XDisplay, Screennr, modes[bestMode]);
XF86VidModeSetViewPort(XDisplay, Screennr, 0, 0); XF86VidModeSetViewPort(XDisplay, Screennr, 0, 0);
@ -343,8 +343,8 @@ bool CIrrDeviceLinux::switchToFullscreen(bool reset)
if (bestMode != -1) if (bestMode != -1)
{ {
os::Printer::log("Starting randr fullscreen mode...", ELL_INFORMATION); os::Printer::log("Starting randr fullscreen mode...", ELL_INFORMATION);
os::Printer::log("width: ", core::stringc(modes[bestMode].width).c_str(), ELL_INFORMATION); os::Printer::log("width", core::stringc(modes[bestMode].width).c_str(), ELL_INFORMATION);
os::Printer::log("height: ", core::stringc(modes[bestMode].height).c_str(), ELL_INFORMATION); os::Printer::log("height", core::stringc(modes[bestMode].height).c_str(), ELL_INFORMATION);
XRRSetScreenConfig(XDisplay,config,DefaultRootWindow(XDisplay),bestMode,OldRandrRotation,CurrentTime); XRRSetScreenConfig(XDisplay,config,DefaultRootWindow(XDisplay),bestMode,OldRandrRotation,CurrentTime);
UseXRandR=true; UseXRandR=true;
@ -367,26 +367,26 @@ void IrrPrintXGrabError(int grabResult, const c8 * grabCommand )
{ {
if ( grabResult == GrabSuccess ) if ( grabResult == GrabSuccess )
{ {
// os::Printer::log(grabCommand, ": GrabSuccess", ELL_INFORMATION); // os::Printer::log(grabCommand, "GrabSuccess", ELL_INFORMATION);
return; return;
} }
switch ( grabResult ) switch ( grabResult )
{ {
case AlreadyGrabbed: case AlreadyGrabbed:
os::Printer::log(grabCommand, ": AlreadyGrabbed", ELL_WARNING); os::Printer::log(grabCommand, "AlreadyGrabbed", ELL_WARNING);
break; break;
case GrabNotViewable: case GrabNotViewable:
os::Printer::log(grabCommand, ": GrabNotViewable", ELL_WARNING); os::Printer::log(grabCommand, "GrabNotViewable", ELL_WARNING);
break; break;
case GrabFrozen: case GrabFrozen:
os::Printer::log(grabCommand, ": GrabFrozen", ELL_WARNING); os::Printer::log(grabCommand, "GrabFrozen", ELL_WARNING);
break; break;
case GrabInvalidTime: case GrabInvalidTime:
os::Printer::log(grabCommand, ": GrabInvalidTime", ELL_WARNING); os::Printer::log(grabCommand, "GrabInvalidTime", ELL_WARNING);
break; break;
default: default:
os::Printer::log(grabCommand, ": grab failed with unknown problem", ELL_WARNING); os::Printer::log(grabCommand, "grab failed with unknown problem", ELL_WARNING);
break; break;
} }
} }
@ -455,7 +455,7 @@ bool CIrrDeviceLinux::createWindow()
} }
#ifdef _DEBUG #ifdef _DEBUG
else else
os::Printer::log("Visual chosen: ", core::stringc(static_cast<u32>(VisualInfo->visualid)).c_str(), ELL_DEBUG); os::Printer::log("Visual chosen", core::stringc(static_cast<u32>(VisualInfo->visualid)).c_str(), ELL_DEBUG);
#endif #endif
// create color map // create color map
@ -1993,7 +1993,7 @@ Bool PredicateIsEventType(Display *display, XEvent *event, XPointer arg)
{ {
if ( event && event->type == *(int*)arg ) if ( event && event->type == *(int*)arg )
{ {
// os::Printer::log("remove event:", core::stringc((int)arg).c_str(), ELL_INFORMATION); // os::Printer::log("remove event", core::stringc((int)arg).c_str(), ELL_INFORMATION);
return True; return True;
} }
return False; return False;

View File

@ -203,7 +203,7 @@ CIrrDeviceSDL::CIrrDeviceSDL(const SIrrlichtCreationParameters& param)
#endif #endif
SDL_INIT_NOPARACHUTE ) < 0) SDL_INIT_NOPARACHUTE ) < 0)
{ {
os::Printer::log( "Unable to initialize SDL!", SDL_GetError()); os::Printer::log("Unable to initialize SDL!", SDL_GetError());
Close = true; Close = true;
} }
else else
@ -429,7 +429,7 @@ bool CIrrDeviceSDL::createWindow()
} }
if ( !Screen ) if ( !Screen )
{ {
os::Printer::log( "Could not initialize display!" ); os::Printer::log("Could not initialize display!" );
return false; return false;
} }
@ -618,7 +618,7 @@ bool CIrrDeviceSDL::run()
else else
{ {
irrevent.MouseInput.Event = irr::EMIE_RMOUSE_LEFT_UP; irrevent.MouseInput.Event = irr::EMIE_RMOUSE_LEFT_UP;
MouseButtonStates &= !irr::EMBSM_RIGHT; MouseButtonStates &= ~irr::EMBSM_RIGHT;
} }
break; break;
@ -631,7 +631,7 @@ bool CIrrDeviceSDL::run()
else else
{ {
irrevent.MouseInput.Event = irr::EMIE_MMOUSE_LEFT_UP; irrevent.MouseInput.Event = irr::EMIE_MMOUSE_LEFT_UP;
MouseButtonStates &= !irr::EMBSM_MIDDLE; MouseButtonStates &= ~irr::EMBSM_MIDDLE;
} }
break; break;

View File

@ -153,6 +153,8 @@ namespace irr
virtual void setPosition(s32 x, s32 y) IRR_OVERRIDE virtual void setPosition(s32 x, s32 y) IRR_OVERRIDE
{ {
SDL_WarpMouse( x, y ); SDL_WarpMouse( x, y );
CursorPos.X = x;
CursorPos.Y = y;
} }
//! Returns the current position of the mouse cursor. //! Returns the current position of the mouse cursor.
@ -200,15 +202,6 @@ namespace irr
#else #else
CursorPos.X = Device->MouseX; CursorPos.X = Device->MouseX;
CursorPos.Y = Device->MouseY; CursorPos.Y = Device->MouseY;
if (CursorPos.X < 0)
CursorPos.X = 0;
if (CursorPos.X > (s32)Device->Width)
CursorPos.X = Device->Width;
if (CursorPos.Y < 0)
CursorPos.Y = 0;
if (CursorPos.Y > (s32)Device->Height)
CursorPos.Y = Device->Height;
#endif #endif
} }

View File

@ -458,7 +458,7 @@ void CIrrMeshFileLoader::skipSection(io::IXMLReader* reader, bool reportSkipping
{ {
#ifdef _DEBUG #ifdef _DEBUG
if (reportSkipping) if (reportSkipping)
os::Printer::log("irrMesh unknown element:", core::stringc(reader->getNodeName()).c_str()); os::Printer::log("irrMesh unknown element", core::stringc(reader->getNodeName()).c_str());
#endif #endif
++tagCounter; ++tagCounter;

View File

@ -1945,7 +1945,7 @@ void CLWOMeshFileLoader::readMat(u32 size)
default: default:
{ {
#ifdef LWO_READER_DEBUG #ifdef LWO_READER_DEBUG
os::Printer::log("LWO loader: skipping ", core::stringc((char*)&uiType, 4)); os::Printer::log("LWO loader: skipping", core::stringc((char*)&uiType, 4));
#endif #endif
File->seek(subsize, true); File->seek(subsize, true);
size -= subsize; size -= subsize;

View File

@ -199,7 +199,7 @@ bool CMD2MeshFileLoader::loadFile(io::IReadFile* file, CAnimatedMeshMD2* mesh)
if (!file->read(textureCoords, sizeof(SMD2TextureCoordinate)*header.numTexcoords)) if (!file->read(textureCoords, sizeof(SMD2TextureCoordinate)*header.numTexcoords))
{ {
delete[] textureCoords; delete[] textureCoords;
os::Printer::log("MD2 Loader: Error reading TextureCoords.", file->getFileName(), ELL_ERROR); os::Printer::log("MD2 Loader: Error reading TextureCoords", file->getFileName(), ELL_ERROR);
return false; return false;
} }
@ -221,7 +221,7 @@ bool CMD2MeshFileLoader::loadFile(io::IReadFile* file, CAnimatedMeshMD2* mesh)
delete[] triangles; delete[] triangles;
delete[] textureCoords; delete[] textureCoords;
os::Printer::log("MD2 Loader: Error reading triangles.", file->getFileName(), ELL_ERROR); os::Printer::log("MD2 Loader: Error reading triangles", file->getFileName(), ELL_ERROR);
return false; return false;
} }

View File

@ -242,7 +242,7 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
if (pPtr + ((sizeof(MS3DVertex) - MS3DVERTEX_NUM_PAD_BYTES) * numVertices) > buffer+fileSize) if (pPtr + ((sizeof(MS3DVertex) - MS3DVERTEX_NUM_PAD_BYTES) * numVertices) > buffer+fileSize)
{ {
delete [] buffer; delete [] buffer;
os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); os::Printer::log("Loading failed. Corrupted data found", file->getFileName(), ELL_ERROR);
return false; return false;
} }
for (u16 tmp=0; tmp<numVertices; ++tmp) for (u16 tmp=0; tmp<numVertices; ++tmp)
@ -273,7 +273,7 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
if (pPtr + ((sizeof(MS3DTriangle) - MS3DTRIANGLE_NUM_PAD_BYTES) * numTriangles) > buffer+fileSize) if (pPtr + ((sizeof(MS3DTriangle) - MS3DTRIANGLE_NUM_PAD_BYTES) * numTriangles) > buffer+fileSize)
{ {
delete [] buffer; delete [] buffer;
os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); os::Printer::log("Loading failed. Corrupted data found", file->getFileName(), ELL_ERROR);
return false; return false;
} }
for (u16 tmp=0; tmp<numTriangles; ++tmp) for (u16 tmp=0; tmp<numTriangles; ++tmp)
@ -349,7 +349,7 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
if (pPtr > buffer+fileSize) if (pPtr > buffer+fileSize)
{ {
delete [] buffer; delete [] buffer;
os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); os::Printer::log("Loading failed. Corrupted data found", file->getFileName(), ELL_ERROR);
return false; return false;
} }
} }
@ -390,7 +390,7 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
if (pPtr > buffer+fileSize) if (pPtr > buffer+fileSize)
{ {
delete [] buffer; delete [] buffer;
os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); os::Printer::log("Loading failed. Corrupted data found", file->getFileName(), ELL_ERROR);
return false; return false;
} }
@ -452,7 +452,7 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
if (pPtr > buffer+fileSize) if (pPtr > buffer+fileSize)
{ {
delete [] buffer; delete [] buffer;
os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); os::Printer::log("Loading failed. Corrupted data found", file->getFileName(), ELL_ERROR);
return false; return false;
} }
@ -479,7 +479,7 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
if (pPtr > buffer+fileSize) if (pPtr > buffer+fileSize)
{ {
delete [] buffer; delete [] buffer;
os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); os::Printer::log("Loading failed. Corrupted data found", file->getFileName(), ELL_ERROR);
return false; return false;
} }
@ -529,7 +529,7 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
if (pPtr > buffer+fileSize) if (pPtr > buffer+fileSize)
{ {
delete [] buffer; delete [] buffer;
os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); os::Printer::log("Loading failed. Corrupted data found", file->getFileName(), ELL_ERROR);
return false; return false;
} }
@ -569,7 +569,7 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
if (pPtr > buffer+fileSize) if (pPtr > buffer+fileSize)
{ {
delete [] buffer; delete [] buffer;
os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); os::Printer::log("Loading failed. Corrupted data found", file->getFileName(), ELL_ERROR);
return false; return false;
} }
@ -625,7 +625,7 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
if (pPtr > buffer+fileSize) if (pPtr > buffer+fileSize)
{ {
delete [] buffer; delete [] buffer;
os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); os::Printer::log("Loading failed. Corrupted data found", file->getFileName(), ELL_ERROR);
return false; return false;
} }
} }
@ -657,7 +657,7 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
if (pPtr > buffer+fileSize) if (pPtr > buffer+fileSize)
{ {
delete [] buffer; delete [] buffer;
os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); os::Printer::log("Loading failed. Corrupted data found", file->getFileName(), ELL_ERROR);
return false; return false;
} }
} }

View File

@ -708,38 +708,45 @@ IMesh* CMeshManipulator::createMeshUniquePrimitives(IMesh* mesh) const
// not yet 32bit // not yet 32bit
IMesh* CMeshManipulator::createMeshWelded(IMesh *mesh, f32 tolerance) const IMesh* CMeshManipulator::createMeshWelded(IMesh *mesh, f32 tolerance) const
{ {
SMesh* clone = new SMesh(); SMesh* meshClone = new SMesh();
clone->BoundingBox = mesh->getBoundingBox(); meshClone->BoundingBox = mesh->getBoundingBox();
core::array<u16> redirects; core::array<u16> redirects;
for (u32 b=0; b<mesh->getMeshBufferCount(); ++b) for (u32 b=0; b<mesh->getMeshBufferCount(); ++b)
{ {
const IMeshBuffer* const mb = mesh->getMeshBuffer(b); const IMeshBuffer* const mb = mesh->getMeshBuffer(b);
const u32 vertexCount = mb->getVertexCount();
// reset redirect list // reset redirect list
redirects.set_used(mb->getVertexCount()); redirects.set_used(vertexCount);
const u16* indices = 0; const video::E_INDEX_TYPE indexType = mb->getIndexType();
u32 indexCount = 0; const u16* indices = mb->getIndices();
const u32 indexCount = mb->getIndexCount();
core::array<u16>* outIdx = 0; core::array<u16>* outIdx = 0;
if ( indexType == video::EIT_32BIT )
{
IMeshBuffer* buffer = mb->createClone();
buffer->setBoundingBox(mb->getBoundingBox());
buffer->getMaterial() = mb->getMaterial();
meshClone->addMeshBuffer(buffer);
buffer->drop();
continue; // TODO: handle 32-bit buffers beside copying them
}
switch(mb->getVertexType()) switch(mb->getVertexType())
{ {
case video::EVT_STANDARD: case video::EVT_STANDARD:
{ {
SMeshBuffer* buffer = new SMeshBuffer(); SMeshBuffer* buffer = new SMeshBuffer();
buffer->BoundingBox = mb->getBoundingBox(); buffer->setBoundingBox(mb->getBoundingBox());
buffer->Material = mb->getMaterial(); buffer->Material = mb->getMaterial();
clone->addMeshBuffer(buffer); meshClone->addMeshBuffer(buffer);
buffer->drop(); buffer->drop();
video::S3DVertex* v = video::S3DVertex* v = (video::S3DVertex*)mb->getVertices();
(video::S3DVertex*)mb->getVertices();
u32 vertexCount = mb->getVertexCount();
indices = mb->getIndices();
indexCount = mb->getIndexCount();
outIdx = &buffer->Indices; outIdx = &buffer->Indices;
buffer->Vertices.reallocate(vertexCount); buffer->Vertices.reallocate(vertexCount);
@ -771,18 +778,14 @@ IMesh* CMeshManipulator::createMeshWelded(IMesh *mesh, f32 tolerance) const
case video::EVT_2TCOORDS: case video::EVT_2TCOORDS:
{ {
SMeshBufferLightMap* buffer = new SMeshBufferLightMap(); SMeshBufferLightMap* buffer = new SMeshBufferLightMap();
buffer->BoundingBox = mb->getBoundingBox(); buffer->setBoundingBox(mb->getBoundingBox());
buffer->Material = mb->getMaterial(); buffer->Material = mb->getMaterial();
clone->addMeshBuffer(buffer); meshClone->addMeshBuffer(buffer);
buffer->drop(); buffer->drop();
video::S3DVertex2TCoords* v = video::S3DVertex2TCoords* v =
(video::S3DVertex2TCoords*)mb->getVertices(); (video::S3DVertex2TCoords*)mb->getVertices();
u32 vertexCount = mb->getVertexCount();
indices = mb->getIndices();
indexCount = mb->getIndexCount();
outIdx = &buffer->Indices; outIdx = &buffer->Indices;
buffer->Vertices.reallocate(vertexCount); buffer->Vertices.reallocate(vertexCount);
@ -814,18 +817,13 @@ IMesh* CMeshManipulator::createMeshWelded(IMesh *mesh, f32 tolerance) const
case video::EVT_TANGENTS: case video::EVT_TANGENTS:
{ {
SMeshBufferTangents* buffer = new SMeshBufferTangents(); SMeshBufferTangents* buffer = new SMeshBufferTangents();
buffer->BoundingBox = mb->getBoundingBox(); buffer->setBoundingBox(mb->getBoundingBox());
buffer->Material = mb->getMaterial(); buffer->Material = mb->getMaterial();
clone->addMeshBuffer(buffer); meshClone->addMeshBuffer(buffer);
buffer->drop(); buffer->drop();
video::S3DVertexTangents* v = video::S3DVertexTangents* v = (video::S3DVertexTangents*)mb->getVertices();
(video::S3DVertexTangents*)mb->getVertices();
u32 vertexCount = mb->getVertexCount();
indices = mb->getIndices();
indexCount = mb->getIndexCount();
outIdx = &buffer->Indices; outIdx = &buffer->Indices;
buffer->Vertices.reallocate(vertexCount); buffer->Vertices.reallocate(vertexCount);
@ -860,7 +858,7 @@ IMesh* CMeshManipulator::createMeshWelded(IMesh *mesh, f32 tolerance) const
break; break;
} }
// Clean up any degenerate tris // set indices for new buffer
core::array<u16> &Indices = *outIdx; core::array<u16> &Indices = *outIdx;
Indices.clear(); Indices.clear();
Indices.reallocate(indexCount); Indices.reallocate(indexCount);
@ -873,6 +871,7 @@ IMesh* CMeshManipulator::createMeshWelded(IMesh *mesh, f32 tolerance) const
bool drop = false; bool drop = false;
// Clean up any degenerate tris
if (a == b || b == c || a == c) if (a == b || b == c || a == c)
drop = true; drop = true;
@ -885,8 +884,9 @@ IMesh* CMeshManipulator::createMeshWelded(IMesh *mesh, f32 tolerance) const
Indices.push_back(c); Indices.push_back(c);
} }
} }
// indexCount-Indices.size() vertices got welded for this meshbuffer
} }
return clone; return meshClone;
} }

View File

@ -250,7 +250,7 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
v.Pos = vertexBuffer[Idx[0]]; v.Pos = vertexBuffer[Idx[0]];
else else
{ {
os::Printer::log("Invalid vertex index in this line:", wordBuffer.c_str(), ELL_ERROR); os::Printer::log("Invalid vertex index in this line", wordBuffer.c_str(), ELL_ERROR);
delete [] buf; delete [] buf;
return 0; return 0;
} }

View File

@ -112,7 +112,7 @@ bool CQ3LevelMesh::loadFile(io::IReadFile* file)
( header.strID != 0x50534252 || header.version != 1 ) // RBSP, starwars jedi, sof ( header.strID != 0x50534252 || header.version != 1 ) // RBSP, starwars jedi, sof
) )
{ {
os::Printer::log("Could not load .bsp file, unknown header.", file->getFileName(), ELL_ERROR); os::Printer::log("Could not load .bsp file, unknown header", file->getFileName(), ELL_ERROR);
return false; return false;
} }

View File

@ -438,7 +438,7 @@ IAnimatedMesh* CSceneManager::getMesh(const io::path& filename, const io::path&
io::IReadFile* file = FileSystem->createAndOpenFile(filename); io::IReadFile* file = FileSystem->createAndOpenFile(filename);
if (!file) if (!file)
{ {
os::Printer::log("Could not load mesh, because file could not be opened: ", filename, ELL_ERROR); os::Printer::log("Could not load mesh, because file could not be opened", filename, ELL_ERROR);
return 0; return 0;
} }
@ -2377,7 +2377,7 @@ bool CSceneManager::loadScene(io::IReadFile* file, ISceneUserDataSerializer* use
ret = SceneLoaderList[i]->loadScene(file, userDataSerializer, rootNode); ret = SceneLoaderList[i]->loadScene(file, userDataSerializer, rootNode);
if (!ret) if (!ret)
os::Printer::log("Could not load scene file, perhaps the format is unsupported: ", file->getFileName().c_str(), ELL_ERROR); os::Printer::log("Could not load scene file, perhaps the format is unsupported", file->getFileName().c_str(), ELL_ERROR);
return ret; return ret;
} }

View File

@ -117,7 +117,6 @@ void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, u32 timeMs)
if (firstUpdate) if (firstUpdate)
{ {
camera->updateAbsolutePosition();
if (CursorControl ) if (CursorControl )
{ {
CursorControl->setPosition(0.5f, 0.5f); CursorControl->setPosition(0.5f, 0.5f);
@ -151,6 +150,7 @@ void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, u32 timeMs)
LastAnimationTime = timeMs; LastAnimationTime = timeMs;
// Update rotation // Update rotation
camera->updateAbsolutePosition();
core::vector3df target = (camera->getTarget() - camera->getAbsolutePosition()); core::vector3df target = (camera->getTarget() - camera->getAbsolutePosition());
core::vector3df relativeRotation = target.getHorizontalAngle(); core::vector3df relativeRotation = target.getHorizontalAngle();

View File

@ -1104,27 +1104,27 @@ void CSkinnedMesh::finalize()
if ( redundantPosKeys > 0 ) if ( redundantPosKeys > 0 )
{ {
os::Printer::log("Skinned Mesh - redundant position frames kicked:", core::stringc(redundantPosKeys).c_str(), ELL_DEBUG); os::Printer::log("Skinned Mesh - redundant position frames kicked", core::stringc(redundantPosKeys).c_str(), ELL_DEBUG);
} }
if ( unorderedPosKeys > 0 ) if ( unorderedPosKeys > 0 )
{ {
irr::os::Printer::log("Skinned Mesh - unsorted position frames kicked:", irr::core::stringc(unorderedPosKeys).c_str(), irr::ELL_DEBUG); irr::os::Printer::log("Skinned Mesh - unsorted position frames kicked", irr::core::stringc(unorderedPosKeys).c_str(), irr::ELL_DEBUG);
} }
if ( redundantScaleKeys > 0 ) if ( redundantScaleKeys > 0 )
{ {
os::Printer::log("Skinned Mesh - redundant scale frames kicked:", core::stringc(redundantScaleKeys).c_str(), ELL_DEBUG); os::Printer::log("Skinned Mesh - redundant scale frames kicked", core::stringc(redundantScaleKeys).c_str(), ELL_DEBUG);
} }
if ( unorderedScaleKeys > 0 ) if ( unorderedScaleKeys > 0 )
{ {
irr::os::Printer::log("Skinned Mesh - unsorted scale frames kicked:", irr::core::stringc(unorderedScaleKeys).c_str(), irr::ELL_DEBUG); irr::os::Printer::log("Skinned Mesh - unsorted scale frames kicked", irr::core::stringc(unorderedScaleKeys).c_str(), irr::ELL_DEBUG);
} }
if ( redundantRotationKeys > 0 ) if ( redundantRotationKeys > 0 )
{ {
os::Printer::log("Skinned Mesh - redundant rotation frames kicked:", core::stringc(redundantRotationKeys).c_str(), ELL_DEBUG); os::Printer::log("Skinned Mesh - redundant rotation frames kicked", core::stringc(redundantRotationKeys).c_str(), ELL_DEBUG);
} }
if ( unorderedRotationKeys > 0 ) if ( unorderedRotationKeys > 0 )
{ {
irr::os::Printer::log("Skinned Mesh - unsorted rotation frames kicked:", irr::core::stringc(unorderedRotationKeys).c_str(), irr::ELL_DEBUG); irr::os::Printer::log("Skinned Mesh - unsorted rotation frames kicked", irr::core::stringc(unorderedRotationKeys).c_str(), irr::ELL_DEBUG);
} }
} }

View File

@ -265,7 +265,7 @@ namespace scene
{ {
if ((filesize-file->getPos())/bytesPerPixel>(size_t)(width*width)) if ((filesize-file->getPos())/bytesPerPixel>(size_t)(width*width))
{ {
os::Printer::log("Error reading heightmap RAW file", "File is too small."); os::Printer::log("Error reading heightmap RAW file: File is too small.");
return false; return false;
} }
TerrainData.Size = width; TerrainData.Size = width;

View File

@ -463,7 +463,7 @@ bool CWGLManager::activateContext(const SExposedVideoData& videoData, bool resto
{ {
if (!wglMakeCurrent((HDC)PrimaryContext.OpenGLWin32.HDc, (HGLRC)PrimaryContext.OpenGLWin32.HRc)) if (!wglMakeCurrent((HDC)PrimaryContext.OpenGLWin32.HDc, (HGLRC)PrimaryContext.OpenGLWin32.HRc))
{ {
os::Printer::log("Render Context switch failed."); os::Printer::log("Render Context switch (back to main) failed.");
return false; return false;
} }
CurrentContext=PrimaryContext; CurrentContext=PrimaryContext;

View File

@ -491,7 +491,7 @@ bool CXMeshFileLoader::parseDataObject()
// parse specific object // parse specific object
#ifdef _XREADER_DEBUG #ifdef _XREADER_DEBUG
os::Printer::log("debug DataObject:", objectName.c_str(), ELL_DEBUG); os::Printer::log("debug DataObject", objectName.c_str(), ELL_DEBUG);
#endif #endif
if (objectName == "template") if (objectName == "template")
@ -848,7 +848,7 @@ bool CXMeshFileLoader::parseDataObjectMesh(SXMesh &mesh)
} }
#ifdef _XREADER_DEBUG #ifdef _XREADER_DEBUG
os::Printer::log("debug DataObject in mesh:", objectName.c_str(), ELL_DEBUG); os::Printer::log("debug DataObject in mesh", objectName.c_str(), ELL_DEBUG);
#endif #endif
if (objectName == "MeshNormals") if (objectName == "MeshNormals")

View File

@ -39,6 +39,8 @@ namespace os
static void print(const c8* message, ELOG_LEVEL ll = ELL_INFORMATION); static void print(const c8* message, ELOG_LEVEL ll = ELL_INFORMATION);
static void log(const c8* message, ELOG_LEVEL ll = ELL_INFORMATION); static void log(const c8* message, ELOG_LEVEL ll = ELL_INFORMATION);
static void log(const wchar_t* message, ELOG_LEVEL ll = ELL_INFORMATION); static void log(const wchar_t* message, ELOG_LEVEL ll = ELL_INFORMATION);
// The string ": " is added between message and hint
static void log(const c8* message, const c8* hint, ELOG_LEVEL ll = ELL_INFORMATION); static void log(const c8* message, const c8* hint, ELOG_LEVEL ll = ELL_INFORMATION);
static void log(const c8* message, const io::path& hint, ELOG_LEVEL ll = ELL_INFORMATION); static void log(const c8* message, const io::path& hint, ELOG_LEVEL ll = ELL_INFORMATION);
static ILogger* Logger; static ILogger* Logger;

View File

@ -1,4 +1,4 @@
Tests finished. 72 tests of 72 passed. Tests finished. 72 tests of 72 passed.
Compiled as DEBUG Compiled as DEBUG
Test suite pass at GMT Sat May 14 18:16:57 2022 Test suite pass at GMT Thu Sep 15 20:10:06 2022