summaryrefslogtreecommitdiff
path: root/goodies/source/base3d/b3dopngl.cxx
diff options
context:
space:
mode:
authorJens-Heiner Rechtien <hr@openoffice.org>2000-09-18 15:33:13 +0000
committerJens-Heiner Rechtien <hr@openoffice.org>2000-09-18 15:33:13 +0000
commit0d14f932b02c43dd83fa3dfbe25d92755a4d7e26 (patch)
tree279498ab88acde1b8fb91f6fb1284d9cfd8fc200 /goodies/source/base3d/b3dopngl.cxx
parent662c532f6f415060501f33261203100ff044fe8b (diff)
initial import
Diffstat (limited to 'goodies/source/base3d/b3dopngl.cxx')
-rw-r--r--goodies/source/base3d/b3dopngl.cxx1502
1 files changed, 1502 insertions, 0 deletions
diff --git a/goodies/source/base3d/b3dopngl.cxx b/goodies/source/base3d/b3dopngl.cxx
new file mode 100644
index 000000000000..e5feb7f41a60
--- /dev/null
+++ b/goodies/source/base3d/b3dopngl.cxx
@@ -0,0 +1,1502 @@
+/*************************************************************************
+ *
+ * $RCSfile: b3dopngl.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 _SV_OUTDEV_HXX
+#include <vcl/outdev.hxx>
+#endif
+
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _B3D_B3DOPNGL_HXX
+#include "b3dopngl.hxx"
+#endif
+
+#ifndef _B3D_HMATRIX_HXX
+#include "hmatrix.hxx"
+#endif
+
+#ifndef _B3D_B3DTEX_HXX
+#include "b3dtex.hxx"
+#endif
+
+#ifndef _B3D_B3DTRANS_HXX
+#include "b3dtrans.hxx"
+#endif
+
+#ifndef _B3D_B3DGEOM_HXX
+#include "b3dgeom.hxx"
+#endif
+
+#ifndef _SFXINIMGR_HXX
+#include <svtools/iniman.hxx>
+#endif
+
+/*************************************************************************
+|*
+|* Konstruktor Base3DOpenGL
+|*
+\************************************************************************/
+
+Base3DOpenGL::Base3DOpenGL(OutputDevice* pOutDev)
+: Base3D(pOutDev),
+ aOpenGL(pOutDev),
+ aEmptyVector(0.0, 0.0, 0.0),
+ aLastNormal(DBL_MAX, DBL_MAX, DBL_MAX),
+ aLastTexCoor(DBL_MAX, DBL_MAX, DBL_MAX),
+ fOffFacMul100((float)(-0.2 * 100.0)),
+ fOffUniMul100((float)(-1.0 * 100.0)),
+ aPhongBuffer(12), // 4K
+ nPhongDivideSize(20),
+ bForceToSinglePrimitiveOutput(TRUE) // (#70626#)
+{
+ // create OpenGL context for pOutDev; pOutDev is NOT a printer,
+ // so don't care about printers in this place
+ if(aOpenGL.IsValid())
+ {
+ // setup default parameters
+ aOpenGL.ClearDepth( 1.0 );
+ aOpenGL.DepthFunc( GL_LEQUAL );
+ aOpenGL.Enable( GL_DEPTH_TEST );
+ aOpenGL.Enable( GL_DITHER );
+ aOpenGL.Enable( GL_NORMALIZE );
+ aOpenGL.Disable( GL_CULL_FACE );
+ aOpenGL.Disable( GL_LIGHTING );
+ aOpenGL.Disable( GL_LINE_SMOOTH );
+ aOpenGL.Disable( GL_POINT_SMOOTH );
+ aOpenGL.Disable( GL_POLYGON_SMOOTH );
+ aOpenGL.Disable( GL_POLYGON_STIPPLE );
+ aOpenGL.Disable( GL_LINE_STIPPLE );
+ aOpenGL.Disable( GL_TEXTURE_1D );
+ aOpenGL.Disable( GL_TEXTURE_2D );
+ aOpenGL.Disable( GL_BLEND );
+ aOpenGL.DepthMask( GL_TRUE );
+ aOpenGL.ShadeModel( GL_SMOOTH );
+ aOpenGL.EdgeFlag( GL_TRUE );
+ aOpenGL.Disable( GL_SCISSOR_TEST );
+ }
+ SetContextIsValid(aOpenGL.IsValid());
+ CalcInternPhongDivideSize();
+
+ // read bForceToSinglePrimitiveOutput-flag from .ini
+ String aTmp = SfxIniManager::Get()->Get(SFX_KEY_3D_OPENGL_FASTER);
+ bForceToSinglePrimitiveOutput =
+ (aTmp.Len() && aTmp.GetChar(0) == sal_Unicode('0'));
+}
+
+/*************************************************************************
+|*
+|* Typbestimmung
+|*
+\************************************************************************/
+
+UINT16 Base3DOpenGL::GetBase3DType()
+{
+ return BASE3D_TYPE_OPENGL;
+}
+
+/*************************************************************************
+|*
+|* Start der Szenenbeschreibung: Evtl. neuer HDC, Loesche Tiefenbuffer
+|*
+\************************************************************************/
+
+void Base3DOpenGL::StartScene()
+{
+ // Falls Transparenz an war, diese zuruecknehmen
+ aOpenGL.Disable( GL_BLEND );
+ aOpenGL.DepthMask( TRUE );
+
+ // OutputDevice setzen und ZBuffer loeschen
+ aOpenGL.SetConnectOutputDevice(GetOutputDevice());
+ aOpenGL.Clear( GL_DEPTH_BUFFER_BIT );
+}
+
+/*************************************************************************
+|*
+|* Scissoring Region setzen
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetScissorRegionPixel(const Rectangle& rRect, BOOL bActivate)
+{
+ // OpenGL specifics
+ aOpenGL.Scissor( rRect.Left(), rRect.Top(),
+ rRect.GetWidth(), rRect.GetHeight());
+
+ // call parent
+ Base3D::SetScissorRegionPixel(rRect, bActivate);
+}
+
+/*************************************************************************
+|*
+|* Dithering
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetDither(BOOL bNew)
+{
+ // call parent
+ Base3D::SetDither(bNew);
+
+ // OpenGL specifics
+ if(GetDither())
+ aOpenGL.Enable( GL_DITHER );
+ else
+ aOpenGL.Disable( GL_DITHER );
+}
+
+/*************************************************************************
+|*
+|* Scissoring aktivieren/deaktivieren
+|*
+\************************************************************************/
+
+void Base3DOpenGL::ActivateScissorRegion(BOOL bNew)
+{
+ // OpenGL specifics
+ if(bNew)
+ {
+ aOpenGL.Enable(GL_SCISSOR_TEST);
+ }
+ else
+ {
+ aOpenGL.Disable(GL_SCISSOR_TEST);
+ }
+
+ // call parent
+ Base3D::ActivateScissorRegion(bNew);
+}
+
+/*************************************************************************
+|*
+|* Ende der Szenenbeschreibung: Erzwinge bisher nicht erzeugte Ausgaben
+|*
+\************************************************************************/
+
+void Base3DOpenGL::EndScene()
+{
+ aOpenGL.Flush();
+ aOpenGL.Finish();
+}
+
+/*************************************************************************
+|*
+|* Neuen freien Eintrag fuer naechste geometrische Daten liefern
+|*
+\************************************************************************/
+
+B3dEntity& Base3DOpenGL::ImplGetFreeEntity()
+{
+ return aEntity;
+}
+
+/*************************************************************************
+|*
+|* starte primitiv auch in OpenGL
+|*
+\************************************************************************/
+
+void Base3DOpenGL::ImplStartPrimitive()
+{
+ bPhongBufferedMode = (GetShadeModel() == Base3DPhong
+ && GetRenderMode() == Base3DRenderFill
+ && (GetObjectMode() == Base3DTriangles
+ || GetObjectMode() == Base3DTriangleStrip
+ || GetObjectMode() == Base3DTriangleFan
+ || GetObjectMode() == Base3DQuads
+ || GetObjectMode() == Base3DQuadStrip
+ || GetObjectMode() == Base3DPolygon ));
+
+ // Transparenz beachten
+ if(GetMaterial(Base3DMaterialDiffuse).GetTransparency())
+ {
+ aOpenGL.Enable( GL_BLEND );
+ aOpenGL.DepthMask( FALSE );
+ aOpenGL.BlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+ }
+ else
+ {
+ aOpenGL.Disable( GL_BLEND );
+ aOpenGL.DepthMask( TRUE );
+ }
+
+ if(bPhongBufferedMode)
+ {
+ // Phong-Modus: Ausgabe sammeln und in kleinere
+ // Dreiecke zerlegt bei ImplEndPrimitive() rendern
+ aPhongBuffer.Erase();
+ }
+ else
+ {
+ // OpenGL direkt benutzen
+ aOpenGL.Begin(GetObjectMode());
+ }
+}
+
+/*************************************************************************
+|*
+|* beende primitiv auch in OpenGL
+|*
+\************************************************************************/
+
+void Base3DOpenGL::ImplEndPrimitive()
+{
+ if(bPhongBufferedMode)
+ {
+ DrawPhongPrimitives();
+ }
+ else
+ {
+ aOpenGL.End();
+ }
+}
+
+/*************************************************************************
+|*
+|* Darstellungsqualitaet setzen
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetDisplayQuality(UINT8 nNew)
+{
+ // call parent
+ Base3D::SetDisplayQuality(nNew);
+
+ // endgueltige Splittinggroesse neuberechnen
+ CalcInternPhongDivideSize();
+}
+
+/*************************************************************************
+|*
+|* PhongMode Splitting-Groesse neu setzen
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetPhongDivideSize(long nNew)
+{
+ nPhongDivideSize = nNew;
+
+ // endgueltige Splittinggroesse neuberechnen
+ CalcInternPhongDivideSize();
+}
+
+/*************************************************************************
+|*
+|* PhongMode interne Splitting-Groesse neu setzen
+|*
+\************************************************************************/
+
+void Base3DOpenGL::CalcInternPhongDivideSize()
+{
+ if(GetDisplayQuality() != 255)
+ {
+ long nNew = GetPhongDivideSize() +
+ ((255L - (INT32)GetDisplayQuality())>>2);
+ nInternPhongDivideSize = nNew * nNew;
+ }
+ else
+ nInternPhongDivideSize = GetPhongDivideSize() * GetPhongDivideSize();
+}
+
+/*************************************************************************
+|*
+|* Zeichne fuer Phong gebufferte primitive als Dreiecke
+|*
+\************************************************************************/
+
+void Base3DOpenGL::DrawPhongPrimitives()
+{
+ UINT32 aCount = aPhongBuffer.Count();
+ UINT32 aPos(0L);
+ bPhongBufferedMode = FALSE;
+ aOpenGL.Begin(Base3DTriangles);
+
+ switch(GetObjectMode())
+ {
+ case Base3DTriangles :
+ {
+ while(aPos < aCount)
+ {
+ DrawPhongTriangle(aPos, aPos+1, aPos+2);
+ aPos += 3;
+ }
+ break;
+ }
+ case Base3DTriangleStrip:
+ {
+ aPos = 1;
+ while(aPos < aCount)
+ {
+ if(aPos%2)
+ DrawPhongTriangle(aPos-1, aPos, aPos+1);
+ else
+ DrawPhongTriangle(aPos-1, aPos+1, aPos);
+ aPos++;
+ }
+ break;
+ }
+ case Base3DTriangleFan:
+ {
+ aPos = 1;
+ while(aPos < aCount)
+ {
+ DrawPhongTriangle(0, aPos, aPos+1);
+ aPos++;
+ }
+ break;
+ }
+ case Base3DQuads:
+ {
+ while(aPos < aCount)
+ {
+ DrawPhongTriangle(aPos, aPos+1, aPos+2);
+ DrawPhongTriangle(aPos+2, aPos+3, aPos);
+ aPos += 4;
+ }
+ break;
+ }
+ case Base3DQuadStrip:
+ {
+ aPos = 1;
+ while(aPos < aCount)
+ {
+ DrawPhongTriangle(aPos, aPos+1, aPos+3);
+ DrawPhongTriangle(aPos, aPos+3, aPos+2);
+ aPos+=2;
+ }
+ break;
+ }
+ case Base3DPolygon:
+ {
+ aPos = 2;
+ while(aPos < aCount)
+ {
+ DrawPhongTriangle(0, aPos-1, aPos);
+ aPos++;
+ }
+ break;
+ }
+ }
+ aOpenGL.End();
+}
+
+/*************************************************************************
+|*
+|* Zeichne fuer Phong gebufferte Dreiecke
+|*
+\************************************************************************/
+
+void Base3DOpenGL::DrawPhongTriangle(UINT32 nInd1, UINT32 nInd2, UINT32 nInd3)
+{
+ Vector3D aPos1 = GetTransformationSet()->ObjectToViewCoor(aPhongBuffer[nInd1].Point().GetVector3D());
+ double fXMin = aPos1.X();
+ double fXMax = aPos1.X();
+ double fYMin = aPos1.Y();
+ double fYMax = aPos1.Y();
+ Vector3D aPos2 = GetTransformationSet()->ObjectToViewCoor(aPhongBuffer[nInd2].Point().GetVector3D());
+ if(aPos2.X() < fXMin)
+ fXMin = aPos2.X();
+ if(aPos2.X() > fXMax)
+ fXMax = aPos2.X();
+ if(aPos2.Y() < fYMin)
+ fYMin = aPos2.Y();
+ if(aPos2.Y() > fYMax)
+ fYMax = aPos2.Y();
+ aPos2 = GetTransformationSet()->ObjectToViewCoor(aPhongBuffer[nInd3].Point().GetVector3D());
+ if(aPos2.X() < fXMin)
+ fXMin = aPos2.X();
+ if(aPos2.X() > fXMax)
+ fXMax = aPos2.X();
+ if(aPos2.Y() < fYMin)
+ fYMin = aPos2.Y();
+ if(aPos2.Y() > fYMax)
+ fYMax = aPos2.Y();
+
+ Size aPixelSize = GetOutputDevice()->LogicToPixel(
+ Size((long)(fXMax - fXMin),(long)(fYMax - fYMin)));
+ if(aPixelSize.Width() * aPixelSize.Height() > nInternPhongDivideSize)
+ {
+ UINT32 aCount = aPhongBuffer.Count();
+ aPhongBuffer.Append();
+ aPhongBuffer.Append();
+ aPhongBuffer.Append();
+
+ aPhongBuffer[aCount ].CalcMiddle(aPhongBuffer[nInd1], aPhongBuffer[nInd2]);
+ aPhongBuffer[aCount+1].CalcMiddle(aPhongBuffer[nInd2], aPhongBuffer[nInd3]);
+ aPhongBuffer[aCount+2].CalcMiddle(aPhongBuffer[nInd3], aPhongBuffer[nInd1]);
+
+ DrawPhongTriangle(nInd1, aCount, aCount+2);
+ DrawPhongTriangle(aCount, nInd2, aCount+1);
+ DrawPhongTriangle(aCount+1, nInd3, aCount+2);
+ DrawPhongTriangle(aCount, aCount+1, aCount+2);
+
+ aPhongBuffer.Remove();
+ aPhongBuffer.Remove();
+ aPhongBuffer.Remove();
+ }
+ else
+ {
+ ImplPostAddVertex(aPhongBuffer[nInd1]);
+ ImplPostAddVertex(aPhongBuffer[nInd2]);
+ ImplPostAddVertex(aPhongBuffer[nInd3]);
+ }
+}
+
+/*************************************************************************
+|*
+|* Geometrische Daten direkt an OpenGL weitergeben
+|* ACHTUNG! Es wird die aktuelle Farbe benutzt, NICHT die in Enttity3D
+|* enthaltene!
+|*
+\************************************************************************/
+
+void Base3DOpenGL::ImplPostAddVertex(B3dEntity& rEntity)
+{
+ if(bPhongBufferedMode)
+ {
+ aPhongBuffer.Append(rEntity);
+ }
+ else
+ {
+ // Normale setzen
+ if(rEntity.IsNormalUsed())
+ {
+ if(GetForceFlat() || GetShadeModel() == Base3DFlat)
+ {
+ if(rEntity.PlaneNormal() != aLastNormal)
+ {
+ aLastNormal = rEntity.PlaneNormal();
+ aOpenGL.Normal3dv(&aLastNormal.X());
+ }
+ }
+ else
+ {
+ if(rEntity.Normal() != aLastNormal)
+ {
+ aLastNormal = rEntity.Normal();
+ aOpenGL.Normal3dv(&aLastNormal.X());
+ }
+ }
+ }
+ else
+ {
+ if(aLastNormal != aEmptyVector)
+ {
+ aLastNormal = aEmptyVector;
+ aOpenGL.Normal3dv(&aLastNormal.X());
+ }
+ }
+
+ // Texturkoordinate setzen
+ if(rEntity.IsTexCoorUsed())
+ {
+ if(rEntity.TexCoor() != aLastTexCoor)
+ {
+ aLastTexCoor = rEntity.TexCoor();
+ aOpenGL.TexCoord3dv(&aLastTexCoor.X());
+ }
+ }
+ else
+ {
+ if(aLastTexCoor != aEmptyVector)
+ {
+ aLastTexCoor = aEmptyVector;
+ aOpenGL.TexCoord3dv(&aLastTexCoor.X());
+ }
+ }
+
+ // Punkt erzeugen
+ aOpenGL.Vertex3dv(&rEntity.Point().X());
+ }
+}
+
+/*************************************************************************
+|*
+|* beim setzen von color und alpha reagieren
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetColor(Color aNew)
+{
+ // call parent
+ Base3D::SetColor(aNew);
+
+ // Normale Farbausgabe
+ aOpenGL.Color4ub(GetColor().GetRed(), GetColor().GetGreen(),
+ GetColor().GetBlue(), 0xff - GetColor().GetTransparency());
+}
+
+/*************************************************************************
+|*
+|* Materialeigenschaften setzen
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetMaterial(Color rNew, Base3DMaterialValue eVal,
+ Base3DMaterialMode eMode)
+{
+ // call parent
+ Base3D::SetMaterial(rNew, eVal, eMode);
+
+ // OpenGL Specifics
+ GLenum eFace = GL_FRONT_AND_BACK;
+ if(eMode == Base3DMaterialFront)
+ eFace = GL_FRONT;
+ if(eMode == Base3DMaterialBack)
+ eFace = GL_BACK;
+ GLenum eName = GL_SPECULAR;
+ if(eVal == Base3DMaterialAmbient)
+ eName = GL_AMBIENT;
+ if(eVal == Base3DMaterialDiffuse)
+ eName = GL_DIFFUSE;
+ if(eVal == Base3DMaterialEmission)
+ eName = GL_EMISSION;
+
+ // Array fuellen
+ float fArray[4] = {
+ ((float)GetMaterial(eVal, eMode).GetRed()) / (float)255.0,
+ ((float)GetMaterial(eVal, eMode).GetGreen()) / (float)255.0,
+ ((float)GetMaterial(eVal, eMode).GetBlue()) / (float)255.0,
+ ((float)(255 - GetMaterial(eVal, eMode).GetTransparency())) / (float)255.0
+ };
+
+ aOpenGL.Materialfv(eFace, eName, fArray);
+}
+
+/*************************************************************************
+|*
+|* Materialeigenschaften setzen, exponent der specular-Eigenschaft
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetShininess(UINT16 nExponent,
+ Base3DMaterialMode eMode)
+{
+ // call parent
+ Base3D::SetShininess(nExponent, eMode);
+
+ // OpenGL Specifics
+ GLenum eFace = GL_FRONT_AND_BACK;
+ if(eMode == Base3DMaterialFront)
+ eFace = GL_FRONT;
+ if(eMode == Base3DMaterialBack)
+ eFace = GL_BACK;
+ aOpenGL.Materialf(eFace, GL_SHININESS, (float)nExponent);
+}
+
+/*************************************************************************
+|*
+|* Aktuell zu benutzende Textur setzen
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetActiveTexture(B3dTexture* pTex)
+{
+ // call parent
+ Base3D::SetActiveTexture(pTex);
+
+ // make current texture, cast ist unkritisch, da innerhalb von
+ // Base3DOpenGL nur Texturen von diesem Typ angelegt worden
+ // sein koennen
+ if(GetActiveTexture())
+ {
+ aOpenGL.Enable(GL_TEXTURE_2D);
+ ((B3dTextureOpenGL*)GetActiveTexture())->MakeCurrentTexture(aOpenGL);
+ }
+ else
+ {
+ aOpenGL.BindTexture(GL_TEXTURE_2D, 0);
+ aOpenGL.Disable(GL_TEXTURE_2D);
+ }
+}
+
+/*************************************************************************
+|*
+|* Ein Textur-Objekt inkarnieren
+|*
+\************************************************************************/
+
+B3dTexture* Base3DOpenGL::CreateTexture(TextureAttributes& rAtt, Bitmap& rBitmap)
+{
+ // Hier Parent NICHT rufen! Sonst wird auch noch eine normale Textur erzeugt
+ B3dTextureOpenGL* pRetval = new B3dTextureOpenGL(rAtt, rBitmap, aOpenGL);
+ DBG_ASSERT(pRetval,"AW: Kein Speicher fuer OpenGL-Textur bekommen!");
+ return pRetval;
+}
+
+/*************************************************************************
+|*
+|* OpenGL - Textur loeschen
+|*
+\************************************************************************/
+
+void Base3DOpenGL::DestroyTexture(B3dTexture* pTex)
+{
+ // Spezielle Loeschaufgaben im Zusammenhang mit OpenGL
+ ((B3dTextureOpenGL*)pTex)->DestroyOpenGLTexture(aOpenGL);
+
+ // call parent, endgueltig loeschen
+ Base3D::DestroyTexture(pTex);
+}
+
+/*************************************************************************
+|*
+|* PolygonOffset setzen
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetPolygonOffset(Base3DPolygonOffset eNew, BOOL bNew)
+{
+ // call parent
+ Base3D::SetPolygonOffset(eNew, bNew);
+
+ if(GetPolygonOffset())
+ aOpenGL.PolygonOffset((float)(fOffFacMul100 / 100.0), (float)(fOffUniMul100 / 100.0));
+ else
+ aOpenGL.PolygonOffset((float)0.0, (float)0.0);
+
+ // OpenGL Specifics
+ switch(eNew)
+ {
+ case Base3DPolygonOffsetFill :
+ if(bNew)
+ aOpenGL.Enable( GL_POLYGON_OFFSET_FILL );
+ else
+ aOpenGL.Disable( GL_POLYGON_OFFSET_FILL );
+ break;
+
+ case Base3DPolygonOffsetLine :
+ if(bNew)
+ aOpenGL.Enable( GL_POLYGON_OFFSET_LINE );
+ else
+ aOpenGL.Disable( GL_POLYGON_OFFSET_LINE );
+ break;
+
+ case Base3DPolygonOffsetPoint :
+ if(bNew)
+ aOpenGL.Enable( GL_POLYGON_OFFSET_POINT );
+ else
+ aOpenGL.Disable( GL_POLYGON_OFFSET_POINT );
+ break;
+ }
+}
+
+/*************************************************************************
+|*
+|* Beleuchtung setzen/lesen
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetLightGroup(B3dLightGroup* pSet, BOOL bSetGlobal)
+{
+ // call parent
+ Base3D::SetLightGroup(pSet, bSetGlobal);
+
+ if(GetLightGroup())
+ {
+ // Allgemeine Parameter setzen
+ SetGlobalAmbientLight(GetLightGroup()->GetGlobalAmbientLight());
+ SetLocalViewer(GetLightGroup()->GetLocalViewer());
+ SetModelTwoSide(GetLightGroup()->GetModelTwoSide());
+ EnableLighting(GetLightGroup()->IsLightingEnabled());
+
+ // Einzelne Lampen setzen
+ if(GetTransformationSet() && bSetGlobal)
+ {
+ aOpenGL.MatrixMode(GL_MODELVIEW);
+ aOpenGL.LoadIdentity();
+ }
+
+ // Set and enable lights from the beginning of array in
+ // OpenGL
+ UINT16 nNumAlloc = 0;
+
+ UINT16 a;
+ for(a=0;a<BASE3D_MAX_NUMBER_LIGHTS;a++)
+ {
+ Base3DLightNumber eNum = (Base3DLightNumber)(Base3DLight0 + a);
+ B3dLight& rLight = GetLightGroup()->GetLightObject(eNum);
+
+ if(rLight.IsEnabled())
+ {
+ Base3DLightNumber eNumAlloc = (Base3DLightNumber)(Base3DLight0 + nNumAlloc);
+ nNumAlloc++;
+
+ Enable(TRUE, eNumAlloc);
+
+ SetIntensity(rLight.GetIntensity(Base3DMaterialAmbient),
+ Base3DMaterialAmbient, eNumAlloc);
+ SetIntensity(rLight.GetIntensity(Base3DMaterialDiffuse),
+ Base3DMaterialDiffuse, eNumAlloc);
+ SetIntensity(rLight.GetIntensity(Base3DMaterialSpecular),
+ Base3DMaterialSpecular, eNumAlloc);
+
+ if(rLight.IsDirectionalSource())
+ {
+ SetDirection(rLight.GetPosition(), eNumAlloc);
+ }
+ else
+ {
+ SetPosition(rLight.GetPosition(), eNumAlloc);
+ SetSpotDirection(rLight.GetSpotDirection(), eNumAlloc);
+ SetSpotExponent(rLight.GetSpotExponent(), eNumAlloc);
+ SetSpotCutoff(rLight.GetSpotCutoff(), eNumAlloc);
+ }
+
+ SetConstantAttenuation(rLight.GetConstantAttenuation(), eNumAlloc);
+ SetLinearAttenuation(rLight.GetLinearAttenuation(), eNumAlloc);
+ SetQuadraticAttenuation(rLight.GetQuadraticAttenuation(), eNumAlloc);
+ }
+ }
+
+ for(a=nNumAlloc;a<BASE3D_MAX_NUMBER_LIGHTS;a++)
+ {
+ Base3DLightNumber eNum = (Base3DLightNumber)(Base3DLight0 + a);
+ Enable(FALSE, eNum);
+ }
+
+ if(GetTransformationSet() && bSetGlobal)
+ PostSetObjectOrientation(GetTransformationSet());
+ }
+}
+
+/*************************************************************************
+|*
+|* globales Umgebungslicht setzen
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetGlobalAmbientLight(const Color rNew)
+{
+ // OpenGL Specifics
+ Color aSource;
+ if(GetOutputDevice()->GetDrawMode() & DRAWMODE_GRAYFILL)
+ {
+ // Graustufen
+ UINT8 nLuminance = rNew.GetLuminance();
+ aSource.SetRed(nLuminance);
+ aSource.SetGreen(nLuminance);
+ aSource.SetBlue(nLuminance);
+ aSource.SetTransparency(rNew.GetTransparency());
+ }
+ else if(GetOutputDevice()->GetDrawMode() & DRAWMODE_WHITEFILL)
+ {
+ // Keine Ausgabe, hier Weiss als Farbe setzen
+ aSource = Color(COL_WHITE);
+ }
+ else
+ {
+ // Normale Farbausgabe
+ aSource = rNew;
+ }
+
+ // Array fuellen
+ float fArray[4] = {
+ ((float)aSource.GetRed()) / (float)255.0,
+ ((float)aSource.GetGreen()) / (float)255.0,
+ ((float)aSource.GetBlue()) / (float)255.0,
+ ((float)aSource.GetTransparency()) / (float)255.0
+ };
+ aOpenGL.LightModelfv(GL_LIGHT_MODEL_AMBIENT, fArray);
+}
+
+/*************************************************************************
+|*
+|* Modus globaler Viewer bei Berechnung specular reflection setzen
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetLocalViewer(BOOL bNew)
+{
+ // OpenGL Specifics
+ aOpenGL.LightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER,
+ bNew ? (float)0.0 : (float)1.0);
+}
+
+/*************************************************************************
+|*
+|* Modus Beleuchtungsmodell beidseitig anwenden setzen
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetModelTwoSide(BOOL bNew)
+{
+ // OpenGL Specifics
+ aOpenGL.LightModelf(GL_LIGHT_MODEL_TWO_SIDE,
+ bNew ? (float)1.0 : (float)0.0);
+}
+
+/*************************************************************************
+|*
+|* Beleuchtungsmodell aktivieren/deaktivieren
+|*
+\************************************************************************/
+
+void Base3DOpenGL::EnableLighting(BOOL bNew)
+{
+ // OpenGL Specifics
+ if(bNew)
+ aOpenGL.Enable( GL_LIGHTING );
+ else
+ aOpenGL.Disable( GL_LIGHTING );
+}
+
+/*************************************************************************
+|*
+|* Die Intensitaet eines bestimmten Aspekts einer Lichtquelle setzen
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetIntensity(const Color rNew,
+ Base3DMaterialValue eVal, Base3DLightNumber eNum)
+{
+ // OpenGL Specifics
+ Color aSource;
+ if(GetOutputDevice()->GetDrawMode() & DRAWMODE_GRAYFILL)
+ {
+ // Graustufen
+ UINT8 nLuminance = rNew.GetLuminance();
+ aSource.SetRed(nLuminance);
+ aSource.SetGreen(nLuminance);
+ aSource.SetBlue(nLuminance);
+ aSource.SetTransparency(rNew.GetTransparency());
+ }
+ else if(GetOutputDevice()->GetDrawMode() & DRAWMODE_WHITEFILL)
+ {
+ // Keine Ausgabe, hier Weiss als Farbe setzen
+ aSource = Color(COL_WHITE);
+ }
+ else
+ {
+ // Normale Farbausgabe
+ aSource = rNew;
+ }
+
+ // Array fuellen
+ float fArray[4] = {
+ ((float)aSource.GetRed()) / (float)255.0,
+ ((float)aSource.GetGreen()) / (float)255.0,
+ ((float)aSource.GetBlue()) / (float)255.0,
+ ((float)aSource.GetTransparency()) / (float)255.0
+ };
+
+ GLenum eLight = GL_LIGHT0 + (eNum - Base3DLight0);
+ GLenum eName = GL_SPECULAR;
+ if(eVal == Base3DMaterialAmbient)
+ eName = GL_AMBIENT;
+ if(eVal == Base3DMaterialDiffuse)
+ eName = GL_DIFFUSE;
+ aOpenGL.Lightfv(eLight, eName, fArray);
+}
+
+/*************************************************************************
+|*
+|* Die Position einer Lichtquelle setzen
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetPosition(const Vector3D& rNew, Base3DLightNumber eNum)
+{
+ // OpenGL Specifics
+ GLenum eLight = GL_LIGHT0 + (eNum - Base3DLight0);
+ float fArray[4] = {
+ (float)rNew[0], (float)rNew[1], (float)rNew[2], (float)1.0
+ };
+ aOpenGL.Lightfv(eLight, GL_POSITION, fArray);
+}
+
+/*************************************************************************
+|*
+|* Die Richtung einer Lichtquelle setzen
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetDirection(const Vector3D& rNew, Base3DLightNumber eNum)
+{
+ // OpenGL Specifics
+ GLenum eLight = GL_LIGHT0 + (eNum - Base3DLight0);
+ float fArray[4] = {
+ (float)rNew[0], (float)rNew[1], (float)rNew[2], (float)0.0
+ };
+ aOpenGL.Lightfv(eLight, GL_POSITION, fArray);
+}
+
+/*************************************************************************
+|*
+|* Die Richtung einer Lichtquelle setzen
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetSpotDirection(const Vector3D& rNew,
+ Base3DLightNumber eNum)
+{
+ // OpenGL Specifics
+ GLenum eLight = GL_LIGHT0 + (eNum - Base3DLight0);
+ float fArray[4] = {
+ (float)rNew[0], (float)rNew[1], (float)rNew[2], (float)0.0
+ };
+ aOpenGL.Lightfv(eLight, GL_SPOT_DIRECTION, fArray);
+}
+
+/*************************************************************************
+|*
+|* Den SpotExponent einer Lichtquelle setzen
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetSpotExponent(UINT16 nNew, Base3DLightNumber eNum)
+{
+ // OpenGL Specifics
+ GLenum eLight = GL_LIGHT0 + (eNum - Base3DLight0);
+ aOpenGL.Lightf(eLight, GL_SPOT_EXPONENT, (float)nNew);
+}
+
+/*************************************************************************
+|*
+|* Die Einengung des Lichtkegels einer Lichtquelle setzen
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetSpotCutoff(double fNew, Base3DLightNumber eNum)
+{
+ // OpenGL Specifics
+ GLenum eLight = GL_LIGHT0 + (eNum - Base3DLight0);
+ aOpenGL.Lightf(eLight, GL_SPOT_CUTOFF, (float)fNew);
+}
+
+/*************************************************************************
+|*
+|* Den konstanten AttenuationFactor einer Lichtquelle setzen
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetConstantAttenuation(double fNew,
+ Base3DLightNumber eNum)
+{
+ // OpenGL Specifics
+ GLenum eLight = GL_LIGHT0 + (eNum - Base3DLight0);
+ aOpenGL.Lightf(eLight, GL_CONSTANT_ATTENUATION, (float)fNew);
+}
+
+/*************************************************************************
+|*
+|* Den linearen AttenuationFactor einer Lichtquelle setzen
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetLinearAttenuation(double fNew,
+ Base3DLightNumber eNum)
+{
+ // OpenGL Specifics
+ GLenum eLight = GL_LIGHT0 + (eNum - Base3DLight0);
+ aOpenGL.Lightf(eLight, GL_LINEAR_ATTENUATION, (float)fNew);
+}
+
+/*************************************************************************
+|*
+|* Den quadratischen AttenuationFactor einer Lichtquelle setzen
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetQuadraticAttenuation(double fNew,
+ Base3DLightNumber eNum)
+{
+ // OpenGL Specifics
+ GLenum eLight = GL_LIGHT0 + (eNum - Base3DLight0);
+ aOpenGL.Lightf(eLight, GL_QUADRATIC_ATTENUATION, (float)fNew);
+}
+
+/*************************************************************************
+|*
+|* Eine Lichtquelle aktivieren/deaktivieren
+|*
+\************************************************************************/
+
+void Base3DOpenGL::Enable(BOOL bNew, Base3DLightNumber eNum)
+{
+ // OpenGL Specifics
+ GLenum eLight = GL_LIGHT0 + (eNum - Base3DLight0);
+ if(bNew)
+ aOpenGL.Enable(eLight);
+ else
+ aOpenGL.Disable(eLight);
+}
+
+/*************************************************************************
+|*
+|* RenderMode setzen
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetRenderMode(Base3DRenderMode eNew,
+ Base3DMaterialMode eMode)
+{
+ // call parent
+ Base3D::SetRenderMode(eNew, eMode);
+
+ // OpenGL Specifics
+ GLenum eFace = GL_FRONT_AND_BACK;
+ if(eMode == Base3DMaterialFront)
+ eFace = GL_FRONT;
+ if(eMode == Base3DMaterialBack)
+ eFace = GL_BACK;
+
+ switch(eNew)
+ {
+ case Base3DRenderNone :
+ {
+ break;
+ }
+ case Base3DRenderPoint :
+ {
+ aOpenGL.PolygonMode(eFace, GL_POINT);
+ break;
+ }
+ case Base3DRenderLine :
+ {
+ aOpenGL.PolygonMode(eFace, GL_LINE);
+ break;
+ }
+ case Base3DRenderFill :
+ {
+ aOpenGL.PolygonMode(eFace, GL_FILL);
+ break;
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* ShadeModel setzen
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetShadeModel(Base3DShadeModel eNew)
+{
+ // call parent
+ Base3D::SetShadeModel(eNew);
+
+ switch(eNew)
+ {
+ case Base3DSmooth :
+ case Base3DPhong :
+ {
+ aOpenGL.ShadeModel(GL_SMOOTH);
+ break;
+ }
+ case Base3DFlat :
+ {
+ aOpenGL.ShadeModel(GL_FLAT);
+ break;
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* CullingMode setzen
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetCullMode(Base3DCullMode eNew)
+{
+ // call parent
+ Base3D::SetCullMode(eNew);
+
+ switch(eNew)
+ {
+ case Base3DCullFront :
+ {
+ aOpenGL.CullFace(GL_FRONT);
+ aOpenGL.Enable(GL_CULL_FACE);
+ break;
+ }
+ case Base3DCullBack :
+ {
+ aOpenGL.CullFace(GL_BACK);
+ aOpenGL.Enable(GL_CULL_FACE);
+ break;
+ }
+ case Base3DCullNone :
+ {
+ aOpenGL.Disable(GL_CULL_FACE);
+ break;
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* EdgeFlag schreiben
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetEdgeFlag(BOOL bNew)
+{
+ // EdgeFlag fuer OpenGL setzen
+ if(bNew)
+ aOpenGL.EdgeFlag(GL_TRUE);
+ else
+ aOpenGL.EdgeFlag(GL_FALSE);
+
+ // call parent
+ Base3D::SetEdgeFlag(bNew);
+}
+
+/*************************************************************************
+|*
+|* PointSize schreiben
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetPointSize(double fNew)
+{
+ // PointSize fuer OpenGL setzen
+ aOpenGL.PointSize((GLfloat)fNew);
+
+ // call parent
+ Base3D::SetPointSize(fNew);
+}
+
+/*************************************************************************
+|*
+|* LineWidth schreiben
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetLineWidth(double fNew)
+{
+ // LineWidth fuer OpenGL setzen
+ aOpenGL.LineWidth((GLfloat)fNew);
+
+ // call parent
+ Base3D::SetLineWidth(fNew);
+}
+
+/*************************************************************************
+|*
+|* Callbacks bei Matrixaenderungen, Default-Implementierungen
+|*
+\************************************************************************/
+
+void Base3DOpenGL::SetTransformationSet(B3dTransformationSet* pSet)
+{
+ // call parent
+ Base3D::SetTransformationSet(pSet);
+
+ if(GetTransformationSet())
+ {
+ PostSetObjectOrientation(GetTransformationSet());
+ PostSetProjection(GetTransformationSet());
+ PostSetTexture(GetTransformationSet());
+ PostSetViewport(GetTransformationSet());
+ }
+}
+
+void Base3DOpenGL::PostSetObjectOrientation(B3dTransformationSet* pCaller)
+{
+ // OpenGL specifics
+ Matrix4D aMat = pCaller->GetObjectTrans();
+ aMat *= pCaller->GetOrientation();
+ double fBuffer[16] = {
+ aMat[0][0], aMat[1][0], aMat[2][0], aMat[3][0],
+ aMat[0][1], aMat[1][1], aMat[2][1], aMat[3][1],
+ aMat[0][2], aMat[1][2], aMat[2][2], aMat[3][2],
+ aMat[0][3], aMat[1][3], aMat[2][3], aMat[3][3]
+ };
+ aOpenGL.MatrixMode(GL_MODELVIEW);
+ aOpenGL.LoadMatrixd(fBuffer);
+}
+
+void Base3DOpenGL::PostSetProjection(B3dTransformationSet* pCaller)
+{
+ // OpenGL specifics
+ const Matrix4D& rMat = pCaller->GetProjection();
+ double fBuffer[16] = {
+ rMat[0][0], rMat[1][0], rMat[2][0], rMat[3][0],
+ rMat[0][1], rMat[1][1], rMat[2][1], rMat[3][1],
+ rMat[0][2], rMat[1][2], rMat[2][2], rMat[3][2],
+ rMat[0][3], rMat[1][3], rMat[2][3], rMat[3][3]
+ };
+ aOpenGL.MatrixMode(GL_PROJECTION);
+ aOpenGL.LoadMatrixd(fBuffer);
+}
+
+void Base3DOpenGL::PostSetTexture(B3dTransformationSet* pCaller)
+{
+ // OpenGL specifics
+ const Matrix4D& rMat = pCaller->GetTexture();
+ double fBuffer[16] = {
+ rMat[0][0], rMat[1][0], rMat[2][0], rMat[3][0],
+ rMat[0][1], rMat[1][1], rMat[2][1], rMat[3][1],
+ rMat[0][2], rMat[1][2], rMat[2][2], rMat[3][2],
+ rMat[0][3], rMat[1][3], rMat[2][3], rMat[3][3]
+ };
+ aOpenGL.MatrixMode(GL_TEXTURE);
+ aOpenGL.LoadMatrixd(fBuffer);
+}
+
+void Base3DOpenGL::PostSetViewport(B3dTransformationSet* pCaller)
+{
+ // OpenGL specifics
+ Rectangle aBoundPixel(GetOutputDevice()->
+ LogicToPixel(pCaller->GetLogicalViewportBounds()));
+ aOpenGL.Viewport( aBoundPixel.Left(), aBoundPixel.Top(),
+ aBoundPixel.GetWidth() - 1, aBoundPixel.GetHeight() - 1);
+}
+
+/*************************************************************************
+|*
+|* Ein Objekt in Form einer B3dGeometry direkt ausgeben
+|*
+\************************************************************************/
+
+void Base3DOpenGL::DrawPolygonGeometry(B3dGeometry& rGeometry, BOOL bOutline)
+{
+ // bForceToSinglePrimitiveOutput: (#70626#)
+ if(bForceToSinglePrimitiveOutput || (GetShadeModel() == Base3DPhong && GetRenderMode() == Base3DRenderFill))
+ {
+ // call parent, render with many primitives
+ Base3D::DrawPolygonGeometry(rGeometry, bOutline);
+ }
+ else
+ {
+ // Buckets der Geometrie holen
+ B3dEntityBucket& rEntityBucket = rGeometry.GetEntityBucket();
+ GeometryIndexValueBucket& rIndexBucket = rGeometry.GetIndexBucket();
+
+ if(rEntityBucket.Count() && rIndexBucket.Count())
+ {
+ // Arrays aktivieren
+ aOpenGL.EnableClientState(GL_VERTEX_ARRAY);
+
+ UINT32 nPolyCounter = 0;
+ UINT32 nEntityCounter = 0;
+ UINT32 nArrayStartIndex = 0;
+ UINT32 nUpperBound;
+
+ // Pointer setzen
+ UINT16 nArray = 0;
+ aOpenGL.VertexPointer(3, GL_DOUBLE, rEntityBucket.GetSlotSize(), &rEntityBucket[0].Point());
+
+ if(bOutline)
+ {
+ // Transparenz Linien beachten
+ if(GetColor().GetTransparency())
+ {
+ aOpenGL.Enable( GL_BLEND );
+ aOpenGL.DepthMask( FALSE );
+ aOpenGL.BlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+ }
+ else
+ {
+ aOpenGL.Disable( GL_BLEND );
+ aOpenGL.DepthMask( TRUE );
+ }
+
+ // ALLE Linien Zeichnen
+ aOpenGL.Disable(GL_CULL_FACE);
+
+ // Polygone als Outline ausgeben
+ aOpenGL.PolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ aOpenGL.PolygonOffset((float)(fOffFacMul100 / 100.0), (float)(fOffUniMul100 / 100.0));
+ aOpenGL.Enable( GL_POLYGON_OFFSET_LINE );
+ aOpenGL.EnableClientState(GL_EDGE_FLAG_ARRAY);
+ aOpenGL.EdgeFlagPointer(rEntityBucket.GetSlotSize(), &rEntityBucket[0].EdgeFlag());
+
+ while(nPolyCounter < rIndexBucket.Count())
+ {
+ // Naechstes Primitiv
+ nUpperBound = rIndexBucket[nPolyCounter].GetIndex();
+ BOOL bLineMode = (rIndexBucket[nPolyCounter++].GetMode() == B3D_INDEX_MODE_LINE);
+
+ if(nUpperBound >> rEntityBucket.GetBlockShift() != nArray)
+ {
+ // Einzelschritt, Bereichsueberschreitung im Buffer
+ // Als Polygon ausgeben
+ aOpenGL.Begin(bLineMode ? Base3DLineStrip : Base3DPolygon);
+
+ // Polygon ausgeben
+ while(nEntityCounter < nUpperBound)
+ {
+ B3dEntity& rEntity = rEntityBucket[nEntityCounter++];
+ aOpenGL.EdgeFlag(rEntity.IsEdgeVisible() ? GL_TRUE : GL_FALSE);
+ aOpenGL.Vertex3dv((const double *)(&rEntity.Point()));
+ }
+
+ // Primitiv abschliessen
+ aOpenGL.End();
+
+ // NUR auf neues Array setzen, wenn noch was da ist (#59941#)
+ if(nEntityCounter < rEntityBucket.Count())
+ {
+ // Pointer auf neues Array setzen
+ nArray = (UINT16)(nEntityCounter >> rEntityBucket.GetBlockShift());
+ nArrayStartIndex = nEntityCounter;
+ B3dEntity& rStart = rEntityBucket[nEntityCounter];
+
+ aOpenGL.VertexPointer(3, GL_DOUBLE, rEntityBucket.GetSlotSize(), &rStart);
+ aOpenGL.EdgeFlagPointer(rEntityBucket.GetSlotSize(), &(rStart.EdgeFlag()));
+ }
+ }
+ else
+ {
+ // Primitiv komplett raushauen, liegt in einem Buffer
+ aOpenGL.DrawArrays(bLineMode ? Base3DLineStrip : Base3DPolygon,
+ nEntityCounter - nArrayStartIndex,
+ nUpperBound - nEntityCounter);
+ nEntityCounter = nUpperBound;
+ }
+ }
+
+ // Arrays deaktivieren
+ aOpenGL.DisableClientState(GL_VERTEX_ARRAY);
+ aOpenGL.DisableClientState(GL_EDGE_FLAG_ARRAY);
+ }
+ else
+ {
+ // Transparenz Flaechen beachten
+ if(GetMaterial(Base3DMaterialDiffuse).GetTransparency())
+ {
+ aOpenGL.Enable( GL_BLEND );
+ aOpenGL.DepthMask( FALSE );
+ aOpenGL.BlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+ }
+ else
+ {
+ aOpenGL.Disable( GL_BLEND );
+ aOpenGL.DepthMask( TRUE );
+ }
+
+ // Polygone gefuellt ausgeben
+ aOpenGL.PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ aOpenGL.EnableClientState(GL_NORMAL_ARRAY);
+ aOpenGL.EnableClientState(GL_TEXTURE_COORD_ARRAY);
+ if(GetForceFlat() || GetShadeModel() == Base3DFlat)
+ aOpenGL.NormalPointer(GL_DOUBLE, rEntityBucket.GetSlotSize(), &rEntityBucket[0].PlaneNormal());
+ else
+ aOpenGL.NormalPointer(GL_DOUBLE, rEntityBucket.GetSlotSize(), &rEntityBucket[0].Normal());
+ aOpenGL.TexCoordPointer(2, GL_DOUBLE, rEntityBucket.GetSlotSize(), &rEntityBucket[0].TexCoor());
+
+ while(nPolyCounter < rIndexBucket.Count())
+ {
+ // Naechstes Primitiv
+ nUpperBound = rIndexBucket[nPolyCounter].GetIndex();
+ BOOL bLineMode = (rIndexBucket[nPolyCounter++].GetMode() == B3D_INDEX_MODE_LINE);
+
+ if(nUpperBound >> rEntityBucket.GetBlockShift() != nArray)
+ {
+ // Einzelschritt, Bereichsueberschreitung im Buffer
+ // Als Polygon ausgeben
+ aOpenGL.Begin(bLineMode ? Base3DLineStrip : Base3DPolygon);
+
+ // Polygon ausgeben
+ while(nEntityCounter < nUpperBound)
+ {
+ B3dEntity& rEntity = rEntityBucket[nEntityCounter++];
+ if(GetForceFlat() || GetShadeModel() == Base3DFlat)
+ aOpenGL.Normal3dv((const double *)(&rEntity.PlaneNormal()));
+ else
+ aOpenGL.Normal3dv((const double *)(&rEntity.Normal()));
+ aOpenGL.TexCoord3dv((const double *)(&rEntity.TexCoor()));
+ aOpenGL.Vertex3dv((const double *)(&rEntity.Point()));
+ }
+
+ // Primitiv abschliessen
+ aOpenGL.End();
+
+ // NUR auf neues Array setzen, wenn noch was da ist (#58702#)
+ if(nEntityCounter < rEntityBucket.Count())
+ {
+ // Pointer auf neues Array setzen
+ nArray = (UINT16)(nEntityCounter >> rEntityBucket.GetBlockShift());
+ nArrayStartIndex = nEntityCounter;
+ B3dEntity& rStart = rEntityBucket[nEntityCounter];
+
+ aOpenGL.VertexPointer(3, GL_DOUBLE, rEntityBucket.GetSlotSize(), &rStart);
+ if(GetForceFlat() || GetShadeModel() == Base3DFlat)
+ aOpenGL.NormalPointer(GL_DOUBLE, rEntityBucket.GetSlotSize(), &(rStart.PlaneNormal()));
+ else
+ aOpenGL.NormalPointer(GL_DOUBLE, rEntityBucket.GetSlotSize(), &(rStart.Normal()));
+ aOpenGL.TexCoordPointer(2, GL_DOUBLE, rEntityBucket.GetSlotSize(), &(rStart.TexCoor()));
+ }
+ }
+ else
+ {
+ // Primitiv komplett raushauen, liegt in einem Buffer
+ aOpenGL.DrawArrays(bLineMode ? Base3DLineStrip : Base3DPolygon,
+ nEntityCounter - nArrayStartIndex,
+ nUpperBound - nEntityCounter);
+ nEntityCounter = nUpperBound;
+ }
+ }
+
+ // Arrays deaktivieren
+ aOpenGL.DisableClientState(GL_VERTEX_ARRAY);
+ aOpenGL.DisableClientState(GL_NORMAL_ARRAY);
+ aOpenGL.DisableClientState(GL_TEXTURE_COORD_ARRAY);
+ }
+ }
+ }
+}
+