Example #1
0
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
}
Example #3
0
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;
}