28 #ifndef GRAPHICS_TINYGL_ZBUFFER_H_ 29 #define GRAPHICS_TINYGL_ZBUFFER_H_ 31 #include "graphics/surface.h" 32 #include "graphics/tinygl/texelbuffer.h" 33 #include "graphics/tinygl/gl.h" 35 #include "common/rect.h" 36 #include "common/textconsole.h" 44 #define ZB_FOG_BITS 16 45 #define ZB_FOG_MAX ( (1 << ZB_FOG_BITS) - 1 ) 47 #define ZB_POINT_Z_FRAC_BITS 14 49 #define ZB_POINT_ST_FRAC_BITS 14 50 #define ZB_POINT_ST_FRAC_SHIFT (ZB_POINT_ST_FRAC_BITS - 1) 51 #define ZB_POINT_ST_MAX ( (_textureSize << ZB_POINT_ST_FRAC_BITS) - 1 ) 53 #define ZB_POINT_RED_BITS 16 54 #define ZB_POINT_RED_FRAC_BITS 8 55 #define ZB_POINT_RED_FRAC_SHIFT (ZB_POINT_RED_FRAC_BITS - 1) 56 #define ZB_POINT_RED_MAX ( (1 << ZB_POINT_RED_BITS) - 1 ) 58 #define ZB_POINT_GREEN_BITS 16 59 #define ZB_POINT_GREEN_FRAC_BITS 8 60 #define ZB_POINT_GREEN_FRAC_SHIFT (ZB_POINT_GREEN_FRAC_BITS - 1) 61 #define ZB_POINT_GREEN_MAX ( (1 << ZB_POINT_GREEN_BITS) - 1 ) 63 #define ZB_POINT_BLUE_BITS 16 64 #define ZB_POINT_BLUE_FRAC_BITS 8 65 #define ZB_POINT_BLUE_FRAC_SHIFT (ZB_POINT_BLUE_FRAC_BITS - 1) 66 #define ZB_POINT_BLUE_MAX ( (1 << ZB_POINT_BLUE_BITS) - 1 ) 68 #define ZB_POINT_ALPHA_BITS 16 69 #define ZB_POINT_ALPHA_FRAC_BITS 8 70 #define ZB_POINT_ALPHA_FRAC_SHIFT (ZB_POINT_ALPHA_FRAC_BITS - 1) 71 #define ZB_POINT_ALPHA_MAX ( (1 << ZB_POINT_ALPHA_BITS) - 1 ) 73 #define RGB_TO_PIXEL(r, g, b) _pbufFormat.ARGBToColor(255, r, g, b) // Default to 255 alpha aka solid colour. 75 static const int DRAW_DEPTH_ONLY = 0;
76 static const int DRAW_FLAT = 1;
77 static const int DRAW_SMOOTH = 2;
116 byte *getPixelBuffer() {
120 int getPixelBufferWidth() {
124 int getPixelBufferHeight() {
128 int getPixelBufferPitch() {
132 int getPixelBufferBpp() {
136 const uint *getZBuffer() {
142 tmp.
init(_pbufWidth, _pbufHeight, _pbufPitch, _pbuf, _pbufFormat);
147 surface.
init(_pbufWidth, _pbufHeight, _pbufPitch, _pbuf, _pbufFormat);
152 FORCEINLINE
void setPixelAt(
int pixel, uint32 value) {
155 ((uint16 *) _pbuf)[pixel] = value;
159 #if defined(SCUMM_BIG_ENDIAN) 160 _pbuf[pixel + 0] = (value >> 16) & 0xFF;
161 _pbuf[pixel + 1] = (value >> 8) & 0xFF;
162 _pbuf[pixel + 2] = value & 0xFF;
163 #elif defined(SCUMM_LITTLE_ENDIAN) 164 _pbuf[pixel + 0] = value & 0xFF;
165 _pbuf[pixel + 1] = (value >> 8) & 0xFF;
166 _pbuf[pixel + 2] = (value >> 16) & 0xFF;
170 ((uint32 *) _pbuf)[pixel] = value;
173 error(
"setPixelAt: Unhandled bytesPerPixel %d",
int(_pbufBpp));
176 FORCEINLINE uint32 getPixelAt(
int i)
const {
179 return ((uint16 *) _pbuf)[i];
182 #if defined(SCUMM_BIG_ENDIAN) 183 return (_pbuf[i + 0] << 16) | (_pbuf[i + 1] << 8) | _pbuf[i + 2];
184 #elif defined(SCUMM_LITTLE_ENDIAN) 185 return _pbuf[i + 0] | (_pbuf[i + 1] << 8) | (_pbuf[i + 2] << 16);
188 return ((uint32 *) _pbuf)[i];
190 error(
"getPixelAt: Unhandled bytesPerPixel %d",
int(_pbufBpp));
193 FORCEINLINE
bool compareDepth(uint &zSrc, uint &zDst) {
194 if (!_depthTestEnabled)
197 switch (_depthFunc) {
230 FORCEINLINE
bool checkAlphaTest(byte aSrc) {
231 if (!_alphaTestEnabled)
234 switch (_alphaTestFunc) {
238 if (aSrc < _alphaTestRefVal)
242 if (aSrc == _alphaTestRefVal)
246 if (aSrc <= _alphaTestRefVal)
250 if (aSrc > _alphaTestRefVal)
254 if (aSrc != _alphaTestRefVal)
258 if (aSrc >= _alphaTestRefVal)
267 FORCEINLINE
bool stencilTest(byte sSrc) {
268 switch (_stencilTestFunc) {
272 if ((_stencilRefVal & _stencilMask) < (sSrc & _stencilMask))
276 if ((_stencilRefVal & _stencilMask) <= (sSrc & _stencilMask))
280 if ((_stencilRefVal & _stencilMask) > (sSrc & _stencilMask))
284 if ((_stencilRefVal & _stencilMask) >= (sSrc & _stencilMask))
288 if ((_stencilRefVal & _stencilMask) == (sSrc & _stencilMask))
292 if ((_stencilRefVal & _stencilMask) != (sSrc & _stencilMask))
301 FORCEINLINE
void stencilOp(
bool stencilTestResult,
bool depthTestResult, byte *sDst) {
302 int op = !stencilTestResult ? _stencilSfail : !depthTestResult ? _stencilDpfail : _stencilDppass;
303 byte oldValue = *sDst;
304 byte newValue = oldValue;
312 newValue = _stencilRefVal;
329 newValue = ~newValue;
331 *sDst = (newValue & _stencilWriteMask) | (oldValue & ~_stencilWriteMask);
334 template <
bool kEnableAlphaTest,
bool kBlendingEnabled>
335 FORCEINLINE
void writePixel(
int pixel,
int value) {
336 writePixel<kEnableAlphaTest, kBlendingEnabled, false>(pixel, value, 0);
339 template <
bool kEnableAlphaTest,
bool kBlendingEnabled,
bool kDepthWrite>
340 FORCEINLINE
void writePixel(
int pixel,
int value, uint z) {
341 if (kBlendingEnabled ==
false) {
342 setPixelAt(pixel, value);
347 byte rSrc, gSrc, bSrc, aSrc;
348 _pbufFormat.colorToARGB(value, aSrc, rSrc, gSrc, bSrc);
350 writePixel<kEnableAlphaTest, kBlendingEnabled, kDepthWrite>(pixel, aSrc, rSrc, gSrc, bSrc, z);
354 FORCEINLINE
void writePixel(
int pixel,
int value) {
355 if (_alphaTestEnabled) {
356 writePixel<true>(pixel, value);
358 writePixel<false>(pixel, value);
362 template <
bool kDepthWrite,
bool kSmoothMode,
bool kFogMode,
bool kEnableAlphaTest,
bool kEnableScissor,
bool kEnableBlending,
bool kStencilEnabled,
bool kDepthTestEnabled>
363 void putPixelNoTexture(
int fbOffset, uint *pz, byte *ps,
int _a,
364 int x,
int y, uint &z, uint &r, uint &g, uint &b, uint &a,
365 int &dzdx,
int &drdx,
int &dgdx,
int &dbdx, uint dadx,
366 uint &fog,
int fog_r,
int fog_g,
int fog_b,
int &dfdx,
367 bool kStippleEnabled);
369 enum class ColorMode {
375 template <
bool kDepthWrite,
bool kSmoothMode,
bool kFogMode,
bool kEnableAlphaTest,
bool kEnableScissor,
bool kEnableBlending,
bool kStencilEnabled,
bool kDepthTestEnabled>
376 void putPixelTexture(
int fbOffset,
const TexelBuffer *texture,
377 FrameBuffer::ColorMode colorMode,
378 uint wrap_s, uint wrap_t, uint *pz, byte *ps,
int _a,
379 int x,
int y, uint &z,
int &t,
int &s,
380 uint &r, uint &g, uint &b, uint &a,
381 int &dzdx,
int &dsdx,
int &dtdx,
int &drdx,
int &dgdx,
int &dbdx, uint dadx,
382 uint &fog,
int fog_r,
int fog_g,
int fog_b,
int &dfdx);
384 template <
bool kDepthWrite,
bool kEnableScissor,
bool kStencilEnabled,
bool kDepthTestEnabled>
385 void putPixelDepth(uint *pz, byte *ps,
int _a,
int x,
int y, uint &z,
int &dzdx,
386 bool stippleEnabled);
389 template <
bool kEnableAlphaTest>
390 FORCEINLINE
void writePixel(
int pixel,
int value) {
391 if (_blendingEnabled) {
392 writePixel<kEnableAlphaTest, true>(pixel, value);
394 writePixel<kEnableAlphaTest, false>(pixel, value);
398 FORCEINLINE
void writePixel(
int pixel, byte rSrc, byte gSrc, byte bSrc) {
399 writePixel(pixel, 255, rSrc, gSrc, bSrc);
402 FORCEINLINE
bool scissorPixel(
int x,
int y) {
403 return !_clipRectangle.contains(x, y);
408 FORCEINLINE
void writePixel(
int pixel, byte aSrc, byte rSrc, byte gSrc, byte bSrc) {
409 if (_alphaTestEnabled) {
410 writePixel<true>(pixel, aSrc, rSrc, gSrc, bSrc);
412 writePixel<false>(pixel, aSrc, rSrc, gSrc, bSrc);
418 template <
bool kEnableAlphaTest>
419 FORCEINLINE
void writePixel(
int pixel, byte aSrc, byte rSrc, byte gSrc, byte bSrc) {
420 if (_blendingEnabled) {
421 writePixel<kEnableAlphaTest, true>(pixel, aSrc, rSrc, gSrc, bSrc);
423 writePixel<kEnableAlphaTest, false>(pixel, aSrc, rSrc, gSrc, bSrc);
427 template <
bool kEnableAlphaTest,
bool kBlendingEnabled>
428 FORCEINLINE
void writePixel(
int pixel, byte aSrc, byte rSrc, byte gSrc, byte bSrc) {
429 writePixel<kEnableAlphaTest, kBlendingEnabled, false>(pixel, aSrc, rSrc, gSrc, bSrc, 0);
432 template <
bool kEnableAlphaTest,
bool kBlendingEnabled,
bool kDepthWrite>
433 FORCEINLINE
void writePixel(
int pixel, byte aSrc, byte rSrc, byte gSrc, byte bSrc, uint z) {
434 writePixel<kEnableAlphaTest, kBlendingEnabled, kDepthWrite, false>(pixel, aSrc, rSrc, gSrc, bSrc, z, 0.0f, 0, 0, 0);
437 template <
bool kEnableAlphaTest,
bool kBlendingEnabled,
bool kDepthWrite,
bool kFogMode>
438 FORCEINLINE
void writePixel(
int pixel, byte aSrc, byte rSrc, byte gSrc, byte bSrc,
float z, uint fog, byte fog_r, byte fog_g, byte fog_b) {
439 if (kEnableAlphaTest) {
440 if (!checkAlphaTest(aSrc))
449 int oneMinusFog = (1 << ZB_FOG_BITS) - fog;
450 int finalR = (rSrc * fog + fog_r * oneMinusFog) >> ZB_FOG_BITS;
451 int finalG = (gSrc * fog + fog_g * oneMinusFog) >> ZB_FOG_BITS;
452 int finalB = (bSrc * fog + fog_b * oneMinusFog) >> ZB_FOG_BITS;
470 if (!kBlendingEnabled) {
471 setPixelAt(pixel, _pbufFormat.ARGBToColor(aSrc, rSrc, gSrc, bSrc));
473 byte rDst, gDst, bDst, aDst;
474 _pbufFormat.colorToARGB(getPixelAt(pixel), aDst, rDst, gDst, bDst);
475 switch (_sourceBlendingFactor) {
477 rSrc = gSrc = bSrc = 0;
482 rSrc = (rDst * rSrc) >> 8;
483 gSrc = (gDst * gSrc) >> 8;
484 bSrc = (bDst * bSrc) >> 8;
486 case TGL_ONE_MINUS_DST_COLOR:
487 rSrc = (rSrc * (255 - rDst)) >> 8;
488 gSrc = (gSrc * (255 - gDst)) >> 8;
489 bSrc = (bSrc * (255 - bDst)) >> 8;
492 rSrc = (rSrc * aSrc) >> 8;
493 gSrc = (gSrc * aSrc) >> 8;
494 bSrc = (bSrc * aSrc) >> 8;
496 case TGL_ONE_MINUS_SRC_ALPHA:
497 rSrc = (rSrc * (255 - aSrc)) >> 8;
498 gSrc = (gSrc * (255 - aSrc)) >> 8;
499 bSrc = (bSrc * (255 - aSrc)) >> 8;
502 rSrc = (rSrc * aDst) >> 8;
503 gSrc = (gSrc * aDst) >> 8;
504 bSrc = (bSrc * aDst) >> 8;
506 case TGL_ONE_MINUS_DST_ALPHA:
507 rSrc = (rSrc * (255 - aDst)) >> 8;
508 gSrc = (gSrc * (255 - aDst)) >> 8;
509 bSrc = (bSrc * (255 - aDst)) >> 8;
515 switch (_destinationBlendingFactor) {
517 rDst = gDst = bDst = 0;
522 rDst = (rDst * rSrc) >> 8;
523 gDst = (gDst * gSrc) >> 8;
524 bDst = (bDst * bSrc) >> 8;
526 case TGL_ONE_MINUS_DST_COLOR:
527 rDst = (rDst * (255 - rSrc)) >> 8;
528 gDst = (gDst * (255 - gSrc)) >> 8;
529 bDst = (bDst * (255 - bSrc)) >> 8;
532 rDst = (rDst * aSrc) >> 8;
533 gDst = (gDst * aSrc) >> 8;
534 bDst = (bDst * aSrc) >> 8;
536 case TGL_ONE_MINUS_SRC_ALPHA:
537 rDst = (rDst * (255 - aSrc)) >> 8;
538 gDst = (gDst * (255 - aSrc)) >> 8;
539 bDst = (bDst * (255 - aSrc)) >> 8;
542 rDst = (rDst * aDst) >> 8;
543 gDst = (gDst * aDst) >> 8;
544 bDst = (bDst * aDst) >> 8;
546 case TGL_ONE_MINUS_DST_ALPHA:
547 rDst = (rDst * (255 - aDst)) >> 8;
548 gDst = (gDst * (255 - aDst)) >> 8;
549 bDst = (bDst * (255 - aDst)) >> 8;
551 case TGL_SRC_ALPHA_SATURATE: {
552 int factor = aSrc < 1 - aDst ? aSrc : 1 - aDst;
553 rDst = (rDst * factor) >> 8;
554 gDst = (gDst * factor) >> 8;
555 bDst = (bDst * factor) >> 8;
561 int finalR = rDst + rSrc;
562 int finalG = gDst + gSrc;
563 int finalB = bDst + bSrc;
573 setPixelAt(pixel, _pbufFormat.RGBToColor(finalR, finalG, finalB));
579 void clear(
int clear_z,
int z,
int clear_color,
int r,
int g,
int b,
580 bool clearStencil,
int stencilValue);
581 void clearRegion(
int x,
int y,
int w,
int h,
bool clearZ,
int z,
582 bool clearColor,
int r,
int g,
int b,
bool clearStencil,
int stencilValue);
585 return _clipRectangle;
588 void setupScissor(
bool enable,
const int (&scissor)[4],
const Common::Rect *clippingRectangle) {
589 _clippingEnabled = enable || clippingRectangle;
591 if (enable && clippingRectangle) {
595 _pbufHeight - scissor[1] - scissor[3],
596 scissor[0] + scissor[2],
597 _pbufHeight - scissor[1]));
602 _pbufHeight - scissor[1] - scissor[3],
603 scissor[0] + scissor[2],
604 _pbufHeight - scissor[1]);
605 }
else if (clippingRectangle) {
606 _clipRectangle = *clippingRectangle;
608 _clipRectangle =
Common::Rect(0, 0, _pbufWidth, _pbufHeight);
612 void enableBlending(
bool enable) {
613 _blendingEnabled = enable;
616 void setBlendingFactors(
int sFactor,
int dFactor) {
617 _sourceBlendingFactor = sFactor;
618 _destinationBlendingFactor = dFactor;
621 void enableAlphaTest(
bool enable) {
622 _alphaTestEnabled = enable;
625 void setAlphaTestFunc(
int func,
int ref) {
626 _alphaTestFunc = func;
627 _alphaTestRefVal = ref;
630 void enableDepthTest(
bool enable) {
631 _depthTestEnabled = enable;
634 void setDepthFunc(
int func) {
638 void enableDepthWrite(
bool enable) {
639 _depthWrite = enable;
642 void enableStencilTest(
bool enable) {
643 _stencilTestEnabled = enable;
646 void setStencilWriteMask(uint stencilWriteMask) {
647 _stencilWriteMask = stencilWriteMask;
650 void enablePolygonStipple(
bool enable) {
651 _polygonStippleEnabled = enable;
654 void setPolygonStipplePattern(
const byte *stipple) {
655 _polygonStipplePattern = stipple;
658 void enableTwoColorStipple(
bool enable) {
659 _twoColorStippleEnabled = enable;
662 void setStippleColor(
int r,
int g,
int b) {
663 _stippleColor = RGB_TO_PIXEL(r, g, b);
666 void setStencilTestFunc(
int stencilFunc, byte stencilValue, byte stencilMask) {
667 _stencilTestFunc = stencilFunc;
668 _stencilRefVal = stencilValue;
669 _stencilMask = stencilMask;
672 void setStencilOp(
int stencilSfail,
int stencilDpfail,
int stencilDppass) {
673 _stencilSfail = stencilSfail;
674 _stencilDpfail = stencilDpfail;
675 _stencilDppass = stencilDppass;
678 void setOffsetStates(
int offsetStates) {
679 _offsetStates = offsetStates;
682 void setOffsetFactor(
float offsetFactor) {
683 _offsetFactor = offsetFactor;
686 void setOffsetUnits(
float offsetUnits) {
687 _offsetUnits = offsetUnits;
690 void setTexture(
const TexelBuffer *texture, uint wraps, uint wrapt) {
691 _currentTexture = texture;
696 void setTextureEnvironment(
const GLTextureEnv *texEnv) {
697 _textureEnv = texEnv;
700 void setTextureSizeAndMask(
int textureSize,
int textureSizeMask) {
701 _textureSize = textureSize;
702 _textureSizeMask = textureSizeMask;
705 void setFogEnabled(
bool enable) {
706 _fogEnabled = enable;
709 void setFogColor(
float colorR,
float colorG,
float colorB) {
722 Buffer *genOffscreenBuffer();
723 void delOffscreenBuffer(
Buffer *buffer);
724 void blitOffscreenBuffer(
Buffer *buffer);
725 void selectOffscreenBuffer(
Buffer *buffer);
726 void clearOffscreenBuffer(
Buffer *buffer);
728 template <
bool kSmoothMode,
bool kDepthWrite,
bool kFogMode,
bool kAlphaTestEnabled,
bool kEnableScissor,
729 bool kBlendingEnabled,
bool kStencilEnabled,
bool kDepthTestEnabled>
731 FrameBuffer::ColorMode kColorMode,
bool kInterpZ,
732 bool kInterpST,
bool kInterpSTZ,
bool stippleEnable);
734 template <
bool kSmoothMode,
bool kDepthWrite,
bool kFogMode,
bool kEnableAlphaTest,
bool kEnableScissor,
735 bool kEnableBlending,
bool kStencilEnabled>
737 FrameBuffer::ColorMode colorMode,
bool interpZ,
738 bool interpST,
bool interpSTZ);
740 template <
bool kSmoothMode,
bool kDepthWrite,
bool kFogMode,
bool kEnableAlphaTest,
bool kEnableScissor,
741 bool kBlendingEnabled>
743 FrameBuffer::ColorMode kColorMode,
bool kInterpZ,
744 bool kInterpST,
bool kInterpSTZ);
746 template <
bool kSmoothMode,
bool kDepthWrite,
bool kFogMode,
bool kEnableAlphaTest,
bool kEnableScissor>
748 FrameBuffer::ColorMode kColorMode,
bool kInterpZ,
749 bool kInterpST,
bool kInterpSTZ);
751 template <
bool kSmoothMode,
bool kDepthWrite,
bool kFogMode,
bool kEnableAlphaTest>
753 FrameBuffer::ColorMode kColorMode,
bool kInterpZ,
754 bool kInterpST,
bool kInterpSTZ);
756 template <
bool kSmoothMode,
bool kDepthWrite,
bool kFogMode>
758 FrameBuffer::ColorMode kColorMode,
bool kInterpZ,
759 bool kInterpST,
bool kInterpSTZ);
761 template <
bool kSmoothMode,
bool kDepthWrite>
763 FrameBuffer::ColorMode kColorMode,
bool kInterpZ,
764 bool kInterpST,
bool kInterpSTZ);
766 template <
bool kSmoothMode>
768 FrameBuffer::ColorMode kColorMode,
bool kInterpZ,
769 bool kInterpST,
bool kInterpSTZ);
771 template <
bool kSmoothMode,
bool kDepthWrite>
773 bool kInterpZ,
bool kInterpST,
bool kInterpSTZ);
794 template <
bool kDepthWrite>
795 FORCEINLINE
void putPixel(uint pixelOffset,
int color,
int x,
int y, uint z);
797 template <
bool kDepthWrite,
bool kEnableScissor>
798 FORCEINLINE
void putPixel(uint pixelOffset,
int color,
int x,
int y, uint z);
800 template <
bool kEnableScissor>
801 FORCEINLINE
void putPixel(uint pixelOffset,
int color,
int x,
int y);
803 template <
bool kInterpRGB,
bool kInterpZ,
bool kDepthWrite>
806 template <
bool kInterpRGB,
bool kInterpZ,
bool kDepthWrite,
bool kEnableScissor>
809 void applyTextureEnvironment(
811 uint previousA, uint previousR, uint previousG, uint previousB,
812 byte &texA, byte &texR, byte &texG, byte &texB);
815 void applyModulation(
816 uint previousA, uint previousR, uint previousG, uint previousB,
817 byte &texA, byte &texR, byte &texG, byte &texB);
832 int _textureSizeMask;
835 bool _clippingEnabled;
840 bool _blendingEnabled;
841 int _sourceBlendingFactor;
842 int _destinationBlendingFactor;
843 bool _alphaTestEnabled;
845 int _alphaTestRefVal;
846 bool _depthTestEnabled;
848 bool _stencilTestEnabled;
849 int _stencilTestFunc;
852 byte _stencilWriteMask;
857 bool _polygonStippleEnabled;
858 bool _twoColorStippleEnabled;
859 uint32 _stippleColor;
860 const byte *_polygonStipplePattern;
872 void gl_free(
void *p);
873 void *gl_malloc(
int size);
874 void *gl_zalloc(
int size);
875 void *gl_realloc(
void *p,
int size);
ConcreteRect findIntersectingRect(const ConcreteRect &r) const
Definition: rect.h:302
void init(int16 width, int16 height, int16 pitch, void *pixels, const PixelFormat &format)
Graphics::Surface * convertTo(const PixelFormat &dstFormat, const byte *srcPalette=0, int srcPaletteCount=256, const byte *dstPalette=0, int dstPaletteCount=0, DitherMethod method=kDitherFloyd) const
Definition: colormasks.h:27
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
Definition: texelbuffer.h:29
Definition: zbuffer.h:108
Definition: zdirtyrect.h:51