Teach symstore more duplicated DLLs
[LibreOffice.git] / drawinglayer / source / processor3d / zbufferprocessor3d.cxx
blob95aff74b62fdd96193ad28c2a1caa1bcef25bc07
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <drawinglayer/processor3d/zbufferprocessor3d.hxx>
21 #include <basegfx/raster/bzpixelraster.hxx>
22 #include <basegfx/raster/rasterconvert3d.hxx>
23 #include <drawinglayer/attribute/materialattribute3d.hxx>
24 #include <drawinglayer/texture/texture.hxx>
25 #include <drawinglayer/primitive3d/drawinglayer_primitivetypes3d.hxx>
26 #include <drawinglayer/primitive3d/textureprimitive3d.hxx>
27 #include <drawinglayer/primitive3d/polygonprimitive3d.hxx>
28 #include <drawinglayer/primitive3d/polypolygonprimitive3d.hxx>
29 #include <drawinglayer/geometry/viewinformation2d.hxx>
30 #include <basegfx/polygon/b3dpolygontools.hxx>
31 #include <basegfx/polygon/b3dpolypolygontools.hxx>
32 #include <drawinglayer/attribute/sdrlightingattribute3d.hxx>
34 using namespace com::sun::star;
36 class ZBufferRasterConverter3D : public basegfx::RasterConverter3D
38 private:
39 const drawinglayer::processor3d::DefaultProcessor3D& mrProcessor;
40 basegfx::BZPixelRaster& mrBuffer;
42 // interpolators for a single line span
43 basegfx::ip_single maIntZ;
44 basegfx::ip_triple maIntColor;
45 basegfx::ip_triple maIntNormal;
46 basegfx::ip_double maIntTexture;
47 basegfx::ip_triple maIntInvTexture;
49 // current material to use for rasterconversion
50 const drawinglayer::attribute::MaterialAttribute3D* mpCurrentMaterial;
52 // some boolean flags for line span interpolator usages
53 bool mbModifyColor : 1;
54 bool mbUseTex : 1;
55 bool mbHasTexCoor : 1;
56 bool mbHasInvTexCoor : 1;
57 bool mbUseNrm : 1;
58 bool mbUseCol : 1;
60 void getTextureCoor(basegfx::B2DPoint& rTarget) const
62 if(mbHasTexCoor)
64 rTarget.setX(maIntTexture.getX().getVal());
65 rTarget.setY(maIntTexture.getY().getVal());
67 else if(mbHasInvTexCoor)
69 const double fZFactor(maIntInvTexture.getZ().getVal());
70 const double fInvZFactor(basegfx::fTools::equalZero(fZFactor) ? 1.0 : 1.0 / fZFactor);
71 rTarget.setX(maIntInvTexture.getX().getVal() * fInvZFactor);
72 rTarget.setY(maIntInvTexture.getY().getVal() * fInvZFactor);
76 void incrementLineSpanInterpolators(double fStep)
78 maIntZ.increment(fStep);
80 if(mbUseTex)
82 if(mbHasTexCoor)
84 maIntTexture.increment(fStep);
86 else if(mbHasInvTexCoor)
88 maIntInvTexture.increment(fStep);
92 if(mbUseNrm)
94 maIntNormal.increment(fStep);
97 if(mbUseCol)
99 maIntColor.increment(fStep);
103 double decideColorAndOpacity(basegfx::BColor& rColor) const
105 // init values with full opacity and material color
106 OSL_ENSURE(nullptr != mpCurrentMaterial, "CurrentMaterial not set (!)");
107 double fOpacity(1.0);
108 rColor = mpCurrentMaterial->getColor();
110 if(mbUseTex)
112 basegfx::B2DPoint aTexCoor(0.0, 0.0);
113 getTextureCoor(aTexCoor);
115 if(mrProcessor.getGeoTexSvx().get())
117 // calc color in spot. This may also set to invisible already when
118 // e.g. bitmap textures have transparent parts
119 mrProcessor.getGeoTexSvx()->modifyBColor(aTexCoor, rColor, fOpacity);
122 if(basegfx::fTools::more(fOpacity, 0.0) && mrProcessor.getTransparenceGeoTexSvx().get())
124 // calc opacity. Object has a 2nd texture, a transparence texture
125 mrProcessor.getTransparenceGeoTexSvx()->modifyOpacity(aTexCoor, fOpacity);
129 if(basegfx::fTools::more(fOpacity, 0.0))
131 if(mrProcessor.getGeoTexSvx().get())
133 if(mbUseNrm)
135 // blend texture with phong
136 rColor = mrProcessor.getSdrLightingAttribute().solveColorModel(
137 basegfx::B3DVector(maIntNormal.getX().getVal(), maIntNormal.getY().getVal(), maIntNormal.getZ().getVal()),
138 rColor,
139 mpCurrentMaterial->getSpecular(),
140 mpCurrentMaterial->getEmission(),
141 mpCurrentMaterial->getSpecularIntensity());
143 else if(mbUseCol)
145 // blend texture with gouraud
146 basegfx::BColor aBlendColor(maIntColor.getX().getVal(), maIntColor.getY().getVal(), maIntColor.getZ().getVal());
147 rColor *= aBlendColor;
149 else if(mrProcessor.getModulate())
151 // blend texture with single material color
152 rColor *= mpCurrentMaterial->getColor();
155 else
157 if(mbUseNrm)
159 // modify color with phong
160 rColor = mrProcessor.getSdrLightingAttribute().solveColorModel(
161 basegfx::B3DVector(maIntNormal.getX().getVal(), maIntNormal.getY().getVal(), maIntNormal.getZ().getVal()),
162 rColor,
163 mpCurrentMaterial->getSpecular(),
164 mpCurrentMaterial->getEmission(),
165 mpCurrentMaterial->getSpecularIntensity());
167 else if(mbUseCol)
169 // modify color with gouraud
170 rColor.setRed(maIntColor.getX().getVal());
171 rColor.setGreen(maIntColor.getY().getVal());
172 rColor.setBlue(maIntColor.getZ().getVal());
176 if(mbModifyColor)
178 rColor = mrProcessor.getBColorModifierStack().getModifiedColor(rColor);
182 return fOpacity;
185 void setupLineSpanInterpolators(const basegfx::RasterConversionLineEntry3D& rA, const basegfx::RasterConversionLineEntry3D& rB)
187 // get inverse XDelta
188 const double xInvDelta(1.0 / (rB.getX().getVal() - rA.getX().getVal()));
190 // prepare Z-interpolator
191 const double fZA(rA.getZ().getVal());
192 const double fZB(rB.getZ().getVal());
193 maIntZ = basegfx::ip_single(fZA, (fZB - fZA) * xInvDelta);
195 // get bools and init other interpolators on demand accordingly
196 mbModifyColor = mrProcessor.getBColorModifierStack().count();
197 mbHasTexCoor = SCANLINE_EMPTY_INDEX != rA.getTextureIndex() && SCANLINE_EMPTY_INDEX != rB.getTextureIndex();
198 mbHasInvTexCoor = SCANLINE_EMPTY_INDEX != rA.getInverseTextureIndex() && SCANLINE_EMPTY_INDEX != rB.getInverseTextureIndex();
199 const bool bTextureActive(mrProcessor.getGeoTexSvx().get() || mrProcessor.getTransparenceGeoTexSvx().get());
200 mbUseTex = bTextureActive && (mbHasTexCoor || mbHasInvTexCoor || mrProcessor.getSimpleTextureActive());
201 const bool bUseColorTex(mbUseTex && mrProcessor.getGeoTexSvx().get());
202 const bool bNeedNrmOrCol(!bUseColorTex || mrProcessor.getModulate());
203 mbUseNrm = bNeedNrmOrCol && SCANLINE_EMPTY_INDEX != rA.getNormalIndex() && SCANLINE_EMPTY_INDEX != rB.getNormalIndex();
204 mbUseCol = !mbUseNrm && bNeedNrmOrCol && SCANLINE_EMPTY_INDEX != rA.getColorIndex() && SCANLINE_EMPTY_INDEX != rB.getColorIndex();
206 if(mbUseTex)
208 if(mbHasTexCoor)
210 const basegfx::ip_double& rTA(getTextureInterpolators()[rA.getTextureIndex()]);
211 const basegfx::ip_double& rTB(getTextureInterpolators()[rB.getTextureIndex()]);
212 maIntTexture = basegfx::ip_double(
213 rTA.getX().getVal(), (rTB.getX().getVal() - rTA.getX().getVal()) * xInvDelta,
214 rTA.getY().getVal(), (rTB.getY().getVal() - rTA.getY().getVal()) * xInvDelta);
216 else if(mbHasInvTexCoor)
218 const basegfx::ip_triple& rITA(getInverseTextureInterpolators()[rA.getInverseTextureIndex()]);
219 const basegfx::ip_triple& rITB(getInverseTextureInterpolators()[rB.getInverseTextureIndex()]);
220 maIntInvTexture = basegfx::ip_triple(
221 rITA.getX().getVal(), (rITB.getX().getVal() - rITA.getX().getVal()) * xInvDelta,
222 rITA.getY().getVal(), (rITB.getY().getVal() - rITA.getY().getVal()) * xInvDelta,
223 rITA.getZ().getVal(), (rITB.getZ().getVal() - rITA.getZ().getVal()) * xInvDelta);
227 if(mbUseNrm)
229 const basegfx::ip_triple& rNA(getNormalInterpolators()[rA.getNormalIndex()]);
230 const basegfx::ip_triple& rNB(getNormalInterpolators()[rB.getNormalIndex()]);
231 maIntNormal = basegfx::ip_triple(
232 rNA.getX().getVal(), (rNB.getX().getVal() - rNA.getX().getVal()) * xInvDelta,
233 rNA.getY().getVal(), (rNB.getY().getVal() - rNA.getY().getVal()) * xInvDelta,
234 rNA.getZ().getVal(), (rNB.getZ().getVal() - rNA.getZ().getVal()) * xInvDelta);
237 if(mbUseCol)
239 const basegfx::ip_triple& rCA(getColorInterpolators()[rA.getColorIndex()]);
240 const basegfx::ip_triple& rCB(getColorInterpolators()[rB.getColorIndex()]);
241 maIntColor = basegfx::ip_triple(
242 rCA.getX().getVal(), (rCB.getX().getVal() - rCA.getX().getVal()) * xInvDelta,
243 rCA.getY().getVal(), (rCB.getY().getVal() - rCA.getY().getVal()) * xInvDelta,
244 rCA.getZ().getVal(), (rCB.getZ().getVal() - rCA.getZ().getVal()) * xInvDelta);
248 virtual void processLineSpan(const basegfx::RasterConversionLineEntry3D& rA, const basegfx::RasterConversionLineEntry3D& rB, sal_Int32 nLine, sal_uInt32 nSpanCount) override;
250 public:
251 ZBufferRasterConverter3D(basegfx::BZPixelRaster& rBuffer, const drawinglayer::processor3d::ZBufferProcessor3D& rProcessor)
252 : basegfx::RasterConverter3D(),
253 mrProcessor(rProcessor),
254 mrBuffer(rBuffer),
255 maIntZ(),
256 maIntColor(),
257 maIntNormal(),
258 maIntTexture(),
259 maIntInvTexture(),
260 mpCurrentMaterial(nullptr),
261 mbModifyColor(false),
262 mbUseTex(false),
263 mbHasTexCoor(false),
264 mbHasInvTexCoor(false),
265 mbUseNrm(false),
266 mbUseCol(false)
269 void setCurrentMaterial(const drawinglayer::attribute::MaterialAttribute3D& rMaterial)
271 mpCurrentMaterial = &rMaterial;
275 void ZBufferRasterConverter3D::processLineSpan(const basegfx::RasterConversionLineEntry3D& rA, const basegfx::RasterConversionLineEntry3D& rB, sal_Int32 nLine, sal_uInt32 nSpanCount)
277 if(!(nSpanCount & 0x0001))
279 if(nLine >= 0 && nLine < static_cast<sal_Int32>(mrBuffer.getHeight()))
281 sal_uInt32 nXA(std::min(mrBuffer.getWidth(), static_cast<sal_uInt32>(std::max(sal_Int32(0), basegfx::fround(rA.getX().getVal())))));
282 const sal_uInt32 nXB(std::min(mrBuffer.getWidth(), static_cast<sal_uInt32>(std::max(sal_Int32(0), basegfx::fround(rB.getX().getVal())))));
284 if(nXA < nXB)
286 // prepare the span interpolators
287 setupLineSpanInterpolators(rA, rB);
289 // bring span interpolators to start condition by incrementing with the possible difference of
290 // clamped and non-clamped XStart. Interpolators are setup relying on double precision
291 // X-values, so that difference is the correct value to compensate for possible clampings
292 incrementLineSpanInterpolators(static_cast<double>(nXA) - rA.getX().getVal());
294 // prepare scanline index
295 sal_uInt32 nScanlineIndex(mrBuffer.getIndexFromXY(nXA, static_cast<sal_uInt32>(nLine)));
296 basegfx::BColor aNewColor;
298 while(nXA < nXB)
300 // early-test Z values if we need to do anything at all
301 const double fNewZ(std::max(0.0, std::min(double(0xffff), maIntZ.getVal())));
302 const sal_uInt16 nNewZ(static_cast< sal_uInt16 >(fNewZ));
303 sal_uInt16& rOldZ(mrBuffer.getZ(nScanlineIndex));
305 if(nNewZ > rOldZ)
307 // detect color and opacity for this pixel
308 const sal_uInt16 nOpacity(std::max(sal_Int16(0), static_cast< sal_Int16 >(decideColorAndOpacity(aNewColor) * 255.0)));
310 if(nOpacity > 0)
312 // avoid color overrun
313 aNewColor.clamp();
315 if(nOpacity >= 0x00ff)
317 // full opacity (not transparent), set z and color
318 rOldZ = nNewZ;
319 mrBuffer.getBPixel(nScanlineIndex) = basegfx::BPixel(aNewColor, 0xff);
321 else
323 basegfx::BPixel& rDest = mrBuffer.getBPixel(nScanlineIndex);
325 if(rDest.getOpacity())
327 // mix new color by using
328 // color' = color * (1 - opacity) + newcolor * opacity
329 const sal_uInt16 nTransparence(0x0100 - nOpacity);
330 rDest.setRed(static_cast<sal_uInt8>(((rDest.getRed() * nTransparence) + (static_cast<sal_uInt16>(255.0 * aNewColor.getRed()) * nOpacity)) >> 8));
331 rDest.setGreen(static_cast<sal_uInt8>(((rDest.getGreen() * nTransparence) + (static_cast<sal_uInt16>(255.0 * aNewColor.getGreen()) * nOpacity)) >> 8));
332 rDest.setBlue(static_cast<sal_uInt8>(((rDest.getBlue() * nTransparence) + (static_cast<sal_uInt16>(255.0 * aNewColor.getBlue()) * nOpacity)) >> 8));
334 if(0xff != rDest.getOpacity())
336 // both are transparent, mix new opacity by using
337 // opacity = newopacity * (1 - oldopacity) + oldopacity
338 rDest.setOpacity(static_cast<sal_uInt8>((nOpacity * (0x0100 - rDest.getOpacity())) >> 8) + rDest.getOpacity());
341 else
343 // dest is unused, set color
344 rDest = basegfx::BPixel(aNewColor, static_cast<sal_uInt8>(nOpacity));
350 // increments
351 nScanlineIndex++;
352 nXA++;
353 incrementLineSpanInterpolators(1.0);
360 // helper class to buffer output for transparent rasterprimitives (filled areas
361 // and lines) until the end of processing. To ensure correct transparent
362 // visualisation, ZBuffers require to not set Z and to mix with the transparent
363 // color. If transparent rasterprimitives overlap, it gets necessary to
364 // paint transparent rasterprimitives from back to front to ensure that the
365 // mixing happens from back to front. For that purpose, transparent
366 // rasterprimitives are held in this class during the processing run, remember
367 // all data and will be rendered
369 class RasterPrimitive3D
371 private:
372 std::shared_ptr< drawinglayer::texture::GeoTexSvx > mpGeoTexSvx;
373 std::shared_ptr< drawinglayer::texture::GeoTexSvx > mpTransparenceGeoTexSvx;
374 drawinglayer::attribute::MaterialAttribute3D maMaterial;
375 basegfx::B3DPolyPolygon maPolyPolygon;
376 double mfCenterZ;
378 bool mbModulate : 1;
379 bool mbFilter : 1;
380 bool mbSimpleTextureActive : 1;
381 bool mbIsLine : 1;
383 public:
384 RasterPrimitive3D(
385 const std::shared_ptr< drawinglayer::texture::GeoTexSvx >& pGeoTexSvx,
386 const std::shared_ptr< drawinglayer::texture::GeoTexSvx >& pTransparenceGeoTexSvx,
387 const drawinglayer::attribute::MaterialAttribute3D& rMaterial,
388 const basegfx::B3DPolyPolygon& rPolyPolygon,
389 bool bModulate,
390 bool bFilter,
391 bool bSimpleTextureActive,
392 bool bIsLine)
393 : mpGeoTexSvx(pGeoTexSvx),
394 mpTransparenceGeoTexSvx(pTransparenceGeoTexSvx),
395 maMaterial(rMaterial),
396 maPolyPolygon(rPolyPolygon),
397 mfCenterZ(basegfx::utils::getRange(rPolyPolygon).getCenter().getZ()),
398 mbModulate(bModulate),
399 mbFilter(bFilter),
400 mbSimpleTextureActive(bSimpleTextureActive),
401 mbIsLine(bIsLine)
405 bool operator<(const RasterPrimitive3D& rComp) const
407 return mfCenterZ < rComp.mfCenterZ;
410 const std::shared_ptr< drawinglayer::texture::GeoTexSvx >& getGeoTexSvx() const { return mpGeoTexSvx; }
411 const std::shared_ptr< drawinglayer::texture::GeoTexSvx >& getTransparenceGeoTexSvx() const { return mpTransparenceGeoTexSvx; }
412 const drawinglayer::attribute::MaterialAttribute3D& getMaterial() const { return maMaterial; }
413 const basegfx::B3DPolyPolygon& getPolyPolygon() const { return maPolyPolygon; }
414 bool getModulate() const { return mbModulate; }
415 bool getFilter() const { return mbFilter; }
416 bool getSimpleTextureActive() const { return mbSimpleTextureActive; }
417 bool getIsLine() const { return mbIsLine; }
420 namespace drawinglayer
422 namespace processor3d
424 void ZBufferProcessor3D::rasterconvertB3DPolygon(const attribute::MaterialAttribute3D& rMaterial, const basegfx::B3DPolygon& rHairline) const
426 if(getTransparenceCounter())
428 // transparent output; record for later sorting and painting from
429 // back to front
430 if(!mpRasterPrimitive3Ds)
432 const_cast< ZBufferProcessor3D* >(this)->mpRasterPrimitive3Ds.reset( new std::vector< RasterPrimitive3D > );
435 mpRasterPrimitive3Ds->push_back(RasterPrimitive3D(
436 getGeoTexSvx(),
437 getTransparenceGeoTexSvx(),
438 rMaterial,
439 basegfx::B3DPolyPolygon(rHairline),
440 getModulate(),
441 getFilter(),
442 getSimpleTextureActive(),
443 true));
445 else
447 // do rasterconversion
448 mpZBufferRasterConverter3D->setCurrentMaterial(rMaterial);
450 if(mnAntiAlialize > 1)
452 const bool bForceLineSnap(getOptionsDrawinglayer().IsAntiAliasing() && getOptionsDrawinglayer().IsSnapHorVerLinesToDiscrete());
454 if(bForceLineSnap)
456 basegfx::B3DHomMatrix aTransform;
457 basegfx::B3DPolygon aSnappedHairline(rHairline);
458 const double fScaleDown(1.0 / mnAntiAlialize);
459 const double fScaleUp(mnAntiAlialize);
461 // take oversampling out
462 aTransform.scale(fScaleDown, fScaleDown, 1.0);
463 aSnappedHairline.transform(aTransform);
465 // snap to integer
466 aSnappedHairline = basegfx::utils::snapPointsOfHorizontalOrVerticalEdges(aSnappedHairline);
468 // add oversampling again
469 aTransform.identity();
470 aTransform.scale(fScaleUp, fScaleUp, 1.0);
472 aSnappedHairline.transform(aTransform);
474 mpZBufferRasterConverter3D->rasterconvertB3DPolygon(aSnappedHairline, mnStartLine, mnStopLine, mnAntiAlialize);
476 else
478 mpZBufferRasterConverter3D->rasterconvertB3DPolygon(rHairline, mnStartLine, mnStopLine, mnAntiAlialize);
481 else
483 mpZBufferRasterConverter3D->rasterconvertB3DPolygon(rHairline, mnStartLine, mnStopLine, 1);
488 void ZBufferProcessor3D::rasterconvertB3DPolyPolygon(const attribute::MaterialAttribute3D& rMaterial, const basegfx::B3DPolyPolygon& rFill) const
490 if(getTransparenceCounter())
492 // transparent output; record for later sorting and painting from
493 // back to front
494 if(!mpRasterPrimitive3Ds)
496 const_cast< ZBufferProcessor3D* >(this)->mpRasterPrimitive3Ds.reset( new std::vector< RasterPrimitive3D > );
499 mpRasterPrimitive3Ds->push_back(RasterPrimitive3D(
500 getGeoTexSvx(),
501 getTransparenceGeoTexSvx(),
502 rMaterial,
503 rFill,
504 getModulate(),
505 getFilter(),
506 getSimpleTextureActive(),
507 false));
509 else
511 mpZBufferRasterConverter3D->setCurrentMaterial(rMaterial);
512 mpZBufferRasterConverter3D->rasterconvertB3DPolyPolygon(rFill, &maInvEyeToView, mnStartLine, mnStopLine);
516 ZBufferProcessor3D::ZBufferProcessor3D(
517 const geometry::ViewInformation3D& rViewInformation3D,
518 const attribute::SdrSceneAttribute& rSdrSceneAttribute,
519 const attribute::SdrLightingAttribute& rSdrLightingAttribute,
520 const basegfx::B2DRange& rVisiblePart,
521 sal_uInt16 nAntiAlialize,
522 double fFullViewSizeX,
523 double fFullViewSizeY,
524 basegfx::BZPixelRaster& rBZPixelRaster,
525 sal_uInt32 nStartLine,
526 sal_uInt32 nStopLine)
527 : DefaultProcessor3D(rViewInformation3D, rSdrSceneAttribute, rSdrLightingAttribute),
528 maInvEyeToView(),
529 mnAntiAlialize(nAntiAlialize),
530 mnStartLine(nStartLine),
531 mnStopLine(nStopLine)
533 // create DeviceToView for Z-Buffer renderer since Z is handled
534 // different from standard 3D transformations (Z is mirrored). Also
535 // the transformation includes the step from unit device coordinates
536 // to discrete units ([-1.0 .. 1.0] -> [minDiscrete .. maxDiscrete]
537 basegfx::B3DHomMatrix aDeviceToView;
540 // step one:
542 // bring from [-1.0 .. 1.0] in X,Y and Z to [0.0 .. 1.0]. Also
543 // necessary to
544 // - flip Y due to screen orientation
545 // - flip Z due to Z-Buffer orientation from back to front
547 aDeviceToView.scale(0.5, -0.5, -0.5);
548 aDeviceToView.translate(0.5, 0.5, 0.5);
552 // step two:
554 // bring from [0.0 .. 1.0] in X,Y and Z to view coordinates
556 // #i102611#
557 // also: scale Z to [1.5 .. 65534.5]. Normally, a range of [0.0 .. 65535.0]
558 // could be used, but a 'unused' value is needed, so '0' is used what reduces
559 // the range to [1.0 .. 65535.0]. It has also shown that small numerical errors
560 // (smaller as basegfx::fTools::mfSmallValue, which is 0.000000001) happen.
561 // Instead of checking those by basegfx::fTools methods which would cost
562 // runtime, just add another 0.5 tolerance to the start and end of the Z-Buffer
563 // range, thus resulting in [1.5 .. 65534.5]
564 const double fMaxZDepth(65533.0);
565 aDeviceToView.translate(-rVisiblePart.getMinX(), -rVisiblePart.getMinY(), 0.0);
567 if(mnAntiAlialize)
568 aDeviceToView.scale(fFullViewSizeX * mnAntiAlialize, fFullViewSizeY * mnAntiAlialize, fMaxZDepth);
569 else
570 aDeviceToView.scale(fFullViewSizeX, fFullViewSizeY, fMaxZDepth);
572 aDeviceToView.translate(0.0, 0.0, 1.5);
575 // update local ViewInformation3D with own DeviceToView
576 const geometry::ViewInformation3D aNewViewInformation3D(
577 getViewInformation3D().getObjectTransformation(),
578 getViewInformation3D().getOrientation(),
579 getViewInformation3D().getProjection(),
580 aDeviceToView,
581 getViewInformation3D().getViewTime(),
582 getViewInformation3D().getExtendedInformationSequence());
583 updateViewInformation(aNewViewInformation3D);
585 // prepare inverse EyeToView transformation. This can be done in constructor
586 // since changes in object transformations when processing TransformPrimitive3Ds
587 // do not influence this prepared partial transformation
588 maInvEyeToView = getViewInformation3D().getDeviceToView() * getViewInformation3D().getProjection();
589 maInvEyeToView.invert();
591 // prepare maRasterRange
592 maRasterRange.reset();
593 maRasterRange.expand(basegfx::B2DPoint(0.0, nStartLine));
594 maRasterRange.expand(basegfx::B2DPoint(rBZPixelRaster.getWidth(), nStopLine));
596 // create the raster converter
597 mpZBufferRasterConverter3D.reset( new ZBufferRasterConverter3D(rBZPixelRaster, *this) );
600 ZBufferProcessor3D::~ZBufferProcessor3D()
602 mpZBufferRasterConverter3D.reset();
604 if(mpRasterPrimitive3Ds)
606 OSL_FAIL("ZBufferProcessor3D: destructed, but there are unrendered transparent geometries. Use ZBufferProcessor3D::finish() to render these (!)");
608 mpRasterPrimitive3Ds.reset();
611 void ZBufferProcessor3D::finish()
613 if(mpRasterPrimitive3Ds)
615 // there are transparent rasterprimitives
616 const sal_uInt32 nSize(mpRasterPrimitive3Ds->size());
618 if(nSize > 1)
620 // sort them from back to front
621 std::sort(mpRasterPrimitive3Ds->begin(), mpRasterPrimitive3Ds->end());
624 for(sal_uInt32 a(0); a < nSize; a++)
626 // paint each one by setting the remembered data and calling
627 // the render method
628 const RasterPrimitive3D& rCandidate = (*mpRasterPrimitive3Ds)[a];
630 mpGeoTexSvx = rCandidate.getGeoTexSvx();
631 mpTransparenceGeoTexSvx = rCandidate.getTransparenceGeoTexSvx();
632 mbModulate = rCandidate.getModulate();
633 mbFilter = rCandidate.getFilter();
634 mbSimpleTextureActive = rCandidate.getSimpleTextureActive();
636 if(rCandidate.getIsLine())
638 rasterconvertB3DPolygon(
639 rCandidate.getMaterial(),
640 rCandidate.getPolyPolygon().getB3DPolygon(0));
642 else
644 rasterconvertB3DPolyPolygon(
645 rCandidate.getMaterial(),
646 rCandidate.getPolyPolygon());
650 // delete them to signal the destructor that all is done and
651 // to allow asserting there
652 mpRasterPrimitive3Ds.reset();
655 } // end of namespace processor3d
656 } // end of namespace drawinglayer
658 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */