AaronCameron.net
I care not for your petty politics.
Not a Member? - Login or Create an Account
Tuesday the 22nd of May 2012 @ 02:55am
Front Page Journal Projects Your Profile About
[]

LibN2L-4 Library Code Reference

Classes
Compounds
Files
Members
Method Index
Full Reference

cRSkyMobile.cpp

Go to the documentation of this file.
00001 /************************************************************************
00002 Nova-2 Library (libN2L, or simply n2l) Game development C++ Library
00003 Copyright (C) 2002  Aaron Cameron
00004 
00005 This library is free software; you can redistribute it and/or
00006 modify it under the terms of the GNU Lesser General Public
00007 License as published by the Free Software Foundation; either
00008 version 2.1 of the License, or (at your option) any later version.
00009 
00010 This library is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 Lesser General Public License for more details.
00014 
00015 You should have received a copy of the GNU Lesser General Public
00016 License along with this library; if not, write to the Free Software
00017 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00018 
00019 A copy of the GNU Lesser General Public License has been provided with
00020 this library in the file 'COPYING'.
00021 
00022 Contact information for the author of this library has been provided
00023 with this library in the file 'AUTHOR'.
00024 ************************************************************************/
00025 #include "renderObjects/cRSkyMobile.h"
00026 
00027 #include "n2l/vfs.h"
00028 #include "n2l/dynVars.h"
00029 #include "n2l/materials.h"
00030 #include "n2l/resourceManagement.h"
00031 
00032 #include "renderObjects/cRFrustum.h"
00033 
00034 using namespace std;
00035 
00036 namespace n2l
00037 {
00038 
00039     /**************************************************************************/
00040     cRSkyMobile::cRSkyMobile()
00041     {
00042         init();
00043     }
00044 
00045     /**************************************************************************/
00046     cRSkyMobile::cRSkyMobile( const cVfsNodeInterface &iNode )
00047     {
00048         init();
00049         load( iNode );
00050     }
00051 
00052     /**************************************************************************/
00053     cRSkyMobile::cRSkyMobile( const cDynVar &iDef )
00054     {
00055         init();
00056         load( iDef );
00057     }
00058 
00059     /**************************************************************************/
00060     cRSkyMobile::~cRSkyMobile()
00061     {
00062         free();
00063     }
00064 
00065     /**************************************************************************/
00066     void cRSkyMobile::load( const cDynVar &iDef )
00067     {
00068         clear();
00069 
00070         // Load mobiles, last (and only, for now)
00071         if (!iDef["mobiles"].isArray()) return;
00072 
00073         try
00074         {
00075             mSkipSort = true;
00076             const cDynVar::tConstIterator Last( iDef["mobiles"].end() );
00077             for (cDynVar::tConstIterator i=iDef["mobiles"].begin(); i!=Last; ++i) {
00078                 const cDynVar &Rotation( i->second["rotation"] );
00079                 const cDynVar &Size( i->second["size"] );
00080                 addSprite(
00081                     i->first,
00082                     tVector3f( Rotation[0], Rotation[1], Rotation[2] ),
00083                     tFloat(i->second.keyValueOr("distance",1.0f)),
00084                     tVector2f( Size.keyValueOr(0,1.0f), Size.keyValueOr(1,1.0f) ),
00085                     cResourceManager::get<cGLTexture>( i->second["texture"] )
00086                 );
00087                     
00088             }
00089             mSkipSort = false;
00090         }
00091         catch ( const cException &iException )
00092         {
00093             clear();
00094             mSkipSort = false;
00095             iException.rethrow();
00096         }
00097         sort();
00098     }
00099 
00100     /**************************************************************************/
00101     void cRSkyMobile::load( const cVfsNodeInterface &iNode )
00102     {
00103         tVfsFileBuffer buffer;
00104         tUint DataOffset;
00105         try
00106         {
00107             DataOffset = vfsNodeFileWithHeader( iNode,
00108                                                 "n2l::cRSkyMobile",
00109                                                 buffer );
00110         }
00111         catch ( const cBadDataUseException & iException )
00112         {
00113             throw cBadDataUseException( "cRSkyMobile::load",
00114                                         tString("Failed to load: \"")+
00115                                         iNode.name() + "\": " +
00116                                         tString(iException) );
00117         }
00118         cDynVar def;
00119         def.unserialize( buffer, DataOffset );
00120         load( def );
00121     }
00122 
00123     /**************************************************************************/
00124     void cRSkyMobile::draw( const tUint iOptions ) const
00125     {
00126         glPushAttrib( GL_ALL_ATTRIB_BITS );
00127 
00128         glEnable( GL_TEXTURE_2D );
00129         glDisable( GL_DEPTH_TEST );
00130         glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
00131         glEnable( GL_BLEND );
00132         glDepthMask( false );
00133         glCullFace( GL_BACK );
00134         glEnable( GL_CULL_FACE );
00135         glColor4f(1,1,1,1);
00136 
00137         const tUint NumSprites( mSprites.size() );
00138 
00139         for (tUint i=0; i<NumSprites; ++i) {
00140             mSprites[i].mTexture->bind();
00141 
00142             glBegin( GL_QUADS );
00143             glTexCoord2f( 0,1 );
00144             mSprites[i].mA.glVertex3f();
00145             
00146             glTexCoord2f( 1,1 );
00147             mSprites[i].mB.glVertex3f();
00148 
00149             glTexCoord2f( 1,0 );
00150             mSprites[i].mC.glVertex3f();
00151 
00152             glTexCoord2f( 0,0 );
00153             mSprites[i].mD.glVertex3f();
00154 
00155             glEnd();
00156         }
00157 
00158         glPopAttrib();
00159     }
00160 
00161     /**************************************************************************/
00162     void cRSkyMobile::draw( const cRFrustum &iFrustum,
00163         const tVector3f &iPosAdjust, const tUint iOptions ) const
00164     {
00165         glPushAttrib( GL_ALL_ATTRIB_BITS );
00166 
00167         glEnable( GL_TEXTURE_2D );
00168         glDisable( GL_DEPTH_TEST );
00169         glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
00170         glEnable( GL_BLEND );
00171         glDepthMask( false );
00172         glCullFace( GL_BACK );
00173         glEnable( GL_CULL_FACE );
00174         glColor4f(1,1,1,1);
00175 
00176         const tUint NumSprites( mSprites.size() );
00177 
00178         for (tUint i=0; i<NumSprites; ++i) {
00179             if (!iFrustum.testQuad( mSprites[i].mA+iPosAdjust,
00180                 mSprites[i].mB+iPosAdjust,
00181                 mSprites[i].mC+iPosAdjust,
00182                 mSprites[i].mD+iPosAdjust )) continue;
00183 
00184             mSprites[i].mTexture->bind();
00185 
00186             glBegin( GL_QUADS );
00187             glTexCoord2f( 0,1 );
00188             mSprites[i].mA.glVertex3f();
00189             
00190             glTexCoord2f( 1,1 );
00191             mSprites[i].mB.glVertex3f();
00192 
00193             glTexCoord2f( 1,0 );
00194             mSprites[i].mC.glVertex3f();
00195 
00196             glTexCoord2f( 0,0 );
00197             mSprites[i].mD.glVertex3f();
00198 
00199             glEnd();
00200         }
00201 
00202         glPopAttrib();
00203     }
00204 
00205     /**************************************************************************/
00206     const cRSkyMobile::tSprite &cRSkyMobile::mustFindSprite(
00207         const tString &iName ) const
00208     {
00209         const vector<tSprite>::const_iterator LastSprite( mSprites.end() );
00210         for (vector<tSprite>::const_iterator i=mSprites.begin();
00211             i!=LastSprite; ++i)
00212         {
00213             if (i->mName==iName) return *i;
00214         }
00215         throw cOutOfBoundsException( "cRSkyMobile::mustFindSprite",
00216             tString("No such sprite named: ")+iName );
00217     }
00218 
00219     /**************************************************************************/
00220     void cRSkyMobile::addSprite( const tString &iName,
00221         const tVector3f &iRotation,
00222         const tFloat &iDistance, const tVector2f &iSize,
00223         const cAutoPtr<const cGLTexture> &iTexture )
00224     {
00225         if (!iTexture.isSet())
00226             throw cBadDataUseException( "cRSkyMobile::addSprite",
00227                 "Tried to add a null texture sprite" );
00228 
00229         // Calculate the unit vectors for this position.
00230         tVector3f uUp(0,1,0);
00231         tVector3f uLeft(1,0,0);
00232         uUp.rotateD( -iRotation.y(), tVector3f(1,0,0) );
00233         uUp.rotateD( iRotation.x(), tVector3f(0,1,0) );
00234         uLeft.rotateD( -iRotation.y(), tVector3f(1,0,0) );
00235         uLeft.rotateD( iRotation.x(), tVector3f(0,1,0) );
00236         tVector3f uPos( uLeft.cross(uUp)*iDistance );
00237 
00238         // Finally, roll the vector around the direction vector
00239         tVector3f posDirV( uPos );
00240         posDirV.normalize();
00241 
00242         uUp.rotateD( -iRotation.z(), posDirV );
00243         uLeft.rotateD( -iRotation.z(), posDirV );
00244 
00245         tSprite newSprite;
00246         newSprite.mName = iName;
00247         newSprite.mA = uPos + (uUp*-0.5f*iSize.y())+(uLeft*0.5f*iSize.x());
00248         newSprite.mB = uPos + (uUp*-0.5f*iSize.y())+(uLeft*-0.5f*iSize.x());
00249         newSprite.mC = uPos + (uUp*0.5f*iSize.y())+(uLeft*-0.5f*iSize.x());
00250         newSprite.mD = uPos + (uUp*0.5f*iSize.y())+(uLeft*0.5f*iSize.x());
00251         newSprite.mDistance = iDistance;    // Keep this to sort faster.
00252         newSprite.mSize = iSize;            // Later queries might want this.
00253         newSprite.mTexture = iTexture;
00254 
00255         mSprites.push_back( newSprite );
00256 
00257         // Stupid to sort the whole list every time.  But hey, I suck.
00258         if (!mSkipSort) sort();
00259     }
00260 
00261     /**************************************************************************/
00262     void cRSkyMobile::clear()
00263     {
00264         mSprites.clear();
00265         mSkipSort = false;
00266     }
00267 
00268     /**************************************************************************/
00269     void cRSkyMobile::init()
00270     {
00271         mSkipSort = false;
00272     }
00273 
00274     /**************************************************************************/
00275     void cRSkyMobile::free()
00276     {
00277     }
00278 
00279     /**************************************************************************/
00280     void cRSkyMobile::sort()
00281     {
00282         const tUint NumSprites( mSprites.size() );
00283         if (NumSprites<2) return;
00284 
00285         for (tUint i1=0; i1<NumSprites-1; ++i1)
00286             for (tUint i2=0; i2<NumSprites-1-i1; ++i2)
00287                 if ( mSprites[i2+1].mDistance > mSprites[i2].mDistance) {
00288                     tSprite tempS( mSprites[i2+1] );
00289                     mSprites[i2+1] = mSprites[i2];
00290                     mSprites[i2] = tempS;
00291                 }
00292     }
00293 
00294 } // namespace
©2012 Aaron Cameron