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