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