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

drawcontext.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 "ps2s/drawenv.h"
00006 
00007 #include "GL/ps2gl.h"
00008 
00009 #include "ps2gl/debug.h"
00010 #include "ps2gl/dlist.h"
00011 #include "ps2gl/immgmanager.h"
00012 #include "ps2gl/dlgmanager.h"
00013 #include "ps2gl/drawcontext.h"
00014 #include "ps2gl/clear.h"
00015 #include "ps2gl/matrix.h"
00016 
00017 /********************************************
00018  * CImmDrawContext methods
00019  */
00020 
00021 CImmDrawContext::CImmDrawContext( CGLContext &context )
00022    : CDrawContext(context),
00023      DrawEnv(NULL),
00024      ClearEnv(NULL),
00025      FrameIsDblBuffered(false),
00026      DoSmoothShading(true),
00027      DoCullFace(false),
00028      CullFaceDir(1),
00029      RescaleNormals(false),
00030      BlendIsEnabled(false),
00031      AlphaTestIsEnabled(false),
00032      IsVertexXformValid(false)
00033 {
00034    GSScale.set_identity();
00035 
00036    ClearEnv = new CClearEnv;
00037 
00038    DrawEnv = new GS::CDrawEnv( GS::kContext1 );
00039    DrawEnv->SetDepthTestPassMode( GS::ZTest::kGEqual );
00040    using namespace GS::ABlend;
00041    DrawEnv->SetAlphaBlendFunc( kSourceRGB, kDestRGB, kSourceAlpha, kDestRGB, 0x80 );
00042    DrawEnv->SetFogColor( 255, 255, 255 );
00043 }
00044 
00045 CImmDrawContext::~CImmDrawContext()
00046 {
00047    // don't delete the frame mem areas -- they are created/destroyed by
00048    // the app
00049 
00050    delete ClearEnv;
00051    delete DrawEnv;
00052 }
00053 
00054 void
00055 CImmDrawContext::SetDrawBuffers( GS::CMemArea *frame0Mem, GS::CMemArea *frame1Mem,
00056                                  GS::CMemArea *depthMem )
00057 {
00058    Frame0Mem = frame0Mem;
00059    Frame1Mem = frame1Mem;
00060    ZBufMem = depthMem;
00061 
00062    FrameIsDblBuffered = ( frame0Mem && frame1Mem );
00063 
00064    // see displaycontext for a comment on this..
00065    CurFrameMem = Frame0Mem;
00066    LastFrameMem = Frame1Mem;
00067 
00068    int width = frame0Mem->GetWidth(), height = frame0Mem->GetHeight();
00069 
00070    // projection xform
00071 
00072    // -1 here flips mapping to: far_clip -> -1, near_clip -> 1
00073    GSScale.set_scale( cpu_vec_xyz(width/2.0f, -1 * height/2.0f, -1 * 8388607.5f) );
00074    SetVertexXformValid(false);
00075 
00076    // clear environment
00077 
00078    ClearEnv->SetDimensions( width, height );
00079    ClearEnv->SetFrameBufAddr( frame0Mem->GetWordAddr() );
00080    ClearEnv->SetFrameBufPsm( frame0Mem->GetPixFormat() );
00081    if ( ZBufMem ) {
00082       ClearEnv->SetDepthBufAddr( ZBufMem->GetWordAddr() );
00083       ClearEnv->SetDepthBufPsm( ZBufMem->GetPixFormat() );
00084    }
00085 
00086    // draw environment
00087 
00088    DrawEnv->SetFrameBufferAddr( CurFrameMem->GetWordAddr() );
00089    DrawEnv->SetFrameBufferDim( width, height );
00090    DrawEnv->CalculateClippedFBXYOffsets( GS::kDontAddHalfPixel );
00091    if ( ZBufMem ) {
00092       DrawEnv->EnableDepthTest();
00093       DrawEnv->SetDepthBufferAddr( ZBufMem->GetWordAddr() );
00094       DrawEnv->SetDepthBufferPSM( ZBufMem->GetPixFormat() );
00095    }
00096    else
00097       DrawEnv->DisableDepthTest();
00098 
00099    GLContext.DrawBufferChanged();
00100 }
00101 
00102 void
00103 CImmDrawContext::SwapBuffers( bool fieldIsEven )
00104 {
00105    // flip frame buffer ptrs
00106    if ( FrameIsDblBuffered ) {
00107       GS::CMemArea* temp = CurFrameMem;
00108       CurFrameMem = LastFrameMem;
00109       LastFrameMem = temp;
00110 
00111       // add a half-pixel offset if the frame we're going to build on the core will
00112       // be displayed in an odd field
00113       DrawEnv->CalculateClippedFBXYOffsets( ! fieldIsEven );
00114 
00115       // clear the new frame
00116       ClearEnv->SetFrameBufAddr( CurFrameMem->GetWordAddr() );
00117 
00118       // draw to the new frame
00119       CVifSCDmaPacket &packet = GLContext.GetVif1Packet();
00120       DrawEnv->SetFrameBufferAddr( CurFrameMem->GetWordAddr() );
00121       DrawEnv->SendSettings( packet );
00122    }
00123 }
00124 
00125 const cpu_mat_44&
00126 CImmDrawContext::GetVertexXform()
00127 {
00128    if ( ! IsVertexXformValid ) {
00129       IsVertexXformValid = true;
00130       VertexXform = (GLContext.GetProjectionStack().GetTop()
00131                      * GLContext.GetModelViewStack().GetTop());
00132       VertexXform = GSScale * VertexXform;
00133    }
00134    return VertexXform;
00135 }
00136 
00137 void
00138 CImmDrawContext::SetDoSmoothShading( bool yesNo )
00139 {
00140    if ( DoSmoothShading != yesNo ) {
00141       DoSmoothShading = yesNo;
00142       GLContext.ShadingChanged();
00143    }
00144 }
00145 
00146 void
00147 CImmDrawContext::SetDoCullFace( bool cull )
00148 {
00149    if ( DoCullFace != cull ) {
00150       DoCullFace = cull;
00151       GLContext.CullFaceEnabledChanged();
00152       GLContext.GetImmGeomManager().GetVsmManager().CullFaceEnabledChanged(cull);
00153    }
00154 }
00155          
00156 void
00157 CImmDrawContext::SetCullFaceDir( int direction )
00158 {
00159    if ( CullFaceDir != direction ) {
00160       CullFaceDir = direction;
00161       GLContext.CullFaceDirChanged();
00162    }
00163 }
00164 
00165 void
00166 CImmDrawContext::SetBlendEnabled( bool enabled )
00167 {
00168    if ( BlendIsEnabled != enabled ) {
00169       BlendIsEnabled = enabled;
00170       GLContext.BlendEnabledChanged();
00171    }
00172 }
00173       
00174 void
00175 CImmDrawContext::SetRescaleNormals( bool rescale )
00176 {
00177    if ( RescaleNormals != rescale ) {
00178       RescaleNormals = rescale;
00179       GLContext.LightPropChanged();
00180    }
00181 }
00182 
00183 void
00184 CImmDrawContext::SetDepthWriteEnabled( bool enabled )
00185 {
00186    DrawEnv->SetDepthWriteEnabled(enabled);
00187    GLContext.DepthWriteEnabledChanged();
00188 }
00189 
00190 void 
00191 CImmDrawContext::SetAlphaTestEnabled( bool enabled ) 
00192 {
00193    if ( AlphaTestIsEnabled != enabled ) {
00194       AlphaTestIsEnabled = enabled;
00195 
00196       if (enabled) {
00197           DrawEnv->EnableAlphaTest();
00198       } else {
00199           DrawEnv->DisableAlphaTest();
00200       }
00201 
00202       GLContext.AlphaTestEnabledChanged();
00203    }
00204 }
00205 
00206 // I hate to do it, but...
00207 #define mCombineBlendFactors( _src, _dest )             \
00208    ((unsigned int)(_src) << 16) | (unsigned int)(_dest)
00209 
00210 void
00211 CImmDrawContext::SetBlendMode( GLenum source, GLenum dest )
00212 {
00213    unsigned int blendFactor = mCombineBlendFactors(source, dest);
00214 
00215    switch (blendFactor) {
00216       case mCombineBlendFactors( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ):
00217          using namespace GS::ABlend;
00218          DrawEnv->SetAlphaBlendFunc( kSourceRGB, kDestRGB, kSourceAlpha, kDestRGB, 0x80 );
00219          GLContext.BlendModeChanged();
00220          break;
00221       default:
00222          mNotImplemented( "alpha blending mode: source = %d, dest = %d", source, dest );
00223    }
00224 }
00225 
00226 #undef mCombineBlendFactors
00227 
00228 void 
00229 CImmDrawContext::SetAlphaFunc( GLenum func, GLclampf ref )
00230 {
00231    GS::tAlphaTestPassMode ePassMode;
00232        
00233    switch(func) {
00234       case GL_NEVER:
00235          ePassMode = GS::ATest::kNever;
00236          break;
00237 
00238       case GL_LESS:
00239          ePassMode = GS::ATest::kLess;
00240          break;
00241 
00242       case GL_EQUAL:
00243          ePassMode = GS::ATest::kEqual;
00244          break;
00245 
00246       case GL_LEQUAL:
00247          ePassMode = GS::ATest::kLEqual;
00248          break;
00249 
00250       case GL_GREATER:
00251          ePassMode = GS::ATest::kGreater;
00252          break;
00253 
00254       case GL_NOTEQUAL:
00255          ePassMode = GS::ATest::kNotEqual;
00256          break;
00257 
00258       case GL_GEQUAL:
00259          ePassMode = GS::ATest::kGEqual;
00260          break;
00261 
00262       case GL_ALWAYS:
00263          ePassMode = GS::ATest::kAlways;
00264          break;
00265 
00266       default:
00267          mError("Unknown alpha test function");
00268          return;
00269    }
00270 
00271    DrawEnv->SetAlphaRefVal(ref * 0x80);
00272    DrawEnv->SetAlphaTestPassMode(ePassMode);
00273    DrawEnv->SetAlphaTestFailAction(GS::ATest::kKeep);
00274 
00275    GLContext.AlphaTestFuncChanged();
00276 }
00277 
00278 /********************************************
00279  * CDListDrawContext methods
00280  */
00281 
00282 class CSetDrawBuffers : public CDListCmd {
00283       GS::CMemArea      *Frame0, *Frame1, *Depth;
00284    public:
00285       CSetDrawBuffers( GS::CMemArea *frame0, GS::CMemArea *frame1, GS::CMemArea *depth )
00286          : Frame0(frame0), Frame1(frame1), Depth(depth) {}
00287       CDListCmd* Play() {
00288          pGLContext->GetImmDrawContext().SetDrawBuffers( Frame0, Frame1, Depth );
00289          return CDListCmd::GetNextCmd(this);
00290       }
00291 };
00292 
00293 void
00294 CDListDrawContext::SetDrawBuffers( GS::CMemArea *frame0Mem, GS::CMemArea *frame1Mem,
00295                                  GS::CMemArea *depthMem )
00296 {
00297    GLContext.GetDListGeomManager().Flush();
00298 
00299    GLContext.GetDListManager().GetOpenDList() += CSetDrawBuffers(frame0Mem, frame1Mem, depthMem);
00300    GLContext.DrawBufferChanged();
00301 }
00302 
00303 class CSetDoSmoothShadingCmd : public CDListCmd {
00304       bool      DoSS;
00305    public:
00306       CSetDoSmoothShadingCmd( bool yesNo ) : DoSS(yesNo) {}
00307       CDListCmd* Play() {
00308          pGLContext->GetImmDrawContext().SetDoSmoothShading( DoSS );
00309          return CDListCmd::GetNextCmd( this );
00310       }
00311 };
00312 
00313 void
00314 CDListDrawContext::SetDoSmoothShading( bool yesNo )
00315 {
00316    GLContext.GetDListGeomManager().Flush();
00317 
00318    GLContext.GetDListManager().GetOpenDList() += CSetDoSmoothShadingCmd( yesNo );
00319    GLContext.ShadingChanged();
00320 }
00321 
00322 class CSetDoCullFaceCmd : public CDListCmd {
00323       bool      DoCull;
00324    public:
00325       CSetDoCullFaceCmd(bool cull) : DoCull(cull) {}
00326       CDListCmd* Play() {
00327          pGLContext->GetImmDrawContext().SetDoCullFace(DoCull);
00328          return CDListCmd::GetNextCmd(this);
00329       }
00330 };
00331 
00332 void
00333 CDListDrawContext::SetDoCullFace( bool cull )
00334 {
00335    GLContext.GetDListGeomManager().Flush();
00336 
00337    GLContext.GetDListManager().GetOpenDList() += CSetDoCullFaceCmd(cull);
00338    GLContext.CullFaceEnabledChanged();
00339 }
00340 
00341 class CSetCullFaceDir : public CDListCmd {
00342       int       CullDir;
00343    public:
00344       CSetCullFaceDir(int dir) : CullDir(dir) {}
00345       CDListCmd* Play() {
00346          pGLContext->GetImmDrawContext().SetCullFaceDir(CullDir);
00347          return CDListCmd::GetNextCmd(this);
00348       }
00349 };
00350 
00351 void
00352 CDListDrawContext::SetCullFaceDir( int direction )
00353 {
00354    GLContext.GetDListGeomManager().Flush();
00355 
00356    GLContext.GetDListManager().GetOpenDList() += CSetCullFaceDir(direction);
00357    GLContext.CullFaceDirChanged();
00358 }
00359 
00360 class CSetBlendEnabledCmd : public CDListCmd {
00361       bool      Enabled;
00362    public:
00363       CSetBlendEnabledCmd( bool enabled ) : Enabled(enabled) {}
00364       CDListCmd* Play() {
00365          pGLContext->GetImmDrawContext().SetBlendEnabled(Enabled);
00366          return CDListCmd::GetNextCmd(this);
00367       }
00368 };
00369 
00370 void
00371 CDListDrawContext::SetBlendEnabled( bool enabled )
00372 {
00373    GLContext.GetDListGeomManager().Flush();
00374 
00375    GLContext.GetDListManager().GetOpenDList() += CSetBlendEnabledCmd(enabled);
00376    GLContext.BlendEnabledChanged();
00377 }
00378 
00379 class CSetAlphaTestEnabledCmd : public CDListCmd {
00380       bool      Enabled;
00381    public:
00382       CSetAlphaTestEnabledCmd( bool enabled ) : Enabled(enabled) {}
00383       CDListCmd* Play() {
00384          pGLContext->GetImmDrawContext().SetAlphaTestEnabled(Enabled);
00385          return CDListCmd::GetNextCmd(this);
00386       }
00387 };
00388 
00389 void
00390 CDListDrawContext::SetAlphaTestEnabled( bool enabled )
00391 {
00392    GLContext.GetDListGeomManager().Flush();
00393 
00394    GLContext.GetDListManager().GetOpenDList() += CSetAlphaTestEnabledCmd(enabled);
00395    GLContext.AlphaTestEnabledChanged();
00396 }
00397 
00398 class CSetAlphaFuncCmd : public CDListCmd {
00399     GLenum   Func;
00400     GLclampf Ref;
00401 public:
00402     CSetAlphaFuncCmd( GLenum func, GLclampf ref ) : Func(func), Ref(ref) {}
00403     CDListCmd* Play() {
00404         pGLContext->GetImmDrawContext().SetAlphaFunc(Func, Ref);
00405         return CDListCmd::GetNextCmd(this);
00406     }
00407 };
00408 
00409 void 
00410 CDListDrawContext::SetAlphaFunc( GLenum func, GLclampf ref )
00411 {
00412     GLContext.GetDListGeomManager().Flush();
00413     
00414     GLContext.GetDListManager().GetOpenDList() += CSetAlphaFuncCmd(func, ref);
00415     GLContext.AlphaTestFuncChanged();
00416 }
00417 
00418 class CSetRescaleNormalsCmd : public CDListCmd {
00419       bool      Rescale;
00420    public:
00421       CSetRescaleNormalsCmd( bool rescale ) : Rescale(rescale) {}
00422       CDListCmd* Play() {
00423          pGLContext->GetDrawContext().SetRescaleNormals(Rescale);
00424          return CDListCmd::GetNextCmd(this);
00425       }
00426 };
00427 
00428 void
00429 CDListDrawContext::SetRescaleNormals( bool rescale )
00430 {
00431    GLContext.GetDListGeomManager().Flush();
00432 
00433    GLContext.GetDListManager().GetOpenDList() += CSetRescaleNormalsCmd(rescale);
00434    GLContext.LightPropChanged();
00435 }
00436 
00437 class CSetBlendMode : public CDListCmd {
00438       GLenum    Source, Dest;
00439    public:
00440       CSetBlendMode( GLenum s, GLenum d ) : Source(s), Dest(d) {}
00441       CDListCmd* Play() {
00442          pGLContext->GetImmDrawContext().SetBlendMode( Source, Dest );
00443          return CDListCmd::GetNextCmd(this);
00444       }
00445 };
00446 
00447 void
00448 CDListDrawContext::SetBlendMode( GLenum source, GLenum dest )
00449 {
00450    GLContext.GetDListGeomManager().Flush();
00451 
00452    GLContext.GetDListManager().GetOpenDList() += CSetBlendMode(source, dest);
00453    GLContext.BlendModeChanged();
00454 }
00455 
00456 class CSetDepthWriteEnabledCmd : public CDListCmd {
00457       bool      Enabled;
00458    public:
00459       CSetDepthWriteEnabledCmd( bool enabled ) : Enabled(enabled) {}
00460       CDListCmd* Play() {
00461          pGLContext->GetImmDrawContext().SetDepthWriteEnabled(Enabled);
00462          return CDListCmd::GetNextCmd(this);
00463       }
00464 };
00465 
00466 void
00467 CDListDrawContext::SetDepthWriteEnabled( bool enabled )
00468 {
00469    GLContext.GetDListGeomManager().Flush();
00470 
00471    GLContext.GetDListManager().GetOpenDList() += CSetDepthWriteEnabledCmd(enabled);
00472    GLContext.DepthWriteEnabledChanged();
00473 }
00474 
00475 /********************************************
00476  * gl api
00477  */
00478 
00479 void glDepthFunc( GLenum func )
00480 {
00481    mNotImplemented( );
00482 }
00483 
00484 void glDrawBuffer( GLenum mode )
00485 {
00486    mNotImplemented( );
00487 }
00488 
00489 void glClipPlane( GLenum plane, const GLdouble *equation )
00490 {
00491    mNotImplemented( );
00492 }
00493 
00494 void glBlendFunc( GLenum sfactor, GLenum dfactor )
00495 {
00496    pGLContext->GetDrawContext().SetBlendMode( sfactor, dfactor );
00497 }
00498 
00499 void glAlphaFunc( GLenum func, GLclampf ref )
00500 {
00501    pGLContext->GetDrawContext().SetAlphaFunc( func, ref );
00502 }
00503 
00504 void glShadeModel( GLenum mode )
00505 {
00506    CImmDrawContext &drawContext = pGLContext->GetImmDrawContext();
00507    drawContext.SetDoSmoothShading( (mode == GL_FLAT) ? false : true );
00508 }
00509 
00510 void glCullFace( GLenum mode )
00511 {
00512    mWarnIf( mode == GL_FRONT_AND_BACK, "GL_FRONT_AND_BACK culling is not supported" );
00513    CImmDrawContext &drawContext = pGLContext->GetImmDrawContext();
00514    drawContext.SetCullFaceDir( (mode == GL_FRONT) ? 1 : -1 );
00515 }
00516 
00517 void glDepthMask( GLboolean enabled )
00518 {
00519    CImmDrawContext &drawContext = pGLContext->GetImmDrawContext();
00520    drawContext.SetDepthWriteEnabled(enabled);
00521 }
00522 
00523 /********************************************
00524  * ps2gl api
00525  */
00526 
00539 void
00540 pglSetDrawBuffers( pgl_area_handle_t frame0_mem, pgl_area_handle_t frame1_mem,
00541                    pgl_area_handle_t depth_mem )
00542 {
00543    pGLContext->GetDrawContext().SetDrawBuffers( reinterpret_cast<GS::CMemArea*>(frame0_mem),
00544                                                 reinterpret_cast<GS::CMemArea*>(frame1_mem),
00545                                                 reinterpret_cast<GS::CMemArea*>(depth_mem) );
00546 }
00547  // pgl_api

ps2gl version 0.2