ScummVM API documentation
zbuffer.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 /*
23  * This file is based on, or a modified version of code from TinyGL (C) 1997-2022 Fabrice Bellard,
24  * which is licensed under the MIT license (see LICENSE).
25  * It also has modifications by the ResidualVM-team, which are covered under the GPLv2 (or later).
26  */
27 
28 #ifndef GRAPHICS_TINYGL_ZBUFFER_H_
29 #define GRAPHICS_TINYGL_ZBUFFER_H_
30 
31 #include "graphics/surface.h"
32 #include "graphics/tinygl/texelbuffer.h"
33 #include "graphics/tinygl/gl.h"
34 
35 #include "common/rect.h"
36 #include "common/textconsole.h"
37 
38 namespace TinyGL {
39 
40 // Z buffer
41 
42 #define ZB_Z_BITS 16
43 
44 #define ZB_FOG_BITS 16
45 #define ZB_FOG_MAX ( (1 << ZB_FOG_BITS) - 1 )
46 
47 #define ZB_POINT_Z_FRAC_BITS 14
48 
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 )
52 
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 )
57 
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 )
62 
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 )
67 
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 )
72 
73 #define RGB_TO_PIXEL(r, g, b) _pbufFormat.ARGBToColor(255, r, g, b) // Default to 255 alpha aka solid colour.
74 
75 static const int DRAW_DEPTH_ONLY = 0;
76 static const int DRAW_FLAT = 1;
77 static const int DRAW_SMOOTH = 2;
78 
79 struct Buffer {
80  byte *pbuf;
81  uint *zbuf;
82  bool used;
83 };
84 
85 struct ZBufferPoint {
86  int x, y, z; // integer coordinates in the zbuffer
87  int s, t; // coordinates for the mapping
88  int r, g, b, a; // color indexes
89  float sz, tz; // temporary coordinates for mapping
90  int f; // fog factor
91 
92  bool operator==(const ZBufferPoint &other) const {
93  return
94  x == other.x &&
95  y == other.y &&
96  z == other.z &&
97  s == other.s &&
98  t == other.t &&
99  r == other.r &&
100  g == other.g &&
101  b == other.b &&
102  a == other.a;
103  }
104 };
105 
106 struct FrameBuffer {
107  FrameBuffer(int width, int height, const Graphics::PixelFormat &format, bool enableStencilBuffer);
108  ~FrameBuffer();
109 
110  Graphics::PixelFormat getPixelFormat() {
111  return _pbufFormat;
112  }
113 
114  byte *getPixelBuffer() {
115  return _pbuf;
116  }
117 
118  int getPixelBufferWidth() {
119  return _pbufWidth;
120  }
121 
122  int getPixelBufferHeight() {
123  return _pbufHeight;
124  }
125 
126  int getPixelBufferPitch() {
127  return _pbufPitch;
128  }
129 
130  int getPixelBufferBpp() {
131  return _pbufBpp;
132  }
133 
134  const uint *getZBuffer() {
135  return _zbuf;
136  }
137 
138  Graphics::Surface *copyFromFrameBuffer(const Graphics::PixelFormat &dstFormat) {
139  Graphics::Surface tmp;
140  tmp.init(_pbufWidth, _pbufHeight, _pbufPitch, _pbuf, _pbufFormat);
141  return tmp.convertTo(dstFormat);
142  }
143 
144  void getSurfaceRef(Graphics::Surface &surface) {
145  surface.init(_pbufWidth, _pbufHeight, _pbufPitch, _pbuf, _pbufFormat);
146  }
147 
148 private:
149 
150  FORCEINLINE void setPixelAt(int pixel, uint32 value) {
151  switch (_pbufBpp) {
152  case 2:
153  ((uint16 *) _pbuf)[pixel] = value;
154  return;
155  case 3:
156  pixel *= 3;
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;
165 #endif
166  return;
167  case 4:
168  ((uint32 *) _pbuf)[pixel] = value;
169  return;
170  }
171  error("setPixelAt: Unhandled bytesPerPixel %d", int(_pbufBpp));
172  }
173 
174  FORCEINLINE uint32 getPixelAt(int i) const {
175  switch (_pbufBpp) {
176  case 2:
177  return ((uint16 *) _pbuf)[i];
178  case 3:
179  i *= 3;
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);
184 #endif
185  case 4:
186  return ((uint32 *) _pbuf)[i];
187  }
188  error("getPixelAt: Unhandled bytesPerPixel %d", int(_pbufBpp));
189  }
190 
191  FORCEINLINE bool compareDepth(uint &zSrc, uint &zDst) {
192  if (!_depthTestEnabled)
193  return true;
194 
195  switch (_depthFunc) {
196  case TGL_NEVER:
197  break;
198  case TGL_LESS:
199  if (zDst < zSrc)
200  return true;
201  break;
202  case TGL_EQUAL:
203  if (zDst == zSrc)
204  return true;
205  break;
206  case TGL_LEQUAL:
207  if (zDst <= zSrc)
208  return true;
209  break;
210  case TGL_GREATER:
211  if (zDst > zSrc)
212  return true;
213  break;
214  case TGL_NOTEQUAL:
215  if (zDst != zSrc)
216  return true;
217  break;
218  case TGL_GEQUAL:
219  if (zDst >= zSrc)
220  return true;
221  break;
222  case TGL_ALWAYS:
223  return true;
224  }
225  return false;
226  }
227 
228  FORCEINLINE bool checkAlphaTest(byte aSrc) {
229  if (!_alphaTestEnabled)
230  return true;
231 
232  switch (_alphaTestFunc) {
233  case TGL_NEVER:
234  break;
235  case TGL_LESS:
236  if (aSrc < _alphaTestRefVal)
237  return true;
238  break;
239  case TGL_EQUAL:
240  if (aSrc == _alphaTestRefVal)
241  return true;
242  break;
243  case TGL_LEQUAL:
244  if (aSrc <= _alphaTestRefVal)
245  return true;
246  break;
247  case TGL_GREATER:
248  if (aSrc > _alphaTestRefVal)
249  return true;
250  break;
251  case TGL_NOTEQUAL:
252  if (aSrc != _alphaTestRefVal)
253  return true;
254  break;
255  case TGL_GEQUAL:
256  if (aSrc >= _alphaTestRefVal)
257  return true;
258  break;
259  case TGL_ALWAYS:
260  return true;
261  }
262  return false;
263  }
264 
265  FORCEINLINE bool stencilTest(byte sSrc) {
266  switch (_stencilTestFunc) {
267  case TGL_NEVER:
268  break;
269  case TGL_LESS:
270  if ((_stencilRefVal & _stencilMask) < (sSrc & _stencilMask))
271  return true;
272  break;
273  case TGL_LEQUAL:
274  if ((_stencilRefVal & _stencilMask) <= (sSrc & _stencilMask))
275  return true;
276  break;
277  case TGL_GREATER:
278  if ((_stencilRefVal & _stencilMask) > (sSrc & _stencilMask))
279  return true;
280  break;
281  case TGL_GEQUAL:
282  if ((_stencilRefVal & _stencilMask) >= (sSrc & _stencilMask))
283  return true;
284  break;
285  case TGL_EQUAL:
286  if ((_stencilRefVal & _stencilMask) == (sSrc & _stencilMask))
287  return true;
288  break;
289  case TGL_NOTEQUAL:
290  if ((_stencilRefVal & _stencilMask) != (sSrc & _stencilMask))
291  return true;
292  break;
293  case TGL_ALWAYS:
294  return true;
295  }
296  return false;
297  }
298 
299  FORCEINLINE void stencilOp(bool stencilTestResult, bool depthTestResult, byte *sDst) {
300  int op = !stencilTestResult ? _stencilSfail : !depthTestResult ? _stencilDpfail : _stencilDppass;
301  byte value = *sDst;
302  switch (op) {
303  case TGL_KEEP:
304  return;
305  case TGL_ZERO:
306  value = 0;
307  break;
308  case TGL_REPLACE:
309  value = _stencilRefVal;
310  break;
311  case TGL_INCR:
312  if (value < 255)
313  value++;
314  break;
315  case TGL_INCR_WRAP:
316  value++;
317  break;
318  case TGL_DECR:
319  if (value > 0)
320  value--;
321  break;
322  case TGL_DECR_WRAP:
323  value--;
324  break;
325  case TGL_INVERT:
326  value = ~value;
327  }
328  *sDst = value & _stencilWriteMask;
329  }
330 
331  template <bool kEnableAlphaTest, bool kBlendingEnabled>
332  FORCEINLINE void writePixel(int pixel, int value) {
333  writePixel<kEnableAlphaTest, kBlendingEnabled, false>(pixel, value, 0);
334  }
335 
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);
340  if (kDepthWrite) {
341  _zbuf[pixel] = z;
342  }
343  } else {
344  byte rSrc, gSrc, bSrc, aSrc;
345  _pbufFormat.colorToARGB(value, aSrc, rSrc, gSrc, bSrc);
346 
347  writePixel<kEnableAlphaTest, kBlendingEnabled, kDepthWrite>(pixel, aSrc, rSrc, gSrc, bSrc, z);
348  }
349  }
350 
351  FORCEINLINE void writePixel(int pixel, int value) {
352  if (_alphaTestEnabled) {
353  writePixel<true>(pixel, value);
354  } else {
355  writePixel<false>(pixel, value);
356  }
357  }
358 
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);
364 
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);
372 
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);
375 
376 
377  template <bool kEnableAlphaTest>
378  FORCEINLINE void writePixel(int pixel, int value) {
379  if (_blendingEnabled) {
380  writePixel<kEnableAlphaTest, true>(pixel, value);
381  } else {
382  writePixel<kEnableAlphaTest, false>(pixel, value);
383  }
384  }
385 
386  FORCEINLINE void writePixel(int pixel, byte rSrc, byte gSrc, byte bSrc) {
387  writePixel(pixel, 255, rSrc, gSrc, bSrc);
388  }
389 
390  FORCEINLINE bool scissorPixel(int x, int y) {
391  return !_clipRectangle.contains(x, y);
392  }
393 
394 public:
395 
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);
399  } else {
400  writePixel<false>(pixel, aSrc, rSrc, gSrc, bSrc);
401  }
402  }
403 
404 private:
405 
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);
410  } else {
411  writePixel<kEnableAlphaTest, false>(pixel, aSrc, rSrc, gSrc, bSrc);
412  }
413  }
414 
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);
418  }
419 
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);
423  }
424 
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))
429  return;
430  }
431 
432  if (kDepthWrite) {
433  _zbuf[pixel] = z;
434  }
435 
436  if (kFogMode) {
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;
441  if (finalR > 255) {
442  rSrc = 255;
443  } else {
444  rSrc = finalR;
445  }
446  if (finalG > 255) {
447  gSrc = 255;
448  } else {
449  gSrc = finalG;
450  }
451  if (finalB > 255) {
452  bSrc = 255;
453  } else {
454  bSrc = finalB;
455  }
456  }
457 
458  if (!kBlendingEnabled) {
459  setPixelAt(pixel, _pbufFormat.ARGBToColor(aSrc, rSrc, gSrc, bSrc));
460  } else {
461  byte rDst, gDst, bDst, aDst;
462  _pbufFormat.colorToARGB(getPixelAt(pixel), aDst, rDst, gDst, bDst);
463  switch (_sourceBlendingFactor) {
464  case TGL_ZERO:
465  rSrc = gSrc = bSrc = 0;
466  break;
467  case TGL_ONE:
468  break;
469  case TGL_DST_COLOR:
470  rSrc = (rDst * rSrc) >> 8;
471  gSrc = (gDst * gSrc) >> 8;
472  bSrc = (bDst * bSrc) >> 8;
473  break;
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;
478  break;
479  case TGL_SRC_ALPHA:
480  rSrc = (rSrc * aSrc) >> 8;
481  gSrc = (gSrc * aSrc) >> 8;
482  bSrc = (bSrc * aSrc) >> 8;
483  break;
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;
488  break;
489  case TGL_DST_ALPHA:
490  rSrc = (rSrc * aDst) >> 8;
491  gSrc = (gSrc * aDst) >> 8;
492  bSrc = (bSrc * aDst) >> 8;
493  break;
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;
498  break;
499  default:
500  break;
501  }
502 
503  switch (_destinationBlendingFactor) {
504  case TGL_ZERO:
505  rDst = gDst = bDst = 0;
506  break;
507  case TGL_ONE:
508  break;
509  case TGL_DST_COLOR:
510  rDst = (rDst * rSrc) >> 8;
511  gDst = (gDst * gSrc) >> 8;
512  bDst = (bDst * bSrc) >> 8;
513  break;
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;
518  break;
519  case TGL_SRC_ALPHA:
520  rDst = (rDst * aSrc) >> 8;
521  gDst = (gDst * aSrc) >> 8;
522  bDst = (bDst * aSrc) >> 8;
523  break;
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;
528  break;
529  case TGL_DST_ALPHA:
530  rDst = (rDst * aDst) >> 8;
531  gDst = (gDst * aDst) >> 8;
532  bDst = (bDst * aDst) >> 8;
533  break;
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;
538  break;
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;
544  }
545  break;
546  default:
547  break;
548  }
549  int finalR = rDst + rSrc;
550  int finalG = gDst + gSrc;
551  int finalB = bDst + bSrc;
552  if (finalR > 255) {
553  finalR = 255;
554  }
555  if (finalG > 255) {
556  finalG = 255;
557  }
558  if (finalB > 255) {
559  finalB = 255;
560  }
561  setPixelAt(pixel, _pbufFormat.RGBToColor(finalR, finalG, finalB));
562  }
563  }
564 
565 public:
566 
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);
571 
572  void setScissorRectangle(const Common::Rect &rect) {
573  _clipRectangle = rect;
574  _enableScissor = true;
575  }
576 
577  void resetScissorRectangle() {
578  _enableScissor = false;
579  }
580 
581  void enableBlending(bool enable) {
582  _blendingEnabled = enable;
583  }
584 
585  void setBlendingFactors(int sFactor, int dFactor) {
586  _sourceBlendingFactor = sFactor;
587  _destinationBlendingFactor = dFactor;
588  }
589 
590  void enableAlphaTest(bool enable) {
591  _alphaTestEnabled = enable;
592  }
593 
594  void setAlphaTestFunc(int func, int ref) {
595  _alphaTestFunc = func;
596  _alphaTestRefVal = ref;
597  }
598 
599  void enableDepthTest(bool enable) {
600  _depthTestEnabled = enable;
601  }
602 
603  void setDepthFunc(int func) {
604  _depthFunc = func;
605  }
606 
607  void enableDepthWrite(bool enable) {
608  _depthWrite = enable;
609  }
610 
611  void enableStencilTest(bool enable) {
612  _stencilTestEnabled = enable;
613  }
614 
615  void setStencilWriteMask(uint stencilWriteMask) {
616  _stencilWriteMask = stencilWriteMask;
617  }
618 
619  void enablePolygonStipple(bool enable) {
620  _polygonStippleEnabled = enable;
621  }
622 
623  void setPolygonStipplePattern(const byte *stipple) {
624  _polygonStipplePattern = stipple;
625  }
626 
627  void setStencilTestFunc(int stencilFunc, int stencilValue, uint stencilMask) {
628  _stencilTestFunc = stencilFunc;
629  _stencilRefVal = stencilValue;
630  _stencilMask = stencilMask;
631  }
632 
633  void setStencilOp(int stencilSfail, int stencilDpfail, int stencilDppass) {
634  _stencilSfail = stencilSfail;
635  _stencilDpfail = stencilDpfail;
636  _stencilDppass = stencilDppass;
637  }
638 
639  void setOffsetStates(int offsetStates) {
640  _offsetStates = offsetStates;
641  }
642 
643  void setOffsetFactor(float offsetFactor) {
644  _offsetFactor = offsetFactor;
645  }
646 
647  void setOffsetUnits(float offsetUnits) {
648  _offsetUnits = offsetUnits;
649  }
650 
651  void setTexture(const TexelBuffer *texture, uint wraps, uint wrapt) {
652  _currentTexture = texture;
653  _wrapS = wraps;
654  _wrapT = wrapt;
655  }
656 
657  void setTextureSizeAndMask(int textureSize, int textureSizeMask) {
658  _textureSize = textureSize;
659  _textureSizeMask = textureSizeMask;
660  }
661 
662  void setFogEnabled(bool enable) {
663  _fogEnabled = enable;
664  }
665 
666  void setFogColor(float colorR, float colorG, float colorB) {
667  _fogColorR = colorR;
668  _fogColorG = colorG;
669  _fogColorB = colorB;
670  }
671 
672 private:
673 
679  Buffer *genOffscreenBuffer();
680  void delOffscreenBuffer(Buffer *buffer);
681  void blitOffscreenBuffer(Buffer *buffer);
682  void selectOffscreenBuffer(Buffer *buffer);
683  void clearOffscreenBuffer(Buffer *buffer);
684 
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>
688  void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
689 
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>
693  void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
694 
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>
698  void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
699 
700  template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, bool kSmoothMode,
701  bool kDepthWrite, bool kFogMode, bool enableAlphaTest, bool kEnableScissor, bool kBlendingEnabled>
702  void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
703 
704  template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, bool kSmoothMode,
705  bool kDepthWrite, bool kFogMode, bool enableAlphaTest, bool kEnableScissor>
706  void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
707 
708  template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, bool kSmoothMode,
709  bool kDepthWrite, bool kFogMode, bool enableAlphaTest>
710  void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
711 
712  template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, bool kSmoothMode,
713  bool kDepthWrite, bool kFogMode>
714  void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
715 
716  template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, bool kSmoothMode,
717  bool kDepthWrite>
718  void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
719 
720  template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, bool kSmoothMode>
721  void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
722 
723 public:
724 
725  void fillTriangleTextureMappingPerspectiveSmooth(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
726  void fillTriangleTextureMappingPerspectiveFlat(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
727  void fillTriangleDepthOnly(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
728  void fillTriangleFlat(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
729  void fillTriangleSmooth(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
730 
731  void plot(ZBufferPoint *p);
732  void fillLine(ZBufferPoint *p1, ZBufferPoint *p2);
733  void fillLineZ(ZBufferPoint *p1, ZBufferPoint *p2);
734 
735 private:
736 
737  void fillLineFlatZ(ZBufferPoint *p1, ZBufferPoint *p2);
738  void fillLineInterpZ(ZBufferPoint *p1, ZBufferPoint *p2);
739  void fillLineFlat(ZBufferPoint *p1, ZBufferPoint *p2);
740  void fillLineInterp(ZBufferPoint *p1, ZBufferPoint *p2);
741 
742  template <bool kDepthWrite>
743  FORCEINLINE void putPixel(uint pixelOffset, int color, int x, int y, uint z);
744 
745  template <bool kDepthWrite, bool kEnableScissor>
746  FORCEINLINE void putPixel(uint pixelOffset, int color, int x, int y, uint z);
747 
748  template <bool kEnableScissor>
749  FORCEINLINE void putPixel(uint pixelOffset, int color, int x, int y);
750 
751  template <bool kInterpRGB, bool kInterpZ, bool kDepthWrite>
752  void drawLine(const ZBufferPoint *p1, const ZBufferPoint *p2);
753 
754  template <bool kInterpRGB, bool kInterpZ, bool kDepthWrite, bool kEnableScissor>
755  void drawLine(const ZBufferPoint *p1, const ZBufferPoint *p2);
756 
757  Buffer _offscreenBuffer;
758  byte *_pbuf;
759  int _pbufWidth;
760  int _pbufHeight;
761  int _pbufPitch;
762  Graphics::PixelFormat _pbufFormat;
763  int _pbufBpp;
764 
765  uint *_zbuf;
766  byte *_sbuf;
767 
768  bool _enableStencil;
769  int _textureSize;
770  int _textureSizeMask;
771 
772  Common::Rect _clipRectangle;
773  bool _enableScissor;
774 
775  const TexelBuffer *_currentTexture;
776  uint _wrapS, _wrapT;
777  bool _blendingEnabled;
778  int _sourceBlendingFactor;
779  int _destinationBlendingFactor;
780  bool _alphaTestEnabled;
781  int _alphaTestFunc;
782  int _alphaTestRefVal;
783  bool _depthTestEnabled;
784  bool _depthWrite;
785  bool _stencilTestEnabled;
786  int _stencilTestFunc;
787  int _stencilRefVal;
788  uint _stencilMask;
789  uint _stencilWriteMask;
790  int _stencilSfail;
791  int _stencilDpfail;
792  int _stencilDppass;
793 
794  bool _polygonStippleEnabled;
795  const byte *_polygonStipplePattern;
796  int _depthFunc;
797  int _offsetStates;
798  float _offsetFactor;
799  float _offsetUnits;
800  bool _fogEnabled;
801  float _fogColorR;
802  float _fogColorG;
803  float _fogColorB;
804 };
805 
806 // memory.c
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);
811 
812 } // end of namespace TinyGL
813 
814 #endif
Definition: surface.h:67
Definition: zbuffer.h:85
Definition: pixelformat.h:138
Definition: rect.h:144
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:79
Definition: zbuffer.h:106