如何在Mac OS中在NSOpenGLView和全屏上下文之间共享纹理?

时间:2011-02-28 14:51:38

标签: opengl fullscreen textures sharing 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上下文之间共享纹理是否缺少一些技巧?

1 个答案:

答案 0 :(得分:0)

我最近在OSX上处理了共享上下文,因为没有为了使其工作而应该完成的事情清单。我认为值得分享几个小问题或关键字,以帮助找出问题所在。

建议:使用DirectX和OpenGL等绘图API而没有正确的检查工具(参见开发人员网站的khronos或NVidia)可能会非常痛苦。正确的工具是您需要的第一件事。

  1. 您创建了一个新的NSOpenGLContext,使用相同的像素格式对其进行初始化,并将其他上下文作为共享资源的来源。太好了!
  2. 您应该使用NSOpenGLView方法将其分配给setOpenGLContext。 (不需要updatesetview或我在网上看到的其他很老的帖子)
    • 如果您使用xib文件创建了窗口,则可以使用awakeFromNib类的NSOpenGLView方法将默认上下文更改为刚刚创建的新上下文
    • 附加到视图的旧上下文将自动销毁
    • 共享上下文中的任何预先存在的资源也将在新的资源中“导入”。
  3. 致电[your_new_Context makeCurrentContext] - 我是在awakeFormNib方法
  4. 中完成的
  5. (我认为这是@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);

  6. 希望这可能会有所帮助。仍然建议阅读https://developer.apple.com/library/content/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_contexts/opengl_contexts.html