コード例 #1
0
ファイル: VolumeFog.cpp プロジェクト: 2asoft/GeometricTools
//----------------------------------------------------------------------------
void VolumeFog::CreateScene ()
{
    // Create a screen-space camera for the background image.
    mScreenCamera = ScreenTarget::CreateCamera();

    // Create a screen polygon for the background image.
    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0);

    mScreenPolygon = ScreenTarget::CreateRectangle(vformat, GetWidth(),
        GetHeight(), 0.0f, 1.0f, 0.0f, 1.0f, 1.0f);

    std::string skyName = Environment::GetPathR("BlueSky.wmtf");
    Texture2D* skyTexture = Texture2D::LoadWMTF(skyName);
    Texture2DEffect* skyEffect = new0 Texture2DEffect();
    mScreenPolygon->SetEffectInstance(skyEffect->CreateInstance(skyTexture));

    // Create the scene graph for the terrain.
    mScene = new0 Node();

    // Begin with a flat height field.
    vformat = VertexFormat::Create(3,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT4, 0,
        VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0);

    mMesh = StandardMesh(vformat).Rectangle(64, 64, 8.0f, 8.0f);
    mScene->AttachChild(mMesh);

    // Set the heights based on a precomputed height field.  Also create a
    // texture image to go with the height field.
    std::string heightFieldName = Environment::GetPathR("HeightField.wmtf");
    Texture2D* heightTexture = Texture2D::LoadWMTF(heightFieldName);
    unsigned char* data = (unsigned char*)heightTexture->GetData(0);
    Float4 white(1.0f, 1.0f, 1.0f, 0.0f);
    VertexBufferAccessor vba(mMesh);
    for (int i = 0; i < vba.GetNumVertices(); ++i)
    {
        unsigned char value = *data;
        float height = 3.0f*value/255.0f + 0.05f*Mathf::SymmetricRandom();

        *data++ = (unsigned char)Mathf::IntervalRandom(32.0f, 64.0f);
        *data++ = 3*(128 - value/2)/4;
        *data++ = 0;
        *data++ = 255;

        vba.Position<Float3>(i)[2] = height;

        // The fog color is white.  The alpha channel is filled in by the
        // function UpdateFog().
        vba.Color<Float4>(0, i) = white;
    }

    UpdateFog();

    std::string effectFile = Environment::GetPathR("VolumeFog.wmfx");
    VolumeFogEffect* effect = new0 VolumeFogEffect(effectFile);
    mMesh->SetEffectInstance(effect->CreateInstance(heightTexture));
}
コード例 #2
0
//----------------------------------------------------------------------------
VisualEffectInstance* Texture2DEffect::CreateUniqueInstance (
    Texture2D* texture, Shader::SamplerFilter filter,
    Shader::SamplerCoordinate coordinate0,
    Shader::SamplerCoordinate coordinate1)
{
    Texture2DEffect* effect = new0 Texture2DEffect();
    PixelShader* pshader = effect->GetPixelShader();
    pshader->SetFilter(0, filter);
    pshader->SetCoordinate(0, 0, coordinate0);
    pshader->SetCoordinate(0, 1, coordinate1);
    return effect->CreateInstance(texture);
}
コード例 #3
0
//----------------------------------------------------------------------------
void ReflectionsAndShadows::CreatePlanes ()
{
    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0);
    int vstride = vformat->GetStride();

    // Create the floor mesh.
    VertexBuffer* vbuffer = new0 VertexBuffer(4, vstride);
    VertexBufferAccessor floor(vformat, vbuffer);

    float xValue = 128.0f;
    float yValue = 256.0f;
    float zValue = 0.0f;
    floor.Position<Float3>(0) = Float3(-xValue, -yValue, zValue);
    floor.Position<Float3>(1) = Float3(+xValue, -yValue, zValue);
    floor.Position<Float3>(2) = Float3(+xValue, +yValue, zValue);
    floor.Position<Float3>(3) = Float3(-xValue, +yValue, zValue);
    floor.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f);
    floor.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f);
    floor.TCoord<Float2>(0, 2) = Float2(1.0f, 1.0f);
    floor.TCoord<Float2>(0, 3) = Float2(0.0f, 1.0f);

    IndexBuffer* ibuffer = new0 IndexBuffer(6, sizeof(int));
    int* indices = (int*)ibuffer->GetData();
    indices[0] = 0;  indices[1] = 1;  indices[2] = 2;
    indices[3] = 0;  indices[4] = 2;  indices[5] = 3;

    mPlane0 = new0 TriMesh(vformat, vbuffer, ibuffer);

    Texture2DEffect* effect = new0 Texture2DEffect(Shader::SF_LINEAR_LINEAR,
        Shader::SC_REPEAT, Shader::SC_REPEAT);
    std::string path = Environment::GetPathR("Sand.wmtf");
    Texture2D* texture = Texture2D::LoadWMTF(path);
    mPlane0->SetEffectInstance(effect->CreateInstance(texture));

    mScene->AttachChild(mPlane0);

    // Create the wall mesh.
    vbuffer = new0 VertexBuffer(4, vstride);
    VertexBufferAccessor wall(vformat, vbuffer);

    xValue = -128.0f;
    yValue = 256.0f;
    zValue = 128.0f;
    wall.Position<Float3>(0) = Float3(xValue, -yValue, 0.0f);
    wall.Position<Float3>(1) = Float3(xValue, +yValue, 0.0f);
    wall.Position<Float3>(2) = Float3(xValue, +yValue, zValue);
    wall.Position<Float3>(3) = Float3(xValue, -yValue, zValue);
    wall.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f);
    wall.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f);
    wall.TCoord<Float2>(0, 2) = Float2(1.0f, 1.0f);
    wall.TCoord<Float2>(0, 3) = Float2(0.0f, 1.0f);

    mPlane1 = new0 TriMesh(vformat, vbuffer, ibuffer);

    path = Environment::GetPathR("Stone.wmtf");
    texture = Texture2D::LoadWMTF(path);
    mPlane1->SetEffectInstance(effect->CreateInstance(texture));

    mScene->AttachChild(mPlane1);
}
コード例 #4
0
//----------------------------------------------------------------------------
void CubeMaps::CreateScene ()
{
    // Create the root of the scene.
    mScene = new0 Node();
    mWireState = new0 WireState();
    mRenderer->SetOverrideWireState(mWireState);

    // Create the walls of the cube room.  Each of the six texture images is
    // RGBA 64-by-64.
    Node* room = new0 Node();
    mScene->AttachChild(room);

    // Index buffer shared by the room walls.
    IndexBuffer* ibuffer = new0 IndexBuffer(6, sizeof(int));
    int* indices = (int*)ibuffer->GetData();
    indices[0] = 0;  indices[1] = 1;  indices[2] = 3;
    indices[3] = 0;  indices[4] = 3;  indices[5] = 2;

    // The vertex format shared by the room walls.
    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0);
    int vstride = vformat->GetStride();
    VertexBufferAccessor vba;

    // The texture effect shared by the room walls.
    Texture2DEffect* effect = new0 Texture2DEffect(Shader::SF_LINEAR);

    VertexBuffer* vbuffer;
    TriMesh* wall;
    std::string textureName;

    // +x wall
    vbuffer = new0 VertexBuffer(4, vstride);
    vba.ApplyTo(vformat, vbuffer);
    vba.Position<Float3>(0) = Float3(+1.0f, -1.0f, -1.0f);
    vba.Position<Float3>(1) = Float3(+1.0f, -1.0f, +1.0f);
    vba.Position<Float3>(2) = Float3(+1.0f, +1.0f, -1.0f);
    vba.Position<Float3>(3) = Float3(+1.0f, +1.0f, +1.0f);
    vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f);
    vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f);
    vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f);
    vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f);
    wall = new0 TriMesh(vformat, vbuffer, ibuffer);
    room->AttachChild(wall);
    textureName = Environment::GetPathR("XpFace.wmtf");
    Texture2D* xpTexture = Texture2D::LoadWMTF(textureName);
    wall->SetEffectInstance(effect->CreateInstance(xpTexture));

    // -x wall
    vbuffer = new0 VertexBuffer(4, vstride);
    vba.ApplyTo(vformat, vbuffer);
    vba.Position<Float3>(0) = Float3(-1.0f, -1.0f, +1.0f);
    vba.Position<Float3>(1) = Float3(-1.0f, -1.0f, -1.0f);
    vba.Position<Float3>(2) = Float3(-1.0f, +1.0f, +1.0f);
    vba.Position<Float3>(3) = Float3(-1.0f, +1.0f, -1.0f);
    vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f);
    vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f);
    vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f);
    vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f);
    wall = new0 TriMesh(vformat, vbuffer, ibuffer);
    room->AttachChild(wall);
    textureName = Environment::GetPathR("XmFace.wmtf");
    Texture2D* xmTexture = Texture2D::LoadWMTF(textureName);
    wall->SetEffectInstance(effect->CreateInstance(xmTexture));

    // +y wall
    vbuffer = new0 VertexBuffer(4, vstride);
    vba.ApplyTo(vformat, vbuffer);
    vba.Position<Float3>(0) = Float3(+1.0f, +1.0f, +1.0f);
    vba.Position<Float3>(1) = Float3(-1.0f, +1.0f, +1.0f);
    vba.Position<Float3>(2) = Float3(+1.0f, +1.0f, -1.0f);
    vba.Position<Float3>(3) = Float3(-1.0f, +1.0f, -1.0f);
    vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f);
    vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f);
    vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f);
    vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f);
    wall = new0 TriMesh(vformat, vbuffer, ibuffer);
    room->AttachChild(wall);
    textureName = Environment::GetPathR("YpFace.wmtf");
    Texture2D* ypTexture = Texture2D::LoadWMTF(textureName);
    wall->SetEffectInstance(effect->CreateInstance(ypTexture));

    // -y wall
    vbuffer = new0 VertexBuffer(4, vstride);
    vba.ApplyTo(vformat, vbuffer);
    vba.Position<Float3>(0) = Float3(+1.0f, -1.0f, -1.0f);
    vba.Position<Float3>(1) = Float3(-1.0f, -1.0f, -1.0f);
    vba.Position<Float3>(2) = Float3(+1.0f, -1.0f, +1.0f);
    vba.Position<Float3>(3) = Float3(-1.0f, -1.0f, +1.0f);
    vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f);
    vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f);
    vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f);
    vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f);
    wall = new0 TriMesh(vformat, vbuffer, ibuffer);
    room->AttachChild(wall);
    textureName = Environment::GetPathR("YmFace.wmtf");
    Texture2D* ymTexture = Texture2D::LoadWMTF(textureName);
    wall->SetEffectInstance(effect->CreateInstance(ymTexture));

    // +z wall
    vbuffer = new0 VertexBuffer(4, vstride);
    vba.ApplyTo(vformat, vbuffer);
    vba.Position<Float3>(0) = Float3(+1.0f, -1.0f, +1.0f);
    vba.Position<Float3>(1) = Float3(-1.0f, -1.0f, +1.0f);
    vba.Position<Float3>(2) = Float3(+1.0f, +1.0f, +1.0f);
    vba.Position<Float3>(3) = Float3(-1.0f, +1.0f, +1.0f);
    vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f);
    vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f);
    vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f);
    vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f);
    wall = new0 TriMesh(vformat, vbuffer, ibuffer);
    room->AttachChild(wall);
    textureName = Environment::GetPathR("ZpFace.wmtf");
    Texture2D* zpTexture = Texture2D::LoadWMTF(textureName);
    wall->SetEffectInstance(effect->CreateInstance(zpTexture));

    // -z wall
    vbuffer = new0 VertexBuffer(4, vstride);
    vba.ApplyTo(vformat, vbuffer);
    vba.Position<Float3>(0) = Float3(-1.0f, -1.0f, -1.0f);
    vba.Position<Float3>(1) = Float3(+1.0f, -1.0f, -1.0f);
    vba.Position<Float3>(2) = Float3(-1.0f, +1.0f, -1.0f);
    vba.Position<Float3>(3) = Float3(+1.0f, +1.0f, -1.0f);
    vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f);
    vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f);
    vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f);
    vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f);
    wall = new0 TriMesh(vformat, vbuffer, ibuffer);
    room->AttachChild(wall);
    textureName = Environment::GetPathR("ZmFace.wmtf");
    Texture2D* zmTexture = Texture2D::LoadWMTF(textureName);
    wall->SetEffectInstance(effect->CreateInstance(zmTexture));

    // A sphere to reflect the environment via a cube map.  The colors will
    // be used to modulate the cube map texture.
    vformat = VertexFormat::Create(3,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_NORMAL, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0);
    vstride = vformat->GetStride();

    mSphere = StandardMesh(vformat).Sphere(64, 64, 0.125f);
    room->AttachChild(mSphere);

    // Generate random vertex colors for the sphere.  The StandardMesh class
    // produces a sphere with duplicated vertices along a longitude line.
    // This allows texture coordinates to be assigned in a manner that treats
    // the sphere as if it were a rectangle mesh.  For vertex colors, we want
    // the duplicated vertices to have the same color, so a hash table is used
    // to look up vertex colors for the duplicates.
    vba.ApplyTo(mSphere);
    std::map<Float3,Float3> dataMap;
    for (int i = 0; i < vba.GetNumVertices(); ++i)
    {
        Float3& position = vba.Position<Float3>(i);
        Float3& color = vba.Color<Float3>(0, i);
        std::map<Float3,Float3>::iterator iter = dataMap.find(position);
        if (iter != dataMap.end())
        {
            color = iter->second;
        }
        else
        {
            color[0] = 0.0f;
            color[1] = Mathf::IntervalRandom(0.5f, 0.75f);
            color[2] = Mathf::IntervalRandom(0.75f, 1.0f);
            dataMap.insert(std::make_pair(position, color));
        }
    }

    // Create the cube map and attach it to the sphere.
    std::string effectFile = Environment::GetPathR("CubeMap.wmfx");
    CubeMapEffect* cubeMapEffect = new0 CubeMapEffect(effectFile);

    ShaderFloat* reflectivity = new0 ShaderFloat(1);
    (*reflectivity)[0] = 0.5f;

    std::string cubeName = Environment::GetPathR("CubeMap.wmtf");
    TextureCube* cubeTexture = TextureCube::LoadWMTF(cubeName);
    cubeTexture->GenerateMipmaps();
    mCubeMapInstance = cubeMapEffect->CreateInstance(cubeTexture,
        reflectivity, false);

    mSphere->SetEffectInstance(mCubeMapInstance);

    // Allow culling to be disabled on the sphere so when you move inside
    // the sphere, you can see the previously hidden facets and verify that
    // the cube image for those facets is correctly oriented.
    mSphereCullState = cubeMapEffect->GetCullState(0, 0);
}
コード例 #5
0
ファイル: ScreenPolygons.cpp プロジェクト: bhlzlx/WildMagic
//----------------------------------------------------------------------------
void ScreenPolygons::CreateScene ()
{
	// The screen camera is designed to map (x,y,z) in [0,1]^3 to (x',y,'z')
	// in [-1,1]^2 x [0,1].
	mScreenCamera = new0 Camera(false);
	mScreenCamera->SetFrustum(0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f);
	mScreenCamera->SetFrame(APoint::ORIGIN, AVector::UNIT_Z, AVector::UNIT_Y,
	                        AVector::UNIT_X);

	// Load the biped just for some model to display.
#ifdef WM5_LITTLE_ENDIAN
	std::string path = Environment::GetPathR("SkinnedBipedPN.wmof");
#else
	std::string path = Environment::GetPathR("SkinnedBipedPN.be.wmof");
#endif
	InStream source;
	source.Load(path);
	mScene = DynamicCast<Node>(source.GetObjectAt(0));
	assertion(mScene != 0, "Error in biped stream.\n");

	// The background is a textured screen polygon (z = 1).
	VertexFormat* vformat = VertexFormat::Create(2,
	                        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
	                        VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0);
	int vstride = vformat->GetStride();

	VertexBuffer* vbuffer = new0 VertexBuffer(4, vstride);
	VertexBufferAccessor vba(vformat, vbuffer);
	vba.Position<Float3>(0) = Float3(0.0f, 0.0f, 1.0f);
	vba.Position<Float3>(1) = Float3(1.0f, 0.0f, 1.0f);
	vba.Position<Float3>(2) = Float3(1.0f, 1.0f, 1.0f);
	vba.Position<Float3>(3) = Float3(0.0f, 1.0f, 1.0f);
	vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f);
	vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f);
	vba.TCoord<Float2>(0, 2) = Float2(1.0f, 1.0f);
	vba.TCoord<Float2>(0, 3) = Float2(0.0f, 1.0f);

	IndexBuffer* ibuffer = new0 IndexBuffer(6, sizeof(int));
	int* indices = (int*)ibuffer->GetData();
	indices[0] = 0;
	indices[1] = 1;
	indices[2] = 2;
	indices[3] = 0;
	indices[4] = 2;
	indices[5] = 3;

	mBackPoly = new0 TriMesh(vformat, vbuffer, ibuffer);
	path = Environment::GetPathR("RedSky.wmtf");
	Texture2DEffect* effect = new0 Texture2DEffect(Shader::SF_LINEAR);
	Texture2D* texture = Texture2D::LoadWMTF(path);
	mBackPoly->SetEffectInstance(effect->CreateInstance(texture));

	// The middle polygon, which may be translated via '+' or '-'.
	vbuffer = new0 VertexBuffer(4, vstride);
	vba.ApplyTo(vformat, vbuffer);
	vba.Position<Float3>(0) = Float3(0.0f, 0.3f, 0.0f);
	vba.Position<Float3>(1) = Float3(1.0f, 0.3f, 0.0f);
	vba.Position<Float3>(2) = Float3(1.0f, 0.7f, 0.0f);
	vba.Position<Float3>(3) = Float3(0.0f, 0.7f, 0.0f);
	vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.3f);
	vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.3f);
	vba.TCoord<Float2>(0, 2) = Float2(1.0f, 0.7f);
	vba.TCoord<Float2>(0, 3) = Float2(0.0f, 0.7f);

	mMidPoly = new0 TriMesh(vformat, vbuffer, ibuffer);
	path = Environment::GetPathR("BallTexture.wmtf");
	texture = Texture2D::LoadWMTF(path);
	mMidPoly->SetEffectInstance(effect->CreateInstance(texture));

	mLinearZ = 1.0f;
	mDepthZ = 1.0f;
	mMidPoly->LocalTransform.SetTranslate(APoint(0.0f, 0.0f, mLinearZ));

	// A portion of the foreground is a textured screen polygon (z = 0).
	vbuffer = new0 VertexBuffer(5, vstride);
	vba.ApplyTo(vformat, vbuffer);
	vba.Position<Float3>(0) = Float3(0.0f,  0.0f,  0.0f);
	vba.Position<Float3>(1) = Float3(0.5f,  0.0f,  0.0f);
	vba.Position<Float3>(2) = Float3(0.75f, 0.5f,  0.0f);
	vba.Position<Float3>(3) = Float3(0.5f,  0.75f, 0.0f);
	vba.Position<Float3>(4) = Float3(0.0f,  0.5f,  0.0f);
	vba.TCoord<Float2>(0, 0) = Float2(0.0f,  0.0f);
	vba.TCoord<Float2>(0, 1) = Float2(0.67f, 0.0f);
	vba.TCoord<Float2>(0, 2) = Float2(1.0f,  0.67f);
	vba.TCoord<Float2>(0, 3) = Float2(0.67f, 1.0f);
	vba.TCoord<Float2>(0, 4) = Float2(0.0f,  0.67f);

	ibuffer = new0 IndexBuffer(9, sizeof(int));
	indices = (int*)ibuffer->GetData();
	indices[0] = 0;
	indices[1] = 1;
	indices[2] = 2;
	indices[3] = 0;
	indices[4] = 2;
	indices[5] = 3;
	indices[6] = 0;
	indices[7] = 3;
	indices[8] = 4;

	mForePoly = new0 TriMesh(vformat, vbuffer, ibuffer);
	path = Environment::GetPathR("Flower.wmtf");
	Texture2DEffect* foreEffect = new0 Texture2DEffect(Shader::SF_LINEAR);
	texture = Texture2D::LoadWMTF(path);
	mForePoly->SetEffectInstance(foreEffect->CreateInstance(texture));

	// Make the foreground semitransparent.
	foreEffect->GetAlphaState(0, 0)->BlendEnabled = true;
}
コード例 #6
0
//----------------------------------------------------------------------------
void CollisionsBoundTree::CreateScene ()
{
    // The root of the scene will have two cylinders as children.
    mScene = new0 Node();
    mWireState = new0 WireState();
    mRenderer->SetOverrideWireState(mWireState);
    mCullState = new0 CullState();
    mCullState->Enabled = false;
    mRenderer->SetOverrideCullState(mCullState);

    // Create a texture image to be used by both cylinders.
    Texture2D* texture = new0 Texture2D(Texture::TF_A8R8G8B8, 2, 2, 1);
    unsigned int* data = (unsigned int*)texture->GetData(0);
    data[0] = Color::MakeR8G8B8(0,     0, 255);  // blue
    data[1] = Color::MakeR8G8B8(0,   255, 255);  // cyan
    data[2] = Color::MakeR8G8B8(255,   0,   0);  // red
    data[3] = Color::MakeR8G8B8(255, 255,   0);  // yellow

    Texture2DEffect* effect = new0 Texture2DEffect(Shader::SF_LINEAR);

    // Create two cylinders, one short and thick, one tall and thin.
    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0);

    StandardMesh sm(vformat);
    VertexBufferAccessor vba;
    int i;

    mCylinder0 = sm.Cylinder(8, 16, 1.0f, 2.0f, false);
    vba.ApplyTo(mCylinder0);
    for (i = 0; i < vba.GetNumVertices(); ++i)
    {
        vba.TCoord<Float2>(0, i) = mBlueUV;
    }
    mCylinder0->SetEffectInstance(effect->CreateInstance(texture));
    mScene->AttachChild(mCylinder0);

    mCylinder1 = sm.Cylinder(16,8,0.25,4.0,false);
    vba.ApplyTo(mCylinder1);
    for (i = 0; i < vba.GetNumVertices(); ++i)
    {
        vba.TCoord<Float2>(0, i) = mRedUV;
    }
    mCylinder1->SetEffectInstance(effect->CreateInstance(texture));
    mScene->AttachChild(mCylinder1);

    mScene->Update();

    // Set up the collision system.  Record0 handles the collision response.
    // Record1 is not given a callback so that 'double processing' of the
    // events does not occur.
    CTree* tree0 = new0 CTree(mCylinder0, 1, false);
    CRecord* record0 = new0 CRecord(tree0, 0, Response, this);
    CTree* tree1 = new0 CTree(mCylinder1, 1, false);
    CRecord* record1 = new0 CRecord(tree1, 0, 0, 0);
    mGroup = new0 CGroup();
    mGroup->Add(record0);
    mGroup->Add(record1);

    ResetColors();
    mGroup->TestIntersection();
}
コード例 #7
0
ファイル: Terrains.cpp プロジェクト: bhlzlx/WildMagic
//----------------------------------------------------------------------------
void Terrains::CreateScene ()
{
	// Create the root of the scene.
	mScene = new0 Node();

	// Load and initialize the sky dome.  It follows the camera.
	std::string skyMeshName = Environment::GetPathR("SkyDomePNT2.wmvf");
	Visual::PrimitiveType type;
	VertexFormat* vformat;
	VertexBuffer* vbuffer;
	IndexBuffer* ibuffer;
	Visual::LoadWMVF(skyMeshName, type, vformat, vbuffer, ibuffer);
	mSkyDome = new0 TriMesh(vformat, vbuffer, ibuffer);
	mScene->AttachChild(mSkyDome);

	APoint skyPosition = mCamera->GetPosition();
	skyPosition[2] = 0.0f;
	mSkyDome->LocalTransform.SetTranslate(skyPosition);
	mSkyDome->LocalTransform.SetUniformScale(mCamera->GetDMax());

	Texture2DEffect* skyEffect = new0 Texture2DEffect(
	                                 Shader::SF_LINEAR_LINEAR, Shader::SC_REPEAT, Shader::SC_REPEAT);
	std::string skyTextureName = Environment::GetPathR("SkyDome.wmtf");
	Texture2D* skyTexture = Texture2D::LoadWMTF(skyTextureName);
	skyTexture->GenerateMipmaps();
	mSkyDome->SetEffectInstance(skyEffect->CreateInstance(skyTexture));

	// Load the height field and create the terrain.
	vformat = VertexFormat::Create(3,
	                               VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
	                               VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0,
	                               VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 1);

	// For lower-resolution terrain, change the paths to Height64/Color64 or
	// Height32/Color32.
	std::string heightName = ThePath + "Data/Height128/height";
	std::string colorName = ThePath + "Data/Color128/color";

	mTerrain = new0 Terrain(heightName, vformat, mCamera);
	mScene->AttachChild(mTerrain);

	// The effect that is shared across all pages.
	std::string effectFile =
	    Environment::GetPathR("BaseMulDetailFogExpSqr.wmfx");
	TerrainEffect* terrainEffect = new0 TerrainEffect(effectFile);

	std::string detailName = Environment::GetPathR("Detail.wmtf");
	Texture2D* detailTexture = Texture2D::LoadWMTF(detailName);
	detailTexture->GenerateMipmaps();

	ShaderFloat* fogColorDensity = new0 ShaderFloat(1);
	(*fogColorDensity)[0] = 0.5686f;
	(*fogColorDensity)[1] = 0.7255f;
	(*fogColorDensity)[2] = 0.8353f;
	(*fogColorDensity)[3] = 0.0015f;

	// Attach an effect to each page.  Preload all resources to video memory.
	// This will avoid frame rate stalls when new terrain pages are
	// encountered as the camera moves.
	const int numRows = mTerrain->GetRowQuantity();
	const int numCols = mTerrain->GetColQuantity();
	for (int r = 0; r < numRows; ++r)
	{
		for (int c = 0; c < numCols; ++c)
		{
			TerrainPage* page = mTerrain->GetPage(r, c);

			char suffix[32];
			sprintf(suffix, ".%d.%d.wmtf", r, c);
			std::string colorTextureName = colorName + std::string(suffix);
			Texture2D* colorTexture = Texture2D::LoadWMTF(colorTextureName);
			colorTexture->GenerateMipmaps();

			VisualEffectInstance* instance = terrainEffect->CreateInstance(
			                                     colorTexture, detailTexture, fogColorDensity);

			page->SetEffectInstance(instance);

			mRenderer->Bind(page->GetVertexBuffer());
			mRenderer->Bind(page->GetVertexFormat());
			mRenderer->Bind(page->GetIndexBuffer());
			mRenderer->Bind(colorTexture);
		}
	}
}
コード例 #8
0
//----------------------------------------------------------------------------
void ClodMeshes::CreateScene ()
{
    mScene = new0 Node();
    mTrnNode = new0 Node();
    mScene->AttachChild(mTrnNode);
    mWireState = new0 WireState();
    mRenderer->SetOverrideWireState(mWireState);

    // Load the face model.
#ifdef WM5_LITTLE_ENDIAN
    std::string path = Environment::GetPathR("FacePN.wmof");
#else
    std::string path = Environment::GetPathR("FacePN.be.wmof");
#endif
    InStream inStream;
    inStream.Load(path);
    TriMeshPtr mesh = StaticCast<TriMesh>(inStream.GetObjectAt(0));
    VertexBufferAccessor vba0(mesh);

    // Remove the normals and add texture coordinates.
    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0);
    int vstride = vformat->GetStride();

    VertexBuffer* vbuffer = new0 VertexBuffer(vba0.GetNumVertices(), vstride);
    VertexBufferAccessor vba1(vformat, vbuffer);

    float xmin = Mathf::MAX_REAL, xmax = -Mathf::MAX_REAL;
    float ymin = Mathf::MAX_REAL, ymax = -Mathf::MAX_REAL;
    int i;
    for (i = 0; i < vba0.GetNumVertices(); ++i)
    {
        Float3 position = vba0.Position<Float3>(i);
        vba1.Position<Float3>(i) = position;

        float x = position[0];
        float y = position[2];
        vba1.TCoord<Float2>(0, i) = Float2(x, y);

        if (x < xmin)
        {
            xmin = x;
        }
        if (x > xmax)
        {
            xmax = x;
        }
        if (y < ymin)
        {
            ymin = y;
        }
        if (y > ymax)
        {
            ymax = y;
        }
    }

    float xmult = 1.0f/(xmax - xmin);
    float ymult = 1.0f/(ymax - ymin);
    for (i = 0; i < vba1.GetNumVertices(); ++i)
    {
        Float2 tcoord = vba1.TCoord<Float2>(0, i);
        vba1.TCoord<Float2>(0,i) = Float2(
            (tcoord[0] - xmin)*xmult,
            (tcoord[1] - ymin)*ymult);
    }

    mesh->SetVertexFormat(vformat);
    mesh->SetVertexBuffer(vbuffer);

    // Create a texture for the face.  Use the generated texture coordinates.
    Texture2DEffect* effect = new0 Texture2DEffect(Shader::SF_LINEAR);
    path = Environment::GetPathR("Magician.wmtf");
    Texture2D* texture = Texture2D::LoadWMTF(path);

#ifdef USE_CLOD_MESH
    // Create the collapse records to be shared by two CLOD meshes.
    int numRecords = 0;
    CollapseRecord* records = 0;
    CreateClodMesh ccm(mesh, numRecords, records);
    CollapseRecordArray* recordArray = new0 CollapseRecordArray(numRecords,
        records);

    mClod[0] = new0 ClodMesh(mesh, recordArray);
    mClod[0]->LocalTransform = mesh->LocalTransform;
    mClod[0]->LocalTransform.SetTranslate(mesh->LocalTransform.GetTranslate()
        - 150.0f*AVector::UNIT_X);
    mClod[0]->SetEffectInstance(effect->CreateInstance(texture));
    mTrnNode->AttachChild(mClod[0]);

    mClod[1] = new0 ClodMesh(mesh, recordArray);
    mClod[1]->LocalTransform = mesh->LocalTransform;
    mClod[1]->LocalTransform.SetTranslate(mesh->LocalTransform.GetTranslate()
        + 150.0f*AVector::UNIT_X - 100.0f*AVector::UNIT_Y);
    mClod[1]->SetEffectInstance(effect->CreateInstance(texture));
    mTrnNode->AttachChild(mClod[1]);

    mActive = mClod[0];
#else
    IndexBuffer* ibuffer = mesh->GetIndexBuffer();
    TriMesh* face = new0 TriMesh(vformat, vbuffer,ibuffer);
    face->LocalTransform = mesh->LocalTransform;
    face->LocalTransform.SetTranslate(mesh->LocalTransform.GetTranslate() -
        150.0f*AVector::UNIT_X);
    face->SetEffectInstance(effect->CreateInstance(texture));
    mTrnNode->AttachChild(face);

    face = new0 TriMesh(vformat, vbuffer, ibuffer);
    face->LocalTransform = mesh->LocalTransform;
    face->LocalTransform.SetTranslate(mesh->LocalTransform.GetTranslate() +
        150.0f*AVector::UNIT_X);
    face->SetEffectInstance(effect->CreateInstance(texture));
    mTrnNode->AttachChild(face);
#endif
}
コード例 #9
0
//----------------------------------------------------------------------------
void BillboardNodes::CreateScene ()
{
    mScene = new0 Node();
    mCullState = new0 CullState();
    mRenderer->SetOverrideCullState(mCullState);
    mWireState = new0 WireState();
    mRenderer->SetOverrideWireState(mWireState);

    // All triangle meshes have this common vertex format.  Use StandardMesh
    // to create these meshes.
    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0);

    StandardMesh stdMesh(vformat);

    // Create the ground.  It covers a square with vertices (1,1,0), (1,-1,0),
    // (-1,1,0), and (-1,-1,0).  Multiply the texture coordinates by a factor
    // to enhance the wrap-around.
    mGround = stdMesh.Rectangle(2, 2, 16.0f, 16.0f);
    VertexBufferAccessor vba(mGround);
    int i;
    for (i = 0; i < vba.GetNumVertices(); ++i)
    {
        Float2& tcoord = vba.TCoord<Float2>(0, i);
        tcoord[0] *= 128.0f;
        tcoord[1] *= 128.0f;
    }

    // Create a texture effect for the ground.
    std::string path = Environment::GetPathR("Horizontal.wmtf");
    Texture2D* texture = Texture2D::LoadWMTF(path);
    VisualEffectInstance* instance = Texture2DEffect::CreateUniqueInstance(
        texture, Shader::SF_LINEAR_LINEAR, Shader::SC_REPEAT,
        Shader::SC_REPEAT);
    mGround->SetEffectInstance(instance);
    mScene->AttachChild(mGround);

    // Create a rectangle mesh.  The mesh is in the xy-plane.  Do not apply
    // local transformations to the mesh.  Use the billboard node transforms
    // to control the mesh location and orientation.
    mRectangle = stdMesh.Rectangle(2, 2, 0.125f, 0.25f);

    // Create a texture effect for the rectangle and for the torus.
    Texture2DEffect* geomEffect = new0 Texture2DEffect(Shader::SF_LINEAR);
    path = Environment::GetPathR("RedSky.wmtf");
    texture = Texture2D::LoadWMTF(path);
    mRectangle->SetEffectInstance(geomEffect->CreateInstance(texture));

    // Create a billboard node that causes a rectangle to always be facing
    // the camera.  This is the type of billboard for an avatar.
    mBillboard0 = new0 BillboardNode(mCamera);
    mBillboard0->AttachChild(mRectangle);
    mScene->AttachChild(mBillboard0);

    // The billboard rotation is about its model-space up-vector (0,1,0).  In
    // this application, world-space up is (0,0,1).  Locally rotate the
    // billboard so it's up-vector matches the world's.
    mBillboard0->LocalTransform.SetTranslate(APoint(-0.25f, 0.0f, 0.25f));
    mBillboard0->LocalTransform.SetRotate(HMatrix(AVector::UNIT_X,
        Mathf::HALF_PI));

    // Create a torus mesh.  Do not apply local transformations to the mesh.
    // Use the billboard node transforms to control the mesh location and
    // orientation.
    mTorus = StandardMesh(vformat, false).Torus(16, 16, 1.0f, 0.25f);
    mTorus->LocalTransform.SetUniformScale(0.1f);

    // Create a texture effect for the torus.  It uses the RedSky image that
    // the rectangle uses.
    mTorus->SetEffectInstance(geomEffect->CreateInstance(texture));

    // Create a billboard node that causes an object to always be oriented
    // the same way relative to the camera.
    mBillboard1 = new0 BillboardNode(mCamera);
    mBillboard1->AttachChild(mTorus);
    mScene->AttachChild(mBillboard1);

    // The billboard rotation is about its model-space up-vector (0,1,0).  In
    // this application, world-space up is (0,0,1).  Locally rotate the
    // billboard so it's up-vector matches the world's.
    mBillboard1->LocalTransform.SetTranslate(APoint(0.25f, 0.0f, 0.25f));
    mBillboard1->LocalTransform.SetRotate(HMatrix(AVector::UNIT_X,
        Mathf::HALF_PI));

#ifdef DEMONSTRATE_VIEWPORT_BOUNDING_RECTANGLE
    // The screen camera is designed to map (x,y,z) in [0,1]^3 to (x',y,'z')
    // in [-1,1]^2 x [0,1].
    mSSCamera = new0 Camera(false);
    mSSCamera->SetFrustum(0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f);
    mSSCamera->SetFrame(APoint::ORIGIN, AVector::UNIT_Z, AVector::UNIT_Y,
        AVector::UNIT_X);

    // Create a semitransparent screen rectangle.
    VertexFormat* ssVFormat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT4, 0);
    int ssVStride = ssVFormat->GetStride();

    VertexBuffer* ssVBuffer = new0 VertexBuffer(4, ssVStride);
    VertexBufferAccessor ssVba(ssVFormat, ssVBuffer);
    Float4 ssColor(0.0f, 0.0f, 1.0f, 0.25f);
    ssVba.Position<Float3>(0) = Float3(0.0f, 0.0f, 0.0f);
    ssVba.Position<Float3>(1) = Float3(1.0f, 0.0f, 0.0f);
    ssVba.Position<Float3>(2) = Float3(1.0f, 1.0f, 0.0f);
    ssVba.Position<Float3>(3) = Float3(0.0f, 1.0f, 0.0f);
    ssVba.Color<Float4>(0, 0) = ssColor;
    ssVba.Color<Float4>(0, 1) = ssColor;
    ssVba.Color<Float4>(0, 2) = ssColor;
    ssVba.Color<Float4>(0, 3) = ssColor;

    IndexBuffer* ssIBuffer = new0 IndexBuffer(6, sizeof(int));
    int* indices = (int*)ssIBuffer->GetData();
    indices[0] = 0;  indices[1] = 1;  indices[2] = 2;
    indices[3] = 0;  indices[4] = 2;  indices[5] = 3;

    mSSRectangle = new0 TriMesh(ssVFormat, ssVBuffer, ssIBuffer);
    mSSRectangle->Update();

    // Create a vertex color effect for the screen rectangle.
    VertexColor4Effect* ssEffect = new0 VertexColor4Effect();
    mSSRectangle->SetEffectInstance(ssEffect->CreateInstance());

    // Alpha blending must be enabled to obtain the semitransparency.
    ssEffect->GetAlphaState(0, 0)->BlendEnabled = true;
#endif
}
コード例 #10
0
//----------------------------------------------------------------------------
void ParticleSystems::CreateScene ()
{
    mScene = new0 Node();
    mWireState = new0 WireState();
    mRenderer->SetOverrideWireState(mWireState);

    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0);
    int vstride = vformat->GetStride();

    const int numParticles = 32;
    VertexBuffer* vbuffer = new0 VertexBuffer(4*numParticles, vstride);
    Float4* positionSizes = new1<Float4>(numParticles);
    for (int i = 0; i < numParticles; ++i)
    {
        positionSizes[i][0] = Mathf::SymmetricRandom();
        positionSizes[i][1] = Mathf::SymmetricRandom();
        positionSizes[i][2] = Mathf::SymmetricRandom();
        positionSizes[i][3] = 0.25f*Mathf::UnitRandom();
    }

    Particles* particles = new0 Particles(vformat, vbuffer, sizeof(int),
        positionSizes, 1.0f);

    particles->AttachController(new0 BloodCellController());
    mScene->AttachChild(particles);

    // Create an image with transparency.
    const int xsize = 32, ysize = 32;
    Texture2D* texture = new0 Texture2D(Texture::TF_A8R8G8B8, xsize,
        ysize, 1);
    unsigned char* data = (unsigned char*)texture->GetData(0);

    float factor = 1.0f/(xsize*xsize + ysize*ysize);
    for (int y = 0, i = 0; y < ysize; ++y)
    {
        for (int x = 0; x < xsize; ++x)
        {
            // The image is red.
            data[i++] = 0;
            data[i++] = 0;
            data[i++] = 255;

            // Semitransparent within a disk, dropping off to zero outside the
            // disk.
            int dx = 2*x - xsize;
            int dy = 2*y - ysize;
            float value = factor*(dx*dx + dy*dy);
            if (value < 0.125f)
            {
                value = Mathf::Cos(4.0f*Mathf::PI*value);
            }
            else
            {
                value = 0.0f;
            }
            data[i++] = (unsigned char)(255.0f*value);
        }
    }

    Texture2DEffect* effect = new0 Texture2DEffect(Shader::SF_LINEAR);
    effect->GetAlphaState(0, 0)->BlendEnabled = true;
    effect->GetDepthState(0, 0)->Enabled = false;
    particles->SetEffectInstance(effect->CreateInstance(texture));
}
コード例 #11
0
//----------------------------------------------------------------------------
void SwitchNodes::CreateScene ()
{
    mScene = new0 Node();
    mWireState = new0 WireState();
    mRenderer->SetOverrideWireState(mWireState);

    mSwitch = new0 SwitchNode();
    mScene->AttachChild(mSwitch);

    // Texture effect to be shared by all objects.
    Texture2DEffect* effect = new0 Texture2DEffect(Shader::SF_LINEAR);
    std::string path = Environment::GetPathR("Flower.wmtf");
    Texture2D* texture = Texture2D::LoadWMTF(path);

    // Create the children of the switch node.
    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0);

    StandardMesh sm(vformat);

    // Create a rectangle mesh (child 0).
    TriMesh* mesh = sm.Rectangle(4, 4, 1.0f, 1.0f);
    mesh->SetEffectInstance(effect->CreateInstance(texture));
    mSwitch->AttachChild(mesh);

    // Create a disk mesh (child 1).
    mesh = sm.Disk(8,16,1.0f);
    mesh->SetEffectInstance(effect->CreateInstance(texture));
    mSwitch->AttachChild(mesh);

    // Create a box mesh (child 2).
    mesh = sm.Box(1.0f,0.5f,0.25f);
    mesh->SetEffectInstance(effect->CreateInstance(texture));
    mSwitch->AttachChild(mesh);

    // Create a closed cylinder mesh (child 3).
    mesh = sm.Cylinder(8,16,1.0f,2.0f,false);
    mesh->SetEffectInstance(effect->CreateInstance(texture));
    mSwitch->AttachChild(mesh);

    // Create a sphere mesh (child 4).
    mesh = sm.Sphere(32,16,1.0f);
    mesh->SetEffectInstance(effect->CreateInstance(texture));
    mSwitch->AttachChild(mesh);

    // Create a torus mesh (child 5).
    mesh = sm.Torus(16,16,1.0f,0.25f);
    mesh->SetEffectInstance(effect->CreateInstance(texture));
    mSwitch->AttachChild(mesh);

    // Create a tetrahedron (child 6).
    mesh = sm.Tetrahedron();
    mesh->SetEffectInstance(effect->CreateInstance(texture));
    mSwitch->AttachChild(mesh);

    // Create a hexahedron (child 7).
    mesh = sm.Hexahedron();
    mesh->SetEffectInstance(effect->CreateInstance(texture));
    mSwitch->AttachChild(mesh);

    // Create an octahedron (child 8).
    mesh = sm.Octahedron();
    mesh->SetEffectInstance(effect->CreateInstance(texture));
    mSwitch->AttachChild(mesh);

    // Create a dodecahedron (child 9).
    mesh = sm.Dodecahedron();
    mesh->SetEffectInstance(effect->CreateInstance(texture));
    mSwitch->AttachChild(mesh);

    // Create an icosahedron (child 10).
    mesh = sm.Icosahedron();
    mesh->SetEffectInstance(effect->CreateInstance(texture));
    mSwitch->AttachChild(mesh);

    // Set the active child (otherwise it is invalid).
    mSwitch->SetActiveChild(0);
}
コード例 #12
0
ファイル: BspNodes.cpp プロジェクト: bhlzlx/WildMagic
//----------------------------------------------------------------------------
void BspNodes::CreateScene ()
{
	// Create the scene graph.
	//
	// 1. The rectangles represent the BSP planes of the BSP tree.  They
	//    share a VertexColor3Effect.  You can see a plane from either side
	//    (backface culling disabled).  The planes do not interfere with view
	//    of the solid objects (wirestate enabled).
	//
	// 2. The sphere, tetrahedron, and cube share a TextureEffect.  These
	//    objects are convex.  The backfacing triangles are discarded
	//    (backface culling enabled).  The front facing triangles are drawn
	//    correctly by convexity, so depthbuffer reads are disabled and
	//    depthbuffer writes are enabled.  The BSP-based sorting of objects
	//    guarantees that front faces of convex objects in the foreground
	//    are drawn after the front faces of convex objects in the background,
	//    which allows us to set the depthbuffer state as we have.  That is,
	//    BSPNode sorts from back to front.
	//
	// 3. The torus has backface culling enabled and depth buffering enabled.
	//    This is necessary, because the torus is not convex.
	//
	// 4. Generally, if all objects are opaque, then you want to draw from
	//    front to back with depth buffering fully enabled.  You need to
	//    reverse-order the elements of the visible set before drawing.  If
	//    any of the objects are semitransparent, then drawing back to front
	//    is the correct order to handle transparency.  However, you do not
	//    get the benefit of early z-rejection for opaque objects.  A better
	//    BSP sorter needs to be built to produce a visible set with opaque
	//    objects listed first (front-to-back order) and semitransparent
	//    objects listed last (back-to-front order).
	//
	// scene
	//     ground
	//     bsp0
	//         bsp1
	//             bsp3
	//                 torus
	//                 rectangle3
	//                 sphere
	//             rectangle1
	//             tetrahedron
	//         rectangle0
	//         bsp2
	//             cube
	//             rectangle2
	//             octahedron

	mScene = new0 Node();

	// Create the ground.  It covers a square with vertices (1,1,0), (1,-1,0),
	// (-1,1,0), and (-1,-1,0).  Multiply the texture coordinates by a factor
	// to enhance the wrap-around.
	VertexFormat* vformat = VertexFormat::Create(2,
	                        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
	                        VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0);

	StandardMesh sm(vformat);
	VertexBufferAccessor vba;

	TriMesh* ground = sm.Rectangle(2, 2, 16.0f, 16.0f);
	vba.ApplyTo(ground);
	for (int i = 0; i < vba.GetNumVertices(); ++i)
	{
		Float2& tcoord = vba.TCoord<Float2>(0, i);
		tcoord[0] *= 128.0f;
		tcoord[1] *= 128.0f;
	}

	std::string path = Environment::GetPathR("Horizontal.wmtf");
	Texture2D* texture = Texture2D::LoadWMTF(path);
	ground->SetEffectInstance(Texture2DEffect::CreateUniqueInstance(texture,
	                          Shader::SF_LINEAR_LINEAR, Shader::SC_REPEAT, Shader::SC_REPEAT));
	mScene->AttachChild(ground);

	// Partition the region above the ground into 5 convex pieces.  Each plane
	// is perpendicular to the ground (not required generally).
	VertexColor3Effect* vceffect = new0 VertexColor3Effect();
	vceffect->GetCullState(0, 0)->Enabled = false;
	vceffect->GetWireState(0, 0)->Enabled = true;

	Vector2f v0(-1.0f, 1.0f);
	Vector2f v1(1.0f, -1.0f);
	Vector2f v2(-0.25f, 0.25f);
	Vector2f v3(-1.0f, -1.0f);
	Vector2f v4(0.0f, 0.0f);
	Vector2f v5(1.0f, 0.5f);
	Vector2f v6(-0.75f, -7.0f/12.0f);
	Vector2f v7(-0.75f, 0.75f);
	Vector2f v8(1.0f, 1.0f);

	BspNode* bsp0 = CreateNode(v0, v1, vceffect, Float3(1.0f, 0.0f, 0.0f));
	BspNode* bsp1 = CreateNode(v2, v3, vceffect, Float3(0.0f, 0.5f, 0.0f));
	BspNode* bsp2 = CreateNode(v4, v5, vceffect, Float3(0.0f, 0.0f, 1.0f));
	BspNode* bsp3 = CreateNode(v6, v7, vceffect, Float3(0.0f, 0.0f, 0.0f));

	bsp0->AttachPositiveChild(bsp1);
	bsp0->AttachNegativeChild(bsp2);
	bsp1->AttachPositiveChild(bsp3);

	// Attach an object in each convex region.
	float height = 0.1f;
	Vector2f center;
	TriMesh* mesh;

	// The texture effect for the convex objects.
	Texture2DEffect* cvxeffect =
	    new0 Texture2DEffect(Shader::SF_LINEAR_LINEAR);
	cvxeffect->GetDepthState(0, 0)->Enabled = false;
	cvxeffect->GetDepthState(0, 0)->Writable = true;

	// The texture effect for the torus.
	Texture2DEffect* toreffect =
	    new0 Texture2DEffect(Shader::SF_LINEAR_LINEAR);

	// The texture image shared by the objects.
	path = Environment::GetPathR("Flower.wmtf");
	texture = Texture2D::LoadWMTF(path);

	// Region 0: Create a torus mesh.
	mesh = sm.Torus(16, 16, 1.0f, 0.25f);
	mesh->SetEffectInstance(toreffect->CreateInstance(texture));
	mesh->LocalTransform.SetUniformScale(0.1f);
	center = (v2 + v6 + v7)/3.0f;
	mesh->LocalTransform.SetTranslate(APoint(center[0], center[1], height));
	bsp3->AttachPositiveChild(mesh);

	// Region 1: Create a sphere mesh.
	mesh = sm.Sphere(32, 16, 1.0f);
	mesh->SetEffectInstance(cvxeffect->CreateInstance(texture));
	mesh->LocalTransform.SetUniformScale(0.1f);
	center = (v0 + v3 + v6 + v7)/4.0f;
	mesh->LocalTransform.SetTranslate(APoint(center[0], center[1], height));
	bsp3->AttachNegativeChild(mesh);

	// Region 2: Create a tetrahedron.
	mesh = sm.Tetrahedron();
	mesh->SetEffectInstance(cvxeffect->CreateInstance(texture));
	mesh->LocalTransform.SetUniformScale(0.1f);
	center = (v1 + v2 + v3)/3.0f;
	mesh->LocalTransform.SetTranslate(APoint(center[0], center[1], height));
	bsp1->AttachNegativeChild(mesh);

	// Region 3: Create a hexahedron (cube).
	mesh = sm.Hexahedron();
	mesh->SetEffectInstance(cvxeffect->CreateInstance(texture));
	mesh->LocalTransform.SetUniformScale(0.1f);
	center = (v1 + v4 + v5)/3.0f;
	mesh->LocalTransform.SetTranslate(APoint(center[0], center[1], height));
	bsp2->AttachPositiveChild(mesh);

	// Region 4: Create an octahedron.
	mesh = sm.Octahedron();
	mesh->SetEffectInstance(cvxeffect->CreateInstance(texture));
	mesh->LocalTransform.SetUniformScale(0.1f);
	center = (v0 + v4 + v5 + v8)/4.0f;
	mesh->LocalTransform.SetTranslate(APoint(center[0], center[1], height));
	bsp2->AttachNegativeChild(mesh);

	mScene->AttachChild(bsp0);
}