void parseVector(const char *¤t, const char *end, std::vector<float> &values, unsigned number) throw() { for (unsigned i = 0; i < number; i++) { while (current != end && *current == ' ') { current += 1; } values.push_back(parseFloat(current, end)); } skipToEndOfLine(current, end); }
GLLObjFile::GLLObjFile(CFURLRef location) { std::string filename = GLLStringFromFileURL(location); int fdes = ::open(filename.c_str(), O_RDONLY); if (fdes < 0) { throw std::runtime_error("Could not open file"); } struct stat statistics; if (fstat(fdes, &statistics) < 0) { close(fdes); throw std::runtime_error("Could not get file size"); } const char *buffer = (const char *) mmap(nullptr, statistics.st_size, PROT_READ, MAP_PRIVATE, fdes, 0); close(fdes); const char *current = buffer; const char *end = &buffer[statistics.st_size]; materialLibraryURLs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); std::string activeMaterial(""); unsigned activeMaterialStart = 0; bool hasFirstMaterial = false; while(current != end) { while (current != end && (*current == ' ' || *current == '\n' || *current == '\r')) { current++; } if (current == end) break; switch (*current) { case 'f': parseFace(current, end); break; case 'v': current += 1; switch (*current) { case 'n': // Normals current += 1; parseVector(current, end, normals, 3); break; case 't': // Tex coords current += 1; parseVector(current, end, texCoords, 2); break; case 'c': // Colors current += 1; parseVector(current, end, colors, 4); break; case ' ': // Vertex parseVector(current, end, vertices, 3); break; default: skipToEndOfLine(current, end); break; } break; case 'm': if (followsString(current, end, "mtllib")) { std::string mtllib = stringToEndOfLine(current, end); try { CFURLRef mtllibLocation = GLLCreateURLFromString(mtllib, location); CFArrayAppendValue(materialLibraryURLs, mtllibLocation); CFRelease(mtllibLocation); } catch (std::exception &e) { std::cerr << "Ignoring mtllib: " << e.what() << std::endl; } } else { skipToEndOfLine(current, end); } break; case 'u': if (followsString(current, end, "usemtl")) { if (hasFirstMaterial) { // End previous material run materialRanges.push_back(MaterialRange(activeMaterialStart, (unsigned) originalIndices.size(), activeMaterial)); } else hasFirstMaterial = true; current += 1; activeMaterial = stringToEndOfLine(current, end); activeMaterialStart = (unsigned) originalIndices.size(); } else { skipToEndOfLine(current, end); } break; case '#': // Comment default: skipToEndOfLine(current, end); break; } } munmap((void *) buffer, statistics.st_size); // Wrap up final material group materialRanges.push_back(MaterialRange(activeMaterialStart, (unsigned) originalIndices.size(), activeMaterial)); fillIndices(); }
void makeTextureMaps() { FILE *fd; char string[100]; char c; int max; float s; unsigned int red, green, blue; GLubyte br, bg, bb; GLfloat *buffer; /*******CLOUD TEXTURE***********/ /* first read the file into a buffer */ fd = fopen("clouds.ppm", "r"); fscanf( fd, "%s", string); if (string[0] != 'P' || string[1] != '6'){ printf( "sorry; not a ppm file\n" ); exit(0); } skipToEndOfLine(fd); fscanf( fd, "%c", &c); /* reads first char of next line */ while (c == '#') { skipToEndOfLine(fd); fscanf(fd, "%c", &c); /* reads first char of next line */ } ungetc(c, fd); fscanf( fd, "%u %u %u", &m, &n, &max); skipToEndOfLine(fd); buffer = (GLfloat *)malloc(sizeof(GLfloat)*n*m*3); for (int i = 0; i < n; i++ ) for (int j = 0; j < m; j++){ fread(&br, 1, 1, fd); fread(&bg, 1, 1, fd); fread(&bb, 1, 1, fd); red = (int)br; green = (int)bg; blue =(int)bb; buffer[3*i*m + 3*j] = red/255.0; buffer[3*i*m + 3*j+1] = green/255.0; buffer[3*i*m + 3*j+2] = blue/255.0; } /* now make the actual texture map, which has dimensions that */ /* are powers of 2 */ textureMapCloud = (GLfloat *)malloc(sizeof(GLfloat)*1024*2048*3); gluScaleImage(GL_RGB, m, n, GL_FLOAT, buffer, 1024, 2048, GL_FLOAT, textureMapCloud); free(buffer); /*******AIRPLANE TEXTURE***********/ fd = fopen("polka_dots.ppm", "r"); fscanf( fd, "%s", string); if (string[0] != 'P' || string[1] != '6'){ printf( "sorry; not a ppm file\n" ); exit(0); } skipToEndOfLine(fd); fscanf( fd, "%c", &c); /* reads first char of next line */ while (c == '#') { skipToEndOfLine(fd); fscanf(fd, "%c", &c); /* reads first char of next line */ } ungetc(c, fd); fscanf( fd, "%u %u %u", &m, &n, &max); skipToEndOfLine(fd); buffer = (GLfloat *)malloc(sizeof(GLfloat)*n*m*3); for (int i = 0; i < n; i++ ) for (int j = 0; j < m; j++){ fread(&br, 1, 1, fd); fread(&bg, 1, 1, fd); fread(&bb, 1, 1, fd); red = (int)br; green = (int)bg; blue =(int)bb; buffer[3*i*m + 3*j] = red/255.0; buffer[3*i*m + 3*j+1] = green/255.0; buffer[3*i*m + 3*j+2] = blue/255.0; } /* now make the actual texture map, which has dimensions that */ /* are powers of 2 */ textureMapAirplane = (GLfloat *)malloc(sizeof(GLfloat)*256*256*3); gluScaleImage(GL_RGB, m, n, GL_FLOAT, buffer, 256, 256, GL_FLOAT, textureMapAirplane); free(buffer); }