iDevGames Forums
Nothing showing up in NSOpenGLView [newb] - Printable Version

+- iDevGames Forums (http://www.idevgames.com/forums)
+-- Forum: Development Zone (/forum-3.html)
+--- Forum: Graphics & Audio Programming (/forum-9.html)
+--- Thread: Nothing showing up in NSOpenGLView [newb] (/thread-9582.html)



Nothing showing up in NSOpenGLView [newb] - binaryinsomnia - Nov 29, 2011 12:23 AM

Hey all,
I'm trying to teach myself OpenGL and Cocoa/Objective-C. I'm a C++/Java developer by trade (so you have some basis of my technical knowledge).

I've been stuck trying to figure out why I can't seem to get, what should be, a simple task working. I'm trying to display a triangle in a window using OpenGL 3.2.

Here is the pertinent method in my AppDelegate.m:
Code:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    // Insert code here to initialize your application
    OGLViewController *oglvc = [[OGLViewController alloc] initWithNibName:nil bundle:nil];    
    
    [oglvc setupViewWithRect:[self.window.contentView bounds]];
    
    [self.window.contentView addSubview:oglvc.view];
    
    [oglvc draw];
}

My custom NSViewController, OGLViewController, implementation is as follows (WARNING: wall o' code):
Code:
//
//  OGLViewController.m
//  TriangleMan
//
//  Created by binaryinsomnia on 11/28/11.
//  Copyright (c) 2011 binaryinsomnia. All rights reserved.
//

#import "OGLViewController.h"
#import "GLProgram.h"
#import "error.h"

#import <OpenGL/gl3.h>

@interface OGLViewController()
{
    GLuint positionAttribute;
    GLuint colorAttribute;
}
@property (retain) GLProgram *oglhelper;
@end

@implementation OGLViewController
@synthesize oglhelper = _oglhelper;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Initialization code here.
    }
    
    return self;
}

-(void)dealloc
{
    [super dealloc];
    
    [_oglhelper release];
}

-(void)setupViewWithRect:(NSRect)aRect
{
    NSOpenGLPixelFormatAttribute pixAttribs[] =
    {
        NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
        NSOpenGLPFAColorSize    , 24                           ,
        NSOpenGLPFAAlphaSize    , 8                            ,
        NSOpenGLPFADoubleBuffer ,
        NSOpenGLPFAAccelerated  ,
        NSOpenGLPFANoRecovery   ,
        0
    };
    
    NSOpenGLPixelFormat *pixFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:pixAttribs];
    
    self.view = [[NSOpenGLView alloc] initWithFrame:aRect pixelFormat:pixFormat];

    [[(NSOpenGLView*)(self.view) openGLContext] makeCurrentContext];
}

-(void)prepareOpenGL
{    
    self.oglhelper = [[GLProgram alloc] initWithVertexShaderFilename:@"Simple"
                                              fragmentShaderFilename:@"Simple"];
    
    [self.oglhelper addAttribute:@"position"];
    [self.oglhelper addAttribute:@"color"];
    
    if (![self.oglhelper link])
    {
        NSLog(@"Link failed");
        
        NSString *progLog = [self.oglhelper programLog];
        NSLog(@"Program Log: %@", progLog);
        
        NSString *fragLog = [self.oglhelper fragmentShaderLog];
        NSLog(@"Frag Log: %@", fragLog);
        
        NSString *vertLog = [self.oglhelper vertexShaderLog];
        NSLog(@"Vert Log: %@", vertLog);
        
        self.oglhelper = nil;
    }
    
    positionAttribute = [self.oglhelper attributeIndex:@"position"];
    colorAttribute    = [self.oglhelper attributeIndex:@"color"];    
}

-(void)addVertexData
{
    GLfloat positionArray[] =
    {
    //   x    y    z    w
        0.0, 0.0, 0.0, 1.0,
        2.0, 0.0, 0.0, 1.0,
        0.0, 1.0, 0.0, 1.0
    };
    
    GLfloat colorArray[] =
    {
    //   r    g    b    a
        1.0, 0.0, 0.0, 1.0,
        0.0, 1.0, 0.0, 1.0,
        0.0, 0.0, 1.0, 1.0
    };
    
    // first, set up the position vertex into the GPU    
    GLuint posVAOId, posVBOId;
    glGenVertexArrays(1, &posVAOId); // get valid VAO
    GetError();
    glBindVertexArray(posVAOId); // bind it to the vertex array
    GetError();
    
    glGenBuffers(1, &posVBOId); // get a valid VBO
    GetError();
    glBindBuffer(GL_ARRAY_BUFFER, posVBOId);  // make it a VBO
    GetError();
    
    // copy data to VRAM
    glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLfloat), positionArray, GL_STATIC_DRAW);
    GetError();
    glVertexAttribPointer(positionAttribute, 3, GL_FLOAT, GL_FALSE, 0, 0);
    GetError();
    glEnableVertexAttribArray(positionAttribute);
    GetError();
    
    // duplication of code... yeah, yeah.
    
    // next, set up the color info into the GPU    
    GLuint colVAOId, colVBOId;
    glGenVertexArrays(1, &colVAOId); // get valid VAO
    GetError();
    glBindVertexArray(colVAOId); // bind it to the vertex array
    GetError();
    
    glGenBuffers(1, &colVBOId); // get a valid VBO
    GetError();
    glBindBuffer(GL_ARRAY_BUFFER, colVBOId);  // make it a VBO
    GetError();
    
    // copy data to VRAM
    glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLfloat), colorArray, GL_STATIC_DRAW);
    GetError();
    glVertexAttribPointer(colorAttribute, 3, GL_FLOAT, GL_FALSE, 0, 0);
    GetError();
    glEnableVertexAttribArray(colorAttribute);
    GetError();
    
    glBindVertexArray(0);
}

-(void)draw
{
    glClearColor(0.0, 0.0, 1.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);
    GetError();
    
    [self prepareOpenGL];
    [self addVertexData];
    
    [self.oglhelper use];
    glDrawArrays(GL_TRIANGLE_FAN, 0, 3);
    
    [[(NSOpenGLView *)(self.view) openGLContext] flushBuffer];
}
@end

I'm using Jeff LaMarche's GLProgram class (https://github.com/jlamarche/iOS-OpenGLES-Stuff/tree/master/Simple%20OpenGL%20ES%202.0%20Example/Classes) to help simplify setting up the shaders/compiling/linking.

So, everything compiles and runs without crashing. But, all I see is a window with nothing drawn or colored. I was hoping to at least have the window colored blue, as I'm not entirely sure that my vertex array was correctly setup.

Do you guys see what can be causing this issue?

Thanks,
binaryinsomnia


RE: Nothing showing up in NSOpenGLView [newb] - OneSadCookie - Nov 29, 2011 01:57 AM

There's so much code here to sift through, and so much done oddly (creating the whole GL view in code?) that it's hard to guess where the problem lies. Perhaps you could post the whole project?

You should also be aware that not all GPUs supported by Lion support OpenGL 3.2. What are you running this on?


RE: Nothing showing up in NSOpenGLView [newb] - binaryinsomnia - Nov 29, 2011 08:00 AM

Hey OneSadCookie,
Thanks for the reply!

I'm trying to setup the GL View programmatically instead of going through InterfaceBuilder. My GL View is taking up the whole window frame, so didn't think I need to work with IB. Of course, perhaps my assumption is incorrect. Smile I was looking at this, https://github.com/beelsebob/Cocoa-GL-Tutorial, to help me get started.

Here's my project: http://www.2shared.com/file/XEUDnkaJ/binaryinsomnia.html

I'm using the 2011 Mac Mini with the AMD discrete GPU.

Thanks,
binaryinsomnia


RE: Nothing showing up in NSOpenGLView [newb] - OneSadCookie - Nov 29, 2011 10:54 AM

Fixed it for you:
http://cl.ly/0O0k2J3d1J361k322O27

1) you can't draw until the view is visible, which doesn't happen until after applicationDidFinishLaunching
2) you were unbinding the VAO but never rebinding the VAO you put data in.

Your code is set up extremely oddly Rasp


RE: Nothing showing up in NSOpenGLView [newb] - binaryinsomnia - Nov 29, 2011 06:41 PM

Sweet! Thank you!

I just checked the changes you'd made. Hmmm... I see you used a block to send the draw message to my view controller. While I've not yet learned about blocks, it seems to me that that is kind of a hack to cover for my extremely odd code. Smile

Speaking of extremely odd code, what makes it odd? How would you go about writing this simple app in the "right way?" I need all the pointers I can get from experienced Cocoa/OpenGL devs as I can get!

In regards to your numerated list...
1) Ah, ok. I need to read up on the lifecycle of a Cocoa app.
2) I have a vague idea what you're talking about there. I'll look over the code to see if I can spot where I'm unbinding and not rebinding the VAO.

Thanks for your time, OneSadCookie!

binaryinsomnia


RE: Nothing showing up in NSOpenGLView [newb] - OneSadCookie - Nov 29, 2011 06:54 PM

Code:
diff -cr binaryinsomnia-cookies/ binaryinsomnia/ | open -f

Yes, both changes were hacks. I imagined you'd take the concept and make it work in a nicer way Wink

You can see what I consider the "normal" way of doing things in https://github.com/OneSadCookie/ either ZeroHour or ObjCGameBase (each slightly different with slightly different flaws).


RE: Nothing showing up in NSOpenGLView [newb] - binaryinsomnia - Nov 29, 2011 07:04 PM

Heh! I fully intend to write this in a more proper form. Smile

Alright, I'll study those examples.

Thanks!