//<<<<<<<<<<<<<<<<<<<<<<<< myDisplay >>>>>>>>>>>>>>>>> void renderFBO(void) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texId[0]); glTexSubImage2D(GL_TEXTURE_2D,0, 0, 0, img.cols, img.rows, GL_RGB, GL_UNSIGNED_BYTE, img.data); CheckGlErrors("glTexSubImage2D"); #ifdef FBO glDrawBuffer(GL_COLOR_ATTACHMENT0); #endif glClear(GL_COLOR_BUFFER_BIT); glBindTexture(GL_TEXTURE_2D, texId[0]); glEnable(GL_TEXTURE_2D); glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex2f(-1, -1); glTexCoord2f(1, 0); glVertex2f(1, -1); glTexCoord2f(1, 1); glVertex2f(1, 1); glTexCoord2f(0, 1); glVertex2f(-1, 1); glEnd(); glDisable(GL_TEXTURE_2D); checkFramebufferStatus(); CheckGlErrors("render"); #ifndef FBO glutSwapBuffers(); #endif }
void FBO::generateDepthOnly() { destroy(); glGenTextures(1, &m_iTexDepthId); glBindTexture(m_eTextureType, m_iTexDepthId); //we create a special texture for depth glTexImage2D(m_eTextureType, 0, GL_DEPTH_COMPONENT, m_iWidth, m_iHeight, 0,GL_DEPTH_COMPONENT, GL_FLOAT, 0); glTexParameteri (m_eTextureType, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri (m_eTextureType, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(m_eTextureType, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(m_eTextureType, GL_TEXTURE_WRAP_T, GL_CLAMP); glBindTexture(m_eTextureType, 0); //Generating ID glGenFramebuffersEXT(1, &m_iId); activate(); //We attach the texture to the depth attachment point glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_DEPTH_ATTACHMENT_EXT,m_eTextureType, m_iTexDepthId, 0); //In order to avoid Color in the depth buffer glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); desactivate(); //Check FBO status if(!checkFramebufferStatus()) std::cerr<<"ERROR : FBO creation Fail "<<std::endl; //Depth Only m_iType = 1; }
void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, QGLFramebufferObject::Attachment attachment, GLenum texture_target, GLenum internal_format, GLint samples, bool mipmap) { QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext()); funcs.initializeOpenGLFunctions(); if (!funcs.hasOpenGLFeature(QOpenGLFunctions::Framebuffers)) return; ctx->d_ptr->refreshCurrentFbo(); size = sz; target = texture_target; // texture dimensions QT_RESET_GLERROR(); // reset error state GLuint fbo = 0; funcs.glGenFramebuffers(1, &fbo); funcs.glBindFramebuffer(GL_FRAMEBUFFER, fbo); GLuint texture = 0; GLuint color_buffer = 0; GLuint depth_buffer = 0; GLuint stencil_buffer = 0; QT_CHECK_GLERROR(); // init texture if (samples == 0) { funcs.glGenTextures(1, &texture); funcs.glBindTexture(target, texture); funcs.glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); if (mipmap) { int width = size.width(); int height = size.height(); int level = 0; while (width > 1 || height > 1) { width = qMax(1, width >> 1); height = qMax(1, height >> 1); ++level; funcs.glTexImage2D(target, level, internal_format, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); } } funcs.glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); funcs.glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); funcs.glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); funcs.glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); funcs.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, texture, 0); QT_CHECK_GLERROR(); valid = checkFramebufferStatus(); funcs.glBindTexture(target, 0); color_buffer = 0; } else {
void testApp::generateFrameBuffers(){ // create a framebuffer object, you need to delete them when program exits. glGenFramebuffersEXT(1, &fboId); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId); // 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. glGenRenderbuffersEXT(1, &rboId); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rboId); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, ofGetWidth(), ofGetHeight()); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); // attach a texture to FBO color attachement point glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, colourTextureId, 0); // attach a renderbuffer to depth attachment point glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rboId); //@ disable color buffer if you don't attach any color buffer image, //@ for example, rendering depth buffer only to a texture. //@ Otherwise, glCheckFramebufferStatusEXT will not be complete. //glDrawBuffer(GL_NONE); //glReadBuffer(GL_NONE); // check FBO status printFramebufferInfo(); bool status = checkFramebufferStatus(); if(!status) fboUsed = false; }
void TransparencyRenderer::draw(Scene & scene, Camera & camera) { stateManager.setRenderingStage(StateManager::TRANSPARENCY_STAGE); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // Bind Framebuffer checkGLErrors("Binding framebuffer"); checkFramebufferStatus(); // Check that framebuffer config OK shaderManager.bindStageShader(); // Bind Transparency stage shaders glDisable(GL_BLEND); // Enable blending glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); // Set blend func for optimized Transparency rendering glEnable(GL_CULL_FACE); // Disable face culling glEnable(GL_DEPTH_TEST); // Disable Z-Buffer glDisable(GL_TEXTURE_2D); // Disable textures //camera.setGLModelView(); //camera.setGLProjection(); //camera.calculatePlanes(); // Will later be used for culling scene.sortEntities(camera); // Sort entities by depth drawLights(scene,camera); glDisable(GL_BLEND); }
void DeferredShader::bindPBuffer() { glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // Bind Framebuffer checkGLErrors("Binding FBO"); checkFramebufferStatus(); // Check that framebuffer config OK }
void FBO::generateColorOnly(bool tex16f) { destroy(); //Generate the texture glGenTextures(1, &m_iTexId); glBindTexture(m_eTextureType, m_iTexId); glTexParameteri (m_eTextureType, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri (m_eTextureType, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(m_eTextureType, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(m_eTextureType, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(m_eTextureType, GL_GENERATE_MIPMAP, GL_TRUE); ///We need six Face for cube, or one for 2D if (m_eTextureType == GL_TEXTURE_CUBE_MAP) { glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X , 0, GL_RGBA8, m_iWidth, m_iHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_Y , 0, GL_RGBA8, m_iWidth, m_iHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_Z , 0, GL_RGBA8, m_iWidth, m_iHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_X , 0, GL_RGBA8, m_iWidth, m_iHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_Y , 0, GL_RGBA8, m_iWidth, m_iHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_Z , 0, GL_RGBA8, m_iWidth, m_iHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); } else{ if(!tex16f) glTexImage2D(m_eTextureType, 0, GL_RGBA8, m_iWidth, m_iHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); else glTexImage2D(m_eTextureType, 0, GL_RGB16F_ARB, m_iWidth, m_iHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); } glBindTexture(m_eTextureType, 0); //Generate renderbuffer glGenRenderbuffersEXT(1, &m_iRenderId); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_iRenderId); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, m_iWidth, m_iHeight); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); //Generating ID glGenFramebuffersEXT(1, &m_iId); activate(); // attach a texture to FBO color attachement point glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, m_eTextureType, m_iTexId, 0); // attach a renderbuffer to depth attachment point glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_iRenderId); desactivate(); //Check FBO status if(!checkFramebufferStatus()) std::cerr<<"ERROR : FBO creation Fail "<<std::endl; //Color Only m_iType = 0; }
void initDisplay() { for(int i=0;i<10;i++) { flag_dessin[i] = false; } flag_dessin[0] = true; instantPrec = glutGet(GLUT_ELAPSED_TIME); sepiaColor[0] = 0.2; sepiaColor[1] = 0.1; sepiaColor[2] = 0; /// INITIALISATION DES TEXTURES ... initTexture(); /// INITIALISATION DES SHADERS ... if(!RTShaders::areShadersSupported(true)) { std::cerr<<"[In initDisplay] : Shaders are not supported..."<<std::endl; exit(5); } testShader = RTShaders::loadShader("./shaders/tstshader.vert","./shaders/tstshader.frag",true); /// INITIALISATION DES FBOS ... if (USE_FBO) { if(initFBO()==false){ cerr<<"FBO not supported ! Exiting"<<endl; exit(5); } glGenFramebuffersEXT(1, &fbo_handler); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fbo_handler); GLuint depth_rb; glGenRenderbuffersEXT(1, &depth_rb); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_rb); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,GL_DEPTH_COMPONENT,image_base->tailu,image_base->tailv); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_rb); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, image_base->indbind , 0); checkFramebufferStatus(); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0); } /// INITIALISATION CLASSIQUE OPENGL ... glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glShadeModel( GL_SMOOTH ); glEnable(GL_TEXTURE_2D); glDisable(GL_BLEND); glDisable(GL_FOG); CHECK_GL; glUseProgramObjectARB(0); }
void MainWidget::initFrameBuffers() { //create fboA and attach texture A to it glGenFramebuffers(1, &fboA); glBindFramebuffer(GL_FRAMEBUFFER, fboA); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureA, 0); checkFramebufferStatus(); glBindFramebuffer(GL_FRAMEBUFFER, 0); glGenFramebuffers(1, &fboB); glBindFramebuffer(GL_FRAMEBUFFER, fboB); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureB, 0); checkFramebufferStatus(); glBindFramebuffer(GL_FRAMEBUFFER, 0); }
void testApp::generateScreenSpaceFrameBuffers() { #ifdef DEBUG cout << "Creating First Framebuffer" <<endl; #endif glGenFramebuffersEXT(1, &fboId); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, depthTextureId, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, colourTextureId, 0); #ifdef DEBUG printFramebufferInfo(); #endif bool status = checkFramebufferStatus(); if(!status) fboUsed = false; #ifdef DEBUG cout << "Creating Second Framebuffer" <<endl; #endif glGenFramebuffersEXT(1, &fboIdFinal); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboIdFinal); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, finalTextureId, 0); glGenRenderbuffersEXT(1, &rboIdFinal); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rboIdFinal); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, ofGetWidth(), ofGetHeight()); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rboIdFinal); #ifdef DEBUG printFramebufferInfo(); #endif status = checkFramebufferStatus(); if(!status) fboUsed = false; glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); }
bool FboCubeSurface::begin(int face) { //qDebug() << "calling bindcubemapface for face" << face; if (checkFramebufferStatus(context())) return false; glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, cubemap, 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthbuffer); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); return true; }
MultiSampleRenderTarget::MultiSampleRenderTarget(unsigned int width, unsigned int height) { width_ = width; height_ = height; // create a texture object glGenTextures(1, &textureID_); glBindTexture(GL_TEXTURE_2D, textureID_); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); // automatic mipmap generation included in OpenGL v1.4 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glBindTexture(GL_TEXTURE_2D, 0); // rebind default texture? // create a framebuffer object, you need to delete them when program exits. glGenFramebuffersEXT(1, &frameBufferID_); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferID_); // 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. glGenRenderbuffersEXT(1, &depthBufferID_); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBufferID_); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); // attach a texture to FBO color attachement point glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, textureID_, 0); // attach a renderbuffer to depth attachment point glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthBufferID_); //@ disable color buffer if you don't attach any color buffer image, //@ for example, rendering depth buffer only to a texture. //@ Otherwise, glCheckFramebufferStatusEXT will not be complete. //glDrawBuffer(GL_NONE); //glReadBuffer(GL_NONE); // check FBO status bool status = checkFramebufferStatus(); if(!status) { throw std::runtime_error("Invalid framebuffer configuration"); exit(-1); } glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); }
bool initFBO() { // Si l'extension est presente if(!GLEW_EXT_framebuffer_object) { std::cerr<<"LES FBO ne sont pas supportés !"<<std::endl; exit(0); } checkFramebufferStatus(); return true; }
void initRS() { glEnable(GL_TEXTURE_2D); // create a texture object glGenTextures(1, &textureId); glBindTexture(GL_TEXTURE_2D, textureId); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glBindTexture(GL_TEXTURE_2D, 0); // create a framebuffer object, you need to delete them when program exits. glGenFramebuffers(1, &fboId); glBindFramebuffer(GL_FRAMEBUFFER, fboId); // 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. glGenRenderbuffers(1, &rboId); glBindRenderbuffer(GL_RENDERBUFFER, rboId); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, TEXTURE_WIDTH, TEXTURE_HEIGHT); glBindRenderbuffer(GL_RENDERBUFFER, 0); // attach a texture to FBO color attachement point glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0); // attach a renderbuffer to depth attachment point glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboId); // check FBO status bool status = checkFramebufferStatus(); if(!status) fboUsed = false; glBindFramebuffer(GL_FRAMEBUFFER, 0); }
void QOpenGLFramebufferObjectPrivate::initTexture(GLenum target, GLenum internal_format, const QSize &size, bool mipmap) { QOpenGLContext *ctx = QOpenGLContext::currentContext(); GLuint texture = 0; funcs.glGenTextures(1, &texture); funcs.glBindTexture(target, texture); funcs.glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); funcs.glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); funcs.glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); funcs.glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); funcs.glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); if (mipmap) { int width = size.width(); int height = size.height(); int level = 0; while (width > 1 || height > 1) { width = qMax(1, width >> 1); height = qMax(1, height >> 1); ++level; funcs.glTexImage2D(target, level, internal_format, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); } } funcs.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, texture, 0); QT_CHECK_GLERROR(); funcs.glBindTexture(target, 0); valid = checkFramebufferStatus(ctx); if (valid) texture_guard = new QOpenGLSharedResourceGuard(ctx, texture, freeTextureFunc); else funcs.glDeleteTextures(1, &texture); }
/*! This resizes a framebuffer object that already exists and has textures already associated with it. */ void FrameBuffer::resizeExistingFBO(int newWidth, int newHeight) { GLint format; // Resize the color buffers for (int i = 0; i < m_maxColorBuffers; i++) { if (m_colorIDs[i] > 0) { glBindTexture(m_colorType[i], m_colorIDs[i]); glGetTexLevelParameteriv(m_colorType[i], 0, GL_TEXTURE_INTERNAL_FORMAT, &format); if (m_colorType[i] == GL_TEXTURE_2D) glTexImage2D(GL_TEXTURE_2D, 0, format, newWidth, newHeight, 0, GL_RGBA, GL_FLOAT, NULL); else if (m_colorType[i] == GL_TEXTURE_2D_ARRAY_EXT) glTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0, format, newWidth, newHeight, m_depth, 0, GL_RGBA, GL_FLOAT, NULL); } } if (m_depthID > 0) { glBindTexture(GL_TEXTURE_2D, m_depthID); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format); glTexImage2D(GL_TEXTURE_2D, 0, format, newWidth, newHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); } if (m_stencilID > 0) { printf("**** Error: Called FrameBuffer::resizeExistingFBO() on FBO with stencil\n"); printf(" buffer. Resizing FBOs with stencil bufs is not supported yet!\n"); exit(0); } glBindTexture(GL_TEXTURE_2D, 0); m_width = newWidth; m_height = newHeight; checkFramebufferStatus(1); }
void FBO::generate() { // create a texture object for the depthmap glGenTextures(1, &m_iTexDepthId); glBindTexture(m_eTextureType, m_iTexDepthId); glTexParameterf(m_eTextureType, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(m_eTextureType, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(m_eTextureType, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(m_eTextureType, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(m_eTextureType, GL_GENERATE_MIPMAP, GL_TRUE); glTexImage2D(m_eTextureType, 0, GL_DEPTH_COMPONENT, m_iWidth, m_iHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0); glBindTexture(m_eTextureType, 0); // create a texture object glGenTextures(1, &m_iTexId); glBindTexture(m_eTextureType, m_iTexId); glTexParameterf(m_eTextureType, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(m_eTextureType, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(m_eTextureType, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(m_eTextureType, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(m_eTextureType, GL_GENERATE_MIPMAP, GL_TRUE); glTexImage2D(m_eTextureType, 0, GL_RGBA8, m_iWidth, m_iHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glBindTexture(m_eTextureType, 0); glGenFramebuffersEXT(1, &m_iId); activate(); // attach a texture to FBO color attachement point glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, m_eTextureType, m_iTexDepthId, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, m_eTextureType, m_iTexId, 0); desactivate(); //Check FBO status if(!checkFramebufferStatus()) std::cerr<<"ERROR : FBO creation Fail "<<std::endl; //Color + Depth m_iType = 2; }
/** * @brief Initialize framebuffer object */ bool ParticleSystem::initFBO() { colAttachID[0] = initTex2D(wWidth, wHeight); glGenRenderbuffers(1, &dboID); glBindRenderbuffer(GL_RENDERBUFFER, dboID); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, wWidth, wHeight); glGenFramebuffers(1, &fboID); glBindFramebuffer(GL_FRAMEBUFFER, fboID); glActiveTexture(GL_TEXTURE0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colAttachID[0], 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, dboID); checkFramebufferStatus(); glBindFramebuffer(GL_FRAMEBUFFER, 0); return false; }
void Fluids::advect(float dt, int b, GLuint& d, GLuint d0, GLuint u, GLuint v) { setFrameBuffer(frambuffer_); do_advect_->setFloat("dt", dt); do_advect_->apply(); setRenderTexture(d); glDrawBuffer(GL_COLOR_ATTACHMENT0); checkFramebufferStatus(); //assert(do_advect_->samplers_.count("density") && do_advect_->samplers_.count("velocity")); glEnable(GL_TEXTURE_2D); set_texture_for_sampler(do_advect_, "d0", 0, d0); set_texture_for_sampler(do_advect_, "u", 1, u); set_texture_for_sampler(do_advect_, "v", 2, v); draw_quad(1); set_boundaries(b, p_prev_, d); glActiveTexture(GL_TEXTURE0 + 2); glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE0 + 1); glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); glUseProgram(0); setRenderTexture(0,0); }
void FboCubeSurface::init() { // check context QOpenGLContext* ctxt = QOpenGLContext::currentContext(); if ( ! ctxt) { qDebug() << "FboCubeSurface: no current context"; return; } initializeOpenGLFunctions(); //glActiveTexture(GL_TEXTURE0); glGenTextures(1, &cubemap); glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap); glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); // set textures // QImage one(QString("/home/armin/Pictures/one.png")); // QImage two(QString("/home/armin/Pictures/two.png")); // QImage three(QString("/home/armin/Pictures/three.png")); // QImage four(QString("/home/armin/Pictures/four.png")); // QImage five(QString("/home/armin/Pictures/five.png")); // QImage six(QString("/home/armin/Pictures/six.png")); // glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + 0, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, one.bits()); // glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + 1, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, two.bits()); // glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + 2, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, three.bits()); // glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + 3, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, four.bits()); // glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + 4, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, five.bits()); // glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + 5, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, six.bits()); for (int i = 0; i < 6; ++i) glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); // create the fbo glGenFramebuffers(1, &framebuffer); glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); // create the uniform depth buffer glGenRenderbuffers(1, &depthbuffer); glBindRenderbuffer(GL_RENDERBUFFER, depthbuffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height); //glBindRenderbuffer(GL_RENDERBUFFER, 0); // attach it glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthbuffer); // attach only the +X cubemap texture (for completeness) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X, cubemap, 0); // this function just checks for framebuffer completeness and throws and exception if it’s not happy checkFramebufferStatus(ctxt); // disable glBindRenderbuffer(GL_RENDERBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindTexture(GL_TEXTURE_CUBE_MAP, 0); }
// final result in x void Fluids::diffuse(float dt, int b, GLuint& temp_x, GLuint& x, GLuint& x0, const bool method1/* = false*/) { setFrameBuffer(frambuffer_); glsl_program* prog = method1 ? do_diffuse_method1_ : do_diffuse_simple_; if(method1) { setRenderTexture(x); glDrawBuffers(1, drawbuffers); checkFramebufferStatus(); do_copy_->apply(); set_texture_for_sampler(do_copy_, "tex", 0, x0); draw_quad(1); } prog->setFloat("dt", dt); prog->apply(); glEnable(GL_TEXTURE_2D); for(int i=0; i< NUM_OP; ++i) { // 2 different ways: both are a bit incorrect though :-) if(method1) setRenderTexture(temp_x); else setRenderTexture(x); glDrawBuffers(1, drawbuffers); checkFramebufferStatus(); if(method1) { // use temp texture for processing //set_texture_for_sampler(prog, "x", 0, x); //set_texture_for_sampler(prog, "x0", 1, x0); set_texture_for_sampler(prog, "x0", 1, x); draw_quad(1); swap(temp_x, x); } else { // change do_diffuse shader, so that only reads from x0 are done even at places where we read from x set_texture_for_sampler(prog, "x0", 0, x0); draw_quad(1); //glBindTexture(GL_TEXTURE_2D, 0); set_boundaries(b, x0, x); prog->setFloat("dt", dt); prog->apply(); swap(x0, x); } } //if(method1 ) // swap(x0, x); setRenderTexture(0,0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); glUseProgram(0); #undef METHOD1 }
void capture_start(const char* filename) { av_register_all(); AVOutputFormat * fmt = av_guess_format("mp4", NULL, NULL); assert(fmt); oc = avformat_alloc_context(); assert(oc); oc->oformat = fmt; snprintf(oc->filename, sizeof(oc->filename), "%s", filename); // add video stream video_st = av_new_stream(oc, 0); assert(video_st); c = video_st->codec; c->codec_id = fmt->video_codec; c->codec_type = AVMEDIA_TYPE_VIDEO; c->bit_rate = 4000000; c->width = SCREEN_WIDTH; c->height = SCREEN_HEIGHT; c->time_base.den = STREAM_FRAME_RATE; c->time_base.num = 1; c->gop_size = STREAM_FRAME_RATE; /* emit one intra frame every twelve frames at most */ c->pix_fmt = PIX_FMT_YUV420P; c->flags |= CODEC_FLAG_GLOBAL_HEADER; av_dump_format(oc, 0, oc->filename, 1); /* now that all the parameters are set, we can open the video codec and allocate the necessary encode buffers */ /* find the video encoder */ AVCodec *codec = avcodec_find_encoder(c->codec_id); assert(codec); /* open the codec */ if (avcodec_open(c, codec) < 0) { fprintf(stderr, "capture.cpp:could not open codec\n"); exit(1); } /* allocate output buffer */ video_outbuf_size = 200000; video_outbuf = (uint8_t*)av_malloc(video_outbuf_size); /* allocate the encoded raw picture */ picture = avcodec_alloc_frame(); int size = c->width * c->height; picture->data[0] = (uint8_t*)av_malloc((size * 3) / 2); /* size for YUV 420 */ picture->data[1] = picture->data[0] + size; picture->data[2] = picture->data[1] + size / 4; picture->linesize[0] = c->width; picture->linesize[1] = c->width / 2; picture->linesize[2] = c->width / 2; img_convert_ctx = sws_getContext( c->width, c->height, PIX_FMT_BGRA, // <- from c->width, c->height, c->pix_fmt, // <- to SWS_BICUBIC, NULL, NULL, NULL); if (img_convert_ctx == NULL) { fprintf(stderr, "capture.cpp:Cannot initialize the conversion context\n"); exit(1); } buffer = (uint8_t*)av_malloc(4*c->width*c->height); /* open the output file, if needed */ #ifndef AVIO_FLAG_WRITE #define AVIO_FLAG_WRITE 2 #endif if (avio_open(&oc->pb, oc->filename, AVIO_FLAG_WRITE) < 0) { fprintf(stderr, "capture.cpp:Could not open %s\n", filename); exit(1); } /* write the stream header, if any */ av_write_header(oc); frame_count=0; glGenFramebuffers(1, &pfbo); glBindFramebuffer(GL_FRAMEBUFFER, pfbo); glGenRenderbuffers(1, &prbo); glBindRenderbuffer(GL_RENDERBUFFER, prbo); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, c->width, c->height); glBindRenderbuffer(GL_RENDERBUFFER, 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, prbo); checkFramebufferStatus(); glBindFramebuffer(GL_FRAMEBUFFER, 0); printf("capture.cpp: Movie capture started: %s\n", filename); }
void Fluids::project(float dt, GLuint& u, GLuint& v, GLuint& p, GLuint& div) { setFrameBuffer(frambuffer_); // stage 1 do_project_a_->apply(); setRenderTexture(div,0); setRenderTexture(p,1); setRenderTexture(velocity_accum_u0t_,2); setRenderTexture(velocity_accum_v0t_,3); glDrawBuffers(4, drawbuffers); checkFramebufferStatus(); glEnable(GL_TEXTURE_2D); set_texture_for_sampler(do_project_a_, "u", 0, u); set_texture_for_sampler(do_project_a_, "v", 1, v); draw_quad(1); setRenderTexture(0,0); setRenderTexture(0,1); setRenderTexture(0,2); setRenderTexture(0,3); glActiveTexture(GL_TEXTURE0 + 3); glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE0 + 2); glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE0 + 1); glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); set_boundaries(0, p_prev_, div); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); setRenderTexture(0,0); // stage 2 do_project_b_->apply(); for(int i=0; i< NUM_OP; ++i) { setRenderTexture(p_prev_,0); glDrawBuffers(1, drawbuffers); checkFramebufferStatus(); set_texture_for_sampler(do_project_b_, "div", 0, div); set_texture_for_sampler(do_project_b_, "p", 1, p); draw_quad(1); swap(p_prev_, p); // p has result set_boundaries(0, p_prev_, p); do_project_b_->apply(); } setRenderTexture(0,0); // stage 3 do_project_c_->apply(); setRenderTexture(u,0); setRenderTexture(v,1); glDrawBuffers(2, drawbuffers); checkFramebufferStatus(); set_texture_for_sampler(do_project_c_, "p", 0, p); set_texture_for_sampler(do_project_c_, "u", 1, velocity_accum_u0t_); // same as u set_texture_for_sampler(do_project_c_, "v", 2, velocity_accum_v0t_); // same as v // we need those to make A = A + B assignment draw_quad(1); setRenderTexture(0,0); setRenderTexture(0,1); set_boundaries(1, p_prev_, u); set_boundaries(2, p_prev_, v); setRenderTexture(0,0); glActiveTexture(GL_TEXTURE0 + 2); glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE0 + 1); glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); glUseProgram(0); setRenderTexture(0,0); setRenderTexture(1,0); setRenderTexture(2,0); setRenderTexture(3,0); }
void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, QGLFramebufferObject::Attachment attachment, GLenum texture_target, GLenum internal_format, GLint samples) { QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext()); fbo_guard.setContext(ctx); bool ext_detected = (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject); if (!ext_detected || (ext_detected && !qt_resolve_framebufferobject_extensions(ctx))) return; size = sz; target = texture_target; // texture dimensions QT_RESET_GLERROR(); // reset error state GLuint fbo = 0; glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo); fbo_guard.setId(fbo); glDevice.setFBO(q, attachment); QT_CHECK_GLERROR(); // init texture if (samples == 0) { glGenTextures(1, &texture); glBindTexture(target, texture); glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); #ifndef QT_OPENGL_ES glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); #else glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); #endif glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target, texture, 0); QT_CHECK_GLERROR(); valid = checkFramebufferStatus(); glBindTexture(target, 0); color_buffer = 0; } else { GLint maxSamples; glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples); samples = qBound(1, int(samples), int(maxSamples)); glGenRenderbuffers(1, &color_buffer); glBindRenderbuffer(GL_RENDERBUFFER_EXT, color_buffer); if (glRenderbufferStorageMultisampleEXT) { glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, internal_format, size.width(), size.height()); } else { samples = 0; glRenderbufferStorage(GL_RENDERBUFFER_EXT, internal_format, size.width(), size.height()); } glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, color_buffer); QT_CHECK_GLERROR(); valid = checkFramebufferStatus(); if (valid) glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_SAMPLES_EXT, &samples); } if (attachment == QGLFramebufferObject::CombinedDepthStencil && (QGLExtensions::glExtensions() & QGLExtensions::PackedDepthStencil)) { // depth and stencil buffer needs another extension glGenRenderbuffers(1, &depth_stencil_buffer); Q_ASSERT(!glIsRenderbuffer(depth_stencil_buffer)); glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_stencil_buffer); Q_ASSERT(glIsRenderbuffer(depth_stencil_buffer)); if (samples != 0 && glRenderbufferStorageMultisampleEXT) glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_DEPTH24_STENCIL8_EXT, size.width(), size.height()); else glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, size.width(), size.height()); GLint i = 0; glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i); glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_stencil_buffer); glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_stencil_buffer); fbo_attachment = QGLFramebufferObject::CombinedDepthStencil; valid = checkFramebufferStatus(); if (!valid) glDeleteRenderbuffers(1, &depth_stencil_buffer); } else if (attachment == QGLFramebufferObject::Depth || attachment == QGLFramebufferObject::CombinedDepthStencil) { glGenRenderbuffers(1, &depth_stencil_buffer); Q_ASSERT(!glIsRenderbuffer(depth_stencil_buffer)); glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_stencil_buffer); Q_ASSERT(glIsRenderbuffer(depth_stencil_buffer)); if (samples != 0 && glRenderbufferStorageMultisampleEXT) { #ifdef QT_OPENGL_ES #define GL_DEPTH_COMPONENT16 0x81A5 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_DEPTH_COMPONENT16, size.width(), size.height()); #else glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_DEPTH_COMPONENT, size.width(), size.height()); #endif } else { #ifdef QT_OPENGL_ES #define GL_DEPTH_COMPONENT16 0x81A5 glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, size.width(), size.height()); #else glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, size.width(), size.height()); #endif } GLint i = 0; glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i); glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_stencil_buffer); fbo_attachment = QGLFramebufferObject::Depth; valid = checkFramebufferStatus(); if (!valid) glDeleteRenderbuffers(1, &depth_stencil_buffer); } else { fbo_attachment = QGLFramebufferObject::NoAttachment; } glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo); if (!valid) { if (color_buffer) glDeleteRenderbuffers(1, &color_buffer); else glDeleteTextures(1, &texture); glDeleteFramebuffers(1, &fbo); fbo_guard.setId(0); } QT_CHECK_GLERROR(); format.setTextureTarget(target); format.setSamples(int(samples)); format.setAttachment(fbo_attachment); format.setInternalTextureFormat(internal_format); }
void setup(){ // ------------- object object1 = new GLObject( ); object1->draw_mode = GL_TRIANGLE_STRIP; object1->nVert = 4; object1->buffs[0].setup(0,2,GL_FALSE,&vertexes[0][0],'v'); // vertexes object1->init(); // ------------- shader for rendering geometry shader_pre=new Shader(); //shader_pre->init( "shaders/afine2D_vert.c", "shaders/sphere_frag.c" ); shader_pre->init( "shaders/afine2D_vert.c", "shaders/sphereHoled_frag.c" ); //randf( -1.0, 1.0 ); for( int i=0; i<nspheres; i++ ){ int ii = i << 2; spheres[ii+0] = randf( -1.0, 1.0 ); spheres[ii+1] = randf( -1.0, 1.0 ); spheres[ii+2] = randf( -1.0, 1.0 ); //spheres[ii+0] = i*0.1-1.0; //spheres[ii+1] = i*0.1-1.0; //spheres[ii+2] = +i*5 + 0.0; spheres[ii+3] = 0.5; } randf( -0.5, 0.5 ); for( int i=0; i<nholes; i++ ){ int ii = i << 2; holes[ii+0] = randf( -0.5, 0.5 ); holes[ii+1] = randf( -0.5, 0.5 ); holes[ii+2] = randf( -0.5, 0.5 ); holes[ii+3] = 0.3; } Vec3f light_dir_; light_dir_.set( -1, -1, 2 ); light_dir_.normalize(); light_dir[0]=light_dir_.x; light_dir[1]=light_dir_.y; light_dir[2]=light_dir_.z; resolution[0] = (float)WIDTH; resolution[1] = (float)HEIGHT; glUseProgram(shader_pre->shaderprogram); GLuint uloc; uloc = glGetUniformLocation( shader_pre->shaderprogram, "resolution" ); glUniform2fv(uloc, 1, resolution ); uloc = glGetUniformLocation( shader_pre->shaderprogram, "camPos" ); glUniform3fv(uloc, 1, camPos ); uloc = glGetUniformLocation( shader_pre->shaderprogram, "camMat" ); glUniformMatrix3fv( uloc, 1, false, camMat ); uloc = glGetUniformLocation( shader_pre->shaderprogram, "sphere" ); glUniform4fv(uloc, 1, sphere ); uloc = glGetUniformLocation( shader_pre->shaderprogram, "light_dir" ); glUniform3fv(uloc, 1, light_dir ); uloc = glGetUniformLocation( shader_pre->shaderprogram, "afineMat" ); glUniformMatrix2fv(uloc, 1, GL_FALSE, afineMat ); uloc = glGetUniformLocation( shader_pre->shaderprogram, "origin" ); glUniform2fv (uloc, 1, origin ); // ------------- shader for blitting from texture shader_post=new Shader(); shader_post->init( "shaders/plain_vert.c", "shaders/SSAO_frag.c" ); resolution[0] = (float)WIDTH; resolution[1] = (float)HEIGHT; glUseProgram(shader_post->shaderprogram); uloc = glGetUniformLocation( shader_post->shaderprogram, "resolution" ); glUniform2fv(uloc, 1, resolution ); // ------------- texture glGenTextures(1, &texRGB ); glBindTexture(GL_TEXTURE_2D, texRGB ); glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, WIDTH, HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); //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_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glGenTextures(1, &texZ); glBindTexture(GL_TEXTURE_2D, texZ); glTexImage2D(GL_TEXTURE_2D, 0,GL_DEPTH_COMPONENT, WIDTH, HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); //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_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // ------------- frameBuffer glGenFramebuffers(1, &FramebufferName); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName); // The depth buffer glGenRenderbuffers(1, &depthrenderbuffer); glBindRenderbuffer(GL_RENDERBUFFER, depthrenderbuffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, WIDTH, HEIGHT ); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthrenderbuffer); // Set "renderedTexture" as our colour attachement #0 glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, texZ, 0 ); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texRGB, 0 ); GLenum DrawBuffers[2] = {GL_DEPTH_ATTACHMENT, GL_COLOR_ATTACHMENT0}; glDrawBuffers(2, DrawBuffers); /* glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, texZ, 0 ); GLenum DrawBuffers[1] = {GL_DEPTH_ATTACHMENT}; glDrawBuffers(1, DrawBuffers); */ if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE){ printf(" problem in FBO ! \n "); checkFramebufferStatus(); } }
int Lua_Framebuffer_new(lua_State *L) { Lua_Image *ptr; unsigned int width, height, percision, alpha; GLint current_fbo; GLenum internal, format; if(!supported.FBO) return 0; width = luaL_checkinteger(L, 1); height = luaL_checkinteger(L, 2); percision = lua_tointeger(L, 3); alpha = lua_toboolean(L, 4); if(percision == 32) { internal = alpha ? GL_RGBA32F_ARB : GL_RGB32F_ARB; format = GL_FLOAT; } else if(percision == 16) { internal = alpha ? GL_RGBA16F_ARB : GL_RGB16F_ARB; format = GL_FLOAT; } else { internal = alpha ? GL_RGBA : GL_RGB; format = GL_UNSIGNED_BYTE; } //save current fbo glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING_EXT, ¤t_fbo); ptr = lua_newuserdata(L, sizeof(Lua_Image)); ptr->w = width; ptr->h = height; // generate texture save target glGenTextures(1, &ptr->texture); glBindTexture(GL_TEXTURE_2D, ptr->texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //~ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); //~ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexImage2D(GL_TEXTURE_2D,0,internal,width,height,0,GL_RGBA,format,0); glBindTexture(GL_TEXTURE_2D, 0); // create framebuffer glGenFramebuffers_(1, &ptr->fbo); glBindFramebuffer_(GL_FRAMEBUFFER_EXT, ptr->fbo); glFramebufferTexture2D_(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, ptr->texture, 0); checkFramebufferStatus(); // unbind framebuffer glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, (GLuint)current_fbo); luaL_getmetatable(L, "scrupp.image"); lua_setmetatable(L, -2); return 1; }
void DeferredShader::init(Camera & camera) { GLsizei screenWidth = camera.getScreenWidth(); GLsizei screenHeight = camera.getScreenHeight(); std::cout << "Buffer dimensions : " << screenWidth << " x " << screenHeight << std::endl; // Init G-Buffer checkFramebufferEXTSupport(); // Create texture to store diffuse color data glGenTextures(1, &gbDiffuse); glBindTexture(GL_TEXTURE_2D, gbDiffuse); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, screenWidth, screenHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); std::cout << "GbDiffuse Tex : " << gbDiffuse << std::endl; // Create texture to store normal data glGenTextures(1, &gbNormal); glBindTexture(GL_TEXTURE_2D, gbNormal); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, screenWidth, screenHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); std::cout << "GbNormal Tex : " << gbNormal << std::endl; // Create texture to store specular data glGenTextures(1, &gbSpecular); glBindTexture(GL_TEXTURE_2D, gbSpecular); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, screenWidth, screenHeight, 0, // Specular data includes specular r,g,b and shininess component GL_RGBA, GL_UNSIGNED_BYTE, 0); std::cout << "GbSpecular Tex : " << gbSpecular << std::endl; // Create depth texture glGenTextures(1, &gbDepth); glBindTexture(GL_TEXTURE_2D, gbDepth); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, screenWidth, screenHeight, 0, // 24 bit depth texture format GL_DEPTH_COMPONENT, GL_FLOAT, 0); std::cout << "GbDepth Tex : " << gbDepth << std::endl; glBindTexture(GL_TEXTURE_2D, 0); // Create FBO glGenFramebuffersEXT(1, &fbo); checkGLErrors("Generate FBO"); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); checkGLErrors("Bind FBO"); std::cout << "FBO ID: " << fbo << std::endl; glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, gbDepth, 0); checkGLErrors("Attach depth renderbuffer to FBO"); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, gbDiffuse, 0); checkGLErrors("Attach diffuse texture to FBO"); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, gbNormal, 0); checkGLErrors("Attach normal texture to FBO"); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_TEXTURE_2D, gbSpecular, 0); checkGLErrors("Attach specular texture to FBO"); // Enable drawing for all color buffer attachments GLenum drawbuffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT}; glDrawBuffers(3, drawbuffers); checkFramebufferStatus(); // Load all shaders shaderManager.initShader(); }
void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSize &sz, QOpenGLFramebufferObject::Attachment attachment, GLenum texture_target, GLenum internal_format, GLint samples, bool mipmap) { QOpenGLContext *ctx = QOpenGLContext::currentContext(); funcs.initializeOpenGLFunctions(); if (!funcs.hasOpenGLFeature(QOpenGLFunctions::Framebuffers)) return; // Fall back to using a normal non-msaa FBO if we don't have support for MSAA if (!funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample) || !funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit)) { samples = 0; } #ifndef QT_OPENGL_ES_2 GLint maxSamples; funcs.glGetIntegerv(GL_MAX_SAMPLES, &maxSamples); samples = qBound(0, int(samples), int(maxSamples)); #endif size = sz; target = texture_target; // texture dimensions QT_RESET_GLERROR(); // reset error state GLuint fbo = 0; funcs.glGenFramebuffers(1, &fbo); funcs.glBindFramebuffer(GL_FRAMEBUFFER, fbo); GLuint color_buffer = 0; QT_CHECK_GLERROR(); // init texture if (samples == 0) { initTexture(texture_target, internal_format, size, mipmap); } else { mipmap = false; funcs.glGenRenderbuffers(1, &color_buffer); funcs.glBindRenderbuffer(GL_RENDERBUFFER, color_buffer); funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, internal_format, size.width(), size.height()); funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color_buffer); QT_CHECK_GLERROR(); valid = checkFramebufferStatus(ctx); if (valid) { funcs.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples); color_buffer_guard = new QOpenGLSharedResourceGuard(ctx, color_buffer, freeRenderbufferFunc); } } format.setTextureTarget(target); format.setSamples(int(samples)); format.setInternalTextureFormat(internal_format); format.setMipmap(mipmap); initAttachments(ctx, attachment); funcs.glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_func()->current_fbo); if (valid) { fbo_guard = new QOpenGLSharedResourceGuard(ctx, fbo, freeFramebufferFunc); } else { if (color_buffer_guard) { color_buffer_guard->free(); color_buffer_guard = 0; } else if (texture_guard) { texture_guard->free(); texture_guard = 0; } funcs.glDeleteFramebuffers(1, &fbo); } QT_CHECK_GLERROR(); }
void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpenGLFramebufferObject::Attachment attachment) { int samples = format.samples(); // free existing attachments if (depth_buffer_guard) { funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); depth_buffer_guard->free(); } if (stencil_buffer_guard) { funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); if (stencil_buffer_guard != depth_buffer_guard) stencil_buffer_guard->free(); } depth_buffer_guard = 0; stencil_buffer_guard = 0; GLuint depth_buffer = 0; GLuint stencil_buffer = 0; // In practice, a combined depth-stencil buffer is supported by all desktop platforms, while a // separate stencil buffer is not. On embedded devices however, a combined depth-stencil buffer // might not be supported while separate buffers are, according to QTBUG-12861. if (attachment == QOpenGLFramebufferObject::CombinedDepthStencil && funcs.hasOpenGLExtension(QOpenGLExtensions::PackedDepthStencil)) { // depth and stencil buffer needs another extension funcs.glGenRenderbuffers(1, &depth_buffer); funcs.glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer); Q_ASSERT(funcs.glIsRenderbuffer(depth_buffer)); if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_DEPTH24_STENCIL8, size.width(), size.height()); else funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, size.width(), size.height()); stencil_buffer = depth_buffer; funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_buffer); funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencil_buffer); valid = checkFramebufferStatus(ctx); if (!valid) { funcs.glDeleteRenderbuffers(1, &depth_buffer); stencil_buffer = depth_buffer = 0; } } if (depth_buffer == 0 && (attachment == QOpenGLFramebufferObject::CombinedDepthStencil || (attachment == QOpenGLFramebufferObject::Depth))) { funcs.glGenRenderbuffers(1, &depth_buffer); funcs.glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer); Q_ASSERT(funcs.glIsRenderbuffer(depth_buffer)); if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) { if (ctx->isOpenGLES()) { if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_DEPTH_COMPONENT24, size.width(), size.height()); else funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_DEPTH_COMPONENT16, size.width(), size.height()); } else { funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_DEPTH_COMPONENT, size.width(), size.height()); } } else { if (ctx->isOpenGLES()) { if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) { funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, size.width(), size.height()); } else { funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, size.width(), size.height()); } } else { funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.width(), size.height()); } } funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_buffer); valid = checkFramebufferStatus(ctx); if (!valid) { funcs.glDeleteRenderbuffers(1, &depth_buffer); depth_buffer = 0; } } if (stencil_buffer == 0 && (attachment == QOpenGLFramebufferObject::CombinedDepthStencil)) { funcs.glGenRenderbuffers(1, &stencil_buffer); funcs.glBindRenderbuffer(GL_RENDERBUFFER, stencil_buffer); Q_ASSERT(funcs.glIsRenderbuffer(stencil_buffer)); #ifdef QT_OPENGL_ES GLenum storage = GL_STENCIL_INDEX8; #else GLenum storage = ctx->isOpenGLES() ? GL_STENCIL_INDEX8 : GL_STENCIL_INDEX; #endif if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, storage, size.width(), size.height()); else funcs.glRenderbufferStorage(GL_RENDERBUFFER, storage, size.width(), size.height()); funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencil_buffer); valid = checkFramebufferStatus(ctx); if (!valid) { funcs.glDeleteRenderbuffers(1, &stencil_buffer); stencil_buffer = 0; } } // The FBO might have become valid after removing the depth or stencil buffer. valid = checkFramebufferStatus(ctx); if (depth_buffer && stencil_buffer) { fbo_attachment = QOpenGLFramebufferObject::CombinedDepthStencil; } else if (depth_buffer) { fbo_attachment = QOpenGLFramebufferObject::Depth; } else { fbo_attachment = QOpenGLFramebufferObject::NoAttachment; } if (valid) { if (depth_buffer) depth_buffer_guard = new QOpenGLSharedResourceGuard(ctx, depth_buffer, freeRenderbufferFunc); if (stencil_buffer) { if (stencil_buffer == depth_buffer) stencil_buffer_guard = depth_buffer_guard; else stencil_buffer_guard = new QOpenGLSharedResourceGuard(ctx, stencil_buffer, freeRenderbufferFunc); } } else { if (depth_buffer) funcs.glDeleteRenderbuffers(1, &depth_buffer); if (stencil_buffer && depth_buffer != stencil_buffer) funcs.glDeleteRenderbuffers(1, &stencil_buffer); } QT_CHECK_GLERROR(); format.setAttachment(fbo_attachment); }
/** * Sets up and binds the FBO. * 1: Set element according to fields. * 2: Let children manipulate setup. * 3: Allocate/deallocate if need be. * 4: Set element according to finished Fbo */ void SoXipFbo::GLRender(SoGLRenderAction* action) { //SoDebugError::postInfo(__FUNCTION__, "(1) in mod out (%d %d %d)", mFboIn.isDirty, mFboMod.isDirty, mFboOut.isDirty); if (autoSize.getValue()) { const SbVec2s &viewportSize = action->getViewportRegion().getViewportSizePixels(); if (viewportSize != SbVec2s(width.getValue(), height.getValue())) { SoDebugError::postInfo("SoXipFbo", "Autosetting FBO size to (%d, %d)", viewportSize[0], viewportSize[1]); width.setValue(viewportSize[0]); height.setValue(viewportSize[1]); mNeedsUpdate = true; } } // Can't use sensors if fields are changed while traversing tree, such as by parent size changing if (width.getValue() != mFboIn.width || height.getValue() != mFboIn.height) mNeedsUpdate = true; if (mNeedsUpdate) { // Check number of buffers checkMaxNumBuffers(); // Dealloc if allocated if (mIsAllocated) deallocate(); mFboIn.clear(); mFboMod.clear(); mFboOut.clear(); int currUnit = SoXipMultiTextureElement::getCurrentUnit(action->getState()); int freeUnit = SoXipMultiTextureElement::getFreeUnit(action->getState()); SoXipMultiTextureElement::setUnit(action->getState(), freeUnit); allocateFbo(); SoXipMultiTextureElement::setUnit(action->getState(), currUnit); //SoDebugError::postInfo(__FUNCTION__, "Allocated new Fbo (dirty)"); mNeedsUpdate = false; } else mFboIn.isDirty = false; mFboMod.isDirty = false; //SoDebugError::postInfo(__FUNCTION__, "(2) in mod out (%d %d %d)", mFboIn.isDirty, mFboMod.isDirty, mFboOut.isDirty); // Send to element and render children to allow modification mFboIn.isOpen = true; SoXipFboElement::set(action->getState(), this, mFboIn); SoXipFboElement::bind(action->getState(), this); int currentFbo; glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, ¤tFbo); if (!glIsFramebufferEXT(mFboIn.fboHandle) || mFboIn.fboHandle != currentFbo) { SoDebugError::postWarning("SoXipFbo", "Error in the setup, fbo not guaranteed to be bound"); mNeedsUpdate = true; return; } ////////// /// Traverse children SoGroup::GLRender(action); /// Traverse children ////////// FboSetup * fbo = SoXipFboElement::getActive(action->getState(), this); // Detect any change in fbo handle if (mFboIn.fboHandle != fbo->fboHandle) SoDebugError::postWarning("SoXipFbo", "Keep Fbo bound during traversal (%d %d)", mFboIn.fboHandle, fbo->fboHandle); //SoDebugError::postInfo(__FUNCTION__, "(3) in mod out (%d %d %d)", mFboIn.isDirty, mFboMod.isDirty, mFboOut.isDirty); // Reflect changes if change since last run if (mFboMod != *fbo) { mFboMod = *fbo; mFboOut = *fbo; int currUnit = SoXipMultiTextureElement::getCurrentUnit(action->getState()); int freeUnit = SoXipMultiTextureElement::getFreeUnit(action->getState()); SoXipMultiTextureElement::setUnit(action->getState(), freeUnit); processColorMods(); processDepthMods(); SoXipMultiTextureElement::setUnit(action->getState(), currUnit); mErrorInSetup = false; } else mFboOut.isDirty = false; //SoDebugError::postInfo(__FUNCTION__, "(4) in mod out (%d %d %d)", mFboIn.isDirty, mFboMod.isDirty, mFboOut.isDirty); SoXipDrawBuffersElement::set(action->getState(), this, mFboOut.numColorAttachments); // Everything is now attached so test completeness if (!mErrorInSetup) mFboOut.isComplete = checkFramebufferStatus(); if (!mFboOut.isComplete) mErrorInSetup = true; // Activate FBO element (also sets draw buffer element) mFboOut.isOpen = false; SoXipFboElement::set(action->getState(), this, mFboOut); //SoDebugError::postInfo(__FUNCTION__, "(5) in mod out (%d %d %d)", mFboIn.isDirty, mFboMod.isDirty, mFboOut.isDirty); if (!mFboOut.isComplete) SoXipDrawBuffersElement::set(action->getState(), this, 0); }