示例#1
0
文件: dlist.c 项目: blaztinn/piglit
void
piglit_init(int argc, char **argv)
{
	GLint max_samples, rb_samples;
	GLuint rb, list;
	GLint width;
	bool pass = true;

	piglit_require_extension("GL_EXT_framebuffer_multisample");

	glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
	if (!piglit_check_gl_error(0))
		piglit_report_result(PIGLIT_FAIL);

	glGenRenderbuffersEXT(1, &rb);
	glBindRenderbufferEXT(GL_RENDERBUFFER, rb);

	/* Make the list.  The Storage should be called during compile. */
	list = glGenLists(1);
	glNewList(list, GL_COMPILE);
	glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER,
					    max_samples,
					    GL_RGBA,
					    1, 1);
	glEndList();

	/* Make sure that the command occurred during the compile. */
	glGetRenderbufferParameterivEXT(GL_RENDERBUFFER,
					GL_RENDERBUFFER_SAMPLES,
					&rb_samples);
	if (rb_samples != max_samples) {
		fprintf(stderr, "glRenderbufferStorageMultisampleEXT not called during "
			"display list compile\n");
		pass = false;
	}


	/* Now, make sure that it doesn't occur at execute.  Start
	 * with storage of a different size so we can distinguish.
	 */
	glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER,
					    max_samples,
					    GL_RGBA,
					    2, 2);

	glCallList(list);
	glGetRenderbufferParameterivEXT(GL_RENDERBUFFER,
					GL_RENDERBUFFER_WIDTH,
					&width);

	if (width != 2) {
		fprintf(stderr, "glRenderbufferStorageMultisampleEXT called "
			"during display list execute");
		pass = false;
	}

	glDeleteRenderbuffersEXT(1, &rb);

	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}
void LLMultisampleBuffer::allocateDepth()
{
	glGenRenderbuffersEXT(1, (GLuint* ) &mDepth);
	glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mDepth);
	if (mStencil)
	{
		glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, mSamples, GL_DEPTH24_STENCIL8_EXT, mResX, mResY);	
	}
	else
	{
		glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, mSamples, GL_DEPTH_COMPONENT16_ARB, mResX, mResY);	
	}
}
示例#3
0
Renderbuffer::Obj::Obj( int aWidth, int aHeight, GLenum internalFormat, int msaaSamples, int coverageSamples )
	: mWidth( aWidth ), mHeight( aHeight ), mInternalFormat( internalFormat ), mSamples( msaaSamples ), mCoverageSamples( coverageSamples )
{
#if defined( CINDER_MSW )
	static bool csaaSupported = ( GLEE_NV_framebuffer_multisample_coverage != 0 );
#else
	static bool csaaSupported = false;
#endif

	GL_SUFFIX(glGenRenderbuffers)( 1, &mId );

	if( mSamples > Fbo::getMaxSamples() )
		mSamples = Fbo::getMaxSamples();

	if( ! csaaSupported )
		mCoverageSamples = 0;

	GL_SUFFIX(glBindRenderbuffer)( GL_SUFFIX(GL_RENDERBUFFER_), mId );

#if ! defined( CINDER_GLES )
  #if defined( CINDER_MSW )
	if( mCoverageSamples ) // create a CSAA buffer
		glRenderbufferStorageMultisampleCoverageNV( GL_RENDERBUFFER_EXT, mCoverageSamples, mSamples, mInternalFormat, mWidth, mHeight );
	else
  #endif
	if( mSamples ) // create a regular MSAA buffer
		glRenderbufferStorageMultisampleEXT( GL_RENDERBUFFER_EXT, mSamples, mInternalFormat, mWidth, mHeight );
	else
#endif
		GL_SUFFIX(glRenderbufferStorage)( GL_SUFFIX(GL_RENDERBUFFER_), mInternalFormat, mWidth, mHeight );
}
示例#4
0
bool RenderSurface::CreateRenderBuffer(unsigned width, unsigned height, unsigned format, int multiSample)
{
    Graphics* graphics = parentTexture_->GetGraphics();
    if (!graphics)
        return false;

    Release();

#ifndef GL_ES_VERSION_2_0
    if (Graphics::GetGL3Support())
    {
        glGenRenderbuffers(1, &renderBuffer_);
        glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer_);
        if (multiSample > 1)
            glRenderbufferStorageMultisample(GL_RENDERBUFFER, multiSample, format, width, height);
        else
            glRenderbufferStorage(GL_RENDERBUFFER, format, width, height);
        glBindRenderbuffer(GL_RENDERBUFFER, 0);
    }
    else
#endif
    {
        glGenRenderbuffersEXT(1, &renderBuffer_);
        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderBuffer_);
#ifndef GL_ES_VERSION_2_0
        if (multiSample > 1)
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, multiSample, format, width, height);
        else
#endif
            glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, format, width, height);
        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
    }

    return true;
}
void GL_GenerateFBO(GLuint texId, GLuint *fboId, int w, int h) {
	GLuint cRboId;
	Console_Printf("    Generate FBO %dx%d. ", w, h);
	
	glGenFramebuffersEXT(1, fboId);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, *fboId);
	
	if(vid_multisample.integer && gl_ext_framebuffer_multisample.integer) {
		Console_Printf("(MSAA) ");
		glGenRenderbuffersEXT(1, &cRboId);
		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, cRboId);
		
		glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, vid_multisample.integer, GL_RGBA, w, h);
		glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, cRboId);
	}

	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, texId, 0);

	//glDrawBuffer(GL_FRONT);
	//glReadBuffer(GL_FRONT);

	GL_CheckFBOStatus();
	
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
void
piglit_init(int argc, char **argv)
{
	GLint max_samples;
	GLuint rb;

	piglit_require_extension("GL_EXT_framebuffer_multisample");

	if (piglit_is_extension_supported("GL_ARB_internalformat_query")) {
		printf("ARB_internalformat_query is supported and "
		       "redefines this behavior; skipping\n");
		piglit_report_result(PIGLIT_SKIP);
	}
	if (piglit_is_extension_supported("GL_ARB_texture_multisample")) {
		printf("ARB_texture_multisample is supposed and "
		       "redefines this behavior; skipping\n");
		piglit_report_result(PIGLIT_SKIP);
	}

	glGetIntegerv(GL_MAX_SAMPLES, &max_samples);

	glGenRenderbuffersEXT(1, &rb);
	glBindRenderbufferEXT(GL_RENDERBUFFER, rb);

	glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER,
					    max_samples + 1,
					    GL_RGBA,
					    1, 1);
	if (!piglit_check_gl_error(GL_INVALID_VALUE))
		piglit_report_result(PIGLIT_FAIL);

	glDeleteRenderbuffersEXT(1, &rb);

	piglit_report_result(PIGLIT_PASS);
}
 inline void VL_glRenderbufferStorageMultisample( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height )
 {
   if (glRenderbufferStorageMultisample)
     glRenderbufferStorageMultisample(target, samples, internalformat, width, height);
   else
   if (glRenderbufferStorageMultisampleEXT)
     glRenderbufferStorageMultisampleEXT(target, samples, internalformat, width, height);
   else
     VL_UNSUPPORTED_FUNC();
 }
示例#8
0
	void display_reset(int samples, bool vsync) {
		int interval = vsync ? 1 : 0;

		if (enigma::is_ext_swapcontrol_supported()) {
		  wglSwapIntervalEXT(interval);
		}
 
		GLint fbo;
		glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &fbo);
 
		GLuint ColorBufferID, DepthBufferID;

		// Cleanup the multi-sampler fbo if turning off multi-sampling
		if (samples == 0) {
			if (enigma::msaa_fbo != 0) {
				glDeleteFramebuffers(1, &enigma::msaa_fbo);
				enigma::msaa_fbo = 0;
			}
			return;
		}

		//TODO: Change the code below to fix this to size properly to views
		// If we don't already have a multi-sample fbo then create one
		if (enigma::msaa_fbo == 0) {
			glGenFramebuffersEXT(1, &enigma::msaa_fbo);
		}
		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, enigma::msaa_fbo);
		// Now make a multi-sample color buffer
		glGenRenderbuffersEXT(1, &ColorBufferID);
		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, ColorBufferID);
		glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_RGBA8, window_get_region_width_scaled(), window_get_region_height_scaled());
		// We also need a depth buffer
		glGenRenderbuffersEXT(1, &DepthBufferID);
		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthBufferID);
		glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_DEPTH_COMPONENT24, window_get_region_width_scaled(), window_get_region_height_scaled());
		// Attach the render buffers to the multi-sampler fbo
		glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, ColorBufferID);
		glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, DepthBufferID);
		
	}
示例#9
0
void RenderBuffer::init(const QSize& size, uint internal_format, int numSamp)
{
    if (m_obj != -1)
        destroy();

    glGenRenderbuffersEXT(1, &m_obj);
    Q_ASSERT(!glIsRenderbufferEXT(m_obj));
    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_obj);
    Q_ASSERT(glIsRenderbufferEXT(m_obj));
    
    glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, numSamp, internal_format, size.width(), size.height());
    mglCheckErrors("renderBuf");
}
示例#10
0
PIGLIT_GL_TEST_CONFIG_END

void
piglit_init(int argc, char **argv)
{
	glGetIntegerv(GL_MAX_SAMPLES_EXT, &numSamples);

	glGenFramebuffersEXT(1, &framebuffer);
	glGenRenderbuffersEXT(1, &renderbuffer);
	glBindFramebufferEXT(GL_FRAMEBUFFER, framebuffer);
	glBindRenderbufferEXT(GL_RENDERBUFFER, renderbuffer);
	glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, numSamples, GL_RGBA, WIDTH, HEIGHT);
	glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
	glEnable (GL_MULTISAMPLE);
}
示例#11
0
void vsx_texture::init_buffer(int width, int height, bool float_texture, bool alpha, bool enable_multisample)
{
  GLenum gl_error; glGetError();
  locked = false;
  prev_buf = 0;
  #ifndef VSXU_OPENGL_ES
    glewInit();
  #endif
  int i_width = width;
  int i_height = height;

  if ( !has_buffer_support() )
  {
    printf("vsx_texture error: No FBO available!\n");
    return;
  }
  GLint prev_buf_l;
  GLuint tex_id;
  glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, (GLint *)&prev_buf_l); HANDLE_GL_ERROR

  // color buffer
  glGenRenderbuffersEXT(1, &colorBuffer); HANDLE_GL_ERROR

  glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, colorBuffer); HANDLE_GL_ERROR

  if(enable_multisample && GLEW_EXT_framebuffer_multisample)
  {
    if (float_texture)
    {
      glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, 4, alpha?GL_RGBA16F_ARB:GL_RGB16F_ARB, width, height); HANDLE_GL_ERROR
    }
    else
    {
      glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, 4, alpha?GL_RGBA8:GL_RGB8, width, height); HANDLE_GL_ERROR
    }
  }
示例#12
0
void
piglit_init(int argc, char **argv)
{
	GLint max_samples;
	GLuint rb, fb, tex;
	GLenum status;
	bool pass = true;

	piglit_require_extension("GL_EXT_framebuffer_multisample");

	glGetIntegerv(GL_MAX_SAMPLES, &max_samples);

	glGenFramebuffersEXT(1, &fb);
	glBindFramebufferEXT(GL_FRAMEBUFFER, fb);

	glGenRenderbuffersEXT(1, &rb);
	glBindRenderbufferEXT(GL_RENDERBUFFER, rb);
	glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, max_samples,
					    GL_RGBA, 1, 1);

	glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
				     GL_RENDERBUFFER, rb);

	glDrawBuffer(GL_COLOR_ATTACHMENT0);
	glReadBuffer(GL_COLOR_ATTACHMENT0);

	status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
	if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
		fprintf(stderr, "FBO incomplete\n");
		piglit_report_result(PIGLIT_FAIL);
	}

	glGenTextures(1, &tex);
	glBindTexture(GL_TEXTURE_2D, tex);

	/* Finally, the actual test! */
	glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 1, 1, 0);
	if (!piglit_check_gl_error(GL_INVALID_FRAMEBUFFER_OPERATION))
		piglit_report_result(PIGLIT_FAIL);

	glDeleteTextures(1, &tex);
	glDeleteRenderbuffersEXT(1, &rb);
	glDeleteFramebuffersEXT(1, &fb);

	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}
示例#13
0
    GLDepthStencilView::GLDepthStencilView(uint32 width, uint32 height, ElementFormat ef, uint32 sampleCount, uint32 sampleQuality):
    mLevel(-1),
    mRBO(0),
    mSampleCount(sampleCount),
    mSampleQuaility(sampleQuality) {
        mWidth = width;
        mHeight = height;
        mElementFormat = ef;

        CHECK_GL_CALL(glGenRenderbuffers(1, &mRBO));
        if(mRBO) {
            glBindRenderbuffer(GL_RENDERBUFFER, mRBO);

            if(mSampleCount <= 1 || !glRenderbufferStorageMultisampleEXT)
                glRenderbufferStorage(GL_RENDERBUFFER, element_format_to_gl_format(ef), width, height);
            else
                glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, mSampleCount, element_format_to_gl_format(ef), width, height);
        }
    }
示例#14
0
void
piglit_init(int argc, char **argv)
{
	GLint max_samples, samples, prev_rb_samples = 0;
	GLuint rb;
	bool pass = true;

	piglit_require_extension("GL_EXT_framebuffer_multisample");

	glGetIntegerv(GL_MAX_SAMPLES, &max_samples);

	glGenRenderbuffersEXT(1, &rb);
	glBindRenderbufferEXT(GL_RENDERBUFFER, rb);
	printf("%10s %10s\n", "requested", "result");
	for (samples = 0; samples <= max_samples; samples++) {
		GLint rb_samples;

		glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER,
						    samples,
						    GL_RGBA,
						    1, 1);

		glGetRenderbufferParameterivEXT(GL_RENDERBUFFER,
						GL_RENDERBUFFER_SAMPLES,
						&rb_samples);

		if ((rb_samples < prev_rb_samples) ||
		    (samples == 0 && rb_samples != 0) ||
		    (samples > 0 && rb_samples < samples)) {
			fprintf(stderr, "%10d %10d (ERROR)\n", samples, rb_samples);
			pass = false;
		} else {
			printf("%10d %10d\n", samples, rb_samples);
		}

		prev_rb_samples = rb_samples;
	}
	glDeleteRenderbuffersEXT(1, &rb);

	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}
void LLMultisampleBuffer::addColorAttachment(U32 color_fmt)
{
	if (color_fmt == 0)
	{
		return;
	}

	U32 offset = mTex.size();
	if (offset >= 4 ||
		(offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers)))
	{
		llerrs << "Too many color attachments!" << llendl;
	}

	U32 tex;
	glGenRenderbuffersEXT(1, &tex);
	
	glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, tex);
	glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, mSamples, color_fmt, mResX, mResY);
	stop_glerror();

	if (mFBO)
	{
		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);
		glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+offset, GL_RENDERBUFFER_EXT, tex);
		stop_glerror();
		GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
		switch (status)
		{
		case GL_FRAMEBUFFER_COMPLETE_EXT:
			break;
		default:
			llerrs << "WTF? " << std::hex << status << llendl;
			break;
		}

		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
	}

	mTex.push_back(tex);
}
示例#16
0
    GLDepthStencilView::GLDepthStencilView(const TexturePtr& texture, int32 level):
    mTexture(texture),
    mLevel(level),
    mRBO(0),
    mSampleCount(1),
    mSampleQuaility(1) {
        GLTexture2D* glTexture = (GLTexture2D*)mTexture.get();
        mTex = (GLuint)glTexture->getTextureId();
        mWidth = glTexture->width(0);
        mHeight = glTexture->height(0);
        mElementFormat = glTexture->format();

        CHECK_GL_CALL(glGenRenderbuffers(1, &mRBO));
        if(mRBO) {
            CHECK_GL_CALL(glBindRenderbuffer(GL_RENDERBUFFER, mRBO));

            if(mSampleCount <= 1 || !glRenderbufferStorageMultisampleEXT) {
                CHECK_GL_CALL(glRenderbufferStorage(GL_RENDERBUFFER, element_format_to_gl_format(mElementFormat), mWidth, mHeight));
            }
            else {
                CHECK_GL_CALL(glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, mSampleCount, element_format_to_gl_format(mElementFormat), mWidth, mHeight));
            }
        }
    }
示例#17
0
void GLTexture::init() {
	if (m_fbType == ENone)
		Log(ETrace, "Uploading a texture : %s", toString().c_str());
	else
		Log(ETrace, "Creating a framebuffer : %s", toString().c_str());

	if (m_samples > 1) {
		int maxSamples = 1;
		if (GLEW_ARB_texture_multisample)
			glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples);
		if (m_samples > maxSamples) {
			Log(EWarn, "Attempted to create a multisample framebuffer "
				"with an unsupported number of samples (requested=%i, supported=%i)",
				m_samples, maxSamples);
			m_samples = maxSamples;
		}
	}

	lookupGLConstants();

	/* Generate an identifier */
	glGenTextures(1, &m_id);

	/* Bind to the texture */
	glBindTexture(m_glType, m_id);

	/* Set the texture filtering / wrapping modes
	   (don't do this for multisample textures)*/
	if (!((m_fbType & EColorBuffer) && m_samples > 1))
		configureTexture(); /* Multisample textures don't have these parameters */

	if (m_fbType == ENone) {
		Assert(m_samples == 1);
		refresh();
	} else {
		/* Create the FBO and bind it */
		glGenFramebuffersEXT(1, &m_fboId);
		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fboId);

		AssertEx(glIsFramebufferEXT(m_fboId), "Creating an FBO failed");
		bool depthAsTexture = m_fbType & EDepthBuffer;

		switch (m_fbType) {
			case EColorAndDepthBuffer:
			case EColorBuffer: {
					if (m_type == ETexture2D) {
						if (!depthAsTexture) {
							glGenRenderbuffersEXT(1, &m_depthId);
							glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthId);
							if (m_samples == 1)
								glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
									GL_DEPTH_COMPONENT32, m_size.x, m_size.y);
							else
								glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT,
									m_samples, GL_DEPTH_COMPONENT32, m_size.x, m_size.y);
							glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
								GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthId);
						} else {
							glGenTextures(1, &m_depthId);
							glBindTexture(m_glType, m_depthId);
							configureTexture();
							glTexParameteri(m_glType, GL_TEXTURE_COMPARE_MODE, GL_NONE);
							glTexParameteri(m_glType, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
							if (m_samples == 1)
								glTexImage2D(m_glType, 0, GL_DEPTH_COMPONENT32, m_size.x, m_size.y,
									0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
							else
								glTexImage2DMultisample(m_glType,
									m_samples, GL_DEPTH_COMPONENT32, m_size.x, m_size.y, GL_FALSE);
							glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
								GL_DEPTH_ATTACHMENT, m_glType, m_depthId, 0);
							glBindTexture(m_glType, m_id);
						}

						if (m_samples == 1)
							glTexImage2D(m_glType, 0, m_internalFormat, m_size.x, m_size.y,
								0, m_format, m_dataFormat, NULL);
						else
							glTexImage2DMultisample(m_glType,
								m_samples, m_internalFormat, m_size.x, m_size.y, GL_FALSE);

						if (isMipMapped())
							glGenerateMipmapEXT(m_glType);

						glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
							GL_COLOR_ATTACHMENT0_EXT, m_glType, m_id, 0);
					} else if (m_type == ETextureCubeMap) {
						Assert(m_size.x == m_size.y && math::isPowerOfTwo(m_size.x));
						Assert(m_fbType == EColorBuffer);
						Assert(m_samples == 1);

						for (int i=0; i<6; i++)
							glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, m_internalFormat,
								m_size.x, m_size.y, 0, m_format, m_dataFormat, NULL);

						if (isMipMapped())
							glGenerateMipmapEXT(m_glType);

						if (depthAsTexture) {
							/* Generate an identifier */
							glGenTextures(1, &m_depthId);
							glBindTexture(m_glType, m_depthId);
							glTexParameteri(m_glType, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
							glTexParameteri(m_glType, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

							for (int i=0; i<6; i++)
								glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT32,
									m_size.x, m_size.y, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);

							if (GLEW_EXT_geometry_shader4)
								activateSide(-1);
							else
								activateSide(0);
						} else {
							glGenRenderbuffersEXT(1, &m_depthId);
							glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthId);
							glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
								GL_DEPTH_COMPONENT32, m_size.x, m_size.y);
							glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
								GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthId);
							activateSide(0);
						}
					} else {
						Log(EError, "Unsupported texture type!");
					}
				}
				break;
			case EDepthBuffer:
				Assert(m_samples == 1);
				if (m_depthMode == ECompare) {
					glTexParameteri(m_glType, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
					glTexParameteri(m_glType, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
				}

				if (m_type == ETexture2D) {
					/* Allocate the texture memory */
					glTexImage2D(m_glType, 0, m_internalFormat,
						m_size.x, m_size.y, 0, GL_DEPTH_COMPONENT,
						m_dataFormat, NULL);

					/* Attach the texture as a depth target */
					glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
						GL_DEPTH_ATTACHMENT_EXT, m_glType, m_id, 0);
				} else if (m_type == ETextureCubeMap) {
					Assert(m_size.x == m_size.y && math::isPowerOfTwo(m_size.x));
					for (int i=0; i<6; i++)
						glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, m_internalFormat,
							m_size.x, m_size.y, 0, m_format, m_dataFormat, NULL);

					if (GLEW_EXT_geometry_shader4)
						activateSide(-1);
					else
						activateSide(0);
				} else {
					Log(EError, "Unsupported texture type!");
				}

				glDrawBuffer(GL_NONE);
				glReadBuffer(GL_NONE);
				break;
			default:
				Log(EError, "Invalid render buffer type!");
		}

		GLenum errorStatusID = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
		std::string errorStatus;
		switch (errorStatusID) {
			case GL_FRAMEBUFFER_COMPLETE_EXT: break;
			case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
				errorStatus = "Incomplete attachment"; break;
			case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
				errorStatus = "Unsupported framebuffer format"; break;
			case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT:
				errorStatus = "Incomplete framebuffer - duplicate attachment"; break;
			case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
				errorStatus = "Incomplete framebuffer - missing attachment"; break;
			case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
				errorStatus = "Incomplete framebuffer - invalid dimensions"; break;
			case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
				errorStatus = "Incomplete framebuffer - no draw buffer"; break;
			case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
				errorStatus = "Incomplete framebuffer - invalid formats"; break;
			case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
				errorStatus = "Incomplete framebuffer - no readbuffer"; break;
			case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT:
				errorStatus = "Incomplete multisample framebuffer"; break;
			case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
				errorStatus = "Incomplete layer targets"; break;
			default:
				errorStatus = "Unknown error status"; break;
		}
		if (!errorStatus.empty())
			Log(EError, "FBO Error 0x%x: %s!\nFramebuffer configuration: %s",
				errorStatusID, errorStatus.c_str(), toString().c_str());

		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, GL_NONE);
	}

	glBindTexture(m_glType, GL_NONE);
}
void ofxFBOTexture::allocate(int w, int h, int internalGlDataType, int numSamples) {
	_isActive = false;


	//OpenGL supported technologies checking.
	
	if(!bSupportsFBO){
		ofLog(OF_LOG_ERROR, "ofxFBOTexture: GL_EXT_framebuffer_object not supported by current OpenGL renderer. "
							" For Apple machines, more info at http://developer.apple.com/graphicsimaging/opengl/capabilities");
		return;
	}
	
	if(!bSupportsMulti && numSamples){
		ofLog(OF_LOG_WARNING, "ofxFBOTexture: GL_EXT_framebuffer_multisample not supported by current OpenGL renderer."
							" Falling back to non-multisampled mode. To disable this message, specify 0 samples."
							" Apple machines, more info at http://developer.apple.com/graphicsimaging/opengl/capabilities");
		numSamples = 0;
	}
	
	if(!bSupportsBlit && numSamples){
		
		//if there's no blit, then it's not worth using multi
		
		ofLog(OF_LOG_WARNING, "ofxFBOTexture: GL_EXT_framebuffer_blit not supported by current OpenGL renderer."
			  " Falling back to non-multisampled mode. To disable this message, specify 0 samples."
			  " Apple machines, more info at http://developer.apple.com/graphicsimaging/opengl/capabilities");
		numSamples = 0;
	}
	
	
	if(maxSamples < numSamples){
		ofLog(OF_LOG_WARNING, "ofxFBOTexture: requested samples too high. Using GL_SAMPLES instead.");
		numSamples = maxSamples;
	}
	
	
	//validate requested dimensions to see that they are within limits.
	
	if(maxTextureSize < w || maxRenderBufferSize < w){
		ofLog(OF_LOG_WARNING, "ofxFBOTexture: requested width was too large. Using largest allowed value instead.");
		if(maxTextureSize < w) w = maxTextureSize;
		if(maxRenderBufferSize < w) w = maxRenderBufferSize;
	}
	
	if( maxTextureSize < h || maxRenderBufferSize < h){
		ofLog(OF_LOG_WARNING, "ofxFBOTexture: requested height was too large. Using largest allowed value instead.");
		if(maxTextureSize < h) h = maxTextureSize;
		if(maxRenderBufferSize < h) h = maxRenderBufferSize;
	}
	

	/**
		 validates arg3 for legacy function calling style
		 i dont check for 1 because 1 is a valid internal color format
		 so we're not sure if the person is passing a boolean or a color format
		 so we can't accuse them of doing the legacy boolean thing.
		 Even if that stops the FBO, the other color format error will help them out.
	 */
	if(internalGlDataType==0){
		ofLog(OF_LOG_WARNING, "ofxFBOTexture::allocate( _ , _ , HERE , _ ) "
			  "The calling statement passed a boolean value like an older version of FBO object. "
			  "This argument has changed to be a color format "
			  "like GL_RGB, GL_RGBA, GL_RGBA16F_ARB, and GL_RGBA32F_ARB. "
			  "Defaulting to GL_RGBA.");
		
		internalGlDataType = GL_RGBA;
	}
	
	
	
	// attempt to free the previous bound texture, if we can:
	clean();
	
	texData.width = w;
	texData.height = h;
	this->numSamples = numSamples;
	
/*
 *GLEE_ARB_texture_rectangle thows errors in the latest from github (post 0062?) so i commented this out

 */
	//#ifndef TARGET_OPENGLES	
//    if (GLEE_ARB_texture_rectangle){
//        texData.tex_w = w;
//        texData.tex_h = h;
//        texData.textureTarget = GL_TEXTURE_RECTANGLE_ARB;
//    } else
//#endif	
//	{	
        texData.tex_w = ofNextPow2(w);
        texData.tex_h = ofNextPow2(h);
//    }
	
//#ifndef TARGET_OPENGLES	
//	if (GLEE_ARB_texture_rectangle){
//		texData.tex_t = w;
//		texData.tex_u = h;
//	} else
//#endif	
//	{
		texData.tex_t = w/texData.tex_w;
		texData.tex_u = h/texData.tex_h;
	//}
	
	texData.width = w;
	texData.height = h;
	texData.bFlipTexture = true;
	texData.glTypeInternal = internalGlDataType;
	
#ifndef TARGET_OPENGLES	
	switch(texData.glTypeInternal) {
		case GL_RGBA32F_ARB:
		case GL_RGBA16F_ARB:
			texData.glType		= GL_RGBA;
			texData.pixelType	= GL_FLOAT;
			pixels				= new float[w * h * 4];
			break;			
		default:
			texData.glType		= texData.glTypeInternal;
			texData.pixelType	= GL_UNSIGNED_BYTE;
			pixels				= new float[w * h * 4];
			break;
	}
#else
	texData.glType		= GL_RGBA;
	texData.pixelType	= GL_UNSIGNED_BYTE;
	pixels				= new unsigned char[w * h * 4];
#endif			
	
	
	// create & setup texture
	glGenTextures(1, (GLuint *)&texData.textureID);   // could be more then one, but for now, just one
	glBindTexture(texData.textureTarget, (GLuint)texData.textureID);
	glTexParameterf(texData.textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameterf(texData.textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexParameterf(texData.textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameterf(texData.textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexImage2D(texData.textureTarget, 0, texData.glTypeInternal, texData.tex_w, texData.tex_h, 0, texData.glType, texData.pixelType, 0);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	
	
#ifndef TARGET_OPENGLES
	glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, (GLint *) &oldFramebuffer);
	
	if(numSamples ){
		// MULTISAMPLE //
		
		//THEO Create the render buffer for depth
		glGenRenderbuffersEXT(1, &depthBuffer);
		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBuffer);
		glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, numSamples, GL_DEPTH_COMPONENT, texData.tex_w, texData.tex_h);
		
		//THEO multi sampled color buffer
		glGenRenderbuffersEXT(1, &colorBuffer);
		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, colorBuffer);
		glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, numSamples, texData.glTypeInternal, texData.tex_w, texData.tex_h);
		
		//THEO create fbo for multi sampled content and attach depth and color buffers to it
		glGenFramebuffersEXT(1, &mfbo);
		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mfbo);
		glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, colorBuffer);
		glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthBuffer);
		
	}else{
		//THEO Create the render buffer for depth
		glGenRenderbuffersEXT(1, &depthBuffer);
		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBuffer);
		glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, texData.tex_w, texData.tex_h);
		glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthBuffer);
	}
	
	// create & setup FBO
	glGenFramebuffersEXT(1, &fbo);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
	
	// attach it to the FBO so we can render to it
	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, texData.textureTarget, (GLuint)texData.textureID, 0);
	
	GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
	if(status != GL_FRAMEBUFFER_COMPLETE_EXT) {
		
		//validate arg3 after the fact because it's worth letting them try that format.
		
		if(internalGlDataType != GL_RGBA &&
		   internalGlDataType != GL_RGB &&
		   internalGlDataType != GL_RGBA16F_ARB &&
		   internalGlDataType != GL_RGBA32F_ARB){
			
			ofLog(OF_LOG_ERROR,  "ofxFBOTexture: Failed to initialize. "
				  "I noticed that the calling statement did not passed an expected color format "
				  "like GL_RGB, GL_RGBA, GL_RGBA16F_ARB, and GL_RGBA32F_ARB. You might try one of those. "
				  "ofxFBOTexture::allocate( _ , _ , HERE , _ ) ");
			
		}else{
			ofLog(OF_LOG_ERROR, "ofxFBOTexture: Failed to initialize.");
		}
		
		
		
		std::exit(1);
	}
	clear(0, 0, 0, 0);
	
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, oldFramebuffer);
#else
	
	if(numSamples ){
		ofLog(OF_LOG_WARNING, "Multi-sampling not supported on OpenGL ES");
	}else{
	}
	
	
	glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, (GLint *) &oldFramebuffer);
	
	// create & setup FBO
	glGenFramebuffersOES(1, &fbo);
	glBindFramebufferOES(GL_FRAMEBUFFER_OES, fbo);
	
	// attach it to the FBO so we can render to it
	glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, texData.textureTarget, (GLuint)texData.textureID, 0);
	
	glBindFramebufferOES(GL_FRAMEBUFFER_OES, oldFramebuffer);
	
#endif	
	
	
	texData.bAllocated = true;
}
示例#19
0
void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
                                       QGLFramebufferObject::Attachment attachment,
                                       GLenum texture_target, GLenum internal_format, GLint samples)
{
    QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
    fbo_guard.setContext(ctx);

    bool ext_detected = (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject);
    if (!ext_detected || (ext_detected && !qt_resolve_framebufferobject_extensions(ctx)))
        return;

    size = sz;
    target = texture_target;
    // texture dimensions

    QT_RESET_GLERROR(); // reset error state
    GLuint fbo = 0;
    glGenFramebuffers(1, &fbo);
    glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo);
    fbo_guard.setId(fbo);

    glDevice.setFBO(q, attachment);

    QT_CHECK_GLERROR();
    // init texture
    if (samples == 0) {
        glGenTextures(1, &texture);
        glBindTexture(target, texture);
        glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0,
                GL_RGBA, GL_UNSIGNED_BYTE, NULL);
#ifndef QT_OPENGL_ES
        glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
#else
        glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameterf(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
#endif
        glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                target, texture, 0);

        QT_CHECK_GLERROR();
        valid = checkFramebufferStatus();
        glBindTexture(target, 0);

        color_buffer = 0;
    } else {
        GLint maxSamples;
        glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples);

        samples = qBound(0, int(samples), int(maxSamples));

        glGenRenderbuffers(1, &color_buffer);
        glBindRenderbuffer(GL_RENDERBUFFER_EXT, color_buffer);
        if (glRenderbufferStorageMultisampleEXT && samples > 0) {
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                internal_format, size.width(), size.height());
        } else {
            samples = 0;
            glRenderbufferStorage(GL_RENDERBUFFER_EXT, internal_format,
                size.width(), size.height());
        }

        glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                                     GL_RENDERBUFFER_EXT, color_buffer);

        QT_CHECK_GLERROR();
        valid = checkFramebufferStatus();

        if (valid)
            glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_SAMPLES_EXT, &samples);
    }

    // In practice, a combined depth-stencil buffer is supported by all desktop platforms, while a
    // separate stencil buffer is not. On embedded devices however, a combined depth-stencil buffer
    // might not be supported while separate buffers are, according to QTBUG-12861.

    if (attachment == QGLFramebufferObject::CombinedDepthStencil
        && (QGLExtensions::glExtensions() & QGLExtensions::PackedDepthStencil)) {
        // depth and stencil buffer needs another extension
        glGenRenderbuffers(1, &depth_buffer);
        Q_ASSERT(!glIsRenderbuffer(depth_buffer));
        glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_buffer);
        Q_ASSERT(glIsRenderbuffer(depth_buffer));
        if (samples != 0 && glRenderbufferStorageMultisampleEXT)
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                GL_DEPTH24_STENCIL8_EXT, size.width(), size.height());
        else
            glRenderbufferStorage(GL_RENDERBUFFER_EXT,
                GL_DEPTH24_STENCIL8_EXT, size.width(), size.height());

        stencil_buffer = depth_buffer;
        glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
                                     GL_RENDERBUFFER_EXT, depth_buffer);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
                                     GL_RENDERBUFFER_EXT, stencil_buffer);

        valid = checkFramebufferStatus();
        if (!valid) {
            glDeleteRenderbuffers(1, &depth_buffer);
            stencil_buffer = depth_buffer = 0;
        }
    }

    if (depth_buffer == 0 && (attachment == QGLFramebufferObject::CombinedDepthStencil
        || (attachment == QGLFramebufferObject::Depth)))
    {
        glGenRenderbuffers(1, &depth_buffer);
        Q_ASSERT(!glIsRenderbuffer(depth_buffer));
        glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_buffer);
        Q_ASSERT(glIsRenderbuffer(depth_buffer));
        if (samples != 0 && glRenderbufferStorageMultisampleEXT) {
#ifdef QT_OPENGL_ES
            if (QGLExtensions::glExtensions() & QGLExtensions::Depth24) {
                glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                    GL_DEPTH_COMPONENT24_OES, size.width(), size.height());
            } else {
                glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                    GL_DEPTH_COMPONENT16, size.width(), size.height());
            }
#else
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                GL_DEPTH_COMPONENT, size.width(), size.height());
#endif
        } else {
#ifdef QT_OPENGL_ES
            if (QGLExtensions::glExtensions() & QGLExtensions::Depth24) {
                glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24_OES, 
                                        size.width(), size.height());
            } else {
                glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, 
                                        size.width(), size.height());
            }
#else
            glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, size.width(), size.height());
#endif
        }
        glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
                                     GL_RENDERBUFFER_EXT, depth_buffer);
        valid = checkFramebufferStatus();
        if (!valid) {
            glDeleteRenderbuffers(1, &depth_buffer);
            depth_buffer = 0;
        }
    }

    if (stencil_buffer == 0 && (attachment == QGLFramebufferObject::CombinedDepthStencil)) {
        glGenRenderbuffers(1, &stencil_buffer);
        Q_ASSERT(!glIsRenderbuffer(stencil_buffer));
        glBindRenderbuffer(GL_RENDERBUFFER_EXT, stencil_buffer);
        Q_ASSERT(glIsRenderbuffer(stencil_buffer));
        if (samples != 0 && glRenderbufferStorageMultisampleEXT) {
#ifdef QT_OPENGL_ES
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                GL_STENCIL_INDEX8_EXT, size.width(), size.height());
#else
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                GL_STENCIL_INDEX, size.width(), size.height());
#endif
        } else {
#ifdef QT_OPENGL_ES
            glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX8_EXT,
                                  size.width(), size.height());
#else
            glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX,
                                  size.width(), size.height());
#endif
        }
        glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
                                  GL_RENDERBUFFER_EXT, stencil_buffer);
        valid = checkFramebufferStatus();
        if (!valid) {
            glDeleteRenderbuffers(1, &stencil_buffer);
            stencil_buffer = 0;
        }
    }

    // The FBO might have become valid after removing the depth or stencil buffer.
    valid = checkFramebufferStatus();

    if (depth_buffer && stencil_buffer) {
        fbo_attachment = QGLFramebufferObject::CombinedDepthStencil;
    } else if (depth_buffer) {
        fbo_attachment = QGLFramebufferObject::Depth;
    } else {
        fbo_attachment = QGLFramebufferObject::NoAttachment;
    }

    glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);
    if (!valid) {
        if (color_buffer)
            glDeleteRenderbuffers(1, &color_buffer);
        else
            glDeleteTextures(1, &texture);
        if (depth_buffer)
            glDeleteRenderbuffers(1, &depth_buffer);
        if (stencil_buffer && depth_buffer != stencil_buffer)
            glDeleteRenderbuffers(1, &stencil_buffer);
        glDeleteFramebuffers(1, &fbo);
        fbo_guard.setId(0);
    }
    QT_CHECK_GLERROR();

    format.setTextureTarget(target);
    format.setSamples(int(samples));
    format.setAttachment(fbo_attachment);
    format.setInternalTextureFormat(internal_format);
}
示例#20
0
void
piglit_init(int argc, char **argv)
{
	GLint max_samples, sample_buffers, samples, rb_samples;
	GLuint rb, fb;
	GLenum status;
	bool pass = true;
	int i;

	piglit_require_extension("GL_EXT_framebuffer_multisample");

	glGetIntegerv(GL_MAX_SAMPLES, &max_samples);

	glGenFramebuffersEXT(1, &fb);
	glBindFramebufferEXT(GL_FRAMEBUFFER, fb);

	glDrawBuffer(GL_COLOR_ATTACHMENT0);
	glReadBuffer(GL_COLOR_ATTACHMENT0);

	for (i = 0; i < max_samples; i++) {
		glGenRenderbuffersEXT(1, &rb);
		glBindRenderbufferEXT(GL_RENDERBUFFER, rb);
		glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER,
						    max_samples,
						    GL_RGBA, 1, 1);

		glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
					     GL_COLOR_ATTACHMENT0,
					     GL_RENDERBUFFER, rb);

		status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
		if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
			fprintf(stderr, "FBO incomplete\n");
			piglit_report_result(PIGLIT_FAIL);
		}

		glGetRenderbufferParameterivEXT(GL_RENDERBUFFER,
						GL_RENDERBUFFER_SAMPLES,
						&rb_samples);

		glGetIntegerv(GL_SAMPLES, &samples);
		if (rb_samples != samples) {
			fprintf(stderr,
				"FBO reported GL_SAMPLES %d for "
				"rb samples %d\n",
				samples, rb_samples);
			pass = false;
		}

		glGetIntegerv(GL_SAMPLE_BUFFERS, &sample_buffers);
		if ((rb_samples != 0) != (sample_buffers == 1)) {
			fprintf(stderr,
				"FBO reported GL_SAMPLE_BUFFERS %d for "
				"rb samples %d\n",
				sample_buffers, samples);
			pass = false;
		}

		glDeleteRenderbuffersEXT(1, &rb);
	}

	glDeleteFramebuffersEXT(1, &fb);

	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}
示例#21
0
void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
                                       QGLFramebufferObject::Attachment attachment,
                                       GLenum texture_target, GLenum internal_format, GLint samples)
{
    QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
    fbo_guard.setContext(ctx);

    bool ext_detected = (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject);
    if (!ext_detected || (ext_detected && !qt_resolve_framebufferobject_extensions(ctx)))
        return;

    size = sz;
    target = texture_target;
    // texture dimensions

    QT_RESET_GLERROR(); // reset error state
    GLuint fbo = 0;
    glGenFramebuffers(1, &fbo);
    glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo);
    fbo_guard.setId(fbo);

    glDevice.setFBO(q, attachment);

    QT_CHECK_GLERROR();
    // init texture
    if (samples == 0) {
        glGenTextures(1, &texture);
        glBindTexture(target, texture);
        glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0,
                GL_RGBA, GL_UNSIGNED_BYTE, NULL);
#ifndef QT_OPENGL_ES
        glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
#else
        glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameterf(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
#endif
        glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                target, texture, 0);

        QT_CHECK_GLERROR();
        valid = checkFramebufferStatus();
        glBindTexture(target, 0);

        color_buffer = 0;
    } else {
        GLint maxSamples;
        glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples);

        samples = qBound(1, int(samples), int(maxSamples));

        glGenRenderbuffers(1, &color_buffer);
        glBindRenderbuffer(GL_RENDERBUFFER_EXT, color_buffer);
        if (glRenderbufferStorageMultisampleEXT) {
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                internal_format, size.width(), size.height());
        } else {
            samples = 0;
            glRenderbufferStorage(GL_RENDERBUFFER_EXT, internal_format,
                size.width(), size.height());
        }

        glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                                     GL_RENDERBUFFER_EXT, color_buffer);

        QT_CHECK_GLERROR();
        valid = checkFramebufferStatus();

        if (valid)
            glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_SAMPLES_EXT, &samples);
    }

    if (attachment == QGLFramebufferObject::CombinedDepthStencil
        && (QGLExtensions::glExtensions() & QGLExtensions::PackedDepthStencil)) {
        // depth and stencil buffer needs another extension
        glGenRenderbuffers(1, &depth_stencil_buffer);
        Q_ASSERT(!glIsRenderbuffer(depth_stencil_buffer));
        glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_stencil_buffer);
        Q_ASSERT(glIsRenderbuffer(depth_stencil_buffer));
        if (samples != 0 && glRenderbufferStorageMultisampleEXT)
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                GL_DEPTH24_STENCIL8_EXT, size.width(), size.height());
        else
            glRenderbufferStorage(GL_RENDERBUFFER_EXT,
                GL_DEPTH24_STENCIL8_EXT, size.width(), size.height());

        GLint i = 0;
        glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
                                     GL_RENDERBUFFER_EXT, depth_stencil_buffer);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
                                     GL_RENDERBUFFER_EXT, depth_stencil_buffer);
        fbo_attachment = QGLFramebufferObject::CombinedDepthStencil;

        valid = checkFramebufferStatus();
        if (!valid)
            glDeleteRenderbuffers(1, &depth_stencil_buffer);
    } else if (attachment == QGLFramebufferObject::Depth
               || attachment == QGLFramebufferObject::CombinedDepthStencil)
    {
        glGenRenderbuffers(1, &depth_stencil_buffer);
        Q_ASSERT(!glIsRenderbuffer(depth_stencil_buffer));
        glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_stencil_buffer);
        Q_ASSERT(glIsRenderbuffer(depth_stencil_buffer));
        if (samples != 0 && glRenderbufferStorageMultisampleEXT) {
#ifdef QT_OPENGL_ES
#define GL_DEPTH_COMPONENT16 0x81A5
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                GL_DEPTH_COMPONENT16, size.width(), size.height());
#else
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                GL_DEPTH_COMPONENT, size.width(), size.height());
#endif
        } else {
#ifdef QT_OPENGL_ES
#define GL_DEPTH_COMPONENT16 0x81A5
            glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, size.width(), size.height());
#else
            glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, size.width(), size.height());
#endif
        }
        GLint i = 0;
        glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
                                     GL_RENDERBUFFER_EXT, depth_stencil_buffer);
        fbo_attachment = QGLFramebufferObject::Depth;
        valid = checkFramebufferStatus();
        if (!valid)
            glDeleteRenderbuffers(1, &depth_stencil_buffer);
    } else {
        fbo_attachment = QGLFramebufferObject::NoAttachment;
    }

    glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);
    if (!valid) {
        if (color_buffer)
            glDeleteRenderbuffers(1, &color_buffer);
        else
            glDeleteTextures(1, &texture);
        glDeleteFramebuffers(1, &fbo);
        fbo_guard.setId(0);
    }
    QT_CHECK_GLERROR();

    format.setTextureTarget(target);
    format.setSamples(int(samples));
    format.setAttachment(fbo_attachment);
    format.setInternalTextureFormat(internal_format);
}
示例#22
0
void ofxFBOTexture::allocate(int w, int h, bool autoClear, int numSamples) {
        _isActive = false;

        texData.width = w;
        texData.height = h;

	if( numSamples == 0 ){
		bUseMultiSample = false;
	}else{
		bUseMultiSample = true;
	}

    if (GLEE_ARB_texture_rectangle){
        texData.tex_w = w;
        texData.tex_h = h;
        texData.textureTarget = GL_TEXTURE_RECTANGLE_ARB;
    } else {
        texData.tex_w = ofNextPow2(w);
        texData.tex_h = ofNextPow2(h);
    }

        if (GLEE_ARB_texture_rectangle){
                texData.tex_t = w;
                texData.tex_u = h;
        } else {
                texData.tex_t = 1.0f;
                texData.tex_u = 1.0f;
        }

        // attempt to free the previous bound texture, if we can:
        clean();

        texData.width = w;
        texData.height = h;
        texData.bFlipTexture = true;
        texData.glType = GL_RGBA;

        this->autoClear = autoClear;
		

		if( bUseMultiSample ){

			// MULTISAMPLE //
			
			//THEO Create the render buffer for depth
			glGenRenderbuffersEXT(1, &depthBuffer);
			glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBuffer);
			glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, numSamples, GL_DEPTH_COMPONENT, texData.tex_w, texData.tex_h);

			//THEO multi sampled color buffer
			glGenRenderbuffersEXT(1, &colorBuffer);
			glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, colorBuffer);
			glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, numSamples, GL_RGBA8, texData.tex_w, texData.tex_h);
			
			
			//THEO create fbo for multi sampled content and attach depth and color buffers to it
			glGenFramebuffersEXT(1, &mfbo);
			glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mfbo);
			glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, colorBuffer);
			glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthBuffer);
		}else{
			
			//THEO Create the render buffer for depth
			glGenRenderbuffersEXT(1, &depthBuffer);
			glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBuffer);
			glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, texData.tex_w, texData.tex_h);
		}
		
		// NORMAL // 
		
        // create & setup texture
        glGenTextures(1, (GLuint *)(&texData.textureID));   // could be more then one, but for now, just one
        glBindTexture(texData.textureTarget, (GLuint)(texData.textureID));
        glTexParameterf(texData.textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(texData.textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameterf(texData.textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameterf(texData.textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexImage2D(texData.textureTarget, 0, texData.glType, texData.tex_w, texData.tex_h, 0, texData.glType, GL_UNSIGNED_BYTE, 0);
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

		// create & setup FBO
        glGenFramebuffersEXT(1, &fbo);
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
		
        // attach it to the FBO so we can render to it
        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, texData.textureTarget, (GLuint)texData.textureID, 0);

		
		if( !bUseMultiSample ){
			// Attach the depth render buffer to the FBO as it's depth attachment
			glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthBuffer);
		}

        GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
        if(status != GL_FRAMEBUFFER_COMPLETE_EXT) {
                cout<<"glBufferTexture failed to initialize. Perhaps your graphics card doesnt support the framebuffer extension? If you are running osx prior to system 10.5, that could be the cause"<<endl;
                std::exit(1);
        }
        clear(0, 0, 0, 0);

        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

        texData.bAllocated = true;

}
void WebGraphicsContext3DDefaultImpl::reshape(int width, int height)
{
#ifdef RENDER_TO_DEBUGGING_WINDOW
    SetWindowPos(m_canvasWindow, HWND_TOP, 0, 0, width, height,
                 SWP_NOMOVE);
    ShowWindow(m_canvasWindow, SW_SHOW);
#endif

    m_cachedWidth = width;
    m_cachedHeight = height;
    makeContextCurrent();

#ifndef RENDER_TO_DEBUGGING_WINDOW
#ifdef USE_TEXTURE_RECTANGLE_FOR_FRAMEBUFFER
    // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on Mac OS X
    GLenum target = GL_TEXTURE_RECTANGLE_ARB;
#else
    GLenum target = GL_TEXTURE_2D;
#endif
    if (!m_texture) {
        // Generate the texture object
        m_texture = createTextureObject(target);
        // Generate the framebuffer object
        glGenFramebuffersEXT(1, &m_fbo);
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
        m_boundFBO = m_fbo;
        if (m_attributes.depth || m_attributes.stencil)
            glGenRenderbuffersEXT(1, &m_depthStencilBuffer);
        // Generate the multisample framebuffer object
        if (m_attributes.antialias) {
            glGenFramebuffersEXT(1, &m_multisampleFBO);
            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
            m_boundFBO = m_multisampleFBO;
            glGenRenderbuffersEXT(1, &m_multisampleColorBuffer);
            if (m_attributes.depth || m_attributes.stencil)
                glGenRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer);
        }
    }

    GLint internalColorFormat, colorFormat, internalDepthStencilFormat = 0;
    if (m_attributes.alpha) {
        internalColorFormat = GL_RGBA8;
        colorFormat = GL_RGBA;
    } else {
        internalColorFormat = GL_RGB8;
        colorFormat = GL_RGB;
    }
    if (m_attributes.stencil || m_attributes.depth) {
        // We don't allow the logic where stencil is required and depth is not.
        // See GraphicsContext3DInternal constructor.
        if (m_attributes.stencil && m_attributes.depth)
            internalDepthStencilFormat = GL_DEPTH24_STENCIL8_EXT;
        else
            internalDepthStencilFormat = GL_DEPTH_COMPONENT;
    }

    bool mustRestoreFBO = false;

    // Resize multisampling FBO
    if (m_attributes.antialias) {
        GLint maxSampleCount;
        glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSampleCount);
        GLint sampleCount = std::min(8, maxSampleCount);
        if (m_boundFBO != m_multisampleFBO) {
            mustRestoreFBO = true;
            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
        }
        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleColorBuffer);
        glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalColorFormat, width, height);
        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_multisampleColorBuffer);
        if (m_attributes.stencil || m_attributes.depth) {
            glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalDepthStencilFormat, width, height);
            if (m_attributes.stencil)
                glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
            if (m_attributes.depth)
                glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
        }
        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
        GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
        if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
            printf("GraphicsContext3D: multisampling framebuffer was incomplete\n");

            // FIXME: cleanup.
            notImplemented();
        }
    }

    // Resize regular FBO
    if (m_boundFBO != m_fbo) {
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
        mustRestoreFBO = true;
    }
    glBindTexture(target, m_texture);
    glTexImage2D(target, 0, internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target, m_texture, 0);
    glBindTexture(target, 0);
    if (!m_attributes.antialias && (m_attributes.stencil || m_attributes.depth)) {
        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalDepthStencilFormat, width, height);
        if (m_attributes.stencil)
            glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
        if (m_attributes.depth)
            glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
    }
    GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
    if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
        printf("WebGraphicsContext3DDefaultImpl: framebuffer was incomplete\n");

        // FIXME: cleanup.
        notImplemented();
    }

    if (mustRestoreFBO)
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO);
#endif // RENDER_TO_DEBUGGING_WINDOW

#ifdef FLIP_FRAMEBUFFER_VERTICALLY
    if (m_scanline) {
        delete[] m_scanline;
        m_scanline = 0;
    }
    m_scanline = new unsigned char[width * 4];
#endif // FLIP_FRAMEBUFFER_VERTICALLY

    GLbitfield clearMask = GL_COLOR_BUFFER_BIT;
    if (m_attributes.stencil)
        clearMask |= GL_STENCIL_BUFFER_BIT;
    if (m_attributes.depth)
        clearMask |= GL_DEPTH_BUFFER_BIT;
    glClear(clearMask);
}
示例#24
0
bool RenderToFrameBuffer::Init(const structRenderTargetInfo & rttInfo)
{
	// Setup our FBO
	glGenFramebuffersEXT(1, &m_fbo);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);

	if ((rttInfo.fSuperSample > 0 || rttInfo.bPhysicalScreen) && rttInfo.iWidthSS > 0 && rttInfo.iHeightSS > 0)
	{
		m_iWidth = (int)((float)rttInfo.iWidthSS * rttInfo.fSuperSample + 0.5f);
		m_iHeight = (int)((float)rttInfo.iHeightSS * rttInfo.fSuperSample + 0.5f);
	}
	else
	{
		m_iWidth = rttInfo.iWidth;
		m_iHeight = rttInfo.iHeight;
	}

	bool bCoverage = false;
	if ((rttInfo.iMultiSample > 0) && RenderToFrameBuffer::IsAvailable()/*[2]*/)
	{
		m_iMultiSample = rttInfo.iMultiSample;
		if (m_iMultiSample > MAX_AAModes)
			m_iMultiSample = MAX_AAModes;

		// coverage supported ?
//		if (glRenderbufferStorageMultisampleCoverageNV)
//			bCoverage = true;
//		else
			bCoverage = false;
	}
	else
		m_iMultiSample = 0;

	int ds = 0;
	int cs = 0;
	if (m_iMultiSample > 0)
	{
		ds = g_AAModes[m_iMultiSample-1].ds;
		cs = bCoverage ? g_AAModes[m_iMultiSample-1].cs : 0;
	}

	if (rttInfo.eFormat != GL_DEPTH_COMPONENT)
	{
		// Create the render buffer for depth	
		glGenRenderbuffersEXT(1, &m_depthBuffer);
		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer);

		GLenum	internalFormat = rttInfo.bStencil ? GL_DEPTH24_STENCIL8_EXT : GL_DEPTH_COMPONENT;
		if (m_iMultiSample > 0)
		{
	        glGenFramebuffersEXT(1, &m_fboMS);
	        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fboMS);

			if (cs==0)
			{
				glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, ds, internalFormat, m_iWidth, m_iHeight);
	            // check the number of samples
				GLint qds = 0;
		        glGetRenderbufferParameterivEXT( GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_SAMPLES_EXT, &qds);
				if (qds < ds)
				{
					Clean();
					return false;
				}
			}
			else
			{
//				glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER_EXT, cs, ds, internalFormat, m_iWidth, m_iHeight);
	            // check the number of samples
				GLint qds = 0;
				GLint qcs = 0;
	            glGetRenderbufferParameterivEXT( GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_COVERAGE_SAMPLES_NV, &qcs);
	            glGetRenderbufferParameterivEXT( GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_COLOR_SAMPLES_NV, &qds);
				if ((qcs < cs) || (qds < ds))
				{
					Clean();
					return false;
				}
			}
		}
		else
			glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalFormat, m_iWidth, m_iHeight);


		// Attach the depth render buffer to the FBO as it's depth attachment
		glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer);
		if (rttInfo.bStencil)
			glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer); 


		if (m_iMultiSample > 0)
		{
	        glGenRenderbuffersEXT(1, &m_colorMS);
	        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_colorMS);

			if (cs==0)
			{
				glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, ds, GL_RGBA8, m_iWidth, m_iHeight);
	            // check the number of samples
				GLint qds = 0;
		        glGetRenderbufferParameterivEXT( GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_SAMPLES_EXT, &qds);
				if (qds < ds)
				{
					Clean();
					return false;
				}
			}
			else
			{
//				glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER_EXT, cs, ds, GL_RGBA8, m_iWidth, m_iHeight);
	            // check the number of samples
				GLint qds = 0;
				GLint qcs = 0;
	            glGetRenderbufferParameterivEXT( GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_COVERAGE_SAMPLES_NV, &qcs);
	            glGetRenderbufferParameterivEXT( GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_COLOR_SAMPLES_NV, &qds);
				if ((qcs < cs) || (qds < ds))
				{
					Clean();
					return false;
				}
			}

	        // attach the multisampled color buffer
			glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_colorMS);
		}
	}
	else
	{
		// The following is REQUIRED or the FBO will not be resolved (since we have no color buffer here)
		// Also note that these states are only valid for the FBO state, so can be done once during init
		glDrawBuffer(GL_NONE);
		glReadBuffer(GL_NONE);
	}

	m_eFormat = rttInfo.eFormat;
	m_eType = rttInfo.eType;
	m_iFiltering = rttInfo.iFiltering;
	m_bMipMap = RenderToFrameBuffer::IsAvailable()/*[1]*/ && rttInfo.bMipMap;
	m_bBindDepth = rttInfo.m_bBindDepth;

	m_bInitialized = true;

	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);	// Unbind the FBO for now

	return true;
}
示例#25
0
void ofxFBOTexture::allocate(int w, int h, int internalGlDataType, int numSamples) {
	_isActive = false;
	
	// attempt to free the previous bound texture, if we can:
	clean();
	
	texData.width = w;
	texData.height = h;
	this->numSamples = numSamples;
	
#ifndef TARGET_OPENGLES	
    if (GLEE_ARB_texture_rectangle){
        texData.tex_w = w;
        texData.tex_h = h;
        texData.textureTarget = GL_TEXTURE_RECTANGLE_ARB;
    } else
#endif	
	{	
        texData.tex_w = ofNextPow2(w);
        texData.tex_h = ofNextPow2(h);
    }
	
#ifndef TARGET_OPENGLES	
	if (GLEE_ARB_texture_rectangle){
		texData.tex_t = w;
		texData.tex_u = h;
	} else
#endif	
	{
		texData.tex_t = w/texData.tex_w;
		texData.tex_u = h/texData.tex_h;
	}
	
	texData.width = w;
	texData.height = h;
	texData.bFlipTexture = true;
	texData.glTypeInternal = internalGlDataType;

#ifndef TARGET_OPENGLES	
	switch(texData.glTypeInternal) {
		case GL_RGBA32F_ARB:
		case GL_RGBA16F_ARB:
			texData.glType		= GL_RGBA;
			texData.pixelType	= GL_FLOAT;
			pixels				= new float[w * h * 4];
			break;
		default:
			texData.glType		= GL_LUMINANCE;
			texData.pixelType	= GL_UNSIGNED_BYTE;
			pixels				= new unsigned char[w * h * 4];
	}
#else
	texData.glType		= GL_RGBA;
	texData.pixelType	= GL_UNSIGNED_BYTE;
	pixels				= new unsigned char[w * h * 4];
#endif			
	
	
	// create & setup texture
	glGenTextures(1, (GLuint *)&texData.textureID);   // could be more then one, but for now, just one
	glBindTexture(texData.textureTarget, (GLuint)texData.textureID);
	glTexParameterf(texData.textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameterf(texData.textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexParameterf(texData.textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameterf(texData.textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexImage2D(texData.textureTarget, 0, texData.glTypeInternal, texData.tex_w, texData.tex_h, 0, texData.glType, texData.pixelType, 0);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	
	
#ifndef TARGET_OPENGLES
	glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, (GLint *) &oldFramebuffer);
	
	if(numSamples ){
		// MULTISAMPLE //
		
		//THEO Create the render buffer for depth
		glGenRenderbuffersEXT(1, &depthBuffer);
		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBuffer);
		glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, numSamples, GL_DEPTH_COMPONENT, texData.tex_w, texData.tex_h);
		
		//THEO multi sampled color buffer
		glGenRenderbuffersEXT(1, &colorBuffer);
		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, colorBuffer);
		glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, numSamples, texData.glTypeInternal, texData.tex_w, texData.tex_h);
		
		//THEO create fbo for multi sampled content and attach depth and color buffers to it
		glGenFramebuffersEXT(1, &mfbo);
		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mfbo);
		glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, colorBuffer);
		glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthBuffer);

	}else{
		//THEO Create the render buffer for depth
		glGenRenderbuffersEXT(1, &depthBuffer);
		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBuffer);
		glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, texData.tex_w, texData.tex_h);
		glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthBuffer);
	}
	
	// create & setup FBO
	glGenFramebuffersEXT(1, &fbo);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
	
	// attach it to the FBO so we can render to it
	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, texData.textureTarget, (GLuint)texData.textureID, 0);
	
	GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
	if(status != GL_FRAMEBUFFER_COMPLETE_EXT) {
		cout<<"glBufferTexture failed to initialize. Perhaps your graphics card doesnt support the framebuffer extension? If you are running osx prior to system 10.5, that could be the cause"<<endl;
		std::exit(1);
	}
	clear(0, 0, 0, 0);
	
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, oldFramebuffer);
#else
	
	if(numSamples ){
		ofLog(OF_LOG_WARNING, "Multi-sampling not supported on OpenGL ES");
	}else{
	}
	
	
	glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, (GLint *) &oldFramebuffer);

	// create & setup FBO
	glGenFramebuffersOES(1, &fbo);
	glBindFramebufferOES(GL_FRAMEBUFFER_OES, fbo);
	
	// attach it to the FBO so we can render to it
	glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, texData.textureTarget, (GLuint)texData.textureID, 0);
	
	glBindFramebufferOES(GL_FRAMEBUFFER_OES, oldFramebuffer);
	
#endif	

	
	texData.bAllocated = true;
}
示例#26
0
int FrameBufferObject::CreateImageObject(unsigned int width, unsigned int height, int depthbuffer_enabled, int stencilbuffer_enabled)
{
	//Create the Image object
	ImageObject new_object;
  EH_DECLARE;

	new_object.width		= width;
	new_object.height		= height;
	new_object.texture_type	= NULL;
	new_object.texture_id	= NULL;
	new_object.depth_id		= NULL;
	new_object.stencil_id	= NULL;

	EH_Log("CreateImageObject %d %d\n", width, height);

	//First determine if the requested dimensions are power of two
	if (ispoweroftwo(width) && ispoweroftwo(height))
	{
		new_object.texture_type = GL_TEXTURE_2D;	//Power of two enum
		EH_Log("Using GL_TEXTURE_2D");
	}
	else
	{
		new_object.texture_type = 0x84F5;			//Non power of two enum
	}


	//Create texture 
	glGenTextures(1, &new_object.texture_id);
    glBindTexture(new_object.texture_type, new_object.texture_id);
    glTexImage2D(new_object.texture_type, 0, GL_RGBA, new_object.width, new_object.height, 0, GL_RGBA, GL_FLOAT, NULL);
	//GLenum filterMode = (new_object.texture_type == 0x84F5) ? GL_NEAREST : GL_LINEAR;
	//GLenum filterMode = GL_NEAREST;
	GLfloat filterMode = GL_LINEAR;
    glTexParameterf(new_object.texture_type, GL_TEXTURE_MIN_FILTER, filterMode);
    glTexParameterf(new_object.texture_type, GL_TEXTURE_MAG_FILTER, filterMode);
    glTexParameterf(new_object.texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);//GL_CLAMP
    glTexParameterf(new_object.texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);//GL_CLAMP
#ifdef OM_MULTISAMPLE
	if (1) {
		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, framebuffer_id);
		glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, 2, GL_RGBA8, 
			new_object.width, new_object.height);
		CheckFramebufferStatus();
	}
#endif
	//Create the depth RenderBuffer if requested
	if (depthbuffer_enabled != 0)
	{
		glGenRenderbuffersEXT(1, &new_object.depth_id);
		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, new_object.depth_id);
		
		
#ifdef OM_MULTISAMPLE
		if (1) {
			//samples=2, format=GL_DEPTH_COMPONENT24, width=256, height=256
			glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, 2, GL_DEPTH_COMPONENT16, 
				new_object.width, new_object.height);
			CheckFramebufferStatus();
		} else
#endif
			glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, new_object.width, new_object.height);


		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer_id);
        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, 
			GL_RENDERBUFFER_EXT, new_object.depth_id);
		//CheckFramebufferStatus();

	}
	//Create the stencil RenderBuffer if requested
	if (stencilbuffer_enabled != 0)
	{
		glGenRenderbuffersEXT(1, &new_object.stencil_id);
		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, new_object.stencil_id);
		glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX,  new_object.width, new_object.height);
	}

	//Push this new image object onto the list
	image_objects.push_back(new_object);

	

	//Return the 'index' for the id of this texture
	return (int)image_objects.size() - 1;
}
FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int msaaSamples, int msaaCoverageSamples)
{
    m_efbFramebuffer = 0;
    m_efbColor = 0;
    m_efbDepth = 0;
    m_resolvedFramebuffer = 0;
    m_resolvedColorTexture = 0;
    m_resolvedDepthTexture = 0;
    m_xfbFramebuffer = 0;

	m_targetWidth = targetWidth;
	m_targetHeight = targetHeight;

	m_msaaSamples = msaaSamples;
	m_msaaCoverageSamples = msaaCoverageSamples;

	// The EFB can be set to different pixel formats by the game through the
	// BPMEM_ZCOMPARE register (which should probably have a different name).
	// They are:
	// - 24-bit RGB (8-bit components) with 24-bit Z
	// - 24-bit RGBA (6-bit components) with 24-bit Z
	// - Multisampled 16-bit RGB (5-6-5 format) with 16-bit Z
	// We only use one EFB format here: 32-bit ARGB with 24-bit Z.
	// Multisampling depends on user settings.
	// The distinction becomes important for certain operations, i.e. the
	// alpha channel should be ignored if the EFB does not have one.

	// Create EFB target.

	glGenFramebuffersEXT(1, &m_efbFramebuffer);

	if (m_msaaSamples <= 1)
	{
		// EFB targets will be textures in non-MSAA mode.

		GLuint glObj[2];
		glGenTextures(2, glObj);
		m_efbColor = glObj[0];
		m_efbDepth = glObj[1];

		glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_efbColor);
		glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, m_targetWidth, m_targetHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

		glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_efbDepth);
		glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);

		glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);

		// Bind target textures to the EFB framebuffer.

		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer);

		glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, m_efbColor, 0);
		glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_ARB, m_efbDepth, 0);

		GL_REPORT_FBO_ERROR();
	}
	else
	{
		// EFB targets will be renderbuffers in MSAA mode (required by OpenGL).
		// Resolve targets will be created to transfer EFB to RAM textures.
		// XFB framebuffer will be created to transfer EFB to XFB texture.

		// Create EFB target renderbuffers.

		GLuint glObj[2];
		glGenRenderbuffersEXT(2, glObj);
		m_efbColor = glObj[0];
		m_efbDepth = glObj[1];

		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_efbColor);
		if (m_msaaCoverageSamples)
			glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER_EXT, m_msaaCoverageSamples, m_msaaSamples, GL_RGBA8, m_targetWidth, m_targetHeight);
		else
			glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, m_msaaSamples, GL_RGBA8, m_targetWidth, m_targetHeight);

		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_efbDepth);
		if (m_msaaCoverageSamples)
			glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER_EXT, m_msaaCoverageSamples, m_msaaSamples, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight);
		else
			glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, m_msaaSamples, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight);

		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);

		// Bind target renderbuffers to EFB framebuffer.

		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer);

		glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_efbColor);
		glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_efbDepth);

		GL_REPORT_FBO_ERROR();

		// Create resolved targets for transferring multisampled EFB to texture.

		glGenFramebuffersEXT(1, &m_resolvedFramebuffer);

		glGenTextures(2, glObj);
		m_resolvedColorTexture = glObj[0];
		m_resolvedDepthTexture = glObj[1];

		glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_resolvedColorTexture);
		glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, m_targetWidth, m_targetHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

		glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_resolvedDepthTexture);
		glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);

		glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);

		// Bind resolved textures to resolved framebuffer.

		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_resolvedFramebuffer);

		glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, m_resolvedColorTexture, 0);
		glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_ARB, m_resolvedDepthTexture, 0);

		GL_REPORT_FBO_ERROR();

		// Return to EFB framebuffer.

		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer);
	}

	// Create XFB framebuffer; targets will be created elsewhere.

	glGenFramebuffersEXT(1, &m_xfbFramebuffer);

	// EFB framebuffer is currently bound, make sure to clear its alpha value to 1.f
	glViewport(0, 0, m_targetWidth, m_targetHeight);
	glScissor(0, 0, m_targetWidth, m_targetHeight);
	glClearColor(0.f, 0.f, 0.f, 1.f);
	glClearDepth(1.0);
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
}
示例#28
0
void CGLFramebufferEXT::Create()
{
    if (m_fbo != 0) return;

    m_width = m_params.width;
    m_height = m_params.height;
    m_depth = m_params.depth;
    m_samples = m_params.samples;

    glGenFramebuffersEXT(1, &m_fbo);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);

    // create color texture
    if (m_params.colorTexture)
    {
        GLint previous;
        glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous);

        glGenTextures(1, &m_colorTexture);
        glBindTexture(GL_TEXTURE_2D, m_colorTexture);

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_params.width, m_params.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

        glBindTexture(GL_TEXTURE_2D, previous);

        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_colorTexture, 0);
    }
    // create color renderbuffer
    else
    {
        glGenRenderbuffersEXT(1, &m_colorRenderbuffer);
        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_colorRenderbuffer);

        if (m_params.samples > 1)
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, m_params.samples, GL_RGBA8, m_params.width, m_params.height);
        else
            glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA8, m_params.width, m_params.height);

        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);

        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_colorRenderbuffer);
    }

    GLuint depthFormat = 0;

    switch (m_params.depth)
    {
    case 16: depthFormat = GL_DEPTH_COMPONENT16; break;
    case 24: depthFormat = GL_DEPTH_COMPONENT24; break;
    case 32: depthFormat = GL_DEPTH_COMPONENT32; break;
    default: depthFormat = GL_DEPTH_COMPONENT16; break;
    }

    // create depth texture
    if (m_params.depthTexture)
    {
        GLint previous;
        glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous);

        glGenTextures(1, &m_depthTexture);
        glBindTexture(GL_TEXTURE_2D, m_depthTexture);

        glTexImage2D(GL_TEXTURE_2D, 0, depthFormat, m_params.width, m_params.height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);

        float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
        glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color);

        glBindTexture(GL_TEXTURE_2D, previous);

        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, m_depthTexture, 0);
    }
    // create depth renderbuffer
    else
    {
        glGenRenderbuffersEXT(1, &m_depthRenderbuffer);
        glBindRenderbufferEXT(GL_RENDERBUFFER, m_depthRenderbuffer);

        if (m_params.samples > 1)
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, m_params.samples, depthFormat, m_params.width, m_params.height);
        else
            glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, depthFormat, m_params.width, m_params.height);

        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);

        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthRenderbuffer);
    }

    GLuint result = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
    if (result != GL_FRAMEBUFFER_COMPLETE_EXT)
    {
        GetLogger()->Error("Framebuffer incomplete: %d\n", result);
        assert(false);
    }

    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_currentFBO);
}
示例#29
0
bool CFrameBufferObject::createMSAA( GLuint width, GLuint height, fboConfig *p_config, fboData *p_data )
{
	GLint query;
	bool ret = false;

	// Step #1
	{
        glGenRenderbuffersEXT( 1, &p_data->depthRB   );
        glGenRenderbuffersEXT( 1, &p_data->colorRB   );
        glGenFramebuffersEXT ( 1, &p_data->resolveFB );
        p_data->depthTex = 0; //no resolve of depth buffer for now
        
        //multisample, so we need to resolve from the FBO, bind the texture to the resolve FBO
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, p_data->resolveFB); 

        glFramebufferTexture2DEXT(	GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, 
									m_eGLTarget, p_data->colorTex, 0);
        ret &= checkStatus(__FILE__, __LINE__, true);

        //now handle the rendering FBO
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, p_data->fb);

        // initialize color renderbuffer
        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, p_data->colorRB);
	}

	// Step #2
	{
		// create a regular MSAA color buffer
		glRenderbufferStorageMultisampleEXT( GL_RENDERBUFFER_EXT, 
											p_config->depthSamples, 
											p_config->colorFormat, 
											width, height);
		// check the number of samples
		glGetRenderbufferParameterivEXT( GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_SAMPLES_EXT, &query);

		if ( query < p_config->depthSamples) {
			ret = false;
		}
		else if ( query > p_config->depthSamples) {
			p_config->depthSamples = query;
		}
	}

	// Step #3
	{
        // attach the multisampled color buffer
        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, p_data->colorRB);
        ret &= checkStatus(__FILE__, __LINE__, true);

        // bind the multisampled depth buffer
        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, p_data->depthRB);
	}

	// Step #4 - create the multisampled depth buffer (without coverage sampling)
	{
        // create a regular (not coverage sampled) MSAA depth buffer
        glRenderbufferStorageMultisampleEXT(	GL_RENDERBUFFER_EXT, 
												p_config->depthSamples, 
												p_config->depthFormat, 
												width, height);

        // check the number of depth samples
        glGetRenderbufferParameterivEXT( GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_SAMPLES_EXT, &query);

        if ( query < p_config->depthSamples) {
            ret = false;
        }
        else if ( query < p_config->depthSamples) {
            p_config->depthSamples = query;
        }
	}

	return ret;
}
void WebGraphicsContext3DDefaultImpl::reshape(int width, int height)
{
    m_cachedWidth = width;
    m_cachedHeight = height;
    makeContextCurrent();

    GLenum target = GL_TEXTURE_2D;

    if (!m_texture) {
        // Generate the texture object
        m_texture = createTextureObject(target);
        // Generate the framebuffer object
        glGenFramebuffersEXT(1, &m_fbo);
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
        m_boundFBO = m_fbo;
        if (m_attributes.depth || m_attributes.stencil)
            glGenRenderbuffersEXT(1, &m_depthStencilBuffer);
        // Generate the multisample framebuffer object
        if (m_attributes.antialias) {
            glGenFramebuffersEXT(1, &m_multisampleFBO);
            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
            m_boundFBO = m_multisampleFBO;
            glGenRenderbuffersEXT(1, &m_multisampleColorBuffer);
            if (m_attributes.depth || m_attributes.stencil)
                glGenRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer);
        }
    }

    GLint internalColorFormat, colorFormat, internalDepthStencilFormat = 0;
    if (m_attributes.alpha) {
        internalColorFormat = GL_RGBA8;
        colorFormat = GL_RGBA;
    } else {
        internalColorFormat = GL_RGB8;
        colorFormat = GL_RGB;
    }
    if (m_attributes.stencil || m_attributes.depth) {
        // We don't allow the logic where stencil is required and depth is not.
        // See GraphicsContext3DInternal constructor.
        if (m_attributes.stencil && m_attributes.depth)
            internalDepthStencilFormat = GL_DEPTH24_STENCIL8_EXT;
        else
            internalDepthStencilFormat = GL_DEPTH_COMPONENT;
    }

    bool mustRestoreFBO = false;

    // Resize multisampling FBO
    if (m_attributes.antialias) {
        GLint maxSampleCount;
        glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSampleCount);
        GLint sampleCount = std::min(8, maxSampleCount);
        if (m_boundFBO != m_multisampleFBO) {
            mustRestoreFBO = true;
            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
        }
        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleColorBuffer);
        glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalColorFormat, width, height);
        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_multisampleColorBuffer);
        if (m_attributes.stencil || m_attributes.depth) {
            glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalDepthStencilFormat, width, height);
            if (m_attributes.stencil)
                glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
            if (m_attributes.depth)
                glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
        }
        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
        GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
        if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
            printf("GraphicsContext3D: multisampling framebuffer was incomplete\n");

            // FIXME: cleanup.
            notImplemented();
        }
    }

    // Resize regular FBO
    if (m_boundFBO != m_fbo) {
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
        mustRestoreFBO = true;
    }
    glBindTexture(target, m_texture);
    glTexImage2D(target, 0, internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target, m_texture, 0);
    glBindTexture(target, 0);
    if (!m_attributes.antialias && (m_attributes.stencil || m_attributes.depth)) {
        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalDepthStencilFormat, width, height);
        if (m_attributes.stencil)
            glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
        if (m_attributes.depth)
            glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
    }
    GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
    if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
        printf("WebGraphicsContext3DDefaultImpl: framebuffer was incomplete\n");

        // FIXME: cleanup.
        notImplemented();
    }

    if (m_attributes.antialias) {
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
        if (m_boundFBO == m_multisampleFBO)
            mustRestoreFBO = false;
    }

    // Initialize renderbuffers to 0.
    GLboolean colorMask[] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE}, depthMask = GL_TRUE, stencilMask = GL_TRUE;
    GLboolean isScissorEnabled = GL_FALSE;
    GLboolean isDitherEnabled = GL_FALSE;
    GLbitfield clearMask = GL_COLOR_BUFFER_BIT;
    glGetBooleanv(GL_COLOR_WRITEMASK, colorMask);
    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    if (m_attributes.depth) {
        glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask);
        glDepthMask(GL_TRUE);
        clearMask |= GL_DEPTH_BUFFER_BIT;
    }
    if (m_attributes.stencil) {
        glGetBooleanv(GL_STENCIL_WRITEMASK, &stencilMask);
        glStencilMask(GL_TRUE);
        clearMask |= GL_STENCIL_BUFFER_BIT;
    }
    isScissorEnabled = glIsEnabled(GL_SCISSOR_TEST);
    glDisable(GL_SCISSOR_TEST);
    isDitherEnabled = glIsEnabled(GL_DITHER);
    glDisable(GL_DITHER);

    glClear(clearMask);

    glColorMask(colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
    if (m_attributes.depth)
        glDepthMask(depthMask);
    if (m_attributes.stencil)
        glStencilMask(stencilMask);
    if (isScissorEnabled)
        glEnable(GL_SCISSOR_TEST);
    else
        glDisable(GL_SCISSOR_TEST);
    if (isDitherEnabled)
        glEnable(GL_DITHER);
    else
        glDisable(GL_DITHER);

    if (mustRestoreFBO)
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO);

#ifdef FLIP_FRAMEBUFFER_VERTICALLY
    if (m_scanline) {
        delete[] m_scanline;
        m_scanline = 0;
    }
    m_scanline = new unsigned char[width * 4];
#endif // FLIP_FRAMEBUFFER_VERTICALLY
}