예제 #1
0
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, ";" );
}
예제 #2
0
파일: pcx.c 프로젝트: Aliandrana/cc65
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;
}