bool StGLStereoFrameBuffer::init(StGLContext& theCtx, const GLsizei theTextureSizeX, const GLsizei theTextureSizeY, const bool theNeedDepthBuffer) { // release current objects release(theCtx); if(theCtx.arbFbo == NULL) { return false; } // create the textures if(!StGLStereoTexture::initTrash(theCtx, theTextureSizeX, theTextureSizeY)) { release(theCtx); return false; } const GLuint aFboBakDraw = theCtx.stglFramebufferDraw(); const GLuint aFboBakRead = theCtx.stglFramebufferRead(); theCtx.stglBindFramebuffer(StGLFrameBuffer::NO_FRAMEBUFFER); const GLint aDepthFormat = theCtx.isGlGreaterEqual(3, 0) ? GL_DEPTH24_STENCIL8 : GL_DEPTH_COMPONENT16; if(theNeedDepthBuffer) { theCtx.arbFbo->glGenRenderbuffers(2, myGLDepthRBIds); theCtx.arbFbo->glBindRenderbuffer(GL_RENDERBUFFER, myGLDepthRBIds[StGLStereoTexture::LEFT_TEXTURE]); theCtx.arbFbo->glRenderbufferStorage(GL_RENDERBUFFER, aDepthFormat, theTextureSizeX, theTextureSizeY); } // build FBOs theCtx.arbFbo->glGenFramebuffers(2, myGLFBufferIds); theCtx.stglBindFramebuffer(myGLFBufferIds[StGLStereoTexture::LEFT_TEXTURE]); // bind left texture to left FBO as color buffer theCtx.arbFbo->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, StGLStereoTexture::myTextures[StGLStereoTexture::LEFT_TEXTURE].getTextureId(), 0); if(theNeedDepthBuffer) { // bind left render buffer to left FBO as depth buffer theCtx.arbFbo->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, myGLDepthRBIds[StGLStereoTexture::LEFT_TEXTURE]); } bool isOk = theCtx.arbFbo->glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE; theCtx.arbFbo->glBindRenderbuffer(GL_RENDERBUFFER, StGLFrameBuffer::NO_RENDERBUFFER); if(!isOk) { release(theCtx); theCtx.stglBindFramebufferDraw(aFboBakDraw); theCtx.stglBindFramebufferRead(aFboBakRead); return false; } theCtx.stglBindFramebuffer(StGLFrameBuffer::NO_FRAMEBUFFER); if(theNeedDepthBuffer) { // create right RenderBuffer (will be used as depth buffer) theCtx.arbFbo->glBindRenderbuffer(GL_RENDERBUFFER, myGLDepthRBIds[StGLStereoTexture::RIGHT_TEXTURE]); theCtx.arbFbo->glRenderbufferStorage(GL_RENDERBUFFER, aDepthFormat, theTextureSizeX, theTextureSizeY); } theCtx.stglBindFramebuffer(myGLFBufferIds[StGLStereoTexture::RIGHT_TEXTURE]); // bind right texture to rights FBO as color buffer theCtx.arbFbo->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, StGLStereoTexture::myTextures[StGLStereoTexture::RIGHT_TEXTURE].getTextureId(), 0); if(theNeedDepthBuffer) { // bind right render buffer to right FBO as depth buffer theCtx.arbFbo->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, myGLDepthRBIds[StGLStereoTexture::RIGHT_TEXTURE]); } isOk = theCtx.arbFbo->glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE; theCtx.arbFbo->glBindRenderbuffer(GL_RENDERBUFFER, StGLFrameBuffer::NO_RENDERBUFFER); theCtx.stglBindFramebufferDraw(aFboBakDraw); theCtx.stglBindFramebufferRead(aFboBakRead); if(!isOk) { release(theCtx); return false; } ST_DEBUG_LOG("OpenGL, created StFrameBuffer(WxH= " + getSizeX() + 'x' + getSizeY() + ')'); // create vertices buffers to draw simple textured quad StArray<StGLVec4> aQuad(4); aQuad[0] = StGLVec4( 1.0f, -1.0f, 0.0f, 1.0f); // top-right aQuad[1] = StGLVec4( 1.0f, 1.0f, 0.0f, 1.0f); // bottom-right aQuad[2] = StGLVec4(-1.0f, -1.0f, 0.0f, 1.0f); // top-left aQuad[3] = StGLVec4(-1.0f, 1.0f, 0.0f, 1.0f); // bottom-left myVerticesBuf.init(theCtx, aQuad); StArray<StGLVec2> aQuadTC(4); aQuadTC[0] = StGLVec2(1.0f, 0.0f); aQuadTC[1] = StGLVec2(1.0f, 1.0f); aQuadTC[2] = StGLVec2(0.0f, 0.0f); aQuadTC[3] = StGLVec2(0.0f, 1.0f); myTexCoordBuf.init(theCtx, aQuadTC); myViewPortX = theTextureSizeX; myViewPortY = theTextureSizeY; return true; }