Revision 10 (by moose, 2006/05/16 02:41:58)
#include <stdio.h>

#include <allegro.h>

#include <alleggl.h>

#include <GL/glu.h>

#include <vector>


#define GRID_SIZE 64

#define M_PI   3.1415926535897932384626433832795


#include "cube.h"

#include "xgl_vector.h"

#include "xgl_quat.h"


#define rad(d) ((M_PI * (d)) / 180.0)

#define deg(r) (((r) / M_PI) * 180.0)


GLuint Tex;
GLuint Slate;

/* Parameters controlling the camera and projection state */
int viewport_w = 320;  /* Viewport Width  (pixels)  */
int viewport_h = 240;  /* Viewport Height (pixels)  */
int fov = 48;          /* Field of view   (degrees) */
float aspect = 1;      /* Aspect ratio              */
 
void ViewOrtho(int x, int y)                                                    // Set Up An Ortho View

{
	glDisable(GL_DEPTH_TEST);
	glDepthMask(GL_FALSE);

        glMatrixMode(GL_PROJECTION);                                    // Select Projection

//        glPushMatrix();                                                 // Push The Matrix

        glLoadIdentity();                                               // Reset The Matrix

        glOrtho( 0, x , y , 0, -1, 1 );                         // Select Ortho Mode

        glMatrixMode(GL_MODELVIEW);                                     // Select Modelview Matrix

//        glPushMatrix();                                                 // Push The Matrix

        glLoadIdentity();                                               // Reset The Matrix

}

void ViewPerspective(void)                                                      // Set Up A Perspective View

{
        glMatrixMode( GL_PROJECTION );                                  // Select Projection

//        glPopMatrix();                                                  // Pop The Matrix

        glMatrixMode( GL_MODELVIEW );                                   // Select Modelview

//        glPopMatrix();                                                  // Pop The Matrix

	glLoadIdentity();
	gluPerspective((float)fov, (double)SCREEN_W/(double)SCREEN_H, 1.0, 1000.0);

	glEnable(GL_DEPTH_TEST);
	glDepthMask(GL_TRUE);
}

class Thing {

	public:
		Thing() : x(0.0), y(0.0), z(0.0) {}
		Thing(float _x, float _y, float _z, float _w, float _h) : x(_x), y(_y), z(_z), w(_w), h(_h) {};
		virtual ~Thing() {}

		virtual void render();
		virtual void update();

	private:
		float x, y, z;
		float w, h;
};

void Thing::render()
{
	ViewOrtho(SCREEN_W, SCREEN_H);


//	glEnable(GL_BLEND);

//	glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

//	glColor4i( 255, 255, 255, 100 );

	glBindTexture(GL_TEXTURE_2D, Slate);

//	allegro_gl_printf_ex(font, 1, 1, -1, "Foo is a really long string that I'm trying to print so I can see something hopefully!");


//	glColor4i( 0, 0, 255, 100 );

//	glBlendFunc(GL_ONE_MINUS_SRC_ALPHA,GL_ONE_MINUS_SRC_COLOR);


//	glBlendFunc (GL_ONE, GL_ONE);

//	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR);

//	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_DST_COLOR);

	 glBindTexture(GL_TEXTURE_2D, Slate);
	glBegin(GL_QUADS);

		glColor4i( 0, 0, 255, 0 );

		glTexCoord2f( 0, 0 );
		glVertex2f( x, y );

		glTexCoord2f( 0, 1 );
		glVertex2f( x, y + h );

		glTexCoord2f( 1, 1 );
		glVertex2f( x + w, y + h );

		glTexCoord2f( 1, 0 );
		glVertex2f( x + w, y );
//		glColor4i( 100, 100, 100, 100 );


	glEnd();

	ViewPerspective();

//	glDisable(GL_BLEND);

}

void Thing::update()
{

}
/*

class ModelLoader;

class Model {

	friend class ModelLoader;



	public:

		Model();

		virtual ~Model();



	private:

		

		int vertex_count;

		double *vertex;



		int normal_count;

		double *normal;



		int texcoord_count;

		double *texcoord;

};



class ModelLoader {

	

	public:

		Model

};

*/
class Camera {
	public:
		Vector position;
		Quaternion orientation;

		static Camera *Instance()
		{
			if(!instance) {
				instance = new Camera();
			}
			return instance;
		}

		static Camera *Instance(Vector v)
		{
			if(!instance) {
				instance = new Camera(v);
			}
			return instance;
		}

		void setup();

	protected:
	Camera():orientation(identity_quat),position(0,0,4) {}
	Camera(Vector givpos):orientation(identity_quat),position(givpos) {}

	private:
	static Camera *instance;

};

Camera *Camera::instance = 0;

void Camera::setup()
{
	glViewport(0, 0, SCREEN_W, SCREEN_H);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective((float)fov, (double)SCREEN_W/(double)SCREEN_H, 1.0, 1000.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	float theta = deg(2 * acos(orientation.w));
	if (orientation.w < 1.0f && orientation.w > -1.0f) {
		glRotatef(theta, orientation.x, orientation.y, orientation.z);
	}

	glTranslatef(-(position.x), -(position.y), -(position.z));
}

void draw_cube(double x, double y, double z, double size)
{
	Cube cube(x, y, z, size);
	cube.Render();
}

void draw_field()
{
//	glPushMatrix();

   draw_cube(2, -2, -4, 2);
   draw_cube(-2, 2, -4, 2);
   draw_cube(-2, -2, -4, 2);
   draw_cube(2, 2, -4, 2);
//	glPopMatrix();

}

int do_keyboard()
{
	Camera *cam = Camera::Instance();
	QUAT q;

	if (key[KEY_LEFT]) {
		get_y_rotate_quat(&q, -0.1);
		cam->orientation*=q; //*= order is different from * order

	}
	if (key[KEY_RIGHT]) {
		get_y_rotate_quat(&q, 0.1);
		cam->orientation*=q; //*= order is different from * order

	}
	if(key[KEY_DOWN]) {
		cam->position-=(cam->orientation+Vector(0,0,-0.1))/10;
	}
	if(key[KEY_UP]) {
		cam->position+=(cam->orientation+Vector(0,0,-0.1))/10;
	}
	if(key[KEY_W]) {
		cam->position-=(cam->orientation+Vector(0,-0.1,0))/10;
	}
	if(key[KEY_S]) {
		cam->position+=(cam->orientation+Vector(0,-0.1,0))/10;
	}
	if(key[KEY_A]) {
		cam->position-=(cam->orientation+Vector(-0.1,0,0))/10;
	}
	if(key[KEY_D]) {
		cam->position+=(cam->orientation+Vector(-0.1,0,0))/10;
	}
	if (key[KEY_1]) {
		glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
	} 
	if(key[KEY_2])
	{
		glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
	}
	return 0;
}

int main ()
{
	BITMAP* temp_bmp = NULL;

	allegro_init();

	install_allegro_gl();
	
	allegro_gl_clear_settings();
	allegro_gl_set (AGL_COLOR_DEPTH, 32);
	allegro_gl_set (AGL_Z_DEPTH, 24);

	allegro_gl_set (AGL_WINDOWED, TRUE);
	allegro_gl_set (AGL_DOUBLEBUFFER, 1);
	allegro_gl_set (AGL_SUGGEST, AGL_COLOR_DEPTH | AGL_Z_DEPTH | AGL_DOUBLEBUFFER | AGL_WINDOWED);

	if (set_gfx_mode(GFX_OPENGL, 640, 480, 0, 0) < 0) {
		allegro_message ("Error setting OpenGL graphics mode:\n%s\n"
		                 "Allegro GL error : %s\n",
		                 allegro_error, allegro_gl_error);
		return -1;
	}

    install_keyboard();
    install_timer();

    glEnable(GL_TEXTURE_2D);

    allegro_gl_set_texture_format(GL_RGBA8);

	temp_bmp = load_bitmap("slate.bmp", 0);
	Slate = allegro_gl_make_texture(temp_bmp);

    // Load the texture

    temp_bmp = load_bitmap("wall-texture.bmp", 0);
    Tex = allegro_gl_make_texture(temp_bmp);
    glBindTexture(GL_TEXTURE_2D, Tex);
	destroy_bitmap(temp_bmp);



	Camera::Instance()->setup();

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

//	glEnable(GL_BLEND);

//	glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	Thing thing(100, 100, 0, 100, 100);
	Thing thing2(150, 150, 1, 100, 100);

	font = allegro_gl_convert_allegro_font_ex(font, AGL_FONT_TYPE_DONT_CARE, 2.0, -1);

    Camera::Instance(Vector(0,0,4));
	while(!key[KEY_ESC]) {
		glClearColor(0.5f, 0.2f, 0.5f, 0.0f);
		glClearDepth(1.0f);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//		glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

//		glBlendFunc (GL_ONE, GL_ONE);

		do_keyboard();
		Camera::Instance()->setup();
		glBindTexture(GL_TEXTURE_2D, Tex);
		draw_field();
		glBindTexture(GL_TEXTURE_2D, Slate);
		thing.render();
		thing2.render();
		glFlush();
		allegro_gl_flip();
	}

    set_gfx_mode (GFX_TEXT, 0, 0, 0, 0);

   return 0;
}
END_OF_MAIN();