如何在 Mac OS 中的 NSOpenGLView 和全屏上下文之间共享纹理?
我正在开发一个使用 2D 纹理创建动画万花筒的应用程序。它开始显示到 NSOpenGLView。我正在添加一个切换到全屏模式的选项。
我更喜欢使用 OS 10.5 方法来全屏,这样我就可以支持 10.5,但我认为如果我使用“在 Mac OS X v10 中创建全屏应用程序”下的文档中描述的方法,我会面临同样的问题.6"。
NSOpenGLContext init 方法 initWithFormat:shareContext: 采用一个可选指针,指向“另一个 OpenGL 图形上下文,其纹理命名空间和显示列表要与接收者共享”。
我用来创建全屏 OpenGL 上下文的代码很简单:
NSOpenGLPixelFormatAttribute myAttributes[] = // Pixel Format Attributes for the FullScreen NSOpenGLContext
{
NSOpenGLPFAFullScreen, // specify full-screen OpenGL context
NSOpenGLPFAScreenMask,
CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), // specify main display
NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute) 32,
NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute) 0,
NSOpenGLPFAStencilSize, 0,
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAAccelerated,
0
};
NSOpenGLPixelFormat *myPixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:myAttributes]; // Create FullScreen NSOpenGLContext with these attributes
NSOpenGLContext *fullScreenContext = [[NSOpenGLContext alloc] initWithFormat:myPixelFormat shareContext: myContext]; // Create an NSOpenGLContext with the FullScreen pixel format.
但是,它似乎不起作用。
我的应用程序仅使用一种纹理,因此我一开始不使用 glGenTextures 和 glBindTexture。相反,我只是使用单个当前纹理作为上下文。
我尝试更改代码以使用 glGenTextures 创建命名纹理,希望在切换到全屏上下文后可以绑定命名纹理,但没有骰子。两种方法给出相同的结果 - 纹理在全屏上下文中不起作用。
我没有收到任何错误,但使用纹理绘图没有任何作用。
每次切换到全屏模式时,我都被迫重新创建纹理。这很糟糕,因为纹理可能非常大(取决于用户加载的图像有多大,直到最大纹理大小。)这迫使我将一个非常大的对象的两个副本加载到 VRAM 中。更糟糕的是,在某些情况下我必须进行字节混合才能获得正确的字节顺序。在大纹理上这需要几秒钟的时间,这会在进入全屏模式时造成“怀孕暂停”。
在 NSOpenGLView 和全屏 OpenGL 上下文之间共享纹理是否缺少一些技巧?
I am working on an app that uses 2D textures to create animated kaleidoscopes. It starts out displaying to an NSOpenGLView. I am adding an option to switch to full-screen mode.
I would prefer to use the OS 10.5 approach to full screen so I can support 10.5, but I think I would face the same issue if I was using the approach described in the docs under "Creating a Full-Screen Application in Mac OS X v10.6".
The NSOpenGLContext init method initWithFormat:shareContext: takes an optional pointer to "Another OpenGL graphics context whose texture namespace and display lists you want to share with the receiver".
The code I'm using to create the full screen OpenGL context is straightforward:
NSOpenGLPixelFormatAttribute myAttributes[] = // Pixel Format Attributes for the FullScreen NSOpenGLContext
{
NSOpenGLPFAFullScreen, // specify full-screen OpenGL context
NSOpenGLPFAScreenMask,
CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), // specify main display
NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute) 32,
NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute) 0,
NSOpenGLPFAStencilSize, 0,
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAAccelerated,
0
};
NSOpenGLPixelFormat *myPixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:myAttributes]; // Create FullScreen NSOpenGLContext with these attributes
NSOpenGLContext *fullScreenContext = [[NSOpenGLContext alloc] initWithFormat:myPixelFormat shareContext: myContext]; // Create an NSOpenGLContext with the FullScreen pixel format.
However, it doesn't seem to work.
My app only uses one texture, so I started out not using glGenTextures and glBindTexture. Instead I just used the single current texture for the context.
I tried changing my code to create a named texture with glGenTextures, in the hopes that I could bind the named texture after switching to the full-screen context, but no dice. Both approaches give the same result - the texture does not work in the full screen context.
I don't get any errors, but drawing with a texture doesn't do anything.
I am forced to recreate my texture each time I switch to full-screen mode. This is bad because the textures are potentially very large (depending on how big an image the user loads, up to the max texture size.) That forces me to load two copies of a very large object into VRAM. Worse, I have to do byte-swizzling in some cases to get the byte order correct. That takes several seconds on a large texture, which makes for a "pregnant pause" when entering full-screen mode.
Is there some trick I'm missing to sharing textures between an NSOpenGLView and a full screen OpenGL context?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这些天我致力于 OSX 上的共享上下文,但苦于缺乏一个应该完成的事情清单以使其正常工作。我认为值得分享一些小事情或关键字,它们可以帮助找出您的案例中的问题所在。
建议:如果没有正确的检查工具(请参阅 khronos 或 NVidia 的开发人员网站),使用 DirectX 和 OpenGL 等绘图 API 可能会非常痛苦。一个合适的工具是您首先需要的。
NSOpenGLContext
,使用相同的像素格式对其进行初始化,并将其他上下文指示为共享资源的源。伟大的!setOpenGLContext
方法将其分配给您的NSOpenGLView
。 (不需要update
、setview
或我在网上看到的非常旧的帖子中的其他内容)xib
文件创建了窗口,则可以使用NSOpenGLView
类的awakeFromNib
方法来更改默认值上下文到刚刚创建的新上下文[your_new_Context makeCurrentContext]
- 我在awakeFormNib
方法中完成了(这里我认为是@Duncan的问题),你需要设置所有渲染说明你需要。渲染状态不跨上下文共享!只有资源。这些是您想要设置的一些渲染状态(根据您的需要更改它们):
glEnableVertexAttribArray(pgmImagePosition_);
glEnableVertexAttribArray(pgmImageTextureCoord_);
glEnable(GL_TEXTURE_2D);
glDisable(GL_DITHER);
glDisable(GL_ALPHA_TEST);
glDisable(GL_BLEND);
glDisable(GL_STENCIL_TEST);
glDisable(GL_FOG);
glDisable(GL_DEPTH_TEST);
glPixelZoom(1.0,1.0);
glClearColor(0.1, 0.1, 0.1, 1.0);
希望这会有所帮助。阅读 https://developer仍然建议使用 .apple.com/library/content/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_contexts/opengl_contexts.html。
I worked on the shared context on OSX in these days, struggling for the absence of a checklist of thing that should be done in order to make it work. I think it's worth to share a couple of little things or keyword that can help to find out where the problem is in your case.
Advise: working with drawing API like DirectX and OpenGL without the right inspection tool (see khronos or NVidia for developer website) can be very painful. A right tool is the first thing you need.
NSOpenGLContext
initializing it with the same pixel format and inidicating the other context as source for sharing resources. Great!NSOpenGLView
using thesetOpenGLContext
method. (no need forupdate
,setview
or other things I saw around on the web in very old post)xib
files, you can use the methodawakeFromNib
of theNSOpenGLView
class to change the default contextto the new one just created[your_new_Context makeCurrentContext]
- I did it in theawakeFormNib
method(And here I think is the problem of @Duncan), you need to set all the rendering state you need. The rendering state are not shared accross context! Only the resources. Those are some of the render state you want to set (change them according to your needs):
glEnableVertexAttribArray(pgmImagePosition_);
glEnableVertexAttribArray(pgmImageTextureCoord_);
glEnable(GL_TEXTURE_2D);
glDisable(GL_DITHER);
glDisable(GL_ALPHA_TEST);
glDisable(GL_BLEND);
glDisable(GL_STENCIL_TEST);
glDisable(GL_FOG);
glDisable(GL_DEPTH_TEST);
glPixelZoom(1.0,1.0);
glClearColor(0.1, 0.1, 0.1, 1.0);
Hope this may help. A reading of https://developer.apple.com/library/content/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_contexts/opengl_contexts.html is still suggested.