source: GTP/branches/IllumWPdeliver2008dec/IlluminationWP/demos/Standalone/Hierarchical Systems Demo [OpenGL]/RESOURCES/include/RttRes/pbuffer.cpp @ 3255

Revision 3255, 28.6 KB checked in by szirmay, 15 years ago (diff)
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <memory.h>
4#include <assert.h>
5#include "pbuffer.h"
6
7#if defined(MACOS)
8        #include <OpenGL/gl.h>
9        #include <GLUT/glut.h>
10#else
11        #include <GL/gl.h>
12        #include <GL/glext.h>
13        #include <GL/glut.h>
14#endif
15
16#include <glh/glh_extensions.h>
17
18#include <string>
19#include <vector>
20#include ".\pbuffer.h"
21
22using namespace std;
23
24#ifndef PB_FPF
25//      #if defined DEBUG || defined _DEBUG
26                #define PB_FPF fprintf
27//      #else
28//              #define PB_FPF
29//      #endif
30#endif
31
32#if defined(WIN32)
33
34PBuffer::PBuffer(const char *strMode, bool managed)
35  : m_hDC(0), m_hGLRC(0), m_hPBuffer(0), m_hOldGLRC(0), m_hOldDC(0),
36    m_bIsTexture(false), m_iWidth(0), m_iHeight(0), m_strMode(strMode),
37    m_bSharedContext(false), m_bShareObjects(false), m_bIsBound(false),
38    m_bIsActive(false), m_bManaged(managed)
39{
40    m_pfAttribList.push_back(WGL_DRAW_TO_PBUFFER_ARB);
41    m_pfAttribList.push_back(true);
42    m_pfAttribList.push_back(WGL_SUPPORT_OPENGL_ARB);
43    m_pfAttribList.push_back(true);
44
45    m_pbAttribList.push_back(WGL_PBUFFER_LARGEST_ARB);
46    m_pbAttribList.push_back(true);
47
48    PB_FPF(stdout, "Declare a Pbuffer with \"%s\" parameters\n", strMode);
49    m_strMode = strMode;
50    parseModeString(m_strMode, &m_pfAttribList, &m_pbAttribList);
51
52    m_pfAttribList.push_back(0);
53    m_pbAttribList.push_back(0);
54
55       
56}
57
58PBuffer::~PBuffer()
59{
60    if (m_bManaged)
61        Destroy();
62}
63
64// This function actually does the creation of the p-buffer.
65// It can only be called once a window has already been created.
66bool PBuffer::Initialize(int iWidth, int iHeight, bool bShareContexts, bool bShareObjects)
67{
68    HDC hdc = wglGetCurrentDC();
69    HGLRC hglrc = wglGetCurrentContext();
70    int format = 0;
71    int nfattribs = 0;
72    int niattribs = 0;
73
74    m_iWidth = iWidth;
75    m_iHeight = iHeight;
76   
77    m_bSharedContext = bShareContexts;
78    m_bShareObjects = bShareObjects;
79   
80    if (m_bSharedContext)
81    {
82        // Get the pixel format for the on-screen window.
83        format = GetPixelFormat(hdc);
84        if (format == 0)
85        {
86            PB_FPF(stderr, "pbuffer creation error:  GetPixelFormat() failed\n");
87            return false;
88        }
89    }
90    else
91    {
92        unsigned int nformats;
93        wglChoosePixelFormatARB(hdc, &m_pfAttribList[0], NULL, 1, &format, &nformats);
94        if (nformats == 0)
95        {
96            PB_FPF(stderr, "pbuffer creation error:  Couldn't find a suitable pixel format.\n");
97            return false;
98        }
99    }
100   
101    m_hPBuffer = wglCreatePbufferARB(hdc, format, m_iWidth, m_iHeight, &m_pbAttribList[0]);
102    if (!m_hPBuffer)
103    {
104        DWORD err = GetLastError();
105        PB_FPF(stderr, "pbuffer creation error:  wglCreatePbufferARB() failed\n");
106        if (err == ERROR_INVALID_PIXEL_FORMAT)
107        {
108            PB_FPF(stderr, "error:  ERROR_INVALID_PIXEL_FORMAT\n");
109        }
110        else if (err == ERROR_NO_SYSTEM_RESOURCES)
111        {
112            PB_FPF(stderr, "error:  ERROR_NO_SYSTEM_RESOURCES\n");
113        }
114        else if (err == ERROR_INVALID_DATA)
115        {
116            PB_FPF(stderr, "error:  ERROR_INVALID_DATA\n");
117        }
118       
119        return false;
120    }
121   
122    // Get the device context.
123    m_hDC = wglGetPbufferDCARB(m_hPBuffer);
124    if (!m_hDC)
125    {
126        PB_FPF(stderr, "pbuffer creation error:  wglGetPbufferDCARB() failed\n");
127        return false;
128    }
129   
130    if (m_bSharedContext)
131    {
132        // Let's use the same gl context..
133        // Since the device contexts are compatible (i.e. same pixelformat),
134        // we should be able to use the same gl rendering context.
135        m_hGLRC = hglrc;
136    }
137    else
138    {
139        // Create a new gl context for the p-buffer.
140        m_hGLRC = wglCreateContext(m_hDC);
141        if (!m_hGLRC)
142        {
143            PB_FPF(stderr, "pbuffer creation error:  wglCreateContext() failed\n");
144            return false;
145        }
146       
147        if(m_bShareObjects)
148        {
149            if(!wglShareLists(hglrc, m_hGLRC))
150            {
151                PB_FPF(stderr, "pbuffer: wglShareLists() failed\n");
152                return false;
153            }
154        }
155    }
156   
157    GLint texFormat = WGL_NO_TEXTURE_ARB;
158    wglQueryPbufferARB(m_hPBuffer, WGL_TEXTURE_FORMAT_ARB, &texFormat);
159
160    if (texFormat != WGL_NO_TEXTURE_ARB)
161        m_bIsTexture = true;
162
163    // Determine the actual width and height we were able to create.
164    wglQueryPbufferARB(m_hPBuffer, WGL_PBUFFER_WIDTH_ARB, &m_iWidth);
165    wglQueryPbufferARB(m_hPBuffer, WGL_PBUFFER_HEIGHT_ARB, &m_iHeight);
166   
167    PB_FPF(stdout, "Created a %d x %d pbuffer\n", m_iWidth, m_iHeight);
168
169#ifdef _DEBUG
170    // query pixel format
171    int iattributes[] = {
172      WGL_RED_BITS_ARB,
173      WGL_GREEN_BITS_ARB,
174      WGL_BLUE_BITS_ARB,
175      WGL_ALPHA_BITS_ARB,
176      WGL_FLOAT_COMPONENTS_NV,
177      WGL_DEPTH_BITS_ARB,
178      WGL_SAMPLES_EXT,
179      WGL_AUX_BUFFERS_ARB
180    };
181    int ivalues[sizeof(iattributes) / sizeof(int)];
182
183    if (wglGetPixelFormatAttribivARB(m_hDC, format, 0, sizeof(iattributes) / sizeof(int), iattributes, ivalues)) {
184      PB_FPF(stdout, "r:%d g:%d b:%d a:%d float:%d depth:%d samples:%d aux:%d\n",
185              ivalues[0], ivalues[1], ivalues[2], ivalues[3], ivalues[4], ivalues[5], ivalues[6], ivalues[7]);
186    }
187#endif
188
189    return true;
190}
191
192void PBuffer::Destroy()
193{
194    if (m_hPBuffer)
195    {
196        if (!m_bSharedContext) wglDeleteContext(m_hGLRC);
197        wglReleasePbufferDCARB(m_hPBuffer, m_hDC);
198        wglDestroyPbufferARB(m_hPBuffer);
199    }
200}
201
202void PBuffer::parseModeString(const char *modeString, vector<int> *pfAttribList, vector<int> *pbAttribList)
203{
204    if (!modeString || strcmp(modeString, "") == 0)
205        return;
206
207    m_iBitsPerComponent = 8;
208        m_iNComponents = 0;
209    bool bIsFloatBuffer = false;
210    bool bIsATIFloatBuffer = false;
211    bool bIsTexture = false;
212    bool bNeedAlpha = false;
213
214        m_HasDepthTexture=false;
215        m_HasAuxBuffers=false;
216
217    char *mode = strdup(modeString);
218
219    vector<string> tokens;
220    char *buf = strtok(mode, " ");
221    while (buf != NULL)
222    {
223        if (strstr(buf, "ati_float") != NULL)
224            bIsATIFloatBuffer = true;
225        else if (strstr(buf, "float") != NULL)
226            bIsFloatBuffer = true;
227
228        if (strstr(buf, "texture") != NULL)
229            bIsTexture = true;
230
231        if (strstr(buf, "alpha") != NULL)
232            bNeedAlpha = true;
233
234        tokens.push_back(buf);
235        buf = strtok(NULL, " ");
236    }
237
238    pfAttribList->push_back(WGL_PIXEL_TYPE_ARB);
239#ifdef WGL_ATI_pixel_format_float
240    if (bIsATIFloatBuffer) {
241      pfAttribList->push_back(WGL_TYPE_RGBA_FLOAT_ATI);
242    } else
243#endif
244    {
245      pfAttribList->push_back(WGL_TYPE_RGBA_ARB);
246    }
247
248    for (unsigned int i = 0; i < tokens.size(); i++)
249    {
250        string token = tokens[i];
251
252        if (token == "rgb" && (m_iNComponents <= 1))
253        {
254/*            pfAttribList->push_back(WGL_RED_BITS_ARB);
255            pfAttribList->push_back(m_iBitsPerComponent);
256            pfAttribList->push_back(WGL_GREEN_BITS_ARB);
257            pfAttribList->push_back(m_iBitsPerComponent);
258            pfAttribList->push_back(WGL_BLUE_BITS_ARB);
259            pfAttribList->push_back(m_iBitsPerComponent);*/
260                        m_iNComponents += 3;
261            continue;
262        }
263                else if (token == "rgb") PB_FPF(stderr, "warning : mistake in components definition (rgb + %d)\n", m_iNComponents);
264
265       
266        if (token == "rgba" && (m_iNComponents == 0))
267        {
268            /*pfAttribList->push_back(WGL_RED_BITS_ARB);
269            pfAttribList->push_back(m_iBitsPerComponent);
270            pfAttribList->push_back(WGL_GREEN_BITS_ARB);
271            pfAttribList->push_back(m_iBitsPerComponent);
272            pfAttribList->push_back(WGL_BLUE_BITS_ARB);
273            pfAttribList->push_back(m_iBitsPerComponent);
274            pfAttribList->push_back(WGL_ALPHA_BITS_ARB);
275            pfAttribList->push_back(m_iBitsPerComponent);*/
276                        m_iNComponents = 4;
277            continue;
278        }
279                else if (token == "rgba") PB_FPF(stderr, "warning : mistake in components definition (rgba + %d)\n", m_iNComponents);
280       
281        if (token == "alpha" && (m_iNComponents <= 3))
282        {
283            /*pfAttribList->push_back(WGL_ALPHA_BITS_ARB);
284            pfAttribList->push_back(m_iBitsPerComponent);*/
285                        m_iNComponents++;
286            continue;
287        }
288                else if (token == "alpha") PB_FPF(stderr, "warning : mistake in components definition (alpha + %d)\n", m_iNComponents);
289
290
291        if (token == "r" && (m_iNComponents <= 1))// && bIsFloatBuffer)
292        {
293            /*pfAttribList->push_back(WGL_RED_BITS_ARB);
294            pfAttribList->push_back(m_iBitsPerComponent);*/
295                        m_iNComponents++;
296            continue;
297        }
298                else if (token == "r") PB_FPF(stderr, "warning : mistake in components definition (r + %d)\n", m_iNComponents);
299
300        if (token == "rg" && (m_iNComponents <= 1))// && bIsFloatBuffer)
301        {
302            /*pfAttribList->push_back(WGL_RED_BITS_ARB);
303            pfAttribList->push_back(m_iBitsPerComponent);
304            pfAttribList->push_back(WGL_GREEN_BITS_ARB);
305            pfAttribList->push_back(m_iBitsPerComponent);*/
306                        m_iNComponents += 2;
307            continue;
308        }
309                else if (token == "r") PB_FPF(stderr, "warning : mistake in components definition (rg + %d)\n", m_iNComponents);
310
311        if (token.find("depth") == 0)
312        {
313            pfAttribList->push_back(WGL_DEPTH_BITS_ARB);
314            pfAttribList->push_back(getIntegerValue(token));
315           
316            continue;
317        }
318
319        if (token.find("stencil") == 0)
320        {
321            pfAttribList->push_back(WGL_STENCIL_BITS_ARB);
322            pfAttribList->push_back(8);
323           
324            continue;
325        }
326
327        if (token.find("samples") == 0)
328        {
329/*            pfAttribList->push_back(WGL_SAMPLE_BUFFERS_ARB);
330            pfAttribList->push_back(1);
331            pfAttribList->push_back(WGL_SAMPLES_ARB);
332            pfAttribList->push_back(getIntegerValue(token));*/
333           
334            continue;
335        }
336
337        if (token.find("aux") == 0)
338        {
339                        m_HasAuxBuffers=true;
340            pfAttribList->push_back(WGL_AUX_BUFFERS_ARB);
341            pfAttribList->push_back(getIntegerValue(token));
342            continue;
343        }
344
345        if (token == "double")
346        {
347            pfAttribList->push_back(WGL_DOUBLE_BUFFER_ARB);
348            pfAttribList->push_back(true);
349
350            continue;
351        }       
352
353        if (token.find("ati_float") == 0)
354        {
355            m_iBitsPerComponent = getIntegerValue(token);
356            // type already set above
357            continue;
358
359        } else if (token.find("float") == 0)
360        {
361            m_iBitsPerComponent = getIntegerValue(token);
362            //bIsFloatBuffer = true; done previously
363            pfAttribList->push_back(WGL_FLOAT_COMPONENTS_NV);
364            pfAttribList->push_back(true);
365
366            continue;
367        }
368       
369        if (token.find("texture") == 0)
370        {
371            if (token.find("textureRECT") == 0 || bIsFloatBuffer)
372            {
373                pbAttribList->push_back(WGL_TEXTURE_TARGET_ARB);
374                pbAttribList->push_back(WGL_TEXTURE_RECTANGLE_NV);
375            }
376            else if (token.find("textureCUBE") == 0)
377            {
378                pbAttribList->push_back(WGL_TEXTURE_TARGET_ARB);
379                pbAttribList->push_back(WGL_TEXTURE_CUBE_MAP_ARB);
380            }
381            else
382            {
383                pbAttribList->push_back(WGL_TEXTURE_TARGET_ARB);
384                pbAttribList->push_back(WGL_TEXTURE_2D_ARB);
385            }
386
387            if (bIsFloatBuffer || bIsATIFloatBuffer)
388            {
389                                if(m_iNComponents == 0)
390                                {
391                                        PB_FPF(stderr, "components not specified. assuming rgba...\n");
392                                        pfAttribList->push_back(WGL_RED_BITS_ARB);
393                                        pfAttribList->push_back(m_iBitsPerComponent);
394                                        pfAttribList->push_back(WGL_GREEN_BITS_ARB);
395                                        pfAttribList->push_back(m_iBitsPerComponent);
396                                        pfAttribList->push_back(WGL_BLUE_BITS_ARB);
397                                        pfAttribList->push_back(m_iBitsPerComponent);
398                                        pfAttribList->push_back(WGL_ALPHA_BITS_ARB);
399                                        pfAttribList->push_back(m_iBitsPerComponent);
400                                        m_iNComponents = 4;
401                                }
402            }
403
404            if (bIsFloatBuffer) {
405                                switch(m_iNComponents)
406                                {
407                                case 1:
408                                        pfAttribList->push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV);
409                                        pfAttribList->push_back(true);
410   
411                                        pbAttribList->push_back(WGL_TEXTURE_FORMAT_ARB);
412                                        pbAttribList->push_back(WGL_TEXTURE_FLOAT_R_NV);
413                                        break;
414                                case 2:
415                                        pfAttribList->push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV);
416                                        pfAttribList->push_back(true);
417   
418                                        pbAttribList->push_back(WGL_TEXTURE_FORMAT_ARB);
419                                        pbAttribList->push_back(WGL_TEXTURE_FLOAT_RG_NV);
420                                        break;
421                                case 3:
422                                        pfAttribList->push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV);
423                                        pfAttribList->push_back(true);
424   
425                                        pbAttribList->push_back(WGL_TEXTURE_FORMAT_ARB);
426                                        pbAttribList->push_back(WGL_TEXTURE_FLOAT_RGB_NV);
427                                        break;
428                                case 4:
429                                        pfAttribList->push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV);
430                                        pfAttribList->push_back(true);
431   
432                                        pbAttribList->push_back(WGL_TEXTURE_FORMAT_ARB);
433                                        pbAttribList->push_back(WGL_TEXTURE_FLOAT_RGBA_NV);
434                                        break;
435                                default:
436                                PB_FPF(stderr, "Bad number of components (r=1,rg=2,rgb=3,rgba=4): %d\n", m_iNComponents);
437                                        break;
438                                }
439            }
440            else
441            {
442                                switch(m_iNComponents)
443                                {
444                                case 3:
445                                        pfAttribList->push_back(WGL_BIND_TO_TEXTURE_RGB_ARB);
446                                        pfAttribList->push_back(true);
447               
448                                        pbAttribList->push_back(WGL_TEXTURE_FORMAT_ARB);
449                                        pbAttribList->push_back(WGL_TEXTURE_RGB_ARB);
450                                        break;
451                                case 4:
452                                        pfAttribList->push_back(WGL_BIND_TO_TEXTURE_RGBA_ARB);
453                                        pfAttribList->push_back(true);
454               
455                                        pbAttribList->push_back(WGL_TEXTURE_FORMAT_ARB);
456                                        pbAttribList->push_back(WGL_TEXTURE_RGBA_ARB);
457                                        break;
458                                default:
459                                PB_FPF(stderr, "Bad number of components (r=1,rg=2,rgb=3,rgba=4): %d\n", m_iNComponents);
460                                        break;
461                                }
462            }
463               
464            string option = getStringValue(token);
465            if (option == "depth")
466            {
467                                m_HasDepthTexture=true;
468
469                pfAttribList->push_back(WGL_BIND_TO_TEXTURE_DEPTH_NV);
470                pfAttribList->push_back(true);
471               
472                pbAttribList->push_back(WGL_DEPTH_TEXTURE_FORMAT_NV);
473                pbAttribList->push_back(WGL_TEXTURE_DEPTH_COMPONENT_NV);
474            }
475
476            continue;
477        }
478
479        if (token.find("mipmap") == 0 && bIsTexture)
480        {
481            pfAttribList->push_back(WGL_MIPMAP_TEXTURE_ARB);
482            pfAttribList->push_back(true);
483           
484            continue;
485        }
486
487        PB_FPF(stderr, "unknown pbuffer attribute: %s\n", token.c_str());
488    }
489
490    if (m_iNComponents > 0)
491    {
492        pfAttribList->push_back(WGL_RED_BITS_ARB);
493        pfAttribList->push_back(m_iBitsPerComponent);
494    }
495    if (m_iNComponents > 1)
496    {
497        pfAttribList->push_back(WGL_GREEN_BITS_ARB);
498        pfAttribList->push_back(m_iBitsPerComponent);
499    }
500    if (m_iNComponents > 2)
501    {
502        pfAttribList->push_back(WGL_BLUE_BITS_ARB);
503        pfAttribList->push_back(m_iBitsPerComponent);
504    }
505    if (m_iNComponents > 3)
506    {
507        pfAttribList->push_back(WGL_ALPHA_BITS_ARB);
508        pfAttribList->push_back(m_iBitsPerComponent);
509    }
510}
511
512// Check to see if the pbuffer was lost.
513// If it was lost, destroy it and then recreate it.
514void PBuffer::HandleModeSwitch()
515{
516    int lost = 0;
517   
518    wglQueryPbufferARB(m_hPBuffer, WGL_PBUFFER_LOST_ARB, &lost);
519   
520    if (lost)
521    {
522        this->~PBuffer();
523        Initialize(m_iWidth, m_iHeight, m_bSharedContext, m_bShareObjects);
524    }
525}
526
527int PBuffer::Bind(int iBuffer)
528{
529    if (!m_bIsTexture)
530    {
531        PB_FPF(stderr, "PBuffer::Bind() failed - pbuffer format does not support render to texture!\n");
532        return 0;
533    }
534
535    int ret = wglBindTexImageARB(m_hPBuffer, iBuffer);
536    if (!ret)
537        PB_FPF(stderr, "PBuffer::Bind() failed.\n");
538   
539    m_bIsBound = true;
540
541    return ret;
542}
543
544int PBuffer::Release(int iBuffer)
545{
546    if (!m_bIsTexture)
547    {
548        PB_FPF(stderr, "PBuffer::Release() failed - pbuffer format does not support render to texture!\n");
549        return 0;
550    }
551
552
553
554    int ret = wglReleaseTexImageARB(m_hPBuffer, iBuffer);
555    if (!ret)
556        PB_FPF(stderr, "PBuffer::Release() failed.\n");
557   
558    m_bIsBound = false;
559   
560    return ret;
561}
562
563
564void PBuffer::Activate(PBuffer *current /* = NULL */)
565{
566        m_hOldGLRC = wglGetCurrentContext();
567    m_hOldDC = wglGetCurrentDC();
568
569        /*
570    if (current == this)
571    {
572        return; // no switch necessary
573    }
574   
575    if (NULL == current || !current->m_bIsActive)
576    {
577        if (m_bIsActive)
578            return;
579
580        m_hOldGLRC = wglGetCurrentContext();
581        m_hOldDC = wglGetCurrentDC();
582    }
583    else
584    {
585        m_hOldGLRC = current->m_hOldGLRC;
586        m_hOldDC = current->m_hOldDC;
587        current->m_hOldGLRC = 0;
588        current->m_hOldDC = 0;
589        current->m_bIsActive = false;       
590    }*/
591
592    if (!wglMakeCurrent(m_hDC, m_hGLRC))
593        PB_FPF(stderr, "PBuffer::Activate() failed.\n");
594
595    m_bIsActive = true;
596}
597
598void PBuffer::Deactivate()
599{
600  /*  if (!m_bIsActive)
601        return;
602  */ 
603    if (!wglMakeCurrent(m_hOldDC, m_hOldGLRC))
604        PB_FPF(stderr, "PBuffer::Deactivate() failed.\n");
605
606 //  m_hOldGLRC = 0;
607 //  m_hOldDC = 0;
608       
609        m_bIsActive = false;
610}
611
612#elif defined(UNIX)
613
614PBuffer::PBuffer(const char *strMode, bool managed)
615  : m_pDisplay(0), m_glxPbuffer(0), m_glxContext(0), m_pOldDisplay(0), m_glxOldDrawable(0),
616    m_glxOldContext(0), m_iWidth(0), m_iHeight(0), m_strMode(strMode),
617    m_bSharedContext(false), m_bShareObjects(false), m_bManaged(managed)
618{
619    m_pfAttribList.push_back(GLX_DRAWABLE_TYPE);
620    m_pfAttribList.push_back(GLX_PBUFFER_BIT);
621    m_pfAttribList.push_back(GLX_RENDER_TYPE);
622    m_pfAttribList.push_back(GLX_RGBA_BIT);
623
624    m_pbAttribList.push_back(GLX_LARGEST_PBUFFER);
625    m_pbAttribList.push_back(true);
626    m_pbAttribList.push_back(GLX_PRESERVED_CONTENTS);
627    m_pbAttribList.push_back(true);
628
629    m_strMode = strMode;
630    parseModeString(m_strMode, &m_pfAttribList, &m_pbAttribList);
631
632    m_pfAttribList.push_back(0);
633    m_pbAttribList.push_back(0);
634}   
635
636PBuffer::~PBuffer()
637{
638    if (m_bManaged)
639        Destroy();
640}
641
642bool PBuffer::Initialize(int iWidth, int iHeight, bool bShareContexts, bool bShareObjects)
643{
644    Display *pDisplay = glXGetCurrentDisplay();
645    int iScreen = DefaultScreen(pDisplay);
646    GLXContext glxContext = glXGetCurrentContext();
647   
648    GLXFBConfig *glxConfig;
649    int iConfigCount;   
650   
651    m_bSharedContext = bShareContexts;
652    m_bShareObjects = bShareObjects;
653   
654    m_iWidth = iWidth;
655    m_iHeight = iHeight;
656   
657    if (m_bSharedContext)
658    {
659        glxConfig = glXGetFBConfigs(pDisplay, iScreen, &iConfigCount);
660        if (!glxConfig)
661        {
662            PB_FPF(stderr, "pbuffer creation error:  glXGetFBConfigs() failed\n");
663            return false;
664        }
665    } 
666    else
667    {
668        glxConfig = glXChooseFBConfigSGIX(pDisplay, iScreen, &m_pfAttribList[0], &iConfigCount);
669        if (!glxConfig)
670        {
671            PB_FPF(stderr, "pbuffer creation error:  glXChooseFBConfig() failed\n");
672            return false;
673        }
674    }
675   
676    m_glxPbuffer = glXCreateGLXPbufferSGIX(pDisplay, glxConfig[0], m_iWidth, m_iHeight, &m_pbAttribList[0]);
677   
678    if (!m_glxPbuffer)
679    {
680        PB_FPF(stderr, "pbuffer creation error:  glXCreatePbuffer() failed\n");
681        return false;
682    }
683   
684    if (m_bSharedContext)
685    {
686        m_glxContext = glxContext;
687    }
688    else
689    {
690        if (m_bShareObjects)
691            m_glxContext = glXCreateContextWithConfigSGIX(pDisplay, glxConfig[0], GLX_RGBA_TYPE, glxContext, true);
692        else
693            m_glxContext = glXCreateContextWithConfigSGIX(pDisplay, glxConfig[0], GLX_RGBA_TYPE, NULL, true);
694       
695        if (!glxConfig)
696        {
697            PB_FPF(stderr, "pbuffer creation error:  glXCreateNewContext() failed\n");
698            return false;
699        }
700    }
701   
702    m_pDisplay = pDisplay;
703   
704    unsigned int w, h;
705    w = h = 0;
706   
707    glXQueryGLXPbufferSGIX(m_pDisplay, m_glxPbuffer, GLX_WIDTH, &w);
708    glXQueryGLXPbufferSGIX(m_pDisplay, m_glxPbuffer, GLX_HEIGHT, &h);
709    m_iWidth = w;
710    m_iHeight = h;
711   
712    PB_FPF(stdout, "Created a %d x %d pbuffer\n", m_iWidth, m_iHeight);
713   
714    return true;
715}
716
717void PBuffer::Destroy()
718{
719    if (m_glxContext && !m_bSharedContext)
720        glXDestroyContext(m_pDisplay, m_glxContext);
721
722    if (m_glxPbuffer)
723        glXDestroyGLXPbufferSGIX(m_pDisplay, m_glxPbuffer);
724
725    m_glxContext = 0;
726    m_glxPbuffer = 0;
727    m_pDisplay = 0;
728}
729
730void PBuffer::parseModeString(const char *modeString, vector<int> *pfAttribList, vector<int> *pbAttribList)
731{
732    if (!modeString || strcmp(modeString, "") == 0)
733        return;
734
735    m_iBitsPerComponent = 8;
736        m_iNComponents = 0;
737    bool bIsFloatBuffer = false;
738    bool bNeedAlpha = false;
739   
740    char *mode = strdup(modeString);
741
742    vector<string> tokens;
743    char *buf = strtok(mode, " ");
744    while (buf != NULL)
745    {
746        if (strstr(buf, "float") != NULL)
747            bIsFloatBuffer = true;
748
749        if (strstr(buf, "alpha") != NULL)
750            bNeedAlpha = true;
751       
752        tokens.push_back(buf);
753        buf = strtok(NULL, " ");
754    }
755   
756    for (unsigned int i = 0; i < tokens.size(); i++)
757    {
758        string token = tokens[i];
759
760        if (token == "rgb" && !bIsFloatBuffer)
761        {
762            pfAttribList->push_back(GLX_RED_SIZE);
763            pfAttribList->push_back(m_iBitsPerComponent);
764            pfAttribList->push_back(GLX_GREEN_SIZE);
765            pfAttribList->push_back(m_iBitsPerComponent);
766            pfAttribList->push_back(GLX_BLUE_SIZE);
767            pfAttribList->push_back(m_iBitsPerComponent);
768                        m_iNComponents += 3;
769            continue;
770        }
771                else if (token == "rgb") PB_FPF(stderr, "warning : mistake in components definition (rgb + %d)\n", m_iNComponents);
772
773        if (token == "rgba" && (m_iNComponents == 0))
774        {
775            pfAttribList->push_back(GLX_RED_SIZE);
776            pfAttribList->push_back(m_iBitsPerComponent);
777            pfAttribList->push_back(GLX_GREEN_SIZE);
778            pfAttribList->push_back(m_iBitsPerComponent);
779            pfAttribList->push_back(GLX_BLUE_SIZE);
780            pfAttribList->push_back(m_iBitsPerComponent);
781            pfAttribList->push_back(GLX_ALPHA_SIZE);
782            pfAttribList->push_back(m_iBitsPerComponent);
783                        m_iNComponents = 4;
784            continue;
785        }
786                else if (token == "rgba") PB_FPF(stderr, "warning : mistake in components definition (rgba + %d)\n", m_iNComponents);
787       
788        if (token.find("alpha") != token.npos)
789        {
790            pfAttribList->push_back(GLX_ALPHA_SIZE);
791            pfAttribList->push_back(m_iBitsPerComponent);
792                        m_iNComponents++;
793            continue;
794        }
795                else if (token == "alpha") PB_FPF(stderr, "warning : mistake in components definition (alpha + %d)\n", m_iNComponents);
796
797        if (token.find("depth") != token.npos)
798        {
799            pfAttribList->push_back(GLX_DEPTH_SIZE);
800            pfAttribList->push_back(getIntegerValue(token));
801           
802            continue;
803        }
804
805        if (token.find("stencil") != token.npos)
806        {
807            pfAttribList->push_back(GLX_STENCIL_SIZE);
808            pfAttribList->push_back(getIntegerValue(token));
809           
810            continue;
811        }
812     
813        if (token.find("samples") != token.npos)
814        {
815            pfAttribList->push_back(GLX_SAMPLE_BUFFERS_ARB);
816            pfAttribList->push_back(1);
817            pfAttribList->push_back(GLX_SAMPLES_ARB);
818            pfAttribList->push_back(getIntegerValue(token));
819           
820            continue;
821        }
822
823        if (token == "double")
824        {
825            pfAttribList->push_back(GLX_DOUBLEBUFFER);
826            pfAttribList->push_back(true);
827
828            continue;
829        }       
830       
831        if (token.find("float") == 0)
832        {
833            m_iBitsPerComponent = getIntegerValue(token);
834            //bIsFloatBuffer = true; done previously
835            pfAttribList->push_back(GLX_FLOAT_COMPONENTS_NV);
836            pfAttribList->push_back(true);
837            continue;
838        }       
839
840        PB_FPF(stderr, "unknown pbuffer attribute: %s\n", token.c_str());
841    }
842}
843
844void PBuffer::Activate(PBuffer *current /* = NULL */)
845{
846    if (current == this)
847    {
848        return; // no switch necessary
849    }
850
851    if (NULL == current || !current->m_bIsActive)
852    {
853        m_pOldDisplay = glXGetCurrentDisplay();
854        m_glxOldDrawable = glXGetCurrentDrawable();
855        m_glxOldContext = glXGetCurrentContext();
856    }
857    else
858    {
859        m_pOldDisplay = current->m_pOldDisplay;
860        m_glxOldDrawable = current->m_glxOldDrawable;
861        m_glxOldContext = current->m_glxOldContext;
862        current->m_pOldDisplay = 0;
863        current->m_glxOldDrawable = 0;
864        current->m_glxOldContext = 0;
865    }
866
867    if (!glXMakeCurrent(m_pDisplay, m_glxPbuffer, m_glxContext))
868        PB_FPF(stderr, "PBuffer::Activate() failed.\n");
869}
870
871void PBuffer::Deactivate()
872{
873    if (!glXMakeCurrent(m_pOldDisplay, m_glxOldDrawable, m_glxOldContext))
874        PB_FPF(stderr, "PBuffer::Deactivate() failed.\n");
875
876    m_pOldDisplay = 0;
877    m_glxOldDrawable = 0;
878    m_glxOldContext = 0;
879}
880
881#elif defined(MACOS)
882
883PBuffer::PBuffer(const char *strMode)
884  :
885    m_iWidth(0), m_iHeight(0), m_strMode(strMode),
886    m_bSharedContext(false), m_bShareObjects(false)
887{
888    PB_FPF(stderr, "pbuffer not implemented under Mac OS X yet\n");
889}
890
891PBuffer::~PBuffer()
892{
893    PB_FPF(stderr, "pbuffer not implemented under Mac OS X yet\n");
894}
895
896bool PBuffer::Initialize(int iWidth, int iHeight, bool bShareContexts, bool bShareObjects)
897{
898    PB_FPF(stderr, "pbuffer not implemented under Mac OS X yet\n");
899
900    return false;
901}
902
903void PBuffer::Activate()
904{
905    PB_FPF(stderr, "pbuffer not implemented under Mac OS X yet\n");
906}
907
908void PBuffer::Deactivate()
909{
910    PB_FPF(stderr, "pbuffer not implemented under Mac OS X yet\n");
911}
912
913#endif
914
915string PBuffer::getStringValue(string token)
916{
917    size_t pos;
918    if ((pos = token.find("=")) != token.npos)
919    {
920        string value = token.substr(pos+1, token.length()-pos+1);
921        return value;
922    }
923    else
924        return "";
925}
926
927int PBuffer::getIntegerValue(string token)
928{
929    size_t pos;
930    if ((pos = token.find("=")) != token.npos)
931    {
932        string value = token.substr(pos+1, token.length()-pos+1);
933        if (value.empty())
934            return 1;
935        return atoi(value.c_str());
936    }
937    else
938        return 1;
939}
940
941//----------------------------------------------------------------------------------
942//
943/// return the total size in bytes of the PBuffer
944//
945//----------------------------------------------------------------------------------
946unsigned int PBuffer::GetSizeInBytes()
947{
948        return m_iWidth * m_iHeight * (m_iNComponents/8);
949}
950/*************************************************************************/ /**
951
952make a copy the entire PBuffer in the memory. You have to allocate this area (ptr).
953if ever you want to read a smaller size : specify it through w,h. otherwise w=h=-1
954
955 */ /*********************************************************************/
956unsigned int PBuffer::CopyToBuffer(void *ptr, int w, int h)
957{
958        GLenum format;
959        GLenum type;
960        switch(m_iNComponents)
961        {
962        case 1: //
963                format = GL_LUMINANCE; // is it right to ask for Red only component ?
964                break;
965        case 2:
966                format = GL_LUMINANCE_ALPHA; //How to ask for GL_RG ??
967                break;
968        case 3:
969                format = GL_RGB;
970                break;
971        case 4:
972                format = GL_RGBA;
973                break;
974        }
975        switch(m_iBitsPerComponent)
976        {
977        case 8:
978                type = GL_UNSIGNED_BYTE;
979                break;
980        case 32:
981                type = GL_FLOAT;
982                break;
983#ifdef GL_NV_half_float
984    case 16:
985                type = GL_HALF_FLOAT_NV;
986                break;
987#endif
988        default:
989                PB_FPF(stderr, "unknown m_iBitsPerComponent\n");
990#       if defined(WIN32)
991                _asm { int 3 }
992#       endif
993        }
994        Activate();
995        if((w < 0) || (w > m_iWidth))
996                w = m_iWidth;
997        if((h < 0) || (h > m_iHeight))
998                h = m_iHeight;
999        glReadPixels(0,0,w,h, format, type, ptr);
1000        Deactivate();
1001        return w * h * (m_iNComponents/8);
1002}
1003
Note: See TracBrowser for help on using the repository browser.