//----------------------------------------------------------------------------- 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(); }
// 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); }
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; }
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; }
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; }
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, ¤t_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; }
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; }
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 }
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); }
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 }
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; }
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(); }