【问题标题】:OpenGL FrameBuffer not rendering off-screenOpenGL FrameBuffer 未在屏幕外渲染
【发布时间】:2015-04-08 02:48:23
【问题描述】:

好的,这是我当前的渲染工作流程。我创建了一个没有深度/模板附件且只有颜色纹理附件的帧缓冲区对象。我绑定帧缓冲区并将我所有的纹理渲染到它上面。然后,我将纹理数据从渲染缓冲区纹理复制到另一个纹理(尽管这部分并不真正相关,因为在渲染到帧缓冲区时会出现问题)。所以问题是一旦渲染超出了窗口边界,它就会停止绘制。所以这是当前渲染的图像(对不起,我必须发布链接,我还没有足够的声誉来发布图像):

这是实际纹理数据的图像(由 gDEBUgger 提供)。

如您所见,它切断的部分是窗口宽度所在的位置。使用glClear 也只覆盖了纹理的窗口大小,没有别的。 我曾尝试使用glDisable(GL_SCISSOR_TEST)glViewport(0, 0, texture_width, texture_height),但它仍然会切断纹理。将视口变小会在同一点上截断,将视口变大只会拉伸图像并截断更多纹理。

我的意思是,这是有道理的,当你甚至看不到像素时,为什么还要在屏幕外绘制像素,这对性能来说太可怕了。但就我而言,我需要这样做。这就是为什么我正在寻找一种方法来禁用它或类似的东西。

另请注意,我已禁用深度测试,因此自从我禁用它以来,深度清除不会超出窗口边界。

有人有什么想法吗?

编辑:以防万一有人在未来看到这个帖子,只是想说什么为我解决了这个问题。我只需要将视口设置为纹理的大小在渲染时将透视矩阵缩放到相同的大小。就我而言,我使用了自己的矩阵类。这是一个例子:

glViewport(0, 0, texture_width, texture_height);
perspective_mat.identity();
perspective_mat.scale(1.0f / (texture_width / 2), -1.0f / (texture_height / 2));
perspective_mat.translate(-1.0f, 1.0f);

如果您使用的是固定管道的东西(没有着色器等),那么您可以使用 openGL 矩阵函数来缩放和转换。 :)

【问题讨论】:

    标签: c++ opengl


    【解决方案1】:

    没有看到你的实际代码,很难说出了什么问题,但是这段代码是有效的。

    // ************************************** Save the Current Viewport Size
    
    GLint screenViewPort[4];
    glGetIntegerv(GL_VIEWPORT, screenViewPort);
    
    // ***************************** Define a Second Output Buffer and Bind it for Writing
    
    glGenFramebuffersEXT(1, wispSecondOutputBuffer);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, wispSecondOutputBuffer[0]);
    
    // ******************************* Set the Viewport to the Texture Size and Reshape
    
    glViewport(0,0,TEXTUREWIDTH, TEXTUREHEIGHT);
    [self resizeTextureGL];
    
    // ************************************** Create the Output Imgage Texture
    
    glGenTextures( 1, wispOutputTexture);
    glBindTexture(GL_TEXTURE_2D, wispOutputTexture[0]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)TEXTUREWIDTH, (GLsizei)TEXTUREHEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    
    // ********************************* Attach the Output Texture to the Frame Buffer
    
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, wispOutputTexture[0], 0);
    
    GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0};
    glDrawBuffers(1, DrawBuffers);
    
    // ************************************ Check that the Frame Buffer is Complete
    
    GLenum frameBufferStatus;
    
    frameBufferStatus = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
    
    if(frameBufferStatus != GL_FRAMEBUFFER_COMPLETE_EXT) NSLog(@"There is a problem with the output frame buffer");
    
    // ****************************************** Render to the Texture
    
    [self runTextureShaders];
    [self runTextureShaders2];
    
    // ************************************ Reset the Viewport and Frame Buffer
    
    glViewport(screenViewPort[0],screenViewPort[1],(GLsizei)screenViewPort[2], (GLsizei)screenViewPort[3]);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
    
    // ******************************* Copy the Texture Data Into the Bitmap Image
    
    glBindTexture(GL_TEXTURE_2D, wispOutputTexture[0]);
    glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, bitmapData);
    

    调用 resizeTextureGL 计算模型、视图和投影矩阵。

    后面的代码我也有:

    // ******************************************* Cleanup Memory
    
    glDeleteTextures(1, wispOutputTexture);
    glDeleteFramebuffersEXT(1, wispSecondOutputBuffer);
    

    【讨论】:

    • 嗯,由于某种原因,它现在似乎正在工作。在设置视口后,我一定错过了它的工作,但不确定如何。但无论如何,感谢您的帮助,无论如何我都会标记为已解决。 :)
    猜你喜欢
    • 2020-11-14
    • 2014-07-22
    • 2012-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-19
    相关资源
    最近更新 更多