我已经关注了如何设置和渲染FBO的一些教程。起初它工作,场景渲染得很好,但事实证明该程序使用的是集成GPU。 (我用我的笔记本电脑)
然后,出于好奇,我用了更高性能的#34; GPU(Nvidia GeForce GT540M
),屏幕全黑。此时我尝试将FBO的颜色纹理保存到文件中,实际上是在那里绘制了场景。
但最终我找到了解决方案。以前我只清除FBO(颜色和深度缓冲区),但现在我清除了FBO和默认的帧缓冲区,并再次渲染场景。
所以问题是,我必须两次调用glClear是不是很糟糕?我真的要两次打电话给glClear吗?为什么一个人清楚地在集成卡上工作?
如果有帮助,我可以展示一些代码。
帧缓冲初始化
bool FrameBufferObject::initializeFBO( int width, int height ) {
glActiveTexture( GL_TEXTURE0 );
if ( !_colorTexture.createEmptyTexture( width, height ) ) {
return false;
}
_textureId = _colorTexture.getTextureId();
if ( !_depthTexture.createDepthTexture( width, height ) ) {
return false;
}
_depthTextureId = _depthTexture.getTextureId();
glGenFramebuffers( 1, &_frameBufferID );
glBindFramebuffer( GL_FRAMEBUFFER, _frameBufferID );
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _textureId, 0 );
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, _depthTextureId, 0 );
if ( glCheckFramebufferStatus( GL_FRAMEBUFFER ) != GL_FRAMEBUFFER_COMPLETE ) {
return false;
}
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
_width = width;
_height = height;
_isInitialized = true;
return true;
}
颜色纹理
bool Texture::createEmptyTexture( int width, int height ) {
if ( isLoaded() ) {
closeTexture();
}
GLuint textureId = 0;
glGenTextures( 1, &textureId );
if ( getOpenGLError( "Unable to generate TextureID." ) ) {
return false;
}
glBindTexture( GL_TEXTURE_2D, textureId );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
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 );
glBindTexture( GL_TEXTURE_2D, 0 );
if ( getOpenGLError( "Error creating empty texture." ) ) {
glDeleteTextures( 1, &textureId );
return false;
}
_isLoaded = true;
_textureWidth = _imageWidth = width;
_textureHeight = _imageHeight = height;
_textureId = textureId;
return true;
}
深度纹理是相同的,除了它使用GL_DEPTH_COMPONENT格式,
glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL );
后处理着色器
顶点着色器
#version 330 core
in vec2 inVertex;
in vec2 inTexture;
out vec2 texCoords;
void main() {
texCoords = inTexture;
gl_Position = vec4( inVertex.x, inVertex.y, 0, 1 );
}
片段着色器
#version 330 core
in vec2 texCoords;
uniform sampler2D texture0;
layout(location = 0) out vec4 outColor;
void main() {
vec4 color = texture( texture0, texCoords );
outColor = color;
}
渲染代码如下所示,
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
fbo.bindFBO();
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
// .. render scene ..
fbo.unbindFBO();
// This is a namespace
PostProcShader::shader.useShader();
PostProcShader::render( fbo.getColorTexture() );
PostProcShader::shader.disableShader();
SDL_GL_SwapWindow( window );
后处理着色器只是在屏幕大小的四边形上渲染纹理。场景使用3个着色器:一个用于3D对象,第二个用于天空盒,最后一个用于字体。
我在VS 2015中使用C ++,SDL2和(当然)OpenGL / Glew。
编辑:
深度测试初始化
glEnable( GL_DEPTH_TEST );
glDepthMask( GL_TRUE );
glDepthFunc( GL_LEQUAL );
glDepthRange( 0.0f, 1.0f );
glClearDepth( 1.0f );
答案 0 :(得分:-1)
从英特尔HUD转到Nvidia时,我遇到了类似的问题。但是我的解决方案很简单。我必须确保在渲染到新的帧缓冲区(在Nvidia上)之前调用glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
,否则我将看不到任何渲染。我怀疑在Nvidia上深度缓冲区的设置没有与Intel上的默认设置相同,因此清除它会将其设置为opengl默认清除值。