Newer
Older
cg / sources / main.cpp
@glproj03 glproj03 on 8 Dec 2005 10 KB trarra. object oriented cube.
//////////////////////////////////////////////////////////////
//                                                          //
// Project: SDL/OpenGL template                             //
// Goal   : just open a window with a valid OpenGL context  //
// Author : Achille Peternier, VRLab - EPFL, 2005           //
//                                                          //
//////////////////////////////////////////////////////////////

//////////////
// #INCLUDE //
//////////////
#include <windows.h>    // Only required under Windows :-D
#include <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 <math.h>

/////////////
// #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")

/////////////
// #DEFINE //
/////////////
// 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                              


///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// CLASSES 

float scale = 10.0f;

class Color {
 public:
  float r;
  float g;
  float b;
  Color(float _r, float _g, float _b) {
    r = _r;
    g = _g;
    b = _b;
  }  

  void setColor() {
    printf("color: %f, %f, %f\n", r, g, b);
    glColor4f (r, g, b, 1.0f);
  }
};


class Vec {
 public:
  float x;
  float y;
  float z;

  Vec(float vx, float vy, float vz) {
    x = vx;
    y = vy;
    z = vz;
  }

  Vec operator+(Vec v) {
    Vec r = Vec(x + v.x, y + v.y, z + v.z);
    return r;
  }

  Vec operator-(Vec v) {
    Vec r = Vec(x - v.x, y -v.y, z - v.z);
    return r;
  }

  Vec operator*(float s) {
    Vec r = Vec(x*s, y*s, z*s);
    return r;
  }

  Vec cross(Vec v) {
    Vec r = Vec(y * v.z - z * v.y, 
		z * v.x - x * v.z, 
		x * v.y - y * v.x);
  }

  Vec normalize() {
    return *this * (1 / this->length());
  }

  float length() {
    return sqrt(x*x+y*y+z*z);
  }

  void print() {
    printf (" vektor: %f, %f, %f\n", x, y, z);
  };

  Vec* clone() {
    return new Vec(x, y, z);
  }
};


class Tri {  
 public:
  Vec *p[3];
  Color *col;
  Vec *normal;

  Tri(Vec* p0, Vec* p1, Vec* p2, Color* c) {
    p[0] = p0;
    p[1] = p1;
    p[2] = p2;
    col = c;
    normal = ((*p[1] - *p[0]).cross(*p[2] - *p[0])).clone();
  }

  ~Tri() {
    delete normal;
  }

  void draw() {
    glBegin (GL_TRIANGLES);    
      this->setNormal();
      col->setColor();
      for (int v = 0; v < 3; v++) {
	glVertex3f (scale * p[v]->x, scale * p[v]->y, scale * p[v]->z);
      }
    glEnd();
    this->print();
  }

  void setNormal() {
    //glNormal3f();
    //this->normal();
  }

  void print() {
    printf("triangle: \n");
    for (int v = 0; v < 3; v++) {
      p[v]->print();
    }		
    printf("\n");
  }
};


class Rect {
 public:
  Tri* t1;
  Tri* t2;
  Rect(Vec* p1, Vec* p2, Vec* p3, Vec* p4, Color* c) {
    t1 = new Tri (p1, p2, p3, c);
    t2 = new Tri (p1, p3, p4, c);
  }
  ~Rect() {
    delete t1;
    delete t2;
  }
  void draw() {
    t1->draw();
    t2->draw();
  }
};


///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// GLOBAL VARS 

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

//light info
float lightpos[] = {10.0f, 12.0f, 15.0f, 1.0f};
float lightdir[] = {5.0f, 5.0f, 5.0f, 1.0f};

float lightdelta = 0.8f;


///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// 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 white (1,1,1);
   Color black (0,0,0);
   Color red (1,0,0);
   Color blue (0,0,1);
   Color green (0,1,0);
   Color yellow (1,1,0);
   
   Vec p0 (0,0,0);
   Vec p1 (1,0,0);
   Vec p2 (1,1,0);
   Vec p3 (0,1,0);

   Vec p4 (0,0,1);
   Vec p5 (1,0,1);
   Vec p6 (1,1,1);
   Vec p7 (0,1,1);

   Rect surf [SURFACE_COUNT] = {
     Rect (&p0, &p3, &p2, &p1, &red),
     Rect (&p4, &p5, &p6, &p7, &blue),
     Rect (&p0, &p4, &p5, &p1, &green),
     Rect (&p2, &p3, &p7, &p6, &yellow),
     Rect (&p1, &p2, &p6, &p5, &black),
     Rect (&p3, &p0, &p4, &p7, &white)
   };

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

	    for (int i = 0; i < SURFACE_COUNT; i++) {
	      surf[i].draw();
	    }
	    /*
	      glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 180.0f);
	      glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
	      glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, lightdir);
	    */
	    
	    ////////////////
	    // 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;
      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);                        
	  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;
	  /*	  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:
      _sleep(20); // 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;
}