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

immgmanager.cpp

Go to the documentation of this file.
00001 /*           Copyright (C) 2001 Sony Computer Entertainment America
00002                               All Rights Reserved
00003                                SCEA Confidential                                */
00004 
00005 #include <stdio.h>
00006 
00007 #include "ps2s/packet.h"
00008 #include "ps2s/cpu_matrix.h"
00009 #include "ps2s/math.h"
00010 #include "ps2s/displayenv.h"
00011 
00012 #include "GL/ps2gl.h"
00013 #include "ps2gl/gmanager.h"
00014 #include "ps2gl/glcontext.h"
00015 #include "ps2gl/dlist.h"
00016 #include "ps2gl/clear.h"
00017 #include "ps2gl/matrix.h"
00018 #include "ps2gl/texture.h"
00019 #include "ps2gl/material.h"
00020 #include "ps2gl/drawcontext.h"
00021 
00022 /********************************************
00023  * CImmGeomManager
00024  */
00025 
00026 CImmGeomManager::CImmGeomManager( CGLContext &context, int immBufferQwordSize )
00027    : CGeomManager(context),
00028      VsmMananger(context),
00029      VertexBuf0( immBufferQwordSize + immBufferQwordSize % 4,
00030                  DMAC::Channels::vif1, Core::MemMappings::UncachedAccl ),
00031      NormalBuf0( immBufferQwordSize * 4 / 3 + 1 + (immBufferQwordSize * 4 / 3 + 1) % 4,
00032                  DMAC::Channels::vif1, Core::MemMappings::UncachedAccl ),
00033      TexCoordBuf0( immBufferQwordSize / 2 + (immBufferQwordSize / 2) % 4,
00034                    DMAC::Channels::vif1, Core::MemMappings::UncachedAccl ),
00035      ColorBuf0( immBufferQwordSize + immBufferQwordSize % 4,
00036                 DMAC::Channels::vif1, Core::MemMappings::UncachedAccl ),
00037      VertexBuf1( immBufferQwordSize + immBufferQwordSize % 4,
00038                  DMAC::Channels::vif1, Core::MemMappings::UncachedAccl ),
00039      NormalBuf1( immBufferQwordSize * 4 / 3 + 1 + (immBufferQwordSize * 4 / 3 + 1) % 4,
00040                  DMAC::Channels::vif1, Core::MemMappings::UncachedAccl ),
00041      TexCoordBuf1( immBufferQwordSize / 2 + (immBufferQwordSize / 2) % 4,
00042                    DMAC::Channels::vif1, Core::MemMappings::UncachedAccl ),
00043      ColorBuf1( immBufferQwordSize + immBufferQwordSize % 4,
00044                 DMAC::Channels::vif1, Core::MemMappings::UncachedAccl ),
00045      CurBuffer(0)
00046 {
00047    CurVertexBuf = &VertexBuf0;
00048    CurNormalBuf = &NormalBuf0;
00049    CurTexCoordBuf = &TexCoordBuf0;
00050    CurColorBuf = &ColorBuf0;
00051 
00052    NumBuffersToBeFreed[0] = NumBuffersToBeFreed[1] = 0;
00053 
00054    VertArray = new CVertArray;
00055 }
00056 
00057 CImmGeomManager::~CImmGeomManager()
00058 {
00059    delete VertArray;
00060 }
00061 
00062 /********************************************
00063  * display management
00064  */
00065 
00066 void
00067 CImmGeomManager::SwapBuffers()
00068 {
00069    // flip the geometry buffers
00070    if ( CurVertexBuf == &VertexBuf0 ) CurVertexBuf = &VertexBuf1;
00071    else CurVertexBuf = &VertexBuf0;
00072    CurVertexBuf->Reset();
00073    if ( CurNormalBuf == &NormalBuf0 ) CurNormalBuf = &NormalBuf1;
00074    else CurNormalBuf = &NormalBuf0;
00075    CurNormalBuf->Reset();
00076    if ( CurTexCoordBuf == &TexCoordBuf0 ) CurTexCoordBuf = &TexCoordBuf1;
00077    else CurTexCoordBuf = &TexCoordBuf0;
00078    CurTexCoordBuf->Reset();
00079    if ( CurColorBuf == &ColorBuf0 ) CurColorBuf = &ColorBuf1;
00080    else CurColorBuf = &ColorBuf0;
00081    CurColorBuf->Reset();
00082 
00083    // free memory that was waiting til end of frame
00084    FreeWaitingBuffers();
00085 }
00086 
00087 void
00088 CImmGeomManager::FreeWaitingBuffers()
00089 {
00090    CurBuffer = 1 - CurBuffer;
00091 
00092    for ( int i = 0; i < NumBuffersToBeFreed[CurBuffer]; i++ )
00093       free( BuffersToBeFreed[CurBuffer][i] );
00094    NumBuffersToBeFreed[CurBuffer] = 0;
00095 }
00096 
00097 /********************************************
00098  * let's get ready to render!
00099  */
00100 
00101 void
00102 CImmGeomManager::BeginDListDef()
00103 {
00104 }
00105 
00106 void
00107 CImmGeomManager::BeginGeom( GLenum mode )
00108 {
00109    if ( Vu1Prim != mode ) VsmMananger.PrimChanged(mode);
00110 
00111    Geometry.SetPrimType( mode );
00112    Geometry.SetNormals( CurNormalBuf->GetNextPtr() );
00113    Geometry.SetVertices( CurVertexBuf->GetNextPtr() );
00114    Geometry.SetTexCoords( CurTexCoordBuf->GetNextPtr() );
00115    Geometry.SetColors( CurColorBuf->GetNextPtr() );
00116 
00117    InsideBeginEnd = true;
00118 }
00119 
00120 void
00121 CImmGeomManager::Vertex( cpu_vec_xyzw newVert )
00122 {
00123    cpu_vec_xyz normal = GetCurNormal();
00124    *CurNormalBuf += normal;
00125 
00126    const float *texCoord = GetCurTexCoord();
00127    *CurTexCoordBuf += texCoord[0];
00128    *CurTexCoordBuf += texCoord[1];
00129 
00130    *CurVertexBuf += newVert;
00131 
00132    Geometry.AddVertices();
00133    Geometry.AddNormals();
00134    Geometry.AddTexCoords();
00135 }
00136 
00137 void
00138 CImmGeomManager::Normal( cpu_vec_xyz normal )
00139 {
00140    if ( DoNormalize ) normal.normalize();
00141    CurNormal = normal;
00142 }
00143 
00144 void
00145 CImmGeomManager::Color( cpu_vec_xyzw color )
00146 {
00147    if ( InsideBeginEnd ) {
00148       *CurColorBuf += color;
00149       Geometry.AddColors();
00150    }
00151    else {
00152       GLContext.GetMaterialManager().Color( color );
00153    }
00154 }
00155 
00156 void
00157 CImmGeomManager::TexCoord( float u, float v )
00158 {
00159    CurTexCoord[0] = u; CurTexCoord[1] = v;
00160 }
00161 
00162 void
00163 CImmGeomManager::DrawBlock( CGeometryBlock &block )
00164 {
00165    CVifSCDmaPacket &packet = GLContext.GetVif1Packet();;
00166    // don't resend vu1 context here!
00167    VsmMananger.DrawArrays( packet, *this, block );
00168 }
00169 
00170 void
00171 CImmGeomManager::CommitNewGeom()
00172 {
00173    bool doReset = true;
00174 
00175    bool vsmChanged = VsmMananger.SyncVu1Renderer();
00176    if ( Geometry.IsPending() ) {
00177       // if the context hasn't changed, try to merge the new geometry
00178       // into the current block
00179       if ( GLContext.GetVu1ContextChanged() == 0
00180            && GLContext.GetGsContextChanged() == 0
00181            && ! vsmChanged
00182            && Geometry.MergeNew() )
00183          doReset = false;
00184       // couldn't merge; draw the old geometry so we can reset and start a new block
00185       else
00186          DrawBlock( Geometry );
00187    }
00188 
00189    if ( doReset ) {
00190       Geometry.MakeNewValuesCurrent();
00191       Geometry.ResetNew(); // if we don't do this counts will keep accumulating
00192 
00193       if ( vsmChanged ) {
00194          VsmMananger.XferVu1Renderer(GLContext.GetVif1Packet());
00195          // SetVu1ContextChanged(true);
00196       }
00197       SyncVu1Context(Geometry.GetPrimType());
00198       SyncGsContext();
00199    }
00200 }
00201 
00202 void
00203 CImmGeomManager::EndGeom()
00204 {
00205    InsideBeginEnd = false;
00206 
00207    Geometry.SetVerticesAreValid(true);
00208    Geometry.SetNormalsAreValid(true);
00209    Geometry.SetTexCoordsAreValid(true);
00210 
00211    // check colors
00212    Geometry.SetColorsAreValid(false);
00213    if ( Geometry.GetNumNewColors() > 0 ) {
00214       mErrorIf( Geometry.GetNumNewVertices() != Geometry.GetNumNewColors(),
00215                 "Sorry, but inside glBegin/glEnd you need "
00216                 "to specify either one color for each vertex given, or none." );
00217       Geometry.SetColorsAreValid(true);
00218 
00219       SyncColorMaterial(true);
00220    }
00221    else {
00222       SyncColorMaterial(false);
00223    }
00224 
00225    Geometry.SetWordsPerVertex(4);
00226    Geometry.SetWordsPerNormal(3);
00227    Geometry.SetWordsPerTexCoord(2);
00228    Geometry.SetWordsPerColor(4);
00229 
00230    CommitNewGeom();
00231 }
00232 
00233 void
00234 CImmGeomManager::SyncVu1Renderer()
00235 {
00236    if ( VsmMananger.SyncVu1Renderer() )
00237       VsmMananger.XferVu1Renderer( GLContext.GetVif1Packet() );
00238 }
00239 
00240 void
00241 CImmGeomManager::SyncVu1Context( GLenum primType )
00242 {
00243    // resend the rendering context if necessary
00244    if ( tU32 changed = GLContext.GetVu1ContextChanged() ) {
00245       VsmMananger.TransferSetupInfo( GLContext.GetVif1Packet(), *this, primType );
00246 
00247       GLContext.SetVu1ContextChanged(false);
00248       Vu1Prim = primType;
00249    }
00250 }
00251 
00252 void
00253 CImmGeomManager::SyncGsContext()
00254 {
00255    if ( tU32 changed = GLContext.GetGsContextChanged() ) {
00256       // has the texture changed?
00257       bool texEnabled = GLContext.GetTexManager().GetTexEnabled();
00258       CVifSCDmaPacket &packet = GLContext.GetVif1Packet();
00259       if ( texEnabled
00260            && changed & GsCtxtFlags::Texture ) {
00261          // we have to wait for all previous buffers to finish, or
00262          // the new texture settings might beat the geometry to the gs..
00263          packet.Cnt();
00264          packet.Flush().Nop();
00265          packet.CloseTag();
00266          GLContext.GetTexManager().UseCurTexture( GLContext.GetVif1Packet() );
00267       }
00268 
00269       // has the draw environment changed?
00270       if ( changed & GsCtxtFlags::DrawEnv ) {
00271          // as with textures..
00272          packet.Cnt();
00273          packet.Flush().Nop();
00274          packet.CloseTag();
00275          // FIXME
00276          GLContext.GetImmDrawContext().GetDrawEnv().SendSettings( GLContext.GetVif1Packet() );
00277       }
00278 
00279       GLContext.SetGsContextChanged(false);
00280    }
00281 }
00282 
00283 void
00284 CImmGeomManager::SyncColorMaterial( bool pvColorsArePresent )
00285 {
00286    CMaterialManager &mm = GLContext.GetMaterialManager();
00287    if ( pvColorsArePresent && mm.GetColorMaterialEnabled() ) {
00288       switch ( mm.GetColorMaterialMode() ) {
00289          case GL_EMISSION:
00290             mNotImplemented( "Only GL_DIFFUSE can change per-vertex" );
00291             break;
00292          case GL_AMBIENT:
00293             mNotImplemented( "Only GL_DIFFUSE can change per-vertex" );
00294             break;
00295          case GL_DIFFUSE:
00296             // fix later..
00297             // GLContext.PerVtxMaterialChanged();
00298             VsmMananger.PerVtxMaterialChanged( Vu1RendererProps::kDiffuse );
00299             break;
00300          case GL_AMBIENT_AND_DIFFUSE:
00301             mNotImplemented( "Only GL_DIFFUSE can change per-vertex" );
00302             break;
00303          case GL_SPECULAR:
00304             mNotImplemented( "Only GL_DIFFUSE can change per-vertex" );
00305             // PerVtxMaterialChanged( PerVtxMaterial::kSpecular );
00306             break;
00307       }
00308    }
00309    else {
00310       VsmMananger.PerVtxMaterialChanged( Vu1RendererProps::kNone );
00311    }
00312 }
00313 
00314 void
00315 CImmGeomManager::Flush()
00316 {
00317    if ( Geometry.IsPending() ) {
00318       DrawBlock( Geometry );
00319       Geometry.Reset();
00320    }
00321 }
00322 
00323 void
00324 CImmGeomManager::DrawArrays( GLenum mode, int first, int count )
00325 {
00326    if ( Vu1Prim != mode ) VsmMananger.PrimChanged(mode);
00327 
00328    Geometry.SetPrimType(mode);
00329 
00330    Geometry.SetVertices( VertArray->GetVertices() );
00331    Geometry.SetNormals( VertArray->GetNormals() );
00332    Geometry.SetTexCoords( VertArray->GetTexCoords() );
00333    Geometry.SetColors( VertArray->GetColors() );
00334 
00335    Geometry.SetVerticesAreValid( VertArray->GetVerticesAreValid() );
00336    Geometry.SetNormalsAreValid( VertArray->GetNormalsAreValid() );
00337    Geometry.SetTexCoordsAreValid( VertArray->GetTexCoordsAreValid() );
00338    Geometry.SetColorsAreValid( VertArray->GetColorsAreValid() );
00339 
00340    Geometry.SetWordsPerVertex( VertArray->GetWordsPerVertex() );
00341    Geometry.SetWordsPerNormal( VertArray->GetWordsPerNormal() );
00342    Geometry.SetWordsPerTexCoord( VertArray->GetWordsPerTexCoord() );
00343    Geometry.SetWordsPerColor( VertArray->GetWordsPerColor() );
00344 
00345    Geometry.AddVertices(count);
00346    Geometry.AddNormals(count);
00347    Geometry.AddTexCoords(count);
00348    Geometry.AddColors(count);
00349 
00350    Geometry.AdjustNewGeomPtrs( first );
00351 
00352    // do this before sync'ing the vu1 renderer in CommitNewGeom
00353    SyncColorMaterial(VertArray->GetColors() != NULL);
00354 
00355    CommitNewGeom();
00356 }
00357 

ps2gl version 0.2