Exemplo n.º 1
0
bool
WebGLFramebuffer::Attachment::IsDeleteRequested() const
{
    return Texture() ? Texture()->IsDeleteRequested()
         : Renderbuffer() ? Renderbuffer()->IsDeleteRequested()
         : false;
}
Exemplo n.º 2
0
bool
WebGLFBAttachPoint::IsDeleteRequested() const
{
    return Texture() ? Texture()->IsDeleteRequested()
         : Renderbuffer() ? Renderbuffer()->IsDeleteRequested()
         : false;
}
Exemplo n.º 3
0
void
WebGLFramebuffer::Attachment::FinalizeAttachment(gl::GLContext* gl,
                                                 FBAttachment attachmentLoc) const
{
    if (!mNeedsFinalize)
        return;

    mNeedsFinalize = false;

    if (!HasImage()) {
        if (attachmentLoc == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
            gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
                                         LOCAL_GL_DEPTH_ATTACHMENT,
                                         LOCAL_GL_RENDERBUFFER, 0);
            gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
                                         LOCAL_GL_STENCIL_ATTACHMENT,
                                         LOCAL_GL_RENDERBUFFER, 0);
        } else {
            gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
                                         attachmentLoc.get(),
                                         LOCAL_GL_RENDERBUFFER, 0);
        }

        return;
    }
    MOZ_ASSERT(HasImage());

    if (Texture()) {
        MOZ_ASSERT(gl == Texture()->Context()->GL());

        const GLenum imageTarget = ImageTarget().get();
        const GLint mipLevel = MipLevel();
        const GLuint glName = Texture()->GLName();

        if (attachmentLoc == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
            gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
                                      LOCAL_GL_DEPTH_ATTACHMENT, imageTarget,
                                      glName, mipLevel);
            gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
                                      LOCAL_GL_STENCIL_ATTACHMENT, imageTarget,
                                      glName, mipLevel);
        } else {
            gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, attachmentLoc.get(),
                                      imageTarget, glName, mipLevel);
        }
        return;
    }

    if (Renderbuffer()) {
        Renderbuffer()->FramebufferRenderbuffer(attachmentLoc);
        return;
    }

    MOZ_ASSERT(false, "Should not get here.");
}
Exemplo n.º 4
0
bool
WebGLFBAttachPoint::HasImage() const
{
    if (Texture() && Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel).IsDefined())
        return true;

    if (Renderbuffer() && Renderbuffer()->IsDefined())
        return true;

    return false;
}
Exemplo n.º 5
0
bool Fbo::initMultisample( bool csaa )
{
#if defined( CINDER_GLES )
	return false;
#else
	glGenFramebuffersEXT( 1, &mObj->mResolveFramebufferId );
	glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, mObj->mResolveFramebufferId ); 
	
	// bind all of the color buffers to the resolve FB's attachment points
	vector<GLenum> drawBuffers;
	for( size_t c = 0; c < mObj->mColorTextures.size(); ++c ) {
		glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + c, getTarget(), mObj->mColorTextures[c].getId(), 0 );
		drawBuffers.push_back( GL_COLOR_ATTACHMENT0_EXT + c );
	}

	if( ! drawBuffers.empty() )
		glDrawBuffers( drawBuffers.size(), &drawBuffers[0] );

	// see if the resolve buffer is ok
	FboExceptionInvalidSpecification ignoredException;
	if( ! checkStatus( &ignoredException ) )
		return false;

	glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, mObj->mId );

	if( mObj->mFormat.mSamples > getMaxSamples() ) {
		mObj->mFormat.mSamples = getMaxSamples();
	}

	// setup the multisampled color renderbuffers
	for( int c = 0; c < mObj->mFormat.mNumColorBuffers; ++c ) {
		mObj->mMultisampleColorRenderbuffers.push_back( Renderbuffer( mObj->mWidth, mObj->mHeight, mObj->mFormat.mColorInternalFormat, mObj->mFormat.mSamples, mObj->mFormat.mCoverageSamples ) );

		// attach the multisampled color buffer
		glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + c, GL_RENDERBUFFER_EXT, mObj->mMultisampleColorRenderbuffers.back().getId() );
	}
	
	if( ! drawBuffers.empty() )
		glDrawBuffers( drawBuffers.size(), &drawBuffers[0] );

	if( mObj->mFormat.mDepthBuffer ) {
		// create the multisampled depth Renderbuffer
		mObj->mMultisampleDepthRenderbuffer = Renderbuffer( mObj->mWidth, mObj->mHeight, mObj->mFormat.mDepthInternalFormat, mObj->mFormat.mSamples, mObj->mFormat.mCoverageSamples );

		// attach the depth Renderbuffer
		glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mObj->mMultisampleDepthRenderbuffer.getId() );
	}

	// see if the primary framebuffer turned out ok
	return checkStatus( &ignoredException );
#endif // ! CINDER_GLES
}
Exemplo n.º 6
0
const webgl::FormatUsageInfo*
WebGLFBAttachPoint::Format() const
{
    MOZ_ASSERT(IsDefined());

    if (Texture())
        return Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel).mFormat;

    if (Renderbuffer())
        return Renderbuffer()->Format();

    return nullptr;
}
Exemplo n.º 7
0
const WebGLRectangleObject&
WebGLFramebuffer::AttachPoint::RectangleObject() const
{
    MOZ_ASSERT(HasImage(),
               "Make sure it has an image before requesting the rectangle.");

    if (Texture()) {
        MOZ_ASSERT(Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel));
        return Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel);
    }

    if (Renderbuffer())
        return *Renderbuffer();

    MOZ_CRASH("Should not get here.");
}
Exemplo n.º 8
0
void
WebGLFramebuffer::AttachPoint::FinalizeAttachment(gl::GLContext* gl,
                                                 FBAttachment attachmentLoc) const
{
    if (!HasImage()) {
        switch (attachmentLoc.get()) {
        case LOCAL_GL_DEPTH_ATTACHMENT:
        case LOCAL_GL_STENCIL_ATTACHMENT:
        case LOCAL_GL_DEPTH_STENCIL_ATTACHMENT:
            break;

        default:
            gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, attachmentLoc.get(),
                                         LOCAL_GL_RENDERBUFFER, 0);
            break;
        }

        return;
    }
    MOZ_ASSERT(HasImage());

    if (Texture()) {
        MOZ_ASSERT(gl == Texture()->Context()->GL());

        const GLenum imageTarget = ImageTarget().get();
        const GLint mipLevel = MipLevel();
        const GLuint glName = Texture()->GLName();

        if (attachmentLoc == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
            gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT,
                                      imageTarget, glName, mipLevel);
            gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_STENCIL_ATTACHMENT,
                                      imageTarget, glName, mipLevel);
        } else {
            gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, attachmentLoc.get(),
                                      imageTarget, glName, mipLevel);
        }
        return;
    }

    if (Renderbuffer()) {
        Renderbuffer()->FramebufferRenderbuffer(attachmentLoc);
        return;
    }

    MOZ_CRASH();
}
Exemplo n.º 9
0
bool
WebGLFramebuffer::AttachPoint::HasAlpha() const
{
    MOZ_ASSERT(HasImage());

    if (Texture() &&
        Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel))
    {
        return FormatHasAlpha(Texture()->ImageInfoAt(mTexImageTarget,
                                                     mTexImageLevel).EffectiveInternalFormat());
    }

    if (Renderbuffer())
        return FormatHasAlpha(Renderbuffer()->InternalFormat());

    return false;
}
Exemplo n.º 10
0
void
WebGLFBAttachPoint::Size(uint32_t* const out_width, uint32_t* const out_height) const
{
    MOZ_ASSERT(HasImage());

    if (Renderbuffer()) {
        *out_width = Renderbuffer()->Width();
        *out_height = Renderbuffer()->Height();
        return;
    }

    MOZ_ASSERT(Texture());
    MOZ_ASSERT(Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel).IsDefined());
    const auto& imageInfo = Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel);

    *out_width = imageInfo.mWidth;
    *out_height = imageInfo.mHeight;
}
Exemplo n.º 11
0
bool
WebGLFramebuffer::AttachPoint::HasUninitializedImageData() const
{
    if (!HasImage())
        return false;

    if (Renderbuffer())
        return Renderbuffer()->HasUninitializedImageData();

    if (Texture()) {
        MOZ_ASSERT(Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel));
        return Texture()->ImageInfoAt(mTexImageTarget,
                                      mTexImageLevel).HasUninitializedImageData();
    }

    MOZ_ASSERT(false, "Should not get here.");
    return false;
}
Exemplo n.º 12
0
bool
WebGLFBAttachPoint::IsDefined() const
{
    /*
    return (Renderbuffer() && Renderbuffer()->IsDefined()) ||
           (Texture() && Texture()->ImageInfoAt(mTexImageTarget,
                                                mTexImageLevel).IsDefined());
    */
    return (Renderbuffer() || Texture());
}
Exemplo n.º 13
0
void
WebGLFramebuffer::AttachPoint::SetImageDataStatus(WebGLImageDataStatus newStatus)
{
    if (!HasImage())
        return;

    if (Renderbuffer()) {
        Renderbuffer()->SetImageDataStatus(newStatus);
        return;
    }

    if (Texture()) {
        Texture()->SetImageDataStatus(mTexImageTarget, mTexImageLevel,
                                      newStatus);
        return;
    }

    MOZ_ASSERT(false, "Should not get here.");
}
Exemplo n.º 14
0
bool
WebGLFramebuffer::AttachPoint::HasImage() const
{
    if (Texture() && Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel))
        return true;

    if (Renderbuffer())
        return true;

    return false;
}
Exemplo n.º 15
0
TexInternalFormat
WebGLFramebuffer::AttachPoint::EffectiveInternalFormat() const
{
    const WebGLTexture* tex = Texture();
    if (tex && tex->HasImageInfoAt(mTexImageTarget, mTexImageLevel)) {
        return tex->ImageInfoAt(mTexImageTarget,
                                mTexImageLevel).EffectiveInternalFormat();
    }

    const WebGLRenderbuffer* rb = Renderbuffer();
    if (rb)
        return rb->InternalFormat();

    return LOCAL_GL_NONE;
}
Exemplo n.º 16
0
bool
WebGLFramebuffer::AttachPoint::IsDefined() const
{
    return Renderbuffer() ||
           (Texture() && Texture()->HasImageInfoAt(ImageTarget(), 0));
}
Exemplo n.º 17
0
void Fbo::init()
{
	bool useAA = m_impl->m_format.m_num_samples > 0;

	// allocate the framebuffer itself
	glGenFramebuffers(1, &m_impl->m_id);
    glBindFramebuffer(GL_FRAMEBUFFER, m_impl->m_id);

	Texture::Format textureFormat;
	textureFormat.set_target(target());
    auto col_fmt = format().color_internal_format();
	textureFormat.set_internal_format(col_fmt);
    
#if !defined(KINSKI_GLES)
    GLint float_types[] = {GL_R32F, GL_RG32F, GL_RGB32F, GL_RGBA32F};
    GLint one_comp_types[] = {GL_RED, GL_GREEN, GL_BLUE, GL_R32F};
    if(contains(float_types, col_fmt)){ textureFormat.set_data_type(GL_FLOAT); }
#endif
	textureFormat.set_wrap(m_impl->m_format.m_wrap_s, m_impl->m_format.m_wrap_t);
	textureFormat.set_min_filter(m_impl->m_format.m_min_filter);
	textureFormat.set_mag_filter(m_impl->m_format.m_mag_filter);
	textureFormat.set_mipmapping(format().has_mipmapping());

	// allocate the color buffers
	for(int c = 0; c < m_impl->m_format.m_num_color_buffers; ++c)
    {
        auto tex = Texture(m_impl->m_width, m_impl->m_height, textureFormat);
        
#if !defined(KINSKI_GLES)
        if(contains(one_comp_types, col_fmt)){ tex.set_swizzle(GL_RED, GL_RED, GL_RED, GL_ONE); }
#endif
		m_impl->m_color_textures.push_back(tex);
	}
	
#if !defined(KINSKI_GLES)
	if(m_impl->m_format.m_num_color_buffers == 0)
    {
        // no color
		glDrawBuffer(GL_NONE);
		glReadBuffer(GL_NONE);
	}
#endif
    
    if(useAA){ useAA = init_multisample(); }
    
	if(!useAA)
    {
        // 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 < m_impl->m_color_textures.size(); ++c)
        {
			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + c, target(),
                                   m_impl->m_color_textures[c].id(), 0);
			drawBuffers.push_back(GL_COLOR_ATTACHMENT0 + c);
		}
#if ! defined(KINSKI_GLES)
        if(!drawBuffers.empty()){ glDrawBuffers(drawBuffers.size(), &drawBuffers[0]); }
#endif

		// allocate and attach depth texture
		if(m_impl->m_format.m_depth_buffer)
        {
			if(m_impl->m_format.m_depth_buffer_texture)
            {
	#if ! defined(KINSKI_GLES)			
				GLuint depthTextureId;
				glGenTextures(1, &depthTextureId);
				glBindTexture(target(), depthTextureId);
				glTexImage2D(target(), 0, format().depth_internal_format(),
                             m_impl->m_width, m_impl->m_height, 0, GL_DEPTH_STENCIL,
                             GL_FLOAT_32_UNSIGNED_INT_24_8_REV, nullptr);
                
//                glTexImage2D(target(), 0, getFormat().getDepthInternalFormat(),
//                             m_impl->m_width, m_impl->m_height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
                
				glTexParameteri(target(), GL_TEXTURE_MIN_FILTER, m_impl->m_format.m_min_filter);
				glTexParameteri(target(), GL_TEXTURE_MAG_FILTER, m_impl->m_format.m_mag_filter);
				glTexParameteri(target(), GL_TEXTURE_WRAP_S, m_impl->m_format.m_wrap_s);
				glTexParameteri(target(), GL_TEXTURE_WRAP_T, m_impl->m_format.m_wrap_t);
				m_impl->m_depth_texture = Texture(target(), depthTextureId, m_impl->m_width,
                                                m_impl->m_height, false);
                
				glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, target(),
                                       m_impl->m_depth_texture.id(), 0);
                
                if(m_impl->m_format.has_stencil_buffer())
                {
                    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, target(),
                                           m_impl->m_depth_texture.id(), 0);
                }
	#endif
			}
            // implement depth buffer as RenderBuffer
			else if(m_impl->m_format.m_depth_buffer)
            {
				m_impl->m_depthRenderbuffer = Renderbuffer(m_impl->m_width, m_impl->m_height,
                                                          m_impl->m_format.depth_internal_format());
				glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
                                          m_impl->m_depthRenderbuffer.id());
                
                if(m_impl->m_format.has_stencil_buffer())
                {
                    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
                                              GL_RENDERBUFFER, m_impl->m_depthRenderbuffer.id());
                }
			}
		}

		FboExceptionInvalidSpecification exc;
        // failed creation; throw
		if(!check_status(&exc)) { throw exc; }
	}
	
	m_impl->m_needs_resolve = false;
	m_impl->m_needs_mipmap_update = false;
    
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
Exemplo n.º 18
0
void
WebGLFBAttachPoint::FinalizeAttachment(gl::GLContext* gl, GLenum attachment) const
{
    if (!HasImage()) {
        switch (attachment) {
        case LOCAL_GL_DEPTH_ATTACHMENT:
        case LOCAL_GL_STENCIL_ATTACHMENT:
        case LOCAL_GL_DEPTH_STENCIL_ATTACHMENT:
            break;

        default:
            gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, attachment,
                                         LOCAL_GL_RENDERBUFFER, 0);
            break;
        }

        return;
    }
    MOZ_ASSERT(HasImage());

    if (Texture()) {
        MOZ_ASSERT(gl == Texture()->mContext->GL());

        const GLenum imageTarget = ImageTarget().get();
        const GLint mipLevel = MipLevel();
        const GLint layer = Layer();
        const GLuint glName = Texture()->mGLName;

        switch (imageTarget) {
        case LOCAL_GL_TEXTURE_2D:
        case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X:
        case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
        case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
        case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
        case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
        case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
            if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
                gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT,
                                          imageTarget, glName, mipLevel);
                gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
                                          LOCAL_GL_STENCIL_ATTACHMENT, imageTarget,
                                          glName, mipLevel);
            } else {
                gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, attachment, imageTarget,
                                          glName, mipLevel);
            }
            break;

        case LOCAL_GL_TEXTURE_2D_ARRAY:
        case LOCAL_GL_TEXTURE_3D:
            if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
                gl->fFramebufferTextureLayer(LOCAL_GL_FRAMEBUFFER,
                                             LOCAL_GL_DEPTH_ATTACHMENT, glName, mipLevel,
                                             layer);
                gl->fFramebufferTextureLayer(LOCAL_GL_FRAMEBUFFER,
                                             LOCAL_GL_STENCIL_ATTACHMENT, glName,
                                             mipLevel, layer);
            } else {
                gl->fFramebufferTextureLayer(LOCAL_GL_FRAMEBUFFER, attachment, glName,
                                             mipLevel, layer);
            }
            break;
        }
        return ;
    }

    if (Renderbuffer()) {
        Renderbuffer()->FramebufferRenderbuffer(attachment);
        return;
    }

    MOZ_CRASH();
}
Exemplo n.º 19
0
bool Fbo::init_multisample()
{
#if defined(KINSKI_GLES)
	return false;
#else
	glGenFramebuffers(1, &m_impl->m_resolve_fbo_id);
	glBindFramebuffer(GL_FRAMEBUFFER, m_impl->m_resolve_fbo_id);
	
	// bind all of the color buffers to the resolve FB's attachment points
	vector<GLenum> drawBuffers;
	for(size_t c = 0; c < m_impl->m_color_textures.size(); ++c)
    {
		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + c, target(),
                               m_impl->m_color_textures[c].id(), 0);
		drawBuffers.push_back(GL_COLOR_ATTACHMENT0 + c);
	}

    if(!drawBuffers.empty()){ glDrawBuffers(drawBuffers.size(), &drawBuffers[0]); }

	// see if the resolve buffer is ok
	FboExceptionInvalidSpecification ignoredException;
    if(!check_status(&ignoredException)){ return false; }

	glBindFramebuffer(GL_FRAMEBUFFER, m_impl->m_id);

	m_impl->m_format.m_num_samples = std::min(m_impl->m_format.m_num_samples, max_num_samples());
    
	// setup the multisampled color renderbuffers
	for(int c = 0; c < m_impl->m_format.m_num_color_buffers; ++c)
    {
		m_impl->mMultisampleColorRenderbuffers.push_back(Renderbuffer(m_impl->m_width, m_impl->m_height,
                                                                    m_impl->m_format.m_color_internal_format,
                                                                    m_impl->m_format.m_num_samples));

		// attach the multisampled color buffer
		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + c, GL_RENDERBUFFER,
                                  m_impl->mMultisampleColorRenderbuffers.back().id());
	}
	
	if(!drawBuffers.empty())
		glDrawBuffers(drawBuffers.size(), &drawBuffers[0]);

	if(m_impl->m_format.m_depth_buffer)
    {
		// create the multisampled depth Renderbuffer
		m_impl->m_multisample_depth_renderbuffer = Renderbuffer(m_impl->m_width, m_impl->m_height,
                                                            m_impl->m_format.m_depth_internal_format,
                                                            m_impl->m_format.m_num_samples);

		// attach the depth Renderbuffer
		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
                                  m_impl->m_multisample_depth_renderbuffer.id());
        
        if(m_impl->m_format.has_stencil_buffer())
        {
            // attach the depth Renderbuffer
            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
                                      m_impl->m_multisample_depth_renderbuffer.id());
        }
	}

	// see if the primary framebuffer turned out ok
	return check_status(&ignoredException);
#endif // ! KINSKI_GLES
}
Exemplo n.º 20
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;
}
Exemplo n.º 21
0
bool
WebGLFramebuffer::AttachPoint::IsComplete() const
{
    if (!HasImage())
        return false;

    const WebGLRectangleObject& rect = RectangleObject();

    if (!rect.Width() ||
        !rect.Height())
    {
        return false;
    }

    if (Texture()) {
        MOZ_ASSERT(Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel));
        const WebGLTexture::ImageInfo& imageInfo =
            Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel);
        GLenum sizedFormat = imageInfo.EffectiveInternalFormat().get();

        if (mAttachmentPoint == LOCAL_GL_DEPTH_ATTACHMENT)
            return IsValidFBOTextureDepthFormat(sizedFormat);

        if (mAttachmentPoint == LOCAL_GL_STENCIL_ATTACHMENT) {
            // Textures can't have the correct format for stencil buffers.
            return false;
        }

        if (mAttachmentPoint == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT)
            return IsValidFBOTextureDepthStencilFormat(sizedFormat);

        if (mAttachmentPoint >= LOCAL_GL_COLOR_ATTACHMENT0 &&
            mAttachmentPoint <= FBAttachment(LOCAL_GL_COLOR_ATTACHMENT0 - 1 +
                                             WebGLContext::kMaxColorAttachments))
        {
            WebGLContext* webgl = Texture()->Context();
            return webgl->IsFormatValidForFB(sizedFormat);
        }
        MOZ_ASSERT(false, "Invalid WebGL attachment point?");
        return false;
    }

    if (Renderbuffer()) {
        GLenum internalFormat = Renderbuffer()->InternalFormat();

        if (mAttachmentPoint == LOCAL_GL_DEPTH_ATTACHMENT)
            return IsValidFBORenderbufferDepthFormat(internalFormat);

        if (mAttachmentPoint == LOCAL_GL_STENCIL_ATTACHMENT)
            return IsValidFBORenderbufferStencilFormat(internalFormat);

        if (mAttachmentPoint == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT)
            return IsValidFBORenderbufferDepthStencilFormat(internalFormat);

        if (mAttachmentPoint >= LOCAL_GL_COLOR_ATTACHMENT0 &&
            mAttachmentPoint <= FBAttachment(LOCAL_GL_COLOR_ATTACHMENT0 - 1 +
                                             WebGLContext::kMaxColorAttachments))
        {
            WebGLContext* webgl = Renderbuffer()->Context();
            return webgl->IsFormatValidForFB(internalFormat);
        }
        MOZ_ASSERT(false, "Invalid WebGL attachment point?");
        return false;
    }
    MOZ_ASSERT(false, "Should not get here.");
    return false;
}