7#include "ps2s/drawenv.h"
11#include "ps2gl/clear.h"
12#include "ps2gl/debug.h"
13#include "ps2gl/dlgmanager.h"
14#include "ps2gl/dlist.h"
15#include "ps2gl/drawcontext.h"
16#include "ps2gl/immgmanager.h"
17#include "ps2gl/matrix.h"
23CImmDrawContext::CImmDrawContext(
CGLContext& context)
27 , FrameIsDblBuffered(false)
28 , DoSmoothShading(true)
32 , RescaleNormals(false)
33 , BlendIsEnabled(false)
34 , AlphaTestIsEnabled(false)
35 , DepthTestIsEnabled(false)
36 , DrawInterlaced(true)
38 , IsVertexXformValid(false)
42 GSScale.set_identity();
46 DrawEnv =
new GS::CDrawEnv(GS::kContext1);
47 DrawEnv->SetDepthTestPassMode(GS::ZTest::kGEqual);
48 using namespace GS::ABlend;
49 DrawEnv->SetAlphaBlendFunc(kSourceRGB, kDestRGB, kSourceAlpha, kDestRGB, 0x80);
50 DrawEnv->SetFogColor(255, 255, 255);
53 DrawEnv->DisableAlphaTest();
54 DrawEnv->SetAlphaRefVal(0);
55 DrawEnv->SetAlphaTestPassMode(GS::ATest::kAlways);
58CImmDrawContext::~CImmDrawContext()
67void CImmDrawContext::SetDrawBuffers(
bool interlaced,
68 GS::CMemArea* frame0Mem, GS::CMemArea* frame1Mem,
69 GS::CMemArea* depthMem)
71 Frame0Mem = frame0Mem;
72 Frame1Mem = frame1Mem;
75 DrawInterlaced = interlaced;
76 FrameIsDblBuffered = (frame0Mem && frame1Mem);
79 CurFrameMem = Frame0Mem;
80 LastFrameMem = Frame1Mem;
82 int width = frame0Mem->GetWidth(), height = frame0Mem->GetHeight();
88 int depthPsm = GS::kPsmz24;
90 depthPsm = depthMem->GetPixFormat();
92 if (depthPsm == GS::kPsmz24)
94 else if (depthPsm == GS::kPsmz32)
96 else if (depthPsm == GS::kPsmz16)
99 mError(
"Unknown depth buffer format");
101 int maxDepthValue = (1 << DepthBits) - 1;
106 GSScale.set_scale(cpu_vec_xyz(width / 2.0f, -1 * height / 2.0f, -1 * (
float)maxDepthValue / 2.0f));
107 SetVertexXformValid(
false);
111 ClearEnv->SetDimensions(width, height);
112 ClearEnv->SetFrameBufAddr(frame0Mem->GetWordAddr());
113 ClearEnv->SetFrameBufPsm(frame0Mem->GetPixFormat());
115 ClearEnv->SetDepthBufAddr(ZBufMem->GetWordAddr());
116 ClearEnv->SetDepthBufPsm(ZBufMem->GetPixFormat());
121 DrawEnv->SetFrameBufferAddr(CurFrameMem->GetWordAddr());
122 DrawEnv->SetFrameBufferDim(width, height);
123 DrawEnv->CalculateClippedFBXYOffsets(GS::kDontAddHalfPixel);
124 DrawEnv->SetFrameBufferPSM(frame0Mem->GetPixFormat());
129 DrawEnv->EnableDepthTest();
130 DrawEnv->SetDepthBufferAddr(ZBufMem->GetWordAddr());
131 DrawEnv->SetDepthBufferPSM(ZBufMem->GetPixFormat());
133 DrawEnv->DisableDepthTest();
135 GLContext.DrawBufferChanged();
138void CImmDrawContext::SwapBuffers(
bool fieldIsEven)
141 if (FrameIsDblBuffered) {
142 GS::CMemArea* temp = CurFrameMem;
143 CurFrameMem = LastFrameMem;
147 ClearEnv->SetFrameBufAddr(CurFrameMem->GetWordAddr());
150 DrawEnv->SetFrameBufferAddr(CurFrameMem->GetWordAddr());
152 GLContext.DrawEnvChanged();
155 if (DrawInterlaced) {
158 DrawEnv->CalculateClippedFBXYOffsets(!fieldIsEven);
160 GLContext.DrawEnvChanged();
165CImmDrawContext::GetVertexXform()
167 if (!IsVertexXformValid) {
168 IsVertexXformValid =
true;
169 VertexXform = (GLContext.GetProjectionStack().GetTop()
170 * GLContext.GetModelViewStack().GetTop());
171 VertexXform = GSScale * VertexXform;
177void CImmDrawContext::SetDoSmoothShading(
bool yesNo)
179 if (DoSmoothShading != yesNo) {
180 DoSmoothShading = yesNo;
181 GLContext.ShadingChanged();
185void CImmDrawContext::SetDoClipping(
bool clip)
187 if (DoClipping != clip) {
189 GLContext.ClippingEnabledChanged();
190 GLContext.GetImmGeomManager().GetRendererManager().ClippingEnabledChanged(clip);
194void CImmDrawContext::SetDoCullFace(
bool cull)
196 if (DoCullFace != cull) {
198 GLContext.CullFaceEnabledChanged();
199 GLContext.GetImmGeomManager().GetRendererManager().CullFaceEnabledChanged(cull);
203void CImmDrawContext::SetCullFaceDir(
int direction)
205 if (CullFaceDir != direction) {
206 CullFaceDir = direction;
207 GLContext.CullFaceDirChanged();
211void CImmDrawContext::SetBlendEnabled(
bool enabled)
213 if (BlendIsEnabled != enabled) {
214 BlendIsEnabled = enabled;
215 GLContext.BlendEnabledChanged();
219void CImmDrawContext::SetRescaleNormals(
bool rescale)
221 if (RescaleNormals != rescale) {
222 RescaleNormals = rescale;
223 GLContext.LightPropChanged();
227void CImmDrawContext::SetDepthWriteEnabled(
bool enabled)
229 DrawEnv->SetDepthWriteEnabled(enabled);
230 GLContext.DepthWriteEnabledChanged();
233void CImmDrawContext::SetFrameBufferDrawMask(
unsigned int mask)
235 DrawEnv->SetFrameBufferDrawMask(mask);
236 GLContext.FrameBufferDrawMaskChanged();
239void CImmDrawContext::SetPolygonMode(GLenum mode)
241 if (PolyMode != mode) {
243 GLContext.PolyModeChanged();
247void CImmDrawContext::SetAlphaTestEnabled(
bool enabled)
249 if (AlphaTestIsEnabled != enabled) {
250 AlphaTestIsEnabled = enabled;
253 DrawEnv->EnableAlphaTest();
255 DrawEnv->DisableAlphaTest();
258 GLContext.AlphaTestEnabledChanged();
262void CImmDrawContext::SetDepthTestEnabled(
bool enabled)
264 if (DepthTestIsEnabled != enabled) {
265 DepthTestIsEnabled = enabled;
268 DrawEnv->EnableDepthTest();
270 DrawEnv->DisableDepthTest();
273 GLContext.DepthTestEnabledChanged();
277void CImmDrawContext::SetInterlacingOffset(
float yPixels)
279 if (DrawEnv->GetInterlacedPixelOffset() != yPixels) {
280 DrawEnv->SetInterlacedPixelOffset(yPixels);
281 bool offset = (DrawInterlaced && GLContext.GetCurrentFieldIsEven());
282 DrawEnv->CalculateClippedFBXYOffsets(offset);
284 GLContext.DrawEnvChanged();
289#define mCombineBlendFactors(_src, _dest) \
290 ((unsigned int)(_src) << 16) | (unsigned int)(_dest)
292void CImmDrawContext::SetBlendMode(GLenum source, GLenum dest)
294 unsigned int blendFactor = mCombineBlendFactors(source, dest);
296 switch (blendFactor) {
297 case mCombineBlendFactors(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA):
298 using namespace GS::ABlend;
299 DrawEnv->SetAlphaBlendFunc(kSourceRGB, kDestRGB, kSourceAlpha, kDestRGB, 0x80);
300 GLContext.BlendModeChanged();
302 case mCombineBlendFactors(GL_SRC_ALPHA, GL_ONE):
303 DrawEnv->SetAlphaBlendFunc(kSourceRGB, kZero, kSourceAlpha, kDestRGB, 0x80);
304 GLContext.BlendModeChanged();
308 case mCombineBlendFactors(GL_ONE_MINUS_SRC_ALPHA, GL_ONE):
309 DrawEnv->SetAlphaBlendFunc(kZero, kSourceRGB, kSourceAlpha, kDestRGB, 0x80);
310 GLContext.BlendModeChanged();
313 mNotImplemented(
"alpha blending mode: source = %d, dest = %d", source, dest);
317#undef mCombineBlendFactors
319void CImmDrawContext::SetAlphaFunc(GLenum func, GLclampf ref)
321 GS::tAlphaTestPassMode ePassMode;
325 ePassMode = GS::ATest::kNever;
329 ePassMode = GS::ATest::kLess;
333 ePassMode = GS::ATest::kEqual;
337 ePassMode = GS::ATest::kLEqual;
341 ePassMode = GS::ATest::kGreater;
345 ePassMode = GS::ATest::kNotEqual;
349 ePassMode = GS::ATest::kGEqual;
353 ePassMode = GS::ATest::kAlways;
357 mError(
"Unknown alpha test function");
361 DrawEnv->SetAlphaRefVal((
unsigned int)(ref * 0xff));
362 DrawEnv->SetAlphaTestPassMode(ePassMode);
363 DrawEnv->SetAlphaTestFailAction(GS::ATest::kKeep);
365 GLContext.AlphaTestFuncChanged();
368void CImmDrawContext::SetDepthFunc(GLenum func)
378 GS::tZTestPassMode ePassMode;
382 ePassMode = GS::ZTest::kNever;
386 ePassMode = GS::ZTest::kGreater;
390 ePassMode = GS::ZTest::kGEqual;
394 ePassMode = GS::ZTest::kAlways;
402 mError(
"Unknown/unsupported depth test function");
406 DrawEnv->SetDepthTestPassMode(ePassMode);
408 GLContext.DepthTestFuncChanged();
416 GS::CMemArea *Frame0, *Frame1, *Depth;
420 CSetDrawBuffers(
bool inter, GS::CMemArea* frame0, GS::CMemArea* frame1, GS::CMemArea* depth)
429 pGLContext->GetImmDrawContext().SetDrawBuffers(Interlaced, Frame0, Frame1, Depth);
430 return CDListCmd::GetNextCmd(
this);
434void CDListDrawContext::SetDrawBuffers(
bool interlaced,
435 GS::CMemArea* frame0Mem, GS::CMemArea* frame1Mem,
436 GS::CMemArea* depthMem)
438 GLContext.GetDListGeomManager().Flush();
440 GLContext.GetDListManager().GetOpenDList() +=
CSetDrawBuffers(interlaced,
441 frame0Mem, frame1Mem,
443 GLContext.DrawBufferChanged();
456 pGLContext->GetImmDrawContext().SetDoSmoothShading(DoSS);
457 return CDListCmd::GetNextCmd(
this);
461void CDListDrawContext::SetDoSmoothShading(
bool yesNo)
463 GLContext.GetDListGeomManager().Flush();
466 GLContext.ShadingChanged();
479 pGLContext->GetImmDrawContext().SetDoClipping(DoClip);
480 return CDListCmd::GetNextCmd(
this);
484void CDListDrawContext::SetDoClipping(
bool clip)
486 GLContext.GetDListGeomManager().Flush();
489 GLContext.ClippingEnabledChanged();
502 pGLContext->GetImmDrawContext().SetDoCullFace(DoCull);
503 return CDListCmd::GetNextCmd(
this);
507void CDListDrawContext::SetDoCullFace(
bool cull)
509 GLContext.GetDListGeomManager().Flush();
512 GLContext.CullFaceEnabledChanged();
525 pGLContext->GetImmDrawContext().SetCullFaceDir(CullDir);
526 return CDListCmd::GetNextCmd(
this);
530void CDListDrawContext::SetCullFaceDir(
int direction)
532 GLContext.GetDListGeomManager().Flush();
534 GLContext.GetDListManager().GetOpenDList() +=
CSetCullFaceDir(direction);
535 GLContext.CullFaceDirChanged();
548 pGLContext->GetImmDrawContext().SetBlendEnabled(Enabled);
549 return CDListCmd::GetNextCmd(
this);
553void CDListDrawContext::SetBlendEnabled(
bool enabled)
555 GLContext.GetDListGeomManager().Flush();
558 GLContext.BlendEnabledChanged();
571 pGLContext->GetImmDrawContext().SetAlphaTestEnabled(Enabled);
572 return CDListCmd::GetNextCmd(
this);
576void CDListDrawContext::SetAlphaTestEnabled(
bool enabled)
578 GLContext.GetDListGeomManager().Flush();
581 GLContext.AlphaTestEnabledChanged();
594 pGLContext->GetImmDrawContext().SetDepthTestEnabled(Enabled);
595 return CDListCmd::GetNextCmd(
this);
599void CDListDrawContext::SetDepthTestEnabled(
bool enabled)
601 GLContext.GetDListGeomManager().Flush();
604 GLContext.DepthTestEnabledChanged();
617 pGLContext->GetImmDrawContext().SetInterlacingOffset(Offset);
618 return CDListCmd::GetNextCmd(
this);
622void CDListDrawContext::SetInterlacingOffset(
float yPixels)
624 GLContext.GetDListGeomManager().Flush();
627 GLContext.DrawEnvChanged();
642 pGLContext->GetImmDrawContext().SetAlphaFunc(Func, Ref);
643 return CDListCmd::GetNextCmd(
this);
647void CDListDrawContext::SetAlphaFunc(GLenum func, GLclampf ref)
649 GLContext.GetDListGeomManager().Flush();
652 GLContext.AlphaTestFuncChanged();
665 pGLContext->GetImmDrawContext().SetDepthFunc(Func);
666 return CDListCmd::GetNextCmd(
this);
670void CDListDrawContext::SetDepthFunc(GLenum func)
672 GLContext.GetDListGeomManager().Flush();
675 GLContext.DepthTestFuncChanged();
688 pGLContext->GetDrawContext().SetRescaleNormals(Rescale);
689 return CDListCmd::GetNextCmd(
this);
693void CDListDrawContext::SetRescaleNormals(
bool rescale)
695 GLContext.GetDListGeomManager().Flush();
698 GLContext.LightPropChanged();
712 pGLContext->GetImmDrawContext().SetBlendMode(Source, Dest);
713 return CDListCmd::GetNextCmd(
this);
717void CDListDrawContext::SetBlendMode(GLenum source, GLenum dest)
719 GLContext.GetDListGeomManager().Flush();
721 GLContext.GetDListManager().GetOpenDList() +=
CSetBlendMode(source, dest);
722 GLContext.BlendModeChanged();
735 pGLContext->GetImmDrawContext().SetDepthWriteEnabled(Enabled);
736 return CDListCmd::GetNextCmd(
this);
740void CDListDrawContext::SetDepthWriteEnabled(
bool enabled)
742 GLContext.GetDListGeomManager().Flush();
745 GLContext.DepthWriteEnabledChanged();
758 pGLContext->GetImmDrawContext().SetFrameBufferDrawMask(Mask);
759 return CDListCmd::GetNextCmd(
this);
763void CDListDrawContext::SetFrameBufferDrawMask(
unsigned int mask)
765 GLContext.GetDListGeomManager().Flush();
768 GLContext.FrameBufferDrawMaskChanged();
775void glDepthFunc(GLenum func)
777 GL_FUNC_DEBUG(
"%s(0x%x)\n", __FUNCTION__, func);
779 pGLContext->GetDrawContext().SetDepthFunc(func);
782void glDrawBuffer(GLenum mode)
784 GL_FUNC_DEBUG(
"%s(0x%x)\n", __FUNCTION__, mode);
789void glReadBuffer(GLenum mode)
791 GL_FUNC_DEBUG(
"%s(0x%x)\n", __FUNCTION__, mode);
796void glClipPlane(GLenum plane,
const GLdouble* equation)
798 GL_FUNC_DEBUG(
"%s(0x%x,%f)\n", __FUNCTION__, plane, equation);
805void glBlendFunc(GLenum sfactor, GLenum dfactor)
807 GL_FUNC_DEBUG(
"%s(0x%x,0x%x)\n", __FUNCTION__, sfactor, dfactor);
809 pGLContext->GetDrawContext().SetBlendMode(sfactor, dfactor);
814void glAlphaFunc(GLenum func, GLclampf ref)
816 GL_FUNC_DEBUG(
"%s(0x%x,%f)\n", __FUNCTION__, func, ref);
818 pGLContext->GetDrawContext().SetAlphaFunc(func, ref);
823void glDepthMask(GLboolean enabled)
825 GL_FUNC_DEBUG(
"%s(%d)\n", __FUNCTION__, enabled);
828 drawContext.SetDepthWriteEnabled(enabled);
831void glShadeModel(GLenum mode)
833 GL_FUNC_DEBUG(
"%s(0x%x)\n", __FUNCTION__, mode);
836 drawContext.SetDoSmoothShading((mode == GL_FLAT) ?
false : true);
839void glCullFace(GLenum mode)
841 GL_FUNC_DEBUG(
"%s(0x%x)\n", __FUNCTION__, mode);
843 mWarnIf(mode == GL_FRONT_AND_BACK,
"GL_FRONT_AND_BACK culling is not supported");
845 drawContext.SetCullFaceDir((mode == GL_FRONT) ? 1 : -1);
848void glColorMask(GLboolean r_enabled, GLboolean g_enabled,
849 GLboolean b_enabled, GLboolean a_enabled)
851 GL_FUNC_DEBUG(
"%s(%d,%d,%d,%d)\n", __FUNCTION__, r_enabled, g_enabled, b_enabled, a_enabled);
854 unsigned int mask = 0;
855 if (r_enabled == GL_FALSE)
857 if (g_enabled == GL_FALSE)
859 if (b_enabled == GL_FALSE)
861 if (a_enabled == GL_FALSE)
863 drawContext.SetFrameBufferDrawMask(mask);
866void glScissor(
int x,
int y,
int width,
int height)
868 GL_FUNC_DEBUG(
"%s(%d,%d,%d,%d)\n", __FUNCTION__, x, y, width, height);
873void glClearAccum(
float red,
float green,
float blue,
float alpha)
875 GL_FUNC_DEBUG(
"%s(%f,%f,%f,%f)\n", __FUNCTION__, red, green, blue, alpha);
880void glClearStencil(
int s)
882 GL_FUNC_DEBUG(
"%s(%d)\n", __FUNCTION__, s);
887void glPolygonMode(GLenum face, GLenum mode)
889 GL_FUNC_DEBUG(
"%s(0x%x,0x%x)\n", __FUNCTION__, face, mode);
892 drawContext.SetPolygonMode(mode);
895void glPolygonOffset(GLfloat factor, GLfloat units)
897 GL_FUNC_DEBUG(
"%s\n", __FUNCTION__);
902void glGetPolygonStipple(GLubyte* mask)
904 GL_FUNC_DEBUG(
"%s\n", __FUNCTION__);
927 pgl_area_handle_t frame0_mem, pgl_area_handle_t frame1_mem,
928 pgl_area_handle_t depth_mem)
930 pGLContext->GetDrawContext().SetDrawBuffers(interlaced,
931 reinterpret_cast<GS::CMemArea*
>(frame0_mem),
932 reinterpret_cast<GS::CMemArea*
>(frame1_mem),
933 reinterpret_cast<GS::CMemArea*
>(depth_mem));
936void pglSetInterlacingOffset(
float yPixels)
938 pGLContext->GetDrawContext().SetInterlacingOffset(yPixels);
void pglSetDrawBuffers(int interlaced, pgl_area_handle_t frame0_mem, pgl_area_handle_t frame1_mem, pgl_area_handle_t depth_mem)