PS2GL
OpenGL*-like API for the PS2
Loading...
Searching...
No Matches
gblock.cpp
1/* Copyright (C) 2000,2001,2002 Sony Computer Entertainment America
2
3 This file is subject to the terms and conditions of the GNU Lesser
4 General Public License Version 2.1. See the file "COPYING" in the
5 main directory of this archive for more details. */
6
7#include "ps2gl/gblock.h"
8#include "ps2gl/gmanager.h"
9
10using namespace ArrayType;
11
12/********************************************
13 * CGeometryBlock
14 */
15
16bool CGeometryBlock::SameDataFormat()
17{
18 bool same = true;
19
20 if (AreVerticesValid != AreNewVerticesValid
21 || AreNormalsValid != AreNewNormalsValid
22 || AreTexCoordsValid != AreNewTexCoordsValid
23 || AreColorsValid != AreNewColorsValid)
24 same = false;
25 else if (AreNewVerticesValid && WordsPerVertex != WordsPerNewVertex)
26 same = false;
27 else if (AreNewNormalsValid && WordsPerNormal != WordsPerNewNormal)
28 same = false;
29 else if (AreNewTexCoordsValid && WordsPerTexCoord != WordsPerNewTexCoord)
30 same = false;
31 else if (AreNewColorsValid && WordsPerColor != WordsPerNewColor)
32 same = false;
33
34 return same;
35}
36
37bool CGeometryBlock::MergeNew()
38{
39 mAssert(IsPending());
40 mErrorIf(NumNewVertices == 0, "Trying to merge geometry with no vertices!");
41
42 bool success = false;
43
44 if (NewArrayType == kLinear)
45 success = MergeNewLinear();
46 else
47 success = MergeNewIndexed();
48
49 return success;
50}
51
52bool CGeometryBlock::MergeNewIndexed()
53{
54 bool success = true;
55
56 if (NewPrimType != PrimType
57 || NewArrayType != ArrayType
58 || NumStrips >= kMaxNumStrips)
59 success = false;
60
61 if (success) {
62 Vertices[NumStrips] = NewVertices;
63 Normals[NumStrips] = NewNormals;
64 TexCoords[NumStrips] = NewTexCoords;
65 Colors[NumStrips] = NewColors;
66
67 StripLengths[NumStrips] = (unsigned int)NumNewVertices;
68 IStripLengths[NumStrips] = NewIStripLengths;
69 Indices[NumStrips] = NewIndices;
70 NumIndices[NumStrips] = NumNewIndices;
71
72 NumStrips++;
73
74 ResetNew();
75 }
76
77 return success;
78}
79
80bool CGeometryBlock::MergeNewLinear()
81{
82 bool success = true;
83
84 if (NewPrimType != PrimType
85 || NewArrayType != ArrayType
86 || !SameDataFormat()
87 || NumStrips == kMaxNumStrips)
88 success = false;
89 else {
90 bool merged = false;
91
92 TotalVertices += NumNewVertices;
93
94 // if the new and old vertices, normals, tex, .. whatever
95 // are all contiguous in memory they can be combined into the same list of
96 // primitives
97
98 int stripLength = GetStripLength(NumStrips - 1);
99 if ((float*)Vertices[NumStrips - 1] + WordsPerVertex * stripLength
100 == (float*)NewVertices
101 && (!AreNormalsValid
102 || (float*)Normals[NumStrips - 1] + WordsPerNormal * stripLength
103 == (float*)NewNormals)
104 && (!AreTexCoordsValid
105 || (float*)TexCoords[NumStrips - 1] + WordsPerTexCoord * stripLength
106 == (float*)NewTexCoords)
107 && (!AreColorsValid
108 || (float*)Colors[NumStrips - 1] + WordsPerColor * stripLength
109 == (float*)NewColors)) {
110 // is this a user-defined prim type?
111 bool mergeUser = true;
112 if (CGeomManager::IsUserPrimType(PrimType))
113 mergeUser = CGeomManager::GetUserPrimMerge(PrimType);
114
115 // strips can't really be merged because they have to be broken
116 // at their boundaries in vu1 by setting adc bits
117 if (PrimType != GL_LINE_STRIP
118 && PrimType != GL_TRIANGLE_STRIP
119 && PrimType != GL_TRIANGLE_FAN
120 && PrimType != GL_QUAD_STRIP
121 && mergeUser) {
122 merged = true;
123 StripLengths[NumStrips - 1] += (unsigned int)NumNewVertices;
124 } else if (PrimType != GL_TRIANGLE_FAN) {
125 StripLengths[NumStrips - 1] |= kContinueFlag;
126 }
127 }
128
129 if (!merged) {
130 // can't be combined with previous list
131 Vertices[NumStrips] = NewVertices;
132 Normals[NumStrips] = NewNormals;
133 TexCoords[NumStrips] = NewTexCoords;
134 Colors[NumStrips] = NewColors;
135
136 StripLengths[NumStrips] = (unsigned int)NumNewVertices;
137 }
138
139 if (!merged)
140 NumStrips++;
141
142 ResetNew();
143 }
144
145 return success;
146}
147
148void CGeometryBlock::MakeNewValuesCurrent()
149{
150 CommitPrimType();
151 ArrayType = NewArrayType;
152
153 NumStrips = 0;
154
155 Vertices[NumStrips] = NewVertices;
156 Normals[NumStrips] = NewNormals;
157 TexCoords[NumStrips] = NewTexCoords;
158 Colors[NumStrips] = NewColors;
159 IStripLengths[NumStrips] = NewIStripLengths;
160 Indices[NumStrips] = NewIndices;
161 NumIndices[NumStrips] = NumNewIndices;
162
163 TotalVertices = NumNewVertices;
164 StripLengths[NumStrips] = (unsigned int)NumNewVertices;
165
166 WordsPerVertex = WordsPerNewVertex;
167 WordsPerNormal = WordsPerNewNormal;
168 WordsPerTexCoord = WordsPerNewTexCoord;
169 WordsPerColor = WordsPerNewColor;
170
171 AreVerticesValid = AreNewVerticesValid;
172 AreNormalsValid = AreNewNormalsValid;
173 AreTexCoordsValid = AreNewTexCoordsValid;
174 AreColorsValid = AreNewColorsValid;
175
176 NumStrips = 1;
177}
178
179void CGeometryBlock::ResetNew()
180{
181 NewPrimType = GL_INVALID_VALUE;
182 NewArrayType = kInvalidArray;
183 NumNewVertices = NumNewNormals = NumNewTexCoords = NumNewColors = 0;
184
185 NewVertices = NewNormals = NewTexCoords = NewColors = NULL;
186 NewIndices = NewIStripLengths = NULL;
187 NumNewIndices = 0;
188 WordsPerNewVertex = WordsPerNewNormal = WordsPerNewTexCoord = WordsPerNewColor = 0;
189 AreNewVerticesValid = AreNewNormalsValid = AreNewTexCoordsValid = AreNewColorsValid = false;
190}
191
192void CGeometryBlock::ResetCurStrip()
193{
194 Vertices[NumStrips] = Normals[NumStrips] = NULL;
195 TexCoords[NumStrips] = Colors[NumStrips] = NULL;
196 StripLengths[NumStrips] = 0;
197 Indices[NumStrips] = 0;
198 IStripLengths[NumStrips] = 0;
199 NumIndices[NumStrips] = 0;
200}
201
202void CGeometryBlock::Reset()
203{
204 TotalVertices = 0;
205 WordsPerVertex = WordsPerNormal = WordsPerTexCoord = WordsPerColor = 0;
206 AreVerticesValid = AreNormalsValid = AreTexCoordsValid = AreColorsValid = false;
207 PrimType = GL_INVALID_VALUE;
208 NumVertsPerPrim = NumVertsToRestartStrip = -1;
209 NumStrips = 0;
210 ResetCurStrip();
211 ResetNew();
212}
213
214void CGeometryBlock::CommitPrimType()
215{
216 if (PrimType != NewPrimType) {
217 if (!CGeomManager::IsUserPrimType(NewPrimType)) {
218 switch (NewPrimType) {
219 case GL_POINTS:
220 NumVertsPerPrim = 1;
221 NumVertsToRestartStrip = 0;
222 break;
223 case GL_LINE_STRIP:
224 NumVertsPerPrim = 1;
225 NumVertsToRestartStrip = 1;
226 break;
227 case GL_TRIANGLE_STRIP:
228 case GL_TRIANGLE_FAN:
229 case GL_QUAD_STRIP:
230 case GL_POLYGON:
231 // the number of verts per prim is used to determine where
232 // (or where not) to break a list of primitives (in DrawArrays).
233 // Let's pretend the triangle strips have 2 verts per primitive
234 // so that they will only be broken on even vertex boundaries
235 // because otherwise the face culling test gets out of sync...
236 NumVertsPerPrim = 2;
237 NumVertsToRestartStrip = 2;
238 break;
239 case GL_LINES:
240 NumVertsPerPrim = 2;
241 NumVertsToRestartStrip = 0;
242 break;
243 case GL_TRIANGLES:
244 NumVertsPerPrim = 3;
245 NumVertsToRestartStrip = 0;
246 break;
247 case GL_QUADS:
248 NumVertsPerPrim = 4;
249 NumVertsToRestartStrip = 0;
250 break;
251 default:
252 mError("Unknown prim type: 0x%08x", NewPrimType);
253 }
254
255 if (NewPrimType == GL_TRIANGLE_FAN)
256 StripsCanBeMerged = false;
257 else
258 StripsCanBeMerged = true;
259 }
260
261 PrimType = NewPrimType;
262 }
263}