Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Soulstorm

macrumors 68000
Original poster
Feb 1, 2005
1,887
1
All my OpenGL work was previewsly done on Carbon, Full Screen with GLUT. But now, I want to create everything inside a Cocoa NSOpenGLView. I create the project, subclass OpenGLView, and write my code. here is my code:

Code:
static void drawAnObject ()
{
	glColor3f(1.0f, 0.85f, 0.35f);
	glBegin(GL_TRIANGLES);
	{
		glVertex3f(  0.0,  0.6, 0.0);
		glVertex3f( -0.1, -0.2, 0.0);
		glVertex3f(  0.1, -0.2 ,0.0);
	}
	glEnd();
}

@implementation MyOpenGLView

-(void)awakeFromNib
{
}

- (void)drawRect:(NSRect)rect
{
       NSLog(@"%f", [self bounds].size.width);
       glClearColor(0, 0, 0, 0);
       glClear(GL_COLOR_BUFFER_BIT);
       drawAnObject();
    
	glFlush();

}


@end

However, I don't want to work into this coordinate space. That way, in order to draw something, I will have to use numbers less than 1.0. So, I try to Change the view to have other coordinates. Here is my new code.

Code:
static void drawAnObject ()
{
	glColor3f(1.0f, 0.85f, 0.35f);
	glBegin(GL_TRIANGLES);
	{
		glVertex3f(  0.0,  60, 0.0);
		glVertex3f( -10, -20, 0.0);
		glVertex3f(  10, -20 ,0.0);
	}
	glEnd();
}

@implementation MyOpenGLView


- (void)drawRect:(NSRect)rect
{
	//glViewport(-100, 100, -100, 100);
	glClearColor(0, 0, 0, 0);
	glClear(GL_COLOR_BUFFER_BIT);
	
	glOrtho(-100, 100, -100, 100, -10, 10);
	glClearColor(0, 0, 0, 0);
	
    
    drawAnObject();
    
	glFlush();

}


@end

I get what I wanted... but for only half a second! The image of a triangle is displayed for 0.1 secs, and then disappears!

EDIT: Here is something a bit strange (at least to me). I changed the code so that the drawing function would happen only ONCE in the program (of course that way, any redraw to the image view will render it useless). However, the image is displayed correctly:
Code:
int test = 1;

static void drawAnObject ()
{
	NSLog(@"drawn object!");
	glColor3f(1.0f, 0.85f, 0.35f);
	glBegin(GL_TRIANGLES);
	{
		glVertex3f(  0.0,  60, 0.0);
		glVertex3f( -10, -20, 0.0);
		glVertex3f(  10, -20 ,0.0);
	}
	glEnd();
}

@implementation MyOpenGLView

-(void)awakeFromNib
{
	
}

- (void)drawRect:(NSRect)rect
{
	NSLog(@"redraw");
	glClearColor(0, 0, 0, 0);
	glClear(GL_COLOR_BUFFER_BIT);
	
	glOrtho(-100, 100, -100, 100, -1, 1);
	
    drawAnObject();
    
	if (test == 1) {
		[[self openGLContext]flushBuffer];
		test = 0;
	}
}


@end

So, something happens when the image is drawn more than once...
Can anyone help me?
 

Attachments

  • Picture 1.png
    Picture 1.png
    1.7 KB · Views: 230

Soulstorm

macrumors 68000
Original poster
Feb 1, 2005
1,887
1
Anyone? I know the problem is easy to solve, I am just too newbie to figure it out...
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
Anyone? I know the problem is easy to solve, I am just too newbie to figure it out...

Hey, you posted in the middle of the night for those of us in the US ;)

I don't know the exact problem since OpenGL is a pain in the arse to work with, but
here is some sample code from Apple where they are using the glOrtho() and glViewport() functions. Maybe you could figure it out based off of that.
 

Gelfin

macrumors 68020
Sep 18, 2001
2,165
5
Denver, CO
Anyone? I know the problem is easy to solve, I am just too newbie to figure it out...

It's been nearly a decade since I've done any work with OpenGL, so there's only so much help I can be, but I think glOrtho will produce a persistent change in the current matrix, so you only need to call it once. By calling it every time you perform a draw, you're offsetting your triangle more and more each frame.

I could be SO wrong, but give it a try.
 

Sin

macrumors regular
Jun 25, 2007
152
0
Not London
It's been nearly a decade since I've done any work with OpenGL, so there's only so much help I can be, but I think glOrtho will produce a persistent change in the current matrix, so you only need to call it once. By calling it every time you perform a draw, you're offsetting your triangle more and more each frame.

I could be SO wrong, but give it a try.

Indeed. Even if you do that, you should also really initialise the matrix stack first.

The OP also doesn't seem to be using the seperate matrix stacks for projection and object matrices.

The usual way to set up OpenGL would be:

At initialisation / resize:

glSetViewport()
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho() / gluPerspective()

When rendering:

glMatrixMode(GL_MODELVIEW)
glLoadIdentity()

and then proceed to apply transforms, push/pop the matrix stack, and render stuff.
 

Soulstorm

macrumors 68000
Original poster
Feb 1, 2005
1,887
1
This code does not work:
Code:
#import "MyOpenGLView.h"

int test = 1;

static void drawAnObject ()
{
	NSLog(@"drawn object!");
	
	glColor3f(1.0f, 0.85f, 0.35f);
	glBegin(GL_TRIANGLES);
	{
		glVertex3f(  0.0,  60, 0.0);
		glVertex3f( -10, -20, 0.0);
		glVertex3f(  10, -20 ,0.0);
	}
	glEnd();
}

@implementation MyOpenGLView

-(void)awakeFromNib
{
	//glViewport(0, 0, NSWidth([self bounds]), NSHeight([self bounds]));
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(-100, 100, -100, 100, -10, 10);
	
}

- (void)drawRect:(NSRect)rect
{
	
	glLoadIdentity();
	glMatrixMode(GL_MODELVIEW);
	NSLog(@"redraw");
	NSRect bounds = [self bounds];
	
	
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glClearColor(0, 0, 0, 0);
	drawAnObject();
    	
	
	[[self openGLContext]flushBuffer];
}


@end

However, this one does.

Code:
#import "MyOpenGLView.h"

int test = 1;

static void drawAnObject ()
{
	NSLog(@"drawn object!");
	
	glColor3f(1.0f, 0.85f, 0.35f);
	glBegin(GL_TRIANGLES);
	{
		glVertex3f(  0.0,  60, 0.0);
		glVertex3f( -10, -20, 0.0);
		glVertex3f(  10, -20 ,0.0);
	}
	glEnd();
}

@implementation MyOpenGLView

- (void)drawRect:(NSRect)rect
{
	glLoadIdentity();
	glMatrixMode(GL_MODELVIEW);
	NSLog(@"redraw");
	NSRect bounds = [self bounds];
	
	glViewport(0, 0, NSWidth(bounds), NSHeight(bounds));
	glOrtho(-100, 100, -100, 100, -10, 10);
		
	glClearColor(0, 0, 0, 0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	drawAnObject();
    	
	
	[[self openGLContext]flushBuffer];
}


@end

Seems I didn't need to do any initializations. A call to glLoadIdentity solved the problem.
 

Sin

macrumors regular
Jun 25, 2007
152
0
Not London
This code does not work:

...

Seems I didn't need to do any initializations. A call to glLoadIdentity solved the problem.

Your first attempt probably didn't work because you did your LoadIdentity at the top of the Draw routine, *before* you set the matrix-stack to MODELVIEW. On the first iteration it was probably still set to PROJECTION and thus you would have trashed your initialised projection matrix.

As a rule, *always* set your matrix stack to what you expect before you poke matrices in, or otherwise always leave it in a known state. Either you need to set MODELVIEW at the end of your initialisation step or at the top of the draw call.

Your working version still does the LoadIdentity before setting up the stack, but now when you've set the MODELVIEW matrix up you call it again and stuff an orthogonal transform at the top of it.

They way you have it now may work for now, but sooner or later you're could run into problems if you misuse the matrix stacks. For example you're not really going to be giving GL many clues about what spaces you're performing things like lighting in. If you start to apply shaders and ask for a particular transform matrix, you'll get given the wrong thing.

The distinction between different parts of the transform might seem a bit pointless when you just want to throw some graphics at the screen (and indeed if you don't need the intermediate stages it probably is) - but I think it's important to know that these intermediate transforms are useful for all kinds of things, and sooner or later you'll probably find yourself needing them. So you'll make life easier in the long run if you separate them out from the start.

Just some advice...
 

Soulstorm

macrumors 68000
Original poster
Feb 1, 2005
1,887
1
Thanks for the advice. I will surely look at it. So, if I understand correctly, you tell me that for now, this will work ok, but when I proceed to advanced graphics options like lighting and shaders, I will have to split my code, right?

I also have another question: Lets just say that I want to enable lighting in my project. So, I want to place the setup functions outside the drawRect function. Where would I put those? If I put them inside the -awakeFromNib function, the program will crash without telling me why.

Here is some sample code that works so far for me.

Code:
#import "MyOpenGLView.h"


GLfloat ambientLight[] = { 0.3, 0.3, 0.3, 1.0 };
GLfloat diffuseLight[] = { 0.7, 0.7, 0.7, 1.0 };
GLfloat lightPosition[] = { 1.0f, 1.0f, 1.0f, 0.0f };
GLfloat  spotDir[] = { 0.0f, 0.0f, -1.0f };


GLfloat no_mat[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat mat_ambient[] = { 0.7, 0.7, 0.7, 1.0 };
GLfloat mat_ambient_color[] = { 0.8, 0.8, 0.2, 1.0 };
GLfloat mat_diffuse[] = { 0.1, 0.5, 0.8, 1.0 };
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat no_shininess[] = { 0.0 };
GLfloat low_shininess[] = { 5.0 };
GLfloat high_shininess[] = { 100.0 };
GLfloat mat_emission[] = { 0.3, 0.2, 0.2, 0.0 };

static void drawAnObject ()
{
	NSLog(@"drawn object!");
	
	glutSolidSphere(50,50,50);
}

static void applyLighing()
{
	glEnable(GL_DEPTH_TEST);	// Hidden surface removal
    glEnable(GL_CULL_FACE);		// Do not calculate inside of jet
    glFrontFace(GL_CCW);		// Counter clock-wise polygons face out
	glShadeModel(GL_SMOOTH);
	
	glEnable(GL_LIGHTING);
	glLightfv(GL_LIGHT0,GL_AMBIENT,ambientLight);
	glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight);
	glLightfv(GL_LIGHT0,GL_POSITION,lightPosition);
	
	glMaterialfv(GL_FRONT,GL_SHININESS,low_shininess);
	glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);
	glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);
	
	glEnable(GL_LIGHT0);
}

@implementation MyOpenGLView
- (id) init
{
	self = [super init];
	if (self != nil) {
		xRot = 0;
		yRot = 0;
		zRot = 0;
		
		
		
	}
	return self;
}

- (void)drawRect:(NSRect)rect
{
	applyLighing();
	
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	
	NSLog(@"redraw");
	NSRect bounds = [self bounds];
	
	glViewport(0, 0, NSWidth(bounds), NSHeight(bounds));
	glOrtho(-100, 100, -100, 100, -100, 100);
		
	
	glClearColor(0, 0, 0, 0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	glPushMatrix();
		//glLightfv(GL_LIGHT0,GL_POSITION,lightPosition);
		//glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,spotDir);
		glRotatef(xRot, 1.0f, 0.0f, 0.0f);
		glRotatef(yRot, 0.0f, 1.0f, 0.0f);
		glRotatef(zRot, 0.0f, 0.0f, 1.0f);
		drawAnObject();	
	glPopMatrix();
	
	[[self openGLContext]flushBuffer];
}

-(IBAction)rotateY:(id)sender
{
	yRot = [sender floatValue];
	[self setNeedsDisplay:YES];
}

-(IBAction)rotateX:(id)sender
{
	xRot = [sender floatValue];
	[self setNeedsDisplay:YES];	
}

-(IBAction)rotateZ:(id)sender
{
	zRot = [sender floatValue];
	[self setNeedsDisplay:YES];
}
@end
 

Sin

macrumors regular
Jun 25, 2007
152
0
Not London
Thanks for the advice. I will surely look at it. So, if I understand correctly, you tell me that for now, this will work ok, but when I proceed to advanced graphics options like lighting and shaders, I will have to split my code, right?

Yes, you'll likely run into some problems sooner or later. The more you try to work around them, the trickier they'll get. Much easier to just keep the different matrices in their respective stacks from the off.

I also have another question: Lets just say that I want to enable lighting in my project. So, I want to place the setup functions outside the drawRect function. Where would I put those? If I put them inside the -awakeFromNib function, the program will crash without telling me why.

I think -awakeFromNib is probably not the appropriate place for setting up a GL context. I'm no expert on the Mac specifics, but I might imagine that the underlying GL context is not fully initialised at this point and calling some functions might cause "unexpected behaviour".

NSOpenGLView offers a -prepareOpenGL method which is probably more appropriate for one-off initialisation (and bear in mind that setting up the viewport and projection isn't really a one-off thing as it depends on window geometry, and is generally better off in -reshape).
 

Soulstorm

macrumors 68000
Original poster
Feb 1, 2005
1,887
1
Well, I did it that way, and I wrote a test code that compiles OK. However, I am not getting the results I want from it. I am attaching 2 files. The first is the way that the result should like (when ran through Carbon) and the second is how it actually looks like (through NSOpenGLView). Here is my code:

Code:
#import "MyOpenGLView.h"

GLfloat ambientLight[] = { 0.3, 0.3, 0.3, 1.0 };
GLfloat diffuseLight[] = { 0.7, 0.7, 0.7, 1.0 };
GLfloat lightPosition[] = { 1.0f, 1.0f, 1.0f, 0.0f };
GLfloat  spotDir[] = { 0.0f, 0.0f, -1.0f };

GLfloat no_mat[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat mat_ambient[] = { 0.7, 0.7, 0.7, 1.0 };
GLfloat mat_ambient_color[] = { 0.8, 0.8, 0.2, 1.0 };
GLfloat mat_diffuse[] = { 0.1, 0.5, 0.8, 1.0 };
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat no_shininess[] = { 0.0 };
GLfloat low_shininess[] = { 5.0 };
GLfloat high_shininess[] = { 100.0 };
GLfloat mat_emission[] = { 0.3, 0.2, 0.2, 0.0 };
GLfloat lmodel_ambient[] = {0.1, 0.1, 0.1, 1.0};

GLfloat white_light[] = {1.0, 1.0, 1.0, 1.0};

@implementation MyOpenGLView
- (id) init
{
	self = [super init];
	if (self != nil) {
		xRot = 0.0f;
		yRot = 0.0f;
		zRot = 0.0f;
	}
	return self;
}


- (void)prepareOpenGL
{
	NSLog(@"preparing OpenGL");
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
	
	glShadeModel(GL_SMOOTH);
	
	glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
	glMaterialfv(GL_FRONT, GL_SHININESS, low_shininess);
	
	glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light);
	glLightfv(GL_LIGHT0, GL_SPECULAR, white_light);
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
	
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glEnable(GL_DEPTH_TEST);
}

-(void)reshape
{
	NSLog(@"reshaping...");
	NSRect bounds = [self bounds];
	glViewport(0, 0, NSWidth(bounds), NSHeight(bounds));
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
}

- (void)drawRect:(NSRect)rect
{
	
	NSLog(@"drawing rect...");
	
	
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glOrtho(-100, 100, -100, 100, -100, 100);
	//glColor3f(1.0f, 0.0f, 0.0f);
    glPushMatrix();	
		glRotatef(xRot, 1.0f, 0.0f, 0.0f);
		glRotatef(yRot, 0.0f, 1.0f, 0.0f);
		glutSolidSphere(50, 50, 50);
    glPopMatrix();
	
	[[self openGLContext]flushBuffer];
}

@end

Any idea why this happens? Do I need to set something else before beginning drawing?
 

Attachments

  • Picture 2.png
    Picture 2.png
    22.5 KB · Views: 118
  • Picture 3.png
    Picture 3.png
    4.4 KB · Views: 1,843

Sin

macrumors regular
Jun 25, 2007
152
0
Not London
Any idea why this happens? Do I need to set something else before beginning drawing?

The first thing I'd rule out, as previously noted, is the fact that you have a projection matrix stuffed into the modelview transform stack. What space should GL do the lighting in? An orthogonal projection transform mostly amounts to a great big scale and translate at the top of the stack, which is probably not helping the normals.

It should be easy enough to change - just move the glOrtho() call out of the draw routine and onto the end of the reshape() function (after the glLoadIdentity)...

You'll also probably want to set the orthogonal projection up to take into account the aspect ratio of the window.
 

Soulstorm

macrumors 68000
Original poster
Feb 1, 2005
1,887
1
Thanks a lot, Sin. You've been a wonderful help.

Seems I must take a read into matrices and matrix types on OpenGL again...
 

Alloye

macrumors 6502a
Apr 11, 2007
657
0
Rocklin, CA
Well, I did it that way, and I wrote a test code that compiles OK. However, I am not getting the results I want from it. I am attaching 2 files. The first is the way that the result should like (when ran through Carbon) and the second is how it actually looks like (through NSOpenGLView). Here is my code:

<snip>

Any idea why this happens? Do I need to set something else before beginning drawing?

One thing that may help is to bracket the code in your reshape method as follows:
Code:
- (void)reshape
{
    [[self openGLContext] makeCurrentContext];
    .
    .
    .
    [NSOpenGLContext clearCurrentContext];
}
You might try it in prepareOpenGL as well. It appears OS X auto-brackets calls to drawRect: with this code, but not the other overrides. I recently discovered this while working on a live-resizable NSOpenGLView. Modifying my reshape method as described above took care of the viewport sizing problems I was having.
 

Soulstorm

macrumors 68000
Original poster
Feb 1, 2005
1,887
1
Problems remain...

Sin was correct.

However, I am still not getting the results I want. This time, I am trying to enable material shininess with this code:
Code:
#import "MyOpenGLView.h"

GLfloat ambientLight[] = { 0.3, 0.3, 0.3, 1.0 };
GLfloat diffuseLight[] = { 0.7, 0.7, 0.7, 1.0 };
GLfloat lightPosition[] = { 1.0f, 1.0f, -1.0f, 0.0f };
GLfloat  spotDir[] = { 0.0f, 0.0f, -1.0f };

GLfloat no_mat[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat mat_ambient[] = { 0.7, 0.7, 0.7, 1.0 };
GLfloat mat_ambient_color[] = { 0.8, 0.8, 0.2, 1.0 };
GLfloat mat_diffuse[] = { 0.1, 0.5, 0.8, 1.0 };
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat no_shininess[] = { 0.0 };
GLfloat low_shininess[] = { 5.0 };
GLfloat high_shininess[] = { 100.0 };
GLfloat mat_emission[] = { 0.3, 0.2, 0.2, 0.0 };
GLfloat lmodel_ambient[] = {0.1, 0.1, 0.1, 1.0};

GLfloat white_light[] = {1.0, 1.0, 1.0, 1.0};
GLfloat red[] = { 1.0, 0.0, 0.0, 1.0 };
GLfloat blue[] = {0.0f, 0.0f, 1.0f, 1.0};

@implementation MyOpenGLView
- (id) init
{
	self = [super init];
	if (self != nil) {
		xRot = 0.0f;
		yRot = 0.0f;
		zRot = 0.0f;
	}
	return self;
}


- (void)prepareOpenGL
{
	
	NSLog(@"preparing OpenGL");
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
	
	glShadeModel(GL_SMOOTH);
	
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, red);
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glEnable(GL_DEPTH_TEST);
	
}

-(void)reshape
{

	NSLog(@"reshaping...");
	NSRect bounds = [self bounds];
	glViewport(0, 0, NSWidth(bounds), NSHeight(bounds));
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(-100, 100, -100, 100, -100, 100);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

- (void)drawRect:(NSRect)rect
{
	NSLog(@"drawing rect...");

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light);
	glLightfv(GL_LIGHT0, GL_SPECULAR, white_light);
	glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
	
	glMaterialfv(GL_FRONT, GL_SHININESS, low_shininess);
	glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
	glMaterialfv(GL_FRONT, GL_DIFFUSE, red);
	
	glPushMatrix();		
		glutSolidSphere(50, 50, 50);
	glPopMatrix();

	[[self openGLContext]flushBuffer];
}



-(IBAction)rotateY:(id)sender
{
	yRot = [sender floatValue];
	[self setNeedsDisplay:YES];
}

-(IBAction)rotateX:(id)sender
{
	xRot = [sender floatValue];
	[self setNeedsDisplay:YES];	
}

-(IBAction)rotateZ:(id)sender
{
	zRot = [sender floatValue];
	[self setNeedsDisplay:YES];
}


@end

However, I am getting the result in the image I am attaching below. No shininess whatsoever. I don't understand... this code works well in Carbon. And I followed the instructions on the red book.

Uh... help?
 

Attachments

  • Picture 1.png
    Picture 1.png
    14.1 KB · Views: 125

Soulstorm

macrumors 68000
Original poster
Feb 1, 2005
1,887
1
Either I am stupid, or my OpenGL implementation is faulty. I am moving the light, and I am using the same code in a Carbon application and it works. Why, I don't know. Any ideas?
 

Alloye

macrumors 6502a
Apr 11, 2007
657
0
Rocklin, CA
Either I am stupid, or my OpenGL implementation is faulty. I am moving the light, and I am using the same code in a Carbon application and it works. Why, I don't know. Any ideas?

Did you happen to try my suggestion? Manually setting the context before making OpenGL calls in methods other than drawRect: definitely corrected some odd behavior in my app. I found the suggestion here.
 

Sin

macrumors regular
Jun 25, 2007
152
0
Not London
Either I am stupid, or my OpenGL implementation is faulty. I am moving the light, and I am using the same code in a Carbon application and it works. Why, I don't know. Any ideas?

Looking at the image you posted, I think there *is* a specular highlight, but it's on the back of the sphere - I can see some white creeping in at the top right. That might indicate that something in your coordinate system is flipped compared to when your other app so your light is slightly behind the sphere... Try with the light's Z component set to zero so that it's in the same plane as the sphere and see if it's more obvious. That way you can make sure the lighting is basically working and go on to work out why your co-ordinates aren't what you expect. Otherwise maybe I'm just seeing things and you can debug the lighting calls.

And it would probably be good practice to follow Alloye's advice about making sure the right context is selected before drawing - although most of your function calls appear to be having an effect, which implies to me that so far your context is valid.
 

Soulstorm

macrumors 68000
Original poster
Feb 1, 2005
1,887
1
Looking at the image you posted, I think there *is* a specular highlight, but it's on the back of the sphere - I can see some white creeping in at the top right. That might indicate that something in your coordinate system is flipped compared to when your other app so your light is slightly behind the sphere... Try with the light's Z component set to zero so that it's in the same plane as the sphere and see if it's more obvious. That way you can make sure the lighting is basically working and go on to work out why your co-ordinates aren't what you expect. Otherwise maybe I'm just seeing things and you can debug the lighting calls.

And it would probably be good practice to follow Alloye's advice about making sure the right context is selected before drawing - although most of your function calls appear to be having an effect, which implies to me that so far your context is valid.


The white spot on the sphere got me thinking, too. However, if I set the light to light the front of the sphere, no shininess is displayed whatsoever, and the white spot is gone.

Aloyee, I followed your advice, but with no effect. And I cannot do this on -prepareOpenGL because the program will crash, since the OpenGLContext of the NSOpenGLView does not exist when -prepareOpenGL is called.

Look, I think it would be best to give you the entire project (it's really small), that way you can see the way I have created the .nib files, etc. I am attaching it below. If you can, please alter it so that the correct image is displayed. It seems I will never find out what the problem is, until I see some simple sample code...
 

Attachments

  • Cocoa OpenGL test1.zip
    54.8 KB · Views: 130
  • Picture 2.png
    Picture 2.png
    15.5 KB · Views: 93

Alloye

macrumors 6502a
Apr 11, 2007
657
0
Rocklin, CA
Aloyee, I followed your advice, but with no effect. And I cannot do this on -prepareOpenGL because the program will crash, since the OpenGLContext of the NSOpenGLView does not exist when -prepareOpenGL is called.

I'm actually brand-new to OpenGL, so I probably can't offer anything else of value. Plus it seems my failure mode was different than yours. In my case, I had a live-resizable NSOpenGLView that wouldn't respect its glViewport() and glOrtho() calls unless I moved them out of reshape and into drawRect. It drove me crazy for hours.

Anyway, sorry for the bum steer, and good luck figuring this out!
 

Sin

macrumors regular
Jun 25, 2007
152
0
Not London
Problems I can see:

Could probably use a glFinish() at the end of the drawRect (I had some update issues without this).

Relies on a depth-buffer, but the window is created without one - go into the nib file and select Maximum for your depth buffer in the glview attributes.

Then you ought to be able to get the highlight to behave itself - I think at the moment you're probably seeing the back-faces...
 

Soulstorm

macrumors 68000
Original poster
Feb 1, 2005
1,887
1
That did it. Thanks a lot, Sin. Actually, in Leopard the option is not "maximum", but "32 bit". Anyway, I understand the error now, thanks a lot.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.