Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

gblock.cpp

Go to the documentation of this file.
00001 /*        Copyright (C) 2000,2001,2002  Sony Computer Entertainment America
00002           
00003           This file is subject to the terms and conditions of the GNU Lesser
00004           General Public License Version 2.1. See the file "COPYING" in the
00005           main directory of this archive for more details.                             */
00006 
00007 #include "ps2gl/gblock.h"
00008 #include "ps2gl/gmanager.h"
00009 
00010 using namespace ArrayType;
00011 
00012 /********************************************
00013  * CGeometryBlock
00014  */
00015 
00016 bool
00017 CGeometryBlock::SameDataFormat()
00018 {
00019    bool same = true;
00020 
00021    if ( AreVerticesValid != AreNewVerticesValid
00022         || AreNormalsValid != AreNewNormalsValid
00023         || AreTexCoordsValid != AreNewTexCoordsValid
00024         || AreColorsValid != AreNewColorsValid )
00025       same = false;
00026    else if ( AreNewVerticesValid && WordsPerVertex != WordsPerNewVertex )
00027       same = false;
00028    else if ( AreNewNormalsValid && WordsPerNormal != WordsPerNewNormal )
00029       same = false;
00030    else if ( AreNewTexCoordsValid && WordsPerTexCoord != WordsPerNewTexCoord )
00031       same = false;
00032    else if ( AreNewColorsValid && WordsPerColor != WordsPerNewColor )
00033       same = false;
00034 
00035    return same;
00036 }
00037 
00038 bool
00039 CGeometryBlock::MergeNew()
00040 {
00041    mAssert( IsPending() );
00042    mErrorIf( NumNewVertices == 0, "Trying to merge geometry with no vertices!" );
00043 
00044    bool success = false;
00045 
00046    if ( NewArrayType == kLinear )
00047       success = MergeNewLinear();
00048    else
00049       success = MergeNewIndexed();
00050 
00051    return success;
00052 }
00053 
00054 bool
00055 CGeometryBlock::MergeNewIndexed()
00056 {
00057    bool success = true;
00058 
00059    if ( NewPrimType != PrimType
00060         || NewArrayType != ArrayType
00061         || NumStrips == kMaxNumStrips )
00062       success = false;
00063 
00064    if ( success ) {
00065       Vertices[NumStrips] = NewVertices;
00066       Normals[NumStrips] = NewNormals;
00067       TexCoords[NumStrips] = NewTexCoords;
00068       Colors[NumStrips] = NewColors;
00069 
00070       StripLengths[NumStrips] = (unsigned int)NumNewVertices;
00071       IStripLengths[NumStrips] = NewIStripLengths;
00072       Indices[NumStrips] = NewIndices;
00073       NumIndices[NumStrips] = NumNewIndices;
00074 
00075       NumStrips++;
00076 
00077       ResetNew();
00078    }
00079 
00080    return success;
00081 }
00082 
00083 bool
00084 CGeometryBlock::MergeNewLinear()
00085 {
00086    bool success = true;
00087 
00088    if ( NewPrimType != PrimType
00089         || NewArrayType != ArrayType
00090         || ! SameDataFormat()
00091         || NumStrips == kMaxNumStrips
00092       )
00093       success = false;
00094    else {
00095       bool merged = false;
00096 
00097       TotalVertices += NumNewVertices;
00098 
00099       // if the new and old vertices, normals, tex, .. whatever
00100       // are all contiguous in memory they can be combined into the same list of
00101       // primitives
00102 
00103       int stripLength = GetStripLength(NumStrips-1);
00104       if ( (float*)Vertices[NumStrips-1] + WordsPerVertex*stripLength
00105            == (float*)NewVertices
00106            && ( ! AreNormalsValid
00107                 || (float*)Normals[NumStrips-1] + WordsPerNormal*stripLength
00108                 == (float*)NewNormals )
00109            && ( ! AreTexCoordsValid
00110                 || (float*)TexCoords[NumStrips-1] + WordsPerTexCoord*stripLength
00111                 == (float*)NewTexCoords )
00112            && ( ! AreColorsValid
00113                 || (float*)Colors[NumStrips-1] + WordsPerColor*stripLength
00114                 == (float*)NewColors )
00115          )
00116       {
00117          // is this a user-defined prim type?
00118          bool mergeUser = true;
00119          if ( CGeomManager::IsUserPrimType(PrimType) )
00120             mergeUser = CGeomManager::GetUserPrimMerge(PrimType);
00121 
00122          // strips can't really be merged because they have to be broken
00123          // at their boundaries in vu1 by setting adc bits
00124          if ( PrimType != GL_LINE_STRIP
00125               && PrimType != GL_TRIANGLE_STRIP
00126               && PrimType != GL_TRIANGLE_FAN
00127               && PrimType != GL_QUAD_STRIP
00128               && mergeUser ) {
00129             merged = true;
00130             StripLengths[NumStrips-1] += (unsigned int)NumNewVertices;
00131          }
00132          else if ( PrimType != GL_TRIANGLE_FAN ) {
00133             StripLengths[NumStrips-1] |= kContinueFlag;
00134          }
00135       }
00136 
00137       if ( ! merged ) {
00138          // can't be combined with previous list
00139          Vertices[NumStrips] = NewVertices;
00140          Normals[NumStrips] = NewNormals;
00141          TexCoords[NumStrips] = NewTexCoords;
00142          Colors[NumStrips] = NewColors;
00143 
00144          StripLengths[NumStrips] = (unsigned int)NumNewVertices;
00145       }
00146 
00147       if ( ! merged )
00148          NumStrips++;
00149 
00150       ResetNew();
00151    }
00152 
00153    return success;
00154 }
00155 
00156 void
00157 CGeometryBlock::MakeNewValuesCurrent()
00158 {
00159    CommitPrimType();
00160    ArrayType = NewArrayType;
00161 
00162    NumStrips = 0;
00163 
00164    Vertices[NumStrips] = NewVertices;
00165    Normals[NumStrips] = NewNormals;
00166    TexCoords[NumStrips] = NewTexCoords;
00167    Colors[NumStrips] = NewColors;
00168    IStripLengths[NumStrips] = NewIStripLengths;
00169    Indices[NumStrips] = NewIndices;
00170    NumIndices[NumStrips] = NumNewIndices;
00171 
00172    TotalVertices = NumNewVertices;
00173    StripLengths[NumStrips] = (unsigned int)NumNewVertices;
00174 
00175    WordsPerVertex = WordsPerNewVertex;
00176    WordsPerNormal = WordsPerNewNormal;
00177    WordsPerTexCoord = WordsPerNewTexCoord;
00178    WordsPerColor = WordsPerNewColor;
00179 
00180    AreVerticesValid = AreNewVerticesValid;
00181    AreNormalsValid = AreNewNormalsValid;
00182    AreTexCoordsValid = AreNewTexCoordsValid;
00183    AreColorsValid = AreNewColorsValid;
00184 
00185    NumStrips = 1;
00186 }
00187 
00188 void
00189 CGeometryBlock::ResetNew()
00190 {
00191    NewPrimType = GL_INVALID_VALUE;
00192    NewArrayType = kInvalidArray;
00193    NumNewVertices = NumNewNormals = NumNewTexCoords = NumNewColors = 0;
00194 
00195    NewVertices = NewNormals = NewTexCoords = NewColors = NULL;
00196    NewIndices = NewIStripLengths = NULL;
00197    NumNewIndices = 0;
00198    WordsPerNewVertex = WordsPerNewNormal = WordsPerNewTexCoord = WordsPerNewColor = 0;
00199    AreNewVerticesValid = AreNewNormalsValid = AreNewTexCoordsValid = AreNewColorsValid = false;
00200 }
00201 
00202 void
00203 CGeometryBlock::ResetCurStrip()
00204 {
00205    Vertices[NumStrips] = Normals[NumStrips] = NULL;
00206    TexCoords[NumStrips] = Colors[NumStrips] = NULL;
00207    StripLengths[NumStrips] = 0;
00208    Indices[NumStrips] = 0;
00209    IStripLengths[NumStrips] = 0;
00210    NumIndices[NumStrips] = 0;
00211 }
00212 
00213 void
00214 CGeometryBlock::Reset()
00215 {
00216    TotalVertices = 0;
00217    WordsPerVertex = WordsPerNormal = WordsPerTexCoord = WordsPerColor = 0;
00218    AreVerticesValid = AreNormalsValid = AreTexCoordsValid = AreColorsValid = false;
00219    PrimType = GL_INVALID_VALUE;
00220    NumVertsPerPrim = NumVertsToRestartStrip = -1;
00221    NumStrips = 0;
00222    ResetCurStrip();
00223    ResetNew();
00224 }
00225 
00226 void
00227 CGeometryBlock::CommitPrimType()
00228 {
00229    if ( PrimType != NewPrimType ) {
00230       if ( ! CGeomManager::IsUserPrimType(NewPrimType) ) {
00231          switch (NewPrimType) {
00232             case GL_POINTS:
00233                NumVertsPerPrim = 1;
00234                NumVertsToRestartStrip = 0;
00235                break;
00236             case GL_LINE_STRIP:
00237                NumVertsPerPrim = 1;
00238                NumVertsToRestartStrip = 1;
00239                break;
00240             case GL_TRIANGLE_STRIP:
00241             case GL_TRIANGLE_FAN:
00242             case GL_QUAD_STRIP:
00243             case GL_POLYGON:
00244                // the number of verts per prim is used to determine where
00245                // (or where not) to break a list of primitives (in DrawArrays).
00246                // Let's pretend the triangle strips have 2 verts per primitive
00247                // so that they will only be broken on even vertex boundaries
00248                // because otherwise the face culling test gets out of sync...
00249                NumVertsPerPrim = 2;
00250                NumVertsToRestartStrip = 2;
00251                break;
00252             case GL_LINES:
00253                NumVertsPerPrim = 2;
00254                NumVertsToRestartStrip = 0;
00255                break;
00256             case GL_TRIANGLES:
00257                NumVertsPerPrim = 3;
00258                NumVertsToRestartStrip = 0;
00259                break;
00260             case GL_QUADS:
00261                NumVertsPerPrim = 4;
00262                NumVertsToRestartStrip = 0;
00263                break;
00264             default:
00265                mError( "Unknown prim type: 0x%08x", NewPrimType );
00266          }
00267 
00268          if (NewPrimType == GL_TRIANGLE_FAN)
00269             StripsCanBeMerged = false;
00270          else
00271             StripsCanBeMerged = true;
00272       }
00273 
00274       PrimType = NewPrimType;
00275    }
00276 }
00277 

ps2gl version cvs