#define GLUT_DISABLE_ATEXIT_HACK #include #include #include #include #include #include #include #include #include #include #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; }