void SceneImporter<real>::ReadScene( std::istream& stream, Scene<real>& oScene ) { // Read the 'Scene' token ReadNextExactToken( stream, "Scene" ); ReadNextExactToken( stream, "{" ); // Read scene components std::string token = ReadNextToken( stream ); while( token != "}" ) { if ( token == "SceneInfo" ) { ReadNextExactToken( stream, "(" ); ReadSceneInfo( stream, oScene ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); } else if ( token == "TurntableCamera" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Camera<real>* camera = ReadTurntableCamera( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( camera, true ); } else if ( token == "DirectionalLight" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Light<real>* light = ReadDirectionalLight( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( light, true ); } else if ( token == "PointLight" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Light<real>* light = ReadPointLight( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( light, true ); } else if ( token == "SpotLight" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Light<real>* light = ReadSpotLight( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( light, true ); } else if ( token == "BlinnPhongMaterial" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Material* material = ReadBlinnPhongMaterial( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( material, true ); } else if ( token == "EnvironmentMaterial" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Material* material = ReadEnvironmentMaterial( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( material, true ); } else if ( token == "CubeMap" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Texture<real>* cubeMap = ReadCubeMap( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( cubeMap, true ); } else if ( token == "Texture2D" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Texture<real>* texture = ReadTexture2D( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( texture, true ); } else if ( token == "Box" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Node<real>* box = ReadBox( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( box, true ); } else if ( token == "Cone" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Node<real>* cone = ReadCone( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( cone, true ); } else if ( token == "Cylinder" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Node<real>* cylinder = ReadCylinder( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( cylinder, true ); } else if ( token == "Plane" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Node<real>* plane = ReadPlane( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( plane, true ); } else if ( token == "Sphere" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Node<real>* sphere = ReadSphere( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( sphere, true ); } else if ( token == "TriMesh" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Node<real>* triMesh = ReadTriMesh( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( triMesh, true ); } else if ( token == "Node" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Node<real>* node = ReadNode( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( node, true ); } else { throw ( std::string( "Unknown token: " ) + token ).c_str(); } token = ReadNextToken( stream ); } // Read scene ending token ReadNextExactToken( stream, ";" ); }
Bitmap* ReadPCXFile (const Collection* A) /* Read a bitmap from a PCX file */ { PCXHeader* P; Bitmap* B; unsigned char* L; Pixel* Px; unsigned MaxIdx = 0; unsigned X, Y; /* Get the file name */ const char* Name = NeedAttrVal (A, "name", "read pcx file"); /* Open the file */ FILE* F = fopen (Name, "rb"); if (F == 0) { Error ("Cannot open PCX file `%s': %s", Name, strerror (errno)); } /* Read the PCX header */ P = ReadPCXHeader (F, Name); /* Dump the header if requested */ if (Verbosity > 0) { DumpPCXHeader (P, Name); } /* Create the bitmap */ B = NewBitmap (P->Width, P->Height); /* Copy the name */ SB_CopyStr (&B->Name, Name); /* Allocate memory for the scan line */ L = xmalloc (P->Width); /* Read the pixel data */ Px = B->Data; if (P->Planes == 1) { /* This is either monochrome or indexed */ if (P->BPP == 1) { /* Monochrome */ for (Y = 0, Px = B->Data; Y < P->Height; ++Y) { unsigned I; unsigned char Mask; /* Read the plane */ ReadPlane (F, P, L); /* Create pixels */ for (X = 0, I = 0, Mask = 0x01; X < P->Width; ++Px) { Px->Index = (L[I] & Mask) != 0; if (Mask == 0x80) { Mask = 0x01; ++I; } else { Mask <<= 1; } } } } else { /* One plane with 8bpp is indexed */ for (Y = 0, Px = B->Data; Y < P->Height; ++Y) { /* Read the plane */ ReadPlane (F, P, L); /* Create pixels */ for (X = 0; X < P->Width; ++X, ++Px) { if (L[X] > MaxIdx) { MaxIdx = L[X]; } Px->Index = L[X]; } } } /* One plane means we have a palette which is either part of the header ** or follows. */ if (P->PalInfo == 0) { /* Create the monochrome palette */ B->Pal = NewMonochromePalette (); } else { unsigned Count; unsigned I; unsigned char Palette[256][3]; unsigned long EndPos; /* Determine the current file position */ unsigned long CurPos = FileGetPos (F); /* Seek to the end of the file */ (void) fseek (F, 0, SEEK_END); /* Get this position */ EndPos = FileGetPos (F); /* There's a palette if the old location is 769 bytes from the end */ if (EndPos - CurPos == sizeof (Palette) + 1) { /* Seek back */ FileSetPos (F, CurPos); /* Check for palette marker */ if (Read8 (F) != 0x0C) { Error ("Invalid palette marker in PCX file `%s'", Name); } } else if (EndPos == CurPos) { /* The palette is in the header */ FileSetPos (F, 16); /* Check the maximum index for safety */ if (MaxIdx > 15) { Error ("PCX file `%s' contains more than 16 indexed colors " "but no extra palette", Name); } } else { Error ("Error in PCX file `%s': %lu bytes at end of pixel data", Name, EndPos - CurPos); } /* Read the palette. We will just read what we need. */ Count = MaxIdx + 1; ReadData (F, Palette, Count * sizeof (Palette[0])); /* Create the palette from the data */ B->Pal = NewPalette (Count); for (I = 0; I < Count; ++I) { B->Pal->Entries[I].R = Palette[I][0]; B->Pal->Entries[I].G = Palette[I][1]; B->Pal->Entries[I].B = Palette[I][2]; B->Pal->Entries[I].A = 0; } } } else { /* 3 or 4 planes are RGB or RGBA (don't know if this exists) */ for (Y = 0, Px = B->Data; Y < P->Height; ++Y) { /* Read the R plane and move the data */ ReadPlane (F, P, L); for (X = 0; X < P->Width; ++X, ++Px) { Px->C.R = L[X]; } /* Read the G plane and move the data */ ReadPlane (F, P, L); for (X = 0; X < P->Width; ++X, ++Px) { Px->C.G = L[X]; } /* Read the B plane and move the data */ ReadPlane (F, P, L); for (X = 0; X < P->Width; ++X, ++Px) { Px->C.B = L[X]; } /* Either read the A plane or clear it */ if (P->Planes == 4) { ReadPlane (F, P, L); for (X = 0; X < P->Width; ++X, ++Px) { Px->C.A = L[X]; } } else { for (X = 0; X < P->Width; ++X, ++Px) { Px->C.A = 0; } } } } /* Close the file */ fclose (F); /* Free memory for the scan line */ xfree (L); /* Free the PCX header */ FreePCXHeader (P); /* Return the bitmap */ return B; }