summaryrefslogtreecommitdiff
path: root/goodies/source/base3d/base3d.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'goodies/source/base3d/base3d.cxx')
-rw-r--r--goodies/source/base3d/base3d.cxx1268
1 files changed, 1268 insertions, 0 deletions
diff --git a/goodies/source/base3d/base3d.cxx b/goodies/source/base3d/base3d.cxx
new file mode 100644
index 000000000000..6a45cb2fb01d
--- /dev/null
+++ b/goodies/source/base3d/base3d.cxx
@@ -0,0 +1,1268 @@
+/*************************************************************************
+ *
+ * $RCSfile: base3d.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:30:10 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 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
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _B3D_BASE3D_HXX
+#include "base3d.hxx"
+#endif
+
+#ifndef _B3D_B3DENTITY_HXX
+#include "b3dentty.hxx"
+#endif
+
+#ifndef _B3D_B3DTEX_HXX
+#include "b3dtex.hxx"
+#endif
+
+#ifndef _B3D_B3DOPNGL_HXX
+#include "b3dopngl.hxx"
+#endif
+
+#ifndef _B3D_B3DDEFLT_HXX
+#include "b3ddeflt.hxx"
+#endif
+
+#ifndef _B3D_B3DPRINT_HXX
+#include "b3dprint.hxx"
+#endif
+
+#ifndef _B3D_B3DGEOM_HXX
+#include "b3dgeom.hxx"
+#endif
+
+#ifndef _B3D_B3DTRANS_HXX
+#include "b3dtrans.hxx"
+#endif
+
+#ifndef _SHL_HXX
+#include <tools/shl.hxx>
+#endif
+
+#ifndef _SV_POLY_HXX
+#include <vcl/poly.hxx>
+#endif
+
+#ifndef _SFXINIPROP_HXX
+#include <svtools/iniprop.hxx>
+#endif
+
+#ifndef _SFXINIMGR_HXX
+#include <svtools/iniman.hxx>
+#endif
+
+/*************************************************************************
+|*
+|* Konstruktor B3dGlobalData
+|*
+\************************************************************************/
+
+B3dGlobalData::B3dGlobalData()
+{
+}
+
+/*************************************************************************
+|*
+|* Destruktor B3dGlobalData
+|*
+\************************************************************************/
+
+B3dGlobalData::~B3dGlobalData()
+{
+}
+
+/*************************************************************************
+|*
+|* Konstruktor Base3D
+|*
+\************************************************************************/
+
+Base3D::Base3D(OutputDevice* pOutDev)
+: OutDev3D(),
+ pDevice(pOutDev),
+ eObjectMode(Base3DPoints),
+ aCurrentColor(Color(0xff, 0xff, 0xff)),
+ aComplexPolygon(),
+ eRenderModeFront(Base3DRenderFill),
+ eRenderModeBack(Base3DRenderFill),
+ eShadeModel(Base3DSmooth),
+ eCullMode(Base3DCullNone),
+ fPointSize(1.0),
+ fLineWidth(1.0),
+ pActiveTexture(NULL),
+ pTransformationSet(NULL),
+ pLightGroup(NULL),
+ aMaterialFront(),
+ aMaterialBack(),
+ nDisplayQuality(127),
+ bEdgeFlag(TRUE),
+ bContextIsValid(TRUE),
+ bPolyOffsetFill(FALSE),
+ bPolyOffsetLine(FALSE),
+ bPolyOffsetPoint(FALSE),
+ bScissorRegionActive(FALSE),
+ bDitherActive(TRUE)
+{
+ // Grundsaetzliche Materialeigenschaften setzen
+ ResetMaterial(Base3DMaterialFrontAndBack);
+
+ // Fuer OS/2 die FP-Exceptions abschalten
+#if defined(OS2)
+#define SC_FPEXCEPTIONS_ON() _control87( MCW_EM, 0 )
+#define SC_FPEXCEPTIONS_OFF() _control87( MCW_EM, MCW_EM )
+ SC_FPEXCEPTIONS_OFF();
+#endif
+
+ // Fuer WIN95/NT die FP-Exceptions abschalten
+#if defined(WNT) || defined(WIN)
+#define SC_FPEXCEPTIONS_ON() _control87( _MCW_EM, 0 )
+#define SC_FPEXCEPTIONS_OFF() _control87( _MCW_EM, _MCW_EM )
+ SC_FPEXCEPTIONS_OFF();
+#endif
+}
+
+/*************************************************************************
+|*
+|* Destruktor Base3D
+|*
+\************************************************************************/
+
+Base3D::~Base3D()
+{
+}
+
+/*************************************************************************
+|*
+|* Erzeuge einen Base3D Kontext in Anhaengigkeit vom uebergebenen
+|* OutputDevice und trage Ihn dort ein
+|*
+\************************************************************************/
+
+Base3D* Base3D::Create(OutputDevice* pOutDev, BOOL bForcePrinter)
+{
+ Base3D* pRetval = NULL;
+ if(pOutDev)
+ {
+ // Anforderungen feststellen
+ BOOL bOwnDevice = FALSE;
+ if(pOutDev->GetOutDevType() == OUTDEV_VIRDEV
+ || pOutDev->GetOutDevType() == OUTDEV_PRINTER
+ || pOutDev->GetConnectMetaFile() != NULL)
+ bOwnDevice = TRUE;
+
+ // Existiert schon ein 3D-Kontext, der auch an dieses
+ // OutputDevice gebunden ist?
+ if(pOutDev->Get3DContext()
+ && ((Base3D*)(pOutDev->Get3DContext()))->GetOutputDevice() == pOutDev)
+ {
+ pRetval = (Base3D*)pOutDev->Get3DContext();
+ }
+
+ // Falls Ja, ist er den Anforderungen gewachsen?
+ if(pRetval)
+ {
+ BOOL bForceNew(FALSE);
+
+ if((!bForceNew) && (bOwnDevice)&&(pRetval->GetBase3DType() == BASE3D_TYPE_OPENGL))
+ {
+ bForceNew = TRUE;
+ }
+
+ if((!bForceNew) && (bForcePrinter)&&(pRetval->GetBase3DType() != BASE3D_TYPE_PRINTER))
+ {
+ bForceNew = TRUE;
+ }
+
+ if((!bForceNew) && (!bForcePrinter)&&(pRetval->GetBase3DType() == BASE3D_TYPE_PRINTER))
+ {
+ bForceNew = TRUE;
+ }
+
+ if(!bForceNew && !bOwnDevice)
+ {
+ // Versuchen, einen OpenGL Kontext zu bekommen? Teste das
+ // globale Flag aus der .INI
+ BOOL bUseOpenGL = FALSE;
+ String aTmp = SfxIniManager::Get()->Get( SFX_KEY_3D_OPENGL );
+
+ if(aTmp.Len() && aTmp.GetChar(0) != sal_Unicode('0'))
+ bUseOpenGL = TRUE;
+
+ if((bUseOpenGL && pRetval->GetBase3DType() != BASE3D_TYPE_OPENGL)
+ || (!bUseOpenGL && pRetval->GetBase3DType() == BASE3D_TYPE_OPENGL))
+ {
+ bForceNew = TRUE;
+ bOwnDevice = !bUseOpenGL;
+ }
+ }
+
+ if(bForceNew)
+ {
+ pRetval->Destroy(pOutDev);
+ pRetval = NULL;
+ }
+ }
+
+ if(!pRetval)
+ {
+ // zerstoere altes Base3D, war nicht mehr an das
+ // OutputDevice gebunden
+ if(pOutDev->Get3DContext())
+ pOutDev->Get3DContext()->Destroy(pOutDev);
+
+ // erzeuge neues Base3D, je nach Anforderungen
+ if(bForcePrinter)
+ {
+ pRetval = new Base3DPrinter(pOutDev);
+ }
+ else if(bOwnDevice)
+ {
+ pRetval = new Base3DDefault(pOutDev);
+ }
+ else
+ {
+ // Versuche OpenGL, fallback auf default
+ // falls OpenGL nicht verfuegbar
+ pRetval = CreateScreenRenderer(pOutDev);
+ }
+
+ // 3D-Kontext eintragen als Renderer im angegebenen OutputDevice
+ if(pRetval)
+ pOutDev->Set3DContext((Base3D*)pRetval);
+ }
+ }
+ return pRetval;
+}
+
+/*************************************************************************
+|*
+|* Versuche, einen 3D Kontext zur Bildschirmdarstellung zu generieren.
+|* Diese Funktion wird nur bei WNT realisiert. Sie muss entscheiden,
+|* ob OpenGL-DLL's verfuegbar sind und entsprechend den OpenGL
+|* Renderer oder einen Default Renderer erzeugen.
+|*
+\************************************************************************/
+
+Base3D* Base3D::CreateScreenRenderer(OutputDevice* pOutDev)
+{
+ // OpenGL Kontext erzeugen
+ Base3D* pRetval = NULL;
+
+ // Versuchen, einen OpenGL Kontext zu bekommen? Teste das
+ // globale Flag aus der .INI
+ BOOL bUseOpenGL = FALSE;
+ String aTmp = SfxIniManager::Get()->Get( SFX_KEY_3D_OPENGL );
+
+ if(aTmp.Len() && aTmp.GetChar(0) != sal_Unicode('0'))
+ bUseOpenGL = TRUE;
+
+ // Versuchen, einen OpenGL Kontext zu bekommen
+ if(bUseOpenGL)
+ pRetval = new Base3DOpenGL(pOutDev);
+
+ if(!pRetval || !pRetval->IsContextValid())
+ {
+ if(pRetval)
+ {
+ delete pRetval;
+ pRetval = NULL;
+ }
+ }
+
+ // versuche alternativ, einen Default Renderer zu inkarnieren
+ if(!pRetval)
+ pRetval = new Base3DDefault(pOutDev);
+
+ return pRetval;
+}
+
+/*************************************************************************
+|*
+|* Entferne den Kontext aus dem assoziierten OutputDevice und zerstoere
+|* sich selbst
+|*
+|* Als Platzhalter fuer den Zeiger auf einen Kontext im OutputDevice
+|* wird momentan pTheCurrentBase3DIncarnation benutzt
+|*
+\************************************************************************/
+
+void Base3D::Destroy(OutputDevice *pOutDev)
+{
+ Base3D* pTmp;
+ if((pTmp = (Base3D*)GetOutputDevice()->Get3DContext()) == this)
+ {
+ GetOutputDevice()->Set3DContext(NULL);
+ delete pTmp;
+ }
+}
+
+/*************************************************************************
+|*
+|* TransformationSet setzen
+|*
+\************************************************************************/
+
+void Base3D::SetTransformationSet(B3dTransformationSet* pSet)
+{
+ // Aktuelles TransformationSet eintragen
+ pTransformationSet = pSet;
+}
+
+/*************************************************************************
+|*
+|* Beleuchtung setzen
+|*
+\************************************************************************/
+
+void Base3D::SetLightGroup(B3dLightGroup* pSet, BOOL bSetGlobal)
+{
+ // Aktuelle Beleuchtung eintragen
+ pLightGroup = pSet;
+}
+
+/*************************************************************************
+|*
+|* Scissoring Region setzen
+|*
+\************************************************************************/
+
+void Base3D::SetScissorRegionPixel(const Rectangle& rRect, BOOL bActivate)
+{
+ aScissorRectangle = rRect;
+ ActivateScissorRegion(bActivate);
+}
+
+void Base3D::SetScissorRegion(const Rectangle& rRect, BOOL bActivate)
+{
+ SetScissorRegionPixel(pDevice->LogicToPixel(rRect), bActivate);
+}
+
+/*************************************************************************
+|*
+|* Scissoring aktivieren/deaktivieren
+|*
+\************************************************************************/
+
+void Base3D::ActivateScissorRegion(BOOL bNew)
+{
+ if(bNew != bScissorRegionActive)
+ bScissorRegionActive = bNew;
+}
+
+/*************************************************************************
+|*
+|* Dithering setzen
+|*
+\************************************************************************/
+
+void Base3D::SetDither(BOOL bNew)
+{
+ bDitherActive = bNew;
+}
+
+/*************************************************************************
+|*
+|* Objektmodus holen
+|*
+\************************************************************************/
+
+Base3DObjectMode Base3D::GetObjectMode()
+{
+ return eObjectMode;
+}
+
+/*************************************************************************
+|*
+|* Ein neues Primitiv vom Typ nMode starten
+|*
+\************************************************************************/
+
+void Base3D::StartPrimitive(Base3DObjectMode eMode)
+{
+ eObjectMode = eMode;
+ if(eObjectMode > Base3DPolygon)
+ {
+ switch(eObjectMode)
+ {
+ case Base3DComplexPolygonCut :
+ {
+ // Neues Polygon beginnen
+ aComplexPolygon.SetTestForCut(TRUE);
+ aComplexPolygon.StartPrimitive();
+ break;
+ }
+ case Base3DComplexPolygon :
+ {
+ // Neues Polygon beginnen
+ aComplexPolygon.SetTestForCut(FALSE);
+ aComplexPolygon.StartPrimitive();
+ break;
+ }
+ }
+ }
+ else
+ {
+ ImplStartPrimitive();
+ }
+}
+
+/*************************************************************************
+|*
+|* Primitiv beenden
+|*
+\************************************************************************/
+
+void Base3D::EndPrimitive()
+{
+ if(eObjectMode > Base3DPolygon)
+ {
+ switch(eObjectMode)
+ {
+ case Base3DComplexPolygon :
+ case Base3DComplexPolygonCut :
+ {
+ // Selbst fuer Darstellung sorgen
+ aComplexPolygon.EndPrimitive(this);
+ break;
+ }
+ }
+ }
+ else
+ {
+ ImplEndPrimitive();
+ }
+}
+
+/*************************************************************************
+|*
+|* Ein Objekt in Form einer B3dGeometry direkt ausgeben
+|*
+\************************************************************************/
+
+void Base3D::DrawPolygonGeometry(B3dGeometry& rGeometry, BOOL bOutline)
+{
+ // Buckets der Geometrie holen
+ B3dEntityBucket& rEntityBucket = rGeometry.GetEntityBucket();
+ GeometryIndexValueBucket& rIndexBucket = rGeometry.GetIndexBucket();
+
+ UINT32 nPolyCounter = 0;
+ UINT32 nEntityCounter = 0;
+ UINT32 nUpperBound;
+
+ while(nPolyCounter < rIndexBucket.Count())
+ {
+ // Naechstes Primitiv
+ nUpperBound = rIndexBucket[nPolyCounter].GetIndex();
+
+ if(bOutline)
+ {
+ // Polygon als Outline ausgeben
+ SetRenderMode(Base3DRenderLine);
+ SetPolygonOffset(Base3DPolygonOffsetLine, TRUE);
+
+ // ALLE Linien Zeichnen
+ SetCullMode(Base3DCullNone);
+ }
+ else
+ {
+ // Polygone gefuellt ausgeben
+ SetRenderMode(Base3DRenderFill);
+ SetPolygonOffset(Base3DPolygonOffsetLine, FALSE);
+ }
+
+ if(rIndexBucket[nPolyCounter++].GetMode() == B3D_INDEX_MODE_LINE)
+ {
+ eObjectMode = Base3DLineStrip;
+ }
+ else
+ {
+ eObjectMode = Base3DPolygon;
+ }
+
+ // Neues Polygon beginnen
+ ImplStartPrimitive();
+
+ // Polygon ausgeben
+ while(nEntityCounter < nUpperBound)
+ {
+ B3dEntity& rEntity = ImplGetFreeEntity();
+ rEntity = rEntityBucket[nEntityCounter++];
+ if(bOutline)
+ {
+ rEntity.SetNormalUsed(FALSE);
+ rEntity.SetTexCoorUsed(FALSE);
+ SetEdgeFlag(rEntity.IsEdgeVisible());
+ }
+ ImplPostAddVertex(rEntity);
+ }
+
+ // Primitiv abschliessen
+ ImplEndPrimitive();
+ }
+}
+
+/*************************************************************************
+|*
+|* Direkter Zugriff auf B3dMaterial fuer abgeleitete Klassen
+|*
+\************************************************************************/
+
+B3dMaterial& Base3D::GetMaterialObject(Base3DMaterialMode eMode)
+{
+ if(eMode == Base3DMaterialFront)
+ return aMaterialFront;
+ return aMaterialBack;
+}
+
+/*************************************************************************
+|*
+|* geometrische Daten uebernehmen
+|*
+\************************************************************************/
+
+void Base3D::AddVertex(Vector3D& rVertex)
+{
+ // Platz fuer neue Daten holen
+ B3dEntity& rEntity = GetFreeEntity();
+ rEntity.Reset();
+
+ // geometrische Daten
+ rEntity.Point() = Point4D(rVertex);
+ rEntity.SetValid();
+
+ // Nachbehandlung
+ PostAddVertex(rEntity);
+}
+
+void Base3D::AddVertex(Vector3D& rVertex, Vector3D& rNormal)
+{
+ // Platz fuer neue Daten holen
+ B3dEntity& rEntity = GetFreeEntity();
+ rEntity.Reset();
+
+ // geometrische Daten
+ rEntity.Point() = Point4D(rVertex);
+ rEntity.SetValid();
+
+ // Normale
+ if(GetLightGroup() && GetLightGroup()->IsLightingEnabled())
+ {
+ rEntity.Normal() = rNormal;
+ rEntity.SetNormalUsed();
+ }
+
+ // Nachbehandlung
+ PostAddVertex(rEntity);
+}
+
+void Base3D::AddVertex(Vector3D& rVertex, Vector3D& rNormal,
+ Vector3D& rTexPos)
+{
+ // Platz fuer neue Daten holen
+ B3dEntity& rEntity = GetFreeEntity();
+ rEntity.Reset();
+
+ // geometrische Daten
+ rEntity.Point() = Point4D(rVertex);
+ rEntity.SetValid();
+
+ // Normale
+ if(GetLightGroup() && GetLightGroup()->IsLightingEnabled())
+ {
+ rEntity.Normal() = rNormal;
+ rEntity.SetNormalUsed();
+ }
+
+ // Texturdaten
+ rEntity.TexCoor() = rTexPos;
+ rEntity.SetTexCoorUsed();
+
+ // Nachbehandlung
+ PostAddVertex(rEntity);
+}
+
+void Base3D::AddVertex(B3dEntity& rEnt)
+{
+ // Platz fuer neue Daten holen
+ B3dEntity& rEntity = GetFreeEntity();
+
+ // Kopieren
+ rEntity = rEnt;
+
+ // Nachbehandlung
+ PostAddVertex(rEntity);
+}
+
+void Base3D::PostAddVertex(B3dEntity& rEntity)
+{
+ // Flag fuer die Sichtbarkeit von Kanten kopieren
+ rEntity.SetEdgeVisible(GetEdgeFlag());
+
+ // aktuelle Farbe eintragen
+ rEntity.Color().SetColor(GetColor().GetColor());
+
+ if(eObjectMode > Base3DPolygon)
+ {
+ switch(eObjectMode)
+ {
+ case Base3DComplexPolygon :
+ case Base3DComplexPolygonCut :
+ {
+ // Punkt ist nun ausgefuellt
+ aComplexPolygon.PostAddVertex(rEntity);
+ break;
+ }
+ }
+ }
+ else
+ {
+ ImplPostAddVertex(rEntity);
+ }
+}
+
+/*************************************************************************
+|*
+|* Platz fuer neuen Punkt anfordern
+|*
+\************************************************************************/
+
+B3dEntity& Base3D::GetFreeEntity()
+{
+ if(eObjectMode > Base3DPolygon)
+ {
+ switch(eObjectMode)
+ {
+ case Base3DComplexPolygon :
+ case Base3DComplexPolygonCut :
+ {
+ // Im eigenen Buffer anlegen
+ return aComplexPolygon.GetFreeEntity();
+ break;
+ }
+ }
+ }
+ return ImplGetFreeEntity();
+}
+
+/*************************************************************************
+|*
+|* Farbe setzen
+|*
+\************************************************************************/
+
+void Base3D::SetColor(Color aNew)
+{
+ // Farbe setzen
+ if(GetOutputDevice()->GetDrawMode() & DRAWMODE_GRAYFILL)
+ {
+ // Graustufen
+ UINT8 nLuminance = aNew.GetLuminance();
+ aCurrentColor = Color(nLuminance, nLuminance, nLuminance);
+ }
+ else if(GetOutputDevice()->GetDrawMode() & DRAWMODE_WHITEFILL)
+ {
+ // Keine Ausgabe, hier Schwarz als Farbe setzen, wird
+ // als Linienfarbe benutzt
+ aCurrentColor = Color(COL_BLACK);
+ }
+ else
+ {
+ // Normale Farbausgabe
+ aCurrentColor = aNew;
+ }
+}
+
+/*************************************************************************
+|*
+|* Farbe liefern
+|*
+\************************************************************************/
+
+Color Base3D::GetColor()
+{
+ return aCurrentColor;
+}
+
+/*************************************************************************
+|*
+|* Materialeigenschaften setzen
+|*
+\************************************************************************/
+
+void Base3D::SetMaterial(Color aNew,
+ Base3DMaterialValue eVal,
+ Base3DMaterialMode eMode)
+{
+ Color aSource;
+ if(GetOutputDevice()->GetDrawMode() & DRAWMODE_GRAYFILL)
+ {
+ // Graustufen
+ UINT8 nLuminance = aNew.GetLuminance();
+ aSource.SetRed(nLuminance);
+ aSource.SetGreen(nLuminance);
+ aSource.SetBlue(nLuminance);
+ aSource.SetTransparency(aNew.GetTransparency());
+ }
+ else if(GetOutputDevice()->GetDrawMode() & DRAWMODE_WHITEFILL)
+ {
+ // Keine Ausgabe, hier Weiss als Farbe setzen
+ aSource = Color(COL_WHITE);
+ }
+ else
+ {
+ // Normale Farbausgabe
+ aSource = aNew;
+ }
+
+ if(eMode == Base3DMaterialFrontAndBack
+ || eMode == Base3DMaterialFront)
+ {
+ aMaterialFront.SetMaterial(aSource, eVal);
+ }
+ if(eMode == Base3DMaterialFrontAndBack
+ || eMode == Base3DMaterialBack)
+ {
+ aMaterialBack.SetMaterial(aSource, eVal);
+ }
+}
+
+/*************************************************************************
+|*
+|* Materialeigenschaften abfragen
+|*
+\************************************************************************/
+
+Color Base3D::GetMaterial(Base3DMaterialValue eVal,
+ Base3DMaterialMode eMode)
+{
+ if(eMode == Base3DMaterialFrontAndBack
+ || eMode == Base3DMaterialFront)
+ {
+ return aMaterialFront.GetMaterial(eVal);
+ }
+ return aMaterialBack.GetMaterial(eVal);
+}
+
+/*************************************************************************
+|*
+|* Materialeigenschaften setzen, exponent der specular-Eigenschaft
+|*
+\************************************************************************/
+
+void Base3D::SetShininess(UINT16 nExponent,
+ Base3DMaterialMode eMode)
+{
+ if(eMode == Base3DMaterialFrontAndBack
+ || eMode == Base3DMaterialFront)
+ {
+ aMaterialFront.SetShininess(nExponent);
+ }
+ if(eMode == Base3DMaterialFrontAndBack
+ || eMode == Base3DMaterialBack)
+ {
+ aMaterialBack.SetShininess(nExponent);
+ }
+}
+
+/*************************************************************************
+|*
+|* Materialeigenschaften abfragen, exponent der specular-Eigenschaft
+|*
+\************************************************************************/
+
+UINT16 Base3D::GetShininess(Base3DMaterialMode eMode)
+{
+ if(eMode == Base3DMaterialFrontAndBack
+ || eMode == Base3DMaterialFront)
+ {
+ return aMaterialFront.GetShininess();
+ }
+ return aMaterialBack.GetShininess();
+}
+
+/*************************************************************************
+|*
+|* Materialeigenschaften auf Ausgangszustand
+|*
+\************************************************************************/
+
+void Base3D::ResetMaterial(Base3DMaterialMode eMode)
+{
+ Color aColor(255, 51, 51, 51);
+ SetMaterial(aColor, Base3DMaterialAmbient, eMode);
+ aColor.SetColor(TRGB_COLORDATA(255, 204, 204, 204));
+ SetMaterial(aColor, Base3DMaterialDiffuse, eMode);
+ aColor.SetColor(TRGB_COLORDATA(255, 0, 0, 0));
+ SetMaterial(aColor, Base3DMaterialSpecular, eMode);
+ aColor.SetColor(TRGB_COLORDATA(255, 0, 0, 0));
+ SetMaterial(aColor, Base3DMaterialEmission, eMode);
+ SetShininess(0, eMode);
+}
+
+/*************************************************************************
+|*
+|* GlobalData holen
+|*
+\************************************************************************/
+
+B3dGlobalData& Base3D::GetGlobalData()
+{
+ B3dGlobalData** ppGlobalData = (B3dGlobalData**)GetAppData(SHL_BASE3D);
+ if(*ppGlobalData)
+ return **ppGlobalData;
+
+ // GlobalData anlegen
+ *ppGlobalData = new B3dGlobalData;
+ return **ppGlobalData;
+}
+
+/*************************************************************************
+|*
+|* TextureStore aus GlobalData holen
+|*
+\************************************************************************/
+
+B3dTextureStore& Base3D::GetTextureStore()
+{
+ return GetGlobalData().GetTextureStore();
+}
+
+/*************************************************************************
+|*
+|* Textur mit den angegebenen Attributen als Grundlage anfordern.
+|*
+\************************************************************************/
+
+B3dTexture* Base3D::ObtainTexture(TextureAttributes& rAtt)
+{
+ B3dTexture* pRetval = NULL;
+
+ // Textur suchen und bei Treffer zurueckgeben
+ B3dTextureStore& rTextureStore = GetTextureStore();
+ for(UINT16 a=0;a<rTextureStore.Count();a++)
+ {
+ if(rTextureStore[a]->GetAttributes() == rAtt)
+ {
+ pRetval = rTextureStore[a];
+ pRetval->Touch();
+ }
+ else
+ {
+ rTextureStore[a]->DecrementUsageCount();
+
+ // Auf zu loeschende Texturen testen
+ if(!rTextureStore[a]->GetUsageCount())
+ {
+ B3dTexture *pTex = rTextureStore[a];
+ rTextureStore.Remove(a);
+ DestroyTexture(pTex);
+ a--;
+ }
+ }
+ }
+
+ // Textur zurueckgeben
+ return pRetval;
+}
+
+/*************************************************************************
+|*
+|* Textur mit den angegebenen Attributen als Grundlage anfordern. Falls
+|* eine solche Textur nicht existiert, erzeuge eine und gib diese zurueck
+|*
+\************************************************************************/
+
+B3dTexture* Base3D::ObtainTexture(TextureAttributes& rAtt, Bitmap& rBitmap)
+{
+ B3dTexture* pRetval = ObtainTexture(rAtt);
+
+ if(!pRetval)
+ {
+ // Existiert tatsaechlich nicht, generiere eine neue Textur
+ B3dTextureStore& rTextureStore = GetTextureStore();
+
+ pRetval = CreateTexture(rAtt, rBitmap);
+ rTextureStore.Insert((const B3dTexture*&)pRetval, rTextureStore.Count());
+ }
+
+ // Textur zurueckgeben
+ return pRetval;
+}
+
+/*************************************************************************
+|*
+|* Gezielt eine Textur freigeben
+|*
+\************************************************************************/
+
+void Base3D::DeleteTexture(TextureAttributes& rAtt)
+{
+ B3dTexture* pTexture = NULL;
+
+ // Textur suchen
+ B3dTextureStore& rTextureStore = GetTextureStore();
+ UINT16 a;
+ for(a=0;a<rTextureStore.Count();a++)
+ {
+ if(rTextureStore[a]->GetAttributes() == rAtt)
+ {
+ pTexture = rTextureStore[a];
+ }
+ }
+
+ if(pTexture)
+ {
+ if(pTexture == pActiveTexture)
+ pActiveTexture = NULL;
+
+ rTextureStore.Remove(a);
+ DestroyTexture(pTexture);
+ }
+}
+
+/*************************************************************************
+|*
+|* Alle Texturen freigeben
+|*
+\************************************************************************/
+
+void Base3D::DeleteAllTextures()
+{
+ pActiveTexture = NULL;
+
+ B3dTextureStore& rTextureStore = GetTextureStore();
+ while(rTextureStore.Count())
+ {
+ B3dTexture *pTex = rTextureStore[0];
+ rTextureStore.Remove(0);
+ DestroyTexture(pTex);
+ }
+}
+
+/*************************************************************************
+|*
+|* Ein Textur-Objekt inkarnieren
+|*
+\************************************************************************/
+
+B3dTexture* Base3D::CreateTexture(TextureAttributes& rAtt, Bitmap& rBitmap)
+{
+ B3dTexture* pRetval = new B3dTexture(rAtt, rBitmap);
+ DBG_ASSERT(pRetval,"AW: Kein Speicher fuer Textur bekommen!");
+ return pRetval;
+}
+
+/*************************************************************************
+|*
+|* Normale Textur loeschen
+|*
+\************************************************************************/
+
+void Base3D::DestroyTexture(B3dTexture* pTex)
+{
+ delete pTex;
+}
+
+/*************************************************************************
+|*
+|* Aktuell zu benutzende Textur setzen
+|*
+\************************************************************************/
+
+void Base3D::SetActiveTexture(B3dTexture* pTex)
+{
+ if(pTex)
+ {
+ if(GetOutputDevice()->GetDrawMode() & DRAWMODE_GRAYFILL)
+ {
+ // Graustufen
+ pTex->SetTextureKind(Base3DTextureIntensity);
+ }
+ else if(GetOutputDevice()->GetDrawMode() & DRAWMODE_WHITEFILL)
+ {
+ // Keine Ausgabe, keine Textur setzen
+ pTex = NULL;
+ }
+ }
+
+ // ... und setzen
+ pActiveTexture = pTex;
+}
+
+/*************************************************************************
+|*
+|* Darstellungsqualitaet setzen
+|*
+\************************************************************************/
+
+void Base3D::SetDisplayQuality(UINT8 nNew)
+{
+ nDisplayQuality = nNew;
+}
+
+/*************************************************************************
+|*
+|* Darstellungsqualitaet lesen
+|*
+\************************************************************************/
+
+UINT8 Base3D::GetDisplayQuality()
+{
+ return nDisplayQuality;
+}
+
+/*************************************************************************
+|*
+|* PolygonOffset setzen
+|*
+\************************************************************************/
+
+void Base3D::SetPolygonOffset(Base3DPolygonOffset eNew, BOOL bNew)
+{
+ switch(eNew)
+ {
+ case Base3DPolygonOffsetFill :
+ bPolyOffsetFill = bNew;
+ break;
+
+ case Base3DPolygonOffsetLine :
+ bPolyOffsetLine = bNew;
+ break;
+
+ case Base3DPolygonOffsetPoint :
+ bPolyOffsetPoint = bNew;
+ break;
+ }
+}
+
+/*************************************************************************
+|*
+|* PolygonOffset lesen
+|*
+\************************************************************************/
+
+BOOL Base3D::GetPolygonOffset(Base3DPolygonOffset eNew)
+{
+ if(eNew == Base3DPolygonOffsetLine)
+ return bPolyOffsetLine;
+ if(eNew == Base3DPolygonOffsetFill)
+ return bPolyOffsetFill;
+ return bPolyOffsetPoint;
+}
+
+/*************************************************************************
+|*
+|* EdgeFlag lesen
+|*
+\************************************************************************/
+
+BOOL Base3D::GetEdgeFlag()
+{
+ return bEdgeFlag;
+}
+
+/*************************************************************************
+|*
+|* EdgeFlag schreiben
+|*
+\************************************************************************/
+
+void Base3D::SetEdgeFlag(BOOL bNew)
+{
+ bEdgeFlag = bNew;
+}
+
+/*************************************************************************
+|*
+|* PointSize lesen
+|*
+\************************************************************************/
+
+double Base3D::GetPointSize()
+{
+ return fPointSize;
+}
+
+/*************************************************************************
+|*
+|* PointSize schreiben
+|*
+\************************************************************************/
+
+void Base3D::SetPointSize(double fNew)
+{
+ fPointSize = fNew;
+}
+
+/*************************************************************************
+|*
+|* LineWidth lesen
+|*
+\************************************************************************/
+
+double Base3D::GetLineWidth()
+{
+ return fLineWidth;
+}
+
+/*************************************************************************
+|*
+|* LineWidth schreiben
+|*
+\************************************************************************/
+
+void Base3D::SetLineWidth(double fNew)
+{
+ fLineWidth = fNew;
+}
+
+/*************************************************************************
+|*
+|* RenderMode setzen
+|*
+\************************************************************************/
+
+void Base3D::SetRenderMode(Base3DRenderMode eNew,
+ Base3DMaterialMode eMode)
+{
+ if(eMode == Base3DMaterialFrontAndBack
+ || eMode == Base3DMaterialFront)
+ {
+ eRenderModeFront = eNew;
+ }
+ if(eMode == Base3DMaterialFrontAndBack
+ || eMode == Base3DMaterialBack)
+ {
+ eRenderModeBack = eNew;
+ }
+}
+
+/*************************************************************************
+|*
+|* RenderMode lieferen
+|*
+\************************************************************************/
+
+Base3DRenderMode Base3D::GetRenderMode(Base3DMaterialMode eMode)
+{
+ if(eMode == Base3DMaterialFrontAndBack
+ || eMode == Base3DMaterialFront)
+ {
+ return eRenderModeFront;
+ }
+ return eRenderModeBack;
+}
+
+/*************************************************************************
+|*
+|* ShadeModel setzen
+|*
+\************************************************************************/
+
+void Base3D::SetShadeModel(Base3DShadeModel eNew)
+{
+ eShadeModel = eNew;
+}
+
+/*************************************************************************
+|*
+|* ShadeModel lieferen
+|*
+\************************************************************************/
+
+Base3DShadeModel Base3D::GetShadeModel()
+{
+ return eShadeModel;
+}
+
+/*************************************************************************
+|*
+|* CullingMode setzen
+|*
+\************************************************************************/
+
+void Base3D::SetCullMode(Base3DCullMode eNew)
+{
+ eCullMode = eNew;
+}
+
+/*************************************************************************
+|*
+|* CullingMode liefern
+|*
+\************************************************************************/
+
+Base3DCullMode Base3D::GetCullMode()
+{
+ return eCullMode;
+}
+
+/*************************************************************************
+|*
+|* Texturenverwaltung
+|*
+\************************************************************************/
+
+SV_IMPL_PTRARR(B3dTextureStore, B3dTexture*);
+
+
+#ifdef DBG_UTIL
+#include "b3dtest.cxx"
+#endif
+