#ifndef NO_OPENGL3 ///See http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-14-render-to-texture/ #include "GLRenderToTexture.h" #include "Bullet3Common/b3Scalar.h" // for b3Assert #include #include bool gIntelLinuxglDrawBufferWorkaround=false; GLRenderToTexture::GLRenderToTexture() :m_framebufferName(0) { #if !defined(_WIN32) && !defined(__APPLE__) const GLubyte* ven = glGetString(GL_VENDOR); printf("ven = %s\n",ven); if (strncmp((const char*)ven,"Intel",5)==0) { printf("Workaround for some crash in the Intel OpenGL driver on Linux/Ubuntu\n"); gIntelLinuxglDrawBufferWorkaround=true; } #endif//!defined(_WIN32) && !defined(__APPLE__) } void GLRenderToTexture::init(int width, int height, GLuint textureId, int renderTextureType) { m_renderTextureType = renderTextureType; glGenFramebuffers(1, &m_framebufferName); glBindFramebuffer(GL_FRAMEBUFFER, m_framebufferName); // The depth buffer // glGenRenderbuffers(1, &m_depthrenderbuffer); // glBindRenderbuffer(GL_RENDERBUFFER, m_depthrenderbuffer); // glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height); // glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthrenderbuffer); switch (m_renderTextureType) { case RENDERTEXTURE_COLOR: { glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, textureId, 0); break; } case RENDERTEXTURE_DEPTH: { glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, textureId, 0); break; } default: { b3Assert(0); } }; glBindFramebuffer( GL_FRAMEBUFFER, 0 ); } bool GLRenderToTexture::enable() { bool status = false; glBindFramebuffer(GL_FRAMEBUFFER, m_framebufferName); switch (m_renderTextureType) { case RENDERTEXTURE_COLOR: { // Set the list of draw buffers. GLenum drawBuffers[2] = {GL_COLOR_ATTACHMENT0,0}; glDrawBuffers(1, drawBuffers); break; } case RENDERTEXTURE_DEPTH: { //Intel OpenGL driver crashes when using GL_NONE for glDrawBuffer on Linux, so use a workaround if (gIntelLinuxglDrawBufferWorkaround) { GLenum drawBuffers[2] = { GL_COLOR_ATTACHMENT0,0}; glDrawBuffers(1, drawBuffers); } else { glDrawBuffer(GL_NONE); } break; } default: { b3Assert(0); } }; // Always check that our framebuffer is ok if(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) { status = true; } return status; } void GLRenderToTexture::disable() { glBindFramebuffer( GL_FRAMEBUFFER, 0 ); } GLRenderToTexture::~GLRenderToTexture() { glBindFramebuffer( GL_FRAMEBUFFER, 0 ); if (m_depthrenderbuffer) { glDeleteRenderbuffers(1,&m_depthrenderbuffer); } if( m_framebufferName) { glDeleteFramebuffers(1, &m_framebufferName); } } #endif