Cocoa 2D OpenGL Texture + easy Question

iceyg

Funky Member
Ok, I'm new to OpenGL, and I tought I could do it, but I'm starting to think I can't anymore.

1. I checked out Apple's OpenGL sample code with the green triangle (Green Triangle ), and I had no trouble doing it. Then I went to the NeHe tutorials to see if I could do textures...Apparently the tutorials there are much different than how Apple lays out their sample code and I don't know why. So, I go looking into Tutorial 6, and I kinda understand it. I wanted to see if I could take that tutorial 6 and make it 2d, without rotatation and without fullscreen (since fullscreen doesn't work on any mac I tried it on >=Mac OS 10.2.8). I wanted to also try and make the tutorial 6 code similar to the Apple sample code. Anyhow, this is what I came up with the OpenGL "red book" in hand.

CODE (40 some Kb)
...and it doesn't work, I just get a white square.
ANY IDEAS?

2. also, does anyone know why the -drawRect() function is always called at start up?...this was maybe why -awakeFromNib is in the tutorials at NeHe among other reasons?

notes on the project:
The CustomOpenGLView class is a subclass of NSOpenGLView and is pretty much the first part of Apple's sample code but instead with a rectangle.
The CustomOpenGLView2 class is also a subclass of NSOpenGLView and is my attempt at the NeHe tutorial 6 2d, no rotation, no fullscreen.
and the ControllerClass class only maintains an outlet that never gets used. FYI the outlet above is to the CustomOpenGLView view in the MainMenu.nib.
 
I haven't looked at your code yet. But drawRect: is called when the window opens. I instead choose to not use an NSOpenGL view, but instead just make an NSOpenGLContext and point it to my window's content view.

This is my Lesson 6 code which I was working on last week, I'm just learning OpenGL as well so some of this may be not quite right but it works. Though, my textures are loaded upside-down... so I anyone can explain that, I would appreciate it. Is it something to do with how the bytes are stored in OpenGL as opposed to the Mac format?

Code:
#import "MyWindowController.h"


@interface MyWindowController (InternalMethods)

-(BOOL)drawGLScene;
-(BOOL)initGL;
-(void)resizeGLSceneWithWidth:(int)width andHeight:(int)height;

@end



@implementation MyWindowController

//  ****************************************************************************************************
//  Handle keyboard input here
//  ****************************************************************************************************

-(void)keyDown:(NSEvent *)theEvent
{
	;
}


//  ****************************************************************************************************
//  All setup for OpenGL goes here
//  ****************************************************************************************************

-(BOOL)initGL
{
	glShadeModel(GL_SMOOTH);							// Enable Smooth Shading
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);				// Black Background
	glClearDepth(1.0f);									// Depth Buffer Setup
	glEnable(GL_DEPTH_TEST);							// Enables Depth Testing
	glDepthFunc(GL_LEQUAL);								// The Type Of Depth Testing To Do
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	// Really Nice Perspective Calculations
	
	glEnable(GL_TEXTURE_2D);
	glEnable(GL_COLOR_MATERIAL);
	
	NSImage * texImg = [NSImage imageNamed:@"a.bmp"];
	glGenTextures(1, &texture);
	glBindTexture(GL_TEXTURE_2D, texture);
	NSBitmapImageRep * bitmap = [NSBitmapImageRep imageRepWithData:[texImg TIFFRepresentation]];
	glTexImage2D(GL_TEXTURE_2D, 0, 3, [texImg size].width, [texImg size].height, 0, GL_RGB, GL_UNSIGNED_BYTE, [bitmap bitmapData]) ;
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // Linear Filtering
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // Linear Filtering
		
	return YES;											// Initialization Went OK
}


//  ****************************************************************************************************
//  Resize And Initialize The GL Window
//  ****************************************************************************************************

-(void)resizeGLSceneWithWidth:(int)width andHeight:(int)height		
{
	
	// Prevent a divide by zero error
	if (height==0) height=1;
	
	// Cocoa-specific, call when resized
	[myGLContext update];	
	
	glViewport(0,0,width,height);
	
	// Select The Projection Matrix
	glMatrixMode(GL_PROJECTION);	
	
	// Reset The Projection Matrix
	glLoadIdentity();									
	
	// Calculate the aspect ratio of the window
	gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
	
	// Select The Modelview Matrix
	glMatrixMode(GL_MODELVIEW);
	
	// Reset The Modelview Matrix
	glLoadIdentity();									
}


//  ****************************************************************************************************
//  Here's where we do all the drawing
//  ****************************************************************************************************

-(BOOL)drawGLScene
{
	
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);                     // Clear Screen And Depth Buffer
	glLoadIdentity();                                                       // Reset The Current Matrix
	glTranslatef(0.0f,0.0f,-5.0f);                                          // Move Into The Screen 5 Units


	glBindTexture(GL_TEXTURE_2D, texture);  
	
	
	glRotatef(rquad,1.0f,1.0f,1.0f);                        // Rotate The Cube On X, Y & Z
	
	glBegin(GL_QUADS);                                      // Start Drawing The Cube
															// Front Face
	glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);      // Bottom Left Of The Texture and Quad
	glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);      // Bottom Right Of The Texture and Quad
	glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);      // Top Right Of The Texture and Quad
	glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);      // Top Left Of The Texture and Quad
																	// Back Face
	glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);      // Bottom Right Of The Texture and Quad
	glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);      // Top Right Of The Texture and Quad
	glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);      // Top Left Of The Texture and Quad
	glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);      // Bottom Left Of The Texture and Quad
																	// Top Face
	glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);      // Top Left Of The Texture and Quad
	glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);      // Bottom Left Of The Texture and Quad
	glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);      // Bottom Right Of The Texture and Quad
	glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);      // Top Right Of The Texture and Quad
																	// Bottom Face
	glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);      // Top Right Of The Texture and Quad
	glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);      // Top Left Of The Texture and Quad
	glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);      // Bottom Left Of The Texture and Quad
	glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);      // Bottom Right Of The Texture and Quad
																	// Right face
	glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);      // Bottom Right Of The Texture and Quad
	glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);      // Top Right Of The Texture and Quad
	glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);      // Top Left Of The Texture and Quad
	glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);      // Bottom Left Of The Texture and Quad
																	// Left Face
	glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);      // Bottom Left Of The Texture and Quad
	glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);      // Bottom Right Of The Texture and Quad
	glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);      // Top Right Of The Texture and Quad
	glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);      // Top Left Of The Texture and Quad
	
	glEnd();                                                // Done Drawing The Quad
	
	// Draw the scene	
	[myGLContext flushBuffer];							// Only works with double-buffered
	
	rtri+=0.2f;											// Increase The Rotation Variable For The Triangle ( NEW )
	rquad-=0.15f;										// Decrease The Rotation Variable For The Quad     ( NEW )
	
	return YES;
}

-(void)dealloc
{
	// Clean up objects
	
	[theTimer invalidate];
	[theTimer release];
	[myGLContext release];
	[super dealloc];
}


//  ****************************************************************************************************
//  Essentially emulate the main() function for this lesson
//  ****************************************************************************************************

- (void)applicationDidFinishLaunching:(NSNotification *)notification 
{	

	// Get the content area of the window
	theView = [[super window] contentView];
	
	// Create a pixel format
	NSOpenGLPixelFormatAttribute attr[] = 
	{
		NSOpenGLPFACompliant,
		NSOpenGLPFAWindow,
		NSOpenGLPFADoubleBuffer,
        NSOpenGLPFAColorSize, 16,
		NSOpenGLPFADepthSize, 16,
        nil 
	};
	
	NSOpenGLPixelFormat * format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr];
	
	// Create an OpenGL context with the previous pixel format
	myGLContext = [[NSOpenGLContext alloc] initWithFormat:format shareContext:nil];  
	
	//  Make the context the current context so all OpenGL calls apply to it
	[myGLContext makeCurrentContext];
	
	[self initGL];
	
	// Lets just set the context to windowed mode for now, point it to the window's content area
	[myGLContext setView: theView];
	
	// Finish setting up OpenGL
	[self resizeGLSceneWithWidth:[theView frame].size.width andHeight:[theView frame].size.height];
	
	// Setup a simple timer for redrawing display
	theTimer = [[NSTimer scheduledTimerWithTimeInterval:0.005
												 target:self 
											   selector:@selector(drawGLScene) 
											   userInfo:nil 
												repeats:YES] retain];
	
}

@end
 
yeah, the NeHe tutorial 6 says that the bitmap needs to be flipped inorder to draw it as it is shown (should be flipped on X-axis yeah). I read this in other places too. OpenGL has a co-ordinate system where the bottom left is (0,0)...for textures, while the Mac OS has top left as (0,0) as the windowing system (I think) but that is the reason why it's upsidedown. I'll take a look at your code tomorrow, but it may not help me because I don't want a whole window to be OpenGL, I only want some of the window...maybe I can hack it up to get it to do my bidding, thanks!

But yeah, back to the upsidedown part...you can either store your textures upsidedown or make a for loop like they have in tutorial 6 to read the byte in correct order. Check out toward the bottom of their "- (BOOL) loadBitmap:(NSString *)filename intoIndex:(int)texIndex" function for that code.
 
I see you're using an NSImage...interesting.
Well, the code segment you gave me was a bit incomplete...It's missing the myGLContext class, the texture and some other usefull things, so it's not much of a help. But it sparked my head into thinking that maybe I should just use the whole window as the interface to my program, and just use opengl and draw to the whole window. I think there is a way to get the mouse events and see if they clicked somewhere specifically in the window etc. I will try that path tomorrow. I'll probably fail, but it'll be worth a shot. I just really wanted to use the MacOSX buttons and such for my interface instead...
 
Sorry about the header:

Code:
/* MyWindowController */

#import <Cocoa/Cocoa.h>

#import <OpenGL/OpenGL.h>
#import <OpenGL/gl.h>
#import <OpenGl/glu.h>

@interface MyWindowController : NSWindowController
{
	NSOpenGLContext * myGLContext;
	NSTimer * theTimer;
	id theView;	
	
	GLfloat         rtri;                                           // Angle For The Triangle ( NEW )
	GLfloat         rquad;                                          // Angle For The Quad     ( NEW )
	GLuint          texture;
}
@end

You don't have to draw to the whole window if you don't want to. You can also use this method to draw to any view you want to. Another idea might be that if you want to use an NSOpenGLView, set a flag saying when to draw.
 
You don't have to draw to the whole window if you don't want to. You can also use this method to draw to any view you want to. Another idea might be that if you want to use an NSOpenGLView, set a flag saying when to draw.

How would I go about using this to draw to any view? I tried to make MyWindowController a subclass of NSOpenGLView in IB and in PB and that just came up as a white (empty) view. (I assume b/c the drawRect function was missing).
 
oh oh oh! I got it to work in a standard NSOpenGLView! woo!! Now time to figure out why it's a white spinning cube. I guess my a.bmp is the wrong size, #colors or something. Then I'll make it 2D. I'll write back with any issues.
 
hey,
One thing that the WWDC provided for me was that I found out an extra easy way to make the OGL texture look as it does in the file.

Answer: change the glTexCoords. I felt almost dumb when the guy in the lab told me this, but oh well.

It should look something like this:
Code:
glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, -1.0f);      // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex2f( 1.0f, -1.0f);      // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0f,  1.0f);      // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f,  1.0f);      // Top Left Of The Texture and Quad

That should make the texture look as it does in the file (a.k.a. not flipped about the x-axis). Hope this helps someone, maybe if someone googles the correct words someday it'll pop up :p
 
Back
Top