Using an offscreen context as a texture

Member
Posts: 269
Joined: 2005.04
Post: #1
So I'm using NSOpenGLContext to create an offscreen context that I can draw into. Then I'm trying to use -createTexture:fromView:internalFormat: to make the context a texture that I can then use in my main view. While I can draw into the offscreen context fine, I can't seem to get createTexture to work properly.

Warning: sloppily edited spaghetti code incoming

Code:
- (id)initWithFrame:(NSRect)frame
{
    NSOpenGLPixelFormat                *format;
    NSOpenGLPixelFormatAttribute    attributes[] = {NSOpenGLPFAAccelerated, NSOpenGLPFAWindow, NSOpenGLPFAColorSize, 16, NSOpenGLPFADepthSize, 16, NSOpenGLPFAStencilSize, 1, NULL};

    // Set up code for main context here
        
    [[self openGLContext] makeCurrentContext];
            
    // Set up OpenGL for main context here

    //Create offscreen context
    offscreenWindow = [[NSWindow alloc] initWithContentRect:NSMakeRect(0,0,480,480) styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
    format = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attributes] autorelease];
    offscreenContext = [[NSOpenGLContext alloc] initWithFormat:format shareContext:[self openGLContext]];
    [[offscreenWindow contentView] display];
    [offscreenWindow orderFront:nil];
    [offscreenContext setView:[offscreenWindow contentView]];
    [offscreenContext makeCurrentContext];

    // Set up offscreen OpenGL here
            
    [[self openGLContext] makeCurrentContext];
            
    glEnable(GL_TEXTURE_2D);
    glGenTextures(1, &offscreenTexID);
    glBindTexture(GL_TEXTURE_2D, offscreenTexID);
    [[self openGLContext] createTexture:GL_TEXTURE_2D fromView:[offscreenWindow contentView] internalFormat:GL_RGB];
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}

- (void) drawStuff
{
    if (draw in offscreen)
        [offscreenContext makeCurrentContext];
    else
        [[self openGLContext] makeCurrentContext];

    // Draw stuff here, works fine

    if (time to use offscreen as texture)
    {
        glFlush();

        [[self openGLContext] makeCurrentContext];

        glBindTexture(GL_TEXTURE_2D, offscreenTexID);

        // Attempt to draw stuff. Draws without a texture
    }
}

Is there something I'm forgetting to do? Do I not have something set up correctly for createTexture? Any other code you need to see?
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #2
480x480 = invalid size for GL_TEXTURE_2D. Use power of two dimensions, or switch to rectangle textures (and drop Rage128 support.)

Another thing that you definitely need to do is to specify the display mask for the offscreen context and the shared context, to ensure they are being created on the same GPU. Otherwise, when Brad Oliver runs your application you'll get zero points. :/

See the Shoot Things source for a fully working example.
Quote this message in a reply
Member
Posts: 269
Joined: 2005.04
Post: #3
arekkusu Wrote:480x480 = invalid size for GL_TEXTURE_2D. Use power of two dimensions, or switch to rectangle textures (and drop Rage128 support.)

*smacks forehead*

The texture draws now, but it seems to be badly corrupted.

Here's a snippet of the texture.

I'm at a loss.
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #4
It sort of looks like the backing store for the offscreen window has been resized after the context was attached, and [offscreenContext update] was never called.

FWIW, Shoot Things sticks an NSOpenGLView into the offscreen window's contentView. That view will automatically handle the resize and update setup.

Also just the obvious stuff, in your offscreen GL setup your viewport size should match the window size, you've cleared the back buffer, etc...
Quote this message in a reply
Member
Posts: 269
Joined: 2005.04
Post: #5
arekkusu Wrote:It sort of looks like the backing store for the offscreen window has been resized after the context was attached, and [offscreenContext update] was never called.

FWIW, Shoot Things sticks an NSOpenGLView into the offscreen window's contentView. That view will automatically handle the resize and update setup.

Also just the obvious stuff, in your offscreen GL setup your viewport size should match the window size, you've cleared the back buffer, etc...

Tried adding the NSOpenGLView to see if that might fix it, but it didn't. On a lark I switched to using GL_TEXTURE_RECTANGLE_EXT instead of GL_TEXTURE_2D even though I had resized the context to 512 by 512 and it worked immediately.

So either I found a bug or Apple needs better documentation (or both).
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #6
Hmm... what hardware is this on? I've successfully gotten render-to-texture contexts to work with GL_TEXTURE_2D on Rage128 iMacs, so it *does* work... but, I've not tested that on other GPUs since rectangle textures are always better there.

Actually, now I remember reading that on nvidia cards you HAVE to use rectangle textures for render-to-texture because of an architecture limit (unswizzled internal storage or something.) On ATI cards either one should work, though.

[Edit: see threads one, two. The rule is, if you have rectangle textures, use them.]
Quote this message in a reply
Member
Posts: 269
Joined: 2005.04
Post: #7
It's on a FX5200, so that explains that.

Good to know that it wasn't *entirely* my fault and that I'm not going completely crazy. Wink
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Full screen context doesn't remain the current context Malarkey 3 3,564 Feb 1, 2007 05:27 PM
Last Post: OneSadCookie
  shared context breaking FTGL texture fonts akb825 12 6,627 Sep 7, 2006 08:56 PM
Last Post: akb825
  resizing offscreen drawable from 2nd thread arekkusu 11 5,421 Feb 8, 2005 09:09 AM
Last Post: TomorrowPlusX