Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 4 of 4

Thread: Only red channel when using FBO render to texture

  1. #1
    Junior Member Newbie
    Join Date
    Sep 2012
    Posts
    12

    Only red channel when using FBO render to texture

    Hi guys,

    Im trying to write a simple example code to use FBO render to texture. Im trying to render a rotating solid sphere on to a quad. I see the sphere, but it seems i get only the red channel being used. The color of the sphere is actually pink by setting red and blue to 1 and i also cleared the framebuffer to blue, but i get black. It seems like the data written to the texture image attached to the fbo has only red channel valid.

    I am using java and i have my own bindings to opengl via jni.

    Here is the code that does the gl initialization to create fbo and attach a texture and depth image to the fbo:

    Code :
        protected void glInitialize() {
          Gl gl = gl();
     
          _fboId = gl.genFramebuffer();
          gl.bindFramebuffer(Gl.DRAW_FRAMEBUFFER, _fboId);
     
          // Create a texture object for fbo.
          _texId = gl.genTexture();
          int texSize = WND_SIZE;
          gl.activeTexture(Gl.TEXTURE0);
          gl.bindTexture(Gl.TEXTURE_2D, _texId);
          gl.texParameterf(Gl.TEXTURE_2D, Gl.TEXTURE_MAG_FILTER, Gl.LINEAR);
          gl.texParameterf(Gl.TEXTURE_2D, Gl.TEXTURE_MIN_FILTER, Gl.LINEAR);
          gl.texParameterf(Gl.TEXTURE_2D, Gl.TEXTURE_WRAP_S, Gl.CLAMP_TO_EDGE);
          gl.texParameterf(Gl.TEXTURE_2D, Gl.TEXTURE_WRAP_T, Gl.CLAMP_TO_EDGE);
          gl.texImage2D(Gl.TEXTURE_2D, 0, Gl.RGBA8, texSize, texSize, 0, Gl.RGBA,
              Gl.UNSIGNED_BYTE, (byte[])null);
          gl.bindTexture(Gl.TEXTURE_2D, 0);
     
          //Create the depth renderbuffer.
          _depthRenderBufferId = gl.genRenderbuffer();
          gl.bindRenderbuffer(Gl.RENDERBUFFER, _depthRenderBufferId);
          gl.renderbufferStorage(Gl.RENDERBUFFER, Gl.DEPTH_COMPONENT, texSize,
              texSize);
          gl.bindRenderbuffer(Gl.RENDERBUFFER, 0);
     
    //      //Create the stencil renderbuffer.
    //      int[] stencilBuffer = new int[1];
    //      gl.genRenderbuffers(1, stencilBuffer);
    //      _stencilRenderBufferId = stencilBuffer[0];
    //      gl.bindRenderbuffer(Gl.RENDERBUFFER, _stencilRenderBufferId);
    //      gl.renderbufferStorage(Gl.RENDERBUFFER, Gl.STENCIL_INDEX, texSize, texSize);
    //      gl.bindRenderbuffer(Gl.RENDERBUFFER, 0);
     
          gl.framebufferTexture2D(Gl.DRAW_FRAMEBUFFER, Gl.COLOR_ATTACHMENT0,
              Gl.TEXTURE_2D, _texId, 0);
          gl.framebufferRenderbuffer(Gl.DRAW_FRAMEBUFFER, Gl.DEPTH_ATTACHMENT,
              Gl.RENDERBUFFER, _depthRenderBufferId);
    //      gl.framebufferRenderbuffer(Gl.FRAMEBUFFER, Gl.STENCIL_ATTACHMENT,
    //          Gl.RENDERBUFFER, _stencilRenderBufferId);
     
          printFramebufferInfo(gl);
          boolean status = checkFramebufferStatus(gl);
          System.out.println("Framebuffer status: "+status);
          gl.bindFramebuffer(Gl.DRAW_FRAMEBUFFER, 0);
     
          gl.pixelStorei(Gl.UNPACK_ALIGNMENT, 4);
          gl.enable(Gl.TEXTURE_2D);
          gl.enable(Gl.DEPTH_TEST);
          gl.depthMask(true);
    //      gl.clearDepth(1.f);
          gl.depthFunc(Gl.LEQUAL);
     
          checkErrors(gl);
        }

    Heres the code where i use the framebuffer :
    Code :
        @Override
        public void glPaint() {
     
          final Gl gl = gl();
          final Glu glu = glu();
     
          gl.pushClientAttrib(Gl.CLIENT_ALL_ATTRIB_BITS);
          gl.pushAttrib(Gl.ALL_ATTRIB_BITS);
     
          gl.colorMask(true, true, true, true);
          gl.activeTexture(Gl.TEXTURE0);
          gl.disable(Gl.TEXTURE_2D);
          gl.bindTexture(Gl.TEXTURE_2D, 0);
          gl.bindFramebuffer(Gl.DRAW_FRAMEBUFFER, _fboId);
     
          gl.viewport(0, 0, WND_SIZE, WND_SIZE);
          gl.matrixMode(Gl.PROJECTION);
          gl.loadIdentity();
          glu.perspective(60.f, 1.f, 1.f, 100.f);
     
          gl.matrixMode(Gl.MODELVIEW);
          gl.loadIdentity();
          gl.translatef(0, 0, -2f);
          _sphereRotateX+= 0.1;
          gl.rotate(_sphereRotateX % 360, 1.0, 0.0, 0.0);
     
          //clear blue for sphere rendering 
          gl.clearColor(0.f, 0.f, 1.f, 1.f);
          gl.clear(Gl.COLOR_BUFFER_BIT | Gl.DEPTH_BUFFER_BIT);
     
          _sphere.glDraw(gl);
          gl.bindFramebuffer(Gl.DRAW_FRAMEBUFFER, 0);
          gl.popAttrib();
          gl.popClientAttrib();
     
          gl.pushClientAttrib(Gl.CLIENT_ALL_ATTRIB_BITS);
          gl.pushAttrib(Gl.ALL_ATTRIB_BITS);
     
          getTextureParameters(gl, _texId);
     
          //draw cube normally.
          gl.activeTexture(Gl.TEXTURE0);
          gl.enable(Gl.TEXTURE_2D);
     
          int width = getWidth();
          int height = getHeight();
          gl.viewport(0, 0, width, height);
          gl.matrixMode(Gl.PROJECTION);
          gl.loadIdentity();
          glu.perspective(60.f, (float)width/(float)height, 1.f, 100.f);
     
          gl.matrixMode(Gl.MODELVIEW);
          gl.loadIdentity();
          gl.translatef(0, 0, -2);
          gl.rotatef(_cameraAngleX, 1, 0, 0);
          gl.rotatef(_cameraAngleY, 0, 1, 0);
     
          gl.clearColor(1.f, 0.8f, 0.f, 1.f);
          gl.clear(Gl.COLOR_BUFFER_BIT | Gl.DEPTH_BUFFER_BIT );
     
          drawTexturedQuad(gl);
    //      drawSolidQuad(gl);
     
          gl.popAttrib();
          gl.popClientAttrib();
     
          checkErrors(gl);
     
          repaint();
        }

    Here is the code to draw the quad with the texture from the framebuffer object:

    Code :
        private void drawTexturedQuad(final Gl gl) {
          gl.bindTexture(Gl.TEXTURE_2D, _texId);
          gl.frontFace(Gl.CW);
          gl.begin(Gl.QUADS);
          // front face
           gl.color3f(0.75f, 1.f, 0.f);
    //      gl.normal3f(0f, -1f, 0f);
     
          gl.texCoord2f(0.f, 0.f);
          gl.vertex3f(-1.f, 0.f, -1.f);
     
          gl.texCoord2f(1.f, 0.f);
          gl.vertex3f(1.f, 0.f, -1.f);
     
          gl.texCoord2f(1.f, 1.f);
          gl.vertex3f(1.f, 0.f, 1.f);
     
          gl.texCoord2f(0.f, 1.f);
          gl.vertex3f(-1.f, 0.f, 1.f);
          gl.end();
          gl.bindTexture(Gl.TEXTURE_2D, 0);
        }

    ...and heres the code to draw a sphere:

    Code :
        public void glDraw(final Gl gl) {
     
          gl.pushClientAttrib(Gl.CLIENT_ALL_ATTRIB_BITS);
          gl.pushAttrib(Gl.ALL_ATTRIB_BITS);
     
          Gl.color3f(1.0f, 0f, 1f);
          Gl.polygonMode(Gl.FRONT_AND_BACK, Gl.FILL);
          gl.vertexArray(3, _verts);
          Gl.enableClientState(Gl.VERTEX_ARRAY);
          for (int i = 0; i < _strips.length; i++) {
            gl.drawElements(Gl.QUAD_STRIP, _strips[i].length, _strips[i]);
          }
          for (int i = 0; i < _caps.length; i++) {
            gl.drawElements(Gl.TRIANGLE_FAN, _caps[i].length, _caps[i]);
          }
     
          gl.polygonMode(Gl.FRONT_AND_BACK, Gl.LINE);
          Gl.color3f(0.0f, 0.0f, 0f);
          for (int i = 0; i < _strips.length; i++) {
            gl.drawElements(Gl.QUAD_STRIP, _strips[i].length, _strips[i]);
          }
          for (int i = 0; i < _caps.length; i++) {
            gl.drawElements(Gl.TRIANGLE_FAN, _caps[i].length, _caps[i]);
          }
     
          gl.popAttrib();
          gl.popClientAttrib();
     
        }

    The image i get currently is this: http://s21.postimg.org/472o42d5j/FBO_incorrect.jpg

    However if i simply render the sphere without fbo (and what i expect should be a texture from the fbo is) : http://s21.postimg.org/j78sx4y6v/sphere_correct.png

    Could someone let me know what im doing wrong here? Any suggestion would be appreciated..

    thanks

  2. #2
    Junior Member Newbie
    Join Date
    Sep 2012
    Posts
    12
    Any suggestion on how to debug? or perhaps try something out that would give me a hint would be great..this is using fixed function pipeline..I verified there were no gl errors as well.
    Last edited by siddharth.cmdz; 08-07-2013 at 08:29 AM.

  3. #3
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,729
    Quote Originally Posted by siddharth.cmdz View Post
    I see the sphere, but it seems i get only the red channel being used.
    Quote Originally Posted by siddharth.cmdz View Post
    Here is the code to draw the quad with the texture from the framebuffer object:
    Code :
           gl.color3f(0.75f, 1.f, 0.f);
    The default glTexEnv() setting for GL_TEXTURE_ENV_MODE is GL_MODULATE, so the texture colours are multiplied by the current colour. Setting the current colour to (0.75,1,0) scales the red channel by 0.75 and sets the blue channel to zero, so (1,0,1) = magenta becomes (0.75,0,0) = red and (0,0,1) = blue becomes (0,0,0) = black.

    Set the current colour to white or GL_TEXTURE_ENV_MODE to GL_REPLACE if you want the texture colours to be reproduced correctly.

  4. #4
    Junior Member Newbie
    Join Date
    Sep 2012
    Posts
    12
    Thanks GClements!! i actually figured this folly a little earlier...its one of those moments where i wasnt thinking it through..but thanks a lot.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •