Пример #1
0
void parseVector(const char *&current, 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);
}
Пример #2
0
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();
}
Пример #3
0
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);
}