How to share textures between an NSOpenGLView and a full screen context in Mac OS?

社会主义新天地 提交于 2019-12-13 14:42:10

问题


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?


回答1:


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.

  1. You created a new NSOpenGLContext initializing it with the same pixel format and inidicating the other context as source for sharing resources. Great!
  2. You should assign it to your NSOpenGLView using the setOpenGLContext method. (no need for update, setview or other things I saw around on the web in very old post)
    • if you've created your window using the xib files, you can use the method awakeFromNib of the NSOpenGLView class to change the default contextto the new one just created
    • the old context attached to the view will be automatically destroyed
    • any preexisitng resource in the shared context will be "imported" in the new one too.
  3. call [your_new_Context makeCurrentContext] - I did it in the awakeFormNib method
  4. (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.



来源:https://stackoverflow.com/questions/5143505/how-to-share-textures-between-an-nsopenglview-and-a-full-screen-context-in-mac-o

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!