OpenGL FrameBuffer无法在屏幕外渲染

时间:2015-02-08 07:14:11

标签: c++ opengl

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

http://i.imgur.com/lj2o7yO.jpg

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

enter image description here

如您所见,切断的部分是窗口宽度的位置。使用glClear也只能覆盖纹理的窗口大小而不包含任何其他内容。 我尝试使用glDisable(GL_SCISSOR_TEST)glViewport(0, 0, texture_width, texture_height),但它仍然会切断纹理。使视口更小在同一点切断,使其更大只是拉伸图像并切断更多的纹理。

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

另请注意,我已禁用深度测试,因此我无法将深度清除超过窗口范围,因为我禁用了它。

有人有任何想法吗?

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

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矩阵函数进行缩放和转换。 :)

1 个答案:

答案 0 :(得分:0)

如果没有看到您的实际代码,很难说出现了什么问题,但此代码可以运行。

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