Skip to content
Browse files

setup basic project, from stripping out A5, time to start work...

  • Loading branch information...
1 parent 76f2c03 commit 2f6b6a42713683cb8cb5b238038d009bb3b62910 @bettsmatt committed
Showing with 1,566 additions and 0 deletions.
  1. BIN BetaFX
  2. +488 −0 G308_Geometry.cpp
  3. +87 −0 G308_Geometry.h
  4. +176 −0 G308_ImageLoader.cpp
  5. +41 −0 G308_ImageLoader.h
  6. +13 −0 Makefile
  7. +94 −0 define.h
  8. +371 −0 main.cpp
  9. +235 −0 quaternion.cpp
  10. +61 −0 quaternion.h
View
BIN BetaFX
Binary file not shown.
View
488 G308_Geometry.cpp
@@ -0,0 +1,488 @@
+//---------------------------------------------------------------------------
+//
+// Copyright (c) 2012 Taehyun Rhee
+//
+// This software is provided 'as-is' for assignment of COMP308
+// in ECS, Victoria University of Wellington,
+// without any express or implied warranty.
+// In no event will the authors be held liable for any
+// damages arising from the use of this software.
+//
+// The contents of this file may not be copied or duplicated in any form
+// without the prior permission of its owner.
+//
+//----------------------------------------------------------------------------
+
+#include "G308_Geometry.h"
+#include "G308_ImageLoader.h"
+#include <stdio.h>
+#include <math.h>
+
+G308_Geometry::G308_Geometry(void) {
+ m_pVertexArray = NULL;
+ m_pNormalArray = NULL;
+ m_pUVArray = NULL;
+ m_pTriangles = NULL;
+
+ mode = G308_SHADE_POLYGON;
+
+ m_nNumPoint = m_nNumUV = m_nNumPolygon = 0;
+ m_glGeomListPoly = m_glGeomListWire = 0;
+
+ pos = (v3*) malloc(sizeof (v3));
+ pos->x = 0; pos->y = 0; pos->z = 0;
+
+ hasTexture = false;
+ textureID = 0;
+
+ hasCubemap = false;
+
+ mat_ambient = (GLfloat*) malloc (sizeof (GLfloat) * 4);
+ mat_diffuse = (GLfloat*) malloc (sizeof (GLfloat) * 4);
+ mat_specular = (GLfloat*) malloc (sizeof (GLfloat) * 4);
+ mat_shininess = (GLfloat*) malloc (sizeof (GLfloat) * 1);
+
+
+ for(int i = 0 ; i < 4 ; i ++){
+ mat_ambient[i] = 1.0f;
+ mat_diffuse[i] = 1.0f;
+ mat_specular[i] = 1.0f;
+ }
+
+ mat_shininess[0] = 1.0f;
+
+ worldRot = 0;
+
+}
+
+G308_Geometry::~G308_Geometry(void) {
+ if (m_pVertexArray != NULL)
+ delete[] m_pVertexArray;
+ if (m_pNormalArray != NULL)
+ delete[] m_pNormalArray;
+ if (m_pUVArray != NULL)
+ delete[] m_pUVArray;
+ if (m_pTriangles != NULL)
+ delete[] m_pTriangles;
+
+}
+
+void G308_Geometry::SetCubemap(){
+ hasCubemap = true;
+
+}
+
+void G308_Geometry::setTexture(GLuint textureID){
+ this->textureID = textureID;
+ hasTexture = true;
+}
+
+void G308_Geometry::setMaterial(GLfloat* ambient, GLfloat* diffuse, GLfloat* specular, GLfloat* shininess){
+
+ for(int i = 0 ; i < 4 ; i ++){
+ mat_diffuse[i] = diffuse[i];
+ mat_specular[i] = specular[i];
+ mat_ambient[i] = ambient[i];
+ }
+ mat_shininess[0] = shininess[0];
+
+}
+
+// Set the position
+void G308_Geometry::SetPos(v3* newPosition){
+ pos = newPosition;
+}
+
+//-------------------------------------------------------
+// Read in the OBJ (Note: fails quietly, so take care)
+//--------------------------------------------------------
+void G308_Geometry::ReadOBJ(const char *filename) {
+ FILE* fp;
+ char mode, vmode;
+ char str[200];
+ int v1, v2, v3, n1, n2, n3, t1, t2, t3;
+ int numVert, numNorm, numUV, numFace;
+ float x, y, z;
+ float u, v;
+
+ numVert = numNorm = numUV = numFace = 0;
+
+ fp = fopen(filename, "r");
+ if (fp == NULL)
+ printf("Error reading %s file\n", filename);
+ else
+ printf("Reading %s file\n", filename);
+
+ // Check number of vertex, normal, uvCoord, and Face
+ while (fgets(str, 200, fp) != NULL) {
+ sscanf(str, "%c%c", &mode, &vmode);
+ switch (mode) {
+ case 'v': /* vertex, uv, normal */
+ if (vmode == 't') // uv coordinate
+ numUV++;
+ else if (vmode == 'n') // normal
+ numNorm++;
+ else if (vmode == ' ') // vertex
+ numVert++;
+ break;
+ case 'f': /* faces */
+ numFace++;
+ break;
+ }
+ }
+
+ m_nNumPoint = numVert;
+ m_nNumUV = numUV;
+ m_nNumPolygon = numFace;
+ m_nNumNormal = numNorm;
+
+ printf("Number of Point %d, UV %d, Normal %d, Face %d\n", numVert, numUV,
+ numNorm, numFace);
+ //-------------------------------------------------------------
+ // Allocate memory for array
+ //-------------------------------------------------------------
+
+ if (m_pVertexArray != NULL)
+ delete[] m_pVertexArray;
+ m_pVertexArray = new G308_Point[m_nNumPoint];
+
+ if (m_pNormalArray != NULL)
+ delete[] m_pNormalArray;
+ m_pNormalArray = new G308_Normal[m_nNumNormal];
+
+ if (m_pUVArray != NULL)
+ delete[] m_pUVArray;
+ m_pUVArray = new G308_UVcoord[m_nNumUV];
+
+ if (m_pTriangles != NULL)
+ delete[] m_pTriangles;
+ m_pTriangles = new G308_Triangle[m_nNumPolygon];
+
+ //-----------------------------------------------------------
+ // Read obj file
+ //-----------------------------------------------------------
+ numVert = numNorm = numUV = numFace = 0;
+
+ fseek(fp, 0L, SEEK_SET);
+ while (fgets(str, 200, fp) != NULL) {
+ sscanf(str, "%c%c", &mode, &vmode);
+ switch (mode) {
+ case 'v': /* vertex, uv, normal */
+ if (vmode == 't') // uv coordinate
+ {
+ sscanf(str, "vt %f %f", &u, &v);
+ m_pUVArray[numUV].u = u;
+ m_pUVArray[numUV].v = v;
+ numUV++;
+ } else if (vmode == 'n') // normal
+ {
+ sscanf(str, "vn %f %f %f", &x, &y, &z);
+ m_pNormalArray[numNorm].x = x;
+ m_pNormalArray[numNorm].y = y;
+ m_pNormalArray[numNorm].z = z;
+ numNorm++;
+ } else if (vmode == ' ') // vertex
+ {
+ sscanf(str, "v %f %f %f", &x, &y, &z);
+ m_pVertexArray[numVert].x = x;
+ m_pVertexArray[numVert].y = y;
+ m_pVertexArray[numVert].z = z;
+ numVert++;
+ }
+ break;
+ case 'f': /* faces : stored value is index - 1 since our index starts from 0, but obj starts from 1 */
+ if (numNorm > 0 && numUV > 0) {
+ sscanf(str, "f %d/%d/%d %d/%d/%d %d/%d/%d", &v1, &t1, &n1, &v2, &t2, &n2, &v3, &t3, &n3);
+ } else if(numNorm > 0 && numUV ==0){
+ sscanf(str, "f %d//%d %d//%d %d//%d", &v1, &n1, &v2, &n2, &v3, &n3);
+ } else if(numUV > 0 && numNorm==0){
+ sscanf(str, "f %d/%d %d/%d %d/%d", &v1, &t1, &v2, &t2, &v3, &t3);
+ } else if(numUV==0 && numNorm==0){
+ sscanf(str, "f %d %d %d", &v1, &v2, &v3);
+ }
+ // Vertex indicies for triangle:
+ if (numVert != 0) {
+ m_pTriangles[numFace].v1 = v1 - 1;
+ m_pTriangles[numFace].v2 = v2 - 1;
+ m_pTriangles[numFace].v3 = v3 - 1;
+ }
+
+ // Normal indicies for triangle
+ if (numNorm != 0) {
+ m_pTriangles[numFace].n1 = n1 - 1;
+ m_pTriangles[numFace].n2 = n2 - 1;
+ m_pTriangles[numFace].n3 = n3 - 1;
+ }
+
+ // UV indicies for triangle
+ if (numUV != 0) {
+ m_pTriangles[numFace].t1 = t1 - 1;
+ m_pTriangles[numFace].t2 = t2 - 1;
+ m_pTriangles[numFace].t3 = t3 - 1;
+ }
+
+ numFace++;
+ break;
+ default:
+ break;
+ }
+ }
+
+ fclose(fp);
+ printf("Reading OBJ file is DONE.\n");
+
+}
+
+//--------------------------------------------------------------
+// [Assignment5]
+// Create a 2D GL texture from the file given
+//--------------------------------------------------------------
+void G308_Geometry::ReadTexture(const char* filename) {
+ //Your code here
+}
+
+
+void G308_Geometry::EnableCubemap(){
+
+
+
+
+ glEnable(GL_TEXTURE_GEN_S);
+ glEnable(GL_TEXTURE_GEN_T);
+ glEnable(GL_TEXTURE_GEN_R);
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+ glEnable(GL_TEXTURE_CUBE_MAP_EXT);
+
+}
+
+void G308_Geometry::DisableCubemap(){
+
+ glDisable(GL_TEXTURE_CUBE_MAP_EXT);
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
+ glDisable(GL_TEXTURE_GEN_R);
+
+}
+
+void G308_Geometry::CreateGLPolyGeometry() {
+ if (m_glGeomListPoly != 0)
+ glDeleteLists(m_glGeomListPoly, 1);
+
+ // Assign a display list; return 0 if err
+ m_glGeomListPoly = glGenLists(1);
+ glNewList(m_glGeomListPoly, GL_COMPILE);
+
+ glBegin(GL_TRIANGLES);
+
+ for(int i = 0 ; i < m_nNumPolygon ; i ++){
+
+ G308_Point v1 = m_pVertexArray[m_pTriangles[i].v1];
+ G308_Point v2 = m_pVertexArray[m_pTriangles[i].v2];
+ G308_Point v3 = m_pVertexArray[m_pTriangles[i].v3];
+
+ G308_Point n1 = m_pNormalArray[m_pTriangles[i].n1];
+ G308_Point n2 = m_pNormalArray[m_pTriangles[i].n2];
+ G308_Point n3 = m_pNormalArray[m_pTriangles[i].n3];
+
+ G308_UVcoord t1 = m_pUVArray[m_pTriangles[i].t1];
+ G308_UVcoord t2 = m_pUVArray[m_pTriangles[i].t2];
+ G308_UVcoord t3 = m_pUVArray[m_pTriangles[i].t3];
+
+ float textMult = 10.0f;
+
+ glTexCoord2f(t1.u * textMult, t1.v * textMult);
+ glNormal3f(n1.x, n1.y, n1.z );
+ glVertex3f(v1.x, v1.y, v1.z );
+
+ glTexCoord2f(t2.u * textMult, t2.v * textMult);
+ glNormal3f(n2.x, n2.y, n2.z );
+ glVertex3f(v2.x, v2.y, v2.z );
+
+ glTexCoord2f(t3.u * textMult, t3.v *textMult);
+ glNormal3f(n3.x, n3.y, n3.z );
+ glVertex3f(v3.x, v3.y, v3.z );
+
+ }
+
+ glEnd();
+
+
+ glEndList();
+}
+
+void G308_Geometry::CreateGLWireGeometry() {
+ if (m_glGeomListWire != 0)
+ glDeleteLists(m_glGeomListWire, 1);http://gm/
+
+ // Assign a display list; return 0 if err
+ m_glGeomListWire = glGenLists(1);
+ glNewList(m_glGeomListWire, GL_COMPILE);
+
+ //----------------------
+ //YOUR CODE GOES HERE
+ //
+ // .....
+ //
+ glBegin(GL_LINE_LOOP);
+
+ // Wireframe
+ for(int i = 0 ; i < m_nNumPolygon ; i ++){
+
+
+ G308_Point v1 = m_pVertexArray[m_pTriangles[i].v1];
+ G308_Point v2 = m_pVertexArray[m_pTriangles[i].v2];
+ G308_Point v3 = m_pVertexArray[m_pTriangles[i].v3];
+
+
+ glVertex3f(
+ v1.x,
+ v1.y,
+ v1.z
+ );
+
+ glVertex3f(
+ v2.x,
+ v2.y,
+ v2.z
+ );
+
+ glVertex3f(
+ v3.x,
+ v3.y,
+ v3.z
+ );
+
+ }
+
+ glEnd();
+
+ glEndList();
+
+}
+
+//--------------------------------------------------------------
+// [Assignment5]
+// Fill the following function to create display list
+// of the obj file to show it as polygon, using texture and normal information (if any)
+//--------------------------------------------------------------
+/*
+void G308_Geometry::CreateGLPolyGeometry() {
+ if (m_glGeomListPoly != 0)
+ glDeleteLists(m_glGeomListPoly, 1);
+
+ // Assign a display list; return 0 if err
+ m_glGeomListPoly = glGenLists(1);
+ glNewList(m_glGeomListPoly, GL_COMPILE);
+
+ //Your code here
+
+ glEndList();
+}/
+/*
+void G308_Geometry::CreateGLWireGeometry() {
+ if (m_glGeomListWire != 0)
+ glDeleteLists(m_glGeomListWire, 1);
+
+ // Assign a display list; return 0 if err
+ m_glGeomListWire = glGenLists(1);
+ glNewList(m_glGeomListWire, GL_COMPILE);
+
+ //Your code here: may not be required for assignment 5
+
+ glEndList();
+
+}
+ */
+
+void G308_Geometry::toggleMode() {
+ if (mode == G308_SHADE_POLYGON) {
+ mode = G308_SHADE_WIREFRAME;
+ } else {
+ mode = G308_SHADE_POLYGON;
+ }
+}
+
+void G308_Geometry::RenderGeometry() {
+
+ glPushMatrix();
+
+ glRotatef(worldRot,0,1,0);
+
+ glTranslated(pos->x,pos->y,pos->z);
+ /*
+ * Materials
+ */
+ glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
+ glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
+ glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
+ glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
+
+ if(hasTexture){
+ glEnable(GL_TEXTURE_2D);
+
+ glBindTexture(GL_TEXTURE_2D, textureID);
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+ }
+
+ if(hasCubemap){
+ EnableCubemap();
+ }
+
+
+ glBegin(GL_TRIANGLES);
+
+ for(int i = 0 ; i < m_nNumPolygon ; i ++){
+
+ G308_Point v1 = m_pVertexArray[m_pTriangles[i].v1];
+ G308_Point v2 = m_pVertexArray[m_pTriangles[i].v2];
+ G308_Point v3 = m_pVertexArray[m_pTriangles[i].v3];
+
+ G308_Point n1 = m_pNormalArray[m_pTriangles[i].n1];
+ G308_Point n2 = m_pNormalArray[m_pTriangles[i].n2];
+ G308_Point n3 = m_pNormalArray[m_pTriangles[i].n3];
+
+ G308_UVcoord t1 = m_pUVArray[m_pTriangles[i].t1];
+ G308_UVcoord t2 = m_pUVArray[m_pTriangles[i].t2];
+ G308_UVcoord t3 = m_pUVArray[m_pTriangles[i].t3];
+
+ float textMult = 10.0f;
+
+ glTexCoord2f(t1.u * textMult, t1.v * textMult);
+ glNormal3f(n1.x, n1.y, n1.z );
+ glVertex3f(v1.x, v1.y, v1.z );
+
+ glTexCoord2f(t2.u * textMult, t2.v * textMult);
+ glNormal3f(n2.x, n2.y, n2.z );
+ glVertex3f(v2.x, v2.y, v2.z );
+
+ glTexCoord2f(t3.u * textMult, t3.v *textMult);
+ glNormal3f(n3.x, n3.y, n3.z );
+ glVertex3f(v3.x, v3.y, v3.z );
+
+ }
+
+
+ glEnd();
+
+ if(hasCubemap){
+ DisableCubemap();
+ }
+
+ if(hasTexture){
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
+ }
+
+
+
+
+ glPopMatrix();
+
+}
View
87 G308_Geometry.h
@@ -0,0 +1,87 @@
+//---------------------------------------------------------------------------
+//
+// Copyright (c) 2012 Taehyun Rhee
+//
+// Edited by Daniel Atkins
+//
+// This software is provided 'as-is' for assignment of COMP308
+// in ECS, Victoria University of Wellington,
+// without any express or implied warranty.
+// In no event will the authors be held liable for any
+// damages arising from the use of this software.
+//
+// The contents of this file may not be copied or duplicated in any form
+// without the prior permission of its owner.
+//
+//----------------------------------------------------------------------------
+
+#pragma once
+
+#include "define.h"
+#include <GL/glut.h>
+
+typedef struct v3 {
+ double x;
+ double y;
+ double z;
+} v3;
+
+class G308_Geometry
+{
+private:
+ // Array for Geometry
+ G308_Point* m_pVertexArray; // Vertex Array
+ G308_Normal* m_pNormalArray; // Normal Array
+ G308_Triangle* m_pTriangles; // Triangle Array
+ G308_UVcoord* m_pUVArray; // Texture Coordinate Array
+
+ // Data for Geoemetry
+ int m_nNumPoint;
+ int m_nNumUV;
+ int m_nNumNormal;
+ int m_nNumPolygon;
+
+ int mode; // Which mode to display
+
+ // Data for Rendering
+ int m_glGeomListPoly; // Display List for Polygon
+ int m_glGeomListWire; // Display List for Wireframe
+
+
+
+ bool hasTexture;
+ GLuint textureID;
+
+ bool hasCubemap;
+
+ GLfloat* mat_specular;
+ GLfloat* mat_shininess;
+ GLfloat* mat_diffuse;
+ GLfloat* mat_ambient;
+
+public:
+
+ float worldRot;
+ v3* pos;
+
+ G308_Geometry(void);
+ ~G308_Geometry(void);
+
+ void ReadOBJ(const char* filename);
+ void ReadTexture(const char* filename);
+
+ void CreateGLPolyGeometry(); // [Assignment5] Create GL Display List for Polygon Geometry, using textures!
+ void CreateGLWireGeometry(); // Already written for you, this time.
+
+ void RenderGeometry(); // mode : G308_SHADE_POLYGON, G308_SHADE_WIREFRAME
+ void toggleMode(); //Switch between showing filled polygons and wireframes
+
+ void SetPos(v3* newPosition); // Set the position
+ void setTexture (GLuint); // Set the Texture
+ void setMaterial(GLfloat*, GLfloat*, GLfloat*, GLfloat*); // Material
+
+ void SetCubemap (); // Set cubema
+
+ void EnableCubemap (); // Enable cubemap
+ void DisableCubemap (); // Disable cubemap
+};
View
176 G308_ImageLoader.cpp
@@ -0,0 +1,176 @@
+//---------------------------------------------------------------------------
+//
+// Copyright (c) 2012 Daniel Atkins
+//
+// This software is provided 'as-is' for assignment of COMP308
+// in ECS, Victoria University of Wellington,
+// without any express or implied warranty.
+// In no event will the authors be held liable for any
+// damages arising from the use of this software.
+//
+// The contents of this file may not be copied or duplicated in any form
+// without the prior permission of its owner.
+//
+//----------------------------------------------------------------------------
+
+#include "G308_ImageLoader.h"
+
+/*
+ * Magical JPEG loader. You probably shouldn't edit this.
+ */
+int loadTextureFromJPEG(char* filename, TextureInfo *info) {
+
+ //Gonna need a file pointer.
+ FILE *fd;
+
+ //Init the structs required by libjpeg
+ struct jpeg_decompress_struct cinfo;
+ struct jpeg_error_mgr jerr;
+
+ //This will keep track of where we are in the file
+ unsigned char * line;
+
+ //Redirect stderr so things aren't messy
+ cinfo.err = jpeg_std_error(&jerr);
+
+ //Init the decompress struct
+ jpeg_create_decompress(&cinfo);
+
+ //Try to open the file. Better code would return an error value,
+ //but I'm just making it exit instead.
+ if (0 == (fd = fopen(filename, "rb"))) {
+ printf("Error opening file");
+ exit(1);
+ }
+ //Self evident.
+ info->filename = filename;
+ //Point libjpeg at the file
+ jpeg_stdio_src(&cinfo, fd);
+ //Read in the JPEG header
+ jpeg_read_header(&cinfo, TRUE);
+ //Used to keep track of offset in 1-D pixel array
+ unsigned int size = cinfo.image_width;
+
+ //Populate the texture-info struct.
+ //If it's not GL_RGB, then you have a really strange JPEG.
+ info->height = cinfo.image_height;
+ info->width = cinfo.image_width;
+ info->format = GL_RGB;
+ //If your JPEG somehow has alpha, you're gonna have a bad time.
+ info->hasAlpha = false;
+
+ //Assign an array for pixels
+ unsigned char* image = (unsigned char*) malloc(sizeof(char) * 3 * cinfo.image_height * cinfo.image_width);
+
+ //Begin magic.
+ jpeg_start_decompress(&cinfo);
+ while (cinfo.output_scanline < cinfo.output_height) {
+ line = image
+ + (3 * size) * cinfo.output_scanline;
+ jpeg_read_scanlines(&cinfo, &line, 1);
+ }
+ jpeg_finish_decompress(&cinfo);
+ jpeg_destroy_decompress(&cinfo);
+
+ //Allocate an array for the pixels. Why two? You'll see.
+ info->textureData = (unsigned char*) malloc(sizeof(char) * 3 * cinfo.image_height * cinfo.image_width);
+
+ //Copy the pixels from image to textureData in reverse row order. Because GL.
+ for(int y = info->height-1; y >= 0; y--){
+ for(int x = 0; x < info->width*3; x++){
+ info->textureData[(info->height-y-1)*(info->width*3)+x] = image[y*info->width*3+x];
+ }
+ }
+ free(image);
+
+ return 0;
+}
+
+/*
+ * Magical PNG loader. You probably shouldn't edit this.
+ */
+int loadTextureFromPNG(char* filename , TextureInfo* t){
+
+ //Required structs and file pointers.
+ png_structp png_ptr;
+ png_infop info_ptr;
+ unsigned int sig_read = 0;
+ FILE *fp;
+
+ //Again, this should return an error code instead of exiting,
+ //but for this assignment, it should work anyway.
+ if ((fp = fopen(filename, "rb")) == NULL){
+ printf("Error opening %s\n",filename);
+ exit(1);
+ }
+
+ //Magic, do not touch.
+ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+
+ if (png_ptr == NULL) {
+ printf("LibPNG did something terrible!\n");
+ fclose(fp);
+ exit(1);
+ }
+
+ //Allocate the struct we're going to read the data into.
+ info_ptr = png_create_info_struct(png_ptr);
+ if (info_ptr == NULL) {
+ printf("LibPNG did something terrible!\n");
+ fclose(fp);
+ png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
+ exit(1);
+ }
+
+ //Error handling magic. Do not touch.
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ printf("LibPNG did something terrible!\n");
+ png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
+ fclose(fp);
+ exit(1);
+ }
+
+ //Point libPNG to the right place
+ png_init_io(png_ptr, fp);
+ png_set_sig_bytes(png_ptr, sig_read);
+
+ //Yet more magic you shouldn't touch. We -probably- have enough memory to read it all in one go.
+ png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND, png_voidp_NULL);
+
+ //Start setting values in the textureinfo struct
+ //Note that PNGs -can- have alpha.
+ t->width = png_get_image_width(png_ptr,info_ptr);
+ t->height = png_get_image_height(png_ptr,info_ptr);
+ switch (png_get_color_type(png_ptr,info_ptr)) {
+ case PNG_COLOR_TYPE_RGBA:
+ t->hasAlpha = true;
+ break;
+ case PNG_COLOR_TYPE_RGB:
+ t->hasAlpha = false;
+ break;
+ default:
+ printf("Invalid PNG.\n");
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+ fclose(fp);
+ exit(1);
+ }
+ //How long is a row?
+ unsigned int row_bytes = png_get_rowbytes(png_ptr, info_ptr);
+ //Allocate some space!
+ t->textureData = (unsigned char*) malloc(row_bytes * t->height);
+
+ //Read the image data into the texture array, in reverse row order. Because GL.
+ png_bytepp row_pointers = png_get_rows(png_ptr, info_ptr);
+ for (int i = 0; i < t->height; i++) {
+ memcpy(t->textureData+(row_bytes * (t->height-1-i)), row_pointers[i], row_bytes);
+ }
+
+ //Clean up
+ png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
+ fclose(fp);
+
+ return 0;
+}
+
+
+
View
41 G308_ImageLoader.h
@@ -0,0 +1,41 @@
+/*
+ * 308_ImageLoader.h
+ *
+ * Created on: Sep 17, 2012
+ * Author: atkinsdani1
+ */
+
+#pragma once
+
+#include <GL/glut.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <jpeglib.h>
+#include <jerror.h>
+#include <png.h>
+
+//Magic defines for libPNG because they removed them from the library
+#define png_infopp_NULL (png_infopp)NULL
+#define int_p_NULL (int*)NULL
+#define png_voidp_NULL NULL
+
+/*
+ * The TextureInfo struct. This is where we keep all the texture info when we load a file.
+ * The actual image is stored as an array of unsigned characters (aka unsigned bytes).
+ * It's three bytes per pixel -- one for each color channel, so this array will have a length
+ * of width*height*3. Note that it is ONE dimensional!
+ */
+typedef struct texInfo {
+
+ char *filename;
+ unsigned char* textureData;
+ int format;
+ int width;
+ int height;
+ bool hasAlpha;
+
+} TextureInfo;
+
+int loadTextureFromJPEG(char*,TextureInfo*);
+
+int loadTextureFromPNG(char*, TextureInfo*);
View
13 Makefile
@@ -0,0 +1,13 @@
+CC = g++
+LPATH = -L/usr/pkg/lib
+LDPATH = -Wl,-R/usr/pkg/lib
+CFLAGS=-g -Wall
+LIBS=-lGL -lglut -lGLU -ljpeg -lpng15 -lm
+IPATH= -I/usr/pkg/include
+
+all:
+ $(CC) $(CFLAGS) -o BetaFX *.cpp $(IPATH) $(LIBS) $(LDPATH) $(LPATH)
+
+clean :
+ rm -rf *.o
+ rm TextureDemo
View
94 define.h
@@ -0,0 +1,94 @@
+//---------------------------------------------------------------------------
+//
+// Copyright (c) 2012 Taehyun Rhee
+//
+// Edited by Daniel Atkins
+//
+// This software is provided 'as-is' for assignment of COMP308
+// in ECS, Victoria University of Wellington,
+// without any express or implied warranty.
+// In no event will the authors be held liable for any
+// damages arising from the use of this software.
+//
+// The contents of this file may not be copied or duplicated in any form
+// without the prior permission of its owner.
+//
+//----------------------------------------------------------------------------
+
+#pragma once
+
+// Default Window
+#define G308_WIN_WIDTH 640
+#define G308_WIN_HEIGHT 480
+
+// Projection parameters
+#define G308_FOVY 20.0
+#define G308_ZNEAR_3D 1
+#define G308_ZFAR_3D 1000.0
+#define G308_ZNEAR_2D -50.0
+#define G308_ZFAR_2D 50.0
+
+// Shading mode : 0 Polygon, 1 Wireframe
+#define G308_SHADE_POLYGON 0
+#define G308_SHADE_WIREFRAME 1
+
+// Define number of vertex
+#define G308_NUM_VERTEX_PER_FACE 3 // Triangle = 3, Quad = 4
+
+// Define Basic Structures
+struct G308_Point {
+ float x;
+ float y;
+ float z;
+};
+
+struct G308_RGBA {
+ float r;
+ float g;
+ float b;
+ float a;
+};
+
+typedef G308_Point G308_Normal;
+
+struct G308_UVcoord {
+
+ float u;
+ float v;
+};
+
+/*
+ * Normals and textures need to be defined by face, not by vertex.
+ * Reminder: these are just indicies into the normal and texture arrays.
+ * n1 and t1 are the normals and texture co-ordinates for vertex 1 of this face.
+ * Same goes for (v2,n2,t2) etc.
+ */
+struct G308_Triangle {
+
+ unsigned int v1;
+ unsigned int v2;
+ unsigned int v3;
+ unsigned int n1;
+ unsigned int n2;
+ unsigned int n3;
+ unsigned int t1;
+ unsigned int t2;
+ unsigned int t3;
+};
+
+struct G308_Quad {
+
+ unsigned int v1;
+ unsigned int v2;
+ unsigned int v3;
+ unsigned int v4;
+ unsigned int n1;
+ unsigned int n2;
+ unsigned int n3;
+ unsigned int n4;
+ unsigned int t1;
+ unsigned int t2;
+ unsigned int t3;
+ unsigned int t4;
+};
+
View
371 main.cpp
@@ -0,0 +1,371 @@
+//---------------------------------------------------------------------------
+//
+// This software is provided 'as-is' for assignment of COMP308
+// in ECS, Victoria University of Wellington,
+// without any express or implied warranty.
+// In no event will the authors be held liable for any
+// damages arising from the use of this software.
+//
+// The contents of this file may not be copied or duplicated in any form
+// without the prior permission of its owner.
+//
+// Copyright (c) 2012 by Taehyun Rhee
+//
+// Edited by Roma Klapaukh, Daniel Atkins, and Taehyun Rhee
+//
+//---------------------------------------------------------------------------
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+#include <GL/glut.h>
+#include <GL/gl.h>
+#include "define.h"
+#include <string.h>
+#include <sstream>
+#include <math.h>
+#include "G308_Geometry.h"
+#include "quaternion.h"
+#include "G308_ImageLoader.h"
+
+GLuint g_mainWnd;
+GLuint g_nWinWidth = G308_WIN_WIDTH;
+GLuint g_nWinHeight = G308_WIN_HEIGHT;
+
+void G308_keyboardListener(unsigned char, int, int);
+void G308_Reshape(int w, int h);
+void G308_display();
+void G308_init();
+void G308_SetCamera();
+void G308_SetLight();
+
+void mouse(int button, int state, int x, int y);
+void mouseMotion (int x, int y);
+void menu (int);
+G308_Point getArcBallVector (int, int);
+
+// Objects
+#define BOX 0
+#define BUNNY 1
+#define SPHERE 2
+#define TABLE 3
+#define TEAPOT 4
+#define TORUS 5
+
+// Materials
+#define BRICK GLuint 0
+#define CUBEMAP 1
+#define NORMAL 2
+#define WOOD 3
+
+#define PI 3.14159265358979323846
+
+/*
+ * Current camera position
+ */
+v3* camPos;
+v3* camLookAt;
+v3* camRot;
+
+/*
+ * Keep track of camera positions
+ */
+typedef struct camera {
+ v3* camPos;
+ v3* camLookAt;
+ v3* camRot;
+} camera;
+
+
+int px;
+int py;
+bool rightMouseDown;
+bool animationMode;
+int menuID;
+
+bool arcBall;
+bool pan;
+bool zoom;
+
+char** menuItems;
+
+G308_Geometry** geometry = NULL;
+int numGeo;
+
+char** geometryFiles;
+v3** geometryPositions;
+
+GLuint* textureIDs;
+int numTextures;
+
+void loadTexture(char*, GLuint);
+
+void animate ();
+int rotations;
+
+v3 spotPosition;
+v3 spotDirection;
+float spotAngle;
+
+quaternion* rot;
+
+void loadCubemap();
+
+int main(int argc, char** argv) {
+
+ if (argc < 1 ) {
+ //Usage instructions for core and challenge
+ printf("Usage\n");
+ printf("./Ass3 priman.asf poses config\n");
+ exit(EXIT_FAILURE);
+ }
+
+
+ rot = new quaternion(1,0,0,0);
+
+ /*
+ * Turn all controls off
+ */
+ rightMouseDown = false;
+ animationMode = false;
+ pan = false;
+ zoom = false;
+ arcBall = false;
+
+ camPos = (v3*) malloc(sizeof(v3));
+ camLookAt = (v3*) malloc(sizeof(v3));
+ camRot = (v3*) malloc(sizeof(v3));
+
+ /*
+ * Set initial camera positions
+ */
+ camPos->x = 0, camPos->y = 0, camPos->z = 20;
+ camLookAt->x = 0, camLookAt->y = 0, camLookAt->z = 0;
+ camRot->x = 0, camRot->y = 1, camRot->z = 0;
+
+ glutInit(&argc, argv);
+ glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
+ glutInitWindowSize(g_nWinWidth, g_nWinHeight);
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
+
+ g_mainWnd = glutCreateWindow("COMP308 Assignment4");
+
+ glutKeyboardFunc(G308_keyboardListener);
+
+ glutDisplayFunc(G308_display);
+ glutReshapeFunc(G308_Reshape);
+
+ G308_init();
+
+ glutIdleFunc(animate);
+ glutMouseFunc(mouse);
+ glutMotionFunc(mouseMotion);
+ glutMainLoop();
+
+ return EXIT_SUCCESS;
+}
+
+void animate(){
+
+ if(rotations > 0){
+ rotations--;
+ for(int i = 0 ; i < numGeo ; i ++){
+ geometry[i]->worldRot += 5;
+ }
+ }
+
+ G308_display();
+
+}
+
+void loadTexture (char* filename, GLuint id){
+
+ texInfo* t = (texInfo*) malloc(sizeof(texInfo));
+
+ loadTextureFromJPEG(filename, t);
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glGenTextures(1, &id);
+ glBindTexture(GL_TEXTURE_2D, id);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, t->width, t->height, 0, GL_RGB,
+ GL_UNSIGNED_BYTE, t->textureData);
+}
+
+
+
+/*
+ * Menu options
+ */
+ void menu (int i){
+
+}
+
+// Init Light and Camera
+void G308_init() {
+ G308_SetLight();
+ G308_SetCamera();
+}
+
+// Display call back
+void G308_display() {
+
+ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ glEnable(GL_LIGHT1);
+ glEnable(GL_LIGHT2);
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_COLOR_MATERIAL);
+
+ glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+ glShadeModel(GL_SMOOTH);
+
+ GLenum err = glGetError();
+ if (err != GL_NO_ERROR) {
+ printf("%s\n", gluErrorString(err));
+ }
+
+
+ glPushMatrix();
+
+ glutWireSphere(3,100,100);
+
+ for(int i = 0 ; i < numGeo ; i ++)
+ geometry[i]->RenderGeometry();
+
+
+
+
+ glPopMatrix();
+
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_LIGHTING);
+ glDisable(GL_LIGHT2);
+ glDisable(GL_LIGHT1);
+ glDisable(GL_LIGHT0);
+ glDisable(GL_COLOR_MATERIAL);
+
+ glutSwapBuffers();
+}
+
+
+void mouseMotion (int x, int y){
+
+}
+
+
+
+void mouse (int button, int state, int x, int y){
+
+}
+
+void G308_keyboardListener(unsigned char key, int x, int y) {
+
+ if(key == 't' && rotations == 0)
+ rotations = 72;
+
+ // Forward
+ if(key == '8'){
+ spotPosition.z += 1;
+ }
+
+ // Back
+ if(key == '2'){
+ spotPosition.z -= 1;
+ }
+
+ // Left
+ if(key == '4'){
+ spotPosition.x -= 1;
+ }
+
+ // Right
+ if(key == '6'){
+ spotPosition.x += 1;
+ }
+
+ // Up
+ if(key == '+'){
+ spotPosition.y -= 1;
+ }
+
+ // Down
+ if(key == '-'){
+ spotPosition.y += 1;
+ }
+
+ // AngleUp
+ if(key == '7'){
+ spotDirection.x += 0.1;
+ }
+
+ // AngleDown
+ if(key == '9'){
+ spotDirection.x -= 0.1;
+ }
+
+ // AngleLeft
+ if(key == '1'){
+ spotDirection.z += 0.1;
+ }
+
+ // AngleRight
+ if(key == '3'){
+ spotDirection.z -= 0.1;
+ }
+
+ // Decrease Angle
+ if(key == '/'){
+ spotAngle -= 1;
+ }
+
+ // Increase Angle
+ if(key == '*'){
+ spotAngle += 1;
+ }
+
+ G308_SetLight();
+ G308_display();
+
+}
+
+// Reshape function
+void G308_Reshape(int w, int h) {
+ if (h == 0)
+ h = 1;
+
+ g_nWinWidth = w;
+ g_nWinHeight = h;
+
+ glViewport(0, 0, g_nWinWidth, g_nWinHeight);
+}
+
+// Set Camera Position
+void G308_SetCamera() {
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluPerspective(G308_FOVY, (double) g_nWinWidth / (double) g_nWinHeight, G308_ZNEAR_3D, G308_ZFAR_3D);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ gluLookAt(
+ camPos->x,camPos->y,camPos->z,
+ camLookAt->x,camLookAt->y,camLookAt->z,
+ camRot->x,camRot->y,camRot->z
+ );
+
+}
+
+// Set View Position
+void G308_SetLight() {
+
+
+}
+
View
235 quaternion.cpp
@@ -0,0 +1,235 @@
+//---------------------------------------------------------------------------
+//
+// This software is provided 'as-is' for assignment of COMP308
+// in ECS, Victoria University of Wellington,
+// without any express or implied warranty.
+// In no event will the authors be held liable for any
+// damages arising from the use of this software.
+//
+// The contents of this file may not be copied or duplicated in any form
+// without the prior permission of its owner.
+//
+// Copyright (c) 2012 by Taehyun Rhee
+//
+// Edited by Roma Klapaukh, Daniel Atkins, and Taehyun Rhee
+//
+//---------------------------------------------------------------------------
+
+
+#include "quaternion.h"
+#include <math.h>
+
+float dotproduct(G308_Point p, G308_Point q) {
+ float a = 0;
+ a += p.x * q.x;
+ a += p.y * q.y;
+ a += p.z * q.z;
+ return a;
+}
+
+G308_Point crossproduct(G308_Point p, G308_Point q) {
+ G308_Point cross;
+ cross.x = p.y * q.z - p.z * q.y;
+ cross.y = p.z * q.x - p.x * q.z;
+ cross.z = p.x * q.y - p.y * q.x;
+ return cross;
+}
+
+quaternion::quaternion(float r, float i, float j, float k) :
+ a(r), b(i), c(j), d(k) {
+}
+
+quaternion::quaternion(float angle, const G308_Point& p) {
+ float ang = angle / (2 * 57.2957795); //convert into radians and halve
+ a = cos(ang);
+ float s = sin(ang);
+ b = s * p.x;
+ c = s * p.y;
+ d = s * p.z;
+}
+
+//Out by a factor of 2 like in the arc ball paper
+quaternion::quaternion(const G308_Point &p1, const G308_Point& p2) {
+ a = dotproduct(p1, p2);
+ G308_Point cross = crossproduct(p1, p2);
+ b = cross.x;
+ c = cross.y;
+ d = cross.z;
+}
+
+quaternion::quaternion(float mat[16]) {
+ float tr, s, q[4];
+ int i, j, k;
+ int nxt[3] = { 1, 2, 0 };
+ tr = mat[0] + mat[5] + mat[10];
+ if (tr > 0.0) {
+ s = sqrt(tr + 1.0);
+ a = s / 2.0;
+ s = 0.5 / s;
+ b = (mat[4 + 2] - mat[2 * 4 + 1]) * s;
+ c = (mat[4 * 2 + 0] - mat[2]) * s;
+ d = (mat[1] - mat[4]) * s;
+ } else {
+ i = 0;
+ if (mat[5] > mat[0]) {
+ i = 1;
+ }
+ if (mat[10] > mat[4 * i + i]) {
+ i = 2;
+ }
+ j = nxt[i];
+ k = nxt[j];
+ s = sqrt((mat[4 * i + i] - (mat[4 * j + i] + mat[4 * k + k])) + 1.0);
+ q[i] = s * 0.5;
+ if (s != 0.0) {
+ s = 0.5 / s;
+ q[3] = (mat[4 * j + k] - mat[4 * k + j]) * s;
+ q[j] = (mat[4 * i + j] - mat[4 * j + i]) * s;
+ q[k] = (mat[4 * i + k] - mat[4 * k + i]) * s;
+ b = q[0];
+ c = q[1];
+ d = q[2];
+ a = q[3];
+ }
+ }
+}
+
+quaternion::quaternion(const quaternion& q) :
+ a(q.a), b(q.b), c(q.c), d(q.d) {
+
+}
+
+quaternion::~quaternion() {
+
+}
+
+G308_Point quaternion::vector() const{
+ G308_Point v;
+ v.x = b;
+ v.y = c;
+ v.z = d;
+ return v;
+}
+
+float quaternion::length() const {
+ float l = a * a + b * b + c * c + d * d;
+ l = sqrt(l);
+ return l;
+}
+
+quaternion quaternion::conjugate() const {
+ quaternion q(a, -b, -c, -d);
+ return q;
+}
+
+quaternion quaternion::multiplicativeInverse() const {
+ float len = length();
+ len = len * len;
+ quaternion c = conjugate();
+ quaternion inverse = c / len;
+ return inverse;
+}
+
+quaternion quaternion::normalise() const {
+ float l = length();
+ return (*this) / l;
+}
+
+void quaternion::print() const{
+ printf("(%.2f,%.2f.%.2f,%.2f)",a,b,c,d);
+}
+
+void quaternion::toMatrix(float* matrix) const {
+ //OpenGL friendly => by column!
+ quaternion q = normalise();
+
+ //column 1
+ matrix[0] = q.a * q.a + q.b * q.b - q.c * q.c - q.d * q.d;
+ matrix[1] = 2 * q.b * q.c + 2 * q.a * q.d;
+ matrix[2] = 2 * q.b * q.d - 2 * q.a * q.c;
+ matrix[3] = 0;
+
+ //column 2
+ matrix[4] = 2 * q.b * q.c - 2 * q.a * q.d;
+ matrix[5] = q.a * q.a - q.b * q.b + q.c * q.c - q.d * q.d;
+ matrix[6] = 2 * q.c * q.d + 2 * q.a * q.b;
+ matrix[7] = 0;
+
+ //column 3
+ matrix[8] = 2 * q.b * q.d + 2 * q.a * q.c;
+ matrix[9] = 2 * q.c * q.d - 2 * q.a * q.b;
+ matrix[10] = q.a * q.a - q.b * q.b - q.c * q.c + q.d * q.d;
+ matrix[11] = 0;
+
+ //column 4
+ matrix[12] = 0;
+ matrix[13] = 0;
+ matrix[14] = 0;
+ matrix[15] = q.a * q.a + q.b * q.b + q.c * q.c + q.d * q.d;
+}
+
+quaternion& quaternion::operator=(const quaternion& q) {
+ a = q.a;
+ b = q.b;
+ c = q.c;
+ d = q.d;
+ return *this;
+}
+
+quaternion operator+(const quaternion& q1, const quaternion& q2) {
+ quaternion q(q1.a + q2.a, q1.b + q2.b, q1.c + q2.c, q1.d + q2.d);
+ return q;
+}
+
+quaternion operator-(const quaternion& q1, const quaternion& q2) {
+ quaternion q(q1.a - q2.a, q1.b - q2.b, q1.c - q2.c, q1.d - q2.d);
+ return q;
+}
+
+quaternion operator*(const quaternion& q1, const quaternion& q2) {
+ float a = q1.a * q2.a - q1.b * q2.b - q1.c * q2.c - q1.d * q2.d;
+ float b = q1.a * q2.b + q1.b * q2.a + q1.c * q2.d - q1.d * q2.c;
+ float c = q1.a * q2.c - q1.b * q2.d + q1.c * q2.a + q1.d * q2.b;
+ float d = q1.a * q2.d + q1.b * q2.c - q1.c * q2.b + q1.d * q2.a;
+
+ quaternion q(a, b, c, d);
+ return q;
+}
+
+quaternion operator*(const quaternion& q1, const float& f) {
+ quaternion q(f * q1.a, f * q1.b, f * q1.c, f * q1.d);
+ return q;
+}
+
+quaternion operator/(const quaternion& q1, const quaternion& q2) {
+ quaternion q2inv = q2.multiplicativeInverse();
+ quaternion r = q1 * q2inv;
+ return r;
+}
+
+quaternion operator/(const quaternion& q1, const float& f) {
+ quaternion q(q1.a / f, q1.b / f, q1.c / f, q1.d / f);
+ return q;
+}
+
+float dotproduct(const quaternion& q1, const quaternion& q2) {
+ float f = q1.a * q2.a + q1.b * q2.b + q1.c * q2.c + q1.d * q2.d;
+ return f;
+}
+
+quaternion slerp(const quaternion& p1, const quaternion& q1, float t) {
+ quaternion q = q1.normalise();
+ quaternion p = p1.normalise();
+ float epsilon = 0.0001;
+ if (dotproduct(p, q) < 0) {
+ q = q * -1;
+ }
+ float dpq = dotproduct(p, q);
+ if ((1.0 - dpq) > epsilon) {
+ float w = acos(dpq);
+ return ((sin((1 - t) * w) * p) + (sin(t * w) * q)) / sin(w);
+ } else {
+ return (1 - t) * p + t * q;
+ }
+
+}
View
61 quaternion.h
@@ -0,0 +1,61 @@
+//---------------------------------------------------------------------------
+//
+// This software is provided 'as-is' for assignment of COMP308
+// in ECS, Victoria University of Wellington,
+// without any express or implied warranty.
+// In no event will the authors be held liable for any
+// damages arising from the use of this software.
+//
+// The contents of this file may not be copied or duplicated in any form
+// without the prior permission of its owner.
+//
+// Copyright (c) 2012 by Taehyun Rhee
+//
+// Edited by Roma Klapaukh, Daniel Atkins, and Taehyun Rhee
+//
+//---------------------------------------------------------------------------
+
+#ifndef QUATERNIONH
+#define QUATERNIONH
+
+#include <stdio.h>
+#include <GL/glut.h>
+#include "define.h"
+
+class quaternion {
+
+private:
+ float a,b,c,d;
+
+public:
+ quaternion(const G308_Point&,const G308_Point&);
+ quaternion(float, const G308_Point&);
+ quaternion(float=0,float=0,float=0,float=0);
+ quaternion(float[16]);
+ quaternion(const quaternion&);
+ ~quaternion();
+ quaternion& operator=(const quaternion&);
+ float length() const;
+ quaternion conjugate() const;
+ void toMatrix(float*) const;
+ quaternion normalise() const;
+ quaternion multiplicativeInverse() const;
+ G308_Point vector() const;
+ void print()const;
+
+friend quaternion operator+(const quaternion&, const quaternion&);
+friend quaternion operator-(const quaternion&, const quaternion&);
+friend quaternion operator*(const quaternion&, const quaternion&);
+friend quaternion operator*(const quaternion&, const float&);
+friend quaternion operator/(const quaternion&, const quaternion&);
+friend quaternion operator/(const quaternion&, const float&);
+friend float dotproduct(const quaternion&, const quaternion&);
+friend quaternion slerp(const quaternion&, const quaternion&, float);
+
+
+};
+
+float dotproduct(G308_Point,G308_Point);
+G308_Point crossproduct(G308_Point,G308_Point);
+
+#endif

0 comments on commit 2f6b6a4

Please sign in to comment.
Something went wrong with that request. Please try again.