Google
Web alhem.net
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

SDL_prim.cpp

Go to the documentation of this file.
00001 #include <math.h> 00002 00003 #include "SDL_prim.h" 00004 00005 00006 /* 00007 * This is incorrect, as it can cause unintended transparency effects. The 00008 * application should probably recognize that anti-aliased lines appear 00009 * brighter and reduce the intensity of the colors itself. 00010 * 00011 * // when anti-aliasing, the slightly fatter line appears brighter 00012 * // than the aliased equivalent, so a reduction in the alpha 00013 * // value makes it appear about the same, just smoother 00014 */ 00015 /* #define SDL_ALPHA_REDUCER (200.0 / 255.0) */ 00016 00017 00018 /* 00019 * simple pixel drawing function. 00020 * 00021 * tests to be sure pixel is within bounds of the surface, so you 00022 * can draw off the screen to your hearts content 00023 * 00024 * it's probably not good practice to be drawing off the screen though... 00025 */ 00026 inline 00027 void SDL_putPixel(SDL_Surface *surf, int x, int y, Uint32 clr) 00028 { 00029 int Bpp = surf->format->BytesPerPixel; 00030 Uint8 *p; 00031 00032 if (! (x < 0 || x >= surf->w || y < 0 || y >= surf->h) ) 00033 { 00034 p = (Uint8*)surf->pixels + y * surf->pitch + x * Bpp; 00035 00036 switch(Bpp) { 00037 case 1: 00038 *p = clr; 00039 break; 00040 00041 case 2: 00042 *(Uint16*)p = clr; 00043 break; 00044 00045 case 3: 00046 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { 00047 p[0] = (clr >> 16) & 0xff; 00048 p[1] = (clr >> 8) & 0xff; 00049 p[2] = clr & 0xff; 00050 } else { 00051 p[0] = clr & 0xff; 00052 p[1] = (clr >> 8) & 0xff; 00053 p[2] = (clr >> 16) & 0xff; 00054 } 00055 break; 00056 00057 case 4: 00058 *(Uint32*)p = clr; 00059 break; 00060 } 00061 } 00062 } 00063 00064 00065 /* 00066 * returns pointer to pixel at x, y 00067 */ 00068 inline 00069 Uint8* SDL_getPixel(SDL_Surface *surf, int x, int y) 00070 { 00071 int Bpp = surf->format->BytesPerPixel; 00072 00073 if (! (x < 0 || x >= surf->w || y < 0 || y >= surf->h) ) 00074 return (Uint8*)surf->pixels + y * surf->pitch + x * Bpp; 00075 else 00076 return 0; 00077 } 00078 00079 00080 /* 00081 * slow pixel blending function 00082 * used as a failover for 8 and 24 bpp 00083 * will be removed soon 00084 * 00085 * 8 bit doesn't work 00086 */ 00087 inline 00088 void __slow_SDL_blendPixel( SDL_Surface *surf, int x, int y, Uint32 clr, 00089 Uint8 alpha) 00090 { 00091 Uint8 *p; 00092 Uint8 r, g, b, r2, g2, b2; 00093 00094 if ( (p = SDL_getPixel(surf, x, y)) ) { 00095 SDL_GetRGB(clr, surf->format, &r, &g, &b); 00096 SDL_GetRGB(*p, surf->format, &r2, &g2, &b2); 00097 00098 r = r2 + ( r - r2 ) * ( alpha / 255.0 ); 00099 g = g2 + ( g - g2 ) * ( alpha / 255.0 ); 00100 b = b2 + ( b - b2 ) * ( alpha / 255.0 ); 00101 00102 clr = SDL_MapRGB(surf->format, r, g, b); 00103 00104 SDL_putPixel(surf, x, y, clr); 00105 } 00106 } 00107 00108 00109 /* 00110 * blends pixel onto surface according to alpha 00111 */ 00112 inline 00113 void SDL_blendPixel( SDL_Surface *surf, int x, int y, Uint32 clr, 00114 Uint8 alpha) 00115 { 00116 Uint8 *p; 00117 Uint32 R, G, B; 00118 Uint32 Rmask = surf->format->Rmask; 00119 Uint32 Gmask = surf->format->Gmask; 00120 Uint32 Bmask = surf->format->Bmask; 00121 00122 if ( (p = SDL_getPixel(surf, x, y)) ) { 00123 switch(surf->format->BytesPerPixel) { 00124 case 1: /* 8 bpp */ 00125 __slow_SDL_blendPixel(surf, x, y, clr, alpha); 00126 break; 00127 00128 case 2: /* 16 bpp */ 00129 R = ( (*(Uint16*)p & Rmask) + ( ((clr & Rmask) - ((*(Uint16*)p) & Rmask)) * alpha >> 8) ) & Rmask; 00130 G = ( (*(Uint16*)p & Gmask) + ( ((clr & Gmask) - ((*(Uint16*)p) & Gmask)) * alpha >> 8) ) & Gmask; 00131 B = ( (*(Uint16*)p & Bmask) + ( ((clr & Bmask) - ((*(Uint16*)p) & Bmask)) * alpha >> 8) ) & Bmask; 00132 *(Uint16*)p = R | G | B; 00133 break; 00134 00135 case 3: /* 24 bpp */ 00136 __slow_SDL_blendPixel(surf, x, y, clr, alpha); 00137 break; 00138 00139 case 4: /* 32 bpp */ 00140 R = ( (*(Uint32*)p & Rmask) + ( ((clr & Rmask) - (*(Uint32*)p & Rmask)) * alpha >> 8) ) & Rmask; 00141 G = ( (*(Uint32*)p & Gmask) + ( ((clr & Gmask) - (*(Uint32*)p & Gmask)) * alpha >> 8) ) & Gmask; 00142 B = ( (*(Uint32*)p & Bmask) + ( ((clr & Bmask) - (*(Uint32*)p & Bmask)) * alpha >> 8) ) & Bmask; 00143 *(Uint32*)p = R | G | B; 00144 break; 00145 } 00146 } 00147 } 00148 00149 00150 /* 00151 * draw a line 00152 */ 00153 void SDL_drawLine( SDL_Surface *surf, int x1, int y1, int x2, int y2, 00154 Uint32 clr ) 00155 { 00156 int x, y, dx, dy, c; 00157 float slope; 00158 00159 dx = x2 - x1; /* change in x */ 00160 dy = y2 - y1; /* change in y */ 00161 00162 slope = (float)dy / dx; 00163 00164 if (abs(dx) >= abs(dy)) { 00165 /* draw left/right - right/left */ 00166 c = (x1 <= x2) ? 1 : -1; 00167 for (x = x1; x != x2 + c; x += c) { 00168 y = y1 + ( (x - x1) * slope + 0.5 ); 00169 SDL_putPixel(surf, x, y, clr); 00170 } 00171 } 00172 else { 00173 /* draw top/bottom - bottom/top */ 00174 c = (y1 <= y2) ? 1 : -1; 00175 for (y = y1; y != y2 + c; y += c) { 00176 x = x1 + ( (y - y1) / slope + 0.5 ); 00177 SDL_putPixel(surf, x, y, clr); 00178 } 00179 } 00180 } 00181 00182 00183 /* 00184 * draw anti-aliased lines 00185 */ 00186 void SDL_drawLine_AA( SDL_Surface *surf, int x1, int y1, int x2, int y2, 00187 Uint32 clr ) 00188 { 00189 SDL_drawLine_Alpha_AA(surf, x1, y1, x2, y2, clr, 255); 00190 } 00191 00192 00193 /* 00194 * draw lines with alpha blending 00195 */ 00196 void SDL_drawLine_Alpha( SDL_Surface *surf, int x1, int y1, int x2, int y2, 00197 Uint32 clr, Uint8 alpha ) 00198 { 00199 int x, y, dx, dy, c; 00200 float slope; 00201 00202 dx = x2 - x1; 00203 dy = y2 - y1; 00204 00205 slope = (float)dy / dx; 00206 00207 if (abs(dx) >= abs(dy)) { 00208 /* draw left/right - right/left */ 00209 c = (x1 <= x2) ? 1 : -1; 00210 for (x = x1; x != x2 + c; x += c) { 00211 y = y1 + ( (x - x1) * slope + 0.5 ); 00212 SDL_blendPixel(surf, x, y, clr, alpha); 00213 } 00214 } 00215 else { 00216 /* draw top/bottom - bottom/top */ 00217 c = (y1 <= y2) ? 1 : -1; 00218 for (y = y1; y != y2 + c; y += c) { 00219 x = x1 + ( (y - y1) / slope + 0.5 ); 00220 SDL_blendPixel(surf, x, y, clr, alpha); 00221 } 00222 } 00223 } 00224 00225 00226 /* 00227 * draw anti-aliased lines with alpha blending 00228 */ 00229 void SDL_drawLine_Alpha_AA( SDL_Surface *surf, int x1, int y1, int x2, int y2, 00230 Uint32 clr, Uint8 alpha ) 00231 { 00232 int x, y, dx, dy, c; 00233 float aa; 00234 float slope; 00235 00236 dx = x2 - x1; 00237 dy = y2 - y1; 00238 00239 /* alpha *= SDL_ALPHA_REDUCER; */ 00240 00241 slope = (float)dy / dx; 00242 00243 if (abs(dx) >= abs(dy)) { 00244 /* draw left/right - right/left */ 00245 c = (x1 <= x2) ? 1 : -1; 00246 for (x = x1; x != x2 + c; x += c) { 00247 /* 00248 * aa is the fill percentage of the pixel adjacent 00249 * the current one. same for below 00250 */ 00251 aa = y1 + ( (x - x1) * slope + 0.5 ); 00252 y = (int)aa; 00253 00254 aa = ( aa - y ) * alpha; 00255 00256 if (alpha > 254) 00257 SDL_putPixel(surf, x, y, clr); 00258 else 00259 SDL_blendPixel(surf, x, y, clr, alpha); 00260 SDL_blendPixel(surf, x, y + 1, clr, (int)aa); 00261 SDL_blendPixel(surf, x, y - 1, clr, alpha - (int)aa); 00262 } 00263 } 00264 else { 00265 /* draw top/bottom - bottom/top */ 00266 c = (y1 <= y2) ? 1 : -1; 00267 for (y = y1; y != y2 + c; y += c) { 00268 aa = x1 + ( (y - y1) / slope + 0.5 ); 00269 x = (int)aa; 00270 00271 aa = ( aa - x ) * alpha; 00272 00273 if (alpha > 254) 00274 SDL_putPixel(surf, x, y, clr); 00275 else 00276 SDL_blendPixel(surf, x, y, clr, alpha); 00277 SDL_blendPixel(surf, x + 1, y, clr, (int)aa); 00278 SDL_blendPixel(surf, x - 1, y, clr, alpha - (int)aa); 00279 } 00280 } 00281 } 00282 00283 00284 /* 00285 * draw a circle 00286 */ 00287 void SDL_drawCircle(SDL_Surface *surf, int x1, int y1, int r, Uint32 clr) 00288 { 00289 int x, y; 00290 00291 for (x = 0; x <= r / 1.4; x++) { 00292 y = 0.5 + sqrt( (r * r) - (x * x) ); 00293 SDL_putPixel(surf, x1 + x, y1 + y, clr); 00294 SDL_putPixel(surf, x1 + x, y1 + -1 * y, clr); 00295 SDL_putPixel(surf, x1 + -1 * x, y1 + -1 * y, clr); 00296 SDL_putPixel(surf, x1 + -1 * x, y1 + y, clr); 00297 00298 /* rotated 90 deg */ 00299 00300 SDL_putPixel(surf, x1 + y, y1 + x, clr); 00301 SDL_putPixel(surf, x1 + y, y1 + -1 * x, clr); 00302 SDL_putPixel(surf, x1 + -1 * y, y1 + -1 * x, clr); 00303 SDL_putPixel(surf, x1 + -1 * y, y1 + x, clr); 00304 } 00305 } 00306 00307 00308 /* 00309 * draw anti-aliased circle 00310 */ 00311 void SDL_drawCircle_AA(SDL_Surface *surf, int x1, int y1, int r, Uint32 clr) 00312 { 00313 SDL_drawCircle_Alpha_AA(surf, x1, y1, r, clr, 255); 00314 } 00315 00316 00317 /* 00318 * draw anti-aliased circle with alpha blending 00319 */ 00320 void SDL_drawCircle_Alpha_AA( SDL_Surface *surf, int x1, int y1, int r, 00321 Uint32 clr, Uint8 alpha ) 00322 { 00323 int x, y; 00324 float aa; 00325 00326 /* alpha *= SDL_ALPHA_REDUCER; */ 00327 00328 for (x = 0; x <= r; x++) { 00329 aa = sqrt( (r * r) - (x * x) ); 00330 y = (int)aa; 00331 aa = (aa - y) * alpha; 00332 00333 /* 00334 * x and y values converge 1/8 around the circle. 00335 * we're drawing around the circle 8 different ways, 00336 * so we need to stop to prevent overlapping. this is 00337 * very tricky as different radius circles will be off 00338 * by one. 00339 * 00340 * as is, this function currently misses anti-aliasing 00341 * 4 pixels on some circles. 00342 */ 00343 00344 if (x <= y) { 00345 SDL_blendPixel(surf, x1 + x, y1 + y, clr, alpha); 00346 SDL_blendPixel(surf, x1 + x, y1 + y + 1, clr, aa); 00347 00348 SDL_blendPixel(surf, x1 + x, y1 - y, clr, alpha); 00349 SDL_blendPixel(surf, x1 + x, y1 - y - 1, clr, aa); 00350 } 00351 if (x < y) { 00352 SDL_blendPixel(surf, x1 + x, y1 + y - 1, clr, alpha - aa); 00353 SDL_blendPixel(surf, x1 + x, y1 - y + 1, clr, alpha - aa); 00354 } 00355 00356 if (x > 0) { 00357 if (x <= y) { 00358 SDL_blendPixel(surf, x1 - x, y1 + y, clr, alpha); 00359 SDL_blendPixel(surf, x1 - x, y1 + y + 1, clr, aa); 00360 SDL_blendPixel(surf, x1 - x, y1 - y, clr, alpha); 00361 SDL_blendPixel(surf, x1 - x, y1 - y - 1, clr, aa); 00362 } 00363 00364 if (x < y) { 00365 SDL_blendPixel(surf, x1 - x, y1 + y - 1, clr, alpha - aa); 00366 SDL_blendPixel(surf, x1 - x, y1 - y + 1, clr, alpha - aa); 00367 } 00368 } 00369 00370 /* rotated 90deg */ 00371 00372 if (x < y) { 00373 SDL_blendPixel(surf, x1 + y, y1 + x, clr, alpha); 00374 SDL_blendPixel(surf, x1 + y + 1, y1 + x, clr, aa); 00375 SDL_blendPixel(surf, x1 + y - 1, y1 + x, clr, alpha - aa); 00376 00377 SDL_blendPixel(surf, x1 - y, y1 + x, clr, alpha); 00378 SDL_blendPixel(surf, x1 - y - 1, y1 + x, clr, aa); 00379 SDL_blendPixel(surf, x1 - y + 1, y1 + x, clr, alpha - aa); 00380 00381 if (x > 0) { 00382 SDL_blendPixel(surf, x1 + y, y1 - x, clr, alpha); 00383 SDL_blendPixel(surf, x1 + y + 1, y1 - x, clr, aa); 00384 SDL_blendPixel(surf, x1 + y - 1, y1 - x, clr, alpha - aa); 00385 00386 SDL_blendPixel(surf, x1 - y, y1 - x, clr, alpha); 00387 SDL_blendPixel(surf, x1 - y - 1, y1 - x, clr, aa); 00388 SDL_blendPixel(surf, x1 - y + 1, y1 - x, clr, alpha - aa); 00389 } 00390 } 00391 00392 if (x > y) 00393 break; 00394 } 00395 } 00396 00397 00398 /* 00399 * draw a filled circle 00400 */ 00401 void SDL_fillCircle(SDL_Surface *surf, int x1, int y1, int r, Uint32 clr) 00402 { 00403 int x, y; 00404 00405 SDL_putPixel(surf, x1, y1, clr); 00406 for (x = 0; x <= r / 1.4; x++) { 00407 for (y = 0.5 + sqrt( (r * r) - (x * x) ); y > 0; --y) { 00408 SDL_putPixel(surf, x1 + x, y1 + y, clr); 00409 SDL_putPixel(surf, x1 + x, y1 + -1 * y, clr); 00410 SDL_putPixel(surf, x1 + -1 * x, y1 + -1 * y, clr); 00411 SDL_putPixel(surf, x1 + -1 * x, y1 + y, clr); 00412 00413 /* rotated 90 deg */ 00414 00415 SDL_putPixel(surf, x1 + y, y1 + x, clr); 00416 SDL_putPixel(surf, x1 + y, y1 + -1 * x, clr); 00417 SDL_putPixel(surf, x1 + -1 * y, y1 + -1 * x, clr); 00418 SDL_putPixel(surf, x1 + -1 * y, y1 + x, clr); 00419 } 00420 } 00421 } 00422 00423 00424 00425 /* 00426 * draw anti-aliased filled circle 00427 */ 00428 void SDL_fillCircle_AA( SDL_Surface *surf, int x1, int y1, int r, Uint32 clr) 00429 { 00430 SDL_drawCircle_Alpha_AA(surf, x1, y1, r, clr, 255); 00431 SDL_fillCircle(surf, x1, y1, r - 1, clr); 00432 } 00433 00434 00435 /* 00436 * draw anti-aliased filled circle with alpha blending 00437 */ 00438 void _SDL_fillCircle_Alpha_AA( SDL_Surface *surf, int x1, int y1, int r, 00439 Uint32 clr, Uint8 alpha, int doaa ) 00440 { 00441 int x, y; 00442 float aa = 0, py; 00443 00444 for (x = 0; x <= r; x++) { 00445 py = aa; 00446 aa = sqrt( (r * r) - (x * x) ); 00447 y = (int)aa; 00448 aa = (aa - y) * alpha; 00449 00450 /* 00451 * this part is similar to the above draw_Alpha_AA, 00452 * but we only need to anti-alias the outer rim 00453 * of the circle because the rest will be filled 00454 */ 00455 if (x <= y && doaa) { 00456 SDL_blendPixel(surf, x1 + x, y1 + y + 1, clr, aa); 00457 SDL_blendPixel(surf, x1 - x, y1 + y + 1, clr, aa); 00458 SDL_blendPixel(surf, x1 + x, y1 - y - 1, clr, aa); 00459 SDL_blendPixel(surf, x1 - x, y1 - y - 1, clr, aa); 00460 00461 /* rotated 90 deg */ 00462 00463 SDL_blendPixel(surf, x1 + y + 1, y1 + x, clr, aa); 00464 SDL_blendPixel(surf, x1 - y - 1, y1 + x, clr, aa); 00465 SDL_blendPixel(surf, x1 + y + 1, y1 - x, clr, aa); 00466 SDL_blendPixel(surf, x1 - y - 1, y1 - x, clr, aa); 00467 } 00468 00469 /* fill the circle */ 00470 for (; y >= 0; y--) { 00471 SDL_blendPixel(surf, x1 + x, y1 + y, clr, alpha); 00472 if (y > 0) 00473 SDL_blendPixel(surf, x1 + x, y1 - y, clr, alpha); 00474 if (x > 0) { 00475 if (y > 0) 00476 SDL_blendPixel(surf, x1 - x, y1 + y, clr, alpha); 00477 SDL_blendPixel(surf, x1 - x, y1 - y, clr, alpha); 00478 } 00479 } 00480 } 00481 } 00482 00483 00484 /* 00485 * draw a filled circle with alpha blending, no aa 00486 */ 00487 void SDL_fillCircle_Alpha( SDL_Surface *surf, int x1, int y1, int r, 00488 Uint32 clr, Uint8 alpha ) 00489 { 00490 _SDL_fillCircle_Alpha_AA( surf, x1, y1, r, clr, alpha, 0 ); 00491 } 00492 00493 00494 /* 00495 * draw a filled circle with alpha blending and anti-aliasing 00496 */ 00497 void SDL_fillCircle_Alpha_AA( SDL_Surface *surf, int x1, int y1, int r, 00498 Uint32 clr, Uint8 alpha ) 00499 { 00500 _SDL_fillCircle_Alpha_AA( surf, x1, y1, r, clr, alpha, 1 ); 00501 } 00502 00503 00504 /* 00505 * draws a triangle 00506 */ 00507 void SDL_drawTriangle( SDL_Surface *surf, int x1, int y1, int x2, int y2, 00508 int x3, int y3, Uint32 clr ) 00509 { 00510 SDL_drawLine(surf, x1, y1, x2, y2, clr); 00511 SDL_drawLine(surf, x2, y2, x3, y3, clr); 00512 SDL_drawLine(surf, x3, y3, x1, y1, clr); 00513 } 00514 00515 00516 /* 00517 * draws an anti-aliased triangle 00518 */ 00519 void SDL_drawTriangle_AA( SDL_Surface *surf, int x1, int y1, int x2, int y2, 00520 int x3, int y3, Uint32 clr ) 00521 { 00522 SDL_drawLine_AA(surf, x1, y1, x2, y2, clr); 00523 SDL_drawLine_AA(surf, x2, y2, x3, y3, clr); 00524 SDL_drawLine_AA(surf, x3, y3, x1, y1, clr); 00525 } 00526 00527 00528 /* 00529 * draws an alpha-blended triangle 00530 */ 00531 void SDL_drawTriangle_Alpha( SDL_Surface *surf, int x1, int y1, int x2, int y2, 00532 int x3, int y3, Uint32 clr, Uint8 alpha ) 00533 { 00534 SDL_drawLine_Alpha(surf, x1, y1, x2, y2, clr, alpha); 00535 SDL_drawLine_Alpha(surf, x2, y2, x3, y3, clr, alpha); 00536 SDL_drawLine_Alpha(surf, x3, y3, x1, y1, clr, alpha); 00537 } 00538 00539 00540 /* 00541 * draws an alpha-blended anti-aliased triangle 00542 */ 00543 void SDL_drawTriangle_Alpha_AA( SDL_Surface *surf, int x1, int y1, int x2, 00544 int y2, int x3, int y3, Uint32 clr, 00545 Uint8 alpha ) 00546 { 00547 SDL_drawLine_Alpha_AA(surf, x1, y1, x2, y2, clr, alpha); 00548 SDL_drawLine_Alpha_AA(surf, x2, y2, x3, y3, clr, alpha); 00549 SDL_drawLine_Alpha_AA(surf, x3, y3, x1, y1, clr, alpha); 00550 } 00551 00552 00553 /* 00554 * draws a filled triangle 00555 */ 00556 void SDL_fillTriangle( SDL_Surface *surf, int x1, int y1, int x2, int y2, 00557 int x3, int y3, Uint32 clr ) 00558 { 00559 short int skipone = 1; 00560 int x, y, c, dx, dy, miny, maxy; 00561 float slope1, slope2, slope3; 00562 00563 /* 00564 * sort points by X coordinate so we can split the drawing 00565 * at a slope change 00566 */ 00567 while ( !(x1 <= x2 && x1 <= x3) ) { 00568 x = x1; 00569 y = y1; 00570 x1 = x2; 00571 y1 = y2; 00572 x2 = x3; 00573 y2 = y3; 00574 x3 = x; 00575 y3 = y; 00576 } 00577 while ( !(x2 <= x3) ) { 00578 x = x2; 00579 y = y2; 00580 x2 = x3; 00581 y2 = y3; 00582 x3 = x; 00583 y3 = y; 00584 } 00585 00586 dx = x3 - x1; 00587 dy = y3 - y1; 00588 slope1 = (float)dy / dx; 00589 00590 dx = x1 - x2; 00591 dy = y1 - y2; 00592 slope2 = (float)dy / dx; 00593 00594 dx = x2 - x3; 00595 dy = y2 - y3; 00596 slope3 = (float)dy / dx; 00597 00598 /* 00599 * draw between first two x,y coordinates 00600 */ 00601 if (x1 != x2) { 00602 for (x = x1; x <= x2; x++) { 00603 miny = y1 + ( (x - x1) * slope1 + 0.5 ); 00604 maxy = y2 + ( (x - x2) * slope2 + 0.5 ); 00605 c = (miny < maxy) ? 1 : -1; 00606 for (y = miny; y != maxy + c; y += c) { 00607 SDL_putPixel(surf, x, y, clr); 00608 } 00609 } 00610 } 00611 else 00612 skipone = 0; 00613 00614 /* 00615 * draw between second two x,y coordinates 00616 */ 00617 if (x2 != x3) { 00618 for (x = x2 + skipone; x <= x3; x++) { 00619 miny = y1 + ( (x - x1) * slope1 + 0.5 ); 00620 maxy = y3 + ( (x - x3) * slope3 + 0.5 ); 00621 c = (miny < maxy) ? 1 : -1; 00622 for (y = miny; y != maxy + c; y += c) { 00623 SDL_putPixel(surf, x, y, clr); 00624 } 00625 } 00626 } 00627 } 00628 00629 00630 /* 00631 * draw an anti-aliased filled triangle 00632 */ 00633 void SDL_fillTriangle_AA( SDL_Surface *surf, int x1, int y1, int x2, int y2, 00634 int x3, int y3, Uint32 clr ) 00635 { 00636 SDL_drawTriangle_AA( surf, x1, y1, x2, y2, x3, y3, clr ); 00637 SDL_fillTriangle( surf, x1, y1, x2, y2, x3, y3, clr ); 00638 } 00639 00640 00641 /* 00642 * draws a filled alpha-blended triangle 00643 */ 00644 void SDL_fillTriangle_Alpha( SDL_Surface *surf, int x1, int y1, int x2, int y2, 00645 int x3, int y3, Uint32 clr, Uint8 alpha ) 00646 { 00647 short int skipone = 1; 00648 int x, y, c, dx, dy, miny, maxy; 00649 float slope1, slope2, slope3; 00650 00651 /* 00652 * sort points by X coordinate so we can split the drawing 00653 * at a slope change 00654 */ 00655 while ( !(x1 <= x2 && x1 <= x3) ) { 00656 x = x1; 00657 y = y1; 00658 x1 = x2; 00659 y1 = y2; 00660 x2 = x3; 00661 y2 = y3; 00662 x3 = x; 00663 y3 = y; 00664 } 00665 while ( !(x2 <= x3) ) { 00666 x = x2; 00667 y = y2; 00668 x2 = x3; 00669 y2 = y3; 00670 x3 = x; 00671 y3 = y; 00672 } 00673 00674 dx = x3 - x1; 00675 dy = y3 - y1; 00676 slope1 = (float)dy / dx; 00677 00678 dx = x1 - x2; 00679 dy = y1 - y2; 00680 slope2 = (float)dy / dx; 00681 00682 dx = x2 - x3; 00683 dy = y2 - y3; 00684 slope3 = (float)dy / dx; 00685 00686 /* 00687 * draw between first two x,y coordinates 00688 */ 00689 if (x1 != x2) { 00690 for (x = x1; x <= x2; x++) { 00691 miny = y1 + ( (x - x1) * slope1 + 0.5 ); 00692 maxy = y2 + ( (x - x2) * slope2 + 0.5 ); 00693 c = (miny < maxy) ? 1 : -1; 00694 for (y = miny; y != maxy + c; y += c) { 00695 SDL_blendPixel(surf, x, y, clr, alpha); 00696 } 00697 } 00698 } 00699 else 00700 skipone = 0; 00701 00702 /* 00703 * draw between second two x,y coordinates 00704 */ 00705 if (x2 != x3) { 00706 for (x = x2 + skipone; x <= x3; x++) { 00707 miny = y1 + ( (x - x1) * slope1 + 0.5 ); 00708 maxy = y3 + ( (x - x3) * slope3 + 0.5 ); 00709 c = (miny < maxy) ? 1 : -1; 00710 for (y = miny; y != maxy + c; y += c) { 00711 SDL_blendPixel(surf, x, y, clr, alpha); 00712 } 00713 } 00714 } 00715 } 00716 00717 00718 /* 00719 * draws a filled anti-aliased alpha-blended triangle 00720 */ 00721 void SDL_fillTriangle_Alpha_AA( SDL_Surface *surf, int x1, int y1, int x2, 00722 int y2, int x3, int y3, Uint32 clr, 00723 Uint8 alpha ) 00724 { 00725 short int skipone = 1; 00726 int x, y, c, dx, dy, miny, maxy; 00727 float slope1, slope2, slope3; 00728 float minaa, maxaa; 00729 00730 /* 00731 * sort points by X coordinate so we can split the drawing 00732 * at a slope change 00733 */ 00734 while ( !(x1 <= x2 && x1 <= x3) ) { 00735 x = x1; 00736 y = y1; 00737 x1 = x2; 00738 y1 = y2; 00739 x2 = x3; 00740 y2 = y3; 00741 x3 = x; 00742 y3 = y; 00743 } 00744 while ( !(x2 <= x3) ) { 00745 x = x2; 00746 y = y2; 00747 x2 = x3; 00748 y2 = y3; 00749 x3 = x; 00750 y3 = y; 00751 } 00752 00753 dx = x3 - x1; 00754 dy = y3 - y1; 00755 slope1 = (float)dy / dx; 00756 00757 dx = x1 - x2; 00758 dy = y1 - y2; 00759 slope2 = (float)dy / dx; 00760 00761 dx = x2 - x3; 00762 dy = y2 - y3; 00763 slope3 = (float)dy / dx; 00764 00765 /* 00766 * draw between first two x,y coordinates 00767 */ 00768 if (x1 != x2) { 00769 for (x = x1; x <= x2; x++) { 00770 minaa = y1 + ( (x - x1) * slope1 ); 00771 maxaa = y2 + ( (x - x2) * slope2 ); 00772 00773 miny = (int)minaa; 00774 maxy = (int)maxaa; 00775 00776 minaa = (minaa - miny) * alpha; 00777 maxaa = (maxaa - maxy) * alpha; 00778 00779 c = (miny < maxy) ? 1 : -1; 00780 for (y = miny; y != maxy + c; y += c) { 00781 SDL_blendPixel(surf, x, y, clr, alpha); 00782 } 00783 if (c > 0) { 00784 SDL_blendPixel(surf, x, miny - c, clr, alpha - minaa); 00785 SDL_blendPixel(surf, x, maxy + c, clr, maxaa); 00786 } 00787 else { 00788 SDL_blendPixel(surf, x, miny - c, clr, minaa); 00789 SDL_blendPixel(surf, x, maxy + c, clr, alpha - maxaa); 00790 } 00791 } 00792 } 00793 else 00794 skipone = 0; 00795 00796 /* 00797 * draw between second two x,y coordinates 00798 */ 00799 if (x2 != x3) { 00800 for (x = x2 + skipone; x <= x3; x++) { 00801 minaa = y1 + ( (x - x1) * slope1 ); 00802 maxaa = y3 + ( (x - x3) * slope3 ); 00803 00804 miny = (int)minaa; 00805 maxy = (int)maxaa; 00806 00807 minaa = (minaa - miny) * alpha; 00808 maxaa = (maxaa - maxy) * alpha; 00809 00810 c = (miny < maxy) ? 1 : -1; 00811 for (y = miny; y != maxy + c; y += c) { 00812 SDL_blendPixel(surf, x, y, clr, alpha); 00813 } 00814 if (c > 0) { 00815 SDL_blendPixel(surf, x, miny - c, clr, alpha - minaa); 00816 SDL_blendPixel(surf, x, maxy + c, clr, maxaa); 00817 } 00818 else { 00819 SDL_blendPixel(surf, x, miny - c, clr, minaa); 00820 SDL_blendPixel(surf, x, maxy + c, clr, alpha - maxaa); 00821 } 00822 } 00823 } 00824 }

Generated for My SDL C++ Gui by doxygen 1.3.6

www.TV-friendship.com
The matchmaking service with an all new twist.

Quantum 'Teleportation'
Some thoughts
Page, code, and content Copyright (C) 2004 by Anders Hedström