/opengles/src/linux-ftk/Surface.cpp

http://ftk.googlecode.com/ · C++ · 368 lines · 262 code · 60 blank · 46 comment · 44 complexity · 3dd5a09a56666a1f9c9cb70231215c4b MD5 · raw file

  1. // ==========================================================================
  2. //
  3. // Surface.cpp Drawing Surface Class for 3D Rendering Library
  4. //
  5. // --------------------------------------------------------------------------
  6. //
  7. // 08-14-2003 Hans-Martin Will initial version
  8. // 08-18-2010 Li XianJing Adapt to ftk
  9. //
  10. // --------------------------------------------------------------------------
  11. //
  12. // Copyright (c) 2004, Hans-Martin Will. All rights reserved.
  13. //
  14. // Redistribution and use in source and binary forms, with or without
  15. // modification, are permitted provided that the following conditions are
  16. // met:
  17. //
  18. // * Redistributions of source code must retain the above copyright
  19. // notice, this list of conditions and the following disclaimer.
  20. // * Redistributions in binary form must reproduce the above copyright
  21. // notice, this list of conditions and the following disclaimer in the
  22. // documentation and/or other materials provided with the distribution.
  23. //
  24. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  25. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27. // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  28. // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
  29. // OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  30. // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  31. // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  32. // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  33. // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  34. // THE POSSIBILITY OF SUCH DAMAGE.
  35. //
  36. // ==========================================================================
  37. #include "stdafx.h"
  38. #include "Surface.h"
  39. #include "Color.h"
  40. #include <string.h>
  41. using namespace EGL;
  42. Surface :: Surface(const Config & config, NativeDisplayType display, NativeWindowType win)
  43. : m_Config(config),
  44. m_Rect (0, 0, config.GetConfigAttrib(EGL_WIDTH),
  45. config.GetConfigAttrib(EGL_HEIGHT)),
  46. m_Display(NULL)
  47. {
  48. FtkColor bg = {0};
  49. U32 width = GetWidth();
  50. U32 height = GetHeight();
  51. m_Config.SetConfigAttrib(EGL_WIDTH, width);
  52. m_Config.SetConfigAttrib(EGL_HEIGHT, height);
  53. m_AlphaBuffer = new U8[width * height];
  54. m_DepthBuffer = new U16[width * height];
  55. m_StencilBuffer = new U32[width * height];
  56. m_ColorBuffer = new U16[width * height];
  57. bg.a = 0xff;
  58. m_Window = win;
  59. if(win != NULL)
  60. {
  61. m_Bitmap = ftk_bitmap_create(width, height, bg);
  62. }
  63. if (display != NULL)
  64. {
  65. m_Display = display;
  66. }
  67. else
  68. {
  69. m_Display = ftk_default_display();
  70. }
  71. return;
  72. }
  73. Surface :: ~Surface()
  74. {
  75. if (m_Bitmap)
  76. {
  77. ftk_bitmap_unref(m_Bitmap);
  78. m_Bitmap = NULL;
  79. }
  80. if (m_Display != NULL)
  81. {
  82. m_Display = NULL;
  83. }
  84. if(m_ColorBuffer != NULL)
  85. {
  86. delete m_ColorBuffer;
  87. m_ColorBuffer = NULL;
  88. }
  89. if (m_AlphaBuffer != 0)
  90. {
  91. delete [] m_AlphaBuffer;
  92. m_AlphaBuffer = 0;
  93. }
  94. if (m_DepthBuffer != 0)
  95. {
  96. delete[] m_DepthBuffer;
  97. m_DepthBuffer = 0;
  98. }
  99. if (m_StencilBuffer != 0)
  100. {
  101. delete[] m_StencilBuffer;
  102. m_StencilBuffer = 0;
  103. }
  104. return;
  105. }
  106. void Surface :: Dispose()
  107. {
  108. if (GetCurrentContext() != 0)
  109. {
  110. m_Disposed = true;
  111. }
  112. else
  113. {
  114. delete this;
  115. }
  116. }
  117. void Surface :: SetCurrentContext(Context * context)
  118. {
  119. m_CurrentContext = context;
  120. if (context == 0 && m_Disposed)
  121. {
  122. delete this;
  123. }
  124. }
  125. namespace {
  126. template <class T> void FillRect(T * base, const Rect & bufferRect,
  127. const Rect & fillRect,
  128. const T& value, const T& mask)
  129. {
  130. Rect rect = Rect::Intersect(fillRect, bufferRect);
  131. base += fillRect.x + fillRect.y * bufferRect.width;
  132. size_t gap = bufferRect.width - fillRect.width;
  133. size_t rows = fillRect.height;
  134. T inverseMask = ~mask;
  135. T maskedValue = value & mask;
  136. while (rows--)
  137. {
  138. for (size_t columns = fillRect.width; columns > 0; columns--)
  139. {
  140. *base = (*base & inverseMask) | maskedValue;
  141. ++base;
  142. }
  143. base += gap;
  144. }
  145. }
  146. template <class T> void FillRect(T * base, const Rect & bufferRect,
  147. const Rect & fillRect,
  148. const T& value)
  149. {
  150. Rect rect = Rect::Intersect(fillRect, bufferRect);
  151. base += fillRect.x + fillRect.y * bufferRect.width;
  152. size_t gap = bufferRect.width - fillRect.width;
  153. size_t rows = fillRect.height;
  154. while (rows--)
  155. {
  156. for (size_t columns = fillRect.width; columns > 0; columns--)
  157. {
  158. *base = value;
  159. ++base;
  160. }
  161. base += gap;
  162. }
  163. }
  164. }
  165. void Surface :: ClearDepthBuffer(U16 depth, bool mask, const Rect& scissor)
  166. {
  167. if (!mask || !m_DepthBuffer)
  168. return;
  169. FillRect(m_DepthBuffer, GetRect(), scissor, depth);
  170. }
  171. void Surface :: ClearStencilBuffer(U32 value, U32 mask, const Rect& scissor)
  172. {
  173. if (!mask || !m_StencilBuffer)
  174. return;
  175. if (mask != ~0)
  176. {
  177. FillRect(m_StencilBuffer, GetRect(), scissor, value, mask);
  178. }
  179. else
  180. {
  181. FillRect(m_StencilBuffer, GetRect(), scissor, value);
  182. }
  183. }
  184. /*
  185. I32 Surface :: DepthBitsFromDepth(GLclampx depth) {
  186. I32 result;
  187. gppMul_16_32s(EGL_CLAMP(depth, EGL_FIXED_0, EGL_FIXED_1), 0xffffff, &result);
  188. return result;
  189. }
  190. */
  191. void Surface :: ClearColorBuffer(const Color & rgba, const Color & mask,
  192. const Rect& scissor)
  193. {
  194. U16 color = rgba.ConvertTo565();
  195. U16 colorMask = mask.ConvertTo565();
  196. if (colorMask == 0xffff)
  197. {
  198. FillRect(m_ColorBuffer, GetRect(), scissor, color);
  199. }
  200. else
  201. {
  202. FillRect(m_ColorBuffer, GetRect(), scissor, color, colorMask);
  203. }
  204. if (mask.A() && m_AlphaBuffer)
  205. FillRect(m_AlphaBuffer, GetRect(), scissor, rgba.A());
  206. }
  207. /*
  208. * For debugging
  209. */
  210. #define BI_BITFIELDS 3
  211. typedef struct tagBITMAPINFOHEADER
  212. {
  213. int biSize;
  214. long biWidth;
  215. long biHeight;
  216. short biPlanes;
  217. short biBitCount;
  218. int biCompression;
  219. int biSizeImage;
  220. long biXPelsPerMeter;
  221. long biYPelsPerMeter;
  222. int biClrUsed;
  223. int biClrImportant;
  224. } BITMAPINFOHEADER;
  225. struct InfoHeader
  226. {
  227. BITMAPINFOHEADER bmiHeader;
  228. short bmiColors[3];
  229. };
  230. typedef struct tagBITMAPFILEHEADER {
  231. short bfType;
  232. int bfSize;
  233. short bfReserved1;
  234. short bfReserved2;
  235. int bfOffBits;
  236. } BITMAPFILEHEADER;
  237. void InitInfoHeader(struct InfoHeader *h, int width, int height)
  238. {
  239. h->bmiHeader.biSize = sizeof(h->bmiHeader);
  240. h->bmiHeader.biWidth = width;
  241. h->bmiHeader.biHeight = height;
  242. h->bmiHeader.biPlanes = 1;
  243. h->bmiHeader.biBitCount = 16;
  244. h->bmiHeader.biCompression = BI_BITFIELDS;
  245. h->bmiHeader.biSizeImage = width * height * sizeof(short);
  246. h->bmiHeader.biXPelsPerMeter = 72 * 25;
  247. h->bmiHeader.biYPelsPerMeter = 72 * 25;
  248. h->bmiHeader.biClrUsed = 0;
  249. h->bmiHeader.biClrImportant = 0;
  250. h->bmiColors[0] = 0xF800;
  251. h->bmiColors[1] = 0x07E0;
  252. h->bmiColors[2] = 0x001F;
  253. }
  254. #include <sys/types.h>
  255. #include <sys/stat.h>
  256. #include <fcntl.h>
  257. #include <unistd.h>
  258. bool Surface::Save(const char *filename)
  259. {
  260. struct InfoHeader info;
  261. BITMAPFILEHEADER header;
  262. int fd= open(filename, O_RDWR|O_CREAT|O_TRUNC, 0666);
  263. U16 *pixels;
  264. U8 data;
  265. int h;
  266. InitInfoHeader(&info, GetWidth(), GetHeight());
  267. header.bfType = 0x4d42;
  268. header.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(info) +
  269. info.bmiHeader.biSizeImage;
  270. header.bfReserved1 = 0;
  271. header.bfReserved2 = 0;
  272. header.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(info);
  273. printf("Saving image %s, %ux%u, %u\n", filename, info.bmiHeader.biWidth,
  274. info.bmiHeader.biHeight,
  275. info.bmiHeader.biSizeImage);
  276. printf("size %u, offset %u\n", header.bfSize, header.bfOffBits);
  277. if (fd < 3)
  278. {
  279. fprintf(stderr, "Could not open file %s for writing\n", filename);
  280. return false;
  281. }
  282. if (write(fd, (const char *)&header, sizeof(header)) != sizeof(header))
  283. {
  284. fprintf(stderr, "Error writing bitmap %s header\n", filename);
  285. close(fd);
  286. return false;
  287. }
  288. if (write(fd, (const char *)&info, sizeof(info)) != sizeof(info))
  289. {
  290. fprintf(stderr, "Error writing bitmap %s info\n", filename);
  291. close(fd);
  292. return false;
  293. }
  294. pixels = m_ColorBuffer;
  295. for (h = GetHeight(); h; --h)
  296. {
  297. if (write(fd, (const char *)pixels, sizeof(U16)*GetWidth()) !=
  298. sizeof(U16)*GetWidth())
  299. {
  300. fprintf(stderr, "Error writing bitmap %s data\n", filename);
  301. close(fd);
  302. return false;
  303. }
  304. pixels += GetWidth();
  305. }
  306. close(fd);
  307. return true;
  308. }