OpenGL FrameBuffer 不在屏幕外渲染

OpenGL FrameBuffer not rendering off-screen

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

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

如您所见,它切断的部分是 window 宽度所在的位置。使用 glClear 也仅涵盖纹理的 window 大小,仅此而已。 我已经尝试将 glDisable(GL_SCISSOR_TEST)glViewport(0, 0, texture_width, texture_height) 一起使用,但它仍然会切断纹理。缩小视口会在同一点切断,增大视口只会拉伸图像并切断更多纹理。

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

另请注意,我已禁用深度测试,因此自从我禁用深度测试以来,深度清除不会超过 window 界限。

有人有什么想法吗?

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

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 矩阵函数来缩放和平移。 :)

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

// ************************************** 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);