cm_draw.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // CDraw32 Class Interface
  3. //
  4. // Basic drawing routines for 32-bit per pixel buffer
  5. ///////////////////////////////////////////////////////////////////////////////
  6. #if !defined(CM_DRAW_H_INC)
  7. #define CM_DRAW_H_INC
  8. // calc offset into image array for a pixel at (x,y)
  9. #define PIXPOS(x,y,stride) (((y)*(stride))+(x))
  10. #ifndef MIN
  11. // handy macros
  12. #define MIN(a,b) ((a) < (b) ? (a) : (b))
  13. #define MAX(a,b) ((a) > (b) ? (a) : (b))
  14. #define ABS(x) ((x)<0 ? -(x):(x))
  15. #define SIGN(x) (((x) < 0) ? -1 : (((x) > 0) ? 1 : 0))
  16. #endif
  17. #ifndef CLAMP
  18. #define SWAP(a,b) { a^=b; b^=a; a^=b; }
  19. #define SQR(a) ((a)*(a))
  20. #define CLAMP(v,l,h) ((v)<(l) ? (l) : (v) > (h) ? (h) : (v))
  21. #define LERP(t, a, b) (((b)-(a))*(t) + (a))
  22. // round a to nearest integer towards 0
  23. #define FLOOR(a) ((a)>0 ? (int)(a) : -(int)(-a))
  24. // round a to nearest integer away from 0
  25. #define CEILING(a) \
  26. ((a)==(int)(a) ? (a) : (a)>0 ? 1+(int)(a) : -(1+(int)(-a)))
  27. #include <stdlib.h>
  28. #endif
  29. class CPixel32
  30. {
  31. public:
  32. byte r;
  33. byte g;
  34. byte b;
  35. byte a;
  36. CPixel32(byte R = 0, byte G = 0, byte B = 0, byte A = 255) : r(R), g(G), b(B), a(A) {}
  37. CPixel32(long l) {r = (l >> 24) & 0xff; g = (l >> 16) & 0xff; b = (l >> 8) & 0xff; a = l & 0xff;};
  38. ~CPixel32()
  39. {}
  40. };
  41. #define PIX32_SIZE sizeof(CPixel32)
  42. // standard image operator macros
  43. #define IMAGE_SIZE(width,height) ((width)*(height)*(PIX32_SIZE))
  44. inline CPixel32 AVE_PIX (CPixel32 x, CPixel32 y)
  45. { CPixel32 t; t.r = (byte)(((int)x.r + (int)y.r)>>1);
  46. t.g = (byte)(((int)x.g + (int)y.g)>>1);
  47. t.b = (byte)(((int)x.b + (int)y.b)>>1);
  48. t.a = (byte)(((int)x.a + (int)y.a)>>1); return t;}
  49. inline CPixel32 ALPHA_PIX (CPixel32 x, CPixel32 y, long alpha, long inv_alpha)
  50. { CPixel32 t; t.r = (byte)((x.r*alpha + y.r*inv_alpha)>>8);
  51. t.g = (byte)((x.g*alpha + y.g*inv_alpha)>>8);
  52. t.b = (byte)((x.b*alpha + y.b*inv_alpha)>>8);
  53. // t.a = (byte)((x.a*alpha + y.a*inv_alpha)>>8); return t;}
  54. t.a = y.a; return t;}
  55. inline CPixel32 LIGHT_PIX (CPixel32 p, long light)
  56. { CPixel32 t;
  57. t.r = (byte)CLAMP(((p.r * light)>>10) + p.r, 0, 255);
  58. t.g = (byte)CLAMP(((p.g * light)>>10) + p.g, 0, 255);
  59. t.b = (byte)CLAMP(((p.b * light)>>10) + p.b, 0, 255);
  60. t.a = p.a; return t;}
  61. // Colors are 32-bit RGBA
  62. // draw class
  63. class CDraw32
  64. {
  65. public: // static drawing context - static so we set only ONCE for many draw calls
  66. static CPixel32* buffer; // pointer to pixel buffer (one active)
  67. static long buf_width; // size of buffer
  68. static long buf_height; // size of buffer
  69. static long stride; // stride of buffer in pixels
  70. static long clip_min_x; // clip bounds
  71. static long clip_min_y; // clip bounds
  72. static long clip_max_x; // clip bounds
  73. static long clip_max_y; // clip bounds
  74. static long* row_off; // Table for quick Y calculations
  75. private:
  76. void BlitClip(long& dstX, long& dstY,
  77. long& width, long& height,
  78. long& srcX, long& srcY);
  79. protected:
  80. public:
  81. CDraw32(); // constructor
  82. ~CDraw32(); // destructor
  83. // set the rect to clip drawing functions to
  84. static void SetClip(long min_x, long min_y,long max_x, long max_y)
  85. {clip_min_x = MAX(min_x,0); clip_max_x = MIN(max_x,buf_width-1);
  86. clip_min_y = MAX(min_y,0); clip_max_y = MIN(max_y,buf_height-1);}
  87. static void GetClip(long& min_x, long& min_y,long& max_x, long& max_y)
  88. {min_x = clip_min_x; min_y = clip_min_y;
  89. max_x = clip_max_x; max_y = clip_max_y; }
  90. // set the buffer to use for drawing off-screen
  91. static void SetBuffer(CPixel32* buf) {buffer = buf;};
  92. // set the dimensions of the off-screen buffer
  93. static bool SetBufferSize(long width,long height,long stride_len);
  94. // call this to free the table for quick y calcs before the program ends
  95. static void CleanUp(void)
  96. {if (row_off) delete [] row_off; row_off=NULL; buf_width=0; buf_height=0;}
  97. // set a pixel at (x,y) to color (no clipping)
  98. void PutPixNC(long x, long y, CPixel32 color)
  99. {buffer[row_off[y] + x] = color;}
  100. // set a pixel at (x,y) to color
  101. void PutPix(long x, long y, CPixel32 color)
  102. { // clipping check
  103. if (x < clip_min_x || x > clip_max_x ||
  104. y < clip_min_y || y > clip_max_y)
  105. return;
  106. PutPixNC(x,y,color);
  107. }
  108. // get the color of a pixel at (x,y)
  109. CPixel32 GetPix(long x, long y)
  110. {return buffer[row_off[y] + x];}
  111. // set a pixel at (x,y) with 50% translucency (no clip)
  112. void PutPixAveNC(long x, long y, CPixel32 color)
  113. { PutPixNC(x,y,AVE_PIX(GetPix(x, y), color)); }
  114. // set a pixel at (x,y) with 50% translucency
  115. void PutPixAve(long x, long y, CPixel32 color)
  116. { // clipping check
  117. if (x < clip_min_x || x > clip_max_x ||
  118. y < clip_min_y || y > clip_max_y)
  119. return;
  120. PutPixNC(x,y,AVE_PIX(GetPix(x, y), color));
  121. }
  122. // set a pixel at (x,y) with translucency level (no clip)
  123. void PutPixAlphaNC(long x, long y, CPixel32 color)
  124. { PutPixNC(x,y,ALPHA_PIX(color, GetPix(x, y), color.a, 256-color.a));}
  125. // set a pixel at (x,y) with translucency level
  126. void PutPixAlpha(long x, long y, CPixel32 color)
  127. { // clipping check
  128. if (x < clip_min_x || x > clip_max_x ||
  129. y < clip_min_y || y > clip_max_y)
  130. return;
  131. PutPixNC(x,y,ALPHA_PIX(color, GetPix(x, y), color.a, 256-color.a));}
  132. // clear screen buffer to color from start to end line
  133. void ClearLines(CPixel32 color,long start,long end);
  134. // clear screen buffer to color provided
  135. void ClearBuffer(CPixel32 color)
  136. {ClearLines(color,0,buf_height-1);};
  137. // fill buffer alpha from start to end line
  138. void SetAlphaLines(byte alpha,long start,long end);
  139. // clear screen buffer to color provided
  140. void SetAlphaBuffer(byte alpha)
  141. {SetAlphaLines(alpha,0,buf_height-1);};
  142. // clip a line segment to the clip rect
  143. bool ClipLine(long& x1, long& y1, long& x2, long& y2);
  144. // draw a solid colored line, no clipping
  145. void DrawLineNC(long x1, long y1, long x2, long y2, CPixel32 color);
  146. // draw a solid color line
  147. void DrawLine(long x1, long y1, long x2, long y2, CPixel32 color)
  148. { if (ClipLine(x1,y1,x2,y2)) DrawLineNC(x1,y1,x2,y2,color);}
  149. void DrawLineAveNC(long x1, long y1, long x2, long y2, CPixel32 color);
  150. // draw a translucent solid color line
  151. void DrawLineAve(long x1, long y1, long x2, long y2, CPixel32 color)
  152. { if (ClipLine(x1,y1,x2,y2)) DrawLineAveNC(x1,y1,x2,y2,color);}
  153. // draw an anti-aliased line, no clipping
  154. void DrawLineAANC(long x0, long y0, long x1, long y1, CPixel32 color);
  155. // draw an anti-aliased line
  156. void DrawLineAA(long x1, long y1, long x2, long y2, CPixel32 color)
  157. { if (ClipLine(x1,y1,x2,y2)) DrawLineAANC(x1,y1,x2,y2,color);}
  158. // draw a filled rectangle, no clipping
  159. void DrawRectNC(long ulx, long uly, long width, long height,CPixel32 color);
  160. // draw a filled rectangle
  161. void DrawRect(long ulx, long uly, long width, long height, CPixel32 color);
  162. // draw a filled rectangle
  163. void DrawRectAve(long ulx, long uly, long width, long height,CPixel32 color);
  164. // draw a box (unfilled rectangle) no clip
  165. void DrawBoxNC(long ulx, long uly, long width, long height, CPixel32 color);
  166. // draw a box (unfilled rectangle)
  167. void DrawBox(long ulx, long uly, long width, long height, CPixel32 color);
  168. // draw a box (unfilled rectangle)
  169. void DrawBoxAve(long ulx, long uly, long width, long height, CPixel32 color);
  170. // draw a circle with fill and edge colors
  171. void DrawCircle(long xc, long yc, long r, CPixel32 edge, CPixel32 fill);
  172. // draw a circle with fill and edge colors averaged with dest
  173. void DrawCircleAve(long xc, long yc, long r, CPixel32 edge, CPixel32 fill);
  174. // draw a polygon (complex) with fill and edge colors
  175. void DrawPolygon(long nvert, POINT *point, CPixel32 edge, CPixel32 fill);
  176. // simple blit function
  177. void BlitNC(long dstX, long dstY, long dstWidth, long dstHeight,
  178. CPixel32* srcImage, long srcX, long srcY, long srcStride);
  179. void Blit(long dstX, long dstY, long dstWidth, long dstHeight,
  180. CPixel32* srcImage, long srcX, long srcY, long srcStride);
  181. // blit image times color
  182. void BlitColor(long dstX, long dstY, long dstWidth, long dstHeight,
  183. CPixel32* srcImage, long srcX, long srcY, long srcStride, CPixel32 color);
  184. void Emboss(long dstX, long dstY, long width, long height,
  185. CPixel32* clrImage, long clrX, long clrY, long clrStride);
  186. };
  187. ///////////////////////////////////////////////////////////////////////////////
  188. #endif