CptanPanic
CptanPanic

Reputation: 858

Rendered to texture, reading pixels results in mostly black

I am trying to modify an existing scientific program which currently renders to a screen to also render to a texture so I can render an image much bigger than screen. The problem I am having is although I see the rendered to screen image ok, the saved texture when I open in matlab is almost all black with some red lines. I followed the tutorial at http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-14-render-to-texture/ Can anyone see what I am doing wrong? For testing I have TEXTURE_SIZE = 512

    glGenFramebuffers(1, &FramebufferName);
    glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
    // The texture we're going to render to
    glGenTextures(1, &renderedTexture);

    // "Bind" the newly created texture : all future texture functions will modify this texture
    glBindTexture(GL_TEXTURE_2D, renderedTexture);

    // Give an empty image to OpenGL ( the last "0" means "empty" )
    glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, TEXTURE_SIZE, TEXTURE_SIZE, 0,GL_RGB, GL_UNSIGNED_BYTE, 0);

    // Poor filtering
    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_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);


// The depth buffer
GLuint depthrenderbuffer;
glGenRenderbuffers(1, &depthrenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthrenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, TEXTURE_SIZE, TEXTURE_SIZE);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthrenderbuffer);
    // Set "renderedTexture" as our colour attachement #0
    glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, renderedTexture, 0);

    GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0};
    glDrawBuffers(1, DrawBuffers); // "1" is the size of DrawBuffers

    // check OpenGL error
    for (GLenum err; (err = glGetError()) != GL_NO_ERROR; ) {
      std::cerr << "OpenGL error: " << err << std::endl;
    }

    // Always check that our framebuffer is ok
    if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
    {
      std::cerr << "OpenGL error: " << std::endl;
      return;
    }
    }

    // Switch to new framebuffer 
    glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
    // Clear the screen
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Rendering Code - Lots of code so I have removed some of it.
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    gluPerspective(CommonDefinitions::PANEL_FOV_VERT_DEG, ASPECT_RATIO, mnNearClip, mnFarClip);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(...);

    // background = black
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glShadeModel(GL_SMOOTH);

    glDisable(GL_DITHER);
    glDisable(GL_TEXTURE);
    glDisable(GL_FOG);

    ...

    // Enable graphics card state
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    ...

     glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, laDiffuse);
      glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, laSpecular);
      int32 lnShininess = lpObject->GetShininess(tcObject::FLS);
      glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, lnShininess);

      ...

      // Inform the graphics card which vertex VBO is active
      glBindBuffer(GL_ARRAY_BUFFER, lpObject->GetVertexId());

      // Enable the vertex pointer on the graphics card
      glVertexPointer(3, GL_FLOAT, 0, NULL);

      // Set the normal VBO on the graphics card
      glBindBuffer(GL_ARRAY_BUFFER, lpObject->GetNormalId());
      glNormalPointer(GL_FLOAT, 0, NULL);

      //Move object into position
      glPushMatrix(); //Save state
      glMultMatrixf((GLfloat*)(lpObject->GetTransform()));
      glMultMatrixf((GLfloat*)(lpObject->GetAttitude()));
      GLfloat lnScale = lpObject->GetScale();
      glScalef(lnScale, lnScale, lnScale);

      // Render - magic number 3 = vertices per triangle
      glDrawArrays(GL_TRIANGLES, 0, lpObject->GetVertexBufferSize()/3);
      glPopMatrix(); //Restore state

      ...

    // Disable graphics card state
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);

    glGetTexImage(GL_TEXTURE_2D,0,GL_RGB,GL_UNSIGNED_BYTE,maColorTest);

    // switch back to window-system-provided framebuffer
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    // check OpenGL error
    for (GLenum err; (err = glGetError()) != GL_NO_ERROR; ) {
      std::cerr << "OpenGL error: " << err << std::endl;
    }

  ofstream fout("image.dat",ios::out | ios::binary);
  fout.write((const char *)maColorTest,TEXTURE_SIZE * TEXTURE_SIZE * 3);
  fout.close();

Upvotes: 0

Views: 101

Answers (1)

CptanPanic
CptanPanic

Reputation: 858

As @Reto mentioned, I was missing the glViewport() call in the code above. Thanks.

Upvotes: 1

Related Questions