ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

ztriangle.cpp

Go to the documentation of this file.
00001 /* ResidualVM - A 3D game interpreter
00002  *
00003  * ResidualVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the AUTHORS
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 /*
00024  * This file is based on, or a modified version of code from TinyGL (C) 1997-1998 Fabrice Bellard,
00025  * which is licensed under the zlib-license (see LICENSE).
00026  * It also has modifications by the ResidualVM-team, which are covered under the GPLv2 (or later).
00027  */
00028 
00029 #include "common/endian.h"
00030 #include "graphics/tinygl/zbuffer.h"
00031 #include "graphics/tinygl/zgl.h"
00032 
00033 namespace TinyGL {
00034 
00035 static const int NB_INTERP = 8;
00036 
00037 template <bool kDepthWrite, bool kEnableAlphaTest, bool kEnableScissor, bool kEnableBlending>
00038 FORCEINLINE static void putPixelFlat(FrameBuffer *buffer, int buf, unsigned int *pz, int _a,
00039                                      int x, int y, unsigned int &z, unsigned int &r, unsigned int &g, unsigned int &b, unsigned int &a, int &dzdx) {
00040     if ((!kEnableScissor || !buffer->scissorPixel(x + _a, y)) && buffer->compareDepth(z, pz[_a])) {
00041         buffer->writePixel<kEnableAlphaTest, kEnableBlending, kDepthWrite>(buf + _a, a >> (ZB_POINT_ALPHA_BITS - 8), r >> (ZB_POINT_RED_BITS - 8), g >> (ZB_POINT_GREEN_BITS - 8), b >> (ZB_POINT_BLUE_BITS - 8), z);
00042     }
00043     z += dzdx;
00044 }
00045 
00046 template <bool kDepthWrite, bool kEnableAlphaTest, bool kEnableScissor, bool kEnableBlending>
00047 FORCEINLINE static void putPixelSmooth(FrameBuffer *buffer, int buf, unsigned int *pz, int _a,
00048                                        int x, int y, unsigned int &z, unsigned int &r, unsigned int &g, unsigned int &b, unsigned int &a,
00049                                        int &dzdx, int &drdx, int &dgdx, int &dbdx, unsigned int dadx) {
00050     if ((!kEnableScissor || !buffer->scissorPixel(x + _a, y)) && buffer->compareDepth(z, pz[_a])) {
00051         buffer->writePixel<kEnableAlphaTest, kEnableBlending, kDepthWrite>(buf + _a, a >> (ZB_POINT_ALPHA_BITS - 8), r >> (ZB_POINT_RED_BITS - 8), g >> (ZB_POINT_GREEN_BITS - 8), b >> (ZB_POINT_BLUE_BITS - 8), z);
00052     }
00053     z += dzdx;
00054     a += dadx;
00055     r += drdx;
00056     g += dgdx;
00057     b += dbdx;
00058 }
00059 
00060 template <bool kDepthWrite, bool kEnableScissor>
00061 FORCEINLINE static void putPixelDepth(FrameBuffer *buffer, int buf, unsigned int *pz, int _a, int x, int y, unsigned int &z, int &dzdx) {
00062     if ((!kEnableScissor || !buffer->scissorPixel(x + _a, y)) && buffer->compareDepth(z, pz[_a])) {
00063         if (kDepthWrite) {
00064             pz[_a] = z;
00065         }
00066     }
00067     z += dzdx;
00068 }
00069 
00070 template <bool kDepthWrite, bool kAlphaTestEnabled, bool kEnableScissor, bool kBlendingEnabled>
00071 FORCEINLINE static void putPixelShadow(FrameBuffer *buffer, int buf, unsigned int *pz, int _a, int x, int y, unsigned int &z, unsigned int &r, unsigned int &g, unsigned int &b, int &dzdx, unsigned char *pm) {
00072     if ((!kEnableScissor || !buffer->scissorPixel(x + _a, y)) && buffer->compareDepth(z, pz[_a]) && pm[_a]) {
00073         buffer->writePixel<kAlphaTestEnabled, kBlendingEnabled, kDepthWrite>(buf + _a, 255, r >> (ZB_POINT_RED_BITS - 8), g >> (ZB_POINT_GREEN_BITS - 8), b >> (ZB_POINT_BLUE_BITS - 8), z);
00074     }
00075     z += dzdx;
00076 }
00077 
00078 template <bool kDepthWrite, bool kLightsMode, bool kSmoothMode, bool kEnableAlphaTest, bool kEnableScissor, bool kEnableBlending>
00079 FORCEINLINE static void putPixelTextureMappingPerspective(FrameBuffer *buffer, int buf,
00080                         Graphics::PixelFormat &textureFormat, Graphics::PixelBuffer &texture, unsigned int *pz, int _a,
00081                         int x, int y, unsigned int &z, unsigned int &t, unsigned int &s, unsigned int &r, unsigned int &g, unsigned int &b, unsigned int &a,
00082                         int &dzdx, int &dsdx, int &dtdx, int &drdx, int &dgdx, int &dbdx, unsigned int dadx) {
00083     if ((!kEnableScissor || !buffer->scissorPixel(x + _a, y)) && buffer->compareDepth(z, pz[_a])) {
00084         unsigned sss = (s & buffer->_textureSizeMask) >> ZB_POINT_ST_FRAC_BITS;
00085         unsigned ttt = (t & buffer->_textureSizeMask) >> ZB_POINT_ST_FRAC_BITS;
00086         int pixel = ttt * buffer->_textureSize + sss;
00087         uint8 c_a, c_r, c_g, c_b;
00088         uint32 *textureBuffer = (uint32 *)texture.getRawBuffer(pixel);
00089         uint32 col = *textureBuffer;
00090         c_a = (col >> textureFormat.aShift) & 0xFF;
00091         c_r = (col >> textureFormat.rShift) & 0xFF;
00092         c_g = (col >> textureFormat.gShift) & 0xFF;
00093         c_b = (col >> textureFormat.bShift) & 0xFF;
00094         if (kLightsMode) {
00095             unsigned int l_a = (a >> (ZB_POINT_ALPHA_BITS - 8));
00096             unsigned int l_r = (r >> (ZB_POINT_RED_BITS - 8));
00097             unsigned int l_g = (g >> (ZB_POINT_GREEN_BITS - 8));
00098             unsigned int l_b = (b >> (ZB_POINT_BLUE_BITS - 8));
00099             c_a = (c_a * l_a) >> (ZB_POINT_ALPHA_BITS - 8);
00100             c_r = (c_r * l_r) >> (ZB_POINT_RED_BITS - 8);
00101             c_g = (c_g * l_g) >> (ZB_POINT_GREEN_BITS - 8);
00102             c_b = (c_b * l_b) >> (ZB_POINT_BLUE_BITS - 8);
00103         }
00104         buffer->writePixel<kEnableAlphaTest, kEnableBlending, kDepthWrite>(buf + _a, c_a, c_r, c_g, c_b, z);
00105     }
00106     z += dzdx;
00107     s += dsdx;
00108     t += dtdx;
00109     if (kSmoothMode) {
00110         a += dadx;
00111         r += drdx;
00112         g += dgdx;
00113         b += dbdx;
00114     }
00115 }
00116 
00117 template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, int kDrawLogic, bool kDepthWrite, bool kAlphaTestEnabled, bool kEnableScissor, bool kBlendingEnabled>
00118 void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
00119     Graphics::PixelBuffer texture;
00120     Graphics::PixelFormat textureFormat;
00121     float fdzdx = 0, fndzdx = 0, ndszdx = 0, ndtzdx = 0;
00122 
00123     ZBufferPoint *tp, *pr1 = 0, *pr2 = 0, *l1 = 0, *l2 = 0;
00124     float fdx1, fdx2, fdy1, fdy2, fz0, d1, d2;
00125     unsigned int *pz1 = NULL;
00126     unsigned char *pm1 = NULL;
00127     int part, update_left = 1, update_right = 1;
00128 
00129     int nb_lines, dx1, dy1, tmp, dx2, dy2, y;
00130 
00131     int error = 0, derror = 0;
00132     int x1 = 0, dxdy_min = 0, dxdy_max = 0;
00133     // warning: x2 is multiplied by 2^16
00134     int x2 = 0, dx2dy2 = 0;
00135 
00136     int z1 = 0, dzdx = 0, dzdy = 0, dzdl_min = 0, dzdl_max = 0;
00137 
00138     int r1 = 0, drdx = 0, drdy = 0, drdl_min = 0, drdl_max = 0;
00139     int g1 = 0, dgdx = 0, dgdy = 0, dgdl_min = 0, dgdl_max = 0;
00140     int b1 = 0, dbdx = 0, dbdy = 0, dbdl_min = 0, dbdl_max = 0;
00141     int a1 = 0, dadx = 0, dady = 0, dadl_min = 0, dadl_max = 0;
00142 
00143     float sz1 = 0.0, dszdx = 0, dszdy = 0, dszdl_min = 0.0, dszdl_max = 0.0;
00144     float tz1 = 0.0, dtzdx = 0, dtzdy = 0, dtzdl_min = 0.0, dtzdl_max = 0.0;
00145 
00146     // we sort the vertex with increasing y
00147     if (p1->y < p0->y) {
00148         tp = p0;
00149         p0 = p1;
00150         p1 = tp;
00151     }
00152     if (p2->y < p0->y) {
00153         tp = p2;
00154         p2 = p1;
00155         p1 = p0;
00156         p0 = tp;
00157     } else if (p2->y < p1->y) {
00158         tp = p1;
00159         p1 = p2;
00160         p2 = tp;
00161     }
00162 
00163     // we compute dXdx and dXdy for all interpolated values
00164 
00165     fdx1 = (float)(p1->x - p0->x);
00166     fdy1 = (float)(p1->y - p0->y);
00167 
00168     fdx2 = (float)(p2->x - p0->x);
00169     fdy2 = (float)(p2->y - p0->y);
00170 
00171     fz0 = fdx1 * fdy2 - fdx2 * fdy1;
00172     if (fz0 == 0)
00173         return;
00174     fz0 = (float)(1.0 / fz0);
00175 
00176     fdx1 *= fz0;
00177     fdy1 *= fz0;
00178     fdx2 *= fz0;
00179     fdy2 *= fz0;
00180 
00181     if (kInterpZ) {
00182         d1 = (float)(p1->z - p0->z);
00183         d2 = (float)(p2->z - p0->z);
00184         dzdx = (int)(fdy2 * d1 - fdy1 * d2);
00185         dzdy = (int)(fdx1 * d2 - fdx2 * d1);
00186     }
00187 
00188     if (kInterpRGB) {
00189         d1 = (float)(p1->r - p0->r);
00190         d2 = (float)(p2->r - p0->r);
00191         drdx = (int)(fdy2 * d1 - fdy1 * d2);
00192         drdy = (int)(fdx1 * d2 - fdx2 * d1);
00193 
00194         d1 = (float)(p1->g - p0->g);
00195         d2 = (float)(p2->g - p0->g);
00196         dgdx = (int)(fdy2 * d1 - fdy1 * d2);
00197         dgdy = (int)(fdx1 * d2 - fdx2 * d1);
00198 
00199         d1 = (float)(p1->b - p0->b);
00200         d2 = (float)(p2->b - p0->b);
00201         dbdx = (int)(fdy2 * d1 - fdy1 * d2);
00202         dbdy = (int)(fdx1 * d2 - fdx2 * d1);
00203 
00204         d1 = (float)(p1->a - p0->a);
00205         d2 = (float)(p2->a - p0->a);
00206         dadx = (int)(fdy2 * d1 - fdy1 * d2);
00207         dady = (int)(fdx1 * d2 - fdx2 * d1);
00208     }
00209 
00210     if (kInterpST || kInterpSTZ) {
00211         if (kInterpSTZ) {
00212             float zz;
00213             zz = (float)p0->z;
00214             p0->sz = (float)p0->s * zz;
00215             p0->tz = (float)p0->t * zz;
00216             zz = (float)p1->z;
00217             p1->sz = (float)p1->s * zz;
00218             p1->tz = (float)p1->t * zz;
00219             zz = (float)p2->z;
00220             p2->sz = (float)p2->s * zz;
00221             p2->tz = (float)p2->t * zz;
00222         } else {
00223             p0->sz = (float)p0->s;
00224             p0->tz = (float)p0->t;
00225             p1->sz = (float)p1->s;
00226             p1->tz = (float)p1->t;
00227             p2->sz = (float)p2->s;
00228             p2->tz = (float)p2->t;
00229         }
00230 
00231         d1 = p1->sz - p0->sz;
00232         d2 = p2->sz - p0->sz;
00233         dszdx = (fdy2 * d1 - fdy1 * d2);
00234         dszdy = (fdx1 * d2 - fdx2 * d1);
00235 
00236         d1 = p1->tz - p0->tz;
00237         d2 = p2->tz - p0->tz;
00238         dtzdx = (fdy2 * d1 - fdy1 * d2);
00239         dtzdy = (fdx1 * d2 - fdx2 * d1);
00240     }
00241 
00242     // screen coordinates
00243 
00244     int pp1 = xsize * p0->y;
00245     pz1 = _zbuf + p0->y * xsize;
00246 
00247     switch (kDrawLogic) {
00248     case DRAW_SHADOW_MASK:
00249         pm1 = shadow_mask_buf + p0->y * xsize;
00250         break;
00251     case DRAW_SHADOW:
00252         pm1 = shadow_mask_buf + p0->y * xsize;
00253         r1 = shadow_color_r;
00254         g1 = shadow_color_g;
00255         b1 = shadow_color_b;
00256         break;
00257     case DRAW_DEPTH_ONLY:
00258         break;
00259     case DRAW_FLAT:
00260         r1 = p2->r;
00261         g1 = p2->g;
00262         b1 = p2->b;
00263         a1 = p2->a;
00264         break;
00265     case DRAW_SMOOTH:
00266         break;
00267     default:
00268         break;
00269     }
00270 
00271     if ((kInterpST || kInterpSTZ) && (kDrawLogic == DRAW_FLAT || kDrawLogic == DRAW_SMOOTH)) {
00272         texture = current_texture;
00273         textureFormat = texture.getFormat();
00274         assert(textureFormat.bytesPerPixel == 4);
00275         fdzdx = (float)dzdx;
00276         fndzdx = NB_INTERP * fdzdx;
00277         ndszdx = NB_INTERP * dszdx;
00278         ndtzdx = NB_INTERP * dtzdx;
00279     }
00280 
00281     if (fz0 > 0) {
00282         l1 = p0;
00283         l2 = p2;
00284         pr1 = p0;
00285         pr2 = p1;
00286     } else {
00287         l1 = p0;
00288         l2 = p1;
00289         pr1 = p0;
00290         pr2 = p2;
00291     }
00292     nb_lines = p1->y - p0->y;
00293     y = p0->y;
00294     for (part = 0; part < 2; part++) {
00295         if (part == 1) {
00296             // second part
00297             if (fz0 > 0) {
00298                 update_left = 0;
00299                 pr1 = p1;
00300                 pr2 = p2;
00301             } else {
00302                 update_right = 0;
00303                 l1 = p1;
00304                 l2 = p2;
00305             }
00306             nb_lines = p2->y - p1->y + 1;
00307         }
00308 
00309         // compute the values for the left edge
00310 
00311         if (update_left) {
00312             dy1 = l2->y - l1->y;
00313             dx1 = l2->x - l1->x;
00314             if (dy1 > 0)
00315                 tmp = (dx1 << 16) / dy1;
00316             else
00317                 tmp = 0;
00318             x1 = l1->x;
00319             error = 0;
00320             derror = tmp & 0x0000ffff;
00321             dxdy_min = tmp >> 16;
00322             dxdy_max = dxdy_min + 1;
00323 
00324             if (kInterpZ) {
00325                 z1 = l1->z;
00326                 dzdl_min = (dzdy + dzdx * dxdy_min);
00327                 dzdl_max = dzdl_min + dzdx;
00328             }
00329 
00330             if (kInterpRGB) {
00331                 r1 = l1->r;
00332                 drdl_min = (drdy + drdx * dxdy_min);
00333                 drdl_max = drdl_min + drdx;
00334 
00335                 g1 = l1->g;
00336                 dgdl_min = (dgdy + dgdx * dxdy_min);
00337                 dgdl_max = dgdl_min + dgdx;
00338 
00339                 b1 = l1->b;
00340                 dbdl_min = (dbdy + dbdx * dxdy_min);
00341                 dbdl_max = dbdl_min + dbdx;
00342 
00343                 a1 = l1->a;
00344                 dadl_min = (dady + dadx * dxdy_min);
00345                 dadl_max = dadl_min + dadx;
00346             }
00347 
00348             if (kInterpST || kInterpSTZ) {
00349                 sz1 = l1->sz;
00350                 dszdl_min = (dszdy + dszdx * dxdy_min);
00351                 dszdl_max = dszdl_min + dszdx;
00352 
00353                 tz1 = l1->tz;
00354                 dtzdl_min = (dtzdy + dtzdx * dxdy_min);
00355                 dtzdl_max = dtzdl_min + dtzdx;
00356             }
00357         }
00358 
00359         // compute values for the right edge
00360 
00361         if (update_right) {
00362             dx2 = (pr2->x - pr1->x);
00363             dy2 = (pr2->y - pr1->y);
00364             if (dy2 > 0)
00365                 dx2dy2 = (dx2 << 16) / dy2;
00366             else
00367                 dx2dy2 = 0;
00368             x2 = pr1->x << 16;
00369         }
00370 
00371         // we draw all the scan line of the part
00372         while (nb_lines > 0) {
00373             int x = x1;
00374             {
00375                 if (kDrawLogic == DRAW_DEPTH_ONLY ||
00376                         (kDrawLogic == DRAW_FLAT && !(kInterpST || kInterpSTZ))) {
00377                     int pp;
00378                     int n;
00379                     unsigned int *pz;
00380                     unsigned int z, a;
00381                     int buf = pp1 + x1;
00382                     unsigned int r = r1;
00383                     unsigned int g = g1;
00384                     unsigned int b = b1;
00385                     n = (x2 >> 16) - x1;
00386                     pp = pp1 + x1;
00387                     if (kInterpZ) {
00388                         pz = pz1 + x1;
00389                         z = z1;
00390                     }
00391                     if (kDrawLogic == DRAW_FLAT) {
00392                         a = a1;
00393                     }
00394                     while (n >= 3) {
00395                         if (kDrawLogic == DRAW_DEPTH_ONLY) {
00396                             putPixelDepth<kDepthWrite, kEnableScissor>(this, buf, pz, 0, x, y, z, dzdx);
00397                             putPixelDepth<kDepthWrite, kEnableScissor>(this, buf, pz, 1, x, y, z, dzdx);
00398                             putPixelDepth<kDepthWrite, kEnableScissor>(this, buf, pz, 2, x, y, z, dzdx);
00399                             putPixelDepth<kDepthWrite, kEnableScissor>(this, buf, pz, 3, x, y, z, dzdx);
00400                             buf += 4;
00401                         }
00402                         if (kDrawLogic == DRAW_FLAT) {
00403                             putPixelFlat<kDepthWrite, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled>(this, pp, pz, 0, x, y, z, r, g, b, a, dzdx);
00404                             putPixelFlat<kDepthWrite, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled>(this, pp, pz, 1, x, y, z, r, g, b, a, dzdx);
00405                             putPixelFlat<kDepthWrite, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled>(this, pp, pz, 2, x, y, z, r, g, g, a, dzdx);
00406                             putPixelFlat<kDepthWrite, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled>(this, pp, pz, 3, x, y, z, r, g, b, a, dzdx);
00407                         }
00408                         if (kInterpZ) {
00409                             pz += 4;
00410                         }
00411                         pp += 4;
00412                         n -= 4;
00413                         x += 4;
00414                     }
00415                     while (n >= 0) {
00416                         if (kDrawLogic == DRAW_DEPTH_ONLY) {
00417                             putPixelDepth<kDepthWrite, kEnableScissor>(this, buf, pz, 0, x, y, z, dzdx);
00418                             buf ++;
00419                         }
00420                         if (kDrawLogic == DRAW_FLAT) {
00421                             putPixelFlat<kDepthWrite, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled>(this, pp, pz, 0, x, y, z, r, g, b, a, dzdx);
00422                         }
00423                         if (kInterpZ) {
00424                             pz += 1;
00425                         }
00426                         pp += 1;
00427                         n -= 1;
00428                         x += 1;
00429                     }
00430                 } else if (kDrawLogic == DRAW_SHADOW_MASK) {
00431                     unsigned char *pm;
00432                     int n;
00433 
00434                     n = (x2 >> 16) - x1;
00435                     pm = pm1 + x1;
00436                     while (n >= 3) {
00437                         pm[0] = 0xff;
00438                         pm[1] = 0xff;
00439                         pm[2] = 0xff;
00440                         pm[3] = 0xff;
00441                         pm += 4;
00442                         n -= 4;
00443                         x += 4;
00444                     }
00445                     while (n >= 0) {
00446                         pm[0] = 0xff;
00447                         pm += 1;
00448                         n -= 1;
00449                         x += 1;
00450                     }
00451                 } else if (kDrawLogic == DRAW_SHADOW) {
00452                     unsigned char *pm;
00453                     int n;
00454                     unsigned int *pz;
00455                     unsigned int z;
00456                     unsigned int r = r1;
00457                     unsigned int g = g1;
00458                     unsigned int b = b1;
00459 
00460                     n = (x2 >> 16) - x1;
00461 
00462                     int buf = pp1 + x1;
00463 
00464                     pm = pm1 + x1;
00465                     pz = pz1 + x1;
00466                     z = z1;
00467                     while (n >= 3) {
00468                         putPixelShadow<kDepthWrite, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled>(this, buf, pz, 0, x, y, z, r, g, b, dzdx, pm);
00469                         putPixelShadow<kDepthWrite, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled>(this, buf, pz, 1, x, y, z, r, g, b, dzdx, pm);
00470                         putPixelShadow<kDepthWrite, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled>(this, buf, pz, 2, x, y, z, r, g, b, dzdx, pm);
00471                         putPixelShadow<kDepthWrite, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled>(this, buf, pz, 3, x, y, z, r, g, b, dzdx, pm);
00472                         pz += 4;
00473                         pm += 4;
00474                         buf += 4;
00475                         n -= 4;
00476                         x += 4;
00477                     }
00478                     while (n >= 0) {
00479                         putPixelShadow<kDepthWrite, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled>(this, buf, pz, 0, x, y, z, r, g, b, dzdx, pm);
00480                         pz += 1;
00481                         pm += 1;
00482                         buf += 1;
00483                         n -= 1;
00484                         x += 1;
00485                     }
00486                 } else if (kDrawLogic == DRAW_SMOOTH && !(kInterpST || kInterpSTZ)) {
00487                     unsigned int *pz;
00488                     int buf = pp1 + x1;
00489                     unsigned int z, r, g, b, a;
00490                     int n;
00491                     n = (x2 >> 16) - x1;
00492                     pz = pz1 + x1;
00493                     z = z1;
00494                     r = r1;
00495                     g = g1;
00496                     b = b1;
00497                     a = a1;
00498                     while (n >= 3) {
00499                         putPixelSmooth<kDepthWrite, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled>(this, buf, pz, 0, x, y, z, r, g, b, a, dzdx, drdx, dgdx, dbdx, dadx);
00500                         putPixelSmooth<kDepthWrite, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled>(this, buf, pz, 1, x, y, z, r, g, b, a, dzdx, drdx, dgdx, dbdx, dadx);
00501                         putPixelSmooth<kDepthWrite, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled>(this, buf, pz, 2, x, y, z, r, g, b, a, dzdx, drdx, dgdx, dbdx, dadx);
00502                         putPixelSmooth<kDepthWrite, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled>(this, buf, pz, 3, x, y, z, r, g, b, a, dzdx, drdx, dgdx, dbdx, dadx);
00503                         pz += 4;
00504                         buf += 4;
00505                         n -= 4;
00506                         x += 4;
00507                     }
00508                     while (n >= 0) {
00509                         putPixelSmooth<kDepthWrite, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled>(this, buf, pz, 0, x, y, z, r, g, b, a, dzdx, drdx, dgdx, dbdx, dadx);
00510                         buf += 1;
00511                         pz += 1;
00512                         n -= 1;
00513                         x += 1;
00514                     }
00515                 } else if (kInterpST || kInterpSTZ) {
00516                     unsigned int *pz;
00517                     unsigned int s, t, z, r, g, b, a;
00518                     int n;
00519                     float sz, tz, fz, zinv;
00520                     int dsdx, dtdx;
00521 
00522                     n = (x2 >> 16) - x1;
00523                     fz = (float)z1;
00524                     zinv = (float)(1.0 / fz);
00525 
00526                     int buf = pp1 + x1;
00527 
00528                     pz = pz1 + x1;
00529                     z = z1;
00530                     sz = sz1;
00531                     tz = tz1;
00532                     r = r1;
00533                     g = g1;
00534                     b = b1;
00535                     a = a1;
00536                     while (n >= (NB_INTERP - 1)) {
00537                         {
00538                             float ss, tt;
00539                             ss = sz * zinv;
00540                             tt = tz * zinv;
00541                             s = (int)ss;
00542                             t = (int)tt;
00543                             dsdx = (int)((dszdx - ss * fdzdx) * zinv);
00544                             dtdx = (int)((dtzdx - tt * fdzdx) * zinv);
00545                             fz += fndzdx;
00546                             zinv = (float)(1.0 / fz);
00547                         }
00548                         for (int _a = 0; _a < NB_INTERP; _a++) {
00549                             putPixelTextureMappingPerspective<kDepthWrite, kInterpRGB, kDrawLogic == DRAW_SMOOTH, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled>(this, buf, textureFormat, texture,
00550                                                        pz, _a, x, y, z, t, s, r, g, b, a, dzdx, dsdx, dtdx, drdx, dgdx, dbdx, dadx);
00551                         }
00552                         pz += NB_INTERP;
00553                         buf += NB_INTERP;
00554                         n -= NB_INTERP;
00555                         x += NB_INTERP;
00556                         sz += ndszdx;
00557                         tz += ndtzdx;
00558                     }
00559 
00560                     {
00561                         float ss, tt;
00562                         ss = sz * zinv;
00563                         tt = tz * zinv;
00564                         s = (int)ss;
00565                         t = (int)tt;
00566                         dsdx = (int)((dszdx - ss * fdzdx) * zinv);
00567                         dtdx = (int)((dtzdx - tt * fdzdx) * zinv);
00568                     }
00569 
00570                     while (n >= 0) {
00571                         putPixelTextureMappingPerspective<kDepthWrite, kInterpRGB, kDrawLogic == DRAW_SMOOTH, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled>(this, buf, textureFormat, texture,
00572                                                    pz, 0, x, y, z, t, s, r, g, b, a, dzdx, dsdx, dtdx, drdx, dgdx, dbdx, dadx);
00573                         pz += 1;
00574                         buf += 1;
00575                         n -= 1;
00576                         x += 1;
00577                     }
00578                 }
00579             }
00580 
00581             // left edge
00582             error += derror;
00583             if (error > 0) {
00584                 error -= 0x10000;
00585                 x1 += dxdy_max;
00586                 if (kInterpZ) {
00587                     z1 += dzdl_max;
00588                 }
00589 
00590                 if (kInterpRGB) {
00591                     r1 += drdl_max;
00592                     g1 += dgdl_max;
00593                     b1 += dbdl_max;
00594                     a1 += dadl_max;
00595                 }
00596 
00597                 if (kInterpST || kInterpSTZ) {
00598                     sz1 += dszdl_max;
00599                     tz1 += dtzdl_max;
00600                 }
00601             } else {
00602                 x1 += dxdy_min;
00603                 if (kInterpZ) {
00604                     z1 += dzdl_min;
00605                 }
00606                 if (kInterpRGB) {
00607                     r1 += drdl_min;
00608                     g1 += dgdl_min;
00609                     b1 += dbdl_min;
00610                     a1 += dadl_min;
00611                 }
00612                 if (kInterpST || kInterpSTZ) {
00613                     sz1 += dszdl_min;
00614                     tz1 += dtzdl_min;
00615                 }
00616             }
00617 
00618             // right edge
00619             x2 += dx2dy2;
00620 
00621             // screen coordinates
00622             pp1 += xsize;
00623             pz1 += xsize;
00624 
00625             if (kDrawLogic == DRAW_SHADOW || kDrawLogic == DRAW_SHADOW_MASK)
00626                 pm1 = pm1 + xsize;
00627             nb_lines--;
00628             y++;
00629         }
00630     }
00631 }
00632 
00633 template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, int kDrawMode, bool kDepthWrite, bool kEnableAlphaTest, bool kEnableScissor>
00634 void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
00635     if (_blendingEnabled) {
00636         fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kDrawMode, kDepthWrite, kEnableAlphaTest, kEnableScissor, true>(p0, p1, p2);
00637     } else {
00638         fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kDrawMode, kDepthWrite, kEnableAlphaTest, kEnableScissor, false>(p0, p1, p2);
00639     }
00640 }
00641 
00642 template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, int kDrawMode, bool kDepthWrite, bool kEnableAlphaTest>
00643 void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
00644     if (_enableScissor) {
00645         fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kDrawMode, kDepthWrite, kEnableAlphaTest, true>(p0, p1, p2);
00646     } else {
00647         fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kDrawMode, kDepthWrite, kEnableAlphaTest, false>(p0, p1, p2);
00648     }
00649 }
00650 
00651 template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, int kDrawMode, bool kDepthWrite>
00652 void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
00653     if (_alphaTestEnabled) {
00654         fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kDrawMode, kDepthWrite, true>(p0, p1, p2);
00655     }  else {
00656         fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kDrawMode, kDepthWrite, false>(p0, p1, p2);
00657     }
00658 }
00659 
00660 template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, int kDrawMode>
00661 void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
00662     if (_depthWrite) {
00663         fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kDrawMode, true>(p0, p1, p2);
00664     } else {
00665         fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kDrawMode, false>(p0, p1, p2);
00666     }
00667 }
00668 
00669 void FrameBuffer::fillTriangleDepthOnly(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
00670     const bool interpZ = true;
00671     const bool interpRGB = false;
00672     const bool interpST = false;
00673     const bool interpSTZ = false;
00674     if (_depthWrite && _depthTestEnabled)
00675         fillTriangle<interpRGB, interpZ, interpST, interpSTZ, DRAW_DEPTH_ONLY, true>(p0, p1, p2);
00676     else 
00677         fillTriangle<interpRGB, interpZ, interpST, interpSTZ, DRAW_DEPTH_ONLY, false>(p0, p1, p2);
00678 }
00679 
00680 void FrameBuffer::fillTriangleFlat(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
00681     const bool interpZ = true;
00682     const bool interpRGB = false;
00683     const bool interpST = false;
00684     const bool interpSTZ = false;
00685     if (_depthWrite && _depthTestEnabled)
00686         fillTriangle<interpRGB, interpZ, interpST, interpSTZ, DRAW_FLAT, true>(p0, p1, p2);
00687     else
00688         fillTriangle<interpRGB, interpZ, interpST, interpSTZ, DRAW_FLAT, false>(p0, p1, p2);
00689 }
00690 
00691 // Smooth filled triangle.
00692 void FrameBuffer::fillTriangleSmooth(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
00693     const bool interpZ = true;
00694     const bool interpRGB = true;
00695     const bool interpST = false;
00696     const bool interpSTZ = false;
00697     if (_depthWrite && _depthTestEnabled)
00698         fillTriangle<interpRGB, interpZ, interpST, interpSTZ, DRAW_SMOOTH, true>(p0, p1, p2);
00699     else
00700         fillTriangle<interpRGB, interpZ, interpST, interpSTZ, DRAW_SMOOTH, false>(p0, p1, p2);
00701 }
00702 
00703 void FrameBuffer::fillTriangleTextureMappingPerspectiveSmooth(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
00704     const bool interpZ = true;
00705     const bool interpRGB = true;
00706     const bool interpST = false;
00707     const bool interpSTZ = true;
00708     if (_depthWrite && _depthTestEnabled)
00709         fillTriangle<interpRGB, interpZ, interpST, interpSTZ, DRAW_SMOOTH, true>(p0, p1, p2);
00710     else
00711         fillTriangle<interpRGB, interpZ, interpST, interpSTZ, DRAW_SMOOTH, false>(p0, p1, p2);
00712 }
00713 
00714 void FrameBuffer::fillTriangleTextureMappingPerspectiveFlat(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
00715     const bool interpZ = true;
00716     const bool interpRGB = true;
00717     const bool interpST = false;
00718     const bool interpSTZ = true;
00719     if (_depthWrite && _depthTestEnabled)
00720         fillTriangle<interpRGB, interpZ, interpST, interpSTZ, DRAW_FLAT, true>(p0, p1, p2);
00721     else
00722         fillTriangle<interpRGB, interpZ, interpST, interpSTZ, DRAW_FLAT, false>(p0, p1, p2);
00723 }
00724 
00725 void FrameBuffer::fillTriangleFlatShadowMask(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
00726     const bool interpZ = true;
00727     const bool interpRGB = false;
00728     const bool interpST = false;
00729     const bool interpSTZ = false;
00730     if (_depthWrite && _depthTestEnabled)
00731         fillTriangle<interpRGB, interpZ, interpST, interpSTZ, DRAW_SHADOW_MASK, true>(p0, p1, p2);
00732     else
00733         fillTriangle<interpRGB, interpZ, interpST, interpSTZ, DRAW_SHADOW_MASK, false>(p0, p1, p2);
00734 }
00735 
00736 void FrameBuffer::fillTriangleFlatShadow(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
00737     const bool interpZ = true;
00738     const bool interpRGB = false;
00739     const bool interpST = false;
00740     const bool interpSTZ = false;
00741     if (_depthWrite && _depthTestEnabled)
00742         fillTriangle<interpRGB, interpZ, interpST, interpSTZ, DRAW_SHADOW, true>(p0, p1, p2);
00743     else
00744         fillTriangle<interpRGB, interpZ, interpST, interpSTZ, DRAW_SHADOW, false>(p0, p1, p2);
00745 }
00746 
00747 } // end of namespace TinyGL


Generated on Sat Mar 23 2019 05:02:23 for ResidualVM by doxygen 1.7.1
curved edge   curved edge