void GLTexture::blit(GPUTexture *target, int what) const { GLTexture *dest = static_cast<GLTexture *>(target); Assert(m_fbType != ENone && (dest == NULL || dest->m_fbType != ENone)); if (!GLEW_EXT_framebuffer_blit) Log(EError, "Your OpenGL driver does not support fast " "framebuffer blitting!"); glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_fboId); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, (dest == NULL) ? GL_NONE : dest->m_fboId); int flags = 0; if (what & EDepthBuffer) flags |= GL_DEPTH_BUFFER_BIT; if (what & EColorBuffer) flags |= GL_COLOR_BUFFER_BIT; if (!dest) { glBlitFramebufferEXT(0, 0, m_size.x, m_size.y, 0, 0, m_size.x, m_size.y, flags, GL_NEAREST); } else { glBlitFramebufferEXT(0, 0, m_size.x, m_size.y, 0, 0, dest->m_size.x, dest->m_size.y, flags, (m_size == dest->m_size) ? GL_NEAREST : GL_LINEAR); } glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, GL_NONE); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_NONE); }
//static void LLRenderTarget::copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1, S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter) { if (!source.mFBO) { llerrs << "Cannot copy framebuffer contents for non FBO render targets." << llendl; } { GLboolean write_depth = mask & GL_DEPTH_BUFFER_BIT ? TRUE : FALSE; LLGLDepthTest depth(write_depth, write_depth); glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, source.mSampleBuffer ? source.mSampleBuffer->mFBO : source.mFBO); stop_glerror(); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); stop_glerror(); check_framebuffer_status(); stop_glerror(); if(gGLManager.mIsATI && mask & GL_STENCIL_BUFFER_BIT) { mask &= ~GL_STENCIL_BUFFER_BIT; glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, GL_STENCIL_BUFFER_BIT, filter); } if(mask) glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); stop_glerror(); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); stop_glerror(); } }
void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1, S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter) { GLboolean write_depth = mask & GL_DEPTH_BUFFER_BIT ? TRUE : FALSE; LLGLDepthTest depth(write_depth, write_depth); gGL.flush(); if (!source.mFBO || !mFBO) { llerrs << "Cannot copy framebuffer contents for non FBO render targets." << llendl; } if (mSampleBuffer) { mSampleBuffer->copyContents(source, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); } else { if (mask == GL_DEPTH_BUFFER_BIT && source.mStencil != mStencil) { stop_glerror(); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, source.mFBO); gGL.getTexUnit(0)->bind(this, true); stop_glerror(); glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, srcX0, srcY0, dstX0, dstY0, dstX1, dstY1); stop_glerror(); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); stop_glerror(); } else { glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, source.mFBO); stop_glerror(); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, mFBO); stop_glerror(); check_framebuffer_status(); stop_glerror(); if(gGLManager.mIsATI && mask & GL_STENCIL_BUFFER_BIT) { mask &= ~GL_STENCIL_BUFFER_BIT; glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, GL_STENCIL_BUFFER_BIT, filter); } if(mask) glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); stop_glerror(); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); stop_glerror(); } } }
void FrameBufferBackend::Post(){ glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, prevFb); Vector<2, int> dims = fb->GetDimension(); glBlitFramebufferEXT(prevDims[0], prevDims[1], prevDims[2], prevDims[3], 0, 0, dims[0], dims[1], GL_COLOR_BUFFER_BIT, GL_LINEAR); glBlitFramebufferEXT(prevDims[0], prevDims[1], prevDims[2], prevDims[3], 0, 0, dims[0], dims[1], GL_DEPTH_BUFFER_BIT, GL_NEAREST); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, prevFb); CHECK_FOR_GL_ERROR(); }
PIGLIT_GL_TEST_CONFIG_END enum piglit_result piglit_display(void) { const float green[] = {0.0f, 1.0f, 0.0f}; const float red[] = {1.0f, 0.0f, 0.0f}; int w = piglit_width; int h = piglit_height; bool success = 1; glDrawBuffer(GL_BACK); /* paint the back buffer green */ glClearColor(0.0f, 1.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); /* blit back to front */ glDrawBuffer(GL_FRONT); glReadBuffer(GL_BACK); glBlitFramebufferEXT(0, 0, w, h, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_LINEAR); /* paint the back buffer red */ glDrawBuffer(GL_BACK); glClearColor(1.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); /* paint a square in the middle of the front buffer red */ glDrawBuffer(GL_FRONT); glReadBuffer(GL_BACK); glBlitFramebufferEXT(w / 4, h / 4, 3 * w / 4, 3 * h / 4, w / 4, h / 4, 3 * w / 4, 3 * h / 4, GL_COLOR_BUFFER_BIT, GL_LINEAR); glReadBuffer(GL_FRONT); /* the middle should be red */ success &= piglit_probe_pixel_rgb(w / 2, h / 2, red); /* the corners should be green */ success &= piglit_probe_pixel_rgb(0, 0, green); success &= piglit_probe_pixel_rgb(w - 1, 0, green); success &= piglit_probe_pixel_rgb(0, h - 1, green); success &= piglit_probe_pixel_rgb(w - 1, h - 1, green); glFlush(); return success ? PIGLIT_PASS : PIGLIT_FAIL; }
static enum piglit_result test_copy(void) { /* Clear stencil to 0xfe. */ glClearStencil(0xfefe); glClear(GL_STENCIL_BUFFER_BIT); /* Initialize stencil. */ glEnable(GL_STENCIL_TEST); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); /* Set the upper-right corner to 0x3333 and copy the content to the lower-left one. */ glStencilFunc(GL_ALWAYS, 0x3333 & mask, ~0); piglit_draw_rect(0, 0, 1, 1); if (test == BLIT) glBlitFramebufferEXT(BUF_SIZE/2+1, BUF_SIZE/2+1, BUF_SIZE, BUF_SIZE, 0, 0, BUF_SIZE/2, BUF_SIZE/2, GL_STENCIL_BUFFER_BIT, GL_NEAREST); else glCopyPixels(BUF_SIZE/2+1, BUF_SIZE/2+1, BUF_SIZE/2, BUF_SIZE/2, GL_STENCIL); /* Initialize the other corners. */ glStencilFunc(GL_ALWAYS, 0x6666 & mask, ~0); piglit_draw_rect(0, -1, 1, 1); glStencilFunc(GL_ALWAYS, 0x9999 & mask, ~0); piglit_draw_rect(-1, 0, 1, 1); glStencilFunc(GL_ALWAYS, 0xbbbb & mask, ~0); piglit_draw_rect(0, 0, 1, 1); glDisable(GL_STENCIL_TEST); return compare_stencil(); }
void R_CopyToFBO(FBO_t *from, FBO_t *to, GLuint mask, GLuint filter) { if (glConfig2.framebufferBlitAvailable) { vec2_t size; if (from) { glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, from->frameBuffer); size[0] = from->width; size[1] = from->height; } else { glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); size[0] = glConfig.vidWidth; size[1] = glConfig.vidHeight; } glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, to->frameBuffer); glBlitFramebufferEXT(0, 0, size[0], size[1], 0, 0, to->width, to->height, mask, filter); //Just set the read buffer to the target as well otherwise we might get f****d.. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, to->frameBuffer); glState.currentFBO = to; } else { // FIXME add non EXT_framebuffer_blit code ri.Error(ERR_FATAL, "R_CopyToFBO no framebufferblitting available"); } }
GLuint FramebufferManager::GetEFBDepthTexture(const EFBRectangle& sourceRc) { if (m_msaaSamples <= 1) { return m_efbDepth; } else { // Transfer the EFB to a resolved texture. EXT_framebuffer_blit is // required. TargetRectangle targetRc = g_renderer->ConvertEFBRectangle(sourceRc); targetRc.ClampLL(0, 0, m_targetWidth, m_targetHeight); // Resolve. glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_efbFramebuffer); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_resolvedFramebuffer); glBlitFramebufferEXT( targetRc.left, targetRc.top, targetRc.right, targetRc.bottom, targetRc.left, targetRc.top, targetRc.right, targetRc.bottom, GL_DEPTH_BUFFER_BIT, GL_NEAREST ); // Return to EFB. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer); return m_resolvedDepthTexture; } }
void GLTexture::blit(GPUTexture *target, int what, const Point2i &sourceOffset, const Vector2i &sourceSize, const Point2i &destOffset, const Vector2i &destSize) const { GLTexture *dest = static_cast<GLTexture *>(target); Assert(m_fbType != ENone && (dest == NULL || dest->m_fbType != ENone)); if (!GLEW_EXT_framebuffer_blit) Log(EError, "Your OpenGL driver does not support fast " "framebuffer blitting!"); glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_fboId); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, (dest == NULL) ? GL_NONE : dest->m_fboId); int flags = 0; if (what & EDepthBuffer) flags |= GL_DEPTH_BUFFER_BIT; if (what & EColorBuffer) flags |= GL_COLOR_BUFFER_BIT; glBlitFramebufferEXT(sourceOffset.x, sourceOffset.y, sourceOffset.x + sourceSize.x, sourceOffset.x + sourceSize.y, destOffset.x, destOffset.y, destOffset.x + destSize.x, destOffset.y + destSize.y, flags, (sourceSize == destSize) ? GL_NEAREST : GL_LINEAR); glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, GL_NONE); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_NONE); }
void Fbo::resolveTextures() const { if( ! mObj->mNeedsResolve ) return; #if ! defined( CINDER_GLES ) // if this FBO is multisampled, resolve it, so it can be displayed if ( mObj->mResolveFramebufferId ) { SaveFramebufferBinding saveFboBinding; glBindFramebufferEXT( GL_READ_FRAMEBUFFER_EXT, mObj->mId ); glBindFramebufferEXT( GL_DRAW_FRAMEBUFFER_EXT, mObj->mResolveFramebufferId ); for( size_t c = 0; c < mObj->mColorTextures.size(); ++c ) { glDrawBuffer( GL_COLOR_ATTACHMENT0_EXT + c ); glReadBuffer( GL_COLOR_ATTACHMENT0_EXT + c ); GLbitfield bitfield = GL_COLOR_BUFFER_BIT; if( mObj->mDepthTexture ) bitfield |= GL_DEPTH_BUFFER_BIT; glBlitFramebufferEXT( 0, 0, mObj->mWidth, mObj->mHeight, 0, 0, mObj->mWidth, mObj->mHeight, bitfield, GL_NEAREST ); } // restore the draw buffers to the default for the antialiased (non-resolve) framebuffer vector<GLenum> drawBuffers; for( size_t c = 0; c < mObj->mColorTextures.size(); ++c ) drawBuffers.push_back( GL_COLOR_ATTACHMENT0_EXT + c ); glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, mObj->mId ); glDrawBuffers( drawBuffers.size(), &drawBuffers[0] ); } #endif mObj->mNeedsResolve = false; }
static enum piglit_result test_copy(void) { /* Clear. */ glClearDepth(0); glClear(GL_DEPTH_BUFFER_BIT); /* Initialize buffers. */ glEnable(GL_DEPTH_TEST); glDepthFunc(GL_ALWAYS); /* Set the upper-right corner to 0x3333 and copy the content to the lower-left one. */ piglit_draw_rect_z(-0.5, 0, 0, 1, 1); if (test == BLIT) glBlitFramebufferEXT(BUF_SIZE/2+1, BUF_SIZE/2+1, BUF_SIZE, BUF_SIZE, 0, 0, BUF_SIZE/2, BUF_SIZE/2, GL_DEPTH_BUFFER_BIT, GL_NEAREST); else glCopyPixels(BUF_SIZE/2+1, BUF_SIZE/2+1, BUF_SIZE/2, BUF_SIZE/2, GL_DEPTH); /* Initialize the other corners. */ piglit_draw_rect_z(-0.25, 0, -1, 1, 1); piglit_draw_rect_z(0.25, -1, 0, 1, 1); piglit_draw_rect_z(0.5, 0, 0, 1, 1); glDisable(GL_DEPTH_TEST); return compare(); }
void WebGraphicsContext3DDefaultImpl::readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type, void* pixels) { #ifndef RENDER_TO_DEBUGGING_WINDOW if (m_attributes.antialias && m_boundFBO == m_multisampleFBO) { glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); } #endif glReadPixels(x, y, width, height, format, type, pixels); #if PLATFORM(CG) if (!m_attributes.alpha) { // If alpha is off, by default glReadPixels should set the alpha to 255 instead of 0. // This is a hack until glReadPixels fixes its behavior. // Pixels are stored in WebGLUnsignedByteArray, which is unsigned char array. unsigned char* data = reinterpret_cast<unsigned char*>(pixels); // FIXME: take into account pack alignment. unsigned long byteLength = width * height * 4 * sizeof(unsigned char); for (unsigned long i = 3; i < byteLength; i += 4) data[i] = 255; } #endif #ifndef RENDER_TO_DEBUGGING_WINDOW if (m_attributes.antialias && m_boundFBO == m_multisampleFBO) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); #endif }
void Fbo::blitFromScreen( const Area &srcArea, const Area &dstArea, GLenum filter, GLbitfield mask ) { SaveFramebufferBinding saveFboBinding; glBindFramebufferEXT( GL_READ_FRAMEBUFFER_EXT, GL_NONE ); glBindFramebufferEXT( GL_DRAW_FRAMEBUFFER_EXT, mObj->mId ); glBlitFramebufferEXT( srcArea.getX1(), srcArea.getY1(), srcArea.getX2(), srcArea.getY2(), dstArea.getX1(), dstArea.getY1(), dstArea.getX2(), dstArea.getY2(), mask, filter ); }
static void copy(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1) { glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, GL_COLOR_BUFFER_BIT, GL_NEAREST); }
static void copy(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLenum mask) { glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, GL_NEAREST); }
void CGLFramebufferEXT::CopyToScreen(int fromX, int fromY, int fromWidth, int fromHeight, int toX, int toY, int toWidth, int toHeight) { glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_fbo); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); glBlitFramebufferEXT(fromX, fromY, fromX + fromWidth, fromY + fromHeight, toX, toY, toX + toWidth, toY + toHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_currentFBO); }
inline void VL_glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { if (glBlitFramebuffer) glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); else if (glBlitFramebufferEXT) glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); else VL_UNSUPPORTED_FUNC(); }
bool WebGraphicsContext3DDefaultImpl::readBackFramebuffer(unsigned char* pixels, size_t bufferSize) { if (bufferSize != static_cast<size_t>(4 * width() * height())) return false; makeContextCurrent(); // Earlier versions of this code used the GPU to flip the // framebuffer vertically before reading it back for compositing // via software. This code was quite complicated, used a lot of // GPU memory, and didn't provide an obvious speedup. Since this // vertical flip is only a temporary solution anyway until Chrome // is fully GPU composited, it wasn't worth the complexity. bool mustRestoreFBO = false; if (m_attributes.antialias) { glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); glBlitFramebufferEXT(0, 0, m_cachedWidth, m_cachedHeight, 0, 0, m_cachedWidth, m_cachedHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); mustRestoreFBO = true; } else { if (m_boundFBO != m_fbo) { mustRestoreFBO = true; glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); } } GLint packAlignment = 4; bool mustRestorePackAlignment = false; glGetIntegerv(GL_PACK_ALIGNMENT, &packAlignment); if (packAlignment > 4) { glPixelStorei(GL_PACK_ALIGNMENT, 4); mustRestorePackAlignment = true; } // FIXME: OpenGL ES 2 does not support GL_BGRA so this fails when // using that backend. glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_BGRA, GL_UNSIGNED_BYTE, pixels); if (mustRestorePackAlignment) glPixelStorei(GL_PACK_ALIGNMENT, packAlignment); if (mustRestoreFBO) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); #ifdef FLIP_FRAMEBUFFER_VERTICALLY if (pixels) flipVertically(pixels, m_cachedWidth, m_cachedHeight); #endif return true; }
void GLFrameBufferObject::swapBuffers() { if (mMultisampleFB) { // blit from multisample buffer to final buffer, triggers resolve size_t width = mColour[0].buffer->getWidth(); size_t height = mColour[0].buffer->getHeight(); glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, mMultisampleFB); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, mFB); glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST); } }
static enum piglit_result test_clear(void) { GLuint cb; GLenum status; float green[3] = {0, 1, 0}; enum piglit_result res; /* Add a colorbuffer. */ glGenRenderbuffersEXT(1, &cb); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, cb); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA8, BUF_SIZE, BUF_SIZE); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER_EXT, cb); glDrawBuffer(GL_COLOR_ATTACHMENT0); glReadBuffer(GL_COLOR_ATTACHMENT0); status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { printf("FBO incomplete status 0x%X\n", status); piglit_report_result(PIGLIT_FAIL); /* RGBA8 must succeed. */ } glClearDepth(0.75); glClear(GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); glColor3fv(green); glDepthFunc(GL_LEQUAL); piglit_draw_rect_z(0.499, -1, -1, 1, 2); /* 0.75 converted to clip space is 0.5. */ glDepthFunc(GL_GEQUAL); piglit_draw_rect_z(0.501, 0, -1, 1, 2); glColor3f(1, 1, 1); glDisable(GL_DEPTH_TEST); res = piglit_probe_rect_rgb(0, 0, BUF_SIZE, BUF_SIZE, green) ? PIGLIT_PASS : PIGLIT_FAIL; /* Display the colorbuffer. */ if (!piglit_automatic) { glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); glBlitFramebufferEXT(0, 0, BUF_SIZE, BUF_SIZE, 0, 0, BUF_SIZE, BUF_SIZE, GL_COLOR_BUFFER_BIT, GL_NEAREST); } glDeleteRenderbuffersEXT(1, &cb); return res; }
void draw(int vertex_count) { // Bind the framebuffer glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer); glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); // Draw renderer_once::draw(vertex_count); // Draw the framebuffer to screen glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer); glBlitFramebufferEXT(0,0, screen->w, screen->h, 0,0, screen->w, screen->h, GL_COLOR_BUFFER_BIT, GL_NEAREST); printGLError(); }
void GLframebuffer::blitDepth(GLtexture* tex) { AX_ASSERT(m_boundDepth); glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_object); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_object2); glDrawBuffer(GL_NONE); glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, tex->getTarget(), tex->getObject(), 0); glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, tex->getTarget(), tex->getObject(), 0); checkStatus(GL_DRAW_FRAMEBUFFER_EXT); glBlitFramebufferEXT(0, 0, m_width, m_height, 0, 0, m_width, m_height, GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT, GL_NEAREST); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_object); GLrender::checkErrors(); }
void ofxFBOTexture::swapOut() { _isActive = false; if( bUseMultiSample ){ // WE THEN COPY THE MULTISAMPLED FBO TO THE TEXTURED FBO glPopAttrib(); glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, mfbo); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fbo); glBlitFramebufferEXT(0, 0, texData.tex_w, texData.tex_h, 0, 0, texData.tex_w, texData.tex_h, GL_COLOR_BUFFER_BIT, GL_LINEAR); } glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); //unbind the FBO }
bool WebGraphicsContext3DDefaultImpl::readBackFramebuffer(unsigned char* pixels, size_t bufferSize) { if (bufferSize != static_cast<size_t>(4 * width() * height())) return false; makeContextCurrent(); #ifdef RENDER_TO_DEBUGGING_WINDOW SwapBuffers(m_canvasDC); #else // Earlier versions of this code used the GPU to flip the // framebuffer vertically before reading it back for compositing // via software. This code was quite complicated, used a lot of // GPU memory, and didn't provide an obvious speedup. Since this // vertical flip is only a temporary solution anyway until Chrome // is fully GPU composited, it wasn't worth the complexity. bool mustRestoreFBO; if (m_attributes.antialias) { glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); glBlitFramebufferEXT(0, 0, m_cachedWidth, m_cachedHeight, 0, 0, m_cachedWidth, m_cachedHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); mustRestoreFBO = true; } else { if (m_boundFBO != m_fbo) { mustRestoreFBO = true; glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); } } #if PLATFORM(SKIA) glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_BGRA, GL_UNSIGNED_BYTE, pixels); #elif PLATFORM(CG) glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels); #else #error Must port to your platform #endif if (mustRestoreFBO) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); #ifdef FLIP_FRAMEBUFFER_VERTICALLY if (pixels) flipVertically(pixels, m_cachedWidth, m_cachedHeight); #endif #endif // RENDER_TO_DEBUGGING_WINDOW return true; }
void StimulusDisplay::drawStoredBuffer(int contextIndex) { glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffers[contextIndex]); glReadBuffer(GL_COLOR_ATTACHMENT0); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); GLenum drawBuffers[] = { GL_BACK_LEFT }; glDrawBuffers(1, drawBuffers); glBlitFramebufferEXT(0, 0, bufferWidths[contextIndex], bufferHeights[contextIndex], 0, 0, bufferWidths[contextIndex], bufferHeights[contextIndex], GL_COLOR_BUFFER_BIT, GL_LINEAR); glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); }
void OpenGLComposite::paintGL() { // The DeckLink API provides IDeckLinkGLScreenPreviewHelper as a convenient way to view the playout video frames // in a window. However, it performs a copy from host memory to the GPU which is wasteful in this case since // we already have the rendered frame to be played out sitting in the GPU in the mIdFrameBuf frame buffer. // Simply copy the off-screen frame buffer to on-screen frame buffer, scaling to the viewing window size. glBindFramebufferEXT(GL_READ_FRAMEBUFFER, mIdFrameBuf); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0); glViewport(0, 0, mViewWidth, mViewHeight); glBlitFramebufferEXT(0, 0, mFrameWidth, mFrameHeight, 0, 0, mViewWidth, mViewHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR); SwapBuffers(hGLDC); ValidateRect(hGLWnd, NULL); }
void StereoAutoFocuser::autoFocus( CameraStereo *cam, const Area &area, GLuint buffer ) { if( ! cam->isStereoEnabled() ) return; // create or resize buffers createBuffers( area ); // blit (multi-sampled) depth buffer to (non-multi-sampled) auto focus fbo // (they need to be the same size for this to work!) { SaveFramebufferBinding saveFboBinding; Area dstArea = mFboLarge.getBounds(); glBindFramebufferEXT( GL_READ_FRAMEBUFFER_EXT, buffer ); glBindFramebufferEXT( GL_DRAW_FRAMEBUFFER_EXT, mFboLarge.getId() ); glBlitFramebufferEXT( area.getX1(), area.getY1(), area.getX2(), area.getY2(), dstArea.getX1(), dstArea.getY1(), dstArea.getX2(), dstArea.getY2(), GL_DEPTH_BUFFER_BIT, GL_NEAREST ); } // create a downsampled copy for the auto focus test mFboLarge.blitTo( mFboSmall, mFboLarge.getBounds(), mFboSmall.getBounds(), GL_NEAREST, GL_DEPTH_BUFFER_BIT ); // load depth samples into buffer glBindFramebufferEXT( GL_READ_FRAMEBUFFER_EXT, mFboSmall.getId() ); glReadPixels(0, 0, AF_WIDTH, AF_HEIGHT, GL_DEPTH_COMPONENT, GL_FLOAT, &mBuffer.front()); mFboSmall.unbindFramebuffer(); // find minimum value std::vector<GLfloat>::const_iterator itr = std::min_element(mBuffer.begin(), mBuffer.end()); size_t p = itr - mBuffer.begin(); mNearest.x = 0.5f + (int) ( (p % AF_WIDTH) / (float) AF_WIDTH * mArea.getWidth() ); mNearest.y = 0.5f + (int) ( (p / AF_WIDTH) / (float) AF_HEIGHT * mArea.getHeight() ); // convert to actual distance from camera float nearClip = cam->getNearClip(); float farClip = cam->getFarClip(); float depth = 2.0f * (*itr) - 1.0f; mNearest.z = 2.0f * nearClip * farClip / ( farClip + nearClip - depth * ( farClip - nearClip ) ); // perform auto focussing float z = math<float>::max( nearClip, mNearest.z * mDepth ); cam->setConvergence( cam->getConvergence() + mSpeed * ( z - cam->getConvergence() ), true ); }
void WebGraphicsContext3DDefaultImpl::copyTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, long x, long y, unsigned long width, unsigned long height) { makeContextCurrent(); if (m_attributes.antialias && m_boundFBO == m_multisampleFBO) { glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); } glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); if (m_attributes.antialias && m_boundFBO == m_multisampleFBO) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); }
void ofxFBOTexture::swapOut() { _isActive = false; #ifndef TARGET_OPENGLES if(numSamples){ // WE THEN COPY THE MULTISAMPLED FBO TO THE TEXTURED FBO glPopAttrib(); glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, mfbo); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fbo); glBlitFramebufferEXT(0, 0, texData.tex_w, texData.tex_h, 0, 0, texData.tex_w, texData.tex_h, GL_COLOR_BUFFER_BIT, GL_LINEAR); } glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, oldFramebuffer); //unbind the FBO #else glBindFramebufferOES(GL_FRAMEBUFFER_OES, oldFramebuffer); #endif }
void GLFrameBufferObject::swapBuffers() { if (mMultisampleFB) { GLint oldfb = 0; glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &oldfb); // Blit from multisample buffer to final buffer, triggers resolve uint32 width = mColour[0].buffer->getWidth(); uint32 height = mColour[0].buffer->getHeight(); glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, mMultisampleFB); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, mFB); glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST); // Unbind glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, oldfb); } }