00001
00002
00003
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
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
00048
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
00065 CurFrameMem = Frame0Mem;
00066 LastFrameMem = Frame1Mem;
00067
00068 int width = frame0Mem->GetWidth(), height = frame0Mem->GetHeight();
00069
00070
00071
00072
00073 GSScale.set_scale( cpu_vec_xyz(width/2.0f, -1 * height/2.0f, -1 * 8388607.5f) );
00074 SetVertexXformValid(false);
00075
00076
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
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
00106 if ( FrameIsDblBuffered ) {
00107 GS::CMemArea* temp = CurFrameMem;
00108 CurFrameMem = LastFrameMem;
00109 LastFrameMem = temp;
00110
00111
00112
00113 DrawEnv->CalculateClippedFBXYOffsets( ! fieldIsEven );
00114
00115
00116 ClearEnv->SetFrameBufAddr( CurFrameMem->GetWordAddr() );
00117
00118
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
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
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
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
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