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;
114 byte *getPixelBuffer() {
118 int getPixelBufferWidth() {
122 int getPixelBufferHeight() {
126 int getPixelBufferPitch() {
130 int getPixelBufferBpp() {
134 const uint *getZBuffer() {
140 tmp.
init(_pbufWidth, _pbufHeight, _pbufPitch, _pbuf, _pbufFormat);
145 surface.
init(_pbufWidth, _pbufHeight, _pbufPitch, _pbuf, _pbufFormat);
150 FORCEINLINE
void setPixelAt(
int pixel, uint32 value) {
153 ((uint16 *) _pbuf)[pixel] = value;
157 #if defined(SCUMM_BIG_ENDIAN) 158 _pbuf[pixel + 0] = (value >> 16) & 0xFF;
159 _pbuf[pixel + 1] = (value >> 8) & 0xFF;
160 _pbuf[pixel + 2] = value & 0xFF;
161 #elif defined(SCUMM_LITTLE_ENDIAN) 162 _pbuf[pixel + 0] = value & 0xFF;
163 _pbuf[pixel + 1] = (value >> 8) & 0xFF;
164 _pbuf[pixel + 2] = (value >> 16) & 0xFF;
168 ((uint32 *) _pbuf)[pixel] = value;
171 error(
"setPixelAt: Unhandled bytesPerPixel %d",
int(_pbufBpp));
174 FORCEINLINE uint32 getPixelAt(
int i)
const {
177 return ((uint16 *) _pbuf)[i];
180 #if defined(SCUMM_BIG_ENDIAN) 181 return (_pbuf[i + 0] << 16) | (_pbuf[i + 1] << 8) | _pbuf[i + 2];
182 #elif defined(SCUMM_LITTLE_ENDIAN) 183 return _pbuf[i + 0] | (_pbuf[i + 1] << 8) | (_pbuf[i + 2] << 16);
186 return ((uint32 *) _pbuf)[i];
188 error(
"getPixelAt: Unhandled bytesPerPixel %d",
int(_pbufBpp));
191 FORCEINLINE
bool compareDepth(uint &zSrc, uint &zDst) {
192 if (!_depthTestEnabled)
195 switch (_depthFunc) {
228 FORCEINLINE
bool checkAlphaTest(byte aSrc) {
229 if (!_alphaTestEnabled)
232 switch (_alphaTestFunc) {
236 if (aSrc < _alphaTestRefVal)
240 if (aSrc == _alphaTestRefVal)
244 if (aSrc <= _alphaTestRefVal)
248 if (aSrc > _alphaTestRefVal)
252 if (aSrc != _alphaTestRefVal)
256 if (aSrc >= _alphaTestRefVal)
265 FORCEINLINE
bool stencilTest(byte sSrc) {
266 switch (_stencilTestFunc) {
270 if ((_stencilRefVal & _stencilMask) < (sSrc & _stencilMask))
274 if ((_stencilRefVal & _stencilMask) <= (sSrc & _stencilMask))
278 if ((_stencilRefVal & _stencilMask) > (sSrc & _stencilMask))
282 if ((_stencilRefVal & _stencilMask) >= (sSrc & _stencilMask))
286 if ((_stencilRefVal & _stencilMask) == (sSrc & _stencilMask))
290 if ((_stencilRefVal & _stencilMask) != (sSrc & _stencilMask))
299 FORCEINLINE
void stencilOp(
bool stencilTestResult,
bool depthTestResult, byte *sDst) {
300 int op = !stencilTestResult ? _stencilSfail : !depthTestResult ? _stencilDpfail : _stencilDppass;
309 value = _stencilRefVal;
328 *sDst = value & _stencilWriteMask;
331 template <
bool kEnableAlphaTest,
bool kBlendingEnabled>
332 FORCEINLINE
void writePixel(
int pixel,
int value) {
333 writePixel<kEnableAlphaTest, kBlendingEnabled, false>(pixel, value, 0);
336 template <
bool kEnableAlphaTest,
bool kBlendingEnabled,
bool kDepthWrite>
337 FORCEINLINE
void writePixel(
int pixel,
int value, uint z) {
338 if (kBlendingEnabled ==
false) {
339 setPixelAt(pixel, value);
344 byte rSrc, gSrc, bSrc, aSrc;
345 _pbufFormat.colorToARGB(value, aSrc, rSrc, gSrc, bSrc);
347 writePixel<kEnableAlphaTest, kBlendingEnabled, kDepthWrite>(pixel, aSrc, rSrc, gSrc, bSrc, z);
351 FORCEINLINE
void writePixel(
int pixel,
int value) {
352 if (_alphaTestEnabled) {
353 writePixel<true>(pixel, value);
355 writePixel<false>(pixel, value);
359 template <
bool kDepthWrite,
bool kSmoothMode,
bool kFogMode,
bool kEnableAlphaTest,
bool kEnableScissor,
bool kEnableBlending,
bool kStencilEnabled,
bool kStippleEnabled,
bool kDepthTestEnabled>
360 void putPixelNoTexture(
int fbOffset, uint *pz, byte *ps,
int _a,
361 int x,
int y, uint &z, uint &r, uint &g, uint &b, uint &a,
362 int &dzdx,
int &drdx,
int &dgdx,
int &dbdx, uint dadx,
363 uint &fog,
int fog_r,
int fog_g,
int fog_b,
int &dfdx);
365 template <
bool kDepthWrite,
bool kLightsMode,
bool kSmoothMode,
bool kFogMode,
bool kEnableAlphaTest,
bool kEnableScissor,
bool kEnableBlending,
bool kStencilEnabled,
bool kDepthTestEnabled>
366 void putPixelTexture(
int fbOffset,
const TexelBuffer *texture,
367 uint wrap_s, uint wrap_t, uint *pz, byte *ps,
int _a,
368 int x,
int y, uint &z,
int &t,
int &s,
369 uint &r, uint &g, uint &b, uint &a,
370 int &dzdx,
int &dsdx,
int &dtdx,
int &drdx,
int &dgdx,
int &dbdx, uint dadx,
371 uint &fog,
int fog_r,
int fog_g,
int fog_b,
int &dfdx);
373 template <
bool kDepthWrite,
bool kEnableScissor,
bool kStencilEnabled,
bool StippleEnabled,
bool kDepthTestEnabled>
374 void putPixelDepth(uint *pz, byte *ps,
int _a,
int x,
int y, uint &z,
int &dzdx);
377 template <
bool kEnableAlphaTest>
378 FORCEINLINE
void writePixel(
int pixel,
int value) {
379 if (_blendingEnabled) {
380 writePixel<kEnableAlphaTest, true>(pixel, value);
382 writePixel<kEnableAlphaTest, false>(pixel, value);
386 FORCEINLINE
void writePixel(
int pixel, byte rSrc, byte gSrc, byte bSrc) {
387 writePixel(pixel, 255, rSrc, gSrc, bSrc);
390 FORCEINLINE
bool scissorPixel(
int x,
int y) {
391 return !_clipRectangle.contains(x, y);
396 FORCEINLINE
void writePixel(
int pixel, byte aSrc, byte rSrc, byte gSrc, byte bSrc) {
397 if (_alphaTestEnabled) {
398 writePixel<true>(pixel, aSrc, rSrc, gSrc, bSrc);
400 writePixel<false>(pixel, aSrc, rSrc, gSrc, bSrc);
406 template <
bool kEnableAlphaTest>
407 FORCEINLINE
void writePixel(
int pixel, byte aSrc, byte rSrc, byte gSrc, byte bSrc) {
408 if (_blendingEnabled) {
409 writePixel<kEnableAlphaTest, true>(pixel, aSrc, rSrc, gSrc, bSrc);
411 writePixel<kEnableAlphaTest, false>(pixel, aSrc, rSrc, gSrc, bSrc);
415 template <
bool kEnableAlphaTest,
bool kBlendingEnabled>
416 FORCEINLINE
void writePixel(
int pixel, byte aSrc, byte rSrc, byte gSrc, byte bSrc) {
417 writePixel<kEnableAlphaTest, kBlendingEnabled, false>(pixel, aSrc, rSrc, gSrc, bSrc, 0);
420 template <
bool kEnableAlphaTest,
bool kBlendingEnabled,
bool kDepthWrite>
421 FORCEINLINE
void writePixel(
int pixel, byte aSrc, byte rSrc, byte gSrc, byte bSrc, uint z) {
422 writePixel<kEnableAlphaTest, kBlendingEnabled, false, false>(pixel, aSrc, rSrc, gSrc, bSrc, z, 0.0f, 0, 0, 0);
425 template <
bool kEnableAlphaTest,
bool kBlendingEnabled,
bool kDepthWrite,
bool kFogMode>
426 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) {
427 if (kEnableAlphaTest) {
428 if (!checkAlphaTest(aSrc))
437 int oneMinusFog = (1 << ZB_FOG_BITS) - fog;
438 int finalR = (rSrc * fog + fog_r * oneMinusFog) >> ZB_FOG_BITS;
439 int finalG = (gSrc * fog + fog_g * oneMinusFog) >> ZB_FOG_BITS;
440 int finalB = (bSrc * fog + fog_b * oneMinusFog) >> ZB_FOG_BITS;
458 if (!kBlendingEnabled) {
459 setPixelAt(pixel, _pbufFormat.ARGBToColor(aSrc, rSrc, gSrc, bSrc));
461 byte rDst, gDst, bDst, aDst;
462 _pbufFormat.colorToARGB(getPixelAt(pixel), aDst, rDst, gDst, bDst);
463 switch (_sourceBlendingFactor) {
465 rSrc = gSrc = bSrc = 0;
470 rSrc = (rDst * rSrc) >> 8;
471 gSrc = (gDst * gSrc) >> 8;
472 bSrc = (bDst * bSrc) >> 8;
474 case TGL_ONE_MINUS_DST_COLOR:
475 rSrc = (rSrc * (255 - rDst)) >> 8;
476 gSrc = (gSrc * (255 - gDst)) >> 8;
477 bSrc = (bSrc * (255 - bDst)) >> 8;
480 rSrc = (rSrc * aSrc) >> 8;
481 gSrc = (gSrc * aSrc) >> 8;
482 bSrc = (bSrc * aSrc) >> 8;
484 case TGL_ONE_MINUS_SRC_ALPHA:
485 rSrc = (rSrc * (255 - aSrc)) >> 8;
486 gSrc = (gSrc * (255 - aSrc)) >> 8;
487 bSrc = (bSrc * (255 - aSrc)) >> 8;
490 rSrc = (rSrc * aDst) >> 8;
491 gSrc = (gSrc * aDst) >> 8;
492 bSrc = (bSrc * aDst) >> 8;
494 case TGL_ONE_MINUS_DST_ALPHA:
495 rSrc = (rSrc * (255 - aDst)) >> 8;
496 gSrc = (gSrc * (255 - aDst)) >> 8;
497 bSrc = (bSrc * (255 - aDst)) >> 8;
503 switch (_destinationBlendingFactor) {
505 rDst = gDst = bDst = 0;
510 rDst = (rDst * rSrc) >> 8;
511 gDst = (gDst * gSrc) >> 8;
512 bDst = (bDst * bSrc) >> 8;
514 case TGL_ONE_MINUS_DST_COLOR:
515 rDst = (rDst * (255 - rSrc)) >> 8;
516 gDst = (gDst * (255 - gSrc)) >> 8;
517 bDst = (bDst * (255 - bSrc)) >> 8;
520 rDst = (rDst * aSrc) >> 8;
521 gDst = (gDst * aSrc) >> 8;
522 bDst = (bDst * aSrc) >> 8;
524 case TGL_ONE_MINUS_SRC_ALPHA:
525 rDst = (rDst * (255 - aSrc)) >> 8;
526 gDst = (gDst * (255 - aSrc)) >> 8;
527 bDst = (bDst * (255 - aSrc)) >> 8;
530 rDst = (rDst * aDst) >> 8;
531 gDst = (gDst * aDst) >> 8;
532 bDst = (bDst * aDst) >> 8;
534 case TGL_ONE_MINUS_DST_ALPHA:
535 rDst = (rDst * (255 - aDst)) >> 8;
536 gDst = (gDst * (255 - aDst)) >> 8;
537 bDst = (bDst * (255 - aDst)) >> 8;
539 case TGL_SRC_ALPHA_SATURATE: {
540 int factor = aSrc < 1 - aDst ? aSrc : 1 - aDst;
541 rDst = (rDst * factor) >> 8;
542 gDst = (gDst * factor) >> 8;
543 bDst = (bDst * factor) >> 8;
549 int finalR = rDst + rSrc;
550 int finalG = gDst + gSrc;
551 int finalB = bDst + bSrc;
561 setPixelAt(pixel, _pbufFormat.RGBToColor(finalR, finalG, finalB));
567 void clear(
int clear_z,
int z,
int clear_color,
int r,
int g,
int b,
568 bool clearStencil,
int stencilValue);
569 void clearRegion(
int x,
int y,
int w,
int h,
bool clearZ,
int z,
570 bool clearColor,
int r,
int g,
int b,
bool clearStencil,
int stencilValue);
573 _clipRectangle = rect;
574 _enableScissor =
true;
577 void resetScissorRectangle() {
578 _enableScissor =
false;
581 void enableBlending(
bool enable) {
582 _blendingEnabled = enable;
585 void setBlendingFactors(
int sFactor,
int dFactor) {
586 _sourceBlendingFactor = sFactor;
587 _destinationBlendingFactor = dFactor;
590 void enableAlphaTest(
bool enable) {
591 _alphaTestEnabled = enable;
594 void setAlphaTestFunc(
int func,
int ref) {
595 _alphaTestFunc = func;
596 _alphaTestRefVal = ref;
599 void enableDepthTest(
bool enable) {
600 _depthTestEnabled = enable;
603 void setDepthFunc(
int func) {
607 void enableDepthWrite(
bool enable) {
608 _depthWrite = enable;
611 void enableStencilTest(
bool enable) {
612 _stencilTestEnabled = enable;
615 void setStencilWriteMask(uint stencilWriteMask) {
616 _stencilWriteMask = stencilWriteMask;
619 void enablePolygonStipple(
bool enable) {
620 _polygonStippleEnabled = enable;
623 void setPolygonStipplePattern(
const byte *stipple) {
624 _polygonStipplePattern = stipple;
627 void setStencilTestFunc(
int stencilFunc,
int stencilValue, uint stencilMask) {
628 _stencilTestFunc = stencilFunc;
629 _stencilRefVal = stencilValue;
630 _stencilMask = stencilMask;
633 void setStencilOp(
int stencilSfail,
int stencilDpfail,
int stencilDppass) {
634 _stencilSfail = stencilSfail;
635 _stencilDpfail = stencilDpfail;
636 _stencilDppass = stencilDppass;
639 void setOffsetStates(
int offsetStates) {
640 _offsetStates = offsetStates;
643 void setOffsetFactor(
float offsetFactor) {
644 _offsetFactor = offsetFactor;
647 void setOffsetUnits(
float offsetUnits) {
648 _offsetUnits = offsetUnits;
651 void setTexture(
const TexelBuffer *texture, uint wraps, uint wrapt) {
652 _currentTexture = texture;
657 void setTextureSizeAndMask(
int textureSize,
int textureSizeMask) {
658 _textureSize = textureSize;
659 _textureSizeMask = textureSizeMask;
662 void setFogEnabled(
bool enable) {
663 _fogEnabled = enable;
666 void setFogColor(
float colorR,
float colorG,
float colorB) {
679 Buffer *genOffscreenBuffer();
680 void delOffscreenBuffer(
Buffer *buffer);
681 void blitOffscreenBuffer(
Buffer *buffer);
682 void selectOffscreenBuffer(
Buffer *buffer);
683 void clearOffscreenBuffer(
Buffer *buffer);
685 template <
bool kInterpRGB,
bool kInterpZ,
bool kInterpST,
bool kInterpSTZ,
bool kSmoothMode,
686 bool kDepthWrite,
bool kFogMode,
bool kAlphaTestEnabled,
bool kEnableScissor,
687 bool kBlendingEnabled,
bool kStencilEnabled,
bool kStippleEnabled,
bool kDepthTestEnabled>
690 template <
bool kInterpRGB,
bool kInterpZ,
bool kInterpST,
bool kInterpSTZ,
bool kSmoothMode,
691 bool kDepthWrite,
bool kFogMode,
bool kAlphaTestEnabled,
bool kEnableScissor,
692 bool kBlendingEnabled,
bool kStencilEnabled,
bool kStippleEnabled>
695 template <
bool kInterpRGB,
bool kInterpZ,
bool kInterpST,
bool kInterpSTZ,
bool kSmoothMode,
696 bool kDepthWrite,
bool kFogMode,
bool kAlphaTestEnabled,
bool kEnableScissor,
697 bool kBlendingEnabled,
bool kStencilEnabled>
700 template <
bool kInterpRGB,
bool kInterpZ,
bool kInterpST,
bool kInterpSTZ,
bool kSmoothMode,
701 bool kDepthWrite,
bool kFogMode,
bool enableAlphaTest,
bool kEnableScissor,
bool kBlendingEnabled>
704 template <
bool kInterpRGB,
bool kInterpZ,
bool kInterpST,
bool kInterpSTZ,
bool kSmoothMode,
705 bool kDepthWrite,
bool kFogMode,
bool enableAlphaTest,
bool kEnableScissor>
708 template <
bool kInterpRGB,
bool kInterpZ,
bool kInterpST,
bool kInterpSTZ,
bool kSmoothMode,
709 bool kDepthWrite,
bool kFogMode,
bool enableAlphaTest>
712 template <
bool kInterpRGB,
bool kInterpZ,
bool kInterpST,
bool kInterpSTZ,
bool kSmoothMode,
713 bool kDepthWrite,
bool kFogMode>
716 template <
bool kInterpRGB,
bool kInterpZ,
bool kInterpST,
bool kInterpSTZ,
bool kSmoothMode,
720 template <
bool kInterpRGB,
bool kInterpZ,
bool kInterpST,
bool kInterpSTZ,
bool kSmoothMode>
742 template <
bool kDepthWrite>
743 FORCEINLINE
void putPixel(uint pixelOffset,
int color,
int x,
int y, uint z);
745 template <
bool kDepthWrite,
bool kEnableScissor>
746 FORCEINLINE
void putPixel(uint pixelOffset,
int color,
int x,
int y, uint z);
748 template <
bool kEnableScissor>
749 FORCEINLINE
void putPixel(uint pixelOffset,
int color,
int x,
int y);
751 template <
bool kInterpRGB,
bool kInterpZ,
bool kDepthWrite>
754 template <
bool kInterpRGB,
bool kInterpZ,
bool kDepthWrite,
bool kEnableScissor>
770 int _textureSizeMask;
777 bool _blendingEnabled;
778 int _sourceBlendingFactor;
779 int _destinationBlendingFactor;
780 bool _alphaTestEnabled;
782 int _alphaTestRefVal;
783 bool _depthTestEnabled;
785 bool _stencilTestEnabled;
786 int _stencilTestFunc;
789 uint _stencilWriteMask;
794 bool _polygonStippleEnabled;
795 const byte *_polygonStipplePattern;
807 void gl_free(
void *p);
808 void *gl_malloc(
int size);
809 void *gl_zalloc(
int size);
810 void *gl_realloc(
void *p,
int size);
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:106