pbuffer blending problem on macmin g4

Apprentice
Posts: 19
Joined: 2008.05
Post: #1
Hello,

I'm currently working on render-target support in our game framework. I have successfully implemented FBO (on machines that support it), and pbuffer in case of absence of FBO's.
I did test it on iMac 24" (intel) and mac mini (intel) and both run somooth and fast (both FBO and pbuffer).
But when i started tests on macmini (g4) with osx 10.4, the pbuffer still sort of works, by sort of i mean it does not crash but there is no alpha blending basically when i create pbuffer with GL_RGB i get texture color (black) in places where i should have alpha-blended result and if i create pbuffer with GL_RGBA i have full transparency in spots where i should have alpha blended results.
I suspect that G4 macmini supports pbuffer (i check gl string) but somehow it does not support blending.

Can anyone confirm that ?
Is it possible to make blending work when rendering to pbuffer context ?
Im also looking for some tips for render to texture problems, like:
Do i need rebuild FBO's or pbuffers after switch from/to windowed/fullscreen?
(So far i don't do that as it works on my test machines but im not sure if that's the way to do it).

I have spend quite some time doing research and so far i cant make the blending work on my g4 macmini. Is there any other way to achieve render to texture on mac? (So far FBO and pbuffers seem like the only choice that will work in real time)

Thanks for any help.
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #2
The G4 Mac mini uses a Radeon 9200. It definitely supports blending, and pbuffers.

From your description it sounds like your pbuffer might be created as 5551, and only getting a single bit of alpha. What is the pixel format of the context that calls CGLSetPBuffer? While rendering to the pbuffer you can call glGetIntegerv(GL_RED_BITS...) etc to determine the format actually being used.



For your second question, how are you switching between window/fullscreen? A CGLPbufferObj exists outside of a GL context, while FBOs do not, so the creation semantics differ.
Quote this message in a reply
Apprentice
Posts: 19
Joined: 2008.05
Post: #3
Hey,

i did try your suggestion but so far i get the same results.
In my main context i have 8 bits per each color component and in pbuffer context i allso have 8 bits per color component.
Here is a part of the code used to create pbuffer:

Code:
if(!m_RenderBuferID || !m_FrameBufferID && gluCheckExtension((const GLubyte*)"GL_APPLE_pixel_buffer",str))
             {
                 LOG(CLL_INF,"Using PBuffer");
                 TexImage* pTextImg = new TexImage();
                 pTextImg->Height = th;
                 pTextImg->Width = tw;
                 pTextImg->MipMap = false;
                 glGenTextures(1,&pTextImg->TextureID);
                 glBindTexture(GL_TEXTURE_2D, pTextImg->TextureID);
                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
                 m_TexHandle = TexHandle(pTextImg);
                 //rebind current texture
                 if(::Cug::Graphics::Globals::g_pCurTexture)
                     glBindTexture (GL_TEXTURE_2D,::Cug::Graphics::Globals::g_pCurTexture->TextureID);
                 if(!aglCreatePBuffer(m_Size.m_X, m_Size.m_Y, GL_TEXTURE_2D, GL_RGB, 0, &m_PBuffer))
                  {
                      LOG(CLL_INF,"Failed to create PBuffer");
                      Graphics::ReleaseTexture(m_TexHandle);
                      return;
                  }
                 const AppSettings& aps = Root::Get()->GetAppSettings();
                 AGLPixelFormat aglPixFmt = NULL;
                 GLint attribwnd[] = {
                     AGL_RGBA,
                     AGL_PIXEL_SIZE, 24,
                     AGL_ALPHA_SIZE, 8,
                     AGL_ACCELERATED,
                     AGL_PBUFFER,
                     AGL_DEPTH_SIZE,aps.m_bZBuffer ? 16:0,
                     AGL_NO_RECOVERY,
                     AGL_NONE
                 };
                 if(!(aglPixFmt = aglChoosePixelFormat(NULL, 0, attribwnd)))
                  {
                      LOG(CLL_ERR,"Can't choose a pixel format");
                      aglDestroyPBuffer(m_PBuffer);
                      m_PBuffer = NULL;
                      Graphics::ReleaseTexture(m_TexHandle);
                      return;
                  }
                 if(!(m_Context = aglCreateContext(aglPixFmt,::Cug::Graphics::Globals::g_AGLContext)))
                  {
                     LOG(CLL_ERR,"Can't create a graphics context");
                     aglDestroyPixelFormat(aglPixFmt);
                     aglPixFmt = NULL;
                     aglDestroyPBuffer(m_PBuffer);
                     m_PBuffer = NULL;
                     Graphics::ReleaseTexture(m_TexHandle);
                      ::Cug::Graphics::aglReportError();
                     return;
                  }
                 aglDestroyPixelFormat(aglPixFmt);
                 aglPixFmt = NULL;
                 if(!aglSetCurrentContext(m_Context))
                  {
                    LOG(CLL_INF,"aglSetCurrentContext filed");
                    aglDestroyContext(m_Context);
                    m_Context = NULL;
                    aglDestroyPBuffer(m_PBuffer);
                    m_PBuffer = NULL;
                    Graphics::ReleaseTexture(m_TexHandle);
                    ::Cug::Graphics::aglReportError();
                    return;
                  }
                 GLint r,g,b,a;
                 glGetIntegerv(GL_RED_BITS,&r);
                 glGetIntegerv(GL_GREEN_BITS,&g);
                 glGetIntegerv(GL_BLUE_BITS,&b);
                 glGetIntegerv(GL_ALPHA_BITS,&a);
                 LOG(CLL_INF," PIX FMT r %d g %d b %d a %d",r,g,b,a);
                 GLint vs = aglGetVirtualScreen(::Cug::Graphics::Globals::g_AGLContext);
                 if(!aglSetPBuffer(m_Context, m_PBuffer, 0, 0, vs))
                  {
                    
                      LOG(CLL_INF,"set pbuffer failed");
                      aglDestroyContext(m_Context);
                      m_Context = NULL;
                      aglDestroyPBuffer(m_PBuffer);
                      m_PBuffer = NULL;
                      aglSetCurrentContext(::Cug::Graphics::Globals::g_AGLContext);
                      Graphics::ReleaseTexture(m_TexHandle);
                      ::Cug::Graphics::aglReportError();
                      return;
                  }
                 aglSetCurrentContext(::Cug::Graphics::Globals::g_AGLContext);
                 glBindTexture(GL_TEXTURE_2D, pTextImg->TextureID);
                 if(!aglTexImagePBuffer(aglGetCurrentContext(),m_PBuffer,GL_FRONT))
                  {
                      LOG(CLL_INF,"aglTexImagePBuffer failed");
                      aglDestroyContext(m_Context);
                      m_Context = NULL;
                      aglDestroyPBuffer(m_PBuffer);
                      m_PBuffer = NULL;
                      if(::Cug::Graphics::Globals::g_pCurTexture)
                          glBindTexture (GL_TEXTURE_2D,::Cug::Graphics::Globals::g_pCurTexture->TextureID);
                      else
                          glBindTexture (GL_TEXTURE_2D,0);
                      Graphics::ReleaseTexture(m_TexHandle);
                      ::Cug::Graphics::aglReportError();
                      return;
                  }
                 m_bIsOK = true;
                 if(::Cug::Graphics::Globals::g_pCurTexture)
                     glBindTexture (GL_TEXTURE_2D,::Cug::Graphics::Globals::g_pCurTexture->TextureID);
                 else
                     glBindTexture (GL_TEXTURE_2D,0);
                
                
             }
Quote this message in a reply
Apprentice
Posts: 19
Joined: 2008.05
Post: #4
Just want to add that blending works when i render to normal context and it works when i render to normal context using texture from pbuffer but when i try to render to pbuffer context blending does not work;
And when i set my pbuffer contex as current i set some gl states states
the code:
Code:
void MirrorOpenGLContextStates()
        {
            //set this context gl states to match main context states ?
            glShadeModel(GL_SMOOTH);
            //set up alpha blending
            if( Globals::g_BlendMode != CUG_BLEND_MODE_SUBTRACT)
                glBlendEquation ( GL_FUNC_ADD );
            switch(Globals::g_BlendMode)
            {
             case CUG_BLEND_MODE_NORMAL:
                 glBlendFunc (GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
                 break;
             case CUG_BLEND_MODE_ADD:
                 glBlendFunc (GL_SRC_ALPHA,GL_ONE);
                 break;
             case CUG_BLEND_MODE_NONE:
                 glBlendFunc (GL_ZERO,GL_ONE);
                 break;
             case CUG_BLEND_MODE_MULTIPLY:
                 glBlendFunc(GL_DST_COLOR,GL_ZERO);
                 break;
             case CUG_BLEND_MODE_SUBTRACT:
                 glBlendEquation ( GL_FUNC_REVERSE_SUBTRACT );
                 glBlendFunc (GL_SRC_ALPHA,GL_ONE);
                 break;
             default:
                 CUG_ASSERT(0, "GL: SetBlendingMode -> Unsupported blend mode");
                 break;
            }
            //setup z buffer states
            if(Globals::g_ZBufferState.m_bEnabled)
                glEnable(GL_DEPTH_TEST);
            else
                glDisable (GL_DEPTH_TEST);
            glDepthMask (Globals::g_ZBufferState.m_bWriteEnable);
            switch(Globals::g_ZBufferState.m_CmpFunc)
            {
             case CUG_CMP_NEVER:
                 glDepthFunc(GL_NEVER);
                 break;
             case CUG_CMP_LESS:
                 glDepthFunc (GL_LESS);
                 break;
             case CUG_CMP_EQUAL:
                 glDepthFunc (GL_EQUAL);
                 break;
             case CUG_CMP_LESSEQUAL:
                 glDepthFunc (GL_LEQUAL);
                 break;
             case CUG_CMP_GREATER:
                 glDepthFunc (GL_GREATER);
                 break;
             case CUG_CMP_NOTEQUAL:
                 glDepthFunc (GL_NOTEQUAL);
                 break;
             case CUG_CMP_GREATEREQUAL:
                 glDepthFunc (GL_GEQUAL);
                 break;
             case CUG_CMP_ALWAYS:
                 glDepthFunc (GL_ALWAYS);
                 break;
            }
            //set up alpha tests functions
            if(Globals::g_AlphaTestState.m_bEnabled)
                glEnable (GL_ALPHA_TEST);
            else
                glDisable (GL_ALPHA_TEST);
            f32 refv = Globals::g_AlphaTestState.m_RefValue/255.0f;
            switch(Globals::g_AlphaTestState.m_CmpFunc)
            {
             case CUG_CMP_NEVER:
                 glAlphaFunc (GL_NEVER,refv);
                 break;
             case CUG_CMP_LESS:
                 glAlphaFunc (GL_LESS,refv);
                 break;
             case CUG_CMP_EQUAL:
                 glAlphaFunc (GL_EQUAL,refv);
                 break;
             case CUG_CMP_LESSEQUAL:
                 glAlphaFunc (GL_LEQUAL,refv);
                 break;
             case CUG_CMP_GREATER:
                 glAlphaFunc (GL_GREATER,refv);
                 break;
             case CUG_CMP_NOTEQUAL:
                 glAlphaFunc (GL_NOTEQUAL,refv);
                 break;
             case CUG_CMP_GREATEREQUAL:
                 glAlphaFunc (GL_GEQUAL,refv);
                 break;
             case CUG_CMP_ALWAYS:
                 glAlphaFunc (GL_ALWAYS,refv);
                 break;
            }
            const AppSettings& aps = Root::Get()->GetAppSettings();
            glViewport(0,0,aps.m_WndWidth,aps.m_WndHeight);
            SetProjection2D (aps.m_WndWidth,aps.m_WndHeight);
            ResetSceneTransform();
            if(Globals::g_pCurTexture)
                glBindTexture (GL_TEXTURE_2D,Globals::g_pCurTexture->TextureID);
        
        }
    }
What is interesting is that when i run this code on my other mac mini with intel and on imac it works as intended and the code for pbuffer setup is same for both intel and ppc.
Quote this message in a reply
Apprentice
Posts: 19
Joined: 2008.05
Post: #5
Ok

now i feel very dumb, it appears that i was modifying the code and @ some point i forgot to enable GL_BLEND for pbuffers context....
It all works now Smile
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Multiply Blending Problem AnotherJake 20 10,576 Dec 15, 2008 05:22 AM
Last Post: chicknstu
  general blending versus texture blending questions WhatMeWorry 2 5,138 Dec 7, 2006 02:43 PM
Last Post: arekkusu
  Pbuffer problems on Intel NVIDIA GeForce 7300 GT NYGhost 5 4,254 Oct 26, 2006 09:39 AM
Last Post: NYGhost
  pBuffer - how to draw in it, then display it? taojones 0 2,412 Nov 13, 2005 09:54 AM
Last Post: taojones
  PBuffer & Render to Texture (read & write) habicht 4 4,093 Feb 7, 2005 05:33 PM
Last Post: habicht