Newer
Older
cg / sources / main.cpp
@glproj03 glproj03 on 29 Jan 2006 13 KB Did a lot off stuff :-)
//////////////////////////////////////////////////////////////
//                                                          //
// Project: SDL/OpenGL template                             //
// Goal   : just open a window with a valid OpenGL context  //
// Author : Achille Peternier, VRLab - EPFL, 2005           //
//                                                          //
//////////////////////////////////////////////////////////////

//////////////
// #INCLUDE //
//////////////

#ifndef UNIX
#include <windows.h>    // Only required under Windows :-D
#endif

#ifndef UNIX
#include <SDL.h>        // This file import the SDL inteface
#else
#include <SDL/SDL.h>    // This file import the SDL inteface
#endif

#include <GL/gl.h>      // This file import the OpenGL interface
#include <GL/glu.h>     // This file offers some OpenGL-related utilities

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

#include <string>
#include <iostream>
#include <fstream>

#include <math.h>

#ifndef UNIX
/////////////
// #PRAGMA //
/////////////
// Visual Studio specific: you can import libraries directly by
// specifing them through a #pragma. On other compilters/platforms add
// the required .lib to the makefile or project proprieties
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")
#pragma comment(lib, "sdl.lib")
#pragma comment(lib, "sdlmain.lib")
#endif

#include "vec.h"
#include "color.h"
#include "poly.h"
#include "model.h"
#include "light.h"

using namespace std;

// Constants hardcoded during compilation
#define WINDOW_TITLE       "the cube"
#define WINDOW_X           800   // Window width
#define WINDOW_Y           600   // Window height
#define WINDOW_COLORDEPTH  32    // Color depth (in bits)
#define WINDOW_ZETADEPTH   24    // z-buffer depth (in bits)

#define SURFACE_COUNT      6
#define PI                 3.14159265f

int debugct = 0;

#define DD() do { printf("DD:%d\n", debugct); debugct++;} while(0);

#ifndef UNIX
#define mysleep(x) do {Sleep(x/100);} while (0);
#else
#define mysleep(x) do {usleep(x);} while (0);
#endif
///////////////////////////////////////////////////////////////////////////
// GLOBAL VARS

int MouseX, MouseY, OldMouseX, OldMouseY;
bool MouseButtonRight, MouseButtonLeft;
bool done = false;   // Quit application when true

string getNextToken(string& line) {
	if ( line.length() < 1 ) {
		return "";
	}

	string mp;

	while ( line[0] == ' ' ) {
		line.erase(0, 1);
	}

	int np = line.find(" ", 0);

	if ( (unsigned int)np == string::npos ) {
		np = line.length();
	}

	mp = line.substr(0, np);
	line.erase(0, np);

	return mp;
}

int getNextPoint(string& line) {
	string tch;
	int sp;
	tch = getNextToken(line);
	if ( tch == "" ) {
		return -1;
	}
	if ( (unsigned int)(sp = tch.find("/", 0)) != string::npos ) {
		tch.erase(sp);
	}
	return (int)atoi(tch.c_str());
}

float getNextCoord(string& line) {
	const char* tch;
	tch = getNextToken(line).c_str();
	if ( tch == "" ) {
		return -1;
	}
	return (float)atof(tch);
}

Model* importModel(char* fname) {

	string line;
	ifstream fp;

	std::vector<Vec*> points;
	Model* mm = new Model();

	Poly* tpoly;

	int tp = -1;

	
	fp.open(fname);

	if ( ! fp.is_open()) {
		printf("Error reading file %s\n", fname);
		return mm;
	}

	while ( !fp.eof() ) {
		getline(fp, line);

		if ( line[0] == 'v' ) {
			line.erase(0,1);
			points.push_back(new Vec(getNextCoord(line), getNextCoord(line), getNextCoord(line)));
		}

		if ( line[0] == 'f' ) {
			line.erase(0,1);

			tpoly = new Poly();
			while ( (tp = getNextPoint(line)) > -1 ) {
				tpoly->addPoint(points.at(tp-1));
			}
			mm->addFace(tpoly);
		}
	}

	fp.close();

	return mm;
}


///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// MAIN //

int main( int argc, char **argv ) {
  char a = '|';
  printf("%d", a);

	// Initialize SDL:
	if (SDL_Init(SDL_INIT_VIDEO) == -1) {
		printf("ERROR: unable to init SDL!\n");
		return 1;
	}

	// current viewport position
	Vec viewer_pos = Vec(0.0f, 0.0f, -50.0f);

	// viewport movement delta
	Vec viewer_zmove_pos = Vec(0.0f, 0.0f, -0.3f);
	Vec viewer_zmove_neg = Vec(0.0f, 0.0f, 0.5f);
	Vec viewer_xmove_pos = Vec(0.3f, 0.0f, 0.0f);
	Vec viewer_xmove_neg = Vec(-0.3f, 0.0f, 0.0f);

	// current viewport rotation
	Vec viewer_rot = Vec(0.0f, 0.0f, 0.0f);

	// viewport rotation delta
	Vec viewer_zrot = Vec (0.0f, 0.0f, 2.0f);
	Vec viewer_yrot = Vec (0.0f, 2.0f, 0.0f);
	Vec viewer_xrot = Vec (2.0f, 0.0f, 0.0f);

	Color black  (0,0,0);
	Color blue   (0,0,1);
	Color red    (1,0,0);
	Color violet (1,0,1);
	Color yellow (1,1,0);
	Color white  (1,1,1);
	Color green  (0,1,0);
	Color cyan   (0,1,1);
	Color grey   (0.5f,0.5f,0.5f);

	std::vector<Model*> models;

	/* begin cube */
	Vec* ulh  = new Vec(0 ,0 ,0 );
	Vec* ulv  = new Vec(0 ,0 ,10);
	Vec* urv  = new Vec(10,0 ,10);
	Vec* urh  = new Vec(10,0 ,0 );

	Vec* olh  = new Vec(0 ,10,0 );
	Vec* olv  = new Vec(0 ,10,10);
	Vec* orv  = new Vec(10,10,10);
	Vec* orh  = new Vec(10,10,0 );

	Vec cen (5,0,5);
	
	Model* cube = new Model();

	std::vector<Vec*> bottom;
	std::vector<Vec*> left;
	std::vector<Vec*> right;
	std::vector<Vec*> top;
	std::vector<Vec*> rear;
	std::vector<Vec*> front;
	
	bottom.push_back(ulh);
	bottom.push_back(urh);
	bottom.push_back(urv);
	bottom.push_back(ulv);

	left.push_back(ulh);
	left.push_back(ulv);
	left.push_back(olv);
	left.push_back(olh);

	right.push_back(urh);
	right.push_back(orh);
	right.push_back(orv);
	right.push_back(urv);

	top.push_back(olh);
	top.push_back(olv);
	top.push_back(orv);
	top.push_back(orh);

	rear.push_back(ulh);
	rear.push_back(olh);
	rear.push_back(orh);
	rear.push_back(urh);

	front.push_back(ulv);
	front.push_back(urv);
	front.push_back(orv);
	front.push_back(olv);

	cube->addFace(new Poly(bottom, red));
	cube->addFace(new Poly(left, green));
	cube->addFace(new Poly(right, cyan));
	cube->addFace(new Poly(top, blue));
	cube->addFace(new Poly(rear, yellow));
	cube->addFace(new Poly(front, white));
	
	cube->setCenter(cen);
	//cube->setDelta(PI/2.0);

	//cube->showNormals();
	
	/* end cube */

	//models.push_back(cube);

	/* begin import */
	char* modelfile = "obj/sample2.obj";
	//char* modelfile = "obj/sample.obj";
	//char* modelfile = "obj/untitled.obj";
	//char* modelfile = "obj/teapot.obj";
	Model* myModel = importModel(modelfile);
	printf("imported %s : %d faces\n", modelfile, myModel->numFaces());
	Vec myCen = Vec(5,-10,5);
	myModel->setCenter(myCen);
	//myModel->showNormals();
	myModel->setDelta(PI/2.0);

	//myModel->vardump("");
	
	/* end import */
	
	//models.push_back(myModel);
	
	/* stage */
	Model* stage = new Model();
	Vec* lr = new Vec(-1000000.0f, 0.0f, -1000000.0f);
	Vec* lf = new Vec(-1000000.0f, 0.0f, 1000000.0f);
	Vec* rr = new Vec(1000000.0f, 0.0f, -1000000.0f);
	Vec* rf = new Vec(1000000.0f, 0.0f, 1000000.0f);
	Poly* sp = new Poly();
	sp->addPoint(lr);
	sp->addPoint(lf);
	sp->addPoint(rf);
	sp->addPoint(rr);
	sp->setColor(grey);
	stage->addFace(sp);
	
	// Prepare configuration:
	int bitsPerColor = 8;
	if (WINDOW_COLORDEPTH == 16) {
		bitsPerColor = 5;
	}

	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, bitsPerColor);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, bitsPerColor);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, bitsPerColor);
	SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, 0);
	SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, 0);
	SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, 0);
	SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, 0);

	if (WINDOW_COLORDEPTH == 32) {
		SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
	} else {
		SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);
	}

	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, WINDOW_ZETADEPTH);
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

	// Create surface:
	unsigned flags = SDL_OPENGL;
	SDL_WM_SetCaption(WINDOW_TITLE, NULL);

	if (SDL_SetVideoMode(WINDOW_X, WINDOW_Y, WINDOW_COLORDEPTH, flags) == NULL ) {
		printf("ERROR: unsupported video configuration!\n");
		return 1;
	}

	// Ok, SDL up with a valid OpenGL context!
	// Now setup some OpenGL parameter:
	// Clear background with a darkblue color
	glClearColor(0.0f, 0.0f, 0.5f, 1.0f);

	// correct clipping
	glEnable (GL_DEPTH_TEST);

	//enable light
	glEnable(GL_LIGHTING);

	//light info
	Vec l1_pos(0.0f, -10.0f, -10.0f);
	Color l1_col(1.0f, 1.0f, 1.0f);

	Color l0_col(0.5f, 0.5f, 0.5f);

	AmbientLight light0(l0_col, GL_LIGHT0);
	DiffuseLight light1(l1_pos, l1_col, GL_LIGHT1);

	glEnable(GL_COLOR_MATERIAL);

	glShadeModel(GL_SMOOTH);
  
	///////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////
	// Mainloop:

	float deltacolor = 0.0f;
	int react_keyevent = 0;

	float viewerMovingSpeed = 1.0f;

	std::vector<Model*>::size_type modelCounter = 0;

	Model* t;
	for ( int i = 0; i < 50; i++ ) {
		t = cube->clone();
		t->rotate(Vec(i*5.0f, 0.0f, 0.0f));
		t->setCenter(new Vec(200.0f*cos(((float)i)*PI/50.0f), 0.0f, 200.0f*sin(((float)i)*PI/50.0f)));
		models.push_back(t);
	}
	for ( int i = 1; i < 50; i++ ) {
		t = cube->clone();
		t->rotate(Vec(i*-5.0f, 0.0f, 0.0f));
		t->setCenter(new Vec(200.0f*cos(((float)-i)*PI/50.0f), 0.0f, 200.0f*sin(((float)-i)*PI/50.0f)));
		models.push_back(t);
	}

	while (!done) {
		/////////////////////
		// Do some rendering:
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		// Setup a perspective view:
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		gluPerspective(45.0f,             // Field of view
				WINDOW_X/WINDOW_Y,  // width/height ratio
				1.0f,               // near clipping plane
				1000.0f);           // far clipping plane
		


		glMatrixMode(GL_MODELVIEW);
	
		//initial viewer position
		glLoadIdentity();

		
		//move viewer
		glTranslatef(viewer_pos.x(), viewer_pos.y(), viewer_pos.z());

		//rotate viewer
		glRotatef(viewer_rot.z(), 0.0f, 0.0f, 1.0f);
		glRotatef(viewer_rot.y(), 0.0f, 1.0f, 0.0f);
		glRotatef(viewer_rot.x(), 1.0f, 0.0f, 0.0f);

		/* draw x- axis */
		//glBegin(GL_LINES); black.drawColor(); glVertex3f(-1000000.0f, 0.0f, 0.0f); glVertex3f(1000000.0f, 0.0f, 0.0f); glEnd();
		/* draw y- axis */
		//glBegin(GL_LINES); black.drawColor(); glVertex3f(0.0f, -1000000.0f, 0.0f); glVertex3f(0.0f, 1000000.0f, 0.0f); glEnd();
		/* draw z- axis */
		//glBegin(GL_LINES); black.drawColor(); glVertex3f(0.0f, 0.0f, -1000000.0f); glVertex3f(0.0f, 0.0f, 1000000.0f); glEnd();

		stage->draw();

		for ( modelCounter = 0; modelCounter < models.size(); modelCounter++ ) {
			models.at(modelCounter)->draw();
			models.at(modelCounter)->rotate(Vec(1.5f, 0.0f, 0.0f));
		}

		cube->draw();
		myModel->draw();

		//draw cube
		//cube->draw();
		//cube->rotate(Vec(0.1f, 0.5f, 1.0f));
		//myModel->draw();
		//myModel->rotate(Vec(0.2f, 0.3f, 1.2f));


		////////////////
		// Check events:
		SDL_Event event;

		while (SDL_PollEvent(&event)) {
			// Quit by click on X:
			if (event.type == SDL_QUIT) {
				done = true;
			}
		}

		// Update mouse:
		OldMouseX = MouseX;
		OldMouseY = MouseY;
		unsigned buttons = SDL_GetMouseState(&MouseX, &MouseY);

		if (buttons&SDL_BUTTON(1)) {
			MouseButtonLeft = true;
		} else {
			MouseButtonLeft = false;
		}

		if (buttons&SDL_BUTTON(3)) {// <-- Beware: may be 2 on mouses
			// without the middle button!
			MouseButtonRight = true;
		} else {
			MouseButtonRight = false;
		}

		//if (MouseButtonLeft)
		//      delta += 1.0f;

		// Update keyboard (used like a joypad):
		Uint8 *keystate = SDL_GetKeyState(NULL);
		if (keystate[SDLK_ESCAPE]) {
			done = true;
		}

		// lights
		if (react_keyevent == 0) {
		  react_keyevent = 10;

		  if (keystate[SDLK_1]) {
			light0.flip();
		  }
		  else if (keystate[SDLK_2]) {
			light1.flip();
		  }
		  else {
			react_keyevent = 0;
		  }

		} else {
		  react_keyevent -= 1;
		}

		//background color
		/*		if (keystate[SDLK_1]) {
			glClearColor(0.5f, 0.0f, 0.0f, 1.0f);
		}

		if (keystate[SDLK_2]) {
			glClearColor(0.0f, 0.5f, 0.0f, 1.0f);
		}

		if (keystate[SDLK_3]) {
			glClearColor(0.0f, 0.0f, 0.5f, 1.0f);
			}*/

		// speed
		if ( keystate[SDLK_LSHIFT] || keystate[SDLK_RSHIFT] ) {
			viewerMovingSpeed = 10.0f;
		} else {
			viewerMovingSpeed = 1.0f;
		}

		// rotate viewer
		if (keystate[SDLK_LEFT]) viewer_rot.add(viewer_yrot*viewerMovingSpeed);
		if (keystate[SDLK_RIGHT]) viewer_rot.sub(viewer_yrot*viewerMovingSpeed);
		if (keystate[SDLK_UP]) viewer_rot.add(viewer_xrot*viewerMovingSpeed);
		if (keystate[SDLK_DOWN]) viewer_rot.sub(viewer_xrot*viewerMovingSpeed);
		
		// move viewer
		if (keystate[SDLK_w]) viewer_pos.add(viewer_zmove_neg*viewerMovingSpeed);
		if (keystate[SDLK_s]) viewer_pos.add(viewer_zmove_pos*viewerMovingSpeed);
		if (keystate[SDLK_a]) viewer_pos.add(viewer_xmove_pos*viewerMovingSpeed);
		if (keystate[SDLK_d]) viewer_pos.add(viewer_xmove_neg*viewerMovingSpeed);

		if (keystate[SDLK_SPACE]) {
			deltacolor += 0.01f;
			if (deltacolor > 1.0f) {
				deltacolor = 0.0f;
			}
		}

		
		////////////////
		// Swap buffers:
		//mysleep(2000); // Just don't kill computer resources ;)
		SDL_GL_SwapBuffers();
	}

	// Ok, release everything and byebye:
	SDL_Quit();
	return 0;
}