NSView doesn't render OpenGL context

Hi ,

I have just written some code to start playing with opengl in cocoa. But it desnt works. Can you tell me why? I have just started coding in cocoa so dont know what is wrong. 😝



MyOpenglView.h :



#import <Cocoa/Cocoa.h>
@interface MyOpenglView : NSView
{
    NSOpenGLPixelFormat* format;
    NSOpenGLContext* context;

}
-(void)prepareOpenGl;
- (void)initGL;
-(void)update;
@end



And MyOpenglView.m :


#import "OpenglView.h"
#import <OpenGL/OpenGL.h>
#import <OpenGL/gl3.h>
@implementation MyOpenglView
- (void)initGL
{
    [context makeCurrentContext];
  
    /
    GLint one = 1;
    [ context setValues:&one forParameter:NSOpenGLCPSwapInterval];
}
-(id)initWithFrame:(NSRect)frame{
    NSOpenGLPixelFormatAttribute attribs[] =
    {
        NSOpenGLPFADoubleBuffer,
        NSOpenGLPFAAllowOfflineRenderers, /
        NSOpenGLPFAMultisample, 1,
        NSOpenGLPFASampleBuffers, 1,
        NSOpenGLPFASamples, 4,
        NSOpenGLPFAColorSize, 32,
        NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core, /
        0
    };
  
    NSOpenGLPixelFormat *pf = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
    if(!pf)
    {
        NSLog(@"Failed to create pixel format.");
        return nil;
    }
  
    self = [super initWithFrame:frame];
    if (self)
    {
        format = pf;
        context = [[NSOpenGLContext alloc] initWithFormat:format shareContext:nil];
      
    }
  
  
    return self;
}
-(void)prepareOpenGl{
    [self initGL];
  
      
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(surfaceNeedsUpdate:)
                                                 name:NSViewGlobalFrameDidChangeNotification
                                               object:self];
  
  
}
- (void)lockFocus
{
    [super lockFocus];
  
    if ([context view] != self)
    {
        [self prepareOpenGl];
      
        [context setView:self];
    }
}
- (void)update
{
        [context update];
  
    }
- (void)surfaceNeedsUpdate:(NSNotification *)notification
{
    [self update];
}
- (void)drawRect:(NSRect)dirtyRect {
    [context makeCurrentContext];
    glClearColor(1,0, 0, 1);
    glClear(GL_COLOR_BUFFER_BIT);
    glFlush();
    [context flushBuffer];
}
@end



Should it show red backgound?


  glClearColor(1,1, 0, 1);
    glClear(GL_COLOR_BUFFER_BIT);

Accepted Reply

If your view is created with interface builder then initWithFrame is not called. Rather, initWithCoder is called and this is what must be overriden in your custom class. Here's some code from something I'm working on:




-(instancetype)initWithCoder:(NSCoder *)decoder

{

NSOpenGLContext *context;

NSOpenGLPixelFormat *format;

self = [super initWithCoder:decoder];

if(self != nil)

{

NSOpenGLPixelFormatAttribute attr[] =

{

NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,

NSOpenGLPFADoubleBuffer,

NSOpenGLPFADepthSize, 24,

NSOpenGLPFAMultisample, 1,

NSOpenGLPFASampleBuffers, 4,

NSOpenGLPFASamples, 4,

NSOpenGLPFAColorSize, 32,

NSOpenGLPFAAccelerated,

0

};

format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr];

[self clearGLContext];

[self setPixelFormat: format];

context = [self openGLContext]; //This will create a new GLContext with the above pixelFormat

[context setView: self ];

}

return self;

}

Replies

If your view is created with interface builder then initWithFrame is not called. Rather, initWithCoder is called and this is what must be overriden in your custom class. Here's some code from something I'm working on:




-(instancetype)initWithCoder:(NSCoder *)decoder

{

NSOpenGLContext *context;

NSOpenGLPixelFormat *format;

self = [super initWithCoder:decoder];

if(self != nil)

{

NSOpenGLPixelFormatAttribute attr[] =

{

NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,

NSOpenGLPFADoubleBuffer,

NSOpenGLPFADepthSize, 24,

NSOpenGLPFAMultisample, 1,

NSOpenGLPFASampleBuffers, 4,

NSOpenGLPFASamples, 4,

NSOpenGLPFAColorSize, 32,

NSOpenGLPFAAccelerated,

0

};

format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr];

[self clearGLContext];

[self setPixelFormat: format];

context = [self openGLContext]; //This will create a new GLContext with the above pixelFormat

[context setView: self ];

}

return self;

}

I doesnt use for this view interface builder :


- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    MyOpenglView* view = [[MyOpenglView alloc]initWithFrame:NSMakeRect(30,30,100,100) ];
    [[_window contentView]addSubview:view];
    [view setNeedsDisplay:YES];
}

Do you know what is wrong?😁 Couse I dont

Add this line to your initWithFrame code:


[context setView: self];