#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