nss: upgrade to release 3.73
[LibreOffice.git] / drawinglayer / source / processor3d / zbufferprocessor3d.cxx
bloba4f0deb33fc482da842cde1e95d8a00a00b45f5d
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 <processor3d/zbufferprocessor3d.hxx>
21 #include <basegfx/raster/bzpixelraster.hxx>
22 #include <basegfx/raster/rasterconvert3d.hxx>
23 #include <drawinglayer/attribute/materialattribute3d.hxx>
24 #include <texture/texture.hxx>
25 #include <basegfx/polygon/b3dpolygon.hxx>
26 #include <basegfx/polygon/b3dpolypolygon.hxx>
27 #include <basegfx/polygon/b3dpolygontools.hxx>
28 #include <basegfx/polygon/b3dpolypolygontools.hxx>
29 #include <drawinglayer/attribute/sdrlightingattribute3d.hxx>
31 using namespace com::sun::star;
33 class ZBufferRasterConverter3D : public basegfx::RasterConverter3D
35 private:
36 const drawinglayer::processor3d::DefaultProcessor3D& mrProcessor;
37 basegfx::BZPixelRaster& mrBuffer;
39 // interpolators for a single line span
40 basegfx::ip_single maIntZ;
41 basegfx::ip_triple maIntColor;
42 basegfx::ip_triple maIntNormal;
43 basegfx::ip_double maIntTexture;
44 basegfx::ip_triple maIntInvTexture;
46 // current material to use for rasterconversion
47 const drawinglayer::attribute::MaterialAttribute3D* mpCurrentMaterial;
49 // some boolean flags for line span interpolator usages
50 bool mbModifyColor : 1;
51 bool mbUseTex : 1;
52 bool mbHasTexCoor : 1;
53 bool mbHasInvTexCoor : 1;
54 bool mbUseNrm : 1;
55 bool mbUseCol : 1;
57 void getTextureCoor(basegfx::B2DPoint& rTarget) const
59 if(mbHasTexCoor)
61 rTarget.setX(maIntTexture.getX().getVal());
62 rTarget.setY(maIntTexture.getY().getVal());
64 else if(mbHasInvTexCoor)
66 const double fZFactor(maIntInvTexture.getZ().getVal());
67 const double fInvZFactor(basegfx::fTools::equalZero(fZFactor) ? 1.0 : 1.0 / fZFactor);
68 rTarget.setX(maIntInvTexture.getX().getVal() * fInvZFactor);
69 rTarget.setY(maIntInvTexture.getY().getVal() * fInvZFactor);
73 void incrementLineSpanInterpolators(double fStep)
75 maIntZ.increment(fStep);
77 if(mbUseTex)
79 if(mbHasTexCoor)
81 maIntTexture.increment(fStep);
83 else if(mbHasInvTexCoor)
85 maIntInvTexture.increment(fStep);
89 if(mbUseNrm)
91 maIntNormal.increment(fStep);
94 if(mbUseCol)
96 maIntColor.increment(fStep);
100 double decideColorAndOpacity(basegfx::BColor& rColor) const
102 // init values with full opacity and material color
103 OSL_ENSURE(nullptr != mpCurrentMaterial, "CurrentMaterial not set (!)");
104 double fOpacity(1.0);
105 rColor = mpCurrentMaterial->getColor();
107 if(mbUseTex)
109 basegfx::B2DPoint aTexCoor(0.0, 0.0);
110 getTextureCoor(aTexCoor);
112 if(mrProcessor.getGeoTexSvx())
114 // calc color in spot. This may also set to invisible already when
115 // e.g. bitmap textures have transparent parts
116 mrProcessor.getGeoTexSvx()->modifyBColor(aTexCoor, rColor, fOpacity);
119 if(basegfx::fTools::more(fOpacity, 0.0) && mrProcessor.getTransparenceGeoTexSvx())
121 // calc opacity. Object has a 2nd texture, a transparence texture
122 mrProcessor.getTransparenceGeoTexSvx()->modifyOpacity(aTexCoor, fOpacity);
126 if(basegfx::fTools::more(fOpacity, 0.0))
128 if(mrProcessor.getGeoTexSvx())
130 if(mbUseNrm)
132 // blend texture with phong
133 rColor = mrProcessor.getSdrLightingAttribute().solveColorModel(
134 basegfx::B3DVector(maIntNormal.getX().getVal(), maIntNormal.getY().getVal(), maIntNormal.getZ().getVal()),
135 rColor,
136 mpCurrentMaterial->getSpecular(),
137 mpCurrentMaterial->getEmission(),
138 mpCurrentMaterial->getSpecularIntensity());
140 else if(mbUseCol)
142 // blend texture with gouraud
143 basegfx::BColor aBlendColor(maIntColor.getX().getVal(), maIntColor.getY().getVal(), maIntColor.getZ().getVal());
144 rColor *= aBlendColor;
146 else if(mrProcessor.getModulate())
148 // blend texture with single material color
149 rColor *= mpCurrentMaterial->getColor();
152 else
154 if(mbUseNrm)
156 // modify color with phong
157 rColor = mrProcessor.getSdrLightingAttribute().solveColorModel(
158 basegfx::B3DVector(maIntNormal.getX().getVal(), maIntNormal.getY().getVal(), maIntNormal.getZ().getVal()),
159 rColor,
160 mpCurrentMaterial->getSpecular(),
161 mpCurrentMaterial->getEmission(),
162 mpCurrentMaterial->getSpecularIntensity());
164 else if(mbUseCol)
166 // modify color with gouraud
167 rColor.setRed(maIntColor.getX().getVal());
168 rColor.setGreen(maIntColor.getY().getVal());
169 rColor.setBlue(maIntColor.getZ().getVal());
173 if(mbModifyColor)
175 rColor = mrProcessor.getBColorModifierStack().getModifiedColor(rColor);
179 return fOpacity;
182 void setupLineSpanInterpolators(const basegfx::RasterConversionLineEntry3D& rA, const basegfx::RasterConversionLineEntry3D& rB)
184 // get inverse XDelta
185 const double xInvDelta(1.0 / (rB.getX().getVal() - rA.getX().getVal()));
187 // prepare Z-interpolator
188 const double fZA(rA.getZ().getVal());
189 const double fZB(rB.getZ().getVal());
190 maIntZ = basegfx::ip_single(fZA, (fZB - fZA) * xInvDelta);
192 // get bools and init other interpolators on demand accordingly
193 mbModifyColor = mrProcessor.getBColorModifierStack().count();
194 mbHasTexCoor = SCANLINE_EMPTY_INDEX != rA.getTextureIndex() && SCANLINE_EMPTY_INDEX != rB.getTextureIndex();
195 mbHasInvTexCoor = SCANLINE_EMPTY_INDEX != rA.getInverseTextureIndex() && SCANLINE_EMPTY_INDEX != rB.getInverseTextureIndex();
196 const bool bTextureActive(mrProcessor.getGeoTexSvx() || mrProcessor.getTransparenceGeoTexSvx());
197 mbUseTex = bTextureActive && (mbHasTexCoor || mbHasInvTexCoor || mrProcessor.getSimpleTextureActive());
198 const bool bUseColorTex(mbUseTex && mrProcessor.getGeoTexSvx());
199 const bool bNeedNrmOrCol(!bUseColorTex || mrProcessor.getModulate());
200 mbUseNrm = bNeedNrmOrCol && SCANLINE_EMPTY_INDEX != rA.getNormalIndex() && SCANLINE_EMPTY_INDEX != rB.getNormalIndex();
201 mbUseCol = !mbUseNrm && bNeedNrmOrCol && SCANLINE_EMPTY_INDEX != rA.getColorIndex() && SCANLINE_EMPTY_INDEX != rB.getColorIndex();
203 if(mbUseTex)
205 if(mbHasTexCoor)
207 const basegfx::ip_double& rTA(getTextureInterpolators()[rA.getTextureIndex()]);
208 const basegfx::ip_double& rTB(getTextureInterpolators()[rB.getTextureIndex()]);
209 maIntTexture = basegfx::ip_double(
210 rTA.getX().getVal(), (rTB.getX().getVal() - rTA.getX().getVal()) * xInvDelta,
211 rTA.getY().getVal(), (rTB.getY().getVal() - rTA.getY().getVal()) * xInvDelta);
213 else if(mbHasInvTexCoor)
215 const basegfx::ip_triple& rITA(getInverseTextureInterpolators()[rA.getInverseTextureIndex()]);
216 const basegfx::ip_triple& rITB(getInverseTextureInterpolators()[rB.getInverseTextureIndex()]);
217 maIntInvTexture = basegfx::ip_triple(
218 rITA.getX().getVal(), (rITB.getX().getVal() - rITA.getX().getVal()) * xInvDelta,
219 rITA.getY().getVal(), (rITB.getY().getVal() - rITA.getY().getVal()) * xInvDelta,
220 rITA.getZ().getVal(), (rITB.getZ().getVal() - rITA.getZ().getVal()) * xInvDelta);
224 if(mbUseNrm)
226 const basegfx::ip_triple& rNA(getNormalInterpolators()[rA.getNormalIndex()]);
227 const basegfx::ip_triple& rNB(getNormalInterpolators()[rB.getNormalIndex()]);
228 maIntNormal = basegfx::ip_triple(
229 rNA.getX().getVal(), (rNB.getX().getVal() - rNA.getX().getVal()) * xInvDelta,
230 rNA.getY().getVal(), (rNB.getY().getVal() - rNA.getY().getVal()) * xInvDelta,
231 rNA.getZ().getVal(), (rNB.getZ().getVal() - rNA.getZ().getVal()) * xInvDelta);
234 if(mbUseCol)
236 const basegfx::ip_triple& rCA(getColorInterpolators()[rA.getColorIndex()]);
237 const basegfx::ip_triple& rCB(getColorInterpolators()[rB.getColorIndex()]);
238 maIntColor = basegfx::ip_triple(
239 rCA.getX().getVal(), (rCB.getX().getVal() - rCA.getX().getVal()) * xInvDelta,
240 rCA.getY().getVal(), (rCB.getY().getVal() - rCA.getY().getVal()) * xInvDelta,
241 rCA.getZ().getVal(), (rCB.getZ().getVal() - rCA.getZ().getVal()) * xInvDelta);
245 virtual void processLineSpan(const basegfx::RasterConversionLineEntry3D& rA, const basegfx::RasterConversionLineEntry3D& rB, sal_Int32 nLine, sal_uInt32 nSpanCount) override;
247 public:
248 ZBufferRasterConverter3D(basegfx::BZPixelRaster& rBuffer, const drawinglayer::processor3d::ZBufferProcessor3D& rProcessor)
249 : basegfx::RasterConverter3D(),
250 mrProcessor(rProcessor),
251 mrBuffer(rBuffer),
252 maIntZ(),
253 maIntColor(),
254 maIntNormal(),
255 maIntTexture(),
256 maIntInvTexture(),
257 mpCurrentMaterial(nullptr),
258 mbModifyColor(false),
259 mbUseTex(false),
260 mbHasTexCoor(false),
261 mbHasInvTexCoor(false),
262 mbUseNrm(false),
263 mbUseCol(false)
266 void setCurrentMaterial(const drawinglayer::attribute::MaterialAttribute3D& rMaterial)
268 mpCurrentMaterial = &rMaterial;
272 void ZBufferRasterConverter3D::processLineSpan(const basegfx::RasterConversionLineEntry3D& rA, const basegfx::RasterConversionLineEntry3D& rB, sal_Int32 nLine, sal_uInt32 nSpanCount)
274 if(nSpanCount & 0x0001)
275 return;
277 if(nLine < 0 || nLine >= static_cast<sal_Int32>(mrBuffer.getHeight()))
278 return;
280 sal_uInt32 nXA(std::min(mrBuffer.getWidth(), static_cast<sal_uInt32>(std::max(sal_Int32(0), basegfx::fround(rA.getX().getVal())))));
281 const sal_uInt32 nXB(std::min(mrBuffer.getWidth(), static_cast<sal_uInt32>(std::max(sal_Int32(0), basegfx::fround(rB.getX().getVal())))));
283 if(nXA >= nXB)
284 return;
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::clamp(maIntZ.getVal(), 0.0, 65535.0));
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);
357 // helper class to buffer output for transparent rasterprimitives (filled areas
358 // and lines) until the end of processing. To ensure correct transparent
359 // visualisation, ZBuffers require to not set Z and to mix with the transparent
360 // color. If transparent rasterprimitives overlap, it gets necessary to
361 // paint transparent rasterprimitives from back to front to ensure that the
362 // mixing happens from back to front. For that purpose, transparent
363 // rasterprimitives are held in this class during the processing run, remember
364 // all data and will be rendered
366 class RasterPrimitive3D
368 private:
369 std::shared_ptr< drawinglayer::texture::GeoTexSvx > mpGeoTexSvx;
370 std::shared_ptr< drawinglayer::texture::GeoTexSvx > mpTransparenceGeoTexSvx;
371 drawinglayer::attribute::MaterialAttribute3D maMaterial;
372 basegfx::B3DPolyPolygon maPolyPolygon;
373 double mfCenterZ;
375 bool mbModulate : 1;
376 bool mbFilter : 1;
377 bool mbSimpleTextureActive : 1;
378 bool mbIsLine : 1;
380 public:
381 RasterPrimitive3D(
382 const std::shared_ptr< drawinglayer::texture::GeoTexSvx >& pGeoTexSvx,
383 const std::shared_ptr< drawinglayer::texture::GeoTexSvx >& pTransparenceGeoTexSvx,
384 const drawinglayer::attribute::MaterialAttribute3D& rMaterial,
385 const basegfx::B3DPolyPolygon& rPolyPolygon,
386 bool bModulate,
387 bool bFilter,
388 bool bSimpleTextureActive,
389 bool bIsLine)
390 : mpGeoTexSvx(pGeoTexSvx),
391 mpTransparenceGeoTexSvx(pTransparenceGeoTexSvx),
392 maMaterial(rMaterial),
393 maPolyPolygon(rPolyPolygon),
394 mfCenterZ(basegfx::utils::getRange(rPolyPolygon).getCenter().getZ()),
395 mbModulate(bModulate),
396 mbFilter(bFilter),
397 mbSimpleTextureActive(bSimpleTextureActive),
398 mbIsLine(bIsLine)
402 bool operator<(const RasterPrimitive3D& rComp) const
404 return mfCenterZ < rComp.mfCenterZ;
407 const std::shared_ptr< drawinglayer::texture::GeoTexSvx >& getGeoTexSvx() const { return mpGeoTexSvx; }
408 const std::shared_ptr< drawinglayer::texture::GeoTexSvx >& getTransparenceGeoTexSvx() const { return mpTransparenceGeoTexSvx; }
409 const drawinglayer::attribute::MaterialAttribute3D& getMaterial() const { return maMaterial; }
410 const basegfx::B3DPolyPolygon& getPolyPolygon() const { return maPolyPolygon; }
411 bool getModulate() const { return mbModulate; }
412 bool getFilter() const { return mbFilter; }
413 bool getSimpleTextureActive() const { return mbSimpleTextureActive; }
414 bool getIsLine() const { return mbIsLine; }
417 namespace drawinglayer::processor3d
419 void ZBufferProcessor3D::rasterconvertB3DPolygon(const attribute::MaterialAttribute3D& rMaterial, const basegfx::B3DPolygon& rHairline) const
421 if(getTransparenceCounter())
423 // transparent output; record for later sorting and painting from
424 // back to front
425 if(!mpRasterPrimitive3Ds)
427 const_cast< ZBufferProcessor3D* >(this)->mpRasterPrimitive3Ds.reset( new std::vector< RasterPrimitive3D > );
430 mpRasterPrimitive3Ds->push_back(RasterPrimitive3D(
431 getGeoTexSvx(),
432 getTransparenceGeoTexSvx(),
433 rMaterial,
434 basegfx::B3DPolyPolygon(rHairline),
435 getModulate(),
436 getFilter(),
437 getSimpleTextureActive(),
438 true));
440 else
442 // do rasterconversion
443 mpZBufferRasterConverter3D->setCurrentMaterial(rMaterial);
445 if(mnAntiAlialize > 1)
447 const bool bForceLineSnap(getOptionsDrawinglayer().IsAntiAliasing() && getOptionsDrawinglayer().IsSnapHorVerLinesToDiscrete());
449 if(bForceLineSnap)
451 basegfx::B3DHomMatrix aTransform;
452 basegfx::B3DPolygon aSnappedHairline(rHairline);
453 const double fScaleDown(1.0 / mnAntiAlialize);
454 const double fScaleUp(mnAntiAlialize);
456 // take oversampling out
457 aTransform.scale(fScaleDown, fScaleDown, 1.0);
458 aSnappedHairline.transform(aTransform);
460 // snap to integer
461 aSnappedHairline = basegfx::utils::snapPointsOfHorizontalOrVerticalEdges(aSnappedHairline);
463 // add oversampling again
464 aTransform.identity();
465 aTransform.scale(fScaleUp, fScaleUp, 1.0);
467 aSnappedHairline.transform(aTransform);
469 mpZBufferRasterConverter3D->rasterconvertB3DPolygon(aSnappedHairline, mnStartLine, mnStopLine, mnAntiAlialize);
471 else
473 mpZBufferRasterConverter3D->rasterconvertB3DPolygon(rHairline, mnStartLine, mnStopLine, mnAntiAlialize);
476 else
478 mpZBufferRasterConverter3D->rasterconvertB3DPolygon(rHairline, mnStartLine, mnStopLine, 1);
483 void ZBufferProcessor3D::rasterconvertB3DPolyPolygon(const attribute::MaterialAttribute3D& rMaterial, const basegfx::B3DPolyPolygon& rFill) const
485 if(getTransparenceCounter())
487 // transparent output; record for later sorting and painting from
488 // back to front
489 if(!mpRasterPrimitive3Ds)
491 const_cast< ZBufferProcessor3D* >(this)->mpRasterPrimitive3Ds.reset( new std::vector< RasterPrimitive3D > );
494 mpRasterPrimitive3Ds->push_back(RasterPrimitive3D(
495 getGeoTexSvx(),
496 getTransparenceGeoTexSvx(),
497 rMaterial,
498 rFill,
499 getModulate(),
500 getFilter(),
501 getSimpleTextureActive(),
502 false));
504 else
506 mpZBufferRasterConverter3D->setCurrentMaterial(rMaterial);
507 mpZBufferRasterConverter3D->rasterconvertB3DPolyPolygon(rFill, &maInvEyeToView, mnStartLine, mnStopLine);
511 ZBufferProcessor3D::ZBufferProcessor3D(
512 const geometry::ViewInformation3D& rViewInformation3D,
513 const attribute::SdrSceneAttribute& rSdrSceneAttribute,
514 const attribute::SdrLightingAttribute& rSdrLightingAttribute,
515 const basegfx::B2DRange& rVisiblePart,
516 sal_uInt16 nAntiAlialize,
517 double fFullViewSizeX,
518 double fFullViewSizeY,
519 basegfx::BZPixelRaster& rBZPixelRaster,
520 sal_uInt32 nStartLine,
521 sal_uInt32 nStopLine)
522 : DefaultProcessor3D(rViewInformation3D, rSdrSceneAttribute, rSdrLightingAttribute),
523 maInvEyeToView(),
524 mnAntiAlialize(nAntiAlialize),
525 mnStartLine(nStartLine),
526 mnStopLine(nStopLine)
528 // create DeviceToView for Z-Buffer renderer since Z is handled
529 // different from standard 3D transformations (Z is mirrored). Also
530 // the transformation includes the step from unit device coordinates
531 // to discrete units ([-1.0 .. 1.0] -> [minDiscrete .. maxDiscrete]
532 basegfx::B3DHomMatrix aDeviceToView;
535 // step one:
537 // bring from [-1.0 .. 1.0] in X,Y and Z to [0.0 .. 1.0]. Also
538 // necessary to
539 // - flip Y due to screen orientation
540 // - flip Z due to Z-Buffer orientation from back to front
542 aDeviceToView.scale(0.5, -0.5, -0.5);
543 aDeviceToView.translate(0.5, 0.5, 0.5);
547 // step two:
549 // bring from [0.0 .. 1.0] in X,Y and Z to view coordinates
551 // #i102611#
552 // also: scale Z to [1.5 .. 65534.5]. Normally, a range of [0.0 .. 65535.0]
553 // could be used, but a 'unused' value is needed, so '0' is used what reduces
554 // the range to [1.0 .. 65535.0]. It has also shown that small numerical errors
555 // (smaller as basegfx::fTools::mfSmallValue, which is 0.000000001) happen.
556 // Instead of checking those by basegfx::fTools methods which would cost
557 // runtime, just add another 0.5 tolerance to the start and end of the Z-Buffer
558 // range, thus resulting in [1.5 .. 65534.5]
559 const double fMaxZDepth(65533.0);
560 aDeviceToView.translate(-rVisiblePart.getMinX(), -rVisiblePart.getMinY(), 0.0);
562 if(mnAntiAlialize)
563 aDeviceToView.scale(fFullViewSizeX * mnAntiAlialize, fFullViewSizeY * mnAntiAlialize, fMaxZDepth);
564 else
565 aDeviceToView.scale(fFullViewSizeX, fFullViewSizeY, fMaxZDepth);
567 aDeviceToView.translate(0.0, 0.0, 1.5);
570 // update local ViewInformation3D with own DeviceToView
571 const geometry::ViewInformation3D aNewViewInformation3D(
572 getViewInformation3D().getObjectTransformation(),
573 getViewInformation3D().getOrientation(),
574 getViewInformation3D().getProjection(),
575 aDeviceToView,
576 getViewInformation3D().getViewTime(),
577 getViewInformation3D().getExtendedInformationSequence());
578 updateViewInformation(aNewViewInformation3D);
580 // prepare inverse EyeToView transformation. This can be done in constructor
581 // since changes in object transformations when processing TransformPrimitive3Ds
582 // do not influence this prepared partial transformation
583 maInvEyeToView = getViewInformation3D().getDeviceToView() * getViewInformation3D().getProjection();
584 maInvEyeToView.invert();
586 // prepare maRasterRange
587 maRasterRange.reset();
588 maRasterRange.expand(basegfx::B2DPoint(0.0, nStartLine));
589 maRasterRange.expand(basegfx::B2DPoint(rBZPixelRaster.getWidth(), nStopLine));
591 // create the raster converter
592 mpZBufferRasterConverter3D.reset( new ZBufferRasterConverter3D(rBZPixelRaster, *this) );
595 ZBufferProcessor3D::~ZBufferProcessor3D()
597 mpZBufferRasterConverter3D.reset();
599 if(mpRasterPrimitive3Ds)
601 OSL_FAIL("ZBufferProcessor3D: destructed, but there are unrendered transparent geometries. Use ZBufferProcessor3D::finish() to render these (!)");
603 mpRasterPrimitive3Ds.reset();
606 void ZBufferProcessor3D::finish()
608 if(!mpRasterPrimitive3Ds)
609 return;
611 // there are transparent rasterprimitives
612 const sal_uInt32 nSize(mpRasterPrimitive3Ds->size());
614 if(nSize > 1)
616 // sort them from back to front
617 std::sort(mpRasterPrimitive3Ds->begin(), mpRasterPrimitive3Ds->end());
620 for(sal_uInt32 a(0); a < nSize; a++)
622 // paint each one by setting the remembered data and calling
623 // the render method
624 const RasterPrimitive3D& rCandidate = (*mpRasterPrimitive3Ds)[a];
626 mpGeoTexSvx = rCandidate.getGeoTexSvx();
627 mpTransparenceGeoTexSvx = rCandidate.getTransparenceGeoTexSvx();
628 mbModulate = rCandidate.getModulate();
629 mbFilter = rCandidate.getFilter();
630 mbSimpleTextureActive = rCandidate.getSimpleTextureActive();
632 if(rCandidate.getIsLine())
634 rasterconvertB3DPolygon(
635 rCandidate.getMaterial(),
636 rCandidate.getPolyPolygon().getB3DPolygon(0));
638 else
640 rasterconvertB3DPolyPolygon(
641 rCandidate.getMaterial(),
642 rCandidate.getPolyPolygon());
646 // delete them to signal the destructor that all is done and
647 // to allow asserting there
648 mpRasterPrimitive3Ds.reset();
651 } // end of namespace
653 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */