2015-07-10 131 views
0

我想修改一个现有的科学程序,目前渲染到屏幕也渲染到纹理,所以我可以渲染比屏幕大得多的图像。我遇到的问题是虽然我看到渲染到屏幕图像确定,但是当我在matlab中打开时保存的纹理几乎全部是黑色的,并带有一些红线。我遵循教程http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-14-render-to-texture/任何人都可以看到我做错了什么?为了测试我有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(); 
+0

您似乎缺少深度缓冲区。也许再次按照教程? – Gerard

+0

我实际上尝试过,没有深度缓冲区。但没有任何区别,我最终将其删除以尝试简化事情。所以我将它添加回代码示例。 – CptanPanic

+0

你使用的是什么OpenGL版本? 'glFramebufferTexture()'仅在3.2及更高版本中可用。我会尝试使用'glFramebufferTexture2D()'来代替。另外,我没有看到用于FBO渲染的'glViewport()'调用。 –

回答

1

如@Reto提到的,我是缺少在上面的代码中的glViewport()调用。 谢谢。