/win32_gl_mask_test.d

http://github.com/AndrejMitrovic/cairoDSamples · D · 273 lines · 214 code · 50 blank · 9 comment · 3 complexity · 80a410061fecdada87e0394089d6c246 MD5 · raw file

  1. module win32_gl_mask_test;
  2. /+
  3. + Copyright Andrej Mitrovic 2011.
  4. + Distributed under the Boost Software License, Version 1.0.
  5. + (See accompanying file LICENSE_1_0.txt or copy at
  6. + http://www.boost.org/LICENSE_1_0.txt)
  7. +/
  8. import core.memory;
  9. import core.runtime;
  10. import core.thread;
  11. import std.conv;
  12. import std.math;
  13. import std.algorithm;
  14. import std.datetime;
  15. import std.array;
  16. import std.stdio;
  17. import std.range;
  18. import std.string;
  19. import std.utf;
  20. pragma(lib, "gdi32.lib");
  21. pragma(lib, "comdlg32.lib");
  22. pragma(lib, "winmm.lib");
  23. import win32.windef;
  24. import win32.winuser;
  25. import win32.wingdi;
  26. import win32.winbase;
  27. import win32.commdlg;
  28. import win32.mmsystem;
  29. import cairo.cairo;
  30. import cairo.win32;
  31. import cairo.gl;
  32. alias cairo.cairo.RGB RGB;
  33. alias std.algorithm.max max;
  34. alias std.algorithm.min min;
  35. string appName = "CairoGL";
  36. string description = "CairoGL Mask Test";
  37. HINSTANCE hinst;
  38. extern (Windows)
  39. int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
  40. {
  41. int result;
  42. void exceptionHandler(Throwable e) { throw e; }
  43. try
  44. {
  45. Runtime.initialize(&exceptionHandler);
  46. result = myWinMain(hInstance, hPrevInstance, lpCmdLine, iCmdShow);
  47. Runtime.terminate(&exceptionHandler);
  48. }
  49. catch (Throwable o)
  50. {
  51. MessageBox(null, o.toString().toUTF16z, "Error", MB_OK | MB_ICONEXCLAMATION);
  52. result = 0;
  53. }
  54. return result;
  55. }
  56. int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
  57. {
  58. hinst = hInstance;
  59. HACCEL hAccel;
  60. HWND hwnd;
  61. MSG msg;
  62. WNDCLASS wndclass;
  63. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  64. wndclass.lpfnWndProc = &WndProc;
  65. wndclass.cbClsExtra = 0;
  66. wndclass.cbWndExtra = 0;
  67. wndclass.hInstance = hInstance;
  68. wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  69. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  70. wndclass.hbrBackground = cast(HBRUSH) GetStockObject(WHITE_BRUSH);
  71. wndclass.lpszMenuName = appName.toUTF16z;
  72. wndclass.lpszClassName = appName.toUTF16z;
  73. if (!RegisterClass(&wndclass))
  74. {
  75. MessageBox(NULL, "This program requires Windows NT!", appName.toUTF16z, MB_ICONERROR);
  76. return 0;
  77. }
  78. hwnd = CreateWindow(appName.toUTF16z, // window class name
  79. description.toUTF16z, // window caption
  80. WS_OVERLAPPEDWINDOW, // window style
  81. CW_USEDEFAULT, // initial x position
  82. CW_USEDEFAULT, // initial y position
  83. CW_USEDEFAULT, // initial x size
  84. CW_USEDEFAULT, // initial y size
  85. NULL, // parent window handle
  86. NULL, // window menu handle
  87. hInstance, // program instance handle
  88. NULL); // creation parameters
  89. ShowWindow(hwnd, iCmdShow);
  90. UpdateWindow(hwnd);
  91. while (GetMessage(&msg, NULL, 0, 0))
  92. {
  93. TranslateMessage(&msg);
  94. DispatchMessage(&msg);
  95. }
  96. return msg.wParam;
  97. }
  98. extern (Windows)
  99. LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  100. {
  101. switch (message)
  102. {
  103. case WM_CREATE:
  104. self = new Window(hwnd); break;
  105. case WM_DESTROY:
  106. return self.OnDestroy(hwnd, message, wParam, lParam);
  107. case WM_PAINT:
  108. return self.OnPaint(hwnd, message, wParam, lParam);
  109. case WM_ERASEBKGND:
  110. return self.OnBackgroundErase(hwnd, message, wParam, lParam);
  111. case WM_SIZE:
  112. {
  113. auto cxClient = LOWORD(lParam);
  114. auto cyClient = HIWORD(lParam);
  115. return self.newSize(cxClient, cyClient);
  116. }
  117. default:
  118. }
  119. return DefWindowProc(hwnd, message, wParam, lParam);
  120. }
  121. Window self;
  122. class Window
  123. {
  124. HWND hwnd;
  125. PAINTSTRUCT ps;
  126. RECT rc;
  127. HDC hdc;
  128. HGLRC hglrc;
  129. int cxClient, cyClient;
  130. GLSurface surf;
  131. GLDevice device;
  132. bool newSize(ushort newX, ushort newY)
  133. {
  134. cxClient = newX;
  135. cyClient = newY;
  136. Render();
  137. return 0;
  138. }
  139. this(HWND hwnd)
  140. {
  141. this.hwnd = hwnd;
  142. hdc = GetDC(hwnd);
  143. PIXELFORMATDESCRIPTOR pfd = PIXELFORMATDESCRIPTOR(
  144. PIXELFORMATDESCRIPTOR.sizeof,
  145. 1, // version number
  146. PFD_DRAW_TO_WINDOW | // support window
  147. PFD_SUPPORT_OPENGL | // support OpenGL
  148. PFD_DOUBLEBUFFER, // double buffered
  149. PFD_TYPE_RGBA, // RGBA type
  150. 24, // 24-bit color depth
  151. 0, 0, 0, 0, 0, 0, // color bits ignored
  152. 0, // no alpha buffer
  153. 0, // shift bit ignored
  154. 0, // no accumulation buffer
  155. 0, 0, 0, 0, // accum bits ignored
  156. 32, // 32-bit z-buffer
  157. 0, // no stencil buffer
  158. 0, // no auxiliary buffer
  159. PFD_TYPE_RGBA, // main layer
  160. 0, // reserved
  161. 0, 0, 0 // layer masks ignored
  162. );
  163. // get the best available match of the pixel format for the device context
  164. int iPixelFormat = ChoosePixelFormat(hdc, &pfd);
  165. // use it
  166. SetPixelFormat(hdc, iPixelFormat, &pfd);
  167. // create a rendering context
  168. hglrc = wglCreateContext(hdc);
  169. device = new GLDevice(hglrc);
  170. ReleaseDC(hwnd, hdc);
  171. }
  172. void Render()
  173. {
  174. InvalidateRect(this.hwnd, NULL, TRUE);
  175. }
  176. int OnPaint(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  177. {
  178. hdc = BeginPaint(hwnd, &ps);
  179. surf = new GLSurface(device, hdc, cxClient, cyClient);
  180. auto ctx = Context(surf);
  181. ctx.setSourceRGB(1, 1, 1);
  182. ctx.paint();
  183. ctx.scale(cxClient, cyClient);
  184. ctx.moveTo(0, 0);
  185. ctx.rectangle(0, 0, 1, 1);
  186. ctx.setSourceRGBA(1, 1, 1, 0);
  187. ctx.setOperator(Operator.CAIRO_OPERATOR_CLEAR);
  188. ctx.fill();
  189. ctx.setSourceRGB(0, 0, 0);
  190. ctx.setOperator(Operator.CAIRO_OPERATOR_OVER);
  191. auto linpat = new LinearGradient(0, 0, 1, 1);
  192. linpat.addColorStopRGB(0, RGB(0, 0.3, 0.8));
  193. linpat.addColorStopRGB(1, RGB(0, 0.8, 0.3));
  194. auto radpat = new RadialGradient(0.5, 0.5, 0.25, 0.5, 0.5, 0.75);
  195. radpat.addColorStopRGBA(0, RGBA(0, 0, 0, 1));
  196. radpat.addColorStopRGBA(0.5, RGBA(0, 0, 0, 0));
  197. ctx.setSource(linpat);
  198. {
  199. StopWatch sw;
  200. sw.start();
  201. scope(exit)
  202. {
  203. sw.stop();
  204. writefln("Done in usecs: %s.", sw.peek().usecs);
  205. sw.reset();
  206. }
  207. ctx.mask(radpat);
  208. }
  209. surf.swapBuffers();
  210. surf.finish();
  211. EndPaint(hwnd, &ps);
  212. return 0;
  213. }
  214. auto OnBackgroundErase(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  215. {
  216. return 0;
  217. }
  218. auto OnDestroy(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  219. {
  220. PostQuitMessage(0);
  221. return 0;
  222. }
  223. }