//-----------------------------------------------------------------------------  
 void GLESTextureBuffer::bindToFramebuffer(GLenum attachment, size_t zoffset)
 {
     assert(zoffset < mDepth);
     glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, attachment,
                               mFaceTarget, mTextureID, mLevel);
     GL_CHECK_ERROR;
 }
 inline void VL_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
 {
   if (glFramebufferTexture2DOES)
     glFramebufferTexture2DOES(target, attachment, textarget, texture, level);
   else
     VL_TRAP();
 }
Beispiel #3
0
// src서피스를 this로 카피.
void XSurfaceOpenGL::CopySurface( XSurface *src )
{
    XSurfaceOpenGL *pSrc = (XSurfaceOpenGL *)src;
    // src를 FBO에 연결
    // glCopyTexImage를 이용해 src에서 this로 옮김.
    GLuint fbo;
    glGenFramebuffersOES(1, &fbo);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, fbo);
    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, pSrc->GetTextureID(), 0);

    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
    if( status != GL_FRAMEBUFFER_COMPLETE_OES )
    {
        XLOG( "status=%d", status );
        return;
    }

    // copy texture from framebuffer
    glBindTexture(GL_TEXTURE_2D, m_textureID);
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, pSrc->GetMemWidth(), pSrc->GetMemHeight());

    // FBO해제
    GRAPHICS_GL->RestoreFrameBuffer();
    glDeleteFramebuffersOES(1, &fbo);
}
Beispiel #4
0
void wyRenderTexture::createFrameBuffer(int w, int h) {
	// create texture
	glGenTextures(1, (GLuint*)&m_texture);
	glBindTexture(GL_TEXTURE_2D, m_texture);

	// apply texture parameters
	glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

	// allocate buffer and create texture from it
	GLvoid* pixels = (GLvoid*)wyCalloc(w * h * 4, sizeof(GLubyte));
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
	wyFree(pixels);

	// generate a new frame buffer
	glGenFramebuffersOES(1, (GLuint*)&m_fbo);

	// get old frame buffer object
	glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, (GLint*)&m_old_fbo);

	// bind
	glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_fbo);

	// associate texture with FBO
	glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, m_texture, 0);

	// restore old buffer
	glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_old_fbo);
}
void GLES11RenderEngine::bindImageAsFramebuffer(EGLImageKHR image,
        uint32_t* texName, uint32_t* fbName, uint32_t* status,
        bool useReadPixels, int reqWidth, int reqHeight) {
    GLuint tname, name;
    if (!useReadPixels) {
        // turn our EGLImage into a texture
        glGenTextures(1, &tname);
        glBindTexture(GL_TEXTURE_2D, tname);
        glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);

        // create a Framebuffer Object to render into
        glGenFramebuffersOES(1, &name);
        glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
        glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
                GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
    } else {
        // since we're going to use glReadPixels() anyways,
        // use an intermediate renderbuffer instead
        glGenRenderbuffersOES(1, &tname);
        glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
        glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, reqWidth, reqHeight);
        // create a FBO to render into
        glGenFramebuffersOES(1, &name);
        glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
        glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
    }

    *status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
    *texName = tname;
    *fbName = name;
}
extern "C" bool UnityResolveMSAA(GLuint destFBO, GLuint colorTex, GLuint colorBuf, GLuint depthTex, GLuint depthBuf)
{
#if GL_APPLE_framebuffer_multisample
	if (_surface.msaaSamples > 0 && _supportsMSAA && destFBO!=_surface.msaaFramebuffer && destFBO!=_surface.framebuffer)
	{
		Profiler_StartMSAAResolve();

		GLint oldFBO;
		GLES_CHK( glGetIntegerv (GL_FRAMEBUFFER_BINDING_OES, &oldFBO) );

		UNITY_DBG_LOG ("UnityResolveMSAA: samples=%i msaaFBO=%i destFBO=%i colorTex=%i colorRB=%i depthTex=%i depthRB=%i\n", _surface.msaaSamples, _surface.msaaFramebuffer, destFBO, colorTex, colorBuf, depthTex, depthBuf);
		UNITY_DBG_LOG ("  bind dest as DRAW FBO and textures/buffers into it\n");

		GLES_CHK( glBindFramebufferOES (GL_DRAW_FRAMEBUFFER_APPLE, destFBO) );
		if (colorTex)
			GLES_CHK( glFramebufferTexture2DOES( GL_DRAW_FRAMEBUFFER_APPLE, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0 ) );
		else if (colorBuf)
			GLES_CHK( glFramebufferRenderbufferOES (GL_DRAW_FRAMEBUFFER_APPLE, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorBuf) );

		if (depthTex)
			GLES_CHK( glFramebufferTexture2DOES( GL_DRAW_FRAMEBUFFER_APPLE, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTex, 0 ) );
		else if (depthBuf)
			GLES_CHK( glFramebufferRenderbufferOES (GL_DRAW_FRAMEBUFFER_APPLE, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuf) );

		UNITY_DBG_LOG ("  bind msaa as READ FBO\n");
		GLES_CHK( glBindFramebufferOES(GL_READ_FRAMEBUFFER_APPLE, _surface.msaaFramebuffer) );

		UNITY_DBG_LOG ("  glResolveMultisampleFramebufferAPPLE ();\n");
		GLES_CHK( glResolveMultisampleFramebufferAPPLE() );

		GLES_CHK( glBindFramebufferOES (GL_FRAMEBUFFER_OES, oldFBO) );

		Profiler_EndMSAAResolve();
		return true;
	}
	#endif
	return false;
}
Beispiel #7
0
void sgTexture::makeRendertarget()
{
	if(textype != GL_TEXTURE_2D || fbo != -1)
		return;

	if(sgRenderer::oglversion > 1)
	{
#if defined __IOS__
		glGenFramebuffers(1, &fbo);
		glBindFramebuffer(GL_FRAMEBUFFER, fbo);
		glBindTexture(textype, 0);
		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texid, 0);
		glClear(GL_COLOR_BUFFER_BIT);

		glGenRenderbuffers(1, &fbo_depth);
		glBindRenderbuffer(GL_RENDERBUFFER, fbo_depth);
//		glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width, height);
		glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo_depth);
#else
		glGenFramebuffersEXT(1, &fbo);
		glBindFramebufferEXT(GL_FRAMEBUFFER, fbo);
		glBindTexture(textype, 0);
		glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texid, 0);
		glClear(GL_COLOR_BUFFER_BIT);

		glGenRenderbuffersEXT(1, &fbo_depth);
		glBindRenderbufferEXT(GL_RENDERBUFFER, fbo_depth);
//		glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width, height);
		glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
		glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo_depth);
#endif
	}else
	{
#if defined __IOS__
		glGenFramebuffersOES(1, &fbo);
		glBindFramebufferOES(GL_FRAMEBUFFER_OES, fbo);
		glBindTexture(GL_TEXTURE_2D, 0);
		glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, texid, 0);

		glGenRenderbuffersOES(1, &fbo_depth);
		glBindRenderbufferOES(GL_RENDERBUFFER_OES, fbo_depth);
		glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, width, height);
		glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, fbo_depth);
#endif
	}
}
void GLES11RenderEngine::bindImageAsFramebuffer(EGLImageKHR image,
        uint32_t* texName, uint32_t* fbName, uint32_t* status) {
    GLuint tname, name;
    // turn our EGLImage into a texture
    glGenTextures(1, &tname);
    glBindTexture(GL_TEXTURE_2D, tname);
    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);

    // create a Framebuffer Object to render into
    glGenFramebuffersOES(1, &name);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);

    *status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
    *texName = tname;
    *fbName = name;
}
Beispiel #9
0
FBO *createFBO(s32 width, s32 height, bool hd) {
    // save current FBO
    FBO *oldFBO = getFBOUsed();
    
    GLuint framebuffer;
    GLuint depthRenderbuffer;
    
    width = width;
    height = height;

    s32 texturePtrId = createTexture(0, 0);
    setTexture(texturePtrId, width, height, 3, NULL);
    Texture *tex = getTexture(texturePtrId);
    
    // create depth renderbuffer
    glGenRenderbuffersOES(1, &depthRenderbuffer);
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, width, height);
    
    // bind framebuffer & attach texture
    glGenFramebuffersOES(1, &framebuffer);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);
    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tex->mTextureId, 0);
    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
    
    // check binding
    if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
        logError(TAG, "CRITICAL ERROR: FBO no complete");
        return 0;
    }

    // save info into structure
    FBO *fbo = (FBO *)malloc(sizeof(FBO));
    fbo->mFBO = framebuffer;
    fbo->mWidth = width;
    fbo->mHeight = height;
    fbo->mTexturePtrId = texturePtrId;
    fbo->mDepthRenderBuffer = depthRenderbuffer;
    
    // restore FBO
    useFBO(oldFBO);
    return fbo;
}
Beispiel #10
0
extern int hdglGenTextureFrameBuffer(const hdTexture *texture)
{
    GLuint fbo, status;

    glGenFramebuffersOES(1, &fbo);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, fbo);
    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, texture->texnum, 0);

    status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
    if (status != GL_FRAMEBUFFER_COMPLETE_OES)
    {
        hdPrintf("Could not create frame buffer.");
        return -1;
    }
    else
    {
        return fbo;
    }
}
	OpenGLRTTexture::OpenGLRTTexture(unsigned int _texture, int width, int height) :
		mTextureID(_texture),
		mWidth(width),
		mHeight(height),
		mFBOID(0),
		mRBOID(0)
	{
		int miplevel = 0;
		glBindTexture(GL_TEXTURE_2D, mTextureID);
		//glGetTexLevelParameteriv(GL_TEXTURE_2D, miplevel, GL_TEXTURE_WIDTH, &mWidth);    // Unsupported by OpenGL ES, using param
		//glGetTexLevelParameteriv(GL_TEXTURE_2D, miplevel, GL_TEXTURE_HEIGHT, &mHeight);  // Unsupported by OpenGL ES, using param
		glBindTexture(GL_TEXTURE_2D, 0);

		mRenderTargetInfo.maximumDepth = 1.0f;
		mRenderTargetInfo.hOffset = 0;
		mRenderTargetInfo.vOffset = 0;
		mRenderTargetInfo.aspectCoef = float(mHeight) / float(mWidth);
		mRenderTargetInfo.pixScaleX = 1.0f / float(mWidth);
		mRenderTargetInfo.pixScaleY = 1.0f / float(mHeight);

		// create a framebuffer object, you need to delete them when program exits.
		glGenFramebuffersOES(1, &mFBOID);
		glBindFramebufferOES(GL_FRAMEBUFFER_OES, mFBOID);

		// create a renderbuffer object to store depth info
		// NOTE: A depth renderable image should be attached the FBO for depth test.
		// If we don't attach a depth renderable image to the FBO, then
		// the rendering output will be corrupted because of missing depth test.
		// If you also need stencil test for your rendering, then you must
		// attach additional image to the stencil attachement point, too.
		glGenRenderbuffersOES(1, &mRBOID);
		glBindRenderbufferOES(GL_RENDERBUFFER_OES, mRBOID);
		glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, mWidth, mHeight);
		glBindRenderbufferOES(GL_RENDERBUFFER_OES, 0);

		// attach a texture to FBO color attachement point
		glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, mTextureID, 0);

		// attach a renderbuffer to depth attachment point
		glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, mRBOID);

		glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
	}
		virtual GLenum createFBO(GLuint& framebuffer, GLuint& depthbuffer, GLuint& img, int width, int height)
		{
			// get currently bound fbo to reset to it later
			GLint current_fbo;
			glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &current_fbo);

			// generate depth buffer
			glGenRenderbuffersOES(1, &depthbuffer);
			glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthbuffer);
			glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, width, height);
			glBindRenderbufferOES(GL_RENDERBUFFER_OES, 0);

			// generate texture save target
			glGenTextures(1, &img);
			glBindTexture(GL_TEXTURE_2D, img);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
			
			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8_OES, width, height,
					0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
			glBindTexture(GL_TEXTURE_2D, 0);

			// create framebuffer
			glGenFramebuffersOES(1, &framebuffer);
			glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);
			glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES,
					GL_TEXTURE_2D, img, 0);
			glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES,
					GL_RENDERBUFFER_OES, depthbuffer);
			GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);

			// unbind framebuffer
			glBindFramebufferOES(GL_FRAMEBUFFER_OES, (GLuint)current_fbo);
			return status;
		}
Beispiel #13
0
bool CCGrabber::activateFBO(RenderContext* ctx, CCTexture2D *pTexture)
{
	bool valid = m_FrameBuffer->isValid(ctx);

	if (valid && m_BoundTexture == pTexture)
		return true;

	if (!valid)
	{
		// generate FBO
		if (!m_FrameBuffer->generate(ctx))
			return false; // device not ready
	}

	m_BoundTexture = pTexture;

	if (pTexture == NULL)
		return false;

	glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &m_oldFBO);

	// bind
	glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_FrameBuffer->useHandle(ctx));

	// associate texture with FBO
	glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D,
		pTexture->activate(ctx), 0);

	// check if it worked
	CCAssert(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) == GL_FRAMEBUFFER_COMPLETE_OES, 
		"Frame Grabber: Could not attach texture to framebuffer");

	glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_oldFBO);

	return true;
}
    //-----------------------------------------------------------------------------  
    // Very fast texture-to-texture blitter and hardware bi/trilinear scaling implementation using FBO
    // Destination texture must be 2D
    // Source texture must be 2D
    // Supports compressed formats as both source and destination format, it will use the hardware DXT compressor
    // if available.
    // @author W.J. van der Laan
    void GLESTextureBuffer::blitFromTexture(GLESTextureBuffer *src, const Image::Box &srcBox, const Image::Box &dstBox)
    {
        if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_FBO) == false)
        {
            // the following code depends on FBO support, it crashes if FBO is not supported.
            // TODO - write PBUFFER version of this function or a version that doesn't require FBO
            return; // for now - do nothing.
        }

//        std::cerr << "GLESTextureBuffer::blitFromTexture " <<
//        src->mTextureID << ":" << srcBox.left << "," << srcBox.top << "," << srcBox.right << "," << srcBox.bottom << " " << 
//        mTextureID << ":" << dstBox.left << "," << dstBox.top << "," << dstBox.right << "," << dstBox.bottom << std::endl;

        // Store reference to FBO manager
        GLESFBOManager *fboMan = static_cast<GLESFBOManager *>(GLESRTTManager::getSingletonPtr());
        
        // Save and clear GL state for rendering
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |  GL_STENCIL_BUFFER_BIT);
        
        RenderSystem* rsys = Root::getSingleton().getRenderSystem();
        rsys->_disableTextureUnitsFrom(0);

        // Disable alpha, depth and scissor testing, disable blending, 
        // disable culling, disble lighting, disable fog and reset foreground
        // colour.
        glDisable(GL_ALPHA_TEST);
        glDisable(GL_DEPTH_TEST);
        glDisable(GL_SCISSOR_TEST);
        glDisable(GL_BLEND);
        glDisable(GL_CULL_FACE);
        glDisable(GL_LIGHTING);
        glDisable(GL_FOG);
        glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
        GL_CHECK_ERROR;

        // Save and reset matrices
        glMatrixMode(GL_MODELVIEW);
        glPushMatrix();
        glLoadIdentity();
        glMatrixMode(GL_PROJECTION);
        glPushMatrix();
        glLoadIdentity();
        glMatrixMode(GL_TEXTURE);
        glPushMatrix();
        glLoadIdentity();
        GL_CHECK_ERROR;
        
        // Set up source texture
        glBindTexture(src->mTarget, src->mTextureID);
        GL_CHECK_ERROR;
        
        // Set filtering modes depending on the dimensions and source
        if(srcBox.getWidth()==dstBox.getWidth() &&
           srcBox.getHeight()==dstBox.getHeight() &&
           srcBox.getDepth()==dstBox.getDepth())
        {
            // Dimensions match -- use nearest filtering (fastest and pixel correct)
            glTexParameteri(src->mTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
            GL_CHECK_ERROR;
            glTexParameteri(src->mTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
            GL_CHECK_ERROR;
        }
        else
        {
            // Dimensions don't match -- use bi or trilinear filtering depending on the
            // source texture.
            if(src->mUsage & TU_AUTOMIPMAP)
            {
                // Automatic mipmaps, we can safely use trilinear filter which
                // brings greatly imporoved quality for minimisation.
                glTexParameteri(src->mTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
                GL_CHECK_ERROR;
                glTexParameteri(src->mTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);    
                GL_CHECK_ERROR;
            }
            else
            {
                // Manual mipmaps, stay safe with bilinear filtering so that no
                // intermipmap leakage occurs.
                glTexParameteri(src->mTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
                GL_CHECK_ERROR;
                glTexParameteri(src->mTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                GL_CHECK_ERROR;
            }
        }
        // Clamp to edge (fastest)
        glTexParameteri(src->mTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        GL_CHECK_ERROR;
        glTexParameteri(src->mTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        GL_CHECK_ERROR;
        
        // Store old binding so it can be restored later
        GLint oldfb;
        glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &oldfb);
        GL_CHECK_ERROR;

        // Set up temporary FBO
        glBindFramebufferOES(GL_FRAMEBUFFER_OES, fboMan->getTemporaryFBO());
        GL_CHECK_ERROR;

        GLuint tempTex = 0;
        if(!fboMan->checkFormat(mFormat))
        {
            // If target format not directly supported, create intermediate texture
            GLenum tempFormat = GLESPixelUtil::getClosestGLInternalFormat(fboMan->getSupportedAlternative(mFormat));
            glGenTextures(1, &tempTex);
            GL_CHECK_ERROR;
            glBindTexture(GL_TEXTURE_2D, tempTex);
            GL_CHECK_ERROR;
            // Allocate temporary texture of the size of the destination area
            glTexImage2D(GL_TEXTURE_2D, 0, tempFormat, 
                         GLESPixelUtil::optionalPO2(dstBox.getWidth()), GLESPixelUtil::optionalPO2(dstBox.getHeight()), 
                         0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
            GL_CHECK_ERROR;
            glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES,
                                      GL_TEXTURE_2D, tempTex, 0);
            GL_CHECK_ERROR;
            // Set viewport to size of destination slice
            glViewport(0, 0, dstBox.getWidth(), dstBox.getHeight());
            GL_CHECK_ERROR;
        }
        else
        {
            // We are going to bind directly, so set viewport to size and position of destination slice
            glViewport(dstBox.left, dstBox.top, dstBox.getWidth(), dstBox.getHeight());
            GL_CHECK_ERROR;
        }
        
        // Process each destination slice
        for(size_t slice=dstBox.front; slice<dstBox.back; ++slice)
        {
            if(!tempTex)
            {
                /// Bind directly
                bindToFramebuffer(GL_COLOR_ATTACHMENT0_OES, slice);
            }

            if(tempTex)
            {
                // Copy temporary texture
                glBindTexture(mTarget, mTextureID);
                GL_CHECK_ERROR;
                switch(mTarget)
                {
                    case GL_TEXTURE_2D:
#if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID
                    case GL_TEXTURE_CUBE_MAP_OES:
#endif
                        glCopyTexSubImage2D(mFaceTarget, mLevel, 
                                            dstBox.left, dstBox.top, 
                                            0, 0, dstBox.getWidth(), dstBox.getHeight());
                        GL_CHECK_ERROR;
                        break;
                }
            }
        }
        // Finish up 
        if(!tempTex)
        {
            // Generate mipmaps
            if(mUsage & TU_AUTOMIPMAP)
            {
                glBindTexture(mTarget, mTextureID);
                GL_CHECK_ERROR;
                glGenerateMipmapOES(mTarget);
                GL_CHECK_ERROR;
            }
        }
        
        // Reset source texture to sane state
        glBindTexture(src->mTarget, src->mTextureID);
        GL_CHECK_ERROR;
        
        // Detach texture from temporary framebuffer
        glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES,
                                     GL_RENDERBUFFER_OES, 0);
        GL_CHECK_ERROR;
        // Restore old framebuffer
        glBindFramebufferOES(GL_FRAMEBUFFER_OES, oldfb);
        GL_CHECK_ERROR;
        // Restore matrix stacks and render state
        glMatrixMode(GL_TEXTURE);
        glPopMatrix();
        glMatrixMode(GL_PROJECTION);
        glPopMatrix();
        glMatrixMode(GL_MODELVIEW);
        glPopMatrix();
        GL_CHECK_ERROR;
        glDeleteTextures(1, &tempTex);
        GL_CHECK_ERROR;
    }
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;
}
Beispiel #16
0
int createFrameBuffer(AndroidContext *rc)
{
	int backingWidth;
	int backingHeight;
	int res;

	if ( rc->framebuff >= 0 )
		releaseFrameBuffer(rc);

	LOG( ANDROID_LOG_DEBUG, TAG, "Android Create FrameBuffer"));

	glGenFramebuffersOES(1, &(rc->framebuff));
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, rc->framebuff);

//	glGenRenderbuffersOES(1, &(rc->depthbuff));
//	glBindRenderbufferOES(GL_RENDERBUFFER_OES, rc->depthbuff);

//	glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
//	glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);

//	LOG( ANDROID_LOG_ERROR, TAG, "Android Depth Buffer Size: %dx%d\n", backingWidth, backingHeight));

//    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, rc->width, rc->height);

//    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES,
//            GL_RENDERBUFFER_OES, rc->depthbuff);

	glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES,
			GL_TEXTURE_2D, rc->texID, 0);

	if ( (res=(int)glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)) != GL_FRAMEBUFFER_COMPLETE_OES )
	{
		LOG( ANDROID_LOG_ERROR, TAG, "Android failed to make complete framebuffer object:");
		switch (res)
		{
			case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES:
				LOG( ANDROID_LOG_ERROR, TAG, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES");
				break;
			case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES:
				LOG( ANDROID_LOG_ERROR, TAG, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES");
				break;
			case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES:
				LOG( ANDROID_LOG_ERROR, TAG, "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES");
				break;
			case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES:
				LOG( ANDROID_LOG_ERROR, TAG, "GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES");
				break;
			case GL_FRAMEBUFFER_UNSUPPORTED_OES:
				LOG( ANDROID_LOG_ERROR, TAG, "GL_FRAMEBUFFER_UNSUPPORTED_OES");
				break;
			default :
				LOG( ANDROID_LOG_ERROR, TAG, "Unknown error: %d", res);
				break;
		}

        return 1;
    }

    //glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);

	return 0;
}
void glFramebufferTexture2DOESLogged(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {
	printf("glFramebufferTexture2DOES(%s, %s, %s, %u, %i)\n", GLEnumName(target), GLEnumName(attachment), GLEnumName(textarget), texture, level);
	glFramebufferTexture2DOES(target, attachment, textarget, texture, level);
}
void TextureGPU::createDrawableIntoColorTexture(PrimitiveTypes::UInt32 w, PrimitiveTypes::UInt32 h, ESamplerState sampler)
{
	
	m_samplerState = sampler;

	StringOps::writeToString("DrawableIntoColorTexture", m_name, 256);

#	if APIABSTRACTION_D3D9
	D3D9Renderer *pD3D9Renderer = static_cast<D3D9Renderer *>(m_pContext->getGPUScreen());
	LPDIRECT3DDEVICE9 pDevice = pD3D9Renderer->m_pD3D9Device;
	
	m_viewport.X = 0;
	m_viewport.Y = 0;
	m_viewport.Width = w;
	m_viewport.Height = h;
	m_viewport.MinZ = 0.0f;
	m_viewport.MaxZ = 1.0f;

	IDirect3DTexture9 *pColorMap = 0;
#if APIABSTRACTION_X360
	HRESULT hr = D3DXCreateTexture( pDevice, 
		w, 
		h, 
		1, 
		D3DUSAGE_RENDERTARGET, 
		D3DFMT_A8R8G8B8, 
		D3DPOOL_DEFAULT, 
		&this->m_pTexture );
#else
	HRESULT hr = pDevice->CreateTexture( 
		w, 
		h, 
		1, 
		D3DUSAGE_RENDERTARGET, 
		D3DFMT_A8R8G8B8, 
		D3DPOOL_DEFAULT, 
		&this->m_pTexture,
		NULL);
#endif
	
	D3DSURFACE_DESC desc;
	m_pTexture->GetSurfaceLevel( 0, &m_pSurface );
	m_pSurface->GetDesc( &desc );
#ifdef _XBOX
	hr = pDevice->CreateRenderTarget(desc.Width, desc.Height, ( D3DFORMAT )MAKESRGBFMT( desc.Format ),
		D3DMULTISAMPLE_NONE, 0, 0,
		&m_pEDRamColorRenderTargetSurface, NULL );
#else
	#if D3D9_USE_RENDER_TO_SURFACE
		hr = D3DXCreateRenderToSurface(pDevice, 
			desc.Width, 
			desc.Height, 
			desc.Format, 
			false,
			D3DFMT_UNKNOWN, 
			&m_pRenderToSurface );
	#endif
#endif
		assert(SUCCEEDED(hr));

#elif APIABSTRACTION_OGL
	glGenTextures(1, &m_texture);
	glBindTexture(GL_TEXTURE_2D, m_texture);
    IRenderer::checkForErrors("glTexImage2D");
	glTexImage2D(
		GL_TEXTURE_2D,				// Target
		0,							// Mip-level
#if defined(SN_TARGET_PS3)
		GL_ARGB_SCE,
#else
		GL_RGBA,						// InternalFormat, for ps3 use GL_ARGB_SCE, why?
#endif
		w,							// width size
		h,							// height size
		0,							// border
		GL_RGBA,						// input pixel format
		GL_UNSIGNED_BYTE,			// input pixel type
		NULL);						// input pixels
    IRenderer::checkForErrors("glTexImage2D");
    
	SamplerState &ss = SamplerStateManager::getInstance()->getSamplerState(m_samplerState);

	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, ss.val_GL_TEXTURE_MIN_FILTER);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, ss.val_GL_TEXTURE_MAG_FILTER);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, ss.val_GL_TEXTURE_WRAP_S);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, ss.val_GL_TEXTURE_WRAP_T);
#if !APIABSTRACTION_IOS
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_LEVEL,0); //only one mip
#endif
	//depth related
	//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_COMPARE_MODE_ARB,GL_COMPARE_R_TO_TEXTURE_ARB);
	//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
	glBindTexture(GL_TEXTURE_2D, 0);

	#if APIABSTRACTION_PS3
		glGenFramebuffersOES(1, &m_frameBufferObject);
	#else
		glGenFramebuffers(1, &m_frameBufferObject);
	#endif
	#if APIABSTRACTION_PS3
		glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_frameBufferObject); //set framebuffer for reading and writing. could also use GL_READ_FRAMEBUFFER to set a buffer for reading vs writing. 
	#else
		glBindFramebuffer(GL_FRAMEBUFFER, m_frameBufferObject); //set framebuffer for reading and writing. could also use GL_READ_FRAMEBUFFER to set a buffer for reading vs writing. 
	#endif
	//glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, w); / no need for this, since it take size of the texture passed

	#if APIABSTRACTION_PS3
		glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0);
	#else
		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0);
	#endif
	m_viewport.x = 0;
	m_viewport.y = 0;
	m_viewport.w = w;
	m_viewport.h = h;
	m_viewport.minDepth = 0;
	m_viewport.maxDepth = 1.0f;

	#if !APIABSTRACTION_IOS
		#if APIABSTRACTION_PS3
			assert(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) == GL_FRAMEBUFFER_COMPLETE_OES);
		#else
			assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
		#endif
	#endif

	#if APIABSTRACTION_PS3
		glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); // back to default
	#else
		glBindFramebuffer(GL_FRAMEBUFFER, 0); // back to default
	#endif
#elif APIABSTRACTION_D3D11
	m_viewport.TopLeftX = 0;
	m_viewport.TopLeftY = 0;
	m_viewport.Width = w;
	m_viewport.Height = h;
	m_viewport.MinDepth = 0.0f;
	m_viewport.MaxDepth = 1.0f;

	D3D11Renderer *pD3D11Renderer = static_cast<D3D11Renderer *>(m_pContext->getGPUScreen());
	ID3D11Device *pDevice = pD3D11Renderer->m_pD3DDevice;
	ID3D11DeviceContext *pDeviceContext = pD3D11Renderer->m_pD3DContext;

	//ID3D11Texture2D *pColorMap = 0;

	D3D11_TEXTURE2D_DESC texDesc;
		texDesc.Width = w;
		texDesc.Height = h;
		texDesc.MipLevels = 0;
		texDesc.ArraySize = 1;
		texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
		texDesc.SampleDesc.Count = 1;
		texDesc.SampleDesc.Quality = 0;
		texDesc.Usage = D3D11_USAGE_DEFAULT;
		texDesc.BindFlags = D3D11_BIND_RENDER_TARGET |
		                    D3D11_BIND_SHADER_RESOURCE;
		texDesc.CPUAccessFlags = 0;
		texDesc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;

		HRESULT hr = pDevice->CreateTexture2D(&texDesc, 0, &m_pTexture);
		assert(SUCCEEDED(hr));

		// Null description means to create a view to all mipmap levels
		// using the format the texture was created with
		hr = pDevice->CreateRenderTargetView(m_pTexture, 0, &m_pRenderTargetView);
		assert(SUCCEEDED(hr));
		hr = pDevice->CreateShaderResourceView(m_pTexture, 0, &m_pShaderResourceView);
		assert(SUCCEEDED(hr));

#endif
}
Beispiel #19
0
	void FrameBuffer::Init(const ax::Size& size)
	{
#ifdef ANDROID
		glGenFramebuffersOES(1, &_frameBuffer);
		glBindFramebufferOES(GL_FRAMEBUFFER_OES, _frameBuffer);
#else
		glGenFramebuffers(1, &_frameBuffer);
		glBindFramebuffer(GL_FRAMEBUFFER, _frameBuffer);
#endif

		// Create texture.
		glGenTextures(1, &_frameBufferTexture);
		glBindTexture(GL_TEXTURE_2D, _frameBufferTexture);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

		glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
//--------------------------------------------------------------------------------------------------------------------
//			glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);

#ifdef ANDROID
		// NULL means reserve texture memory, but texels are undefined.
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.x, size.y, 0, GL_RGBA,
			GL_UNSIGNED_BYTE, NULL);

		// Attach 2D texture to this FBO.
		glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES,
			GL_TEXTURE_2D, _frameBufferTexture, 0);

		// Does the GPU support current FBO configuration.
		GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);

		if (status != GL_FRAMEBUFFER_COMPLETE_OES) {
			ax::Error("Generating frame buffer : ", status);
		}

#else
		// NULL means reserve texture memory, but texels are undefined.
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, size.x, size.y, 0, GL_RGBA,
			GL_UNSIGNED_BYTE, NULL);

		// Attach 2D texture to this FBO.
		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
			GL_TEXTURE_2D, _frameBufferTexture, 0);

		// Does the GPU support current FBO configuration.
		GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);

		if (status != GL_FRAMEBUFFER_COMPLETE) {
			ax::Error("Generating frame buffer : ", status);
		}
#endif

#ifdef ANDROID
		glBindFramebufferOES(GL_FRAMEBUFFER_OES, _frameBuffer);
		glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
#else
		glBindFramebuffer(GL_FRAMEBUFFER, _frameBuffer);
		glBindFramebuffer(GL_FRAMEBUFFER, 0);
#endif


		GLenum err = GL_NO_ERROR;
		while((err = glGetError()) != GL_NO_ERROR)
		{
		  ax::Error("GL :", err);
		}
	}
    /** Detect which internal formats are allowed as RTT
        Also detect what combinations of stencil and depth are allowed with this internal
        format.
    */
    void GLESFBOManager::detectFBOFormats()
    {
        // Try all formats, and report which ones work as target
        GLuint fb, tid;
        GLenum target = GL_TEXTURE_2D;

        for(size_t x=0; x<PF_COUNT; ++x)
        {
            mProps[x].valid = false;

			// Fetch GL format token
			GLenum fmt = GLESPixelUtil::getGLInternalFormat((PixelFormat)x);
            if(fmt == GL_NONE && x!=0)
                continue;

			// No test for compressed formats
			if(PixelUtil::isCompressed((PixelFormat)x))
				continue;

            // Create and attach framebuffer
            glGenFramebuffersOES(1, &fb);
            glBindFramebufferOES(GL_FRAMEBUFFER_OES, fb);
            if (fmt!=GL_NONE)
            {
				// Create and attach texture
				glGenTextures(1, &tid);
				glBindTexture(target, tid);
				
                // Set some default parameters
                glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_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);
                            
				glTexImage2D(target, 0, fmt, PROBE_SIZE, PROBE_SIZE, 0, fmt, GL_UNSIGNED_BYTE, 0);
				glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES,
                                target, tid, 0);
            }

            // Check status
            GLuint status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);

			// Ignore status in case of fmt==GL_NONE, because no implementation will accept
			// a buffer without *any* attachment. Buffers with only stencil and depth attachment
			// might still be supported, so we must continue probing.
            if(fmt == GL_NONE || status == GL_FRAMEBUFFER_COMPLETE_OES)
            {
                mProps[x].valid = true;
				StringUtil::StrStreamType str;
				str << "FBO " << PixelUtil::getFormatName((PixelFormat)x) 
					<< " depth/stencil support: ";

                // For each depth/stencil formats
                for (size_t depth = 0; depth < DEPTHFORMAT_COUNT; ++depth)
                {
                    if (depthFormats[depth] != GL_DEPTH24_STENCIL8_OES)
                    {
                        // General depth/stencil combination

                        for (size_t stencil = 0; stencil < STENCILFORMAT_COUNT; ++stencil)
                        {
                            //StringUtil::StrStreamType l;
                            //l << "Trying " << PixelUtil::getFormatName((PixelFormat)x) 
                            //	<< " D" << depthBits[depth] 
                            //	<< "S" << stencilBits[stencil];
                            //LogManager::getSingleton().logMessage(l.str());

                            if (_tryFormat(depthFormats[depth], stencilFormats[stencil]))
                            {
                                /// Add mode to allowed modes
                                str << "D" << depthBits[depth] << "S" << stencilBits[stencil] << " ";
                                FormatProperties::Mode mode;
                                mode.depth = depth;
                                mode.stencil = stencil;
                                mProps[x].modes.push_back(mode);
                            }
                        }
                    }
                    else
                    {
                        // Packed depth/stencil format
                        if (_tryPackedFormat(depthFormats[depth]))
                        {
                            /// Add mode to allowed modes
                            str << "Packed-D" << depthBits[depth] << "S" << 8 << " ";
                            FormatProperties::Mode mode;
                            mode.depth = depth;
                            mode.stencil = 0;   // unuse
                            mProps[x].modes.push_back(mode);
                        }
                    }
                }
                LogManager::getSingleton().logMessage(str.str());
            }

            // Delete texture and framebuffer
            glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
            glDeleteFramebuffersOES(1, &fb);
			
            if (fmt!=GL_NONE)
                glDeleteTextures(1, &tid);
        }

		String fmtstring;
        for(size_t x=0; x<PF_COUNT; ++x)
        {
            if(mProps[x].valid)
                fmtstring += PixelUtil::getFormatName((PixelFormat)x)+" ";
        }
        LogManager::getSingleton().logMessage("[GLES] : Valid FBO targets " + fmtstring);
    }
Beispiel #21
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;
}
void CreateRenderingSurfaceGLES(EAGLSurfaceDesc* surface)
{
	gDefaultFBO = surface->systemFramebuffer;

	GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, surface->systemFramebuffer) );
	GLES_CHK( glBindRenderbufferOES(GL_RENDERBUFFER_OES, surface->systemRenderbuffer) );

	DestroyRenderingSurfaceGLES(surface);

	GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, surface->systemFramebuffer) );
	GLES_CHK( glBindRenderbufferOES(GL_RENDERBUFFER_OES, surface->systemRenderbuffer) );

	if( surface->targetW != surface->systemW || surface->targetH != surface->systemH )
	{
		GLES_CHK( glGenTextures(1, &surface->targetRT) );
		GLES_CHK( glBindTexture(GL_TEXTURE_2D, surface->targetRT) );
        GLES_CHK( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GLES_UPSCALE_FILTER) );
        GLES_CHK( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GLES_UPSCALE_FILTER) );
        GLES_CHK( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) );
        GLES_CHK( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) );

        GLenum fmt  = surface->use32bitColor ? GL_RGBA : GL_RGB;
        GLenum type = surface->use32bitColor ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT_5_6_5;
        GLES_CHK( glTexImage2D(GL_TEXTURE_2D, 0, fmt, surface->targetW, surface->targetH, 0, fmt, type, 0) );

		GLES_CHK( glGenFramebuffersOES(1, &surface->targetFramebuffer) );
		GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, surface->targetFramebuffer) );
		GLES_CHK( glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, surface->targetRT, 0) );

		GLES_CHK( glBindTexture(GL_TEXTURE_2D, 0) );
		gDefaultFBO = surface->targetFramebuffer;
	}

#if GL_APPLE_framebuffer_multisample
	if(_supportsMSAA && surface->msaaSamples > 1)
	{
		GLES_CHK( glGenRenderbuffersOES(1, &surface->msaaRenderbuffer) );
		GLES_CHK( glBindRenderbufferOES(GL_RENDERBUFFER_OES, surface->msaaRenderbuffer) );

		GLES_CHK( glGenFramebuffersOES(1, &surface->msaaFramebuffer) );
		GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, surface->msaaFramebuffer) );

		GLES_CHK( glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, surface->msaaSamples, surface->format, surface->targetW, surface->targetH) );
		GLES_CHK( glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, surface->msaaRenderbuffer) );

		gDefaultFBO = surface->msaaFramebuffer;
	}
#endif

	GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, gDefaultFBO) );
	if(surface->depthFormat != 0)
	{
		GLES_CHK( glGenRenderbuffersOES(1, &surface->depthbuffer) );
		GLES_CHK( glBindRenderbufferOES(GL_RENDERBUFFER_OES, surface->depthbuffer) );

		bool needMSAA = GL_APPLE_framebuffer_multisample && (surface->msaaSamples > 1);

	#if GL_APPLE_framebuffer_multisample
		if(needMSAA)
			GLES_CHK( glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, surface->msaaSamples, surface->depthFormat, surface->targetW, surface->targetH) );
	#endif

		if(!needMSAA)
			GLES_CHK( glRenderbufferStorageOES(GL_RENDERBUFFER_OES, surface->depthFormat, surface->targetW, surface->targetH) );

		GLES_CHK( glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, surface->depthbuffer) );
	}
}
void TextureGPU::createDrawableIntoColorTextureWithDepth(PrimitiveTypes::UInt32 w, PrimitiveTypes::UInt32 h, ESamplerState sampler, bool use32BitRedForDepth /* = false*/)
{
	StringOps::writeToString("createDrawableIntoColorTextureWithDepth", m_name, 256);
	m_samplerState = sampler;

#	if APIABSTRACTION_D3D9
	D3D9Renderer *pD3D9Renderer = static_cast<D3D9Renderer *>(m_pContext->getGPUScreen());
	LPDIRECT3DDEVICE9 pDevice = pD3D9Renderer->m_pD3D9Device;
	
	m_viewport.X = 0;
	m_viewport.Y = 0;
	m_viewport.Width = w;
	m_viewport.Height = h;
	m_viewport.MinZ = 0.0f;
	m_viewport.MaxZ = 1.0f;
#if APIABSTRACTION_X360
	HRESULT hr = D3DXCreateTexture(pDevice, 
		w, 
		h, 
		1, 
		D3DUSAGE_RENDERTARGET, 
		use32BitRedForDepth ? D3DFMT_R32F : D3DFMT_A8R8G8B8,
		D3DPOOL_DEFAULT, 
		&this->m_pTexture );
#else
	HRESULT hr = pDevice->CreateTexture(
		w, 
		h, 
		1, 
		D3DUSAGE_RENDERTARGET, 
		use32BitRedForDepth ? D3DFMT_R32F : D3DFMT_A8R8G8B8,
		D3DPOOL_DEFAULT, 
		&this->m_pTexture,
		NULL);
#endif

	D3DSURFACE_DESC desc;
	m_pTexture->GetSurfaceLevel( 0, &m_pSurface );
	m_pSurface->GetDesc( &desc );

#ifdef _XBOX
	//create depth stencil surface to use with this texture
	hr = pDevice->CreateDepthStencilSurface(
		w,
		h,
		D3DFMT_D24S8,
		D3DMULTISAMPLE_NONE,
		0,     // multi sample quality
		TRUE,  // Set this flag to TRUE to enable z-buffer discarding, and FALSE otherwise.
		//If this flag is set, the contents of the depth stencil buffer will be invalid
		// after calling either IDirect3DDevice9::Present or IDirect3DDevice9::SetDepthStencilSurface with a different depth surface.
		&m_pEDRamDSRenderTargetSurface,
		NULL);

	assert(SUCCEEDED(hr));

	hr = pDevice->CreateRenderTarget(
		desc.Width, desc.Height,
		( D3DFORMAT )MAKESRGBFMT( desc.Format ),
		D3DMULTISAMPLE_NONE, 0, 0,
		&m_pEDRamColorRenderTargetSurface, NULL );
#else
#if D3D9_USE_RENDER_TO_SURFACE
	hr = D3DXCreateRenderToSurface(pDevice, 
		desc.Width, 
		desc.Height, 
		desc.Format, 
		TRUE, 
		D3DFMT_D16, 
		&m_pRenderToSurface );
#else
	//create depth stencil surface to use with this texture
	hr = pDevice->CreateDepthStencilSurface(
		w,
		h,
		D3DFMT_D24S8,
		D3DMULTISAMPLE_NONE,
		0,     // multi sample quality
		TRUE,  // Set this flag to TRUE to enable z-buffer discarding, and FALSE otherwise.
		//If this flag is set, the contents of the depth stencil buffer will be invalid
		// after calling either IDirect3DDevice9::Present or IDirect3DDevice9::SetDepthStencilSurface with a different depth surface.
		&m_pDSSurface,
		NULL);
#endif
#endif

	assert(SUCCEEDED(hr));

#elif APIABSTRACTION_OGL

	SamplerState &ss = SamplerStateManager::getInstance()->getSamplerState(m_samplerState);

	GLuint texture;
	glGenTextures(1, &texture);
	glBindTexture(GL_TEXTURE_2D, texture);
    IRenderer::checkForErrors("glTexImage2D");
    
    #if PE_PLAT_IS_IOS
        PEWARN("We are creating depth texture as 32 bit, because I could not get 16 bit depth working. If you figure it out, change it to 16 bit for better perf (hopefully!)");
    #endif
    
    glTexImage2D(
		GL_TEXTURE_2D,				// Target
		0,							// Mip-level
        #if PE_PLAT_IS_IOS
            GL_DEPTH_COMPONENT, 	// InternalFormat
        #else
            GL_DEPTH_COMPONENT16,
        #endif
        w,							// width size
		h,							// height size
		0,							// border
		GL_DEPTH_COMPONENT,						// input pixel format
        #if PE_PLAT_IS_IOS
            GL_UNSIGNED_INT,			// input pixel type
        #else
            GL_UNSIGNED_SHORT,
        #endif
		NULL);						// input pixels

    IRenderer::checkForErrors("glTexImage2D");
    
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, ss.val_GL_TEXTURE_MIN_FILTER);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, ss.val_GL_TEXTURE_MAG_FILTER);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, ss.val_GL_TEXTURE_WRAP_S);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, ss.val_GL_TEXTURE_WRAP_T);
    
#if !APIABSTRACTION_IOS
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_LEVEL,0); //only one mip

	// depth related comparison functions
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
#endif
    
	glBindTexture(GL_TEXTURE_2D, 0);
	
	#if APIABSTRACTION_PS3
		glGenFramebuffersOES(1, &m_frameBufferObject);
	#else
		glGenFramebuffers(1, &m_frameBufferObject);
	#endif

	#if APIABSTRACTION_PS3
		glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_frameBufferObject); //set framebuffer for reading and writing. could also use GL_READ_FRAMEBUFFER to set a buffer for reading vs writing. 
	#else
		glBindFramebuffer(GL_FRAMEBUFFER, m_frameBufferObject); //set framebuffer for reading and writing. could also use GL_READ_FRAMEBUFFER to set a buffer for reading vs writing. 
	#endif

	//glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, w); / no need for this, since it take size of the texture passed

	#if APIABSTRACTION_PS3
		glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_TEXTURE_2D, texture, 0);
	#else
		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texture, 0);
	#endif

	m_viewport.x = 0;
	m_viewport.y = 0;
	m_viewport.w = w;
	m_viewport.h = h;
	m_viewport.minDepth = 0;
	m_viewport.maxDepth = 1.0f;

	// had to comment out this assert becasue apparently with newest hardware it is actually complete too
	//assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE); // make sure API requires color texture too

	// need to cerate color texture too, otherwise framebuffer object is incomplete
	glGenTextures(1, &m_texture);
	glBindTexture(GL_TEXTURE_2D, m_texture);
    IRenderer::checkForErrors("glTexImage2D");
    #if PE_PLAT_IS_IOS
        if (use32BitRedForDepth)
            PEWARN("We are creating depth+color and storing dpeth in color. for ios we store it as rgba, since we cant store it as 32bit red..");
    #endif
	glTexImage2D(
		GL_TEXTURE_2D,				// Target
		0,							// Mip-level
		#if defined(SN_TARGET_PS3)
			use32BitRedForDepth ? GL_LUMINANCE32F_ARB  : GL_ARGB_SCE,
		#else
			#if APIABSTRACTION_IOS
				use32BitRedForDepth ? GL_RGBA : GL_RGBA,				// InternalFormat, for ps3 use GL_ARGB_SCE, why?
			#else
				use32BitRedForDepth ? GL_R32F : GL_RGBA,						// InternalFormat, for ps3 use GL_ARGB_SCE, why?
			#endif
		#endif
		w,							// width size
		h,							// height size
		0,							// border
		GL_RGBA,					// input pixel format
		GL_UNSIGNED_BYTE,			// input pixel type
		NULL);						// input pixels
    IRenderer::checkForErrors("glTexImage2D");
    
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, ss.val_GL_TEXTURE_MIN_FILTER);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, ss.val_GL_TEXTURE_MAG_FILTER);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, ss.val_GL_TEXTURE_WRAP_S);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, ss.val_GL_TEXTURE_WRAP_T);
    
#if !APIABSTRACTION_IOS
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_LEVEL,0); //only one mip
#endif
    
	//depth related
	//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_COMPARE_MODE_ARB,GL_COMPARE_R_TO_TEXTURE_ARB);
	//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
	glBindTexture(GL_TEXTURE_2D, 0);

	#if APIABSTRACTION_PS3
		glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0);
	#else
		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0);
	#endif

	#if !APIABSTRACTION_IOS
		#if APIABSTRACTION_PS3
			assert(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) == GL_FRAMEBUFFER_COMPLETE_OES);
		#else
			assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
		#endif
	#endif
    
    IRenderer::checkRenderBufferComplete();
    
	#if APIABSTRACTION_PS3
		glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); // back to default
	#else
		glBindFramebuffer(GL_FRAMEBUFFER, 0); // back to default
	#endif
#elif APIABSTRACTION_D3D11
	m_viewport.TopLeftX = 0;
	m_viewport.TopLeftY = 0;
	m_viewport.Width = w;
	m_viewport.Height = h;
	m_viewport.MinDepth = 0.0f;
	m_viewport.MaxDepth = 1.0f;

	D3D11Renderer *pD3D11Renderer = static_cast<D3D11Renderer *>(m_pContext->getGPUScreen());
	ID3D11Device *pDevice = pD3D11Renderer->m_pD3DDevice;
	ID3D11DeviceContext *pDeviceContext = pD3D11Renderer->m_pD3DContext;

	//ID3D11Texture2D *pColorMap = 0;

	D3D11_TEXTURE2D_DESC texDesc;
	texDesc.Width = w;
	texDesc.Height = h;
	texDesc.MipLevels = 1;
	texDesc.ArraySize = 1;
	texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	texDesc.SampleDesc.Count = 1;
	texDesc.SampleDesc.Quality = 0;
	texDesc.Usage = D3D11_USAGE_DEFAULT;
	texDesc.BindFlags = D3D11_BIND_RENDER_TARGET |
		D3D11_BIND_SHADER_RESOURCE;
	texDesc.CPUAccessFlags = 0;
	texDesc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;

	HRESULT hr = pDevice->CreateTexture2D(&texDesc, 0, &m_pTexture);
	assert(SUCCEEDED(hr));

	// Null description means to create a view to all mipmap levels
	// using the format the texture was created with
	hr = pDevice->CreateRenderTargetView(m_pTexture, 0, &m_pRenderTargetView);
	assert(SUCCEEDED(hr));
	hr = pDevice->CreateShaderResourceView(m_pTexture, 0, &m_pShaderResourceView);
	assert(SUCCEEDED(hr));

	// Now create depth part fo the texture
	ID3D11Texture2D *pDepthMap = 0;

	texDesc.Format = DXGI_FORMAT_R32_TYPELESS;
	texDesc.Usage = D3D11_USAGE_DEFAULT;
	texDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL |
		D3D11_BIND_SHADER_RESOURCE;
	texDesc.CPUAccessFlags = 0;
	texDesc.MiscFlags = 0;

	hr = pDevice->CreateTexture2D(&texDesc, 0, &pDepthMap);
	assert(SUCCEEDED(hr));

	// setting up view for rendering into depth buffer/and reading (stenciling) from it (z-buffer algorithm red/write)
	D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
	dsvDesc.Format = DXGI_FORMAT_D32_FLOAT;
	dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
	dsvDesc.Texture2D.MipSlice = 0;
	dsvDesc.Flags = 0;//D3D11_DSV_READ_ONLY_DEPTH;

	hr = pDevice->CreateDepthStencilView(pDepthMap, &dsvDesc, &m_DepthStencilView);
	assert(SUCCEEDED(hr));

	D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
	srvDesc.Format = DXGI_FORMAT_R32_FLOAT;
	srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
	srvDesc.Texture2D.MipLevels = texDesc.MipLevels;
	srvDesc.Texture2D.MostDetailedMip = 0;

	hr = pDevice->CreateShaderResourceView(pDepthMap, &srvDesc, &m_pDepthShaderResourceView);
	assert(SUCCEEDED(hr));

	pDepthMap->Release();
#endif
}
Beispiel #24
0
int main(void)
{
	EGLint major, minor, eglCfgCount, eglCfgVisualId, width, height;
	const IMG_gralloc_module_public_t *module;
	buffer_handle_t srcBuffer, destBuffer;
	EGLImageKHR eglSrcImage, eglDestImage;
	EGLConfig eglConfig, eglFBConfig;
	GLuint fboName, textureNames[2];
	EGLNativeWindowType eglWindow;
	EGLSurface eglWindowSurface;
	alloc_device_t *device;
	EGLContext eglContext;
	EGLDisplay eglDisplay;
	int err = 1, stride;
	GLenum glError;

	ANativeWindowBuffer sSrcBuffer =
	{
		.common.magic	= ANDROID_NATIVE_BUFFER_MAGIC,
		.common.version	= sizeof(ANativeWindowBuffer),
		.common.incRef	= incRefNop,
		.common.decRef	= decRefNop,
		.width			= SRC_WIDTH,
		.height			= SRC_HEIGHT,
		.stride			= SRC_STRIDE,
		.usage			= GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE,
	};

	ANativeWindowBuffer sDestBuffer =
	{
		.common.magic	= ANDROID_NATIVE_BUFFER_MAGIC,
		.common.version	= sizeof(ANativeWindowBuffer),
		.common.incRef	= incRefNop,
		.common.decRef	= decRefNop,
		.width			= DEST_WIDTH,
		.height			= DEST_HEIGHT,
		.stride			= DEST_STRIDE,
		.format			= DEST_FORMAT,
		.usage			= GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE,
	};

	EGLint eglCfgAttribs[] =
	{
		EGL_RED_SIZE,			5,
		EGL_GREEN_SIZE,			6,
		EGL_BLUE_SIZE,			5,
		EGL_ALPHA_SIZE,			0,
		EGL_SURFACE_TYPE,		EGL_WINDOW_BIT,
		EGL_RENDERABLE_TYPE,	EGL_OPENGL_ES_BIT,
#ifdef EGL_ANDROID_recordable
		EGL_RECORDABLE_ANDROID,	EGL_TRUE,
#endif
		EGL_NONE,
	};

	const float srcVertexArray[2 * 4] = {
		 0.0f,	 1.0f,
		 0.0f,	 0.0f,
		 1.0f, 	 1.0f,
		 1.0f,	 0.0f,
	};

	const float texCoordArray[2 * 4] = {
		 0.0f,	 0.0f,
		 0.0f,	 1.0f,
		 1.0f,	 0.0f,
		 1.0f,	 1.0f,
	};

	const float destVertexArray[2 * 4] = {
		-1.0f,	 0.0f,
		-1.0f,	-1.0f,
		 0.0f,	 0.0f,
		 0.0f,	-1.0f,
	};

	eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
	if(eglDisplay == EGL_NO_DISPLAY)
	{
		printf("eglGetDisplay failed\n");
		goto err_out;
	}

	if(!eglInitialize(eglDisplay, &major, &minor))
	{
		printf("eglInitialize failed (err=0x%x)\n", eglGetError());
		goto err_out;
	}

	if(!eglChooseConfig(eglDisplay, eglCfgAttribs,
						&eglConfig, 1, &eglCfgCount))
	{
		printf("eglChooseConfig failed (err=0x%x)\n", eglGetError());
		goto err_terminate;
	}

	if(!eglCfgCount)
	{
		printf("eglChooseConfig found no suitable configs\n");
		goto err_terminate;
	}

	if(!eglGetConfigAttrib(eglDisplay, eglConfig,
						   EGL_NATIVE_VISUAL_ID, &eglCfgVisualId))
	{
		printf("eglGetConfigAttrib failed (err=0x%x)\n", eglGetError());
		goto err_terminate;
	}

	sSrcBuffer.format = eglCfgVisualId;

	/* Handle FB rendering ***************************************************/

	eglWindow = android_createDisplaySurface();
	if(!eglWindow)
	{
		printf("android_createDisplaySurface returned NULL\n");
		goto err_terminate;
	}

	eglWindow->common.incRef(&eglWindow->common);

	eglFBConfig = findMatchingWindowConfig(eglDisplay, EGL_OPENGL_ES_BIT, eglWindow);
	/* FIXME: findMatchingWindowConfig returns no error code */

	eglContext = eglCreateContext(eglDisplay, eglFBConfig, EGL_NO_CONTEXT, NULL);
	if(eglContext == EGL_NO_CONTEXT)
	{
		printf("eglCreateContext failed (err=0x%x)\n", eglGetError());
		goto err_window_decref;
	}

	eglWindowSurface = eglCreateWindowSurface(eglDisplay, eglFBConfig, eglWindow, NULL);
	if(eglWindowSurface == EGL_NO_SURFACE)
	{
		printf("eglCreateWindowSurface failed (err=0x%x)\n", eglGetError());
		goto err_destroy_context;
	}

	if(!eglQuerySurface(eglDisplay, eglWindowSurface, EGL_WIDTH, &width))
	{
		printf("eglQuerySurface #1 failed (err=0x%x)\n", eglGetError());
		goto err_destroy_context;
	}

	if(!eglQuerySurface(eglDisplay, eglWindowSurface, EGL_HEIGHT, &height))
	{
		printf("eglQuerySurface #2 failed (err=0x%x)\n", eglGetError());
		goto err_destroy_context;
	}

	if(!eglMakeCurrent(eglDisplay, eglWindowSurface, eglWindowSurface, eglContext))
	{
		printf("eglMakeCurrent failed (err=0x%x)\n", eglGetError());
		goto err_destroy_surface;
	}

	/* Allocate some compatible buffers with gralloc *************************/

	err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
						(const hw_module_t **)&module);
	if(err)
	{
		printf("hw_get_module failed (err=%d)\n", err);
		goto err_make_non_current;
	}

	err = module->base.common.methods->open((const hw_module_t *)module,
											GRALLOC_HARDWARE_GPU0,
											(hw_device_t **)&device);
	if(err)
	{
		printf("module->common.methods->open() failed (err=%d)\n", err);
		goto err_make_non_current;
	}

	err = device->alloc(device, SRC_WIDTH, SRC_HEIGHT, eglCfgVisualId,
						GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE,
						&srcBuffer, &stride);
	if(err)
	{
		printf("device->alloc() failed (err=%d)\n", err);
		goto err_close;
	}

	err = device->alloc(device, DEST_WIDTH, DEST_HEIGHT, DEST_FORMAT,
						GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE,
						&destBuffer, &stride);
	if(err)
	{
		printf("device->alloc() failed (err=%d)\n", err);
		goto err_free_src;
	}

	err = module->base.registerBuffer(&module->base, srcBuffer);
	if(err)
	{
		printf("module->registerBuffer() failed (err=%d)\n", err);
		goto err_free_dest;
	}

	err = module->base.registerBuffer(&module->base, destBuffer);
	if(err)
	{
		printf("module->registerBuffer() failed (err=%d)\n", err);
		goto err_unregister_src;
	}

	sSrcBuffer.handle = srcBuffer;
	sDestBuffer.handle = destBuffer;

	/* Make some EGLImageKHRs out of them ************************************/

	eglSrcImage = eglCreateImageKHR(eglDisplay, EGL_NO_CONTEXT,
									EGL_NATIVE_BUFFER_ANDROID,
									(EGLClientBuffer)&sSrcBuffer, 0);
	if(eglSrcImage == EGL_NO_IMAGE_KHR)
	{
		printf("eglCreateImageKHR #1 failed (err=0x%x)\n", eglGetError());
		goto err_unregister_dest;
	}

	eglDestImage = eglCreateImageKHR(eglDisplay, EGL_NO_CONTEXT,
									 EGL_NATIVE_BUFFER_ANDROID,
									 (EGLClientBuffer)&sDestBuffer, 0);
	if(eglDestImage == EGL_NO_IMAGE_KHR)
	{
		printf("eglCreateImageKHR #2 failed (err=0x%x)\n", eglGetError());
		goto err_destroy_src_image;
	}

	/* Create funny textures *************************************************/

	glGenTextures(2, textureNames);
	glError = glGetError();
	if(glError != GL_NO_ERROR)
	{
		printf("glGenTextures generated error 0x%x\n", glError);
		goto err_destroy_dest_image;
	}

	glBindTexture(GL_TEXTURE_2D, textureNames[0]);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

	glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglSrcImage);
	glError = glGetError();
	if(glError != GL_NO_ERROR)
	{
		printf("glEGLImageTargetTexture2DOES generated error 0x%x\n", glError);
		goto err_delete_textures;
	}

	glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureNames[1]);
	glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

	glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, eglDestImage);
	glError = glGetError();
	if(glError != GL_NO_ERROR)
	{
		printf("glEGLImageTargetTexture2DOES generated error 0x%x\n", glError);
		goto err_delete_textures;
	}

	/* Create FBO ************************************************************/

	glGenFramebuffersOES(1, &fboName);
	glError = glGetError();
	if(glError != GL_NO_ERROR)
	{
		printf("glGenFrameBuffersOES generated error 0x%x\n", glError);
		goto err_delete_textures;
	}

	glBindFramebufferOES(GL_FRAMEBUFFER_OES, fboName);
	glError = glGetError();
	if(glError != GL_NO_ERROR)
	{
		printf("glBindFramebufferOES generated error 0x%x\n", glError);
		goto err_delete_framebuffer;
	}

	glBindTexture(GL_TEXTURE_2D, textureNames[0]);

	glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES,
							  GL_TEXTURE_2D, textureNames[0], 0);
	glError = glGetError();
	if(glError != GL_NO_ERROR)
	{
		printf("glFramebufferTexture2DOES generated error 0x%x\n", glError);
		goto err_delete_framebuffer;
	}

	/*************************************************************************/

	glError = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
	if(glError != GL_FRAMEBUFFER_COMPLETE_OES)
	{
		printf("glCheckFramebufferStatus generated error 0x%x\n", glError);
		goto err_delete_framebuffer;
	}

	/* Draw some stuff */

	{
		const float vertexArray[2 * 4] = {
			-1.0f,	 1.0f,
			-1.0f,	-1.0f,
			 1.0f,	 1.0f,
			 1.0f,	-1.0f,
		};

		const float colorArray[4 * 4] = {
			 1.0f, 0.0f, 0.0f, 1.0f,
			 0.0f, 1.0f, 0.0f, 1.0f,
			 0.0f, 0.0f, 1.0f, 1.0f,
			 1.0f, 0.0f, 1.0f, 1.0f,
		};

		char dummy[4];

		glViewport(0, 0, SRC_WIDTH, SRC_HEIGHT);

		glEnableClientState(GL_VERTEX_ARRAY);
		glEnableClientState(GL_COLOR_ARRAY);

		glVertexPointer(2, GL_FLOAT, 0, vertexArray);
		glColorPointer(4, GL_FLOAT, 0, colorArray);

		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

		glDisableClientState(GL_COLOR_ARRAY);
		glDisableClientState(GL_VERTEX_ARRAY);

		glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, dummy);
	}

	/* RGB -> YUV blit */

	err = module->Blit2(module, srcBuffer, destBuffer,
						SRC_WIDTH, SRC_HEIGHT, 0, 0);
	if(err)
	{
		printf("module->Blit2() failed (err=%d)\n", err);
		goto err_delete_framebuffer;
	}

	/* Present both to screen (should appear identical) */

	glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
	glViewport(0, 0, width, height);

	glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT);

	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);

	glTexCoordPointer(2, GL_FLOAT, 0, texCoordArray);

	glEnable(GL_TEXTURE_EXTERNAL_OES);
	glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureNames[1]);
	glVertexPointer(2, GL_FLOAT, 0, destVertexArray);
	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
	glDisable(GL_TEXTURE_EXTERNAL_OES);

	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, textureNames[0]);
	glVertexPointer(2, GL_FLOAT, 0, srcVertexArray);
	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
	glDisable(GL_TEXTURE_2D);

	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
	glDisableClientState(GL_VERTEX_ARRAY);

	eglSwapBuffers(eglDisplay, eglWindowSurface);
	sleep(1);

err_delete_framebuffer:
	glDeleteFramebuffersOES(1, &fboName);
err_delete_textures:
	glDeleteTextures(2, textureNames);
err_destroy_dest_image:
	eglDestroyImageKHR(eglDisplay, eglDestImage);
err_destroy_src_image:
	eglDestroyImageKHR(eglDisplay, eglSrcImage);
err_unregister_dest:
	err = module->base.unregisterBuffer(&module->base, destBuffer);
	if(err)
		printf("module->unregisterBuffer() failed (err=%d)\n", err);
err_unregister_src:
	err = module->base.unregisterBuffer(&module->base, srcBuffer);
	if(err)
		printf("module->unregisterBuffer() failed (err=%d)\n", err);
err_free_dest:
	err = device->free(device, destBuffer);
	if(err)
		printf("device->free() failed (err=%d)\n", err);
err_free_src:
	err = device->free(device, srcBuffer);
	if(err)
		printf("device->free() failed (err=%d)\n", err);
err_close:
	err = device->common.close((hw_device_t *)device);
	if(err)
		printf("hal->close() failed (err=%d)\n", err);
err_make_non_current:
	eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
err_destroy_surface:
	eglDestroySurface(eglDisplay, eglWindowSurface);
err_destroy_context:
	eglDestroyContext(eglDisplay, eglContext);
err_window_decref:
	eglWindow->common.decRef(&eglWindow->common);
err_terminate:
	eglTerminate(eglDisplay);
err_out:
	return err;
}
Beispiel #25
0
void initTextureWithCGImage(CGImageRef image)
{
	int i;
    
	// Query renderer capabilities that affect this app's rendering paths
	renderer.extension[APPLE_texture_2D_limited_npot] =
    (0 != strstr((char *)glGetString(GL_EXTENSIONS), "GL_APPLE_texture_2D_limited_npot"));
	renderer.extension[IMG_texture_format_BGRA8888] =
    (0 != strstr((char *)glGetString(GL_EXTENSIONS), "GL_IMG_texture_format_BGRA8888"));
	glGetIntegerv(GL_MAX_TEXTURE_SIZE, &renderer.maxTextureSize);
    
	// Constant state for the lifetime of the app-- position and unit0 are always used
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
	glEnable(GL_TEXTURE_2D);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    
	// Load image into texture
	loadTextureFromCGImage(image, &Input, &renderer);
    
	// Modify quad texcoords to match (possibly padded) image
	for (i = 0; i < 4; i++)
	{
		fullquad[i].s *= Input.s;
		fullquad[i].t *= Input.t;
		flipquad[i].s *= Input.s;
		flipquad[i].t *= Input.t;
	}
	
	// Create 1x1 for default constant texture
	// To enable a texture unit, a valid texture has to be bound even if the combine modes do not access it
	GLubyte half[4] = { 0x80, 0x80, 0x80, 0x80 };
	glActiveTexture(GL_TEXTURE1);
	glGenTextures(1, &Half.texID);
	Half.wide = Half.high = 1;
	Half.s = Half.t = 1.0;
	glBindTexture(GL_TEXTURE_2D, Half.texID);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, half);
	glActiveTexture(GL_TEXTURE0);
    
	// Remember the FBO being used for the display framebuffer
	glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, (GLint *)&SystemFBO);
    
	// Create scratch textures and FBOs
	glGenTextures(1, &Degen.texID);
	Degen.wide = Input.wide;
	Degen.high = Input.high;
	Degen.s = Input.s;
	Degen.t = Input.t;
	glBindTexture(GL_TEXTURE_2D, Degen.texID);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Degen.wide, Degen.high, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
	glGenFramebuffersOES(1, &DegenFBO);
	glBindFramebufferOES(GL_FRAMEBUFFER_OES, DegenFBO);
	glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, Degen.texID, 0);
	rt_assert(GL_FRAMEBUFFER_COMPLETE_OES == glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
	
	glGenTextures(1, &Scratch.texID);
	Scratch.wide = Input.wide;
	Scratch.high = Input.high;
	Scratch.s = Input.s;
	Scratch.t = Input.t;
	glBindTexture(GL_TEXTURE_2D, Scratch.texID);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Scratch.wide, Scratch.high, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
	glGenFramebuffersOES(1, &ScratchFBO);
	glBindFramebufferOES(GL_FRAMEBUFFER_OES, ScratchFBO);
	glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, Scratch.texID, 0);
	rt_assert(GL_FRAMEBUFFER_COMPLETE_OES == glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
	glBindFramebufferOES(GL_FRAMEBUFFER_OES, SystemFBO);
	
	glCheckError();
}