diff --git a/changes.txt b/changes.txt index 3a6690ab..96e07797 100644 --- a/changes.txt +++ b/changes.txt @@ -11,6 +11,10 @@ Changes in ogl-es (not yet released - will be merged with trunk at some point) -------------------------- Changes in 1.9 (not yet released) +- Optimize quaternion::rotationFromTo. Thanks @Robert Eisele for patch and proof (https://raw.org/proof/quaternion-from-two-vectors) +- Shader material example shows now how to pass material values. + In 1.8 we could still use gl_FrontMaterial, but that is no longer supported in shaders +- Get IMeshBuffer::append functions working for a few more cases and adapt interface so one can prevent the BoundingBox update. - Bugfix: SMaterialLayer::operator!= no longer returns true when comparing a layer without texture matrix with one with a set identity texture matrix. Those are the same. - SMaterialLayer no longer releases allocated texture memory before destructor unless explicitly requested. This can avoid constantly allocation/releasing memory in the active driver material when setting materials. @@ -403,7 +407,16 @@ Changes in 1.9 (not yet released) - burningvideo: mipmaplevel adjusted ( not that bad bokeh...(sometimes) ) -------------------------- -Changes in 1.8.6 +Changes in 1.8.6 +- Fix compiling on OSX with case-sensitive filesystems: IrrFramework-Info.plist now always starting with upper-case. + Thanks @Ryan Schmidt for bug report and patch. +- Fix: The build-in libpng now uses same zlib headers as rest of Irrlicht. + This fixes OSX compiling (which didn't have zlib in include path and used system header for this one instead). + Thanks @Ryan Schmidt for bug report. +- Backport parts of COpenGLCommon.h to ensure that COpenGLExtensionHandler, COpenGLShaderMaterialRenderer and COpenGLTexture all use identical GL extension settings +- Backport removing register keywords (deprecated by c++17) +- Backport bugfix from trunk to make CUserPointerAttribute::setString work on 64-bit systems. +- Remove unnecessary implemented assignment operator in quaternion, irrMap, SViewFrustum, line2d and IQ3Shader which cause warnings with -Wdeprecated in newer gcc - Avoid warning about stringop-overflow in string::subString when compiling in release with newer gcc - Update library zlib to 1.2.11 (from 1.2.8) - Update library bzip2 to 1.0.8 (from 1.0.6) diff --git a/examples/10.Shaders/main.cpp b/examples/10.Shaders/main.cpp index 21c22924..72199640 100644 --- a/examples/10.Shaders/main.cpp +++ b/examples/10.Shaders/main.cpp @@ -48,8 +48,10 @@ class MyShaderCallBack : public video::IShaderConstantSetCallBack { public: MyShaderCallBack() : WorldViewProjID(-1), TransWorldID(-1), InvWorldID(-1), PositionID(-1), - ColorID(-1), TextureID(-1) + ColorID(-1), TextureID(-1), EmissiveID(-1) { + for ( int i=0; i<4; ++i ) + Emissive[i] = 0.f; } virtual void OnCreate(video::IMaterialRendererServices* services, s32 userData) @@ -57,11 +59,15 @@ public: if (UseHighLevelShaders) { // Get shader constants id. + // Constants are "uniforms" in other shading languages. + // And they are not constant at all but can be changed before every draw call + // (the naming probably comes from Direct3D where they are called constants) WorldViewProjID = services->getVertexShaderConstantID("mWorldViewProj"); TransWorldID = services->getVertexShaderConstantID("mTransWorld"); InvWorldID = services->getVertexShaderConstantID("mInvWorld"); PositionID = services->getVertexShaderConstantID("mLightPos"); ColorID = services->getVertexShaderConstantID("mLightColor"); + EmissiveID = services->getPixelShaderConstantID("mEmissive"); // Textures ID are important only for OpenGL interface. video::IVideoDriver* driver = services->getVideoDriver(); @@ -91,6 +97,21 @@ public: services->setVertexShaderConstant(reinterpret_cast(&col), 9, 1); } + // Called when any SMaterial value changes + virtual void OnSetMaterial(const irr::video::SMaterial& material) + { + // Remember material values to pass them on to shader in OnSetConstants + Emissive[0] = material.EmissiveColor.getRed() / 255.0f; + Emissive[1] = material.EmissiveColor.getGreen() / 255.0f; + Emissive[2] = material.EmissiveColor.getBlue() / 255.0f; + Emissive[3] = material.EmissiveColor.getAlpha() / 255.0f; + + // Note: Until Irrlicht 1.8 it was possible to use gl_FrontMaterial in glsl + // This is no longer supported since Irrlicht 1.9 + // Reason: Passing always every material value is slow, harder to port + // and generally getting deprecated in newer shader systems. + } + virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData) { @@ -145,6 +166,12 @@ public: } else services->setVertexShaderConstant(world.pointer(), 10, 4); + + // Set material values + if (UseHighLevelShaders) + { + services->setPixelShaderConstant(EmissiveID, Emissive, 4); + } } private: @@ -154,6 +181,9 @@ private: s32 PositionID; s32 ColorID; s32 TextureID; + + s32 EmissiveID; + irr::f32 Emissive[4]; }; /* @@ -398,6 +428,7 @@ int main() node->setMaterialFlag(video::EMF_LIGHTING, false); node->setMaterialFlag(video::EMF_BLEND_OPERATION, true); node->setMaterialType((video::E_MATERIAL_TYPE)newMaterialType2); + node->getMaterial(0).EmissiveColor = irr::video::SColor(0,50,0,50); smgr->addTextSceneNode(gui->getBuiltInFont(), L"PS & VS & EMT_TRANSPARENT", diff --git a/include/CDynamicMeshBuffer.h b/include/CDynamicMeshBuffer.h index 4a707285..b4e38a57 100644 --- a/include/CDynamicMeshBuffer.h +++ b/include/CDynamicMeshBuffer.h @@ -108,17 +108,97 @@ namespace scene \param numVertices Number of vertices in the array. \param indices Pointer to index array. \param numIndices Number of indices in array. */ - 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, bool updateBoundingBox=true) IRR_OVERRIDE { - // TODO + // We simply assume it has the same vertex and index type as this object. If other types are passed this will crash + append(getVertexType(), vertices, numVertices, getIndexType(), indices, numIndices, updateBoundingBox); } //! Append the meshbuffer to the current buffer - /** Only works for compatible vertex types - \param other Buffer to append to this one. */ - virtual void append(const IMeshBuffer* const other) IRR_OVERRIDE + /** \param other Buffer to append to this one. */ + virtual void append(const IMeshBuffer* const other, bool updateBoundingBox=true) IRR_OVERRIDE { - // TODO + append(other->getVertexType(), other->getVertices(), other->getVertexCount(), other->getIndexType(), other->getIndices(), other->getIndexCount(), updateBoundingBox); + } + + void append(video::E_VERTEX_TYPE vertexType, const void* const vertices, u32 numVertices, video::E_INDEX_TYPE indexType, const void* const indices, u32 numIndices, bool updateBoundingBox) + { + if (vertices == getVertices() || indices == getIndices()) // can't do that because we're doing reallocations on those blocks + return; + + const u32 vertexCount = getVertexCount(); + + VertexBuffer->reallocate(vertexCount+numVertices, false); + if ( vertexType == getVertexType() ) + { + const irr::u32 typeSize = getVertexPitchFromType(vertexType); + VertexBuffer->set_used(vertexCount+numVertices); + irr::u8* target = &static_cast(VertexBuffer->pointer())[vertexCount*typeSize]; + memcpy(target, vertices, numVertices*typeSize); + } + else + { + switch ( vertexType ) + { + case video::EVT_STANDARD: + for (u32 i=0; ipush_back(static_cast(vertices)[i]); + } + break; + case video::EVT_2TCOORDS: + for (u32 i=0; ipush_back(static_cast(vertices)[i]); + } + break; + case video::EVT_TANGENTS: + for (u32 i=0; ipush_back(static_cast(vertices)[i]); + } + break; + } + } + + if ( updateBoundingBox && numVertices > 0) + { + if ( vertexCount == 0 ) + BoundingBox.reset( static_cast(vertices)[0].Pos ); + + const u32 typePitch = getVertexPitchFromType(vertexType); + const irr::u8* v8 = static_cast(vertices); + for (u32 i=0; i(v8)->Pos); + } + } + + IndexBuffer->reallocate(getIndexCount()+numIndices, false); + switch ( indexType ) + { + case video::EIT_16BIT: + { + const irr::u16* indices16 = reinterpret_cast(indices); + for (u32 i=0; ipush_back(indices16[i]+vertexCount); + } + break; + } + case video::EIT_32BIT: + { + const irr::u32* indices32 = reinterpret_cast(indices); + for (u32 i=0; ipush_back(indices32[i]+vertexCount); + } + break; + } + } + + setDirty(); } diff --git a/include/CMeshBuffer.h b/include/CMeshBuffer.h index 6f1ff368..e3380cfc 100644 --- a/include/CMeshBuffer.h +++ b/include/CMeshBuffer.h @@ -191,59 +191,48 @@ namespace scene //! Append the vertices and indices to the current buffer /** Only works for compatible types, i.e. either the same type or the main buffer is of standard type. Otherwise, behavior is - undefined. + undefined. Also can't append it's own vertices/indices to itself. */ - 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, bool updateBoundingBox=true) IRR_OVERRIDE { - if (vertices == getVertices()) + if (vertices == getVertices() || indices == getIndices()) // can't do that because we're doing reallocations on those blocks return; const u32 vertexCount = getVertexCount(); u32 i; - Vertices.reallocate(vertexCount+numVertices); + Vertices.reallocate(vertexCount+numVertices, false); for (i=0; i(vertices)[i]); - BoundingBox.addInternalPoint(static_cast(vertices)[i].Pos); } - Indices.reallocate(getIndexCount()+numIndices); + if ( updateBoundingBox && numVertices > 0) + { + if ( vertexCount == 0 ) + BoundingBox.reset(static_cast(vertices)[0].Pos); + + for (i=0; i(vertices)[i].Pos); + } + + Indices.reallocate(getIndexCount()+numIndices, false); for (i=0; igetVertexType() ) return; - const u32 vertexCount = getVertexCount(); - u32 i; - - Vertices.reallocate(vertexCount+other->getVertexCount()); - for (i=0; igetVertexCount(); ++i) - { - Vertices.push_back(reinterpret_cast(other->getVertices())[i]); - } - - Indices.reallocate(getIndexCount()+other->getIndexCount()); - for (i=0; igetIndexCount(); ++i) - { - Indices.push_back(other->getIndices()[i]+vertexCount); - } - BoundingBox.addInternalBox(other->getBoundingBox()); - */ + append(other->getVertices(), other->getVertexCount(), other->getIndices(), other->getIndexCount(), updateBoundingBox); } diff --git a/include/IMaterialRendererServices.h b/include/IMaterialRendererServices.h index 321afd1a..d04258b5 100644 --- a/include/IMaterialRendererServices.h +++ b/include/IMaterialRendererServices.h @@ -24,7 +24,7 @@ public: //! Destructor virtual ~IMaterialRendererServices() {} - //! Return an index constant for the vertex shader based on a name. + //! Return an index constant for the vertex shader based on a uniform variable name. virtual s32 getVertexShaderConstantID(const c8* name) = 0; //! Call when you set shader constants outside of IShaderConstantSetCallBack @@ -41,27 +41,8 @@ public: //! Call this when you are done setting shader constants outside of OnCreate or OnSetConstants virtual void stopUseProgram() {} - //! Sets a constant for the vertex shader based on a name. - /** This can be used if you used a high level shader language like GLSL - or HLSL to create a shader. Example: If you created a shader which has - variables named 'mWorldViewProj' (containing the WorldViewProjection - matrix) and another one named 'fTime' containing one float, you can set - them in your IShaderConstantSetCallBack derived class like this: - \code - virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData) - { - video::IVideoDriver* driver = services->getVideoDriver(); - - f32 time = (f32)os::Timer::getTime()/100000.0f; - services->setVertexShaderConstant("fTime", &time, 1); - - core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION)); - worldViewProj *= driver->getTransform(video::ETS_VIEW); - worldViewProj *= driver->getTransform(video::ETS_WORLD); - services->setVertexShaderConstant("mWorldViewProj", worldViewProj.M, 16); - } - \endcode - \param index Index of the variable + //! Sets a value for a vertex shader uniform variable. + /**\param index Index of the variable (as received from getVertexShaderConstantID) \param floats Pointer to array of floats \param count Amount of floats in array. \return True if successful. @@ -77,7 +58,7 @@ public: */ virtual bool setVertexShaderConstant(s32 index, const u32* ints, int count) = 0; - //! Sets a vertex shader constant. + //! Sets a vertex shader constant (or "uniform" in more modern terms) /** Can be used if you created a shader using pixel/vertex shader assembler or ARB_fragment_program or ARB_vertex_program. \param data: Data to be set in the constants @@ -85,14 +66,14 @@ public: \param constantAmount: Amount of registers to be set. One register consists of 4 floats. */ virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1) = 0; - //! Return an index constant for the pixel shader based on a name. + //! Return an index constant for the pixel shader for the given uniform variable name virtual s32 getPixelShaderConstantID(const c8* name) = 0; - //! Sets a constant for the pixel shader based on a name. + //! Sets a value for the given pixel shader uniform variable /** This can be used if you used a high level shader language like GLSL or HLSL to create a shader. See setVertexShaderConstant() for an example on how to use this. - \param index Index of the variable + \param index Index of the variable (as received from getPixelShaderConstantID) \param floats Pointer to array of floats \param count Amount of floats in array. \return True if successful. */ @@ -116,6 +97,26 @@ public: virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1) = 0; //! \deprecated. This method may be removed by Irrlicht 2.0 + /** This can be used if you use a high level shader language like GLSL + or HLSL to create a shader. Example: If you created a shader which has + variables named 'mWorldViewProj' (containing the WorldViewProjection + matrix) and another one named 'fTime' containing one float, you can set + them in your IShaderConstantSetCallBack derived class like this: + \code + virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData) + { + video::IVideoDriver* driver = services->getVideoDriver(); + + f32 time = (f32)os::Timer::getTime()/100000.0f; + services->setVertexShaderConstant("fTime", &time, 1); + + core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION)); + worldViewProj *= driver->getTransform(video::ETS_VIEW); + worldViewProj *= driver->getTransform(video::ETS_WORLD); + services->setVertexShaderConstant("mWorldViewProj", worldViewProj.M, 16); + } + \endcode + **/ IRR_DEPRECATED bool setVertexShaderConstant(const c8* name, const f32* floats, int count) { return setVertexShaderConstant(getVertexShaderConstantID(name), floats, count); diff --git a/include/IMeshBuffer.h b/include/IMeshBuffer.h index 253d2712..ab8560e9 100644 --- a/include/IMeshBuffer.h +++ b/include/IMeshBuffer.h @@ -126,19 +126,21 @@ namespace scene virtual const video::SColor& getColor(u32 i) const = 0; //! Append the vertices and indices to the current buffer - /** Only works for compatible vertex types - and not implemented for most buffers for now. + /** Only works for compatible vertex and index types + and not implemented for some buffers for now. \param vertices Pointer to a vertex array. \param numVertices Number of vertices in the array. \param indices Pointer to index array. - \param numIndices Number of indices in array. */ - virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) = 0; + \param numIndices Number of indices in array. + \param updateBoundingBox When true update boundingbox by the added vertices */ + virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices, bool updateBoundingBox=true) = 0; - //! Not supported right now by any meshbuffer + //! Not supported right now by all meshbuffer //! In theory: Append the meshbuffer to the current buffer - /** Only works for compatible vertex types - \param other Buffer to append to this one. */ - virtual void append(const IMeshBuffer* const other) = 0; + /** Only works for compatible vertex and index types + \param other Buffer to append to this one. +s \param updateBoundingBox When true update boundingbox by the added vertices */ + virtual void append(const IMeshBuffer* const other, bool updateBoundingBox=true) = 0; //! get the current hardware mapping hint virtual E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const = 0; diff --git a/include/IVideoDriver.h b/include/IVideoDriver.h index ff21f797..f90f3694 100644 --- a/include/IVideoDriver.h +++ b/include/IVideoDriver.h @@ -392,8 +392,7 @@ namespace video const io::path& name = "rt", const ECOLOR_FORMAT format = ECF_UNKNOWN) =0; //! Adds a new render target texture with 6 sides for a cubemap map to the texture cache. - /** NOTE: Only supported on D3D9 so far. - \param sideLen Length of one cubemap side. + /** \param sideLen Length of one cubemap side. \param name A name for the texture. Later calls of getTexture() with this name will return this texture. The name can _not_ be empty. \param format The color format of the render target. Floating point formats are supported. diff --git a/include/SSharedMeshBuffer.h b/include/SSharedMeshBuffer.h index f894625b..ece68109 100644 --- a/include/SSharedMeshBuffer.h +++ b/include/SSharedMeshBuffer.h @@ -187,13 +187,13 @@ namespace scene //! 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, bool updateBoundingBox) IRR_OVERRIDE { // can't do that as it doesn't own the vertex memory } //! append the meshbuffer to the current buffer - virtual void append(const IMeshBuffer* const other) IRR_OVERRIDE + virtual void append(const IMeshBuffer* const other, bool updateBoundingBox) IRR_OVERRIDE { // can't do that as it doesn't own the vertex memory } diff --git a/include/SSkinMeshBuffer.h b/include/SSkinMeshBuffer.h index b2b812b4..9883c654 100644 --- a/include/SSkinMeshBuffer.h +++ b/include/SSkinMeshBuffer.h @@ -355,10 +355,10 @@ struct SSkinMeshBuffer : public IMeshBuffer } //! 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, bool updateBoundingBox) IRR_OVERRIDE {} //! append the meshbuffer to the current buffer - virtual void append(const IMeshBuffer* const other) IRR_OVERRIDE {} + virtual void append(const IMeshBuffer* const other, bool updateBoundingBox) IRR_OVERRIDE {} //! get the current hardware mapping hint for vertex buffers virtual E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const IRR_OVERRIDE diff --git a/include/quaternion.h b/include/quaternion.h index 77a05995..863f073e 100644 --- a/include/quaternion.h +++ b/include/quaternion.h @@ -721,6 +721,8 @@ inline core::quaternion& quaternion::makeIdentity() inline core::quaternion& quaternion::rotationFromTo(const vector3df& from, const vector3df& to) { // Based on Stan Melax's article in Game Programming Gems + // Optimized by Robert Eisele: https://raw.org/proof/quaternion-from-two-vectors + // Copy, since cannot modify local vector3df v0 = from; vector3df v1 = to; @@ -745,10 +747,8 @@ inline core::quaternion& quaternion::rotationFromTo(const vector3df& from, const return set(axis.X, axis.Y, axis.Z, 0).normalize(); } - const f32 s = sqrtf( (1+d)*2 ); // optimize inv_sqrt - const f32 invs = 1.f / s; - const vector3df c = v0.crossProduct(v1)*invs; - return set(c.X, c.Y, c.Z, s * 0.5f).normalize(); + const vector3df c = v0.crossProduct(v1); + return set(c.X, c.Y, c.Z, 1 + d).normalize(); } diff --git a/media/d3d9.hlsl b/media/d3d9.hlsl index ff52d6fa..11e1e079 100644 --- a/media/d3d9.hlsl +++ b/media/d3d9.hlsl @@ -11,6 +11,7 @@ float4x4 mInvWorld; // Inverted world matrix float4x4 mTransWorld; // Transposed world matrix float3 mLightPos; // Light position (actually just camera-pos in this case) float4 mLightColor; // Light color +float4 mEmissive; // Emissive material color // Vertex shader output structure @@ -83,6 +84,7 @@ PS_OUTPUT pixelMain(float2 TexCoord : TEXCOORD0, // multiply with diffuse and do other senseless operations Output.RGBColor = Diffuse * col; Output.RGBColor *= 4.0; + Output.RGBColor += mEmissive; return Output; } diff --git a/media/opengl.frag b/media/opengl.frag index 82c3d5c9..5f258ac5 100644 --- a/media/opengl.frag +++ b/media/opengl.frag @@ -1,9 +1,11 @@ uniform sampler2D myTexture; +uniform vec4 mEmissive; void main (void) { vec4 col = texture2D(myTexture, vec2(gl_TexCoord[0])); col *= gl_Color; gl_FragColor = col * 4.0; + gl_FragColor += mEmissive; } diff --git a/source/Irrlicht/Irrlicht-gcc.cbp b/source/Irrlicht/Irrlicht-gcc.cbp index 3789af68..e5cb5c8b 100644 --- a/source/Irrlicht/Irrlicht-gcc.cbp +++ b/source/Irrlicht/Irrlicht-gcc.cbp @@ -864,6 +864,7 @@ + diff --git a/source/Irrlicht/Irrlicht10.0.vcxproj b/source/Irrlicht/Irrlicht10.0.vcxproj index a1b34199..a1d084b2 100644 --- a/source/Irrlicht/Irrlicht10.0.vcxproj +++ b/source/Irrlicht/Irrlicht10.0.vcxproj @@ -1164,7 +1164,6 @@ - diff --git a/source/Irrlicht/Irrlicht10.0.vcxproj.filters b/source/Irrlicht/Irrlicht10.0.vcxproj.filters index 0c54eb7c..2e9bb292 100644 --- a/source/Irrlicht/Irrlicht10.0.vcxproj.filters +++ b/source/Irrlicht/Irrlicht10.0.vcxproj.filters @@ -1269,7 +1269,6 @@ include\scene - Irrlicht\scene\loaders diff --git a/source/Irrlicht/libpng/pngstruct.h b/source/Irrlicht/libpng/pngstruct.h index a94de65b..00d82ab5 100644 --- a/source/Irrlicht/libpng/pngstruct.h +++ b/source/Irrlicht/libpng/pngstruct.h @@ -27,7 +27,20 @@ /* We must ensure that zlib uses 'const' in declarations. */ # define ZLIB_CONST #endif -#include "zlib.h" + +/* Irrlicht change: + Avoid that build-in png uses a different zlib than the rest of Irrlicht. + Note: This also would allow removing zlib from the include paths, which + probably was done just to hide this bug. Anyway, it's less broken now + than it was and the rest is up to Irrlicht 1.9. +*/ +#include "IrrCompileConfig.h" +#ifndef _IRR_USE_NON_SYSTEM_ZLIB_ + #include // use system lib +#else + #include "../zlib/zlib.h" +#endif + #ifdef const /* zlib.h sometimes #defines const to nothing, undo this. */ # undef const