Newer
Older
cg / sources / main.cpp
@ajaggi ajaggi on 28 Dec 2005 10 KB Added some obj files
//////////////////////////////////////////////////////////////
//                                                          //
// 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

#include <SDL.h>        // This file import the SDL inteface
#include <SDL/SDL.h>    // This file import the SDL inteface
#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 "array.h"
#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;
int firstprint = 1;

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

///////////////////////////////////////////////////////////////////////////
// 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;

	Array* points = new Array();
	Array* tpoints = new Array();
	Model* mm = new Model(new Array());

	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(new Vec(getNextCoord(line), getNextCoord(line), getNextCoord(line)));
		}

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

			tpoints->clear();
			while ( (tp = getNextPoint(line)) > -1 ) {
				tpoints->push(points->get(tp-1));
			}
			mm->addFace(new Poly(tpoints));
		}
	}

	fp.close();

	delete points;
	delete tpoints;

	return mm;
}


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

int main( int argc, char **argv )
{
   // Initialize SDL:
   if (SDL_Init(SDL_INIT_VIDEO) == -1)
   {
     printf("ERROR: unable to init SDL!\n");
     return 1;
   }

   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);

   Vec* p0  = new Vec(0 ,0 ,0 );
   Vec* p1  = new Vec(10,0 ,0 );
   Vec* p2  = new Vec(10,10,0 );
   Vec* p3  = new Vec(0 ,10,0 );

   Vec* p4  = new Vec(0 ,0 ,10);
   Vec* p5  = new Vec(10,0 ,10);
   Vec* p6  = new Vec(10,10,10);
   Vec* p7  = new Vec(0 ,10,10);

   Vec cen (5,5,5);

   /*

          4---7
          |pp5|
      4---0---3---7---4
      |pp2|pp0|pp3|pp1|
      5---1---2---6---5
          |pp4|
	  5---6

    */

   Array* pp0 = new Array();
   pp0->push(p0);
   pp0->push(p3);
   pp0->push(p2);
   pp0->push(p1);

   Array* pp1 = new Array();
   pp1->push(p4);
   pp1->push(p5);
   pp1->push(p6);
   pp1->push(p7);

   Array* pp2 = new Array();
   pp2->push(p4);
   pp2->push(p0);
   pp2->push(p1);
   pp2->push(p5);

   Array* pp3 = new Array();
   pp3->push(p2);
   pp3->push(p3);
   pp3->push(p7);
   pp3->push(p6);

   Array* pp4 = new Array();
   pp4->push(p1);
   pp4->push(p2);
   pp4->push(p6);
   pp4->push(p5);

   Array* pp5 = new Array();
   pp5->push(p3);
   pp5->push(p0);
   pp5->push(p4);
   pp5->push(p7);
  
	Array* polys = new Array();
	polys->push(new Poly(pp0, red));
	polys->push(new Poly(pp1, green));
	polys->push(new Poly(pp2, cyan));
	polys->push(new Poly(pp3, blue));
	polys->push(new Poly(pp4, yellow));
	polys->push(new Poly(pp5, violet));

   //Model* myModel = importModel("obj/untitled.obj");
//printf("imported obj/untitled.obj : %d faces\n", myModel->numberOfFaces());

  Poly* t;
  polys->reset();
  while ( t = (Poly*)polys->next() ) {
	  //printf("polys %d setCenter\n", polys->pos()-1);
	  t->setCenter(cen);
  }

   //light info
   Vec pos0(-10.0f, 12.0f, 15.0f);
   Vec dir0(5.0f, -5.0f, 5.0f);

   Light light0(&pos0, &dir0);

   // 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);
   glEnable(GL_LIGHT0);

   glEnable(GL_COLOR_MATERIAL);

   ///////////////////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////////////////
   // Mainloop:

   float deltay = 0.0f;
   float deltaz = 0.0f;
   float deltacolor = 0.0f;


   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

	    // Place the viewer 50 units backward:
	    glMatrixMode(GL_MODELVIEW);
	    glLoadIdentity();
	    glTranslatef(0.0f, 0.0f, -50.0f);

	    // Draw a rotating triangle:
	    glRotatef(deltay, 0.0f, 1.0f, 0.0f); // Rotation around the Y axis
	    glRotatef(deltaz, 1.0f, 0.0f, 0.0f);

	    polys->reset();
	    while ( t = (Poly*)polys->next() ) {
		   t->draw();
		  t->rotate(Vec(0.0f, 0.01f, 0.01f));
	    }

		light0.draw();
		light0.trace();

		//myModel->draw();

	    ////////////////
	    // 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;

	  //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);

	  //scene rotation
	  if (keystate[SDLK_LEFT])
			deltay -= 2.0f;
	  if (keystate[SDLK_RIGHT])
			deltay += 2.0f;
	  if (keystate[SDLK_UP])
			deltaz -= 2.0f;
	  if (keystate[SDLK_DOWN])
			deltaz += 2.0f;

	  //light rotation
	  /*	  if (keystate[SDLK_a])
			lightpos[0]+=lightdelta;
	  if (keystate[SDLK_d])
		    lightpos[0]-=lightdelta;
	  if (keystate[SDLK_w])
			lightpos[1]+=lightdelta;
	  if (keystate[SDLK_s])
		    lightpos[1]-=lightdelta;
	  if (keystate[SDLK_q])
			lightpos[2]+=lightdelta;
	  if (keystate[SDLK_e])
		    lightpos[2]-=lightdelta;
	  */
	  if (keystate[SDLK_SPACE]) {
		    deltacolor += 0.01f;
			if (deltacolor > 1.0f) {
				deltacolor = 0.0f;
			}
	  }



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

      // Plain stupid log, just to show values:
      //printf("X: %d, Y: %d, but1: %d, but2: %d\n",
      //     MouseX, MouseY, MouseButtonLeft, MouseButtonRight);
   }

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