Displaying Large Objects into NSOpenGLView

Discussion in 'Mac Programming' started by Soulstorm, Aug 27, 2008.

  1. macrumors 68000

    Soulstorm

    Joined:
    Feb 1, 2005
    #1
    Well, as you may recall from a previews thread, I am building a .obj file loader. The question I have concerns general OpenGL, so it doesn't require of me to show much code, or from you to know about .obj files. I succeeded in making the loader, and I also succeeded in displaying that object on screen. Materials are also used. (I hope I can implement textures into the next few days...).

    I have a problem, though. I have made an application which loads and displays a model. However, as you imagine, the dimensions of each model are completely different. One model could have vertices that have coordinates like those:

    x: 1000 y: 8673 z: 9344

    Other models may have vertices like those:

    x: 9,34 y:7,34 z: 9,44

    My problem is that I can't think of any good way of resizing the view each time I load a new model to something that produces a viewable result. My display code so far is the following:

    MyOpenGLView.h code:

    Code:
           #import <Cocoa/Cocoa.h>
    #import "ObjLoaders.h"
    #include <iostream>
    #include "General.h"
    #include <GLUT/GLUT.h>
    using namespace std;
    
    
    
    #define FILENAME "lightcycle-low.obj"
    #define FILENAME2 "lightcycle-low.txt"
    #define FILENAME3 "Cube.obj"
    #define FILENAME4 "Cone.obj"
    #define FILENAME5 "test/lightcycle-high.obj"
    #define FILENAME6 "Bau2.obj"
    
    
    #define UPDATE_SECONDS 1.0f/200
    #define STANDARD_ROTATION_DEGREES_PREDEFINED_VALUE 0.3f
    #define STEP_SIZE 0.5f
    
    
    @interface MyOpenGLView : NSOpenGLView {
    	
    	
    	float yRot;
    	float xRot;
    	float standardRotationDegrees;
    	
    	float upAndDownTranslation;
    	float leftAndRightTranslation;
    	float nearAndFarTrasnlation;
    	NSTimer *timer;
    }
    
    -(IBAction)stopDefaultRotation:(id)sender;
    - (void)rotate:(float)degrees;
    
    - (IBAction)rotateUp:(id)sender;
    - (IBAction)rotateDown:(id)sender;
    - (IBAction)rotateLeft:(id)sender;
    - (IBAction)rotateRight:(id)sender;
    - (IBAction)moveCameraLeft:(id)sender;
    - (IBAction)moveCameraRight:(id)sender;
    - (IBAction)moveCameraUp:(id)sender;
    - (IBAction)moveCameraDown:(id)sender;
    - (IBAction)moveCameraForward:(id)sender;
    - (IBAction)moveCameraBackwards:(id)sender;
    
    - (IBAction)loadOBJFile:(id)sender;
    @end
    
    
    
    MyOpenGLView.mm code:
    Code:
    #import "MyOpenGLView.h"
    
    
    OBJModel model;
    
    @implementation MyOpenGLView
    
    - (void) heartbeat
    {
    	[self rotate:standardRotationDegrees];
    	if(![[NSApplication sharedApplication] isHidden])
    		[self setNeedsDisplay:YES];
    	//[self rotateLeft:self];
    }
    
    - (void)prepareOpenGL
    {
    	standardRotationDegrees = 0.3f;
    	timer = [NSTimer scheduledTimerWithTimeInterval:(UPDATE_SECONDS) target:self selector:@selector(heartbeat) userInfo:nil repeats:YES];
    	[timer retain];
    	
    	//[[NSRunLoop currentRunLoop] addTimer: timer forMode: NSDefaultRunLoopMode];
    	//[[NSRunLoop currentRunLoop] addTimer: timer forMode: NSEventTrackingRunLoopMode];
    	
    	NSLog(@"preparing openGL...");
    	glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
    	
    	//glEnable(GL_COLOR_MATERIAL);
    	
    	glEnable(GL_DEPTH_TEST);
    	glShadeModel(GL_SMOOTH);
    	
    	yRot = 0.0f;
    	xRot = 0.0;;
    	upAndDownTranslation = 0.0f;
    	leftAndRightTranslation = 0.0f;
    	nearAndFarTrasnlation = 0.0f;
    	
    	
    	model.loadOBJFile(FILENAME4);
    	//GLfloat lightpos[4] = {0.0f, 0.2f, -1.0, 1.0f};
    	GLfloat lightpos[4] = {2.0f, 2.0f, 2.0, 1.0f};
    	glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
    	glEnable(GL_LIGHTING);
    	glEnable(GL_LIGHT0);
    	
    }
    
    - (void)reshape
    {
    	[[self openGLContext]makeCurrentContext];
    	NSRect bounds = [self bounds];
    	//NSLog(@"reshaping: %f, %f", NSWidth(bounds), NSHeight(bounds));
    	glViewport(0, 0, NSWidth(bounds), NSHeight(bounds));
    	glMatrixMode(GL_PROJECTION);
    	glLoadIdentity();
    	gluPerspective(45, NSWidth(bounds)/NSHeight(bounds), 0.1f, 1000.0f);
    	//	glOrtho(-20, 20, -20, 20, -100, 100);
    	glMatrixMode(GL_MODELVIEW);
    	glLoadIdentity();
    	[NSOpenGLContext clearCurrentContext];
    	
    }
    
    
    - (void)drawRect:(NSRect)rect {
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    	
    	glLoadIdentity();
    	
    	
    	//glTranslatef(0.0f, 0.0f, -20.0f);
    	
    	gluLookAt(0, 0, nearAndFarTrasnlation, 0, 0, 0, 0, 1, 0);
    	glTranslatef(leftAndRightTranslation, 0, 0);
    	glRotatef(xRot, 1.0f, 0.0f, 0.0f);
    	glRotatef(yRot, 0.0f, 0.0f, 1.0f);
    	
    	//draw the model
    	for (int i=0; i<model.numTriangles(); i++) {
    		model.drawFaceAtIndex(i);
    	}
    	
    
    	[[self openGLContext]flushBuffer];
    }
    
    #pragma mark -
    #pragma mark Moving The Camera
    - (void)rotate:(float)degrees
    {
    	yRot = yRot - degrees;
    }
    - (IBAction)rotateUp:(id)sender
    {
    	xRot-= 5.0f;
    	if(xRot < 0.1f)
    		xRot = 359.9;
    	[self setNeedsDisplay:YES];
    }
    - (IBAction)rotateDown:(id)sender
    {
    	xRot += 5.0f;
    	if(xRot > 359.9f)
    		xRot = 0.0f;
    	[self setNeedsDisplay:YES];
    }
    - (IBAction)rotateLeft:(id)sender
    {
    	yRot -= 5.0f;
    	if(yRot < 0.1f)
    		yRot = 359.9;
    	[self setNeedsDisplay:YES];
    }
    - (IBAction)rotateRight:(id)sender
    {
    	yRot += 5.0f;
    	if(yRot > 359.9f)
    		yRot = 0.0f;
    	[self setNeedsDisplay:YES];
    }
    
    -(IBAction)stopDefaultRotation:(id)sender
    {
    	if(standardRotationDegrees > 0.0f)
    		standardRotationDegrees = 0.0f;
    	else
    		standardRotationDegrees = STANDARD_ROTATION_DEGREES_PREDEFINED_VALUE;
    }
    
    
    - (IBAction)moveCameraLeft:(id)sender
    {
    	leftAndRightTranslation -= STEP_SIZE;
    	[self setNeedsDisplay:YES];
    }
    - (IBAction)moveCameraRight:(id)sender
    {
    	leftAndRightTranslation += STEP_SIZE;
    	[self setNeedsDisplay:YES];
    }
    - (IBAction)moveCameraUp:(id)sender
    {
    
    }
    - (IBAction)moveCameraDown:(id)sender
    {
    	
    }
    - (IBAction)moveCameraForward:(id)sender
    {
    	nearAndFarTrasnlation += STEP_SIZE;
    	[self setNeedsDisplay:YES];
    }
    - (IBAction)moveCameraBackwards:(id)sender
    {
    	if(nearAndFarTrasnlation < 0)
    		nearAndFarTrasnlation = 0;
    	nearAndFarTrasnlation -= STEP_SIZE;
    	[self setNeedsDisplay:YES];
    }
    
    
    
    - (IBAction)loadOBJFile:(id)sender
    {
    	NSOpenPanel *openPanel = [NSOpenPanel openPanel];
    	[openPanel setCanChooseDirectories:NO];
    	[openPanel setCanChooseFiles:YES];
    	[openPanel setAllowsMultipleSelection:NO];
    	[openPanel setAllowedFileTypes:[NSArray arrayWithObject:@".obj"]];
    	if ([openPanel runModalForDirectory:NSHomeDirectory() file:nil] == NSOKButton) {
    		[[NSFileManager defaultManager]changeCurrentDirectoryPath:[[openPanel filename]stringByDeletingLastPathComponent]];
    		model.reset();
    		model.loadOBJFile([[[openPanel filename]stringByStandardizingPath]cStringUsingEncoding:NSUTF8StringEncoding]);
    	}
    }
    
    - (void) dealloc
    {
    	if(timer != nil)
    		[timer release];
    	[super dealloc];
    }
    
    @end
    
    
    As you can see, I have used gluPerspective() with gluLookAt(). Although some models are displayed correctly, I have a model that has vertices like x:300.0 y:20.0 z:1000.0. That model is not displayed at all. Therefore, I need a way to resize the view to something that can hold objects of any size each time I load a new model.

    Can you recommend any way of coping with that problem?
     
  2. macrumors 6502a

    Joined:
    Sep 3, 2005
    Location:
    Cramlington, UK
    #2
    Rather than scale the view, I would be tempted to scale the model when you draw it, ie just push a glScale on the model view matrix before drawing it. You could work out the scaling factor from the vertex bounds when you load the model.

    b e n
     

Share This Page