我正在开发Android应用程序类型的手指画.我正在使用OpenGL ES 2.0.基本上我有一个图像,其中每个触摸屏应对应一个圆形alpha应用,其中显示位于下方的另一个图像.我尝试了不同的技术,但速度相当慢,因为它的功能就像使用有机glTexSubImage2D一样,减慢了渲染阶段.我试图了解FBO的使用,因为它们允许屏幕外渲染.有人可以更好地解释它在屏幕外渲染的意义以及加速我的方法可以获得哪些优势?
我认为屏幕外意味着您可以更改我创建的帧缓冲区,而不是onDrawFrame?在另一个线程?
我已经达到了另一个似乎无法自己解决的僵局.我真的希望有人可以帮助我.
我一直试图用GLSL创造一个漂亮的小绽放效果,效果很好.当我尝试将一些东西搬进我的场景时,我注意到在渲染之前我忘了清除我的FBO.
没有清除它工作从不改变场景,因为我总是使用相同的纹理.用glClear(); 命令它仍然有效,但对于第一帧,我得到的只是一个黑屏.所以我想我的问题是我不能让我的FBO每一帧都不断更新.
我觉得我要么缺少一些非常明显的东西,要么做一些可怕的错误.
我会感谢您提出的任何建议.
这是第一帧的结果:

来源:( 使用openFrameworks)
建立:
void testApp::setup(){
ofSetVerticalSync(true);
ofDisableSetupScreen();
width = ofGetWidth();
height = ofGetHeight();
//complie/link/generate ShaderObjects ....
horizontalBlurFrag.load("/opt/openframeworks/apps/examples/FBO_basic_shader_new_continued_v4_2/bin/data/fragment_shader_horizontal.glsl", GL_FRAGMENT_SHADER);
verticalBlurFrag.load("/opt/openframeworks/apps/examples/FBO_basic_shader_new_continued_v4_2/bin/data/fragment_shader_vertical.glsl", GL_FRAGMENT_SHADER);
BlurVertex.load("/opt/openframeworks/apps/examples/FBO_basic_shader_new_continued_v4_2/bin/data/horizontal_blur.glsl", GL_VERTEX_SHADER);
blendTextures.load("/opt/openframeworks/apps/examples/FBO_basic_shader_new_continued_v4_2/bin/data/blend_shader.glsl", GL_FRAGMENT_SHADER);
fboOriginal.initialize(width, height);
fboH800.initialize(width, height);
fboV800.initialize(width, height);
fboH400.initialize(width, height);
fboV400.initialize(width, height);}
Run Code Online (Sandbox Code Playgroud)
画:
void testApp::draw(){
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
//set orthographic projection
glOrtho( -1, 1, -1, 1, 1.0, 40.0 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glViewport( 0, 0, width, height);
glDisable(GL_TEXTURE_2D);
fboOriginal.bind();
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, …Run Code Online (Sandbox Code Playgroud) 我目前有一个使用多个过程的渲染引擎,其中图像的各个部分在纹理上渲染,然后使用着色器进行组合.它有效,现在我想激活多次采样.
我在这里阅读(http://www.opengl.org/wiki/Framebuffer_Object_Examples#MSAA),使用OpenGL,您无法将a附加GL_TEXTURE2D_MULTISAMPLE到帧缓冲对象.
这似乎是一种使用多次采样并且仍然可以访问结果的方法,因为纹理是使用多采样渲染缓冲区,然后将结果复制到多重采样纹理中.
我的问题是:前进的最佳方式是什么?
谢谢.
如何通过OpenGL编程访问显卡的视频内存,具体来说,获取所有内容的视频内存?
我尝试了以下两种方法,但都失败了.将它们连接起来,我希望你能指出我的程序中的错误或我对视频内存结构的理解.提前致谢!
我的基本想法是继续在视频内存中分配一个未初始化的区域,直到探索视频内存的所有内容.
(1)在main函数中,我创建了一个带有双缓冲区的窗口(参见下面的代码).
int main(int argc,char ** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); // double buffers
glutInitWindowPosition(0,0);
glutInitWindowSize(windowWidth, windowHeight);
glutCreateWindow("Hope to be successful!");
glutDisplayFunc(myDisplay); // call back function "myDisplay"
glutKeyboardFunc(keyboard);
glutMainLoop();
free(PixelData);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
然后,在"myDisplay"函数中,首先调用glReadPixels()函数从后面的帧缓冲区中读出给定大小的像素矩形,将这些像素信息保存在数组"PixelData"中,最后显示这些像素信息.通过调用glDrawPixels()函数来调整屏幕.执行此程序后,只显示一个黑色窗口.黑色是默认颜色.所以这意味着窗口什么都没有.然后我试图从后面的帧缓冲区中读取其他区域,并且它们都不包含任何内容.
从上面得出的结论是后框架缓冲器中不包含任何内容.但是,这是不合理的,因为前缓冲区应该只包含当前屏幕内容/窗口,因此在屏幕底部打开和最小化的其他窗口应该将其内容放在后面的帧缓冲区中,但后面的帧缓冲区是空的.那些存储了哪些窗口(由我在底部打开并最小化)?
我想为我的程序分配的帧缓冲区(后面和前面)只占整个视频内存的一小部分.因此,那些最小化的窗口内容应该存储在视频存储器的其他位置.
一段时间后,我阅读了OpenGL frameBuffer对象(FBO)的介绍,并且有一句话:默认情况下,OpenGL使用帧缓冲作为完全由窗口系统创建和管理的渲染目标.此默认帧缓冲区称为窗口系统提供的帧缓冲区.这似乎证实了我的上述猜测.
(2)然后我开始研究FBO,希望FBO可以帮助我探索整个视频内存.
在下面的main函数中,我创建了一个FBO和7个渲染缓冲对象(RBO),然后通过颜色附加点将这7个RBO附加到此FBO.
const int RBO_COUNT = 7; //how many renderBuffer objects are created to attach to the frameBuffer object
int main(int argc, char **argv)
{
....
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_ALPHA); // display mode
...
// create a …Run Code Online (Sandbox Code Playgroud) 我想要做的是使用OpenGL执行一些渲染,然后使用CUDA直接对渲染的RGB和深度组件执行一些只读后处理(计算),而不将数据复制到PBO.
为此,我创建了一个FBO并将两个RBO连接到它(一个用于RGBA,另一个用于DEPTH).
然后,我使用GL_RENDERBUFFER作为参数为每个RBO调用cudaGraphicsGLRegisterImage.对于颜色RBO cudaGraphicsGLRegisterImage返回cudaSuccess,但对于深度RBO,我收到一个cudaErrorInvalidValue.
我已经在论坛中的某个地方读到过nvidia目前不支持CUDA为深度组件渲染缓冲区互操作,尽管它在文档中很好地存在.
我正在使用CUDA Toolkit 5.0,我有一张Quadro 2000卡.
有人成功地做了这个,怎么样?
以下是一些代码提取:
glGenRenderbuffers(1, &rbo_color);
glBindRenderbuffer(GL_RENDERBUFFER, rbo_color);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, WIDTH, HEIGHT);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
if (cudaGraphicsGLRegisterImage(&resource_color, rbo_color, GL_RENDERBUFFER, cudaGraphicsMapFlagsReadOnly) != cudaSuccess)
fprintf(stderr, "Error in registering rbo color with cuda\n");
glGenRenderbuffers(1, &rbo_depth);
glBindRenderbuffer(GL_RENDERBUFFER, rbo_depth);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32F, WIDTH, HEIGHT);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
if (cudaGraphicsGLRegisterImage(&resource_depth, rbo_depth, GL_RENDERBUFFER, cudaGraphicsMapFlagsReadOnly) != cudaSuccess)
fprintf(stderr, "Error in registering rbo depth with cuda\n");
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 opengl 纹理数组来存储大量阴影贴图。不幸的是,我总是在检查帧缓冲区时收到“不完整的附件”错误。我尝试像在 nvidia 的级联阴影映射示例中一样设置我的纹理数组(请参阅 NVIDIA 的级联阴影映射示例)。
所以这里有一些代码:
创建纹理:
glGenTextures(1, &shadowMapArray_);
glBindTexture(GL_TEXTURE_2D_ARRAY, shadowMapArray_);
//maxArrayDepth_ = GL_MAX_ARRAY_TEXTURE_LAYERS
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT, size_, size_, maxArrayDepth_, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
Run Code Online (Sandbox Code Playgroud)创建 FBO:
glGenFramebuffers(1, &fbo_);
glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
glDrawBuffer(GL_NONE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
Run Code Online (Sandbox Code Playgroud)将阴影贴图绘制到图层中:
glUseProgram(programID_);
glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadowMapArray_, 0, currArraySize_);
GLView::checkGLFramebuffer("ShadowMapGenerator::createShadowMap()"); //here i get the incomplete attachment
[...]
currArraySize_++;
Run Code Online (Sandbox Code Playgroud)系统规格:
带有 Nvidia 驱动程序 304.60 和 GTX 560 Ti …
我有一个应用程序,我需要执行以下操作:
我有那么多工作.
接下来,我希望能够将步骤#2移动到单独的共享GL上下文中.
在初始化时,我创建了一个共享上下文:
rootContext = CGLGetCurrentContext();
CGLPixelFormatObj pf = CGLGetPixelFormat(rootContext);
CGLCreateContext(pf, rootContext, &childContext);
Run Code Online (Sandbox Code Playgroud)
...然后使其成为当前并在其上设置帧缓冲...
CGLSetCurrentContext(childContext);
glGenTextures(1, &childTexture);
glBindTexture(GL_TEXTURE_2D, childTexture);
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, image.width(), image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glGenFramebuffers(1, &childFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, childFramebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, childTexture, 0);
Run Code Online (Sandbox Code Playgroud)
然后,当渲染每一帧时,我将childContext当前渲染并渲染到它:
CGLSetCurrentContext(childContext);
glBindFramebuffer(GL_FRAMEBUFFER, childFramebuffer);
glUseProgram(childProgram);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, inputTexture);
glUniform1i(childTextureUniform, 0);
glBindBuffer(GL_ARRAY_BUFFER, childQuadPositionBuffer);
glVertexAttribPointer(childPositionAttribute, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*2, (void*)0);
glEnableVertexAttribArray(childPositionAttribute);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, childQuadElementBuffer);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void*)0);
glDisableVertexAttribArray(childPositionAttribute);
glUseProgram(0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
Run Code Online (Sandbox Code Playgroud)
...然后我创建rootContext …
我想将一个场景绘制到默认的帧缓冲区,同时还将一些与我绘制的模型相关的辅助数据绘制到具有与默认帧缓冲区相同的图像尺寸的屏幕外缓冲区.
我知道我可以分别做两个这样的事情,两个glDraw*调用(一个渲染到一个FBO,一个不渲染),它将使用两个合适的着色器程序.
我认为(仍在学习这一点),我可以做他们大多同时,由两个renderbuffers /纹理连接到一个FBO,做一个glDraw*与它的片段着色器将写入对应于多个FBO适当的值到多个输出一个着色器程序中调用附件,最后将FBO中两个图像中的一个复制到默认帧缓冲区,使用它来构建场景填充四边形或调用glBlitFramebuffer.
但是我可以使用一个着色器程序进行一次glDraw*调用,并让我的片段着色器同时写入可见帧缓冲区和一些屏幕外FBO吗?从我所看到的相关文档中我不怀疑,但我不确定.
我试图渲染为COLOR_ATTACHMENTs的多个纹理而没有成功。通过显示它们,我得到的只是一个黑屏(带有红色透明填充),这意味着我的纹理已读取但为“空”。
我的伪代码是:将3个纹理附加到具有纹理索引1、2和3以及颜色分别为0、1和2的FBO。作为测试用例,我尝试将场景渲染为3个颜色附件,因此它们应该具有相同的精确数据。然后在第2遍着色器(使用2Dsampler)中读取其中一个纹理,并在四边形上显示它们。
我最初打算使用这两种额外的颜色附件,是使用GPU乒乓技术将它们用作随机数据缓冲区。到目前为止,我只是将它们用作纹理克隆以进行测试。
尝试从GL_TEXTURE1(COLOR_ATTACHMENT0)读取时,一切正常,但从其他2(黑屏)来看则没问题。
代码 :
// Texture indices - inside a 'myGlut' struct
GLenum skyboxTextureIndex = GL_TEXTURE0;
GLenum colorTextureIndex = GL_TEXTURE1;
unsigned int colorTextureIndexInt = 1;
GLenum depthTexture1Index = GL_TEXTURE2;
unsigned int depthTexture1IndexInt = 2;
GLenum depthTexture2Index = GL_TEXTURE3;
unsigned int depthTexture2IndexInt = 3;
//** Below is inside 'main()' **//
// Create frame buffer
myGlut.frameBuffer = glutils::createFrameBuffer();
// Create texture to hold color buffer
glActiveTexture(myGlut.colorTextureIndex);
glBindTexture(GL_TEXTURE_2D, myGlut.colorTexture);
myGlut.colorTexture = glutils::createTextureAttachment(myGlut.camera -> getRenderResizedWidthPx(), myGlut.camera …Run Code Online (Sandbox Code Playgroud) 我想将vtkRenderWindow的屏幕外渲染到帧缓冲区对象中.
我不知道该怎么做,但我认为是这样的:
我的问题是 - 我如何用窗口的内容创建vtkFrameBufferObject,所以我可以在屏幕外渲染到FBO?应该如上所述完成吗?
fbo ×10
opengl ×8
c++ ×3
shader ×2
textures ×2
android ×1
arrays ×1
blur ×1
cuda ×1
depth-buffer ×1
framebuffer ×1
macos ×1
opengl-es ×1
video-memory ×1
vtk ×1