root/OpenSceneGraph/trunk/src/osgViewer/PixelBufferWin32.cpp @ 13130

Revision 13130, 25.5 kB (checked in by robert, 16 hours ago)

Added .tf & .tf-255 plugin for reading ascii 1D transfer functon files in support for volume rendering.

  • Property svn:eol-style set to native
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12 *
13 * Some elements of GraphicsWindowWin32 have used the Producer implementation as a reference.
14 * These elements are licensed under OSGPL as above, with Copyright (C) 2001-2004  Don Burns.
15 */
16
17#include <osgViewer/api/Win32/PixelBufferWin32>
18#include <osgViewer/api/Win32/GraphicsWindowWin32>
19#include <osg/TextureRectangle>
20
21#include <vector>
22#include <map>
23#include <sstream>
24#include <windowsx.h>
25
26#ifndef WGL_ARB_pbuffer
27#define WGL_ARB_pbuffer 1
28DECLARE_HANDLE(HPBUFFERARB);
29#define WGL_DRAW_TO_PBUFFER_ARB             0x202D
30#define WGL_MAX_PBUFFER_PIXELS_ARB          0x202E
31#define WGL_MAX_PBUFFER_WIDTH_ARB           0x202F
32#define WGL_MAX_PBUFFER_HEIGHT_ARB          0x2030
33#define WGL_PBUFFER_LARGEST_ARB             0x2033
34#define WGL_PBUFFER_WIDTH_ARB               0x2034
35#define WGL_PBUFFER_HEIGHT_ARB              0x2035
36#define WGL_PBUFFER_LOST_ARB                0x2036
37#endif
38
39#ifndef WGL_ARB_pixel_format
40#define WGL_ARB_pixel_format 1
41#define WGL_NUMBER_PIXEL_FORMATS_ARB        0x2000
42#define WGL_DRAW_TO_WINDOW_ARB              0x2001
43#define WGL_DRAW_TO_BITMAP_ARB              0x2002
44#define WGL_ACCELERATION_ARB                0x2003
45#define WGL_NEED_PALETTE_ARB                0x2004
46#define WGL_NEED_SYSTEM_PALETTE_ARB         0x2005
47#define WGL_SWAP_LAYER_BUFFERS_ARB          0x2006
48#define WGL_SWAP_METHOD_ARB                 0x2007
49#define WGL_NUMBER_OVERLAYS_ARB             0x2008
50#define WGL_NUMBER_UNDERLAYS_ARB            0x2009
51#define WGL_TRANSPARENT_ARB                 0x200A
52#define WGL_TRANSPARENT_RED_VALUE_ARB       0x2037
53#define WGL_TRANSPARENT_GREEN_VALUE_ARB     0x2038
54#define WGL_TRANSPARENT_BLUE_VALUE_ARB      0x2039
55#define WGL_TRANSPARENT_ALPHA_VALUE_ARB     0x203A
56#define WGL_TRANSPARENT_INDEX_VALUE_ARB     0x203B
57#define WGL_SHARE_DEPTH_ARB                 0x200C
58#define WGL_SHARE_STENCIL_ARB               0x200D
59#define WGL_SHARE_ACCUM_ARB                 0x200E
60#define WGL_SUPPORT_GDI_ARB                 0x200F
61#define WGL_SUPPORT_OPENGL_ARB              0x2010
62#define WGL_DOUBLE_BUFFER_ARB               0x2011
63#define WGL_STEREO_ARB                      0x2012
64#define WGL_PIXEL_TYPE_ARB                  0x2013
65#define WGL_COLOR_BITS_ARB                  0x2014
66#define WGL_RED_BITS_ARB                    0x2015
67#define WGL_RED_SHIFT_ARB                   0x2016
68#define WGL_GREEN_BITS_ARB                  0x2017
69#define WGL_GREEN_SHIFT_ARB                 0x2018
70#define WGL_BLUE_BITS_ARB                   0x2019
71#define WGL_BLUE_SHIFT_ARB                  0x201A
72#define WGL_ALPHA_BITS_ARB                  0x201B
73#define WGL_ALPHA_SHIFT_ARB                 0x201C
74#define WGL_ACCUM_BITS_ARB                  0x201D
75#define WGL_ACCUM_RED_BITS_ARB              0x201E
76#define WGL_ACCUM_GREEN_BITS_ARB            0x201F
77#define WGL_ACCUM_BLUE_BITS_ARB             0x2020
78#define WGL_ACCUM_ALPHA_BITS_ARB            0x2021
79#define WGL_DEPTH_BITS_ARB                  0x2022
80#define WGL_STENCIL_BITS_ARB                0x2023
81#define WGL_AUX_BUFFERS_ARB                 0x2024
82#define WGL_NO_ACCELERATION_ARB             0x2025
83#define WGL_GENERIC_ACCELERATION_ARB        0x2026
84#define WGL_FULL_ACCELERATION_ARB           0x2027
85#define WGL_SWAP_EXCHANGE_ARB               0x2028
86#define WGL_SWAP_COPY_ARB                   0x2029
87#define WGL_SWAP_UNDEFINED_ARB              0x202A
88#define WGL_TYPE_RGBA_ARB                   0x202B
89#define WGL_TYPE_COLORINDEX_ARB             0x202C
90#define WGL_SAMPLE_BUFFERS_ARB                0x2041
91#define WGL_SAMPLES_ARB                        0x2042
92#endif
93
94#ifndef WGL_ARB_render_texture
95#define WGL_ARB_render_texture 1
96#define WGL_BIND_TO_TEXTURE_RGB_ARB         0x2070
97#define WGL_BIND_TO_TEXTURE_RGBA_ARB        0x2071
98#define WGL_TEXTURE_FORMAT_ARB              0x2072
99#define WGL_TEXTURE_TARGET_ARB              0x2073
100#define WGL_MIPMAP_TEXTURE_ARB              0x2074
101#define WGL_TEXTURE_RGB_ARB                 0x2075
102#define WGL_TEXTURE_RGBA_ARB                0x2076
103#define WGL_NO_TEXTURE_ARB                  0x2077
104#define WGL_TEXTURE_CUBE_MAP_ARB            0x2078
105#define WGL_TEXTURE_1D_ARB                  0x2079
106#define WGL_TEXTURE_2D_ARB                  0x207A
107#define WGL_MIPMAP_LEVEL_ARB                0x207B
108#define WGL_CUBE_MAP_FACE_ARB               0x207C
109#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D
110#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E
111#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F
112#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080
113#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081
114#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082
115#define WGL_FRONT_LEFT_ARB                  0x2083
116#define WGL_FRONT_RIGHT_ARB                 0x2084
117#define WGL_BACK_LEFT_ARB                   0x2085
118#define WGL_BACK_RIGHT_ARB                  0x2086
119#define WGL_AUX0_ARB                        0x2087
120#define WGL_AUX1_ARB                        0x2088
121#define WGL_AUX2_ARB                        0x2089
122#define WGL_AUX3_ARB                        0x208A
123#define WGL_AUX4_ARB                        0x208B
124#define WGL_AUX5_ARB                        0x208C
125#define WGL_AUX6_ARB                        0x208D
126#define WGL_AUX7_ARB                        0x208E
127#define WGL_AUX8_ARB                        0x208F
128#define WGL_AUX9_ARB                        0x2090
129#endif
130
131#ifndef WGL_NV_render_depth_texture
132#define WGL_NV_render_depth_texture 1
133#define WGL_BIND_TO_TEXTURE_DEPTH_NV   0x20A3
134#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4
135#define WGL_DEPTH_TEXTURE_FORMAT_NV    0x20A5
136#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6
137#define WGL_DEPTH_COMPONENT_NV         0x20A7
138#endif
139
140#ifndef WGL_NV_render_texture_rectangle
141#define WGL_NV_render_texture_rectangle 1
142#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0
143#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1
144#define WGL_TEXTURE_RECTANGLE_NV       0x20A2
145#endif
146
147#ifndef WGL_SAMPLE_BUFFERS_ARB
148#define        WGL_SAMPLE_BUFFERS_ARB         0x2041
149#endif
150#ifndef WGL_SAMPLES_ARB
151#define        WGL_SAMPLES_ARB                0x2042
152#endif
153
154namespace
155{
156
157static std::string sysError()
158{
159    DWORD stat, err = GetLastError();
160    LPVOID lpMsgBuf = 0;
161
162    stat = FormatMessage(   FORMAT_MESSAGE_ALLOCATE_BUFFER |
163                     FORMAT_MESSAGE_FROM_SYSTEM |
164                     FORMAT_MESSAGE_IGNORE_INSERTS,
165                     NULL,
166                     err,
167                     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
168                     (LPTSTR) &lpMsgBuf,\
169                     0,NULL
170                     );
171
172    std::ostringstream msgResult;
173    if ( stat > 0 && lpMsgBuf )
174    {
175        msgResult << (LPCTSTR)lpMsgBuf;
176        LocalFree( lpMsgBuf );
177    }
178    else
179    {
180        msgResult << "Error code " << err;
181    }
182
183    return msgResult.str();
184}
185
186
187    static int __tempwnd_id = 0;
188class TemporaryWindow: public osg::Referenced
189{
190public:
191    TemporaryWindow():
192        _handle(0),
193        _dc(0),
194        _context(0),
195        _instance(0)
196    {
197        create();
198    }
199
200    HWND  getHandle() const    { return _handle; }
201    HDC   getDC() const        { return _dc; }
202    HGLRC getContext() const   { return _context; }
203
204    bool makeCurrent();
205
206protected:
207    ~TemporaryWindow();
208
209    TemporaryWindow(const TemporaryWindow &):
210        _handle(0),
211        _dc(0),
212        _context(0),
213        _instance(0) {}
214
215    TemporaryWindow &operator=(const TemporaryWindow &) { return *this; }
216
217    void create();
218    void kill();
219
220private:
221    HWND _handle;
222    HDC _dc;
223    HGLRC _context;
224    HINSTANCE _instance;
225    std::string _classname;
226};
227
228void TemporaryWindow::create()
229{
230    std::ostringstream oss;
231    oss << "tempwnd" << (++__tempwnd_id);
232    _classname = oss.str();
233
234    _instance = GetModuleHandle(0);
235
236    WNDCLASS wndclass;
237
238    wndclass.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
239    wndclass.lpfnWndProc   = DefWindowProc;
240    wndclass.cbClsExtra    = 0;
241    wndclass.cbWndExtra    = 0;
242    wndclass.hInstance     = _instance;
243    wndclass.hCursor       = 0;
244    wndclass.hIcon         = 0;
245    wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
246    wndclass.lpszMenuName  = 0;
247    wndclass.lpszClassName = _classname.c_str();
248
249    if (!RegisterClass(&wndclass))
250        return;
251
252    if (!(_handle = CreateWindowEx( 0,
253                                    _classname.c_str(),
254                                    TEXT(_classname.c_str()),
255                                    WS_POPUP,
256                                    0,
257                                    0,
258                                    100,
259                                    100,
260                                    0,
261                                    0,
262                                    _instance,
263                                    0)))
264    {
265        OSG_WARN << "PixelBufferWin32, could not create temporary window: " << sysError() << std::endl;
266        kill();
267        return;
268    }
269
270    if (!(_dc = GetDC(_handle)))
271    {
272        OSG_WARN << "PixelBufferWin32, could not get device context for temporary window: " << sysError() << std::endl;
273        kill();
274        return;
275    }
276
277    PIXELFORMATDESCRIPTOR pfd = {
278        sizeof(PIXELFORMATDESCRIPTOR),
279        1,
280        PFD_DRAW_TO_WINDOW |
281        PFD_SUPPORT_OPENGL,
282        PFD_TYPE_RGBA,
283        24,
284        0, 0, 0, 0, 0, 0,
285        0,
286        0,
287        0,
288        0, 0, 0, 0,
289        16,
290        0,
291        0,
292        PFD_MAIN_PLANE,
293        0,
294        0, 0, 0
295    };
296
297    int visual_id = ChoosePixelFormat(_dc, &pfd);
298
299    if (!SetPixelFormat(_dc, visual_id, &pfd))
300    {
301        OSG_WARN << "PixelBufferWin32, could not set pixel format for temporary window: " << sysError() << std::endl;
302        kill();
303        return;
304    }
305
306    if (!(_context = wglCreateContext(_dc)))
307    {
308        OSG_WARN << "PixelBufferWin32, could not get graphics context for temporary window: " << sysError() << std::endl;
309        kill();
310        return;
311    }
312}
313
314TemporaryWindow::~TemporaryWindow()
315{
316    kill();
317}
318
319void TemporaryWindow::kill()
320{
321    if (_context)
322    {
323        // mew 2005-05-09 commented out due to crashes.
324        // possible causes are unsafe destructor ordering, or context already
325        // deleted by window deletion; see:
326        // http://openscenegraph.org/pipermail/osg-users/2005-May/052753.html
327        //wglDeleteContext(_context);
328        _context = 0;
329    }
330
331    if (_dc)
332    {
333        ReleaseDC(_handle, _dc);
334        _dc = 0;
335    }
336
337    if (_handle)
338    {
339        DestroyWindow(_handle);
340        _handle = 0;
341    }
342
343    UnregisterClass(_classname.c_str(), _instance);
344    _instance = 0;
345}
346
347bool TemporaryWindow::makeCurrent()
348{
349    bool result = wglMakeCurrent(_dc, _context) == TRUE ? true : false;
350    if (!result)
351    {
352        OSG_NOTICE << "PixelBufferWin32, could not make the temporary window's context active: " << sysError() << std::endl;
353    }
354    return result;
355}
356
357class WGLExtensions : public osg::Referenced
358{
359public:
360    typedef HPBUFFERARB (WINAPI * WGLCreatePBufferProc)    (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
361    typedef HDC         (WINAPI * WGLGetPBufferDCProc)     (HPBUFFERARB hPbuffer);
362    typedef int         (WINAPI * WGLReleasePBufferDCProc) (HPBUFFERARB hPbuffer, HDC hDC);
363    typedef bool        (WINAPI * WGLDestroyPBufferProc)   (HPBUFFERARB hPbuffer);
364    typedef bool        (WINAPI * WGLQueryPBufferProc)     (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
365    typedef bool        (WINAPI * WGLBindTexImageProc)     (HPBUFFERARB hPbuffer, int iBuffer);
366    typedef bool        (WINAPI * WGLReleaseTexImageProc)  (HPBUFFERARB hPbuffer, int iBuffer);
367    typedef bool        (WINAPI * WGLSetPbufferAttribProc) (HPBUFFERARB hPbuffer, const int * piAttribList);
368    typedef bool        (WINAPI * WGLChoosePixelFormatProc) (HDC, const int *, const float *, unsigned int, int *, unsigned int *);
369    typedef bool        (WINAPI * WGLMakeContextCurrentProc) (HDC, HDC, HGLRC);
370
371    WGLCreatePBufferProc        wglCreatePbufferARB;
372    WGLGetPBufferDCProc            wglGetPbufferDCARB;
373    WGLReleasePBufferDCProc        wglReleasePbufferDCARB;
374    WGLDestroyPBufferProc        wglDestroyPbufferARB;
375    WGLQueryPBufferProc            wglQueryPbufferARB;
376    WGLBindTexImageProc            wglBindTexImageARB;
377    WGLReleaseTexImageProc        wglReleaseTexImageARB;
378    WGLChoosePixelFormatProc    wglChoosePixelFormatARB;
379    WGLMakeContextCurrentProc    wglMakeContextCurrentARB;
380
381    static WGLExtensions *instance();
382
383    bool isValid();
384
385protected:
386    WGLExtensions();
387    ~WGLExtensions();
388
389private:
390    static std::map<HGLRC, osg::ref_ptr<WGLExtensions> > _instances;
391};
392
393std::map<HGLRC, osg::ref_ptr<WGLExtensions> > WGLExtensions::_instances;
394WGLExtensions::WGLExtensions()
395{
396    wglCreatePbufferARB     = (WGLCreatePBufferProc)wglGetProcAddress("wglCreatePbufferARB");
397    wglGetPbufferDCARB      = (WGLGetPBufferDCProc)wglGetProcAddress("wglGetPbufferDCARB");
398    wglReleasePbufferDCARB  = (WGLReleasePBufferDCProc)wglGetProcAddress("wglReleasePbufferDCARB");
399    wglDestroyPbufferARB    = (WGLDestroyPBufferProc)wglGetProcAddress("wglDestroyPbufferARB");
400    wglQueryPbufferARB      = (WGLQueryPBufferProc)wglGetProcAddress("wglQueryPbufferARB");
401    wglBindTexImageARB      = (WGLBindTexImageProc)wglGetProcAddress("wglBindTexImageARB");
402    wglReleaseTexImageARB   = (WGLReleaseTexImageProc)wglGetProcAddress("wglReleaseTexImageARB");
403    wglChoosePixelFormatARB = (WGLChoosePixelFormatProc)wglGetProcAddress("wglChoosePixelFormatARB");
404    wglMakeContextCurrentARB = (WGLMakeContextCurrentProc)wglGetProcAddress("wglMakeContextCurrentARB");
405    if (!wglMakeContextCurrentARB)
406    {
407        wglMakeContextCurrentARB = (WGLMakeContextCurrentProc)wglGetProcAddress("wglMakeContextCurrentEXT");
408    }
409}
410
411WGLExtensions::~WGLExtensions()
412{
413}
414
415bool WGLExtensions::isValid()
416{
417    return (wglCreatePbufferARB && wglGetPbufferDCARB && wglReleasePbufferDCARB && wglDestroyPbufferARB &&
418        wglQueryPbufferARB && wglChoosePixelFormatARB );
419}
420
421WGLExtensions *WGLExtensions::instance()
422{
423    HGLRC context = wglGetCurrentContext();
424
425    // Get wgl function pointers for the current graphics context, or if there is no
426    // current context then use a temporary window.
427
428    if (!_instances[context])
429    {
430        if ( context == 0 )
431        {
432            osg::ref_ptr<TemporaryWindow> tempWin= new TemporaryWindow;
433            tempWin->makeCurrent();
434            _instances[HGLRC(0)] = new WGLExtensions;
435        }
436        else
437        {
438            _instances[context] = new WGLExtensions;
439        }
440    }
441
442    return _instances[context].get();
443}
444
445
446}
447
448using namespace osgViewer;
449
450
451PixelBufferWin32::PixelBufferWin32( osg::GraphicsContext::Traits* traits ):
452  _initialized(false),
453  _valid(false),
454  _realized(false),
455  _boundBuffer(0)
456{
457    _traits = traits;
458
459    init();
460
461    if (valid())
462    {
463        setState( new osg::State );
464        getState()->setGraphicsContext( this );
465
466        if (_traits.valid() && _traits->sharedContext.valid() )
467        {
468            getState()->setContextID( _traits->sharedContext->getState()->getContextID() );
469            incrementContextIDUsageCount( getState()->getContextID() );
470        }
471        else
472        {
473            getState()->setContextID( osg::GraphicsContext::createNewContextID() );
474        }
475    }
476}
477
478PixelBufferWin32::~PixelBufferWin32()
479{
480    closeImplementation();
481}
482
483void PixelBufferWin32::init()
484{
485    if (_initialized) return;
486    if (!_traits) return;
487    if (!_traits->pbuffer) return;
488
489    WGLExtensions* wgle = WGLExtensions::instance();
490
491    if (!wgle || !wgle->isValid())
492    {
493        OSG_NOTICE << "PixelBufferWin32::init(), Error: some wgl extensions not supported" << std::endl;
494        return;
495    }
496
497    std::vector<int> fAttribList;
498    std::vector<int> bAttribList;
499
500    fAttribList.push_back(WGL_DRAW_TO_PBUFFER_ARB);
501    fAttribList.push_back(true);
502    fAttribList.push_back(WGL_SUPPORT_OPENGL_ARB);
503    fAttribList.push_back(true);
504    fAttribList.push_back(WGL_PIXEL_TYPE_ARB);
505    fAttribList.push_back(WGL_TYPE_RGBA_ARB);
506
507    bAttribList.push_back(WGL_PBUFFER_LARGEST_ARB);
508    bAttribList.push_back(true);
509
510    fAttribList.push_back(WGL_RED_BITS_ARB);
511    fAttribList.push_back(_traits->red);
512    fAttribList.push_back(WGL_GREEN_BITS_ARB);
513    fAttribList.push_back(_traits->green);
514    fAttribList.push_back(WGL_BLUE_BITS_ARB);
515    fAttribList.push_back(_traits->blue);
516    if (_traits->alpha)
517    {
518        fAttribList.push_back(WGL_ALPHA_BITS_ARB);
519        fAttribList.push_back(_traits->alpha);
520    }
521
522    fAttribList.push_back(WGL_DEPTH_BITS_ARB);
523    fAttribList.push_back(_traits->depth);
524
525    if (_traits->stencil)
526    {
527        fAttribList.push_back(WGL_STENCIL_BITS_ARB);
528        fAttribList.push_back(_traits->stencil);
529    }
530
531    if (_traits->sampleBuffers)
532    {
533        fAttribList.push_back(WGL_SAMPLE_BUFFERS_ARB);
534        fAttribList.push_back(_traits->sampleBuffers);
535
536        fAttribList.push_back(WGL_SAMPLES_ARB);
537        fAttribList.push_back(_traits->samples);
538    }
539
540    if (_traits->doubleBuffer)
541    {
542        fAttribList.push_back(WGL_DOUBLE_BUFFER_ARB);
543        fAttribList.push_back(true);
544    }
545
546    if (_traits->target != 0 && wgle->wglBindTexImageARB )
547    {
548        // TODO: Cube Maps
549       if (_traits->target == GL_TEXTURE_RECTANGLE)
550       {
551            bAttribList.push_back(WGL_TEXTURE_TARGET_ARB);
552            bAttribList.push_back(WGL_TEXTURE_RECTANGLE_NV);
553
554            if (_traits->alpha)
555                fAttribList.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV);
556            else
557                fAttribList.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV);
558            fAttribList.push_back(true);
559
560       }
561       else
562       {
563            bAttribList.push_back(WGL_TEXTURE_TARGET_ARB);
564            bAttribList.push_back(WGL_TEXTURE_2D_ARB);
565
566            if (_traits->alpha)
567                fAttribList.push_back(WGL_BIND_TO_TEXTURE_RGBA_ARB);
568            else
569                fAttribList.push_back(WGL_BIND_TO_TEXTURE_RGB_ARB);
570            fAttribList.push_back(true);
571
572       }
573
574        bAttribList.push_back(WGL_TEXTURE_FORMAT_ARB);
575        if (_traits->alpha)
576            bAttribList.push_back(WGL_TEXTURE_RGBA_ARB);
577        else
578            bAttribList.push_back(WGL_TEXTURE_RGB_ARB);
579
580        if (_traits->mipMapGeneration)
581        {
582            fAttribList.push_back(WGL_MIPMAP_TEXTURE_ARB);
583            fAttribList.push_back(true);
584        }
585    }
586
587    fAttribList.push_back(0);
588    bAttribList.push_back(0);
589
590    HDC hdc = 0;
591    int format;
592    osg::ref_ptr<TemporaryWindow> tempWin;
593
594    tempWin = new TemporaryWindow;
595    hdc = tempWin->getDC();
596    tempWin->makeCurrent();
597
598    wgle = WGLExtensions::instance();
599
600    unsigned int nformats = 0;
601    wgle->wglChoosePixelFormatARB(hdc, &fAttribList[0], NULL, 1, &format, &nformats);
602    if (nformats == 0)
603    {
604        OSG_NOTICE << "PixelBufferWin32::init(), Error: Couldn't find a suitable pixel format" << std::endl;
605        return;
606    }
607
608    _hwnd = reinterpret_cast<HWND>(wgle->wglCreatePbufferARB(hdc, format, _traits->width, _traits->height, &bAttribList[0]));
609    if (!_hwnd)
610    {
611        OSG_NOTICE << "PixelBufferWin32::init, wglCreatePbufferARB error: " << sysError() << std::endl;
612        return ;
613    }
614
615    _hdc = wgle->wglGetPbufferDCARB(reinterpret_cast<HPBUFFERARB>(_hwnd));
616    if (!_hdc)
617    {
618        OSG_NOTICE << "PixelBufferWin32::init, wglGetPbufferDCARB error: " << sysError() << std::endl;
619        return;
620    }
621
622    _hglrc = wglCreateContext(_hdc);
623    if (!_hglrc)
624    {
625        OSG_NOTICE << "PixelBufferWin32::init, wglCreateContext error: " << sysError() << std::endl;
626        return;
627    }
628
629    int iWidth = 0;
630    int iHeight = 0;
631    wgle->wglQueryPbufferARB(reinterpret_cast<HPBUFFERARB>(_hwnd), WGL_PBUFFER_WIDTH_ARB, &iWidth);
632    wgle->wglQueryPbufferARB(reinterpret_cast<HPBUFFERARB>(_hwnd), WGL_PBUFFER_HEIGHT_ARB, &iHeight);
633
634    if (_traits->width != iWidth || _traits->height != iHeight)
635    {
636        OSG_NOTICE << "PixelBufferWin32::init(), pbuffer created with different size then requsted" << std::endl;
637        OSG_NOTICE << "\tRequested size (" << _traits->width << "," << _traits->height << ")" << std::endl;
638        OSG_NOTICE << "\tPbuffer size (" << iWidth << "," << iHeight << ")" << std::endl;
639        _traits->width  = iWidth;
640        _traits->height = iHeight;
641    }
642
643    _initialized = true;
644    _valid = true;
645
646    return;
647}
648
649bool PixelBufferWin32::realizeImplementation()
650{
651    if (_realized)
652    {
653        OSG_NOTICE<<"PixelBufferWin32::realizeImplementation() Already realized"<<std::endl;
654        return true;
655    }
656
657    if (!_initialized) init();
658
659    if (!_initialized) return false;
660
661    if ( _traits->sharedContext.valid() )
662    {
663        GraphicsHandleWin32* graphicsHandleWin32 = dynamic_cast<GraphicsHandleWin32*>(_traits->sharedContext.get());
664        if (graphicsHandleWin32)
665        {
666            if ( !wglShareLists(graphicsHandleWin32->getWGLContext(), _hglrc) )
667            {
668                OSG_NOTICE << "PixelBufferWin32::realizeImplementation, wglShareLists error: " << sysError() << std::endl;
669            }
670        }
671    }
672
673    _realized = true;
674    return true;
675}
676
677void PixelBufferWin32::closeImplementation()
678{
679    if (_hwnd)
680    {
681        WGLExtensions* wgle = WGLExtensions::instance();
682
683        wglMakeCurrent(NULL,NULL);
684
685        if ( !wglDeleteContext(_hglrc) )
686        {
687            OSG_NOTICE << "PixelBufferWin32::closeImplementation, wglDeleteContext error: " << sysError() << std::endl;
688        }
689
690        if (wgle && wgle->isValid())
691        {
692            // Note that closeImplementation() should only be called from the same thread as created the pbuffer,
693            // otherwise these routines will return an error.
694
695            if ( !wgle->wglReleasePbufferDCARB(reinterpret_cast<HPBUFFERARB>(_hwnd), _hdc) )
696            {
697                OSG_NOTICE << "PixelBufferWin32::closeImplementation, wglReleasePbufferDCARB error: " << sysError() << std::endl;
698            }
699            if ( !wgle->wglDestroyPbufferARB(reinterpret_cast<HPBUFFERARB>(_hwnd)) )
700            {
701                OSG_NOTICE << "PixelBufferWin32::closeImplementation, wglDestroyPbufferARB error: " << sysError() << std::endl;
702            }
703        }
704    }
705    _valid = false;
706    _initialized = false;
707    _hwnd = 0;
708    _hdc = 0;
709    _hglrc = 0;
710}
711
712bool PixelBufferWin32::makeCurrentImplementation()
713{
714    bool result = wglMakeCurrent(_hdc, _hglrc)==TRUE?true:false;
715    if (!result)
716    {
717        OSG_NOTICE << "PixelBufferWin32::makeCurrentImplementation, wglMakeCurrent error: " << sysError() << std::endl;
718    }
719
720    // If the pbuffer is bound to a texture then release it.  This operation requires a current context, so
721    // do it after the MakeCurrent.
722
723    if ( _boundBuffer!=0 )
724    {
725        WGLExtensions* wgle = WGLExtensions::instance();
726        if ( wgle && wgle->wglReleaseTexImageARB )
727        {
728            if ( !wgle->wglReleaseTexImageARB(reinterpret_cast<HPBUFFERARB>(_hwnd), _boundBuffer) )
729            {
730                OSG_NOTICE << "PixelBufferWin32::makeCurrentImplementation, wglReleaseTexImageARB error: " << sysError() << std::endl;
731            }
732            _boundBuffer=0;
733        }
734    }
735
736    return result;
737}
738
739bool PixelBufferWin32::makeContextCurrentImplementation( GraphicsContext* readContext )
740{
741    WGLExtensions* wgle = WGLExtensions::instance();
742
743    if ( !wgle || !wgle->wglMakeContextCurrentARB )
744    {
745        OSG_NOTICE << "PixelBufferWin32, wglMakeContextCurrentARB not available" << std::endl;
746        return false;
747    }
748
749    GraphicsHandleWin32* graphicsHandleWin32 = dynamic_cast<GraphicsHandleWin32*>(readContext);
750    if (graphicsHandleWin32)
751    {
752        return wgle->wglMakeContextCurrentARB(_hdc, graphicsHandleWin32->getHDC(), _hglrc);
753    }
754    return false;
755}
756
757bool PixelBufferWin32::releaseContextImplementation()
758{
759    if (!_realized)
760    {
761        OSG_NOTICE<<"Warning: GraphicsWindow not realized, cannot do makeCurrent."<<std::endl;
762        return false;
763    }
764
765    return wglMakeCurrent( _hdc, 0 ) == TRUE?true:false;
766}
767
768void PixelBufferWin32::bindPBufferToTextureImplementation( GLenum buffer )
769{
770    WGLExtensions* wgle = WGLExtensions::instance();
771
772    if ( !wgle || !wgle->wglBindTexImageARB )
773    {
774        OSG_NOTICE << "PixelBufferWin32, wglBindTexImageARB not available" << std::endl;
775        return;
776    }
777
778    int bindBuffer;
779
780    switch (buffer)
781    {
782        case GL_BACK:
783            bindBuffer = WGL_BACK_LEFT_ARB;
784            break;
785        case GL_FRONT:
786            bindBuffer = WGL_FRONT_LEFT_ARB;
787            break;
788        default:
789            bindBuffer = static_cast<int>(buffer);
790    }
791
792    if ( bindBuffer != _boundBuffer )
793    {
794        if ( _boundBuffer != 0 && !wgle->wglReleaseTexImageARB(reinterpret_cast<HPBUFFERARB>(_hwnd), _boundBuffer) )
795        {
796            OSG_NOTICE << "PixelBufferWin32::bindPBufferToTextureImplementation, wglReleaseTexImageARB error: " << sysError() << std::endl;
797        }
798
799        if ( !wgle->wglBindTexImageARB(reinterpret_cast<HPBUFFERARB>(_hwnd), bindBuffer) )
800        {
801            OSG_NOTICE << "PixelBufferWin32::bindPBufferToTextureImplementation, wglBindTexImageARB error: " << sysError() << std::endl;
802        }
803        _boundBuffer = bindBuffer;
804    }
805}
806
807void PixelBufferWin32::swapBuffersImplementation()
808{
809    SwapBuffers( _hdc );
810}
Note: See TracBrowser for help on using the browser.