diff options
author | Armin Weiss <aw@openoffice.org> | 2008-05-14 08:22:09 +0000 |
---|---|---|
committer | Armin Weiss <aw@openoffice.org> | 2008-05-14 08:22:09 +0000 |
commit | 8c60e50f5f06d8ecdd7207f5daecc31905574a55 (patch) | |
tree | 14fb2ce494dbcbabe57b9582cc12f72e96870a65 /drawinglayer | |
parent | a1d9844c940ec385d3ec35966656103e0ba68068 (diff) |
#i39532# aw033 progresses from git
Diffstat (limited to 'drawinglayer')
21 files changed, 1226 insertions, 847 deletions
diff --git a/drawinglayer/inc/drawinglayer/primitive3d/sdrpolypolygonprimitive3d.hxx b/drawinglayer/inc/drawinglayer/primitive3d/sdrpolypolygonprimitive3d.hxx index dc02967f1f0b..5f4d19de29ec 100644 --- a/drawinglayer/inc/drawinglayer/primitive3d/sdrpolypolygonprimitive3d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive3d/sdrpolypolygonprimitive3d.hxx @@ -4,9 +4,9 @@ * * $RCSfile: sdrpolypolygonprimitive3d.hxx,v $ * - * $Revision: 1.2 $ + * $Revision: 1.3 $ * - * last change: $Author: aw $ $Date: 2006-11-07 15:49:07 $ + * last change: $Author: aw $ $Date: 2008-05-14 09:21:27 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -70,6 +70,9 @@ namespace drawinglayer // compare operator virtual bool operator==(const BasePrimitive3D& rPrimitive) const; + // get range + virtual basegfx::B3DRange getB3DRange(double fTime) const; + // provide unique ID DeclPrimitrive3DIDBlock() }; diff --git a/drawinglayer/inc/drawinglayer/primitive3d/sdrprimitive3d.hxx b/drawinglayer/inc/drawinglayer/primitive3d/sdrprimitive3d.hxx index 23273ce761f2..7bc70e3c7ebc 100644 --- a/drawinglayer/inc/drawinglayer/primitive3d/sdrprimitive3d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive3d/sdrprimitive3d.hxx @@ -4,9 +4,9 @@ * * $RCSfile: sdrprimitive3d.hxx,v $ * - * $Revision: 1.5 $ + * $Revision: 1.6 $ * - * last change: $Author: aw $ $Date: 2006-10-19 10:32:40 $ + * last change: $Author: aw $ $Date: 2008-05-14 09:21:28 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -83,6 +83,9 @@ namespace drawinglayer // will use given Slice3Ds and expand by evtl. line width / 2 basegfx::B3DRange get3DRangeFromSlices(const Slice3DVector& rSlices) const; + // tooling for testing. Eventually adds geometry to visualize the BoundRect of the primitive + Primitive3DSequence EventuallyAddTestRange(Primitive3DSequence& rTarget) const; + public: SdrPrimitive3D( const basegfx::B3DHomMatrix& rTransform, diff --git a/drawinglayer/inc/drawinglayer/processor3d/defaultprocessor3d.hxx b/drawinglayer/inc/drawinglayer/processor3d/defaultprocessor3d.hxx index f7de8ae0d2a8..9104d262985d 100644 --- a/drawinglayer/inc/drawinglayer/processor3d/defaultprocessor3d.hxx +++ b/drawinglayer/inc/drawinglayer/processor3d/defaultprocessor3d.hxx @@ -4,9 +4,9 @@ * * $RCSfile: defaultprocessor3d.hxx,v $ * - * $Revision: 1.2 $ + * $Revision: 1.3 $ * - * last change: $Author: aw $ $Date: 2006-10-19 10:33:20 $ + * last change: $Author: aw $ $Date: 2008-05-14 09:21:28 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -52,22 +52,12 @@ #include <basegfx/color/bcolormodifier.hxx> #endif -#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_BASEPRIMITIVE2D_HXX -#include <drawinglayer/primitive2d/baseprimitive2d.hxx> -#endif - -#ifndef INCLUDED_DRAWINGLAYER_GEOMETRY_TRANSFORMATION3D_HXX -#include <drawinglayer/geometry/transformation3d.hxx> -#endif - -#ifndef _SV_BITMAPEX_HXX -#include <vcl/bitmapex.hxx> -#endif - ////////////////////////////////////////////////////////////////////////////// // predefines namespace basegfx { class BZPixelRaster; + class B3DPolygon; + class B3DPolyPolygon; } namespace drawinglayer { namespace attribute { @@ -82,7 +72,6 @@ namespace drawinglayer { namespace primitive3d { class GradientTexturePrimitive3D; class HatchTexturePrimitive3D; class BitmapTexturePrimitive3D; - class AlphaTexturePrimitive3D; class TransformPrimitive3D; class ModifiedColorPrimitive3D; }} @@ -99,19 +88,19 @@ namespace drawinglayer { class DefaultProcessor3D : public BaseProcessor3D { - private: + protected: // render information const attribute::SdrSceneAttribute& mrSdrSceneAttribute; // read-only scene infos (normal handling, etc...) const attribute::SdrLightingAttribute& mrSdrLightingAttribute; // read-only light infos (lights, etc...) - basegfx::B3DHomMatrix maDeviceToView; // scale and translate to map to target view size + + // renderer transformations and range. Need to be correctly set by the + // derived implementations basegfx::B3DHomMatrix maWorldToEye; // world to eye coordinates basegfx::B3DHomMatrix maWorldToView; // mul maWorldToEye with maProjection and maDeviceToView - basegfx::B3DHomMatrix maInvEyeToView; // back from view to eye coordinates - basegfx::B3DHomMatrix maInvWorldToView; // back from view to world coordinates basegfx::B2DRange maRasterRange; // the (0, 0, W, H) range from mpBZPixelRaster - // the target - basegfx::BZPixelRaster* mpBZPixelRaster; + // inverse from maWorldToView, filled on demand + basegfx::B3DHomMatrix maInvWorldToView; // back from view to world coordinates // the modifiedColorPrimitive stack basegfx::BColorModifierStack maBColorModifierStack; @@ -122,62 +111,64 @@ namespace drawinglayer // the current active transparence texture texture::GeoTexSvx* mpTransparenceGeoTexSvx; + // width and height in target pixels + sal_uInt32 mnRasterWidth; + sal_uInt32 mnRasterHeight; + // bitfield unsigned mbModulate : 1; unsigned mbFilter : 1; - unsigned mbProcessTransparent : 1; - unsigned mbContainsTransparent : 1; + unsigned mbSimpleTextureActive : 1; ////////////////////////////////////////////////////////////////////////////// // rendering support - void impRender_GRX3(const primitive3d::GradientTexturePrimitive3D& rPrimitive, bool bTransparence); - void impRender_HAX3(const primitive3d::HatchTexturePrimitive3D& rPrimitive); - void impRender_BMX3(const primitive3d::BitmapTexturePrimitive3D& rPrimitive); - void impRender_MCOL(const primitive3d::ModifiedColorPrimitive3D& rModifiedCandidate); - void impRender_POH3(const primitive3d::PolygonHairlinePrimitive3D& rPrimitive); - void impRender_POM3(const primitive3d::PolyPolygonMaterialPrimitive3D& rPrimitive); - void impRender_TRN3(const primitive3d::TransformPrimitive3D& rTransformCandidate); + void impRenderGradientTexturePrimitive3D(const primitive3d::GradientTexturePrimitive3D& rPrimitive, bool bTransparence); + void impRenderHatchTexturePrimitive3D(const primitive3d::HatchTexturePrimitive3D& rPrimitive); + void impRenderBitmapTexturePrimitive3D(const primitive3d::BitmapTexturePrimitive3D& rPrimitive); + void impRenderModifiedColorPrimitive3D(const primitive3d::ModifiedColorPrimitive3D& rModifiedCandidate); + void impRenderPolygonHairlinePrimitive3D(const primitive3d::PolygonHairlinePrimitive3D& rPrimitive); + void impRenderPolyPolygonMaterialPrimitive3D(const primitive3d::PolyPolygonMaterialPrimitive3D& rPrimitive); + void impRenderTransformPrimitive3D(const primitive3d::TransformPrimitive3D& rTransformCandidate); ////////////////////////////////////////////////////////////////////////////// - // lighting support - basegfx::BColor impSolveColorModel( - basegfx::B3DVector aNormal, - const attribute::MaterialAttribute3D& rMaterial); + // rasterconversions for filled and non-filled polygons. These NEED to be + // implemented from derivations + virtual void rasterconvertB3DPolygon(const attribute::MaterialAttribute3D& rMaterial, const basegfx::B3DPolygon& rHairline) const = 0; + virtual void rasterconvertB3DPolyPolygon(const attribute::MaterialAttribute3D& rMaterial, const basegfx::B3DPolyPolygon& rFill) const = 0; + + // the processing method for a single, known primitive + virtual void processBasePrimitive3D(const primitive3d::BasePrimitive3D& rBasePrimitive); public: DefaultProcessor3D( - const geometry::ViewInformation2D& rViewInformation, - const geometry::Transformation3D& rTransformation3D, + double fTime, const attribute::SdrSceneAttribute& rSdrSceneAttribute, - const attribute::SdrLightingAttribute& rSdrLightingAttribute, - double fSizeX, - double fSizeY, - const basegfx::B2DRange& rVisiblePart); + const attribute::SdrLightingAttribute& rSdrLightingAttribute); virtual ~DefaultProcessor3D(); - // the central processing method + // the central processing method. It checks for known primitive implementation + // and uses processBasePrimitive3D or forwards to API implementations virtual void process(const primitive3d::Primitive3DSequence& rSource); - // helpers for drawing transparent parts in 2nd run - void processNonTransparent(const primitive3d::Primitive3DSequence& rSource); - void processTransparent(const primitive3d::Primitive3DSequence& rSource); - // data read access + const attribute::SdrSceneAttribute& getSdrSceneAttribute() const { return mrSdrSceneAttribute; } const attribute::SdrLightingAttribute& getSdrLightingAttribute() const { return mrSdrLightingAttribute; } + + // data read access renderer stuff const basegfx::BColorModifierStack& getBColorModifierStack() const { return maBColorModifierStack; } const texture::GeoTexSvx* getGeoTexSvx() const { return mpGeoTexSvx; } const texture::GeoTexSvx* getTransparenceGeoTexSvx() const { return mpTransparenceGeoTexSvx; } bool getModulate() const { return mbModulate; } bool getFilter() const { return mbFilter; } - - // get the result as bitmapEx - BitmapEx getBitmapEx() const; + bool getSimpleTextureActive() const { return mbSimpleTextureActive; } + sal_uInt32 getRasterWidth() const { return mnRasterWidth; } + sal_uInt32 getRasterHeight() const { return mnRasterHeight; } }; } // end of namespace processor3d } // end of namespace drawinglayer ////////////////////////////////////////////////////////////////////////////// -#endif //_DRAWINGLAYER_PROCESSOR3D_DEFAULTPROCESSOR3D_HXX +#endif // INCLUDED_DRAWINGLAYER_PROCESSOR3D_DEFAULTPROCESSOR3D_HXX // eof diff --git a/drawinglayer/inc/drawinglayer/processor3d/zbufferprocessor3d.hxx b/drawinglayer/inc/drawinglayer/processor3d/zbufferprocessor3d.hxx new file mode 100644 index 000000000000..d99b717c6ee6 --- /dev/null +++ b/drawinglayer/inc/drawinglayer/processor3d/zbufferprocessor3d.hxx @@ -0,0 +1,137 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: zbufferprocessor3d.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: aw $ $Date: 2008-05-14 09:21:28 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef INCLUDED_DRAWINGLAYER_PROCESSOR3D_ZBUFFERPROCESSOR3D_HXX +#define INCLUDED_DRAWINGLAYER_PROCESSOR3D_ZBUFFERPROCESSOR3D_HXX + +#ifndef INCLUDED_DRAWINGLAYER_PROCESSOR3D_DEFAULTPROCESSOR3D_HXX +#include <drawinglayer/processor3d/defaultprocessor3d.hxx> +#endif + +#ifndef _SV_BITMAPEX_HXX +#include <vcl/bitmapex.hxx> +#endif + +////////////////////////////////////////////////////////////////////////////// +// predefines + +namespace basegfx { + class BZPixelRaster; +} + +namespace drawinglayer { + namespace attribute { + class SdrSceneAttribute; + class SdrLightingAttribute; + class MaterialAttribute3D; + } + namespace geometry { + class ViewInformation2D; + class Transformation3D; + } +} + +class ZBufferRasterConverter3D; + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace processor3d + { + class ZBufferProcessor3D : public DefaultProcessor3D + { + private: + // the raster target, a Z-Buffer + basegfx::BZPixelRaster* mpBZPixelRaster; + + // inverse of EyeToView for rasterconversion with evtl. Phong shading + basegfx::B3DHomMatrix maInvEyeToView; + + // The raster converter for Z-Buffer + ZBufferRasterConverter3D* mpZBufferRasterConverter3D; + + // AA value. Defines how many oversmples will be used in X and Y. Values 0, 1 + // will switch it off while e.g. 2 will use 2x2 pixels for each pixel to create + sal_uInt16 mnAntiAlialize; + + // bitfield + // a combination of bools to allow two-pass rendering to render + // the transparent parts in the 2nd run (if any) as needed for Z-Buffer + unsigned mbProcessTransparent : 1; + unsigned mbContainsTransparent : 1; + + + ////////////////////////////////////////////////////////////////////////////// + // rasterconversions for filled and non-filled polygons + virtual void rasterconvertB3DPolygon(const attribute::MaterialAttribute3D& rMaterial, const basegfx::B3DPolygon& rHairline) const; + virtual void rasterconvertB3DPolyPolygon(const attribute::MaterialAttribute3D& rMaterial, const basegfx::B3DPolyPolygon& rFill) const; + + // the processing method for a single, known primitive + virtual void processBasePrimitive3D(const primitive3d::BasePrimitive3D& rBasePrimitive); + + public: + ZBufferProcessor3D( + const geometry::ViewInformation2D& rViewInformation, + const geometry::Transformation3D& rTransformation3D, + const attribute::SdrSceneAttribute& rSdrSceneAttribute, + const attribute::SdrLightingAttribute& rSdrLightingAttribute, + double fSizeX, + double fSizeY, + const basegfx::B2DRange& rVisiblePart, + sal_uInt16 nAntiAlialize); + virtual ~ZBufferProcessor3D(); + + // helpers for drawing transparent parts in 2nd run. To use this + // processor, call processNonTransparent and then processTransparent + // with the same primitives. The 2nd call will only do something, + // when transparent parts are contained + void processNonTransparent(const primitive3d::Primitive3DSequence& rSource); + void processTransparent(const primitive3d::Primitive3DSequence& rSource); + + // get the result as bitmapEx + BitmapEx getBitmapEx() const; + + // data access + const basegfx::B3DHomMatrix& getViewToEye() const { return maInvEyeToView; } + }; + } // end of namespace processor3d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +#endif //INCLUDED_DRAWINGLAYER_PROCESSOR3D_ZBUFFERPROCESSOR3D_HXX + +// eof diff --git a/drawinglayer/prj/d.lst b/drawinglayer/prj/d.lst index bfee82aadd55..e5a6d6ae8b57 100644 --- a/drawinglayer/prj/d.lst +++ b/drawinglayer/prj/d.lst @@ -84,7 +84,8 @@ mkdir: %_DEST%\inc%_EXT%\drawinglayer\processor2d mkdir: %_DEST%\inc%_EXT%\drawinglayer\processor3d ..\inc\drawinglayer\processor3d\baseprocessor3d.hxx %_DEST%\inc%_EXT%\drawinglayer\processor3d\baseprocessor3d.hxx -..\inc\drawinglayer\processor3d\defaultprocessor3d.hxx %_DEST%\inc%_EXT%\drawinglayer\processor3d\defaultprocessor3d.hxx +..\inc\drawinglayer\processor3d\zbufferprocessor3d.hxx %_DEST%\inc%_EXT%\drawinglayer\processor3d\zbufferprocessor3d.hxx +..\inc\drawinglayer\processor3d\tbufferprocessor3d.hxx %_DEST%\inc%_EXT%\drawinglayer\processor3d\tbufferprocessor3d.hxx mkdir: %_DEST%\inc%_EXT%\drawinglayer\attribute ..\inc\drawinglayer\attribute\fillattribute.hxx %_DEST%\inc%_EXT%\drawinglayer\attribute\fillattribute.hxx diff --git a/drawinglayer/source/primitive2d/gridprimitive2d.cxx b/drawinglayer/source/primitive2d/gridprimitive2d.cxx index bf09b9d7da19..a9786591763e 100644 --- a/drawinglayer/source/primitive2d/gridprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/gridprimitive2d.cxx @@ -4,9 +4,9 @@ * * $RCSfile: gridprimitive2d.cxx,v $ * - * $Revision: 1.7 $ + * $Revision: 1.8 $ * - * last change: $Author: aw $ $Date: 2008-03-05 09:15:42 $ + * last change: $Author: aw $ $Date: 2008-05-14 09:21:53 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -93,7 +93,7 @@ namespace drawinglayer double fStepY(getHeight()); const double fMinimalStep(10.0); - // guarantee a step width of 100.0 + // guarantee a step width of 10.0 if(basegfx::fTools::less(fStepX, fMinimalStep)) { fStepX = fMinimalStep; @@ -170,12 +170,22 @@ namespace drawinglayer for(double fY(0.0); fY < aScale.getY(); fY += fStepY) { const bool bYZero(basegfx::fTools::equalZero(fY)); - basegfx::B2DPoint aViewPos(aRST * basegfx::B2DPoint(fX, fY)); - if(rViewInformation.getDiscreteViewport().isInside(aViewPos) && !bXZero && !bYZero) + if(!bXZero && !bYZero) { - const basegfx::B2DPoint aLogicPos(rViewInformation.getInverseViewTransformation() * aViewPos); - aPositionsCross.push_back(aLogicPos); + // get discrete position and test against 3x3 area surrounding it + // since it's a cross + const double fHalfCrossSize(3.0 * 0.5); + const basegfx::B2DPoint aViewPos(aRST * basegfx::B2DPoint(fX, fY)); + const basegfx::B2DRange aDiscreteRangeCross( + aViewPos.getX() - fHalfCrossSize, aViewPos.getY() - fHalfCrossSize, + aViewPos.getX() + fHalfCrossSize, aViewPos.getY() + fHalfCrossSize); + + if(rViewInformation.getDiscreteViewport().overlaps(aDiscreteRangeCross)) + { + const basegfx::B2DPoint aLogicPos(rViewInformation.getInverseViewTransformation() * aViewPos); + aPositionsCross.push_back(aLogicPos); + } } if(getSubdivisionsX() && !bYZero) @@ -184,7 +194,7 @@ namespace drawinglayer for(sal_uInt32 a(0L); a < nSmallStepsX && fF < aScale.getX(); a++, fF += fSmallStepX) { - aViewPos = aRST * basegfx::B2DPoint(fF, fY); + const basegfx::B2DPoint aViewPos(aRST * basegfx::B2DPoint(fF, fY)); if(rViewInformation.getDiscreteViewport().isInside(aViewPos)) { @@ -200,7 +210,7 @@ namespace drawinglayer for(sal_uInt32 a(0L); a < nSmallStepsY && fF < aScale.getY(); a++, fF += fSmallStepY) { - aViewPos = aRST * basegfx::B2DPoint(fX, fF); + const basegfx::B2DPoint aViewPos(aRST * basegfx::B2DPoint(fX, fF)); if(rViewInformation.getDiscreteViewport().isInside(aViewPos)) { diff --git a/drawinglayer/source/primitive2d/polygonprimitive2d.cxx b/drawinglayer/source/primitive2d/polygonprimitive2d.cxx index cc4ada33da6d..dacf1f624b52 100644 --- a/drawinglayer/source/primitive2d/polygonprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/polygonprimitive2d.cxx @@ -4,9 +4,9 @@ * * $RCSfile: polygonprimitive2d.cxx,v $ * - * $Revision: 1.10 $ + * $Revision: 1.11 $ * - * last change: $Author: aw $ $Date: 2008-03-05 09:15:43 $ + * last change: $Author: aw $ $Date: 2008-05-14 09:21:53 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -288,18 +288,30 @@ namespace drawinglayer return false; } - basegfx::B2DRange PolygonStrokePrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const + basegfx::B2DRange PolygonStrokePrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const { - // get range of it (subdivided) - basegfx::B2DRange aRetval(basegfx::tools::getRange(getB2DPolygon())); - - // if width, grow by line width if(getLineAttribute().getWidth()) { - aRetval.grow(getLineAttribute().getWidth() / 2.0); + if(basegfx::B2DLINEJOIN_MITER == getLineAttribute().getLineJoin()) + { + // if line is mitered, use parent call since mitered line + // geometry may use more space than the geometry grown by half line width + return BasePrimitive2D::getB2DRange(rViewInformation); + } + else + { + // for all other B2DLINEJOIN_* get the range from the base geometry + // and expand by half the line width + basegfx::B2DRange aRetval(basegfx::tools::getRange(getB2DPolygon())); + aRetval.grow(getLineAttribute().getWidth() / 2.0); + return aRetval; + } + } + else + { + // range of polygon is adequate + return basegfx::tools::getRange(getB2DPolygon()); } - - return aRetval; } // provide unique ID diff --git a/drawinglayer/source/primitive2d/sceneprimitive2d.cxx b/drawinglayer/source/primitive2d/sceneprimitive2d.cxx index dd1c73ccd305..b90c017d5b9d 100644 --- a/drawinglayer/source/primitive2d/sceneprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/sceneprimitive2d.cxx @@ -4,9 +4,9 @@ * * $RCSfile: sceneprimitive2d.cxx,v $ * - * $Revision: 1.11 $ + * $Revision: 1.12 $ * - * last change: $Author: aw $ $Date: 2008-03-13 08:22:01 $ + * last change: $Author: aw $ $Date: 2008-05-14 09:21:53 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -36,65 +36,23 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_drawinglayer.hxx" -#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_SCENEPRIMITIVE2D_HXX #include <drawinglayer/primitive2d/sceneprimitive2d.hxx> -#endif - -#ifndef _BGFX_TOOLS_CANVASTOOLS_HXX #include <basegfx/tools/canvastools.hxx> -#endif - -#ifndef _BGFX_POLYGON_B2DPOLYGONTOOLS_HXX #include <basegfx/polygon/b2dpolygontools.hxx> -#endif - -#ifndef _BGFX_POLYGON_B2DPOLYGON_HXX #include <basegfx/polygon/b2dpolygon.hxx> -#endif - -#ifndef _BGFX_POLYPOLYGON_B2DPOLYGONCLIPPER_HXX #include <basegfx/polygon/b2dpolygonclipper.hxx> -#endif - -#ifndef _BGFX_POLYPOLYGON_B2DPOLYGONTOOLS_HXX #include <basegfx/polygon/b2dpolypolygontools.hxx> -#endif - -#ifndef _BGFX_MATRIX_B2DHOMMATRIX_HXX #include <basegfx/matrix/b2dhommatrix.hxx> -#endif - -#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_BITMAPPRIMITIVE2D_HXX #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx> -#endif - -#ifndef INCLUDED_DRAWINGLAYER_PROCESSOR3D_DEFAULTPROCESSOR3D_HXX -#include <drawinglayer/processor3d/defaultprocessor3d.hxx> -#endif - -#ifndef INCLUDED_DRAWINGLAYER_PROCESSOR3D_SHADOW3DEXTRACTOR_HXX +#include <drawinglayer/processor3d/zbufferprocessor3d.hxx> +#include <drawinglayer/processor3d/tbufferprocessor3d.hxx> #include <drawinglayer/processor3d/shadow3dextractor.hxx> -#endif - -#ifndef INCLUDED_DRAWINGLAYER_PROCESSOR3D_LABEL3DEXTRACTOR_HXX #include <drawinglayer/processor3d/label3dextractor.hxx> -#endif - -#ifndef INCLUDED_DRAWINGLAYER_GEOMETRY_VIEWINFORMATION2D_HXX #include <drawinglayer/geometry/viewinformation2d.hxx> -#endif - -#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_PRIMITIVETYPES2D_HXX #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> -#endif - -#ifndef INCLUDED_SVTOOLS_OPTIONSDRAWINGLAYER_HXX #include <svtools/optionsdrawinglayer.hxx> -#endif - -#ifndef INCLUDED_DRAWINGLAYER_PROCESSOR3D_GEOMETRY2DEXTRACTOR_HXX #include <drawinglayer/processor3d/geometry2dextractor.hxx> -#endif +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> ////////////////////////////////////////////////////////////////////////////// @@ -114,15 +72,6 @@ namespace drawinglayer { // use unit range and transform to discrete coordinates rDiscreteRange = basegfx::B2DRange(0.0, 0.0, 1.0, 1.0); - - { - // take a look at object transformation - basegfx::B2DVector aScale, aTranslate; - double fRotate, fShearX; - getObjectTransformation().decompose(aScale, aTranslate, fRotate, fShearX); - fRotate = 0; - } - rDiscreteRange.transform(rViewInformation.getViewTransformation() * getObjectTransformation()); // force to discrete expanded bounds (it grows, so expanding works perfectly well) @@ -218,20 +167,25 @@ namespace drawinglayer aDiscreteRange.getHeight() * fReduceFactor); aLogicRenderSize *= rViewInformation.getInverseViewTransformation(); + // determine the oversample value + static bool bDoOversample(false); + static sal_uInt16 nDefaultOversampleValue(3); + const sal_uInt16 nOversampleValue((bDoOversample || aDrawinglayerOpt.IsAntiAliasing()) ? nDefaultOversampleValue : 0); + // use default 3D primitive processor to create BitmapEx for aUnitVisiblePart and process - processor3d::DefaultProcessor3D aProcessor3D( + processor3d::ZBufferProcessor3D aZBufferProcessor3D( rViewInformation, getTransformation3D(), getSdrSceneAttribute(), getSdrLightingAttribute(), aLogicRenderSize.getX(), aLogicRenderSize.getY(), - aUnitVisibleRange); - - aProcessor3D.processNonTransparent(getChildren3D()); - aProcessor3D.processTransparent(getChildren3D()); + aUnitVisibleRange, + nOversampleValue); - const BitmapEx aNewBitmap(aProcessor3D.getBitmapEx()); + aZBufferProcessor3D.processNonTransparent(getChildren3D()); + aZBufferProcessor3D.processTransparent(getChildren3D()); + const BitmapEx aNewBitmap(aZBufferProcessor3D.getBitmapEx()); const Size aBitmapSizePixel(aNewBitmap.GetSizePixel()); if(aBitmapSizePixel.getWidth() && aBitmapSizePixel.getHeight()) @@ -248,9 +202,19 @@ namespace drawinglayer aNew2DTransform *= rViewInformation.getInverseViewTransformation(); // create bitmap primitive and add - BitmapPrimitive2D* pNewTextBitmap = new BitmapPrimitive2D(aNewBitmap, aNew2DTransform); - const Primitive2DReference xRef(pNewTextBitmap); + const Primitive2DReference xRef(new BitmapPrimitive2D(aNewBitmap, aNew2DTransform)); appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, xRef); + + // test: Allow to add an outline in the debugger when tests are needed + static bool bAddOutlineToCreated3DSceneRepresentation(false); + + if(bAddOutlineToCreated3DSceneRepresentation) + { + basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(basegfx::B2DRange(0.0, 0.0, 1.0, 1.0))); + aOutline.transform(aNew2DTransform); + const Primitive2DReference xRef2(new PolygonHairlinePrimitive2D(aOutline, basegfx::BColor(1.0, 0.0, 0.0))); + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, xRef2); + } } } diff --git a/drawinglayer/source/primitive3d/hatchtextureprimitive3d.cxx b/drawinglayer/source/primitive3d/hatchtextureprimitive3d.cxx index 2963b14380f5..5381264214c3 100644 --- a/drawinglayer/source/primitive3d/hatchtextureprimitive3d.cxx +++ b/drawinglayer/source/primitive3d/hatchtextureprimitive3d.cxx @@ -4,9 +4,9 @@ * * $RCSfile: hatchtextureprimitive3d.cxx,v $ * - * $Revision: 1.8 $ + * $Revision: 1.9 $ * - * last change: $Author: aw $ $Date: 2008-03-05 09:15:44 $ + * last change: $Author: aw $ $Date: 2008-05-14 09:21:53 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -234,7 +234,7 @@ namespace drawinglayer if(a2DHatchLines.count()) { // clip against texture polygon - a2DHatchLines = basegfx::tools::clipPolyPolygonOnPolyPolygon(a2DHatchLines, aTexPolyPolygon, true, false); + a2DHatchLines = basegfx::tools::clipPolyPolygonOnPolyPolygon(a2DHatchLines, aTexPolyPolygon, true, true); } if(a2DHatchLines.count()) diff --git a/drawinglayer/source/primitive3d/sdrcubeprimitive3d.cxx b/drawinglayer/source/primitive3d/sdrcubeprimitive3d.cxx index c39a00bfc1e1..1303c4c28ea2 100644 --- a/drawinglayer/source/primitive3d/sdrcubeprimitive3d.cxx +++ b/drawinglayer/source/primitive3d/sdrcubeprimitive3d.cxx @@ -4,9 +4,9 @@ * * $RCSfile: sdrcubeprimitive3d.cxx,v $ * - * $Revision: 1.8 $ + * $Revision: 1.9 $ * - * last change: $Author: aw $ $Date: 2008-03-05 09:15:44 $ + * last change: $Author: aw $ $Date: 2008-05-14 09:21:53 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -195,7 +195,7 @@ namespace drawinglayer appendPrimitive3DSequenceToPrimitive3DSequence(aRetval, aShadow); } - return aRetval; + return EventuallyAddTestRange(aRetval); } SdrCubePrimitive3D::SdrCubePrimitive3D( diff --git a/drawinglayer/source/primitive3d/sdrextrudeprimitive3d.cxx b/drawinglayer/source/primitive3d/sdrextrudeprimitive3d.cxx index 6326aa6d78c8..7a4bcd7d0e5b 100644 --- a/drawinglayer/source/primitive3d/sdrextrudeprimitive3d.cxx +++ b/drawinglayer/source/primitive3d/sdrextrudeprimitive3d.cxx @@ -4,9 +4,9 @@ * * $RCSfile: sdrextrudeprimitive3d.cxx,v $ * - * $Revision: 1.10 $ + * $Revision: 1.11 $ * - * last change: $Author: aw $ $Date: 2008-03-19 04:35:22 $ + * last change: $Author: aw $ $Date: 2008-05-14 09:21:53 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -225,7 +225,7 @@ namespace drawinglayer } } - return aRetval; + return EventuallyAddTestRange(aRetval); } void SdrExtrudePrimitive3D::impCreateSlices() @@ -242,7 +242,9 @@ namespace drawinglayer const Slice3DVector& SdrExtrudePrimitive3D::getSlices() const { - if(getPolyPolygon().count() && !maSlices.size() && (getSdrLFSAttribute().getFill() || getSdrLFSAttribute().getLine())) + // This can be made dependent of getSdrLFSAttribute().getFill() and getSdrLFSAttribute().getLine() + // again when no longer geometry is needed for non-visible 3D objects as it is now for chart + if(getPolyPolygon().count() && !maSlices.size()) { ::osl::Mutex m_mutex; const_cast< SdrExtrudePrimitive3D& >(*this).impCreateSlices(); diff --git a/drawinglayer/source/primitive3d/sdrlatheprimitive3d.cxx b/drawinglayer/source/primitive3d/sdrlatheprimitive3d.cxx index 0bd1aafbe461..ff128619019f 100644 --- a/drawinglayer/source/primitive3d/sdrlatheprimitive3d.cxx +++ b/drawinglayer/source/primitive3d/sdrlatheprimitive3d.cxx @@ -4,9 +4,9 @@ * * $RCSfile: sdrlatheprimitive3d.cxx,v $ * - * $Revision: 1.11 $ + * $Revision: 1.12 $ * - * last change: $Author: aw $ $Date: 2008-03-19 04:35:22 $ + * last change: $Author: aw $ $Date: 2008-05-14 09:21:53 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -219,7 +219,7 @@ namespace drawinglayer } } - return aRetval; + return EventuallyAddTestRange(aRetval); } void SdrLathePrimitive3D::impCreateSlices() @@ -247,7 +247,9 @@ namespace drawinglayer const Slice3DVector& SdrLathePrimitive3D::getSlices() const { - if(getPolyPolygon().count() && !maSlices.size() && (getSdrLFSAttribute().getFill() || getSdrLFSAttribute().getLine())) + // This can be made dependent of getSdrLFSAttribute().getFill() and getSdrLFSAttribute().getLine() + // again when no longer geometry is needed for non-visible 3D objects as it is now for chart + if(getPolyPolygon().count() && !maSlices.size()) { ::osl::Mutex m_mutex; const_cast< SdrLathePrimitive3D& >(*this).impCreateSlices(); diff --git a/drawinglayer/source/primitive3d/sdrpolypolygonprimitive3d.cxx b/drawinglayer/source/primitive3d/sdrpolypolygonprimitive3d.cxx index 6b98e7419a0d..0b7db9f187cd 100644 --- a/drawinglayer/source/primitive3d/sdrpolypolygonprimitive3d.cxx +++ b/drawinglayer/source/primitive3d/sdrpolypolygonprimitive3d.cxx @@ -4,9 +4,9 @@ * * $RCSfile: sdrpolypolygonprimitive3d.cxx,v $ * - * $Revision: 1.4 $ + * $Revision: 1.5 $ * - * last change: $Author: aw $ $Date: 2008-03-05 09:15:44 $ + * last change: $Author: aw $ $Date: 2008-05-14 09:21:53 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -48,6 +48,14 @@ #include <drawinglayer/primitive3d/drawinglayer_primitivetypes3d.hxx> #endif +#ifndef _BGFX_POLYPOLYGON_B3DPOLYGONTOOLS_HXX +#include <basegfx/polygon/b3dpolypolygontools.hxx> +#endif + +#ifndef INCLUDED_DRAWINGLAYER_ATTRIBUTE_SDRATTRIBUTE_HXX +#include <drawinglayer/attribute/sdrattribute.hxx> +#endif + ////////////////////////////////////////////////////////////////////////////// using namespace com::sun::star; @@ -95,7 +103,7 @@ namespace drawinglayer } } - return aRetval; + return EventuallyAddTestRange(aRetval); } SdrPolyPolygonPrimitive3D::SdrPolyPolygonPrimitive3D( @@ -121,6 +129,35 @@ namespace drawinglayer return false; } + basegfx::B3DRange SdrPolyPolygonPrimitive3D::getB3DRange(double /*fTime*/) const + { + // added this implementation to make sure that non-visible objects of this + // kind will deliver their expansion. If not implemented, it would never deliver + // the used space for non-visible objects since the decomposition for that + // case will be empty (what is correct). To support chart ATM which relies on + // non-visible objects occupying space in 3D, this method was added + basegfx::B3DRange aRetval; + + if(getPolyPolygon3D().count()) + { + aRetval = basegfx::tools::getRange(getPolyPolygon3D()); + aRetval.transform(getTransform()); + + if(getSdrLFSAttribute().getLine()) + { + const attribute::SdrLineAttribute& rLine = *getSdrLFSAttribute().getLine(); + + if(rLine.isVisible() && !basegfx::fTools::equalZero(rLine.getWidth())) + { + // expand by half LineWidth as tube radius + aRetval.grow(rLine.getWidth() / 2.0); + } + } + } + + return aRetval; + } + // provide unique ID ImplPrimitrive3DIDBlock(SdrPolyPolygonPrimitive3D, PRIMITIVE3D_ID_SDRPOLYPOLYGONPRIMITIVE3D) diff --git a/drawinglayer/source/primitive3d/sdrprimitive3d.cxx b/drawinglayer/source/primitive3d/sdrprimitive3d.cxx index 27a0e6a91867..49d7622d44dc 100644 --- a/drawinglayer/source/primitive3d/sdrprimitive3d.cxx +++ b/drawinglayer/source/primitive3d/sdrprimitive3d.cxx @@ -4,9 +4,9 @@ * * $RCSfile: sdrprimitive3d.cxx,v $ * - * $Revision: 1.6 $ + * $Revision: 1.7 $ * - * last change: $Author: aw $ $Date: 2008-03-05 09:15:44 $ + * last change: $Author: aw $ $Date: 2008-05-14 09:21:53 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -48,6 +48,10 @@ #include <basegfx/polygon/b3dpolypolygontools.hxx> #endif +#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE3D_SDRDECOMPOSITIONTOOLS3D_HXX +#include <drawinglayer/primitive3d/sdrdecompositiontools3d.hxx> +#endif + ////////////////////////////////////////////////////////////////////////////// using namespace com::sun::star; @@ -96,7 +100,7 @@ namespace drawinglayer if(rLine.isVisible() && !basegfx::fTools::equalZero(rLine.getWidth())) { - // expand by hald LineWidth as tube radius + // expand by half LineWidth as tube radius aRetval.grow(rLine.getWidth() / 2.0); } } @@ -132,6 +136,31 @@ namespace drawinglayer return false; } + + Primitive3DSequence SdrPrimitive3D::EventuallyAddTestRange(Primitive3DSequence& rTarget) const + { + static bool bAddBoundCretsForTest(false); + + if(bAddBoundCretsForTest) + { + const basegfx::B3DRange a3DRange(getB3DRange(0.0)); + const basegfx::B3DPolyPolygon aLine(basegfx::tools::createCubePolyPolygonFromB3DRange(a3DRange)); + const basegfx::BColor aBColor(0.0, 0.0, 1.0); + const ::std::vector< double > aEmptyVector; + const drawinglayer::attribute::SdrLineAttribute aLineAttribute( + basegfx::B2DLINEJOIN_NONE, + 0.0, + 0.0, + aBColor, + aEmptyVector, + 0.0); + const basegfx::B3DHomMatrix aEmptyTransform; + const Primitive3DSequence aLines(create3DPolyPolygonLinePrimitives(aLine, aEmptyTransform, aLineAttribute)); + appendPrimitive3DSequenceToPrimitive3DSequence(rTarget, aLines); + } + + return rTarget; + } } // end of namespace primitive3d } // end of namespace drawinglayer diff --git a/drawinglayer/source/primitive3d/sdrsphereprimitive3d.cxx b/drawinglayer/source/primitive3d/sdrsphereprimitive3d.cxx index a74e948324b8..37a31f2c95e0 100644 --- a/drawinglayer/source/primitive3d/sdrsphereprimitive3d.cxx +++ b/drawinglayer/source/primitive3d/sdrsphereprimitive3d.cxx @@ -4,9 +4,9 @@ * * $RCSfile: sdrsphereprimitive3d.cxx,v $ * - * $Revision: 1.9 $ + * $Revision: 1.10 $ * - * last change: $Author: aw $ $Date: 2008-03-05 09:15:44 $ + * last change: $Author: aw $ $Date: 2008-05-14 09:21:54 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -182,7 +182,7 @@ namespace drawinglayer appendPrimitive3DSequenceToPrimitive3DSequence(aRetval, aShadow); } - return aRetval; + return EventuallyAddTestRange(aRetval); } SdrSpherePrimitive3D::SdrSpherePrimitive3D( diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx index 52c6b77647ff..17b9ef1cef03 100644 --- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx @@ -4,9 +4,9 @@ * * $RCSfile: vclmetafileprocessor2d.cxx,v $ * - * $Revision: 1.21 $ + * $Revision: 1.22 $ * - * last change: $Author: aw $ $Date: 2008-03-13 08:22:03 $ + * last change: $Author: aw $ $Date: 2008-05-14 09:21:54 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -1431,7 +1431,6 @@ namespace drawinglayer { // set VCL clip region; subdivide before conversion to tools polygon. Subdivision necessary (!) mpOutputDevice->Push(PUSH_CLIPREGION); - mpOutputDevice->SetClipRegion(Region(PolyPolygon(maClipPolyPolygon))); mpOutputDevice->SetClipRegion(Region(PolyPolygon(basegfx::tools::adaptiveSubdivideByAngle(maClipPolyPolygon)))); } diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx b/drawinglayer/source/processor2d/vclprocessor2d.cxx index 6ac5fb9b9c02..e6c5677c590d 100644 --- a/drawinglayer/source/processor2d/vclprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx @@ -4,9 +4,9 @@ * * $RCSfile: vclprocessor2d.cxx,v $ * - * $Revision: 1.27 $ + * $Revision: 1.28 $ * - * last change: $Author: aw $ $Date: 2008-04-16 04:59:58 $ + * last change: $Author: aw $ $Date: 2008-05-14 09:21:54 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -700,9 +700,26 @@ namespace drawinglayer // get BoundRect basegfx::B2DRange aOutlineRange(rMetaCandidate.getB2DRange(getViewInformation2D())); aOutlineRange.transform(maCurrentTransformation); - const Rectangle aDestRectView( - basegfx::fround(aOutlineRange.getMinX()), basegfx::fround(aOutlineRange.getMinY()), - basegfx::fround(aOutlineRange.getMaxX()), basegfx::fround(aOutlineRange.getMaxY())); + + // Due to the integer MapModes used from VCL aind inside MetaFiles errors of up to three + // pixels in size may happen. As long as there is no better way (e.g. convert the MetaFile + // to primitives) it is necessary to reduce maximum pixel size by 1 in X and Y and to use + // the inner pixel bounds accordingly (ceil resp. floor). This will also be done for logic + // units e.g. when creating a new MetaFile, but since much huger value ranges are used + // there typically will be okay for this compromize. + Rectangle aDestRectView( + (sal_Int32)ceil(aOutlineRange.getMinX()), (sal_Int32)ceil(aOutlineRange.getMinY()), + (sal_Int32)floor(aOutlineRange.getMaxX()), (sal_Int32)floor(aOutlineRange.getMaxY())); + + if(aDestRectView.Right() > aDestRectView.Left()) + { + aDestRectView.Right()--; + } + + if(aDestRectView.Bottom() > aDestRectView.Top()) + { + aDestRectView.Bottom()--; + } // get metafile (copy it) GDIMetaFile aMetaFile; @@ -905,15 +922,12 @@ namespace drawinglayer const std::vector< basegfx::B2DPoint >& rPositions = rMarkArrayCandidate.getPositions(); const basegfx::BColor aRGBColor(maBColorModifierStack.getModifiedColor(rMarkArrayCandidate.getRGBColor())); const Color aVCLColor(aRGBColor); - const bool bWasEnabled(mpOutputDevice->IsMapModeEnabled()); + const basegfx::B2DHomMatrix aTransObjectToDiscrete(mpOutputDevice->GetViewTransformation() * maCurrentTransformation); for(std::vector< basegfx::B2DPoint >::const_iterator aIter(rPositions.begin()); aIter != rPositions.end(); aIter++) { - const basegfx::B2DPoint aViewPosition(maCurrentTransformation * (*aIter)); - Point aPos(basegfx::fround(aViewPosition.getX()), basegfx::fround(aViewPosition.getY())); - - aPos = mpOutputDevice->LogicToPixel(aPos); - mpOutputDevice->EnableMapMode(false); + const basegfx::B2DPoint aDiscretePosition(aTransObjectToDiscrete * (*aIter)); + const Point aPos(basegfx::fround(aDiscretePosition.getX()), basegfx::fround(aDiscretePosition.getY())); switch(rMarkArrayCandidate.getStyle()) { @@ -953,7 +967,6 @@ namespace drawinglayer } } - mpOutputDevice->EnableMapMode(bWasEnabled); } break; diff --git a/drawinglayer/source/processor3d/defaultprocessor3d.cxx b/drawinglayer/source/processor3d/defaultprocessor3d.cxx index 06501c5919ec..79cea6ce84a2 100644 --- a/drawinglayer/source/processor3d/defaultprocessor3d.cxx +++ b/drawinglayer/source/processor3d/defaultprocessor3d.cxx @@ -4,9 +4,9 @@ * * $RCSfile: defaultprocessor3d.cxx,v $ * - * $Revision: 1.9 $ + * $Revision: 1.10 $ * - * last change: $Author: aw $ $Date: 2008-04-16 04:59:59 $ + * last change: $Author: aw $ $Date: 2008-05-14 09:21:54 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -40,34 +40,14 @@ #include <drawinglayer/processor3d/defaultprocessor3d.hxx> #endif -#ifndef _SV_BMPACC_HXX -#include <vcl/bmpacc.hxx> -#endif - -#ifndef _BGFX_RASTER_BZPIXELRASTER_HXX -#include <basegfx/raster/bzpixelraster.hxx> -#endif - -#ifndef _BGFX_RASTER_B3DPOLYPOLYGONRASTERCONVERTER_HXX -#include <basegfx/raster/b3dpolypolygonrasterconverter.hxx> -#endif - -#ifndef INCLUDED_DRAWINGLAYER_ATTRIBUTE_MATERIALATTRIBUTE3D_HXX -#include <drawinglayer/attribute/materialattribute3d.hxx> +#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE3D_TEXTUREPRIMITIVE3D_HXX +#include <drawinglayer/primitive3d/textureprimitive3d.hxx> #endif #ifndef INCLUDED_DRAWINGLAYER_TEXTURE_TEXTURE_HXX #include <drawinglayer/texture/texture.hxx> #endif -#ifndef INCLUDED_DRAWINGLAYER_ATTRIBUTE_SDRATTRIBUTE3D_HXX -#include <drawinglayer/attribute/sdrattribute3d.hxx> -#endif - -#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE3D_TEXTUREPRIMITIVE3D_HXX -#include <drawinglayer/primitive3d/textureprimitive3d.hxx> -#endif - #ifndef INCLUDED_DRAWINGLAYER_TEXTURE_TEXTURE3D_HXX #include <drawinglayer/texture/texture3d.hxx> #endif @@ -80,14 +60,18 @@ #include <drawinglayer/primitive3d/modifiedcolorprimitive3d.hxx> #endif -#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE3D_POLYGONTUBEPRIMITIVE3D_HXX -#include <drawinglayer/primitive3d/polygontubeprimitive3d.hxx> +#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE3D_POLYGONPRIMITIVE3D_HXX +#include <drawinglayer/primitive3d/polygonprimitive3d.hxx> #endif #ifndef _BGFX_POLYGON_B3DPOLYGONTOOLS_HXX #include <basegfx/polygon/b3dpolygontools.hxx> #endif +#ifndef INCLUDED_DRAWINGLAYER_ATTRIBUTE_MATERIALATTRIBUTE3D_HXX +#include <drawinglayer/attribute/materialattribute3d.hxx> +#endif + #ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE3D_POLYPOLYGONPRIMITIVE3D_HXX #include <drawinglayer/primitive3d/polypolygonprimitive3d.hxx> #endif @@ -96,6 +80,14 @@ #include <basegfx/polygon/b3dpolypolygontools.hxx> #endif +#ifndef _COM_SUN_STAR_DRAWING_SHADEMODE_HPP_ +#include <com/sun/star/drawing/ShadeMode.hpp> +#endif + +#ifndef INCLUDED_DRAWINGLAYER_ATTRIBUTE_SDRATTRIBUTE3D_HXX +#include <drawinglayer/attribute/sdrattribute3d.hxx> +#endif + #ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE3D_TRANSFORMPRIMITIVE3D_HXX #include <drawinglayer/primitive3d/transformprimitive3d.hxx> #endif @@ -104,423 +96,26 @@ #include <drawinglayer/primitive3d/drawinglayer_primitivetypes3d.hxx> #endif -#ifndef INCLUDED_DRAWINGLAYER_GEOMETRY_VIEWINFORMATION2D_HXX -#include <drawinglayer/geometry/viewinformation2d.hxx> -#endif - ////////////////////////////////////////////////////////////////////////////// using namespace com::sun::star; ////////////////////////////////////////////////////////////////////////////// -namespace -{ - BitmapEx BPixelRasterToBitmapEx(const basegfx::BPixelRaster& rRaster) - { - BitmapEx aRetval; - const sal_uInt32 nWidth(rRaster.getWidth()); - const sal_uInt32 nHeight(rRaster.getHeight()); - - if(nWidth && nHeight) - { - sal_uInt8 nInitAlpha(255); - Bitmap aContent(Size(nWidth, nHeight), 24); - AlphaMask aAlpha(Size(nWidth, nHeight), &nInitAlpha); - BitmapWriteAccess* pContent = aContent.AcquireWriteAccess(); - BitmapWriteAccess* pAlpha = aAlpha.AcquireWriteAccess(); - - if(pContent && pAlpha) - { - sal_uInt32 nIndex(0L); - - for(sal_uInt32 y(0L); y < nHeight; y++) - { - for(sal_uInt32 x(0L); x < nWidth; x++) - { - const basegfx::BPixel& rPixel(rRaster.getBPixel(nIndex++)); - - if(rPixel.getOpacity()) - { - pContent->SetPixel(y, x, BitmapColor(rPixel.getRed(), rPixel.getGreen(), rPixel.getBlue())); - pAlpha->SetPixel(y, x, BitmapColor(255 - rPixel.getOpacity())); - } - } - } - - delete pContent; - delete pAlpha; - } - - aRetval = BitmapEx(aContent, aAlpha); - } - - return aRetval; - } -} // end of anonymous namespace - -////////////////////////////////////////////////////////////////////////////// -// own default 3D rasterconverter based on basic 3d raster implementation -// in basegfx - -namespace drawinglayer -{ - namespace - { - class BZPolyRaCon : public basegfx::B3DPolyPolygonRasterConverter - { - protected: - basegfx::BZPixelRaster& mrBuffer; - const attribute::MaterialAttribute3D& mrMaterial; - const processor3d::DefaultProcessor3D& mrProcessor; - - // virtual rasterconverter - virtual void processSpan(const basegfx::B3DScanline& rA, const basegfx::B3DScanline& rB, sal_Int32 nLine, sal_uInt32 nSpanCount); - virtual void processLine(const basegfx::B3DScanline& rEntry, sal_Int32 nLine); - - public: - BZPolyRaCon( - bool bArea, - basegfx::BZPixelRaster& rBuffer, - const attribute::MaterialAttribute3D& rMaterial, - const processor3d::DefaultProcessor3D& rProcessor) - : B3DPolyPolygonRasterConverter(bArea), - mrBuffer(rBuffer), - mrMaterial(rMaterial), - mrProcessor(rProcessor) - {} - }; - - void BZPolyRaCon::processSpan(const basegfx::B3DScanline& rA, const basegfx::B3DScanline& rB, sal_Int32 nLine, sal_uInt32 nSpanCount) - { - if(!(nSpanCount & 0x0001)) - { - if(nLine >= 0L && nLine < (sal_Int32)mrBuffer.getHeight()) - { - sal_Int32 nXA((sal_Int32)(rA.getXInterpolator().getVal())); - sal_Int32 nXB((sal_Int32)(rB.getXInterpolator().getVal())); - OSL_ENSURE(nXB >= nXA,"processSpan: positive run expected (!)"); - - if(nXB > nXA) - { - // initialize Z interpolator - const sal_uInt32 nSpanLength(nXB - nXA); - basegfx::BDInterpolator aZ(rA.getZInterpolator().getVal(), rB.getZInterpolator().getVal(), nSpanLength); - - // prepare some references to used variables - const basegfx::BColor& rColor(mrMaterial.getColor()); - const basegfx::BColor& rSpecular(mrMaterial.getSpecular()); - const basegfx::BColor& rEmission(mrMaterial.getEmission()); - const sal_uInt16 nSpecularIntensity(mrMaterial.getSpecularIntensity()); - - // get bools and init other interpolators on demand accordingly - const bool bUseTex((mrProcessor.getGeoTexSvx() || mrProcessor.getTransparenceGeoTexSvx()) && rA.getTextureCoordinateIndex() != SCANLINE_EMPTY_INDEX && rB.getTextureCoordinateIndex() != SCANLINE_EMPTY_INDEX); - const bool bUseColorTex(bUseTex && mrProcessor.getGeoTexSvx()); - const bool bNeedOthers(!bUseColorTex || (bUseColorTex && mrProcessor.getModulate())); - const bool bUseNrm(bNeedOthers && rA.getNormalIndex() != SCANLINE_EMPTY_INDEX && rB.getNormalIndex() != SCANLINE_EMPTY_INDEX); - const bool bUseCol(!bUseNrm && bNeedOthers && rA.getBColorIndex() != SCANLINE_EMPTY_INDEX && rB.getBColorIndex() != SCANLINE_EMPTY_INDEX); - const bool bModifyColor(mrProcessor.getBColorModifierStack().count()); - basegfx::B2DPointInterpolator aTex; - basegfx::B3DVectorInterpolator aNrm; - basegfx::BColorInterpolator aCol; - - if(bUseTex) - { - const basegfx::B2DPointInterpolator& rLA(maGlobalTextureCoordinateInterpolators[rA.getTextureCoordinateIndex()]); - const basegfx::B2DPointInterpolator& rLB(maGlobalTextureCoordinateInterpolators[rB.getTextureCoordinateIndex()]); - aTex = basegfx::B2DPointInterpolator(rLA.getVal(), rLB.getVal(), rLA.getZVal(), rLB.getZVal(), nSpanLength); - } - - if(bUseNrm) - { - aNrm = basegfx::B3DVectorInterpolator( - maGlobalNormalInterpolators[rA.getNormalIndex()].getVal(), - maGlobalNormalInterpolators[rB.getNormalIndex()].getVal(), - nSpanLength); - } - - if(bUseCol) - { - aCol = basegfx::BColorInterpolator( - maGlobalBColorInterpolators[rA.getBColorIndex()].getVal(), - maGlobalBColorInterpolators[rB.getBColorIndex()].getVal(), - nSpanLength); - } - - if(nXA < 0L) - { - const double fIncrement(-nXA); - nXA = 0L; - aZ.increment(fIncrement); - - if(bUseTex) - { - aTex.increment(fIncrement); - } - - if(bUseNrm) - { - aNrm.increment(fIncrement); - } - - if(bUseCol) - { - aCol.increment(fIncrement); - } - } - - if(nXB > (sal_Int32)mrBuffer.getWidth()) - { - nXB = mrBuffer.getWidth(); - } - - if(nXA < nXB) - { - sal_uInt32 nScanlineIndex(mrBuffer.getIndexFromXY((sal_uInt32)nXA, (sal_uInt32)nLine)); - - while(nXA < nXB) - { - // get old and new Z to see if we need to do somethng at all - sal_uInt16& rOldZ(mrBuffer.getZ(nScanlineIndex)); - const sal_uInt16 nNewZ((sal_uInt16)(aZ.getVal())); - - if(nNewZ > rOldZ) - { - // prepare color - basegfx::BColor aNewColor(rColor); - double fOpacity(1.0); - bool bOpacity(true); - - if(bUseTex) - { - // get texture coor - const basegfx::B2DPoint aTexCoor(aTex.getVal() / aTex.getZVal()); - - if(mrProcessor.getGeoTexSvx()) - { - // calc color in spot - mrProcessor.getGeoTexSvx()->modifyBColor(aTexCoor, aNewColor, fOpacity); - bOpacity = basegfx::fTools::more(fOpacity, 0.0); - } - - if(bOpacity && mrProcessor.getTransparenceGeoTexSvx()) - { - // calc opacity - mrProcessor.getTransparenceGeoTexSvx()->modifyOpacity(aTexCoor, fOpacity); - bOpacity = basegfx::fTools::more(fOpacity, 0.0); - } - } - - if(bOpacity) - { - if(mrProcessor.getGeoTexSvx()) - { - if(bUseNrm) - { - // blend texture with phong - aNewColor = mrProcessor.getSdrLightingAttribute().solveColorModel(aNrm.getVal(), aNewColor, rSpecular, rEmission, nSpecularIntensity); - } - else if(bUseCol) - { - // blend texture with gouraud - aNewColor *= aCol.getVal(); - } - else if(mrProcessor.getModulate()) - { - // blend texture with single material color - aNewColor *= rColor; - } - } - else - { - if(bUseNrm) - { - // modify color with phong - aNewColor = mrProcessor.getSdrLightingAttribute().solveColorModel(aNrm.getVal(), rColor, rSpecular, rEmission, nSpecularIntensity); - } - else if(bUseCol) - { - // modify color with gouraud - aNewColor = aCol.getVal(); - } - } - - if(bModifyColor) - { - aNewColor = mrProcessor.getBColorModifierStack().getModifiedColor(aNewColor); - } - - if(basegfx::fTools::moreOrEqual(fOpacity, 1.0)) - { - // full opacity, set z and color - rOldZ = nNewZ; - mrBuffer.getBPixel(nScanlineIndex) = basegfx::BPixel(aNewColor, 0xff); - } - else - { - basegfx::BPixel& rDest = mrBuffer.getBPixel(nScanlineIndex); - - if(rDest.getOpacity()) - { - // mix color and existing color - const double fOld(1.0 - fOpacity); - fOpacity *= 255.0; - rDest.setRed((sal_uInt8)(((double)rDest.getRed() * fOld) + (aNewColor.getRed() * fOpacity))); - rDest.setGreen((sal_uInt8)(((double)rDest.getGreen() * fOld) + (aNewColor.getGreen() * fOpacity))); - rDest.setBlue((sal_uInt8)(((double)rDest.getBlue() * fOld) + (aNewColor.getBlue() * fOpacity))); - - if((sal_uInt8)255 != rDest.getOpacity()) - { - // mix opacities by adding - double fNewOpacity(rDest.getOpacity() + fOpacity); - - if(fNewOpacity > 255.0) - { - // set full opacity - rDest.setOpacity(0xff); - } - else - { - // set new opacity which is still transparent, so set no z - rDest.setOpacity((sal_uInt8)(fNewOpacity)); - } - } - } - else - { - // set color and opacity - rDest = basegfx::BPixel(aNewColor, (sal_uInt8)(fOpacity * 255.0)); - } - } - } - } - - // increments - { - nScanlineIndex++; - nXA++; - aZ.increment(); - - if(bUseTex) - { - aTex.increment(); - } - - if(bUseNrm) - { - aNrm.increment(); - } - - if(bUseCol) - { - aCol.increment(); - } - } - } - } - } - } - } - } - - void BZPolyRaCon::processLine(const basegfx::B3DScanline& rEntry, sal_Int32 nLine) - { - if(nLine >= 0L && nLine < (sal_Int32)mrBuffer.getHeight()) - { - sal_Int32 nXA((sal_uInt32)(rEntry.getXInterpolator().getVal())); - sal_Int32 nXB((sal_uInt32)(rEntry.getXInterpolator().getVal() + rEntry.getXInterpolator().getInc())); - - if(nXA == nXB) - { - // only one position, get values and set direct - if(nXA >= 0L && nXA < (sal_Int32)mrBuffer.getWidth()) - { - const sal_uInt32 nScanlineIndex(mrBuffer.getIndexFromXY((sal_uInt32)nXA, (sal_uInt32)nLine)); - sal_uInt16& rOldZ(mrBuffer.getZ(nScanlineIndex)); - const sal_uInt16 nNewZ((sal_uInt16)(rEntry.getZInterpolator().getVal()) + 0x00ff); - - if(nNewZ > rOldZ) - { - rOldZ = nNewZ; - mrBuffer.getBPixel(nScanlineIndex) = basegfx::BPixel(mrMaterial.getColor(), 0xff); - } - } - } - else - { - double fZStart(rEntry.getZInterpolator().getVal()); - double fZStop(fZStart + rEntry.getZInterpolator().getInc()); - - if(nXB < nXA) - { - ::std::swap(nXB, nXA); - ::std::swap(fZStart, fZStop); - } - - const basegfx::BPixel aPixel(mrMaterial.getColor(), 0xff); - const sal_uInt32 nSpanLength(nXB - nXA); - basegfx::BDInterpolator aZ(fZStart, fZStop, nSpanLength); - - if(nXA < 0L) - { - const double fIncrement(-nXA); - nXA = 0L; - aZ.increment(fIncrement); - } - - if(nXB > (sal_Int32)mrBuffer.getWidth()) - { - nXB = mrBuffer.getWidth(); - } - - if(nXA < nXB) - { - sal_uInt32 nScanlineIndex(mrBuffer.getIndexFromXY((sal_uInt32)nXA, (sal_uInt32)nLine)); - - while(nXA < nXB) - { - sal_uInt16& rOldZ(mrBuffer.getZ(nScanlineIndex)); - const sal_uInt16 nNewZ((sal_uInt16)(aZ.getVal()) + 0x00ff); - - if(nNewZ > rOldZ) - { - rOldZ = nNewZ; - mrBuffer.getBPixel(nScanlineIndex) = aPixel; - } - - nScanlineIndex++; - nXA++; - aZ.increment(); - } - } - } - } - } - - const ::rtl::OUString& getNamePropertyTime() - { - static ::rtl::OUString s_sNamePropertyTime(RTL_CONSTASCII_USTRINGPARAM("Time")); - return s_sNamePropertyTime; - } - } // end of anonymous namespace -} // end of namespace drawinglayer - -////////////////////////////////////////////////////////////////////////////// -// the DefaultProcessor3D itself - namespace drawinglayer { namespace processor3d { - void DefaultProcessor3D::impRender_GRX3(const primitive3d::GradientTexturePrimitive3D& rPrimitive, bool bTransparence) + void DefaultProcessor3D::impRenderGradientTexturePrimitive3D(const primitive3d::GradientTexturePrimitive3D& rPrimitive, bool bTransparence) { const primitive3d::Primitive3DSequence& rSubSequence = rPrimitive.getChildren(); if(rSubSequence.hasElements()) { // rescue values - const bool bOldModulate(mbModulate); mbModulate = rPrimitive.getModulate(); - const bool bOldFilter(mbFilter); mbFilter = rPrimitive.getFilter(); + const bool bOldModulate(getModulate()); mbModulate = rPrimitive.getModulate(); + const bool bOldFilter(getFilter()); mbFilter = rPrimitive.getFilter(); + const bool bOldSimpleTextureActive(mbSimpleTextureActive); texture::GeoTexSvx* pOldTex = (bTransparence) ? mpTransparenceGeoTexSvx : mpGeoTexSvx; // create texture @@ -584,11 +179,14 @@ namespace drawinglayer break; } } + + mbSimpleTextureActive = false; } else { // no color distance -> same color, use simple texture pNewTex = new texture::GeoTexSvxMono(aStart, 1.0 - aStart.luminance()); + mbSimpleTextureActive = true; } // set created texture @@ -610,6 +208,7 @@ namespace drawinglayer // restore values mbModulate = bOldModulate; mbFilter = bOldFilter; + mbSimpleTextureActive = bOldSimpleTextureActive; if(bTransparence) { @@ -622,18 +221,25 @@ namespace drawinglayer } } - void DefaultProcessor3D::impRender_HAX3(const primitive3d::HatchTexturePrimitive3D& rPrimitive) + void DefaultProcessor3D::impRenderHatchTexturePrimitive3D(const primitive3d::HatchTexturePrimitive3D& rPrimitive) { const primitive3d::Primitive3DSequence& rSubSequence = rPrimitive.getChildren(); if(rSubSequence.hasElements()) { // rescue values - const bool bOldModulate(mbModulate); mbModulate = rPrimitive.getModulate(); - const bool bOldFilter(mbFilter); mbFilter = rPrimitive.getFilter(); + const bool bOldModulate(getModulate()); mbModulate = rPrimitive.getModulate(); + const bool bOldFilter(getFilter()); mbFilter = rPrimitive.getFilter(); texture::GeoTexSvx* pOldTex = mpGeoTexSvx; - // calculate logic pixel size in world coordinates + // calculate logic pixel size in world coordinates. Check if InvWorldToView + // is valid + if(maInvWorldToView.isIdentity()) + { + maInvWorldToView = maWorldToView; + maInvWorldToView.invert(); + } + const basegfx::B3DPoint aZero(maInvWorldToView * basegfx::B3DPoint(0.0, 0.0, 0.0)); const basegfx::B3DPoint aOne(maInvWorldToView * basegfx::B3DPoint(1.0, 1.0, 1.0)); const basegfx::B3DVector aLogicPixelSizeWorld(aOne - aZero); @@ -671,15 +277,15 @@ namespace drawinglayer } } - void DefaultProcessor3D::impRender_BMX3(const primitive3d::BitmapTexturePrimitive3D& rPrimitive) + void DefaultProcessor3D::impRenderBitmapTexturePrimitive3D(const primitive3d::BitmapTexturePrimitive3D& rPrimitive) { const primitive3d::Primitive3DSequence& rSubSequence = rPrimitive.getChildren(); if(rSubSequence.hasElements()) { // rescue values - const bool bOldModulate(mbModulate); mbModulate = rPrimitive.getModulate(); - const bool bOldFilter(mbFilter); mbFilter = rPrimitive.getFilter(); + const bool bOldModulate(getModulate()); mbModulate = rPrimitive.getModulate(); + const bool bOldFilter(getFilter()); mbFilter = rPrimitive.getFilter(); texture::GeoTexSvx* pOldTex = mpGeoTexSvx; // create texture @@ -713,23 +319,28 @@ namespace drawinglayer } } - void DefaultProcessor3D::impRender_MCOL(const primitive3d::ModifiedColorPrimitive3D& rModifiedCandidate) + void DefaultProcessor3D::impRenderModifiedColorPrimitive3D(const primitive3d::ModifiedColorPrimitive3D& rModifiedCandidate) { const primitive3d::Primitive3DSequence& rSubSequence = rModifiedCandidate.getChildren(); if(rSubSequence.hasElements()) { + // put modifier on stack maBColorModifierStack.push(rModifiedCandidate.getColorModifier()); + + // process sub-list process(rModifiedCandidate.getChildren()); + + // remove modifier from stack maBColorModifierStack.pop(); } } - void DefaultProcessor3D::impRender_POH3(const primitive3d::PolygonHairlinePrimitive3D& rPrimitive) + void DefaultProcessor3D::impRenderPolygonHairlinePrimitive3D(const primitive3d::PolygonHairlinePrimitive3D& rPrimitive) { basegfx::B3DPolygon aHairline(rPrimitive.getB3DPolygon()); - if(aHairline.count() && mpBZPixelRaster) + if(aHairline.count()) { // hairlines need no extra data, clear it aHairline.clearTextureCoordinates(); @@ -744,23 +355,22 @@ namespace drawinglayer if(a2DRange.overlaps(maRasterRange)) { const attribute::MaterialAttribute3D aMaterial(rPrimitive.getBColor()); - BZPolyRaCon aNewRaCon(false, *mpBZPixelRaster, aMaterial, *this); - aNewRaCon.addPolygon(aHairline, maInvEyeToView); - aNewRaCon.rasterconvert(0L, mpBZPixelRaster->getHeight()); + + rasterconvertB3DPolygon(aMaterial, aHairline); } } } - void DefaultProcessor3D::impRender_POM3(const primitive3d::PolyPolygonMaterialPrimitive3D& rPrimitive) + void DefaultProcessor3D::impRenderPolyPolygonMaterialPrimitive3D(const primitive3d::PolyPolygonMaterialPrimitive3D& rPrimitive) { basegfx::B3DPolyPolygon aFill(rPrimitive.getB3DPolyPolygon()); basegfx::BColor aObjectColor(rPrimitive.getMaterial().getColor()); - bool bPaintIt(aFill.count() && mpBZPixelRaster); + bool bPaintIt(aFill.count()); if(bPaintIt) { // get rid of texture coordinates if there is no texture - if(aFill.areTextureCoordinatesUsed() && !mpGeoTexSvx && !mpTransparenceGeoTexSvx) + if(aFill.areTextureCoordinatesUsed() && !getGeoTexSvx() && !getTransparenceGeoTexSvx()) { aFill.clearTextureCoordinates(); } @@ -788,10 +398,10 @@ namespace drawinglayer if(bPaintIt) { - ::com::sun::star::drawing::ShadeMode aShadeMode(mrSdrSceneAttribute.getShadeMode()); + ::com::sun::star::drawing::ShadeMode aShadeMode(getSdrSceneAttribute().getShadeMode()); basegfx::B3DHomMatrix aNormalTransform(maWorldToEye); - if(mrSdrSceneAttribute.getTwoSidedLighting()) + if(getSdrSceneAttribute().getTwoSidedLighting()) { // get plane normal of polygon in view coordinates (with ZBuffer values), // left-handed coordinate system @@ -828,7 +438,7 @@ namespace drawinglayer aFill.transformNormals(aNormalTransform); // prepare color model parameters, evtl. use blend color - const basegfx::BColor aColor(mbModulate ? basegfx::BColor(1.0, 1.0, 1.0) : rPrimitive.getMaterial().getColor()); + const basegfx::BColor aColor(getModulate() ? basegfx::BColor(1.0, 1.0, 1.0) : rPrimitive.getMaterial().getColor()); const basegfx::BColor& rSpecular(rPrimitive.getMaterial().getSpecular()); const basegfx::BColor& rEmission(rPrimitive.getMaterial().getEmission()); const sal_uInt16 nSpecularIntensity(rPrimitive.getMaterial().getSpecularIntensity()); @@ -842,7 +452,7 @@ namespace drawinglayer { // solve color model. Transform normal to eye coor const basegfx::B3DVector aNormal(aPartFill.getNormal(b)); - const basegfx::BColor aSolvedColor(mrSdrLightingAttribute.solveColorModel(aNormal, aColor, rSpecular, rEmission, nSpecularIntensity)); + const basegfx::BColor aSolvedColor(getSdrLightingAttribute().solveColorModel(aNormal, aColor, rSpecular, rEmission, nSpecularIntensity)); aPartFill.setBColor(b, aSolvedColor); } @@ -868,13 +478,13 @@ namespace drawinglayer const basegfx::B3DVector aPlaneEyeNormal(aNormalTransform * rPrimitive.getB3DPolyPolygon().getB3DPolygon(0L).getNormal()); // prepare color model parameters, evtl. use blend color - const basegfx::BColor aColor(mbModulate ? basegfx::BColor(1.0, 1.0, 1.0) : rPrimitive.getMaterial().getColor()); + const basegfx::BColor aColor(getModulate() ? basegfx::BColor(1.0, 1.0, 1.0) : rPrimitive.getMaterial().getColor()); const basegfx::BColor& rSpecular(rPrimitive.getMaterial().getSpecular()); const basegfx::BColor& rEmission(rPrimitive.getMaterial().getEmission()); const sal_uInt16 nSpecularIntensity(rPrimitive.getMaterial().getSpecularIntensity()); // solve color model for plane vector and use that color for whole plane - aObjectColor = mrSdrLightingAttribute.solveColorModel(aPlaneEyeNormal, aColor, rSpecular, rEmission, nSpecularIntensity); + aObjectColor = getSdrLightingAttribute().solveColorModel(aPlaneEyeNormal, aColor, rSpecular, rEmission, nSpecularIntensity); } if(::com::sun::star::drawing::ShadeMode_DRAFT == aShadeMode) @@ -883,38 +493,28 @@ namespace drawinglayer aFill.clearNormals(); aFill.clearBColors(); } - } - if(bPaintIt) - { // draw it to ZBuffer const attribute::MaterialAttribute3D aMaterial( aObjectColor, rPrimitive.getMaterial().getSpecular(), rPrimitive.getMaterial().getEmission(), rPrimitive.getMaterial().getSpecularIntensity()); - BZPolyRaCon aNewRaCon(true, *mpBZPixelRaster, aMaterial, *this); - for(sal_uInt32 a(0L); a < aFill.count(); a++) - { - aNewRaCon.addPolygon(aFill.getB3DPolygon(a), maInvEyeToView); - } - - aNewRaCon.rasterconvert(0L, mpBZPixelRaster->getHeight()); + rasterconvertB3DPolyPolygon(aMaterial, aFill); } } - void DefaultProcessor3D::impRender_TRN3(const primitive3d::TransformPrimitive3D& rTransformCandidate) + void DefaultProcessor3D::impRenderTransformPrimitive3D(const primitive3d::TransformPrimitive3D& rTransformCandidate) { // remember current transformations - basegfx::B3DHomMatrix aLastWorldToView(maWorldToView); - basegfx::B3DHomMatrix aLastWorldToEye(maWorldToEye); - basegfx::B3DHomMatrix aLastInvWorldToView(maInvWorldToView); + const basegfx::B3DHomMatrix aLastWorldToView(maWorldToView); + const basegfx::B3DHomMatrix aLastWorldToEye(maWorldToEye); + const basegfx::B3DHomMatrix aLastInvWorldToView(maInvWorldToView); // create new transformations maWorldToView = maWorldToView * rTransformCandidate.getTransformation(); maWorldToEye = maWorldToEye * rTransformCandidate.getTransformation(); - maInvWorldToView = maWorldToView; - maInvWorldToView.invert(); + maInvWorldToView.identity(); // let break down process(rTransformCandidate.getChildren()); @@ -925,6 +525,93 @@ namespace drawinglayer maInvWorldToView = aLastInvWorldToView; } + void DefaultProcessor3D::processBasePrimitive3D(const primitive3d::BasePrimitive3D& rBasePrimitive) + { + // it is a BasePrimitive3D implementation, use getPrimitiveID() call for switch + switch(rBasePrimitive.getPrimitiveID()) + { + case PRIMITIVE3D_ID_GRADIENTTEXTUREPRIMITIVE3D : + { + // GradientTexturePrimitive3D + const primitive3d::GradientTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::GradientTexturePrimitive3D& >(rBasePrimitive); + impRenderGradientTexturePrimitive3D(rPrimitive, false); + break; + } + case PRIMITIVE3D_ID_HATCHTEXTUREPRIMITIVE3D : + { + // HatchTexturePrimitive3D + static bool bDoHatchDecomposition(false); + + if(bDoHatchDecomposition) + { + // let break down + process(rBasePrimitive.get3DDecomposition(getTime())); + } + else + { + // hatchTexturePrimitive3D + const primitive3d::HatchTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::HatchTexturePrimitive3D& >(rBasePrimitive); + impRenderHatchTexturePrimitive3D(rPrimitive); + } + break; + } + case PRIMITIVE3D_ID_BITMAPTEXTUREPRIMITIVE3D : + { + // BitmapTexturePrimitive3D + const primitive3d::BitmapTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::BitmapTexturePrimitive3D& >(rBasePrimitive); + impRenderBitmapTexturePrimitive3D(rPrimitive); + break; + } + case PRIMITIVE3D_ID_ALPHATEXTUREPRIMITIVE3D : + { + // AlphaTexturePrimitive3D + const primitive3d::AlphaTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::AlphaTexturePrimitive3D& >(rBasePrimitive); + impRenderGradientTexturePrimitive3D(rPrimitive, true); + break; + } + case PRIMITIVE3D_ID_MODIFIEDCOLORPRIMITIVE3D : + { + // ModifiedColorPrimitive3D + // Force output to unified color. + const primitive3d::ModifiedColorPrimitive3D& rPrimitive = static_cast< const primitive3d::ModifiedColorPrimitive3D& >(rBasePrimitive); + impRenderModifiedColorPrimitive3D(rPrimitive); + break; + } + case PRIMITIVE3D_ID_POLYGONHAIRLINEPRIMITIVE3D : + { + // directdraw of PolygonHairlinePrimitive3D + const primitive3d::PolygonHairlinePrimitive3D& rPrimitive = static_cast< const primitive3d::PolygonHairlinePrimitive3D& >(rBasePrimitive); + impRenderPolygonHairlinePrimitive3D(rPrimitive); + break; + } + case PRIMITIVE3D_ID_POLYPOLYGONMATERIALPRIMITIVE3D : + { + // directdraw of PolyPolygonMaterialPrimitive3D + const primitive3d::PolyPolygonMaterialPrimitive3D& rPrimitive = static_cast< const primitive3d::PolyPolygonMaterialPrimitive3D& >(rBasePrimitive); + impRenderPolyPolygonMaterialPrimitive3D(rPrimitive); + break; + } + case PRIMITIVE3D_ID_TRANSFORMPRIMITIVE3D : + { + // transform group (TransformPrimitive3D) + impRenderTransformPrimitive3D(static_cast< const primitive3d::TransformPrimitive3D& >(rBasePrimitive)); + break; + } + case PRIMITIVE3D_ID_SDRLABELPRIMITIVE3D : + { + // SdrLabelPrimitive3D. Accept, but ignore. Is handled by the scenePrimitive decompose + // method which creates 2d text objects at the 3d-projection-dependent positions. + break; + } + default: + { + // process recursively + process(rBasePrimitive.get3DDecomposition(getTime())); + break; + } + } + } + void DefaultProcessor3D::process(const primitive3d::Primitive3DSequence& rSource) { if(rSource.hasElements()) @@ -943,105 +630,7 @@ namespace drawinglayer if(pBasePrimitive) { - // it is a BasePrimitive3D implementation, use getPrimitiveID() call for switch - switch(pBasePrimitive->getPrimitiveID()) - { - case PRIMITIVE3D_ID_GRADIENTTEXTUREPRIMITIVE3D : - { - // GradientTexturePrimitive3D - const primitive3d::GradientTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::GradientTexturePrimitive3D& >(*pBasePrimitive); - impRender_GRX3(rPrimitive, false); - break; - } - case PRIMITIVE3D_ID_HATCHTEXTUREPRIMITIVE3D : - { - // HatchTexturePrimitive3D - static bool bDoHatchDecomposition(true); - - if(bDoHatchDecomposition) - { - // let break down - process(pBasePrimitive->get3DDecomposition(getTime())); - } - else - { - // hatchTexturePrimitive3D - const primitive3d::HatchTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::HatchTexturePrimitive3D& >(*pBasePrimitive); - impRender_HAX3(rPrimitive); - } - break; - } - case PRIMITIVE3D_ID_BITMAPTEXTUREPRIMITIVE3D : - { - // BitmapTexturePrimitive3D - const primitive3d::BitmapTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::BitmapTexturePrimitive3D& >(*pBasePrimitive); - impRender_BMX3(rPrimitive); - break; - } - case PRIMITIVE3D_ID_ALPHATEXTUREPRIMITIVE3D : - { - // AlphaTexturePrimitive3D - const primitive3d::AlphaTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::AlphaTexturePrimitive3D& >(*pBasePrimitive); - - if(mbProcessTransparent) - { - impRender_GRX3(rPrimitive, true); - } - else - { - mbContainsTransparent = true; - } - break; - } - case PRIMITIVE3D_ID_MODIFIEDCOLORPRIMITIVE3D : - { - // ModifiedColorPrimitive3D - // Force output to unified color. - const primitive3d::ModifiedColorPrimitive3D& rPrimitive = static_cast< const primitive3d::ModifiedColorPrimitive3D& >(*pBasePrimitive); - impRender_MCOL(rPrimitive); - break; - } - case PRIMITIVE3D_ID_POLYGONHAIRLINEPRIMITIVE3D : - { - // directdraw of PolygonHairlinePrimitive3D - const primitive3d::PolygonHairlinePrimitive3D& rPrimitive = static_cast< const primitive3d::PolygonHairlinePrimitive3D& >(*pBasePrimitive); - - if((bool)mbProcessTransparent == (0L != mpTransparenceGeoTexSvx)) - { - impRender_POH3(rPrimitive); - } - break; - } - case PRIMITIVE3D_ID_POLYPOLYGONMATERIALPRIMITIVE3D : - { - // directdraw of PolyPolygonMaterialPrimitive3D - const primitive3d::PolyPolygonMaterialPrimitive3D& rPrimitive = static_cast< const primitive3d::PolyPolygonMaterialPrimitive3D& >(*pBasePrimitive); - - if((bool)mbProcessTransparent == (0L != mpTransparenceGeoTexSvx)) - { - impRender_POM3(rPrimitive); - } - break; - } - case PRIMITIVE3D_ID_TRANSFORMPRIMITIVE3D : - { - // transform group (TransformPrimitive3D) - impRender_TRN3(static_cast< const primitive3d::TransformPrimitive3D& >(*pBasePrimitive)); - break; - } - case PRIMITIVE3D_ID_SDRLABELPRIMITIVE3D : - { - // SdrLabelPrimitive3D. Accept, but ignore. Is handled by the scenePrimitive decompose - // method which creates 2d text objects at the 3d-projection-dependent positions. - break; - } - default: - { - // process recursively - process(pBasePrimitive->get3DDecomposition(getTime())); - break; - } - } + processBasePrimitive3D(*pBasePrimitive); } else { @@ -1054,123 +643,32 @@ namespace drawinglayer } } - void DefaultProcessor3D::processNonTransparent(const primitive3d::Primitive3DSequence& rSource) - { - mbProcessTransparent = false; - mbContainsTransparent = false; - process(rSource); - } - - void DefaultProcessor3D::processTransparent(const primitive3d::Primitive3DSequence& rSource) - { - if(mbContainsTransparent) - { - mbProcessTransparent = true; - process(rSource); - } - } - DefaultProcessor3D::DefaultProcessor3D( - const geometry::ViewInformation2D& rViewInformation, - const geometry::Transformation3D& rTransformation3D, + double fTime, const attribute::SdrSceneAttribute& rSdrSceneAttribute, - const attribute::SdrLightingAttribute& rSdrLightingAttribute, - double fSizeX, - double fSizeY, - const basegfx::B2DRange& rVisiblePart) - : BaseProcessor3D(rViewInformation.getViewTime()), + const attribute::SdrLightingAttribute& rSdrLightingAttribute) + : BaseProcessor3D(fTime), mrSdrSceneAttribute(rSdrSceneAttribute), mrSdrLightingAttribute(rSdrLightingAttribute), - maDeviceToView(), maWorldToEye(), maWorldToView(), - maInvEyeToView(), - maInvWorldToView(), maRasterRange(), - mpBZPixelRaster(0), maBColorModifierStack(), mpGeoTexSvx(0), mpTransparenceGeoTexSvx(0), + mnRasterWidth(0), + mnRasterHeight(0), mbModulate(false), mbFilter(false), - mbProcessTransparent(false), - mbContainsTransparent(false) + mbSimpleTextureActive(false) { - // generate ViewSizes - const double fFullViewSizeX((rViewInformation.getViewTransformation() * basegfx::B2DVector(fSizeX, 0.0)).getLength()); - const double fFullViewSizeY((rViewInformation.getViewTransformation() * basegfx::B2DVector(0.0, fSizeY)).getLength()); - const double fViewSizeX(fFullViewSizeX * rVisiblePart.getWidth()); - const double fViewSizeY(fFullViewSizeY * rVisiblePart.getHeight()); - const sal_uInt32 nViewSizeX((sal_uInt32)floor(fViewSizeX)); - const sal_uInt32 nViewSizeY((sal_uInt32)floor(fViewSizeY)); - - if(nViewSizeX && nViewSizeY) - { - // create view unit buffer - mpBZPixelRaster = new basegfx::BZPixelRaster(nViewSizeX + 1L, nViewSizeY + 1L); - OSL_ENSURE(mpBZPixelRaster, "DefaultProcessor3D: Could not allocate basegfx::BZPixelRaster (!)"); - - // create DeviceToView - // outcome is [-1.0 .. 1.0] in X,Y and Z. - - { - // step one: - // - // bring from [-1.0 .. 1.0] in X,Y and Z to [0.0 .. 1.0]. Also - // necessary to - // - flip Y due to screen orientation - // - flip Z due to Z-Buffer orientation from back to front - - maDeviceToView.scale(0.5, -0.5, -0.5); - maDeviceToView.translate(0.5, 0.5, 0.5); - } - - { - // step two: - // - // bring from [0.0 .. 1.0] in X,Y and Z to view cordinates. also: - // - scale Z to [0.0 .. fMaxZDepth] - const double fMaxZDepth(double(0x0000ff00)); - maDeviceToView.translate(-rVisiblePart.getMinX(), -rVisiblePart.getMinY(), 0.0); - maDeviceToView.scale(fFullViewSizeX, fFullViewSizeY, fMaxZDepth); - } - - // create world to eye transformation - maWorldToEye = rTransformation3D.getOrientation() * rTransformation3D.getTransformation(); - - // create EyeToView transformation - maWorldToView = maDeviceToView * rTransformation3D.getProjection() * maWorldToEye; - - // create inverse EyeToView transformation - maInvEyeToView = maDeviceToView * rTransformation3D.getProjection(); - maInvEyeToView.invert(); - - // create inverse WorldToView transformation - maInvWorldToView = maWorldToView; - maInvWorldToView.invert(); - - // prepare maRasterRange - maRasterRange.expand(basegfx::B2DPoint(0.0, 0.0)); - maRasterRange.expand(basegfx::B2DPoint(mpBZPixelRaster->getWidth(), mpBZPixelRaster->getHeight())); - } + // a derivation has to set maWorldToEye, maWorldToView + // maRasterRange, mnRasterWidth and mnRasterHeight. Those values are + // used in the basic render methods } DefaultProcessor3D::~DefaultProcessor3D() { - if(mpBZPixelRaster) - { - delete mpBZPixelRaster; - } - } - - BitmapEx DefaultProcessor3D::getBitmapEx() const - { - if(mpBZPixelRaster) - { - return BPixelRasterToBitmapEx(*mpBZPixelRaster); - } - - return BitmapEx(); } } // end of namespace processor3d } // end of namespace drawinglayer diff --git a/drawinglayer/source/processor3d/makefile.mk b/drawinglayer/source/processor3d/makefile.mk index 873de0f29642..3d8650e7a26c 100644 --- a/drawinglayer/source/processor3d/makefile.mk +++ b/drawinglayer/source/processor3d/makefile.mk @@ -4,9 +4,9 @@ # # $RCSfile: makefile.mk,v $ # -# $Revision: 1.3 $ +# $Revision: 1.4 $ # -# last change: $Author: aw $ $Date: 2008-01-30 12:25:05 $ +# last change: $Author: aw $ $Date: 2008-05-14 09:21:54 $ # # The Contents of this file are made available subject to # the terms of GNU Lesser General Public License Version 2.1. @@ -49,9 +49,8 @@ SLOFILES= \ $(SLO)$/defaultprocessor3d.obj \ $(SLO)$/label3dextractor.obj \ $(SLO)$/shadow3dextractor.obj \ - $(SLO)$/geometry2dextractor.obj - - + $(SLO)$/geometry2dextractor.obj \ + $(SLO)$/zbufferprocessor3d.obj # --- Targets ---------------------------------- diff --git a/drawinglayer/source/processor3d/zbufferprocessor3d.cxx b/drawinglayer/source/processor3d/zbufferprocessor3d.cxx new file mode 100644 index 000000000000..c2f5f4dc2502 --- /dev/null +++ b/drawinglayer/source/processor3d/zbufferprocessor3d.cxx @@ -0,0 +1,679 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: zbufferprocessor3d.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: aw $ $Date: 2008-05-14 09:21:54 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_drawinglayer.hxx" + +#include <drawinglayer/processor3d/zbufferprocessor3d.hxx> +#include <basegfx/raster/bpixelraster.hxx> +#include <vcl/bmpacc.hxx> +#include <basegfx/raster/rasterconvert3d.hxx> +#include <basegfx/raster/bzpixelraster.hxx> +#include <drawinglayer/attribute/materialattribute3d.hxx> +#include <drawinglayer/texture/texture.hxx> +#include <drawinglayer/attribute/sdrattribute3d.hxx> +#include <drawinglayer/primitive3d/drawinglayer_primitivetypes3d.hxx> +#include <drawinglayer/primitive3d/textureprimitive3d.hxx> +#include <drawinglayer/primitive3d/polygonprimitive3d.hxx> +#include <drawinglayer/primitive3d/polypolygonprimitive3d.hxx> +#include <drawinglayer/geometry/viewinformation2d.hxx> +#include <drawinglayer/geometry/transformation3d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace +{ + BitmapEx BPixelRasterToBitmapEx(const basegfx::BPixelRaster& rRaster, sal_uInt16 mnAntiAlialize) + { + BitmapEx aRetval; + const sal_uInt32 nWidth(mnAntiAlialize ? rRaster.getWidth()/mnAntiAlialize : rRaster.getWidth()); + const sal_uInt32 nHeight(mnAntiAlialize ? rRaster.getHeight()/mnAntiAlialize : rRaster.getHeight()); + + if(nWidth && nHeight) + { + const Size aDestSize(nWidth, nHeight); + sal_uInt8 nInitAlpha(255); + Bitmap aContent(aDestSize, 24); + AlphaMask aAlpha(aDestSize, &nInitAlpha); + BitmapWriteAccess* pContent = aContent.AcquireWriteAccess(); + BitmapWriteAccess* pAlpha = aAlpha.AcquireWriteAccess(); + + if(pContent && pAlpha) + { + if(mnAntiAlialize) + { + const sal_uInt16 nDivisor(mnAntiAlialize * mnAntiAlialize); + + for(sal_uInt32 y(0L); y < nHeight; y++) + { + for(sal_uInt32 x(0L); x < nWidth; x++) + { + sal_uInt16 nRed(0); + sal_uInt16 nGreen(0); + sal_uInt16 nBlue(0); + sal_uInt16 nOpacity(0); + sal_uInt32 nIndex(rRaster.getIndexFromXY(x * mnAntiAlialize, y * mnAntiAlialize)); + + for(sal_uInt32 c(0); c < mnAntiAlialize; c++) + { + for(sal_uInt32 d(0); d < mnAntiAlialize; d++) + { + const basegfx::BPixel& rPixel(rRaster.getBPixel(nIndex++)); + nRed = nRed + rPixel.getRed(); + nGreen = nGreen + rPixel.getGreen(); + nBlue = nBlue + rPixel.getBlue(); + nOpacity = nOpacity + rPixel.getOpacity(); + } + + nIndex += rRaster.getWidth() - mnAntiAlialize; + } + + nOpacity = nOpacity / nDivisor; + + if(nOpacity) + { + pContent->SetPixel(y, x, BitmapColor( + (sal_uInt8)(nRed / nDivisor), + (sal_uInt8)(nGreen / nDivisor), + (sal_uInt8)(nBlue / nDivisor))); + pAlpha->SetPixel(y, x, BitmapColor(255 - (sal_uInt8)nOpacity)); + } + } + } + } + else + { + sal_uInt32 nIndex(0L); + + for(sal_uInt32 y(0L); y < nHeight; y++) + { + for(sal_uInt32 x(0L); x < nWidth; x++) + { + const basegfx::BPixel& rPixel(rRaster.getBPixel(nIndex++)); + + if(rPixel.getOpacity()) + { + pContent->SetPixel(y, x, BitmapColor(rPixel.getRed(), rPixel.getGreen(), rPixel.getBlue())); + pAlpha->SetPixel(y, x, BitmapColor(255 - rPixel.getOpacity())); + } + } + } + } + + delete pContent; + delete pAlpha; + } + + aRetval = BitmapEx(aContent, aAlpha); + } + + return aRetval; + } +} // end of anonymous namespace + +////////////////////////////////////////////////////////////////////////////// + +class ZBufferRasterConverter3D : public basegfx::RasterConverter3D +{ +private: + const drawinglayer::processor3d::DefaultProcessor3D& mrProcessor; + basegfx::BZPixelRaster& mrBuffer; + + // interpolators for a single line span + basegfx::ip_single maIntZ; + basegfx::ip_triple maIntColor; + basegfx::ip_triple maIntNormal; + basegfx::ip_double maIntTexture; + basegfx::ip_triple maIntInvTexture; + + // current material to use for ratsreconversion + const drawinglayer::attribute::MaterialAttribute3D* mpCurrentMaterial; + + // bitfield + // some boolean flags for line span interpolator usages + unsigned mbModifyColor : 1; + unsigned mbUseTex : 1; + unsigned mbHasTexCoor : 1; + unsigned mbHasInvTexCoor : 1; + unsigned mbUseNrm : 1; + unsigned mbUseCol : 1; + + void getTextureCoor(basegfx::B2DPoint& rTarget) const + { + if(mbHasTexCoor) + { + rTarget.setX(maIntTexture.getX().getVal()); + rTarget.setY(maIntTexture.getY().getVal()); + } + else if(mbHasInvTexCoor) + { + const double fZFactor(maIntInvTexture.getZ().getVal()); + const double fInvZFactor(basegfx::fTools::equalZero(fZFactor) ? 1.0 : 1.0 / fZFactor); + rTarget.setX(maIntInvTexture.getX().getVal() * fInvZFactor); + rTarget.setY(maIntInvTexture.getY().getVal() * fInvZFactor); + } + } + + void incrementLineSpanInterpolators(double fStep) + { + maIntZ.increment(fStep); + + if(mbUseTex) + { + if(mbHasTexCoor) + { + maIntTexture.increment(fStep); + } + else if(mbHasInvTexCoor) + { + maIntInvTexture.increment(fStep); + } + } + + if(mbUseNrm) + { + maIntNormal.increment(fStep); + } + + if(mbUseCol) + { + maIntColor.increment(fStep); + } + } + + double decideColorAndOpacity(basegfx::BColor& rColor) + { + // init values with full opacity and material color + OSL_ENSURE(0 != mpCurrentMaterial, "CurrentMaterial not set (!)"); + double fOpacity(1.0); + rColor = mpCurrentMaterial->getColor(); + + if(mbUseTex) + { + basegfx::B2DPoint aTexCoor(0.0, 0.0); + getTextureCoor(aTexCoor); + + if(mrProcessor.getGeoTexSvx()) + { + // calc color in spot. This may also set to invisible already when + // e.g. bitmap textures have transparent parts + mrProcessor.getGeoTexSvx()->modifyBColor(aTexCoor, rColor, fOpacity); + } + + if(basegfx::fTools::more(fOpacity, 0.0) && mrProcessor.getTransparenceGeoTexSvx()) + { + // calc opacity. Object has a 2nd texture, a transparence texture + mrProcessor.getTransparenceGeoTexSvx()->modifyOpacity(aTexCoor, fOpacity); + } + } + + if(basegfx::fTools::more(fOpacity, 0.0)) + { + if(mrProcessor.getGeoTexSvx()) + { + if(mbUseNrm) + { + // blend texture with phong + rColor = mrProcessor.getSdrLightingAttribute().solveColorModel( + basegfx::B3DVector(maIntNormal.getX().getVal(), maIntNormal.getY().getVal(), maIntNormal.getZ().getVal()), + rColor, + mpCurrentMaterial->getSpecular(), + mpCurrentMaterial->getEmission(), + mpCurrentMaterial->getSpecularIntensity()); + } + else if(mbUseCol) + { + // blend texture with gouraud + basegfx::BColor aBlendColor(maIntColor.getX().getVal(), maIntColor.getY().getVal(), maIntColor.getZ().getVal()); + rColor *= aBlendColor; + } + else if(mrProcessor.getModulate()) + { + // blend texture with single material color + rColor *= mpCurrentMaterial->getColor(); + } + } + else + { + if(mbUseNrm) + { + // modify color with phong + rColor = mrProcessor.getSdrLightingAttribute().solveColorModel( + basegfx::B3DVector(maIntNormal.getX().getVal(), maIntNormal.getY().getVal(), maIntNormal.getZ().getVal()), + rColor, + mpCurrentMaterial->getSpecular(), + mpCurrentMaterial->getEmission(), + mpCurrentMaterial->getSpecularIntensity()); + } + else if(mbUseCol) + { + // modify color with gouraud + rColor.setRed(maIntColor.getX().getVal()); + rColor.setGreen(maIntColor.getY().getVal()); + rColor.setBlue(maIntColor.getZ().getVal()); + } + } + + if(mbModifyColor) + { + rColor = mrProcessor.getBColorModifierStack().getModifiedColor(rColor); + } + } + + return fOpacity; + } + + void setupLineSpanInterpolators(const basegfx::RasterConversionLineEntry3D& rA, const basegfx::RasterConversionLineEntry3D& rB) + { + // get inverse XDelta + const double xInvDelta(1.0 / (rB.getX().getVal() - rA.getX().getVal())); + + // prepare Z-interpolator + const double fZA(rA.getZ().getVal()); + const double fZB(rB.getZ().getVal()); + maIntZ = basegfx::ip_single(fZA, (fZB - fZA) * xInvDelta); + + // get bools and init other interpolators on demand accordingly + mbModifyColor = mrProcessor.getBColorModifierStack().count(); + mbHasTexCoor = SCANLINE_EMPTY_INDEX != rA.getTextureIndex() && SCANLINE_EMPTY_INDEX != rB.getTextureIndex(); + mbHasInvTexCoor = SCANLINE_EMPTY_INDEX != rA.getInverseTextureIndex() && SCANLINE_EMPTY_INDEX != rB.getInverseTextureIndex(); + const bool bTextureActive(mrProcessor.getGeoTexSvx() || mrProcessor.getTransparenceGeoTexSvx()); + mbUseTex = bTextureActive && (mbHasTexCoor || mbHasInvTexCoor || mrProcessor.getSimpleTextureActive()); + const bool bUseColorTex(mbUseTex && mrProcessor.getGeoTexSvx()); + const bool bNeedNrmOrCol(!bUseColorTex || (bUseColorTex && mrProcessor.getModulate())); + mbUseNrm = bNeedNrmOrCol && SCANLINE_EMPTY_INDEX != rA.getNormalIndex() && SCANLINE_EMPTY_INDEX != rB.getNormalIndex(); + mbUseCol = !mbUseNrm && bNeedNrmOrCol && SCANLINE_EMPTY_INDEX != rA.getColorIndex() && SCANLINE_EMPTY_INDEX != rB.getColorIndex(); + + if(mbUseTex) + { + if(mbHasTexCoor) + { + const basegfx::ip_double& rTA(getTextureInterpolators()[rA.getTextureIndex()]); + const basegfx::ip_double& rTB(getTextureInterpolators()[rB.getTextureIndex()]); + maIntTexture = basegfx::ip_double( + rTA.getX().getVal(), (rTB.getX().getVal() - rTA.getX().getVal()) * xInvDelta, + rTA.getY().getVal(), (rTB.getY().getVal() - rTA.getY().getVal()) * xInvDelta); + } + else if(mbHasInvTexCoor) + { + const basegfx::ip_triple& rITA(getInverseTextureInterpolators()[rA.getInverseTextureIndex()]); + const basegfx::ip_triple& rITB(getInverseTextureInterpolators()[rB.getInverseTextureIndex()]); + maIntInvTexture = basegfx::ip_triple( + rITA.getX().getVal(), (rITB.getX().getVal() - rITA.getX().getVal()) * xInvDelta, + rITA.getY().getVal(), (rITB.getY().getVal() - rITA.getY().getVal()) * xInvDelta, + rITA.getZ().getVal(), (rITB.getZ().getVal() - rITA.getZ().getVal()) * xInvDelta); + } + } + + if(mbUseNrm) + { + const basegfx::ip_triple& rNA(getNormalInterpolators()[rA.getNormalIndex()]); + const basegfx::ip_triple& rNB(getNormalInterpolators()[rB.getNormalIndex()]); + maIntNormal = basegfx::ip_triple( + rNA.getX().getVal(), (rNB.getX().getVal() - rNA.getX().getVal()) * xInvDelta, + rNA.getY().getVal(), (rNB.getY().getVal() - rNA.getY().getVal()) * xInvDelta, + rNA.getZ().getVal(), (rNB.getZ().getVal() - rNA.getZ().getVal()) * xInvDelta); + } + + if(mbUseCol) + { + const basegfx::ip_triple& rCA(getColorInterpolators()[rA.getColorIndex()]); + const basegfx::ip_triple& rCB(getColorInterpolators()[rB.getColorIndex()]); + maIntColor = basegfx::ip_triple( + rCA.getX().getVal(), (rCB.getX().getVal() - rCA.getX().getVal()) * xInvDelta, + rCA.getY().getVal(), (rCB.getY().getVal() - rCA.getY().getVal()) * xInvDelta, + rCA.getZ().getVal(), (rCB.getZ().getVal() - rCA.getZ().getVal()) * xInvDelta); + } + } + + virtual void processLineSpan(const basegfx::RasterConversionLineEntry3D& rA, const basegfx::RasterConversionLineEntry3D& rB, sal_Int32 nLine, sal_uInt32 nSpanCount); + +public: + ZBufferRasterConverter3D(basegfx::BZPixelRaster& rBuffer, const drawinglayer::processor3d::ZBufferProcessor3D& rProcessor) + : basegfx::RasterConverter3D(), + mrProcessor(rProcessor), + mrBuffer(rBuffer), + maIntZ(), + maIntColor(), + maIntNormal(), + maIntTexture(), + maIntInvTexture(), + mpCurrentMaterial(0), + mbModifyColor(false), + mbUseTex(false), + mbHasTexCoor(false), + mbUseNrm(false), + mbUseCol(false) + {} + + void setCurrentMaterial(const drawinglayer::attribute::MaterialAttribute3D& rMaterial) + { + mpCurrentMaterial = &rMaterial; + } +}; + +void ZBufferRasterConverter3D::processLineSpan(const basegfx::RasterConversionLineEntry3D& rA, const basegfx::RasterConversionLineEntry3D& rB, sal_Int32 nLine, sal_uInt32 nSpanCount) +{ + if(!(nSpanCount & 0x0001)) + { + if(nLine >= 0 && nLine < (sal_Int32)mrBuffer.getHeight()) + { + sal_uInt32 nXA(::std::min(mrBuffer.getWidth(), (sal_uInt32)::std::max((sal_Int32)0, basegfx::fround(rA.getX().getVal())))); + const sal_uInt32 nXB(::std::min(mrBuffer.getWidth(), (sal_uInt32)::std::max((sal_Int32)0, basegfx::fround(rB.getX().getVal())))); + + if(nXA < nXB) + { + // prepare the span interpolators + setupLineSpanInterpolators(rA, rB); + + // bring span interpolators to start condition by incrementing with the possible difference of + // clamped and non-clamped XStart. Interpolators are setup relying on double precision + // X-values, so that difference is the correct value to compensate for possible clampings + incrementLineSpanInterpolators(static_cast<double>(nXA) - rA.getX().getVal()); + + // prepare scanline index + sal_uInt32 nScanlineIndex(mrBuffer.getIndexFromXY(nXA, static_cast<sal_uInt32>(nLine))); + basegfx::BColor aNewColor; + + while(nXA < nXB) + { + // early-test Z values if we need to do anything at all + const double fNewZ(::std::max(0.0, ::std::min((double)0xffff, maIntZ.getVal()))); + const sal_uInt16 nNewZ(static_cast< sal_uInt16 >(fNewZ)); + sal_uInt16& rOldZ(mrBuffer.getZ(nScanlineIndex)); + + if(nNewZ > rOldZ) + { + // detect color and opacity for this pixel + const sal_uInt16 nOpacity(::std::max((sal_Int16)0, static_cast< sal_Int16 >(decideColorAndOpacity(aNewColor) * 255.0))); + + if(nOpacity > 0) + { + // avoid color overrun + aNewColor.clamp(); + + if(nOpacity >= 0x00ff) + { + // full opacity, set z and color + rOldZ = nNewZ; + mrBuffer.getBPixel(nScanlineIndex) = basegfx::BPixel(aNewColor, 0xff); + } + else + { + basegfx::BPixel& rDest = mrBuffer.getBPixel(nScanlineIndex); + + if(rDest.getOpacity()) + { + // both transparent, mix color based on front pixel's opacity + // (the new one) + const sal_uInt16 nTransparence(0x0100 - nOpacity); + rDest.setRed((sal_uInt8)(((rDest.getRed() * nTransparence) + ((sal_uInt16)(255.0 * aNewColor.getRed()) * nOpacity)) >> 8)); + rDest.setGreen((sal_uInt8)(((rDest.getGreen() * nTransparence) + ((sal_uInt16)(255.0 * aNewColor.getGreen()) * nOpacity)) >> 8)); + rDest.setBlue((sal_uInt8)(((rDest.getBlue() * nTransparence) + ((sal_uInt16)(255.0 * aNewColor.getBlue()) * nOpacity)) >> 8)); + + if(0xff != rDest.getOpacity()) + { + // destination is also transparent, mix opacities by weighting + // old opacity with new pixel's transparence and adding new opacity + rDest.setOpacity((sal_uInt8)(((rDest.getOpacity() * nTransparence) >> 8) + nOpacity)); + } + } + else + { + // dest is not visible. Set color. + rDest = basegfx::BPixel(aNewColor, (sal_uInt8)nOpacity); + } + } + } + } + + // increments + nScanlineIndex++; + nXA++; + incrementLineSpanInterpolators(1.0); + } + } + } + } +} + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace processor3d + { + // the processing method for a single, known primitive + void ZBufferProcessor3D::processBasePrimitive3D(const primitive3d::BasePrimitive3D& rBasePrimitive) + { + // it is a BasePrimitive3D implementation, use getPrimitiveID() call for switch + switch(rBasePrimitive.getPrimitiveID()) + { + case PRIMITIVE3D_ID_ALPHATEXTUREPRIMITIVE3D : + { + // AlphaTexturePrimitive3D + const primitive3d::AlphaTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::AlphaTexturePrimitive3D& >(rBasePrimitive); + + if(mbProcessTransparent) + { + impRenderGradientTexturePrimitive3D(rPrimitive, true); + } + else + { + mbContainsTransparent = true; + } + break; + } + case PRIMITIVE3D_ID_POLYGONHAIRLINEPRIMITIVE3D : + { + // directdraw of PolygonHairlinePrimitive3D + const primitive3d::PolygonHairlinePrimitive3D& rPrimitive = static_cast< const primitive3d::PolygonHairlinePrimitive3D& >(rBasePrimitive); + + // do something when either not transparent and no transMap, or transparent and a TransMap + if((bool)mbProcessTransparent == (0 != getTransparenceGeoTexSvx())) + { + impRenderPolygonHairlinePrimitive3D(rPrimitive); + } + break; + } + case PRIMITIVE3D_ID_POLYPOLYGONMATERIALPRIMITIVE3D : + { + // directdraw of PolyPolygonMaterialPrimitive3D + const primitive3d::PolyPolygonMaterialPrimitive3D& rPrimitive = static_cast< const primitive3d::PolyPolygonMaterialPrimitive3D& >(rBasePrimitive); + + // do something when either not transparent and no transMap, or transparent and a TransMap + if((bool)mbProcessTransparent == (0 != getTransparenceGeoTexSvx())) + { + impRenderPolyPolygonMaterialPrimitive3D(rPrimitive); + } + break; + } + default: + { + // use the DefaultProcessor3D::processBasePrimitive3D() + DefaultProcessor3D::processBasePrimitive3D(rBasePrimitive); + break; + } + } + } + + void ZBufferProcessor3D::processNonTransparent(const primitive3d::Primitive3DSequence& rSource) + { + if(mpBZPixelRaster) + { + mbProcessTransparent = false; + mbContainsTransparent = false; + process(rSource); + } + } + + void ZBufferProcessor3D::processTransparent(const primitive3d::Primitive3DSequence& rSource) + { + if(mpBZPixelRaster && mbContainsTransparent) + { + mbProcessTransparent = true; + process(rSource); + } + } + + void ZBufferProcessor3D::rasterconvertB3DPolygon(const attribute::MaterialAttribute3D& rMaterial, const basegfx::B3DPolygon& rHairline) const + { + if(mpBZPixelRaster) + { + mpZBufferRasterConverter3D->setCurrentMaterial(rMaterial); + mpZBufferRasterConverter3D->rasterconvertB3DPolygon(rHairline, 0, mpBZPixelRaster->getHeight(), mnAntiAlialize ? mnAntiAlialize : 1); + } + } + + void ZBufferProcessor3D::rasterconvertB3DPolyPolygon(const attribute::MaterialAttribute3D& rMaterial, const basegfx::B3DPolyPolygon& rFill) const + { + if(mpBZPixelRaster) + { + mpZBufferRasterConverter3D->setCurrentMaterial(rMaterial); + mpZBufferRasterConverter3D->rasterconvertB3DPolyPolygon(rFill, &maInvEyeToView, 0, mpBZPixelRaster->getHeight()); + } + } + + ZBufferProcessor3D::ZBufferProcessor3D( + const geometry::ViewInformation2D& rViewInformation, + const geometry::Transformation3D& rTransformation3D, + const attribute::SdrSceneAttribute& rSdrSceneAttribute, + const attribute::SdrLightingAttribute& rSdrLightingAttribute, + double fSizeX, + double fSizeY, + const basegfx::B2DRange& rVisiblePart, + sal_uInt16 nAntiAlialize) + : DefaultProcessor3D(rViewInformation.getViewTime(), rSdrSceneAttribute, rSdrLightingAttribute), + mpBZPixelRaster(0), + maInvEyeToView(), + mbProcessTransparent(false), + mbContainsTransparent(false), + mnAntiAlialize(nAntiAlialize), + mpZBufferRasterConverter3D(0) + { + // generate ViewSizes + const double fFullViewSizeX((rViewInformation.getViewTransformation() * basegfx::B2DVector(fSizeX, 0.0)).getLength()); + const double fFullViewSizeY((rViewInformation.getViewTransformation() * basegfx::B2DVector(0.0, fSizeY)).getLength()); + const double fViewSizeX(fFullViewSizeX * rVisiblePart.getWidth()); + const double fViewSizeY(fFullViewSizeY * rVisiblePart.getHeight()); + + // generate mnRasterWidth and mnRasterHeight + mnRasterWidth = (sal_uInt32)floor(fViewSizeX) + 1; + mnRasterHeight = (sal_uInt32)floor(fViewSizeY) + 1; + + if(mnRasterWidth && mnRasterHeight) + { + // create view unit buffer + mpBZPixelRaster = new basegfx::BZPixelRaster( + mnAntiAlialize ? mnRasterWidth * mnAntiAlialize : mnRasterWidth, + mnAntiAlialize ? mnRasterHeight * mnAntiAlialize : mnRasterHeight); + OSL_ENSURE(mpBZPixelRaster, "ZBufferProcessor3D: Could not allocate basegfx::BZPixelRaster (!)"); + basegfx::B3DHomMatrix aDeviceToView; + + // create DeviceToView + // outcome is [-1.0 .. 1.0] in X,Y and Z. + + { + // step one: + // + // bring from [-1.0 .. 1.0] in X,Y and Z to [0.0 .. 1.0]. Also + // necessary to + // - flip Y due to screen orientation + // - flip Z due to Z-Buffer orientation from back to front + + aDeviceToView.scale(0.5, -0.5, -0.5); + aDeviceToView.translate(0.5, 0.5, 0.5); + } + + { + // step two: + // + // bring from [0.0 .. 1.0] in X,Y and Z to view cordinates. also: + // - scale Z to [0.0 .. fMaxZDepth] + const double fMaxZDepth(double(0x0000ff00)); + aDeviceToView.translate(-rVisiblePart.getMinX(), -rVisiblePart.getMinY(), 0.0); + + if(mnAntiAlialize) + aDeviceToView.scale(fFullViewSizeX * mnAntiAlialize, fFullViewSizeY * mnAntiAlialize, fMaxZDepth); + else + aDeviceToView.scale(fFullViewSizeX, fFullViewSizeY, fMaxZDepth); + } + + // create world to eye transformation + maWorldToEye = rTransformation3D.getOrientation() * rTransformation3D.getTransformation(); + + // create EyeToView transformation + maWorldToView = aDeviceToView * rTransformation3D.getProjection() * maWorldToEye; + + // create inverse EyeToView transformation + maInvEyeToView = aDeviceToView * rTransformation3D.getProjection(); + maInvEyeToView.invert(); + + // prepare maRasterRange + maRasterRange.expand(basegfx::B2DPoint(0.0, 0.0)); + maRasterRange.expand(basegfx::B2DPoint(mpBZPixelRaster->getWidth(), mpBZPixelRaster->getHeight())); + + // create the raster converter + mpZBufferRasterConverter3D = new ZBufferRasterConverter3D(*mpBZPixelRaster, *this); + } + } + + ZBufferProcessor3D::~ZBufferProcessor3D() + { + if(mpBZPixelRaster) + { + delete mpZBufferRasterConverter3D; + delete mpBZPixelRaster; + } + } + + BitmapEx ZBufferProcessor3D::getBitmapEx() const + { + if(mpBZPixelRaster) + { + return BPixelRasterToBitmapEx(*mpBZPixelRaster, mnAntiAlialize); + } + + return BitmapEx(); + } + } // end of namespace processor3d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/drawinglayer/source/texture/texture.cxx b/drawinglayer/source/texture/texture.cxx index 0fb1e986484f..cde3b701bac8 100644 --- a/drawinglayer/source/texture/texture.cxx +++ b/drawinglayer/source/texture/texture.cxx @@ -4,9 +4,9 @@ * * $RCSfile: texture.cxx,v $ * - * $Revision: 1.4 $ + * $Revision: 1.5 $ * - * last change: $Author: aw $ $Date: 2008-03-05 09:15:46 $ + * last change: $Author: aw $ $Date: 2008-05-14 09:21:54 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -79,7 +79,7 @@ namespace drawinglayer void GeoTexSvx::modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const { - // base implementation uses inverse of luminance of solved color + // base implementation uses inverse of luminance of solved color (for testing only, may also be pure virtual) basegfx::BColor aBaseColor; modifyBColor(rUV, aBaseColor, rfOpacity); rfOpacity = 1.0 - aBaseColor.luminance(); |