diff --git a/changes.txt b/changes.txt index 9ffa50fc..7b1d0dbe 100644 --- a/changes.txt +++ b/changes.txt @@ -1,5 +1,7 @@ -------------------------- Changes in 1.9 (not yet released) +- Material.ZWriteEnable is now of type E_ZWRITE instead of bool. This allows now setting materials to always "on" independent of material type and transparency. + This breaks compiling. To have old values replace false with EZW_OFF and true with EWZ_AUTO. - Materials EMT_REFLECTION_2_LAYER and EMT_TRANSPARENT_REFLECTION_2_LAYER on OpenGL are now same as in D3D9. Before GL used a sphere-map for those instead of reflection. - Bugfix: CGUIToolBar automatic placement no longer outside of screen when there are modals screens when creating it. Or when there are other window elements going over full window-size. diff --git a/include/SMaterial.h b/include/SMaterial.h index e2e34fe5..90f5c671 100644 --- a/include/SMaterial.h +++ b/include/SMaterial.h @@ -247,16 +247,33 @@ namespace video 0 }; - //! Fine-tuning for SMaterial.ZWriteFineControl - enum E_ZWRITE_FINE_CONTROL + //! For SMaterial.ZWriteEnable + enum E_ZWRITE { - //! Default. Only write zbuffer when SMaterial::ZWriteEnable is true and SMaterial::isTransparent() returns false. - EZI_ONLY_NON_TRANSPARENT, - //! Writing will just be based on SMaterial::ZWriteEnable value, transparency is ignored. - //! Needed mostly for certain shader materials where SMaterial::isTransparent always returns false. - EZI_ZBUFFER_FLAG + //! zwrite always disabled for this material + EZW_OFF = 0, + + //! This is the default setting for SMaterial and tries to handle things automatically. + //! This is also the value which is set when SMaterial::setFlag(EMF_ZWRITE_ENABLE) is enabled. + //! Usually zwriting is enabled non-transparent materials - as far as Irrlicht can recognize those. + //! Basically Irrlicht tries to handle the zwriting for you and assumes transparent materials don't need it. + //! This is addionally affected by IVideoDriver::setAllowZWriteOnTransparent + EZW_AUTO, + + //! zwrite always enabled for this material + EZW_ON }; + //! Names for E_ZWRITE + const c8* const ZWriteNames[] = + { + "Off", + "Auto", + "On", + 0 + }; + + //! Maximum number of texture an SMaterial can have. /** SMaterial might ignore some textures in most function, like assignment and comparison, @@ -296,9 +313,8 @@ namespace video PolygonOffsetFactor(0), PolygonOffsetDirection(EPO_FRONT), PolygonOffsetDepthBias(0.f), PolygonOffsetSlopeScale(0.f), Wireframe(false), PointCloud(false), GouraudShading(true), - Lighting(true), ZWriteEnable(true), BackfaceCulling(true), FrontfaceCulling(false), - FogEnable(false), NormalizeNormals(false), UseMipMaps(true), - ZWriteFineControl(EZI_ONLY_NON_TRANSPARENT) + Lighting(true), ZWriteEnable(EZW_AUTO), BackfaceCulling(true), FrontfaceCulling(false), + FogEnable(false), NormalizeNormals(false), UseMipMaps(true) { } //! Copy constructor @@ -354,7 +370,6 @@ namespace video PolygonOffsetDepthBias = other.PolygonOffsetDepthBias; PolygonOffsetSlopeScale = other.PolygonOffsetSlopeScale; UseMipMaps = other.UseMipMaps; - ZWriteFineControl = other.ZWriteFineControl; return *this; } @@ -508,12 +523,10 @@ namespace video //! Will this material be lighted? Default: true bool Lighting:1; - //! Is the zbuffer writable or is it read-only. Default: true. - /** This flag is forced to false if the MaterialType is a - transparent type and the scene parameter - ALLOW_ZWRITE_ON_TRANSPARENT is not set. If you set this parameter - to true, make sure that ZBuffer value is other than ECFN_DISABLED */ - bool ZWriteEnable:1; + //! Is the zbuffer writable or is it read-only. Default: EZW_AUTO. + /** If this parameter is not EZW_OFF, you probably also want to set ZBuffer + to values other than ECFN_DISABLED */ + E_ZWRITE ZWriteEnable:2; //! Is backface culling enabled? Default: true bool BackfaceCulling:1; @@ -532,11 +545,6 @@ namespace video /** Sometimes, disabling mipmap usage can be useful. Default: true */ bool UseMipMaps:1; - //! Give more control how the ZWriteEnable flag is interpreted - /** Note that there is also the global flag AllowZWriteOnTransparent - which when set acts like all materials have set EZI_ALLOW_ON_TRANSPARENT. */ - E_ZWRITE_FINE_CONTROL ZWriteFineControl:1; - //! Gets the texture transformation matrix for level i /** \param i The desired level. Must not be larger than MATERIAL_MAX_TEXTURES \return Texture matrix for texture level i. */ @@ -603,7 +611,7 @@ namespace video case EMF_ZBUFFER: ZBuffer = value; break; case EMF_ZWRITE_ENABLE: - ZWriteEnable = value; break; + ZWriteEnable = value ? EZW_AUTO : EZW_OFF; break; case EMF_BACK_FACE_CULLING: BackfaceCulling = value; break; case EMF_FRONT_FACE_CULLING: @@ -684,7 +692,7 @@ namespace video case EMF_ZBUFFER: return ZBuffer!=ECFN_DISABLED; case EMF_ZWRITE_ENABLE: - return ZWriteEnable; + return ZWriteEnable != EZW_OFF; case EMF_BACK_FACE_CULLING: return BackfaceCulling; case EMF_FRONT_FACE_CULLING: @@ -756,8 +764,7 @@ namespace video PolygonOffsetDirection != b.PolygonOffsetDirection || PolygonOffsetDepthBias != b.PolygonOffsetDepthBias || PolygonOffsetSlopeScale != b.PolygonOffsetSlopeScale || - UseMipMaps != b.UseMipMaps || - ZWriteFineControl != b.ZWriteFineControl; + UseMipMaps != b.UseMipMaps ; for (u32 i=0; (iFlags & 0x2) //(Alpha mapped) { B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; - B3dMaterial.Material.ZWriteEnable = false; + B3dMaterial.Material.ZWriteEnable = video::EZW_OFF; } else if (B3dMaterial.Textures[0]->Flags & 0x4) //(Masked) B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; // TODO: create color key texture @@ -984,7 +984,7 @@ bool CB3DMeshFileLoader::readChunkBRUS() else { B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; - B3dMaterial.Material.ZWriteEnable = false; + B3dMaterial.Material.ZWriteEnable = video::EZW_OFF; } } else //No texture: @@ -994,7 +994,7 @@ bool CB3DMeshFileLoader::readChunkBRUS() else { B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; - B3dMaterial.Material.ZWriteEnable = false; + B3dMaterial.Material.ZWriteEnable = video::EZW_OFF; } } @@ -1023,7 +1023,7 @@ bool CB3DMeshFileLoader::readChunkBRUS() if (B3dMaterial.fx & 32) //force vertex alpha-blending { B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; - B3dMaterial.Material.ZWriteEnable = false; + B3dMaterial.Material.ZWriteEnable = video::EZW_OFF; } B3dMaterial.Material.Shininess = B3dMaterial.shininess; diff --git a/source/Irrlicht/CBurningShader_Raster_Reference.cpp b/source/Irrlicht/CBurningShader_Raster_Reference.cpp index d12ed6c8..c04db94b 100644 --- a/source/Irrlicht/CBurningShader_Raster_Reference.cpp +++ b/source/Irrlicht/CBurningShader_Raster_Reference.cpp @@ -655,7 +655,7 @@ void CBurningShader_Raster_Reference::setMaterial ( const SBurningShaderMaterial } // depth buffer write - ShaderParam.SetRenderState( BD3DRS_ZWRITEENABLE, m.ZWriteEnable ); + ShaderParam.SetRenderState( BD3DRS_ZWRITEENABLE, m.ZWriteEnable != video::EZW_OFF ); } /*! diff --git a/source/Irrlicht/CColladaFileLoader.cpp b/source/Irrlicht/CColladaFileLoader.cpp index ab4d7fe0..7645254d 100644 --- a/source/Irrlicht/CColladaFileLoader.cpp +++ b/source/Irrlicht/CColladaFileLoader.cpp @@ -1541,7 +1541,7 @@ void CColladaFileLoader::readEffect(io::IXMLReaderUTF8* reader, SColladaEffect * if ((effect->Transparency != 0.0f) && (effect->Transparency != 1.0f)) { effect->Mat.MaterialType = irr::video::EMT_TRANSPARENT_VERTEX_ALPHA; - effect->Mat.ZWriteEnable = false; + effect->Mat.ZWriteEnable = video::EZW_OFF; } video::E_TEXTURE_CLAMP twu = video::ETC_REPEAT; @@ -1658,7 +1658,7 @@ void CColladaFileLoader::readBindMaterialSection(io::IXMLReaderUTF8* reader, con if ((material->Transparency!=0.0f) && (material->Transparency!=1.0f)) { toBind[i]->getMaterial().MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; - toBind[i]->getMaterial().ZWriteEnable = false; + toBind[i]->getMaterial().ZWriteEnable = video::EZW_OFF; } } SceneManager->getMeshManipulator()->setVertexColors(&tmpmesh,material->Mat.DiffuseColor); diff --git a/source/Irrlicht/CGeometryCreator.cpp b/source/Irrlicht/CGeometryCreator.cpp index c2700e84..22ce7170 100644 --- a/source/Irrlicht/CGeometryCreator.cpp +++ b/source/Irrlicht/CGeometryCreator.cpp @@ -1065,7 +1065,7 @@ IMesh* CGeometryCreator::createVolumeLightMesh( Buffer->Material.MaterialTypeParam = pack_textureBlendFunc( video::EBF_SRC_COLOR, video::EBF_SRC_ALPHA, video::EMFN_MODULATE_1X ); Buffer->Material.Lighting = false; - Buffer->Material.ZWriteEnable = false; + Buffer->Material.ZWriteEnable = video::EZW_OFF; Buffer->setDirty(EBT_VERTEX_AND_INDEX); diff --git a/source/Irrlicht/CNullDriver.cpp b/source/Irrlicht/CNullDriver.cpp index 7af3d132..06a7f97c 100644 --- a/source/Irrlicht/CNullDriver.cpp +++ b/source/Irrlicht/CNullDriver.cpp @@ -196,7 +196,7 @@ CNullDriver::CNullDriver(io::IFileSystem* io, const core::dimension2d& scre InitMaterial2D.AntiAliasing=video::EAAM_OFF; InitMaterial2D.Lighting=false; - InitMaterial2D.ZWriteEnable=false; + InitMaterial2D.ZWriteEnable=video::EZW_OFF; InitMaterial2D.ZBuffer=video::ECFN_DISABLED; InitMaterial2D.UseMipMaps=false; for (u32 i=0; igetAbsoluteTransformation()); @@ -2149,7 +2149,7 @@ io::IAttributes* CNullDriver::createAttributesFromMaterial(const video::SMateria attr->addBool("PointCloud", material.PointCloud); attr->addBool("GouraudShading", material.GouraudShading); attr->addBool("Lighting", material.Lighting); - attr->addBool("ZWriteEnable", material.ZWriteEnable); + attr->addEnum("ZWriteEnable", (irr::s32)material.ZWriteEnable, video::ZWriteNames); attr->addInt("ZBuffer", material.ZBuffer); attr->addBool("BackfaceCulling", material.BackfaceCulling); attr->addBool("FrontfaceCulling", material.FrontfaceCulling); @@ -2165,7 +2165,6 @@ io::IAttributes* CNullDriver::createAttributesFromMaterial(const video::SMateria attr->addEnum("PolygonOffsetDirection", material.PolygonOffsetDirection, video::PolygonOffsetDirectionNames); attr->addFloat("PolygonOffsetDepthBias", material.PolygonOffsetDepthBias); attr->addFloat("PolygonOffsetSlopeScale", material.PolygonOffsetSlopeScale); - attr->addInt("ZWriteFineControl", material.ZWriteFineControl); // TODO: Would be nice to have a flag that only serializes rest of texture data when a texture pointer exists. prefix = "BilinearFilter"; @@ -2228,7 +2227,13 @@ void CNullDriver::fillMaterialStructureFromAttributes(video::SMaterial& outMater outMaterial.PointCloud = attr->getAttributeAsBool("PointCloud", outMaterial.PointCloud); outMaterial.GouraudShading = attr->getAttributeAsBool("GouraudShading", outMaterial.GouraudShading); outMaterial.Lighting = attr->getAttributeAsBool("Lighting", outMaterial.Lighting); - outMaterial.ZWriteEnable = attr->getAttributeAsBool("ZWriteEnable", outMaterial.ZWriteEnable); + + io::E_ATTRIBUTE_TYPE attType = attr->getAttributeType("ZWriteEnable"); + if (attType == io::EAT_BOOL ) // Before Irrlicht 1.9 + outMaterial.ZWriteEnable = attr->getAttributeAsBool("ZWriteEnable", outMaterial.ZWriteEnable != video::EZW_OFF ) ? video::EZW_AUTO : video::EZW_OFF; + else if (attType == io::EAT_ENUM ) + outMaterial.ZWriteEnable = (video::E_ZWRITE)attr->getAttributeAsEnumeration("ZWriteEnable", video::ZWriteNames, outMaterial.ZWriteEnable); + outMaterial.ZBuffer = (u8)attr->getAttributeAsInt("ZBuffer", outMaterial.ZBuffer); outMaterial.BackfaceCulling = attr->getAttributeAsBool("BackfaceCulling", outMaterial.BackfaceCulling); outMaterial.FrontfaceCulling = attr->getAttributeAsBool("FrontfaceCulling", outMaterial.FrontfaceCulling); @@ -2245,7 +2250,7 @@ void CNullDriver::fillMaterialStructureFromAttributes(video::SMaterial& outMater outMaterial.PolygonOffsetDirection = (video::E_POLYGON_OFFSET)attr->getAttributeAsEnumeration("PolygonOffsetDirection", video::PolygonOffsetDirectionNames, outMaterial.PolygonOffsetDirection); outMaterial.PolygonOffsetDepthBias = attr->getAttributeAsFloat("PolygonOffsetDepthBias", outMaterial.PolygonOffsetDepthBias); outMaterial.PolygonOffsetSlopeScale = attr->getAttributeAsFloat("PolygonOffsetSlopeScale", outMaterial.PolygonOffsetSlopeScale); - outMaterial.ZWriteFineControl = (video::E_ZWRITE_FINE_CONTROL)attr->getAttributeAsInt("ZWriteFineControl", outMaterial.ZWriteFineControl); + prefix = "BilinearFilter"; if (attr->existsAttribute(prefix.c_str())) // legacy outMaterial.setFlag(EMF_BILINEAR_FILTER, attr->getAttributeAsBool(prefix.c_str())); diff --git a/source/Irrlicht/CNullDriver.h b/source/Irrlicht/CNullDriver.h index efd5e425..ec2e095f 100644 --- a/source/Irrlicht/CNullDriver.h +++ b/source/Irrlicht/CNullDriver.h @@ -745,22 +745,16 @@ namespace video inline bool getWriteZBuffer(const SMaterial&material) const { - if (material.ZWriteEnable) + switch ( material.ZWriteEnable ) { - if (!AllowZWriteOnTransparent) - { - switch (material.ZWriteFineControl) - { - case EZI_ONLY_NON_TRANSPARENT: - return !material.isTransparent(); - case EZI_ZBUFFER_FLAG: - return true; - } - } - else + case video::EZW_OFF: + return false; + case video::EZW_AUTO: + return AllowZWriteOnTransparent || !material.isTransparent(); + case video::EZW_ON: return true; } - return false; + return true; // never should get here, but some compilers don't know and complain } struct SSurface diff --git a/source/Irrlicht/COgreMeshFileLoader.cpp b/source/Irrlicht/COgreMeshFileLoader.cpp index 9daf3698..9df20871 100644 --- a/source/Irrlicht/COgreMeshFileLoader.cpp +++ b/source/Irrlicht/COgreMeshFileLoader.cpp @@ -1013,7 +1013,7 @@ void COgreMeshFileLoader::readPass(io::IReadFile* file, OgreTechnique& technique else if (token=="depth_write") { getMaterialToken(file, token); - pass.Material.ZWriteEnable=(token=="on"); + pass.Material.ZWriteEnable=(token=="on") ? video::EZW_ON : video::EZW_OFF; } else if (token=="depth_func") { diff --git a/source/Irrlicht/COpenGLShaderMaterialRenderer.h b/source/Irrlicht/COpenGLShaderMaterialRenderer.h index fad2efbf..50e70f1d 100644 --- a/source/Irrlicht/COpenGLShaderMaterialRenderer.h +++ b/source/Irrlicht/COpenGLShaderMaterialRenderer.h @@ -69,6 +69,13 @@ protected: COpenGLDriver* Driver; IShaderConstantSetCallBack* CallBack; + // I didn't write this, but here's my understanding: + // Those flags seem to be exclusive so far (so could be an enum). + // Maybe the idea was to make them non-exclusive in future (basically having a shader-material) + // Actually currently there's not even any need to cache them (probably even slower than not doing so). + // They seem to be mostly for downward compatibility. + // I suppose the idea is to use SMaterial.BlendOperation + SMaterial.BlendFactor and a simple non-transparent type as base for more flexibility in the future. + // Note that SMaterial.BlendOperation + SMaterial.BlendFactor are in some drivers already evaluated before OnSetMaterial. bool Alpha; bool Blending; bool FixedBlending; diff --git a/source/Irrlicht/CQ3LevelMesh.cpp b/source/Irrlicht/CQ3LevelMesh.cpp index 7d7ca779..b2f9060e 100644 --- a/source/Irrlicht/CQ3LevelMesh.cpp +++ b/source/Irrlicht/CQ3LevelMesh.cpp @@ -718,7 +718,7 @@ s32 CQ3LevelMesh::setShaderFogMaterial( video::SMaterial &material, const tBSPFa material.setTexture(2, 0); material.setTexture(3, 0); material.ZBuffer = video::ECFN_LESSEQUAL; - material.ZWriteEnable = false; + material.ZWriteEnable = video::EZW_OFF; material.MaterialTypeParam = 0.f; s32 shaderState = -1; @@ -746,7 +746,7 @@ s32 CQ3LevelMesh::setShaderMaterial( video::SMaterial &material, const tBSPFace material.setTexture(2, 0); material.setTexture(3, 0); material.ZBuffer = video::ECFN_LESSEQUAL; - material.ZWriteEnable = true; + material.ZWriteEnable = video::EZW_AUTO; material.MaterialTypeParam = 0.f; s32 shaderState = -1; @@ -804,7 +804,7 @@ s32 CQ3LevelMesh::setShaderMaterial( video::SMaterial &material, const tBSPFace if ( group->isDefined( "depthwrite" ) ) { - material.ZWriteEnable = true; + material.ZWriteEnable = video::EZW_ON; } SBlendFunc blendfunc ( LoadParam.defaultModulate ); diff --git a/source/Irrlicht/CQuake3ShaderSceneNode.cpp b/source/Irrlicht/CQuake3ShaderSceneNode.cpp index 9df0f61e..972f131d 100644 --- a/source/Irrlicht/CQuake3ShaderSceneNode.cpp +++ b/source/Irrlicht/CQuake3ShaderSceneNode.cpp @@ -368,13 +368,14 @@ void CQuake3ShaderSceneNode::render() material.setTexture(0, tex ); material.ZBuffer = getDepthFunction( group->get( "depthfunc" ) ); + // TODO: maybe should be video::EZW_ON instead of EZW_AUTO now (we didn't have that before and I just kept old values here when introducing it to not break anything) if ( group->isDefined( "depthwrite" ) ) { - material.ZWriteEnable = true; + material.ZWriteEnable = video::EZW_AUTO; } else { - material.ZWriteEnable = drawCount == 0; + material.ZWriteEnable = drawCount == 0 ? video::EZW_AUTO : video::EZW_OFF; } //resolve quake3 blendfunction to irrlicht Material Type diff --git a/source/Irrlicht/CSkyBoxSceneNode.cpp b/source/Irrlicht/CSkyBoxSceneNode.cpp index 015a1e57..2ad3fe6e 100644 --- a/source/Irrlicht/CSkyBoxSceneNode.cpp +++ b/source/Irrlicht/CSkyBoxSceneNode.cpp @@ -39,7 +39,7 @@ CSkyBoxSceneNode::CSkyBoxSceneNode(video::ITexture* top, video::ITexture* bottom video::SMaterial mat; mat.Lighting = false; mat.ZBuffer = video::ECFN_DISABLED; - mat.ZWriteEnable = false; + mat.ZWriteEnable = video::EZW_OFF; mat.AntiAliasing=0; mat.TextureLayer[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE; mat.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE; diff --git a/source/Irrlicht/CSkyDomeSceneNode.cpp b/source/Irrlicht/CSkyDomeSceneNode.cpp index 7b6affe0..7cf81f39 100644 --- a/source/Irrlicht/CSkyDomeSceneNode.cpp +++ b/source/Irrlicht/CSkyDomeSceneNode.cpp @@ -49,7 +49,7 @@ CSkyDomeSceneNode::CSkyDomeSceneNode(video::ITexture* sky, u32 horiRes, u32 vert Buffer = new SMeshBuffer(); Buffer->Material.Lighting = false; Buffer->Material.ZBuffer = video::ECFN_DISABLED; - Buffer->Material.ZWriteEnable = false; + Buffer->Material.ZWriteEnable = video::EZW_OFF; Buffer->Material.AntiAliasing = video::EAAM_OFF; Buffer->Material.setTexture(0, sky); Buffer->BoundingBox.MaxEdge.set(0,0,0); diff --git a/source/Irrlicht/CSoftwareDriver.cpp b/source/Irrlicht/CSoftwareDriver.cpp index 3ffebb1c..426aac29 100644 --- a/source/Irrlicht/CSoftwareDriver.cpp +++ b/source/Irrlicht/CSoftwareDriver.cpp @@ -139,7 +139,7 @@ void CSoftwareDriver::selectRightTriangleRenderer() renderer = ETR_TEXTURE_GOURAUD_ADD; } else - if ((Material.ZBuffer==ECFN_DISABLED) && !Material.ZWriteEnable) + if ((Material.ZBuffer==ECFN_DISABLED) && Material.ZWriteEnable == video::EZW_OFF) renderer = ETR_TEXTURE_GOURAUD_NOZ; else { diff --git a/source/Irrlicht/CSoftwareDriver2.cpp b/source/Irrlicht/CSoftwareDriver2.cpp index 2456a6f5..10a85e2e 100644 --- a/source/Irrlicht/CSoftwareDriver2.cpp +++ b/source/Irrlicht/CSoftwareDriver2.cpp @@ -177,7 +177,7 @@ void CBurningVideoDriver::setCurrentShader() ITexture *texture1 = Material.org.getTexture(1); bool zMaterialTest = Material.org.ZBuffer != ECFN_DISABLED && - Material.org.ZWriteEnable && + Material.org.ZWriteEnable != video::EZW_OFF && getWriteZBuffer(Material.org); EBurningFFShader shader = zMaterialTest ? ETR_TEXTURE_GOURAUD : ETR_TEXTURE_GOURAUD_NOZ; @@ -2291,7 +2291,7 @@ void CBurningVideoDriver::drawStencilShadowVolume(const core::arraysetMaterial(mat); diff --git a/tests/tests-last-passed-at.txt b/tests/tests-last-passed-at.txt index d18c9ac6..a62cf4c8 100644 --- a/tests/tests-last-passed-at.txt +++ b/tests/tests-last-passed-at.txt @@ -1,4 +1,4 @@ Tests finished. 72 tests of 72 passed. Compiled as DEBUG -Test suite pass at GMT Tue Dec 17 13:59:20 2019 +Test suite pass at GMT Thu Jan 02 15:17:55 2020