我想在一个线程中渲染我的场景,然后在另一个线程拥有的窗口中将结果blit.为了避免将帧缓冲区读回到cpu内存,我想使用framebuffer对象.到目前为止,我还没有能够使这个工作(白色纹理),这让我相信opengl不支持这个.
如果有人能指出我在文档中描述的位置,那将是一个奖励.
我有一个子类 CAOpenGLLayer class,它覆盖 drawInCGLContext在那里我画了一个矩形OpenGL.将CAOpenGLLayer被添加到CALayer和示出.
因此,当我想绘制一些内容时,我需要drawInCGLContext使用这种架构.
我想要的是另一种class用于绘制,动画或渲染的上下文,但每次drawInCGLContext出现时都会显示.
所以基本上我的子类应该做的唯一事情就是显示一个遥控器(OpenGL)context,实现这个目标的最佳方法是什么?或者我应该考虑不同的方法?
*不使用a CALayer不是一种选择.
我正在使用SDL2和OpenGL创建一个应用程序,它在3台不同的计算机上运行良好.但是在另一台计算机(更新的arch linux)上,它没有,它崩溃了这个错误:
OpenGL context already created
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:如何检查是否已经创建了OpenGL上下文?然后,如果它已经创建,我该如何获得它的处理?
如果我不能这样做,我该如何绕过这个问题?
我想知道,是否有可能同时在多个GPU上运行多窗口OpenGL应用程序?更具体地说,假设我创建了一个具有两个窗口的应用程序,每个窗口彼此共享它的GL上下文.现在,如果我将其中一个窗口从显示器1(在GPU 1上运行)移动到显示器2(在GPU 2上运行),这实际上是否有效?单独分享上下文是否可以解决问题?
我的第一个猜测是否定的.如果这真的不那么简单,有没有办法实现这一目标?我还可以想象这取决于两个GPU是否由相同的驱动程序控制(更糟糕的是,让机器有ATI和nVidia卡,两者都支持不同的GL版本).
我很感激有关这个主题的任何见解,纯信息,因为我快速谷歌搜索后找不到任何东西.有谁知道可能性?
编辑:顺便说一句,不幸的是我目前没有多台GPU可用的机器,所以我会测试一下.
在苹果的文档中,我读到了这个:
所以我希望能够创建一次我的缓冲区对象,然后使用它们在多个上下文中同时渲染。但是,如果我这样做,我的 NVIDIA GeForce GT 650M 就会崩溃,回溯如下:
Crashed Thread: 10 Dispatch queue: com.apple.root.default-qos
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: EXC_I386_GPFLT
…
Thread 10 Crashed:: Dispatch queue: com.apple.root.default-qos
0 GLEngine 0x00007fff924111d7 gleLookupHashObject + 51
1 GLEngine 0x00007fff925019a9 gleBindBufferObject + 52
2 GLEngine 0x00007fff9243c035 glBindBuffer_Exec + 127
Run Code Online (Sandbox Code Playgroud)
我已经在https://gist.github.com/jlstrecker/9df10ef177c2a49bae3e发布了我的完整代码。在顶部,有#define SHARE_BUFFERS- 当被注释掉时它工作得很好,但取消注释它会崩溃。
我不想争论我是否应该使用 OpenGL 2.1——这是我正在使用的其他软件的要求。我也不想争论我是否应该使用 GLUT——我的示例代码只是使用它,因为它包含在 Mac 上并且没有任何外部依赖项。我也不是在寻找关于性能/优化的反馈。
我只想知道我是否可以期望能够在多个上下文中同时从单个共享缓冲区对象进行渲染——如果是这样,为什么我的代码会崩溃。
我在我的应用程序中使用了两个 OpenGL 上下文。
第一个用于渲染数据,第二个用于后台加载和生成 VBO 和纹理。
当我的加载上下文生成一个 VBO 并将其发送到我的渲染线程时,我在我的 VBO 中得到无效数据(全零),除非我调用glFlush或glFinish在加载上下文上创建 VBO 之后。
我认为这是由于我的加载上下文没有任何缓冲区交换或任何告诉 GPU 开始在其命令队列上工作并且什么都不做的东西(这导致渲染上下文端的 VBO 为空)。
从我所见,这种刷新在 Windows 上不是必需的(用 Nvidia GPU 测试,即使没有刷新也能工作),但在 linux/macOS 上是必需的。
苹果文档上的这个页面说调用glFlush是必要的(https://developer.apple.com/library/archive/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/OpenGLESApplicationDesign/OpenGLESApplicationDesign.html)
如果您的应用程序在多个上下文之间共享 OpenGL ES 对象(例如顶点缓冲区或纹理),您应该调用 glFlush 函数来同步对这些资源的访问。例如,您应该在一个上下文中加载顶点数据后调用 glFlush 函数,以确保其内容已准备好被另一个上下文检索。
但是调用glFinish还是glFlush必要的,或者是否有更简单/更轻松的命令可用于实现相同的结果?(这是必要的,glFlush还是glFinish?)
另外,是否有文档或参考文献讨论过这个问题?我找不到任何提及,并且在实现之间的工作方式似乎有所不同。
在我的代码中,我有一个由两个缓冲区对象和一个顶点数组对象支持的对象的包装类。我在构造函数中使用它生成它们(稍微简化):
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &ibo);
glGenBuffers(1, &vbo);
printf("Ind buffers %d %d %d\n", vao, ibo, vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
Run Code Online (Sandbox Code Playgroud)
printf 在主线程上的前几个创建中给出了这个。
Ind buffers 1 1 2
Ind buffers 3 4 5
Ind buffers 4 6 7
Ind buffers 5 8 9
Ind buffers 6 10 11
Ind buffers 7 12 13
Run Code Online (Sandbox Code Playgroud)
中间有一个非索引的,它需要 VAO #2 和缓冲区 #3。这对我来说看起来不错。每个数组对象都附有两个唯一的缓冲区。
我稍后也使用此代码加载后台资源(而不是生成它们)。每个线程都有自己的上下文,使用 glfwCreateContext 创建并与主窗口共享资源。首次创建这些资源时,会出现以下输出:
Ind buffers 1 14 15
Ind buffers 1 16 17
Ind buffers 1 18 19
Ind buffers 1 20 24 …Run Code Online (Sandbox Code Playgroud) 我有一个 Windows 应用程序,可以创建多个视图窗口,可以使用 OpenGL (3.2+) 渲染一些模型。每个窗口都可以渲染它自己的独立对象,或者两个(或更多)窗口可以渲染相同的对象(但例如从不同的相机角度):

在阅读了 stackoverflow 上的各种帖子后,我决定创建一个 OpenGL 上下文 (HGLRC),对于我渲染到的每个窗口 (HDC),我切换为
wglMakeCurrent(targetWindowHDC, m_deviceContext)
Run Code Online (Sandbox Code Playgroud)
正如您在屏幕截图中所看到的,这似乎工作得很好(窗口代码发生在主线程上,对于渲染,我有自己的 RenderThread,所有 OpenGL 操作都限制在其中)。对于每个窗口,我都会渲染到 FBO(如果用户激活它,则该 FBO 具有 MSAA 支持),只有在场景中的某些内容发生变化时才会更新,否则它只会按原样将其绘制到窗口。
现在我的问题是,每次切换到绘图到另一个窗口时都必须设置什么状态?我的方法在性能方面合理吗?
这是我现在每次将上下文设为另一个 HDC 的当前上下文后设置的内容:
glClearDepth( 1.0f );
glClearColor( color.r, color.g, color.b, 1.0f );
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glDepthFunc(GL_LEQUAL);
glDepthRange(0.0f, 1.0f);
glPointSize(3.0f);
glEnable(GL_BLEND);
glBlendFunc( srcBlend, dstBlend );
glPolygonMode( GL_FRONT_AND_BACK, targetType );
glEnable( GL_CULL_FACE );
glCullFace( GL_BACK );
glViewport( 0, 0, vp.width, vp.height );
Run Code Online (Sandbox Code Playgroud)
这些基本上是用户设置渲染窗口时可以更改的所有设置,因此我需要在渲染每个窗口之前确保它们设置正确。
但真的有必要拨打所有这些电话吗?这意味着在上面有 4 个渲染窗口的示例中,我需要每帧调用这些窗口 4 次。有没有更好的办法?使用多个 GL 上下文会更高效吗?
我是U/I编程的新手,我正在尝试使用OpenGL.当我运行一个用GLUT创建一个新的OpenGL窗口的示例程序时,它工作正常.好.但是,在另一个程序的上下文中,我必须响应Draw事件(在Windows上),传递给我的设备上下文 - 以及我可能没有GLUT可用的地方 - 我的困惑是:
什么时候创建和销毁设备上下文?我可以绘制给我的任何设备上下文,或只有其中一些(我怎么知道)?
我是否必须创建自己的OpenGL上下文并使用它来绘制,或者我可以使用"当前"的OpenGL上下文?每次发送绘制事件时,是否必须重新创建上下文?
基本上我的问题是,鉴于我被发送"Draw"事件的情况,我多久尝试创建一次OpenGL上下文,以及这与设备上下文的创建/销毁周期有何关系?
我想使用openGL的某些功能,但与呈现可视内容无关.有没有办法在没有任何依赖项的情况下创建它(不是对windows,也不是某些包[SDL,SFML,GLUT])?只允许使用的库是没有外部库的库,就像我使用的GLEW一样.