PageRenderTime 72ms CodeModel.GetById 39ms app.highlight 28ms RepoModel.GetById 1ms app.codeStats 1ms

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