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

标签 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 创建命名纹理,希望在切换到全屏上下文后可以绑定(bind)命名纹理,但没有骰子。两种方法都给出了相同的结果——纹理在全屏环境中不起作用。

我没有收到任何错误,但是用纹理绘制不会做任何事情。

每次切换到全屏模式时,我都被迫重新创建纹理。这很糟糕,因为纹理可能非常大(取决于用户加载的图像有多大,直到最大纹理大小。)这迫使我将一个非常大的对象的两个副本加载到 VRAM 中。更糟糕的是,在某些情况下,我必须进行字节转换才能使字节顺序正确。在大纹理上这需要几秒钟,这会在进入全屏模式时造成“怀孕暂停”。

在 NSOpenGLView 和全屏 OpenGL 上下文之间共享纹理是否缺少一些技巧?

最佳答案

这些天,我在 OSX 上处理共享上下文,为没有一个应该做的事情 list 而苦苦挣扎。我认为值得分享一些小事或关键字,以帮助找出问题所在。

建议:在没有正确检查工具的情况下使用 DirectX 和 OpenGL 等绘图 API(请参阅开发人员网站的 khronos 或 NVidia)可能会非常痛苦。正确的工具是您首先需要的。

  • 您创建了一个新的 NSOpenGLContext使用相同的像素格式对其进行初始化,并将其他上下文指示为共享资源的源。伟大的!
  • 你应该把它分配给你的NSOpenGLView使用 setOpenGLContext方法。 (不需要 updatesetview 或我在非常旧的帖子中在网上看到的其他内容)
  • 如果您使用 xib 创建了窗口文件,可以使用awakeFromNib的方法的NSOpenGLView类将默认上下文更改为刚刚创建的新上下文
  • 附加到 View 的旧上下文将自动销毁
  • 共享上下文中的任何预先存在的资源也将在新资源中“导入”。
  • 调用[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仍然建议。

    关于opengl - 如何在 Mac OS 中的 NSOpenGLView 和全屏上下文之间共享纹理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5143505/

    相关文章:

    c++ - 无法编译此 SDL 类(class)... :/

    c++ - 三角形不渲染

    android - 应用程序从 SplashScreenActivity(全屏)移动到 MainActivity(非全屏)时出现

    安卓应用全屏

    c++ - 使用 GLUT 的多重纹理

    opengl - 是否有最大允许数量的帧缓冲区对象?

    c++ - 用 OpenGL 模糊?

    vb.net - 使 Winforms 全屏显示

    cuda - 绑定(bind)的 CUDA 纹理读数为零

    algorithm - 查找两个图像之间的图像子集