You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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:

1. Grab Your Original CGL Context First

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];
2. Create a Compatible Pixel Format for the Shared Context

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];
3. Initialize the Shared NSOpenGLContext

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];
4. Set Up the New NSWindow and NSOpenGLView

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];
5. Render Your Shared Texture in the New View

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];
}
Critical Tips to Avoid Headaches
  • 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:37:23