void Fbo::init() { gl::SaveFramebufferBinding bindingSaver; #if defined( CINDER_MSW ) static bool csaaSupported = ( GLEE_NV_framebuffer_multisample_coverage != 0 ); #else static bool csaaSupported = false; #endif bool useCSAA = csaaSupported && ( mObj->mFormat.mCoverageSamples > mObj->mFormat.mSamples ); bool useMSAA = ( mObj->mFormat.mCoverageSamples > 0 ) || ( mObj->mFormat.mSamples > 0 ); if( useCSAA ) useMSAA = false; // allocate the framebuffer itself GL_SUFFIX(glGenFramebuffers)( 1, &mObj->mId ); GL_SUFFIX(glBindFramebuffer)( GL_SUFFIX(GL_FRAMEBUFFER_), mObj->mId ); Texture::Format textureFormat; textureFormat.setTarget( getTarget() ); textureFormat.setInternalFormat( getFormat().getColorInternalFormat() ); textureFormat.setWrap( mObj->mFormat.mWrapS, mObj->mFormat.mWrapT ); textureFormat.setMinFilter( mObj->mFormat.mMinFilter ); textureFormat.setMagFilter( mObj->mFormat.mMagFilter ); textureFormat.enableMipmapping( getFormat().hasMipMapping() ); // allocate the color buffers for( int c = 0; c < mObj->mFormat.mNumColorBuffers; ++c ) { mObj->mColorTextures.push_back( Texture( mObj->mWidth, mObj->mHeight, textureFormat ) ); } #if ! defined( CINDER_GLES ) if( mObj->mFormat.mNumColorBuffers == 0 ) { // no color glDrawBuffer( GL_NONE ); glReadBuffer( GL_NONE ); } #endif if( ( ( ! useCSAA ) && ( ! useMSAA ) ) || ( ! initMultisample( useCSAA ) ) ) { // if we don't need any variety of multisampling or it failed to initialize // attach all the textures to the framebuffer vector<GLenum> drawBuffers; for( size_t c = 0; c < mObj->mColorTextures.size(); ++c ) { GL_SUFFIX(glFramebufferTexture2D)( GL_SUFFIX(GL_FRAMEBUFFER_), GL_SUFFIX(GL_COLOR_ATTACHMENT0_) + c, getTarget(), mObj->mColorTextures[c].getId(), 0 ); drawBuffers.push_back( GL_SUFFIX(GL_COLOR_ATTACHMENT0_) + c ); } #if ! defined( CINDER_GLES ) if( ! drawBuffers.empty() ) glDrawBuffers( drawBuffers.size(), &drawBuffers[0] ); #endif // allocate and attach depth texture if( mObj->mFormat.mDepthBuffer ) { if( mObj->mFormat.mDepthBufferAsTexture ) { #if ! defined( CINDER_GLES ) GLuint depthTextureId; glGenTextures( 1, &depthTextureId ); glBindTexture( getTarget(), depthTextureId ); glTexImage2D( getTarget(), 0, getFormat().getDepthInternalFormat(), mObj->mWidth, mObj->mHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL ); glTexParameteri( getTarget(), GL_TEXTURE_MIN_FILTER, mObj->mFormat.mMinFilter ); glTexParameteri( getTarget(), GL_TEXTURE_MAG_FILTER, mObj->mFormat.mMagFilter ); glTexParameteri( getTarget(), GL_TEXTURE_WRAP_S, mObj->mFormat.mWrapS ); glTexParameteri( getTarget(), GL_TEXTURE_WRAP_T, mObj->mFormat.mWrapT ); glTexParameteri( getTarget(), GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE ); mObj->mDepthTexture = Texture( getTarget(), depthTextureId, mObj->mWidth, mObj->mHeight, true ); glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, getTarget(), mObj->mDepthTexture.getId(), 0 ); //glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, getTarget(), mObj->mDepthTexture.getId(), 0 ); #else throw; // this should never fire in OpenGL ES #endif } else if( mObj->mFormat.mDepthBuffer ) { // implement depth buffer as RenderBuffer mObj->mDepthRenderbuffer = Renderbuffer( mObj->mWidth, mObj->mHeight, mObj->mFormat.getDepthInternalFormat() ); GL_SUFFIX(glFramebufferRenderbuffer)( GL_SUFFIX(GL_FRAMEBUFFER_), GL_SUFFIX(GL_DEPTH_ATTACHMENT_), GL_SUFFIX(GL_RENDERBUFFER_), mObj->mDepthRenderbuffer.getId() ); } } FboExceptionInvalidSpecification exc; if( ! checkStatus( &exc ) ) { // failed creation; throw throw exc; } } mObj->mNeedsResolve = false; mObj->mNeedsMipmapUpdate = false; }
bool AppImplMswRendererGl::initializeInternal( HWND wnd, HDC dc ) { int pixelFormat; mWnd = wnd; mDC = dc; static PIXELFORMATDESCRIPTOR pfd = // pfd Tells Windows How We Want Things To Be { sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor 1, // Version Number PFD_DRAW_TO_WINDOW | // Format Must Support Window PFD_SUPPORT_OPENGL | // Format Must Support OpenGL PFD_DOUBLEBUFFER, // Must Support Double Buffering PFD_TYPE_RGBA, // Request An RGBA Format 32, // Select Our Color Depth 0, 0, 0, 0, 0, 0, // Color Bits Ignored 0, // No Alpha Buffer 0, // Shift Bit Ignored 0, // No Accumulation Buffer 0, 0, 0, 0, // Accumulation Bits Ignored 16, // 32Bit Z-Buffer (Depth Buffer) 0, // No Stencil Buffer 0, // No Auxiliary Buffer PFD_MAIN_PLANE, // Main Drawing Layer 0, // Reserved 0, 0, 0 // Layer Masks Ignored }; /* Our first pass, Multisampling hasn't been created yet, so we create a window normally If it is supported, then we're on our second pass that means we want to use our pixel format for sampling so set PixelFormat to arbMultiSampleformat instead */ if( ! sMultisampleSupported ) { pixelFormat = ::ChoosePixelFormat( dc, &pfd ); // Find A Compatible Pixel Format if( pixelFormat == 0 ) { // Did We Find A Compatible Format? return false; } } else { pixelFormat = sArbMultisampleFormat; } if( ! ::SetPixelFormat( dc, pixelFormat, &pfd ) ) { // Are We Able To Set The Pixel Format? return false; } if( ! ( mRC = ::wglCreateContext( dc ) ) ) { // Are We Able To Get A Rendering Context? return false; } if( ! ::wglMakeCurrent( dc, mRC ) ){ // Try To Activate The Rendering Context return false; } if (glewInit() != GLEW_OK) { console() << "GLEW failes to init." << std::endl; return false; } if( ( ! sMultisampleSupported ) && ( mRenderer->getAntiAliasing() > RendererGl::AA_NONE ) ) { int level = initMultisample( pfd, mRenderer->getAntiAliasing(), dc ); mRenderer->setAntiAliasing( RendererGl::AA_NONE + level ); if( level > 0 ) { // kill the current context and relaunch ::wglMakeCurrent( NULL, NULL ); ::wglDeleteContext( mRC ); return true; // our caller will run us again } } if( mPrevRC ) { BOOL success = ::wglCopyContext( mPrevRC, mRC, GL_ALL_ATTRIB_BITS ); } if( mPrevRC ) { wglShareLists( mPrevRC, mRC ); } return true; // Success }
GHOST_TSuccess GHOST_WindowWin32::installDrawingContext(GHOST_TDrawingContextType type) { GHOST_TSuccess success; switch (type) { case GHOST_kDrawingContextTypeOpenGL: { // If this window has multisample enabled, use the supplied format if (m_multisampleEnabled) { if (SetPixelFormat(m_hDC, m_msPixelFormat, &sPreferredFormat) == FALSE) { success = GHOST_kFailure; break; } // Create the context m_hGlRc = ::wglCreateContext(m_hDC); if (m_hGlRc) { if (::wglMakeCurrent(m_hDC, m_hGlRc) == TRUE) { if (s_firsthGLRc) { if (is_crappy_intel_card()) { if (::wglMakeCurrent(NULL, NULL) == TRUE) { ::wglDeleteContext(m_hGlRc); m_hGlRc = s_firsthGLRc; } else { ::wglDeleteContext(m_hGlRc); m_hGlRc = NULL; } } else { ::wglCopyContext(s_firsthGLRc, m_hGlRc, GL_ALL_ATTRIB_BITS); ::wglShareLists(s_firsthGLRc, m_hGlRc); } } else { s_firsthGLRc = m_hGlRc; } if (m_hGlRc) { success = ::wglMakeCurrent(m_hDC, m_hGlRc) == TRUE ? GHOST_kSuccess : GHOST_kFailure; } else { success = GHOST_kFailure; } } else { success = GHOST_kFailure; } } else { success = GHOST_kFailure; } if (success == GHOST_kFailure) { printf("Failed to get a context....\n"); } } else { if (m_stereoVisual) sPreferredFormat.dwFlags |= PFD_STEREO; // Attempt to match device context pixel format to the preferred format int iPixelFormat = EnumPixelFormats(m_hDC); if (iPixelFormat == 0) { success = GHOST_kFailure; break; } if (::SetPixelFormat(m_hDC, iPixelFormat, &sPreferredFormat) == FALSE) { success = GHOST_kFailure; break; } // For debugging only: retrieve the pixel format chosen PIXELFORMATDESCRIPTOR preferredFormat; ::DescribePixelFormat(m_hDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &preferredFormat); // Create the context m_hGlRc = ::wglCreateContext(m_hDC); if (m_hGlRc) { if (::wglMakeCurrent(m_hDC, m_hGlRc) == TRUE) { if (s_firsthGLRc) { if (is_crappy_intel_card()) { if (::wglMakeCurrent(NULL, NULL) == TRUE) { ::wglDeleteContext(m_hGlRc); m_hGlRc = s_firsthGLRc; } else { ::wglDeleteContext(m_hGlRc); m_hGlRc = NULL; } } else { ::wglShareLists(s_firsthGLRc, m_hGlRc); } } else { s_firsthGLRc = m_hGlRc; } if (m_hGlRc) { success = ::wglMakeCurrent(m_hDC, m_hGlRc) == TRUE ? GHOST_kSuccess : GHOST_kFailure; } else { success = GHOST_kFailure; } } else { success = GHOST_kFailure; } } else { success = GHOST_kFailure; } if (success == GHOST_kFailure) { printf("Failed to get a context....\n"); } // Attempt to enable multisample if (m_multisample && WGL_ARB_multisample && !m_multisampleEnabled && !is_crappy_intel_card()) { success = initMultisample(preferredFormat); if (success) { // Make sure we don't screw up the context if (m_hGlRc == s_firsthGLRc) s_firsthGLRc = NULL; m_drawingContextType = GHOST_kDrawingContextTypeOpenGL; removeDrawingContext(); // Create a new window GHOST_TWindowState new_state = getState(); m_nextWindow = new GHOST_WindowWin32((GHOST_SystemWin32 *)GHOST_ISystem::getSystem(), m_title, m_left, m_top, m_width, m_height, new_state, type, m_stereo, m_multisample, m_parentWindowHwnd, m_multisampleEnabled, m_msPixelFormat); // Return failure so we can trash this window. success = GHOST_kFailure; break; } else { m_multisampleEnabled = GHOST_kSuccess; printf("Multisample failed to initialized\n"); success = GHOST_kSuccess; } } } } break; case GHOST_kDrawingContextTypeNone: success = GHOST_kSuccess; break; default: success = GHOST_kFailure; } return success; }