00001
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
00100
00101
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
00118 bool mergeUser = true;
00119 if ( CGeomManager::IsUserPrimType(PrimType) )
00120 mergeUser = CGeomManager::GetUserPrimMerge(PrimType);
00121
00122
00123
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
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
00245
00246
00247
00248
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