问题
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.
- You created a new
NSOpenGLContext
initializing it with the same pixel format and inidicating the other context as source for sharing resources. Great! - You should assign it to your
NSOpenGLView
using thesetOpenGLContext
method. (no need forupdate
,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 methodawakeFromNib
of theNSOpenGLView
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.
- if you've created your window using the
- call
[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.
来源:https://stackoverflow.com/questions/5143505/how-to-share-textures-between-an-nsopenglview-and-a-full-screen-context-in-mac-o