9#include "ps2s/cpu_matrix.h"
10#include "ps2s/displayenv.h"
12#include "ps2s/packet.h"
15#include "ps2gl/clear.h"
16#include "ps2gl/dlist.h"
17#include "ps2gl/drawcontext.h"
18#include "ps2gl/glcontext.h"
19#include "ps2gl/gmanager.h"
20#include "ps2gl/material.h"
21#include "ps2gl/matrix.h"
22#include "ps2gl/renderer.h"
23#include "ps2gl/texture.h"
25using namespace ArrayType;
31CImmGeomManager::CImmGeomManager(
CGLContext& context,
int immBufferQwordSize)
33 , RendererManager(context)
34 , VertexBuf0(immBufferQwordSize + immBufferQwordSize % 4,
35 DMAC::Channels::vif1, Core::MemMappings::UncachedAccl)
36 , NormalBuf0(immBufferQwordSize * 4 / 3 + 1 + (immBufferQwordSize * 4 / 3 + 1) % 4,
37 DMAC::Channels::vif1, Core::MemMappings::UncachedAccl)
38 , TexCoordBuf0(immBufferQwordSize / 2 + (immBufferQwordSize / 2) % 4,
39 DMAC::Channels::vif1, Core::MemMappings::UncachedAccl)
40 , ColorBuf0(immBufferQwordSize + immBufferQwordSize % 4,
41 DMAC::Channels::vif1, Core::MemMappings::UncachedAccl)
42 , VertexBuf1(immBufferQwordSize + immBufferQwordSize % 4,
43 DMAC::Channels::vif1, Core::MemMappings::UncachedAccl)
44 , NormalBuf1(immBufferQwordSize * 4 / 3 + 1 + (immBufferQwordSize * 4 / 3 + 1) % 4,
45 DMAC::Channels::vif1, Core::MemMappings::UncachedAccl)
46 , TexCoordBuf1(immBufferQwordSize / 2 + (immBufferQwordSize / 2) % 4,
47 DMAC::Channels::vif1, Core::MemMappings::UncachedAccl)
48 , ColorBuf1(immBufferQwordSize + immBufferQwordSize % 4,
49 DMAC::Channels::vif1, Core::MemMappings::UncachedAccl)
51 CurVertexBuf = &VertexBuf0;
52 CurNormalBuf = &NormalBuf0;
53 CurTexCoordBuf = &TexCoordBuf0;
54 CurColorBuf = &ColorBuf0;
58 RendererManager.ArrayAccessChanged(RendererProps::kLinear);
61CImmGeomManager::~CImmGeomManager()
66void CImmGeomManager::SwapBuffers()
69 if (CurVertexBuf == &VertexBuf0)
70 CurVertexBuf = &VertexBuf1;
72 CurVertexBuf = &VertexBuf0;
73 CurVertexBuf->Reset();
74 if (CurNormalBuf == &NormalBuf0)
75 CurNormalBuf = &NormalBuf1;
77 CurNormalBuf = &NormalBuf0;
78 CurNormalBuf->Reset();
79 if (CurTexCoordBuf == &TexCoordBuf0)
80 CurTexCoordBuf = &TexCoordBuf1;
82 CurTexCoordBuf = &TexCoordBuf0;
83 CurTexCoordBuf->Reset();
84 if (CurColorBuf == &ColorBuf0)
85 CurColorBuf = &ColorBuf1;
87 CurColorBuf = &ColorBuf0;
95void CImmGeomManager::BeginGeom(GLenum mode)
100 Geometry.SetPrimType(mode);
101 Geometry.SetArrayType(kLinear);
103 Geometry.SetNormals(CurNormalBuf->GetNextPtr());
104 Geometry.SetVertices(CurVertexBuf->GetNextPtr());
105 Geometry.SetTexCoords(CurTexCoordBuf->GetNextPtr());
106 Geometry.SetColors(CurColorBuf->GetNextPtr());
108 InsideBeginEnd =
true;
111void CImmGeomManager::Vertex(cpu_vec_xyzw newVert)
113 cpu_vec_xyz normal = GetCurNormal();
114 *CurNormalBuf += normal;
116 const float* texCoord = GetCurTexCoord();
117 *CurTexCoordBuf += texCoord[0];
118 *CurTexCoordBuf += texCoord[1];
120 *CurVertexBuf += newVert;
122 Geometry.AddVertices();
123 Geometry.AddNormals();
124 Geometry.AddTexCoords();
127void CImmGeomManager::Normal(cpu_vec_xyz normal)
134void CImmGeomManager::Color(cpu_vec_xyzw color)
136 if (InsideBeginEnd) {
137 *CurColorBuf += color;
138 Geometry.AddColors();
140 GLContext.GetMaterialManager().Color(color);
144void CImmGeomManager::TexCoord(
float u,
float v)
150void CImmGeomManager::EndGeom()
152 InsideBeginEnd =
false;
154 Geometry.SetVerticesAreValid(
true);
155 Geometry.SetNormalsAreValid(
true);
156 Geometry.SetTexCoordsAreValid(
true);
159 Geometry.SetColorsAreValid(
false);
160 if (Geometry.GetNumNewColors() > 0) {
161 mErrorIf(Geometry.GetNumNewVertices() != Geometry.GetNumNewColors(),
162 "Sorry, but inside glBegin/glEnd you need "
163 "to specify either one color for each vertex given, or none.");
164 Geometry.SetColorsAreValid(
true);
166 SyncColorMaterial(
true);
168 SyncColorMaterial(
false);
171 Geometry.SetWordsPerVertex(4);
172 Geometry.SetWordsPerNormal(3);
173 Geometry.SetWordsPerTexCoord(2);
174 Geometry.SetWordsPerColor(4);
183void CImmGeomManager::DrawArrays(GLenum mode,
int first,
int count)
188 Geometry.SetPrimType(mode);
189 Geometry.SetArrayType(kLinear);
191 Geometry.SetVertices(VertArray->GetVertices());
192 Geometry.SetNormals(VertArray->GetNormals());
193 Geometry.SetTexCoords(VertArray->GetTexCoords());
194 Geometry.SetColors(VertArray->GetColors());
196 Geometry.SetVerticesAreValid(VertArray->GetVerticesAreValid());
197 Geometry.SetNormalsAreValid(VertArray->GetNormalsAreValid());
198 Geometry.SetTexCoordsAreValid(VertArray->GetTexCoordsAreValid());
199 Geometry.SetColorsAreValid(VertArray->GetColorsAreValid());
201 Geometry.SetWordsPerVertex(VertArray->GetWordsPerVertex());
202 Geometry.SetWordsPerNormal(VertArray->GetWordsPerNormal());
203 Geometry.SetWordsPerTexCoord(VertArray->GetWordsPerTexCoord());
204 Geometry.SetWordsPerColor(VertArray->GetWordsPerColor());
206 Geometry.AddVertices(count);
207 Geometry.AddNormals(count);
208 Geometry.AddTexCoords(count);
209 Geometry.AddColors(count);
211 Geometry.AdjustNewGeomPtrs(first);
214 SyncColorMaterial(VertArray->GetColors() != NULL);
219void CImmGeomManager::DrawingIndexedArray()
221 if (!LastArrayAccessIsValid || !LastArrayAccessWasIndexed) {
222 GLContext.ArrayAccessChanged();
223 RendererManager.ArrayAccessChanged(RendererProps::kIndexed);
224 LastArrayAccessIsValid =
true;
226 LastArrayAccessWasIndexed =
true;
229void CImmGeomManager::DrawIndexedArrays(GLenum primType,
230 int numIndices,
const unsigned char* indices,
254 if (Prim != primType)
255 PrimChanged(primType);
257 Geometry.SetPrimType(primType);
258 Geometry.SetArrayType(kIndexed);
260 Geometry.SetVertices(VertArray->GetVertices());
261 Geometry.SetNormals(VertArray->GetNormals());
262 Geometry.SetTexCoords(VertArray->GetTexCoords());
263 Geometry.SetColors(VertArray->GetColors());
265 Geometry.SetVerticesAreValid(VertArray->GetVerticesAreValid());
266 Geometry.SetNormalsAreValid(VertArray->GetNormalsAreValid());
267 Geometry.SetTexCoordsAreValid(VertArray->GetTexCoordsAreValid());
268 Geometry.SetColorsAreValid(VertArray->GetColorsAreValid());
270 Geometry.SetWordsPerVertex(VertArray->GetWordsPerVertex());
271 Geometry.SetWordsPerNormal(VertArray->GetWordsPerNormal());
272 Geometry.SetWordsPerTexCoord(VertArray->GetWordsPerTexCoord());
273 Geometry.SetWordsPerColor(VertArray->GetWordsPerColor());
275 Geometry.AddVertices(numVertices);
276 Geometry.AddNormals(numVertices);
277 Geometry.AddTexCoords(numVertices);
278 Geometry.AddColors(numVertices);
280 Geometry.SetNumIndices(numIndices);
281 Geometry.SetIndices(indices);
282 Geometry.SetIStripLengths(NULL);
285 SyncColorMaterial(VertArray->GetColors() != NULL);
294void CImmGeomManager::DrawingLinearArray()
296 if (!LastArrayAccessIsValid || LastArrayAccessWasIndexed) {
297 GLContext.ArrayAccessChanged();
298 RendererManager.ArrayAccessChanged(RendererProps::kLinear);
299 LastArrayAccessIsValid =
true;
301 LastArrayAccessWasIndexed =
false;
304void CImmGeomManager::CommitNewGeom()
307 if (Geometry.GetNewArrayType() == kLinear)
308 DrawingLinearArray();
310 DrawingIndexedArray();
315 if (Geometry.IsPending()) {
321 if (GLContext.GetRendererContextChanged() == 0
322 && GLContext.GetGsContextChanged() == 0
323 && !UserRenderContextChanged
325 && Geometry.MergeNew()) {
329 if (Geometry.GetArrayType() == kLinear)
337 Geometry.MakeNewValuesCurrent();
340 if (rendererChanged) {
341 RendererManager.MakeNewRendererCurrent();
342 RendererManager.LoadRenderer(GLContext.GetVif1Packet());
344 SyncRendererContext(Geometry.GetPrimType());
349void CImmGeomManager::PrimChanged(GLenum primType)
351 GLContext.PrimChanged();
352 RendererManager.PrimChanged(primType);
355void CImmGeomManager::SyncRenderer()
358 RendererManager.MakeNewRendererCurrent();
359 RendererManager.LoadRenderer(GLContext.GetVif1Packet());
363void CImmGeomManager::SyncRendererContext(GLenum primType)
366 if (GLContext.GetRendererContextChanged()
367 || (RendererManager.IsCurRendererCustom() && UserRenderContextChanged)) {
368 RendererManager.GetCurRenderer().
InitContext(primType,
369 GLContext.GetRendererContextChanged(),
370 UserRenderContextChanged);
372 GLContext.SetRendererContextChanged(
false);
373 UserRenderContextChanged =
false;
378void CImmGeomManager::SyncGsContext()
380 if (tU32 changed = GLContext.GetGsContextChanged()) {
382 bool texEnabled = GLContext.GetTexManager().GetTexEnabled();
383 CVifSCDmaPacket& packet = GLContext.GetVif1Packet();
385 && changed & GsCtxtFlags::Texture) {
389 packet.Flush().Nop();
391 GLContext.GetTexManager().UseCurTexture(GLContext.GetVif1Packet());
395 if (changed & GsCtxtFlags::DrawEnv) {
398 packet.Flush().Nop();
401 GLContext.AddingDrawEnvToPacket((tU128*)GLContext.GetVif1Packet().GetNextPtr() + 1);
402 GLContext.GetImmDrawContext().GetDrawEnv().SendSettings(GLContext.GetVif1Packet());
405 GLContext.SetGsContextChanged(
false);
409void CImmGeomManager::SyncColorMaterial(
bool pvColorsArePresent)
412 if (pvColorsArePresent && mm.GetColorMaterialEnabled()) {
413 switch (mm.GetColorMaterialMode()) {
415 mNotImplemented(
"Only GL_DIFFUSE can change per-vertex");
418 mNotImplemented(
"Only GL_DIFFUSE can change per-vertex");
422 GLContext.PerVtxMaterialChanged();
423 RendererManager.PerVtxMaterialChanged(RendererProps::kDiffuse);
425 case GL_AMBIENT_AND_DIFFUSE:
426 mNotImplemented(
"Only GL_DIFFUSE can change per-vertex");
429 mNotImplemented(
"Only GL_DIFFUSE can change per-vertex");
434 RendererManager.PerVtxMaterialChanged(RendererProps::kNoMaterial);
438void CImmGeomManager::Flush()
440 if (Geometry.IsPending()) {
441 if (Geometry.GetArrayType() == kLinear)
virtual void InitContext(GLenum primType, tU32 rcChanges, bool userRcChanged)=0
virtual void DrawIndexedArrays(CGeometryBlock &block)
Draw arrays of vertices that are accessed by index (i.e., glDrawElements)
virtual void DrawLinearArrays(CGeometryBlock &block)
Draw arrays of vertices that are accessed linearly (i.e., glDrawArrays)