- #define GLUT_DISABLE_ATEXIT_HACK
- #include <GL/gl.h>
- #include <GL/glu.h>
- #include <GL/glut.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include <ctime>
- #include <malloc.h>
- #include <math.h>
- #include "Targa.h"
- int screenWidth = 600;
- int screenHeight = 600;
- int fps = 60;
- GLdouble cameraPos[] = {0.0, 0.0, 25.0};
- double rotation = 0.0;
- GLfloat lightAmb[] = {1.0, 0.0, 0.0, 1.0};
- GLfloat lightDif[] = {0.7, 0.7, 0.7, 1.0};
- GLfloat lightPos[] = {10, 10, 10, 1.0};
- GLfloat lightSpec[] = {1, 1, 1, 1};
- GLuint tex[1];
- typedef struct {
- unsigned short vertices;
- unsigned short normals;
- unsigned short indices;
- unsigned short texCoords;
- float verticesArray[10000];
- float normalsArray[10000];
- unsigned short indicesArray[10000];
- float texCoordsArray[10000];
- } _3DSOBJ;
- _3DSOBJ *ship;
- _3DSOBJ *load3DSObject(const char *filename){
- FILE *f = fopen(filename, "rb");
- _3DSOBJ *object = (_3DSOBJ*)malloc(sizeof(_3DSOBJ));
- int size;
- unsigned short id = 0;
- unsigned int next = 0;
- if(f != NULL){
- fseek(f, 0, SEEK_END);
- size = ftell(f);
- fseek(f, 0, SEEK_SET);
- while(ftell(f) < size){
- id = 0;
- next = 0;
- fread(&id, 2, 1, f);
- fread(&next, 4, 1, f);
- switch(id){
- case 0x4D4D:
- printf("MAIN3DS\n");
- break;
- case 0x3D3D:
- printf("EDIT3DS\n");
- break;
- case 0x4000:
- printf("EDIT_OBJECT\n");
- char c;
- printf("\tObject name: ");
- do {
- fread(&c, 1, 1, f);
- printf("%c", c);
- } while(c != '\0');
- printf("\n");
- break;
- case 0x4100:
- printf("OBJ_TRIMESH\n");
- break;
- case 0x4110:
- printf("TRI_VERTEXL\n");
- fread(&object->vertices, sizeof(unsigned short), 1, f);
- printf("\tVertices: %d\n", object->vertices);
- for(int i = 0; i < object->vertices * 3; i++){
- fread(&object->verticesArray[i], sizeof(float), 1, f);
- if((i + 1) % 3 == 0)
- printf("\t\tVertex %d: (%.3f, %.3f, %.3f)\n", (i + 1) / 3, object->verticesArray[i - 2], object->verticesArray[i - 1], object->verticesArray[i]);
- }
- break;
- case 0x4120:
- printf("TRI_POLYGONL\n");
- fread(&object->indices, sizeof(unsigned short), 1, f);
- printf("\tIndices: %d\n", object->indices);
- GLushort tmp;
- int i2;
- i2 = 0;
- for(int i = 0; i < object->indices * 4; i++){
- if((i + 1) % 4 == 0) {
- fread(&tmp, sizeof(unsigned short), 1, f);
- printf("\t\tPolygon %d: (%d, %d, %d)\n", i2 / 3, object->indicesArray[i2 - 3], object->indicesArray[i2 - 2], object->indicesArray[i2 - 1]);
- } else {
- fread(&object->indicesArray[i2], sizeof(unsigned short), 1, f);
- i2++;
- }
- }
- break;
- case 0x4140:
- printf("TRI_MAPPINGCOORS\n");
- fread(&object->texCoords, sizeof(unsigned short), 1, f);
- printf("\tTex indices: %d\n", object->texCoords);
- for(int i = 0; i < object->texCoords * 2; i++){
- fread(&object->texCoordsArray[i], sizeof(float), 1, f);
- if((i + 1) % 2 == 0)
- printf("\t\tTex index %d: (%.3f, %.3f)\n", (i + 1) / 2, object->texCoordsArray[i - 1], object->texCoordsArray[i]);
- }
- break;
- default:
- fseek(f, next - 6, SEEK_CUR);
- }
- }
- for(int i = 0; i < object->indices; i++){
- GLfloat p1x = object->verticesArray[object->indicesArray[i * 3] * 3];
- GLfloat p1y = object->verticesArray[object->indicesArray[i * 3] * 3 + 1];
- GLfloat p1z = object->verticesArray[object->indicesArray[i * 3] * 3 + 2];
- GLfloat p2x = object->verticesArray[object->indicesArray[i * 3 + 1] * 3];
- GLfloat p2y = object->verticesArray[object->indicesArray[i * 3 + 1] * 3 + 1];
- GLfloat p2z = object->verticesArray[object->indicesArray[i * 3 + 1] * 3 + 2];
- GLfloat p3x = object->verticesArray[object->indicesArray[i * 3 + 2] * 3];
- GLfloat p3y = object->verticesArray[object->indicesArray[i * 3 + 2] * 3 + 1];
- GLfloat p3z = object->verticesArray[object->indicesArray[i * 3 + 2] * 3 + 2];
- GLfloat nx1 = (p2y - p1y) * (p3z - p1z) - (p2z - p1z) * (p3y - p1y);
- GLfloat ny1 = (p2z - p1z) * (p3x - p1x) - (p2x - p1x) * (p3z - p1z);
- GLfloat nz1 = (p2x - p1x) * (p3y - p1y) - (p2y - p1y) * (p3x - p1x);
- GLfloat l1 = sqrtf(powf(nx1, 2) + powf(ny1, 2) + powf(ny1, 2));
- nx1 /= l1;
- ny1 /= l1;
- nz1 /= l1;
- GLfloat nx2 = (p1y - p2y) * (p3z - p2z) - (p1z - p2z) * (p3y - p2y);
- GLfloat ny2 = (p1z - p2z) * (p3x - p2x) - (p1x - p2x) * (p3z - p2z);
- GLfloat nz2 = (p1x - p2x) * (p3y - p2y) - (p1y - p2y) * (p3x - p2x);
- GLfloat l2 = sqrtf(pow(nx2, 2) + pow(ny2, 2) + pow(ny2, 2));
- nx2 /= l2;
- ny2 /= l2;
- nz2 /= l2;
- GLfloat nx3 = (p2y - p3y) * (p1z - p3z) - (p2z - p3z) * (p1y - p3y);
- GLfloat ny3 = (p2z - p3z) * (p1x - p3x) - (p2x - p3x) * (p1z - p3z);
- GLfloat nz3 = (p2x - p3x) * (p1y - p3y) - (p2y - p3y) * (p1x - p3x);
- GLfloat l3 = sqrtf(pow(nx3, 2) + pow(ny3, 2) + pow(ny3, 2));
- nx3 /= l3;
- ny3 /= l3;
- nz3 /= l3;
- object->normals += 9;
- object->normalsArray[i * 9] = nx1;
- object->normalsArray[i * 9 + 1] = ny1;
- object->normalsArray[i * 9 + 2] = nz1;
- object->normalsArray[i * 9 + 3] = nx2;
- object->normalsArray[i * 9 + 4] = ny2;
- object->normalsArray[i * 9 + 5] = nz2;
- object->normalsArray[i * 9 + 6] = nx3;
- object->normalsArray[i * 9 + 7] = ny3;
- object->normalsArray[i * 9 + 8] = nz3;
- }
- fclose(f);
- return object;
- } else {
- printf("Can't open file\n");
- return NULL;
- }
- }
- void init(){
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_NORMALIZE);
- glEnable(GL_LIGHTING);
- glEnable(GL_COLOR_MATERIAL);
- glEnable(GL_AUTO_NORMAL);
- glEnable(GL_NORMALIZE);
- glEnable(GL_LIGHT0);
- glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lightAmb);
- glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmb);
- glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDif);
- glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
- glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpec);
- glMaterialfv(GL_FRONT, GL_SPECULAR, lightSpec);
- glMateriali(GL_FRONT, GL_SHININESS, 100);
- glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
- glGenTextures(1, tex);
- glBindTexture(GL_TEXTURE_2D, tex[0]);
- LoadTGATexture("statek2.tga");
- ship = load3DSObject("obiekt.3DS");
- if(ship != NULL) {
- printf("Success!!\n");
- }
- }
- void display() {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glClearColor(0.5, 0.5, 0.5, 1.0);
- glLoadIdentity ();
- gluLookAt(cameraPos[0], cameraPos[1], cameraPos[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
- glPointSize(3);
- glScalef(0.05, 0.05, 0.05);
- glRotatef(rotation, 1, 1, 1);
- glBegin(GL_TRIANGLES);
- for(int i = 0; i < ship->indices * 3; i++){
- glTexCoord2fv(&ship->texCoordsArray[ship->indicesArray[i] * 2]);
- glNormal3fv(&ship->normalsArray[ship->indicesArray[i] * 3]);
- glVertex3fv(&ship->verticesArray[ship->indicesArray[i] * 3]);
- }
- glEnd();
- glFlush();
- glutPostRedisplay();
- glutSwapBuffers();
- }
- void reshape(int w, int h) {
- glViewport(0, 0, (GLsizei) w, (GLsizei) h);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(45.0, (GLfloat)w / (GLfloat)h, 1.5, 50.0);
- glMatrixMode(GL_MODELVIEW);
- }
- void keyboard(unsigned char key, int x, int y){
- switch(key){
- case 27 :
- case 'q':
- free(ship);
- exit(0);
- break;
- }
- }
- void timerfunc(int p){
- rotation += 1;
- glutPostRedisplay();
- glutTimerFunc(1000/fps, &timerfunc, 0);
- }
- void menu(int value) {
- switch(value) {
- case 0:
- exit(0);
- break;
- }
- }
- int main(int argc, char *argv[]) {
- srand(time(NULL));
- glutInit(&argc, argv);
- glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
- glutInitWindowSize(screenWidth, screenHeight);
- glutCreateWindow(argv[0]);
- glutDisplayFunc(display);
- glutReshapeFunc(reshape);
- glutKeyboardFunc(keyboard);
- glutTimerFunc(1000/fps, &timerfunc, 0);
- glutCreateMenu(menu);
- glutAddMenuEntry("Wyjscie", 0);
- glutAttachMenu(GLUT_RIGHT_BUTTON);
- init();
- glutMainLoop();
- return 0;
- }