OpenGL 2.1核心上下文与新NSWindow视图间的纹理共享问题
Got it, let's walk through exactly how to set up shared OpenGL contexts using CGLContextObj to render your existing textures in a brand new NSOpenGLView and NSWindow. I’ve tailored this to your OpenGL 2.1 core profile setup, so it should fit right in:
First, you need to get a reference to the CGL context from your existing OpenGL setup. If you’re using an NSOpenGLView for your main rendering, this is straightforward:
// Get the NSOpenGLContext from your original view NSOpenGLContext *originalGLContext = self.mainOpenGLView.openGLContext; // Extract the underlying CGLContextObj CGLContextObj originalCGLContext = [originalGLContext CGLContextObj];
Shared contexts need matching pixel formats to play nice. You can either reuse the pixel format from your original context (best for compatibility) or create a new one with identical attributes:
// Option 1: Reuse the original pixel format (recommended) NSOpenGLPixelFormat *sharedPixelFormat = originalGLContext.pixelFormat; // Option 2: Create a new compatible pixel format (if you need custom tweaks) NSOpenGLPixelFormatAttribute attrs[] = { NSOpenGLPFAColorSize, 24, NSOpenGLPFADepthSize, 16, NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion2_1Core, 0 // End of attributes }; NSOpenGLPixelFormat *sharedPixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
Now create the new context that shares resources with your original one. You can do this via NSOpenGLContext directly, or work with CGL primitives if you prefer:
// Option 1: Using NSOpenGLContext (simpler for Cocoa) NSOpenGLContext *sharedGLContext = [[NSOpenGLContext alloc] initWithFormat:sharedPixelFormat shareContext:originalGLContext]; // Option 2: Direct CGL approach (if you need low-level control) CGLContextObj sharedCGLContext; // Create CGL context, passing the original as the share context CGLCreateContext(sharedPixelFormat.CGLPixelFormatObj, originalCGLContext, &sharedCGLContext); // Wrap it in an NSOpenGLContext for use with NSOpenGLView NSOpenGLContext *sharedGLContext = [[NSOpenGLContext alloc] initWithCGLContext:sharedCGLContext pixelFormat:sharedPixelFormat];
Build your new window and view, then attach the shared context to the view:
// Define the window size and position NSRect windowFrame = NSMakeRect(200, 200, 640, 480); // Create the window with standard style masks NSWindow *sharedWindow = [[NSWindow alloc] initWithContentRect:windowFrame styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable backing:NSBackingStoreBuffered defer:NO]; // Create the NSOpenGLView with our shared pixel format NSOpenGLView *sharedGLView = [[NSOpenGLView alloc] initWithFrame:windowFrame pixelFormat:sharedPixelFormat]; // Assign the shared context to the view sharedGLView.openGLContext = sharedGLContext; // Set the view as the window's content and show it [sharedWindow setContentView:sharedGLView]; [sharedWindow makeKeyAndOrderFront:nil];
Since the contexts share resources, you can directly use the texture IDs from your original context in the new view’s drawRect: method. Here’s a quick example of drawing a full-screen quad with your texture:
- (void)drawRect:(NSRect)dirtyRect { // Make the shared context current for this view [self.openGLContext makeCurrentContext]; // Clear the view to a dark background glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Bind your existing texture (use the same ID from your main context) glBindTexture(GL_TEXTURE_2D, yourExistingTextureID); // Draw a simple quad to display the texture (using immediate mode for simplicity in OpenGL 2.1) glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f); glTexCoord2f(1.0f, 0.0f); glVertex2f(1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex2f(1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, 1.0f); glEnd(); // Flush the buffer to update the view [self.openGLContext flushBuffer]; }
- Match OpenGL Profiles: Both contexts must use the exact same profile (OpenGL 2.1 core in your case). Mismatched profiles will break resource sharing entirely.
- Thread Safety: CGL contexts are tied to the thread they’re created on by default. If your new window runs on a different thread, you’ll need to call
CGLSetCurrentContext(sharedCGLContext)on that thread before rendering, and ensure proper synchronization between threads. - Resource Access: While textures are shared, only one context can modify a resource at a time. If you’re updating the texture in your main context, make sure the shared context isn’t accessing it simultaneously.
内容的提问来源于stack exchange,提问作者JDBones

