我正在尝试为FBO启用mutlisampling和alpha-to-coverage.使用默认的帧缓冲区,我所要做的就是调用glEnable(GL_MULTISAMPLE)和glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE).但是,我无法使用自己的FBO达到同样的效果.
我的目标:将场景绘制到FBO,就像使用上述属性绘制到默认帧缓冲区一样.从那里我希望能够将图像用作未来通过着色器的纹理.
这适用:制作没有多重采样/ alpha到覆盖的FBO的代码,1种颜色附件,1种深度附件:
// Generate the color attachment
glGenTextures(1,&defaultColorAttachment0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,defaultColorAttachment0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,screenWidth,screenHeight,0,GL_RGBA,GL_UNSIGNED_BYTE,NULL);
// Bind the texture to the FBO
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, defaultColorAttachment0,0);
// Generate the depth attachment
glGenRenderbuffers(1,&defaultDepthBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, defaultDepthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, screenWidth, screenHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, defaultDepthBuffer);
Run Code Online (Sandbox Code Playgroud)
这不起作用.试图制作多重采样FBO的代码:
// Generate the color attachment
glGenTextures(1,&defaultColorAttachment0);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, defaultColorAttachment0);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA, screenWidth, screenHeight, GL_FALSE);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, defaultColorAttachment0,0);
// Generate the depth attachment
glGenRenderbuffers(1,&defaultDepthBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, defaultDepthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, …Run Code Online (Sandbox Code Playgroud) 我很想知道很长一段时间处理OpenGL FrameBuffer对象(FBO)的最佳方法.切换FBO可能成本很高,但也定义了新的附件.
你怎么快速做到的?
我在这三个之间犹豫不决:
1 FBO用于所有内容,更改附件但不要在FBO之间切换
1渲染路径中每个渲染目标(大小+格式)的FBO.这意味着我将为相似的渲染目标重用相同的FBO.但这样一种自定义模糊将花费4+ FBO.
每个渲染目标1个FBO,仅设置附件一次,然后在FBO之间切换
另外,我应该最小化FBO开关的数量(比如我最小化纹理绑定的数量)?
我将OpenGL中的场景以低分辨率渲染到帧缓冲区中.然后我打算将这个版本绘制到整个屏幕上(用GL_NEAREST进行升级).我使用纹理blitting(glBlitFramebuffer)来做到这一点.在我的Nvidia GPU上,这可以工作,但是当我在Intel i7集成显卡上执行完全相同的代码时,目标帧缓冲区上的y位置似乎是错误的(即图像渲染得太远了).
glGetError没有返回错误.由于Nvidia的驱动程序往往非常宽容,我希望我错过了Nvidia不关心的OpenGL规范中的细节.我搜索了互联网和stackoverflow,无法找到描述的类似问题.两位司机都报告支持OpenGL 3.0
我的绘图代码:
//setup viewport for small image
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, image.getWidth(), image.getHeight());
//bind small framebuffer
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
glDrawBuffers(GL_COLOR_ATTACHMENT0);
glClear(GL_COLOR_BUFFER_BIT);
//draw
renderRotatedFull(1);//nothing interesting at all happening here
//reset Viewport
glPopAttrib();
//prepare and execute blitting
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glDrawBuffers(GL_BACK_LEFT);
glBlitFramebuffer(0, 0, image.getWidth(), image.getHeight(), 0, 0, Game.width,
Game.height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
//throws exception if there is an OpenGL error
org.lwjgl.opengl.Util.checkGLError();
Run Code Online (Sandbox Code Playgroud)
初始化完成如下:
fbo =glGenFramebuffers();
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
rbo = glGenRenderbuffers();
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, image.getWidth(), image.getHeight());
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, …Run Code Online (Sandbox Code Playgroud) 我有一个framebuffer对象,我在其中使用N个纹理上的多目标渲染.在某个时候,我想清除其中一些纹理的内容,但不是全部.如果我打电话
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Run Code Online (Sandbox Code Playgroud)
绑定到FBO的每个纹理都将被清除(我是对的吗?).有没有办法在特定的绘制缓冲区/纹理上执行此操作?
When I resize my window, I need to resize my textures that are attached to my framebuffer. I tried calling glTexStorage2D again, with different size parameters. However that does not work.
How can I resize the textures attached to my framebuffer? (Including the depth attachment)
EDIT
Code I tried:
glBindTexture(m_target, m_name);
glTexStorage2D(m_target, 1, m_format, m_width, m_height);
glBindTexture(m_target, 0);
Run Code Online (Sandbox Code Playgroud)
where m_name, m_target and m_format are saved from the original texture and m_width and m_height are the new dimensions.
EDIT2
Please tell …
我可以使用像素缓冲区对象(PBO)直接从FBO读取像素值(即使用glReadPixels)(即FBO仍然连接时)?
如是,
{
//DATA_SIZE = WIDTH * HEIGHT * 3 (BECAUSE I AM USING 3 CHANNELS ONLY)
// FBO and PBO status is good
.
.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);
//Draw the objects
Run Code Online (Sandbox Code Playgroud)
以下glReadPixels工作正常
glReadPixels(0, 0, screenWidth, screenHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, (uchar*)cvimg->imageData);
Run Code Online (Sandbox Code Playgroud)
以下glReadPixels不工作:(
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboId);
//yes glWriteBuffer has also same target and I also checked with every possible values
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
glReadPixels(0, 0, screenWidth, screenHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, (uchar*)cvimg->imageData);
.
.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); //back to window framebuffer
Run Code Online (Sandbox Code Playgroud) 将像素从纹理复制到纹理的最佳方法是什么?
我找到了一些方法来实现这一目标.例如,有一个方法,glCopyImageSubData()但我的目标版本是OpenGL 2.1,所以我不能使用它.另外,由于性能非常重要,glGetTexImage2D()不是一种选择.由于我将视频帧作为纹理处理,因此我必须每秒复制大约30~60次.
我找到的可用选项是下一个:
您可以忽略创建fbo的成本,因为fbo只会创建一次.
请不要发布像'取决于'的东西.做你的基准.'.我不只针对一个GPU.如果有的话请,请让我知道它取决于什么.
此外,因为测量OpenGL调用的时间非常困难,所以我想知道的不是定量结果.我需要一些关于我应该避免哪种方法的建议.
如果您知道更好的复制纹理方法,请告诉我.
谢谢你的阅读.
根据ARB_geometry_shader4,可以使用几何着色器和连接到帧缓冲对象的立方体贴图将场景渲染到立方体贴图的6个面上.我想用这种方式创建一个阴影贴图.但是,我似乎无法解决冲突:
因此,当我想渲染到立方体贴图时,看起来我无法使用任何深度测试.或者我到底错过了什么?
编辑:看起来更新的Nvidia驱动程序(180.48)支持深度立方体贴图.
我正在渲染到OpenGL屏幕外的帧缓冲对象,并喜欢将其保存为图像.请注意,FBO大于显示尺寸.我可以渲染到屏幕外缓冲区并将其用作纹理,这是有效的.我可以使用偏移量通过显示"滚动"这个更大的纹理,这让我充满信心,我渲染到比窗口更大的上下文.
如果我将屏幕外缓冲区保存到图像文件,它总是会被裁剪.保存的代码片段是:
void ofFBOTexture::saveImage(string fileName) {
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
// get the raw buffer from ofImage
unsigned char* pixels = imageSaver.getPixels();
glReadPixels(0, 0, 1024, 1024, GL_RGB, GL_UNSIGNED_BYTE, pixels);
imageSaver.saveImage(fileName);
}
Run Code Online (Sandbox Code Playgroud)
请注意,图像内容被裁剪,可见部分被正确保存(这意味着像素格式没有错误,GL_RGB问题等),但剩余空间用一种颜色填充.
所以,我的问题是 - 我做错了什么?
我想用FBO进行屏幕外渲染(在没有任何WS的控制台环境中).我知道有必要创建一个OpenGL上下文,并且至少有一个虚拟窗口用于任何操作,因此我做了以下初始化:
// Step 1 - Get the default display.
eglDisplay = eglGetDisplay((EGLNativeDisplayType)0);
// Step 2 - Initialize EGL.
EGLint iMajorVersion, iMinorVersion;
if (!eglInitialize(eglDisplay, &iMajorVersion, &iMinorVersion))
{
printf("Error: eglInitialize() failed.\n");
goto cleanup;
}
// Step 3 - Make OpenGL ES the current API.
eglBindAPI(EGL_OPENGL_ES_API);
if (!TestEGLError("eglBindAPI"))
{
goto cleanup;
}
// Step 4 - Specify the required configuration attributes.
EGLint pi32ConfigAttribs[5];
pi32ConfigAttribs[0] = EGL_SURFACE_TYPE;
pi32ConfigAttribs[1] = EGL_WINDOW_BIT;
pi32ConfigAttribs[2] = EGL_RENDERABLE_TYPE;
pi32ConfigAttribs[3] = EGL_OPENGL_ES2_BIT;
pi32ConfigAttribs[4] = EGL_NONE;
// Step 5 - Find …Run Code Online (Sandbox Code Playgroud) fbo ×10
opengl ×9
benchmarking ×1
c++ ×1
copy ×1
framebuffer ×1
glreadpixels ×1
glsl ×1
gpu ×1
java ×1
lwjgl ×1
off-screen ×1
opengl-3 ×1
pbo ×1
rendering ×1
textures ×1
windowless ×1