Exemple #1
0
//----------------------------------------------------------------------------
VisualEffectInstance* VolumeFogEffect::CreateInstance (Texture2D* baseTexture)
{
	VisualEffectInstance* instance = new0 VisualEffectInstance(this, 0);
	instance->SetVertexConstant(0, 0, new0 PVWMatrixConstant());
	instance->SetPixelTexture(0, 0, baseTexture);
	return instance;
}
//----------------------------------------------------------------------------
VisualEffectInstance* Texture2ColorBlendEffect::CreateInstance (
    Texture2D* texture0, Texture2D* texture1) const
{
    VisualEffectInstance* instance = new0 VisualEffectInstance(this, 0);
    instance->SetVertexConstant(0, 0, new0 PVWMatrixConstant());
    instance->SetPixelTexture(0, 0, texture0);
    instance->SetPixelTexture(0, 1, texture1);

    PixelShader* pshader = GetPixelShader();

    Shader::SamplerFilter filter0 = pshader->GetFilter(0);
    if (filter0 != Shader::SF_NEAREST && filter0 != Shader::SF_LINEAR
    &&  !texture0->HasMipmaps())
    {
        texture0->GenerateMipmaps();
    }

    Shader::SamplerFilter filter1 = pshader->GetFilter(1);
    if (filter1 != Shader::SF_NEAREST && filter1 != Shader::SF_LINEAR
    &&  !texture1->HasMipmaps())
    {
        texture1->GenerateMipmaps();
    }

    return instance;
}
//----------------------------------------------------------------------------
VisualEffectInstance* MaterialEffect::CreateInstance (Material* material)
    const
{
    VisualEffectInstance* instance = new0 VisualEffectInstance(this, 0);
    instance->SetVertexConstant(0, "PVWMatrix", new0 PVWMatrixConstant());
    instance->SetVertexConstant(0, "MaterialDiffuse",
        new0 MaterialDiffuseConstant(material));
    return instance;
}
//----------------------------------------------------------------------------
VisualEffectInstance* SimpleBumpMapEffect::CreateInstance (
    Texture2D* baseTexture, Texture2D* normalTexture)
{
    VisualEffectInstance* instance = new0 VisualEffectInstance(this, 0);
    instance->SetVertexConstant(0, 0, new0 PVWMatrixConstant());
    instance->SetPixelTexture(0, 0, baseTexture);
    instance->SetPixelTexture(0, 1, normalTexture);
    return instance;
}
//----------------------------------------------------------------------------
VisualEffectInstance* SphereMapEffect::CreateInstance (
    Texture2D* environmentTexture)
{
    VisualEffectInstance* instance = new0 VisualEffectInstance(this, 0);
    instance->SetVertexConstant(0, 0, new0 PVWMatrixConstant());
    instance->SetVertexConstant(0, 1, new0 VWMatrixConstant());
    instance->SetPixelTexture(0, 0, environmentTexture);
    return instance;
}
//----------------------------------------------------------------------------
void PointInPolyhedron::CreateScene ()
{
    mScene = new0 Node();
    mWireState = new0 WireState();
    mRenderer->SetOverrideWireState(mWireState);

    // Create a semitransparent sphere mesh.
    VertexFormat* vformatMesh = VertexFormat::Create(1,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0);
    TriMesh* mesh = StandardMesh(vformatMesh).Sphere(16, 16, 1.0f);
    Material* material = new0 Material();
    material->Diffuse = Float4(1.0f, 0.0f, 0.0f, 0.25f);
    VisualEffectInstance* instance = MaterialEffect::CreateUniqueInstance(
        material);
    instance->GetEffect()->GetAlphaState(0, 0)->BlendEnabled = true;
    mesh->SetEffectInstance(instance);

    // Create the data structures for the polyhedron that represents the
    // sphere mesh.
    CreateQuery(mesh);

    // Create a set of random points.  Points inside the polyhedron are
    // colored white.  Points outside the polyhedron are colored blue.
    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0);
    int vstride = vformat->GetStride();

    VertexBuffer* vbuffer = new0 VertexBuffer(1024, vstride);
    VertexBufferAccessor vba(vformat, vbuffer);
    Float3 white(1.0f, 1.0f, 1.0f);
    Float3 blue(0.0f, 0.0f, 1.0f);
    for (int i = 0; i < vba.GetNumVertices(); ++i)
    {
        Vector3f random(Mathf::SymmetricRandom(),
            Mathf::SymmetricRandom(), Mathf::SymmetricRandom());

        vba.Position<Vector3f>(i) = random;

        if (mQuery->Contains(random))
        {
            vba.Color<Float3>(0, i) = white;
        }
        else
        {
            vba.Color<Float3>(0, i) = blue;
        }
    }

    DeleteQuery();

    mPoints = new0 Polypoint(vformat, vbuffer);
    mPoints->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance());

    mScene->AttachChild(mPoints);
    mScene->AttachChild(mesh);
}
Exemple #7
0
//----------------------------------------------------------------------------
VisualEffectInstance* MRTEffect::CreateInstance (Texture2D* texture0,
    Texture2D* texture1)
{
    VisualEffectInstance* instance = new0 VisualEffectInstance(this, 0);
    instance->SetVertexConstant(0, 0, new0 PVWMatrixConstant());
    instance->SetPixelTexture(0, 0, texture0);
    instance->SetPixelTexture(0, 1, texture1);
    return instance;
}
Exemple #8
0
//----------------------------------------------------------------------------
VisualEffectInstance* SMBlurEffect::CreateInstance (ShaderFloat* weights,
    ShaderFloat* offsets, Texture2D* baseTexture) const
{
    VisualEffectInstance* instance = new0 VisualEffectInstance(this, 0);
    instance->SetVertexConstant(0, 0, new0 PVWMatrixConstant());
    instance->SetPixelConstant(0, 0, weights);
    instance->SetPixelConstant(0, 1, offsets);
    instance->SetPixelTexture(0, 0, baseTexture);
    return instance;
}
//----------------------------------------------------------------------------
VisualEffectInstance* SkinningEffect::CreateInstance (
    ShaderFloat* skinningMatrix[4])
{
    VisualEffectInstance* instance = new0 VisualEffectInstance(this, 0);
    instance->SetVertexConstant(0, 0, new0 PVWMatrixConstant());
    for (int i = 0; i < 4; ++i)
    {
        instance->SetVertexConstant(0, i + 1, skinningMatrix[i]);
    }
    return instance;
}
//----------------------------------------------------------------------------
void ClipMesh::CreateScene ()
{
    mScene = new0 Node();

    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0);

    // The plane is fixed at z = 0.
    mPlane.SetNormal(AVector::UNIT_Z);
    mPlane.SetConstant(0.0f);
    mMeshPlane = StandardMesh(vformat).Rectangle(32, 32, 16.0f, 16.0f);
    VisualEffectInstance* instance =
        VertexColor3Effect::CreateUniqueInstance();
    instance->GetEffect()->GetWireState(0,0)->Enabled = true;
    mMeshPlane->SetEffectInstance(instance);
    mScene->AttachChild(mMeshPlane);

    VertexBufferAccessor vba(mMeshPlane);
    Float3 green(0.0f, 1.0f, 0.0f);
    int i;
    for (i = 0; i < vba.GetNumVertices(); ++i)
    {
        vba.Color<Float3>(0, i) = green;
    }

    // Get the positions and indices for a torus.
    mTorus = StandardMesh(vformat).Torus(64, 64, 4.0f, 1.0f);
    instance = VertexColor3Effect::CreateUniqueInstance();
    mTorusWireState = instance->GetEffect()->GetWireState(0, 0);
    mTorus->SetEffectInstance(instance);
    mScene->AttachChild(mTorus);

    vba.ApplyTo(mTorus);
    mTorusVerticesMS.resize(vba.GetNumVertices());
    mTorusVerticesWS.resize(vba.GetNumVertices());
    Float3 black(0.0f, 0.0f, 0.0f);
    for (i = 0; i < vba.GetNumVertices(); ++i)
    {
        mTorusVerticesMS[i] = vba.Position<Float3>(i);
        mTorusVerticesWS[i] = mTorusVerticesMS[i];
        vba.Color<Float3>(0, i) = black;
    }

    IndexBuffer* ibuffer = mTorus->GetIndexBuffer();
    int numIndices = ibuffer->GetNumElements();
    int* indices = (int*)ibuffer->GetData();
    mTorusIndices.resize(numIndices);
    memcpy(&mTorusIndices[0], indices, numIndices*sizeof(int));

    Update();
}
Exemple #11
0
//----------------------------------------------------------------------------
void Delaunay3D::ChangeTetraStatus (int index, const Float4& color,
    bool enableWire)
{
    Visual* tetra = DynamicCast<Visual>(mScene->GetChild(1 + index));
    assertion(tetra != 0, "Expecting a Visual object.\n");
    VertexBufferAccessor vba(tetra);
    for (int i = 0; i < 4; ++i)
    {
        vba.Color<Float4>(0, i) = color;
    }
    mRenderer->Update(tetra->GetVertexBuffer());

    VisualEffectInstance* instance = tetra->GetEffectInstance();
    instance->GetEffect()->GetWireState(0, 0)->Enabled = enableWire;
}
//----------------------------------------------------------------------------
void GelatinCube::CreateBox ()
{
    // Create a quadratic spline using the interior particles as control
    // points.
    int numSlices = mModule->GetNumSlices() - 2;
    int numRows = mModule->GetNumRows() - 2;
    int numCols = mModule->GetNumCols() - 2;
    mSpline = new0 BSplineVolumef(numCols, numRows, numSlices, 2, 2, 2);

    for (int s = 0; s < numSlices; ++s)
    {
        for (int r = 0; r < numRows; ++r)
        {
            for (int c = 0; c < numCols; ++c)
            {
                mSpline->SetControlPoint(c, r, s,
                    mModule->Position(s + 1, r + 1, c + 1));
            }
        }
    }

    // Generate the box.
    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0);

    VertexFormat* vformats[6] =
        { vformat, vformat, vformat, vformat, vformat, vformat };

    mBox = new0 BoxSurface(mSpline, 8, 8, 8, vformats);

    // The texture effect for the box faces.
    std::string path = Environment::GetPathR("WaterWithAlpha.wmtf");
    Texture2D* texture = Texture2D::LoadWMTF(path);
    VisualEffectInstance* instance = Texture2DEffect::CreateUniqueInstance(
        texture, Shader::SF_LINEAR, Shader::SC_REPEAT, Shader::SC_REPEAT);
    for (int i = 0; i < 6; ++i)
    {
        TriMesh* mesh = StaticCast<TriMesh>(mBox->GetChild(i));
        mesh->SetEffectInstance(instance);
    }

    // The texture has an alpha channel of 1/2 for all texels.
    instance->GetEffect()->GetAlphaState(0, 0)->BlendEnabled = true;

    mBox->EnableSorting();
    mTrnNode->AttachChild(mBox);
}
//----------------------------------------------------------------------------
VisualEffectInstance* Texture3DEffect::CreateInstance (Texture3D* texture)
const
{
	VisualEffectInstance* instance = new0 VisualEffectInstance(this, 0);
	instance->SetVertexConstant(0, 0, new0 PVWMatrixConstant());
	instance->SetPixelTexture(0, 0, texture);

	Shader::SamplerFilter filter = GetPixelShader()->GetFilter(0);
	if (filter != Shader::SF_NEAREST && filter != Shader::SF_LINEAR
	        &&  !texture->HasMipmaps())
	{
		texture->GenerateMipmaps();
	}

	return instance;
}
//----------------------------------------------------------------------------
void GpuGaussianBlur2::SetBlurInput ()
{
    VisualEffectInstance* instance = mIP->GetMainEffectInstance();
    float dCol = mIP->GetColSpacing();
    float dRow = mIP->GetRowSpacing();

    ShaderFloat* deltaConstant = new0 ShaderFloat(1);
    float* delta = deltaConstant->GetData();
    delta[0] = dCol;
    delta[1] = dRow;
    instance->SetPixelConstant(0, "Delta", deltaConstant);

    ShaderFloat* weightConstant = new0 ShaderFloat(1);
    float* weight = weightConstant->GetData();
    weight[0] = 0.01f;  // = kappa*DeltaT/DeltaX^2
    weight[1] = 0.01f;  // = kappa*DeltaT/DeltaY^2
    weight[2] = 1.0f - 2.0f*weight[0] - 2.0f*weight[1];  // must be positive
    instance->SetPixelConstant(0, "Weight", weightConstant);
}
Exemple #15
0
//----------------------------------------------------------------------------
VisualEffectInstance* SMSceneEffect::CreateInstance (
    ProjectorWorldPositionConstant* lightWorldPosition,
    ProjectorMatrixConstant* lightPVMatrix, ShaderFloat* lightBSMatrix,
    ShaderFloat* screenBSMatrix, ShaderFloat* lightColor,
    Texture2D* baseTexture, Texture2D* blurTexture,
    Texture2D* projectedTexture) const
{
    VisualEffectInstance* instance = new0 VisualEffectInstance(this, 0);
    instance->SetVertexConstant(0, 0, new0 PVWMatrixConstant());
    instance->SetVertexConstant(0, 1, new0 WMatrixConstant());
    instance->SetVertexConstant(0, 2, lightPVMatrix);
    instance->SetVertexConstant(0, 3, lightBSMatrix);
    instance->SetVertexConstant(0, 4, screenBSMatrix);
    instance->SetVertexConstant(0, 5, lightWorldPosition);
    instance->SetVertexConstant(0, 6, new0 CameraWorldPositionConstant());
    instance->SetPixelConstant(0, 0, lightColor);
    instance->SetPixelTexture(0, 0, baseTexture);
    instance->SetPixelTexture(0, 1, blurTexture);
    instance->SetPixelTexture(0, 2, projectedTexture);
    return instance;
}
Exemple #16
0
//----------------------------------------------------------------------------
TriMesh* Delaunay3D::CreateTetra (int index) const
{
    const Vector3f* dvertices = mDelaunay->GetVertices();
    const int* dindices = mDelaunay->GetIndices();

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

    VertexBuffer* vbuffer = new0 VertexBuffer(4, vstride);
    VertexBufferAccessor vba(vformat, vbuffer);
    vba.Position<Vector3f>(0) = dvertices[dindices[4*index    ]];
    vba.Position<Vector3f>(1) = dvertices[dindices[4*index + 1]];
    vba.Position<Vector3f>(2) = dvertices[dindices[4*index + 2]];
    vba.Position<Vector3f>(3) = dvertices[dindices[4*index + 3]];
    Float4 lightGray(0.75f, 0.75f, 0.75f, 1.0f);
    vba.Color<Float4>(0, 0) = lightGray;
    vba.Color<Float4>(0, 1) = lightGray;
    vba.Color<Float4>(0, 2) = lightGray;
    vba.Color<Float4>(0, 3) = lightGray;

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

    TriMesh* tetra = new0 TriMesh(vformat, vbuffer, ibuffer);
    VisualEffectInstance* instance =
        VertexColor4Effect::CreateUniqueInstance();
    instance->GetEffect()->GetAlphaState(0, 0)->BlendEnabled = true;
    instance->GetEffect()->GetWireState(0, 0)->Enabled = true;
    tetra->SetEffectInstance(instance);

    return tetra;
}
//----------------------------------------------------------------------------
VisualEffectInstance* BlendedTerrainEffect::CreateInstance (
    ShaderFloat* flowDirection, ShaderFloat* powerFactor,
    Texture2D* grassTexture, Texture2D* stoneTexture, Texture2D* cloudTexture)
{
    VisualEffectInstance* instance = new0 VisualEffectInstance(this, 0);
    instance->SetVertexConstant(0, 0, new0 PVWMatrixConstant());
    instance->SetVertexConstant(0, 1, flowDirection);
    instance->SetPixelConstant(0, 0, powerFactor);
    instance->SetPixelTexture(0, 0, grassTexture);
    instance->SetPixelTexture(0, 1, stoneTexture);
    instance->SetPixelTexture(0, 2, mBlendTexture);
    instance->SetPixelTexture(0, 3, cloudTexture);
    return instance;
}
//----------------------------------------------------------------------------
VisualEffectInstance* DLitMatTexEffect::CreateInstance (
    Light* directionalLight, Material* material, Texture2D* diffuseTexture)
{
    VisualEffectInstance* instance = new0 VisualEffectInstance(this, 0);
    instance->SetVertexConstant(0, 0,
        new0 PVWMatrixConstant());
    instance->SetPixelConstant(0, 0,
        new0 CameraModelPositionConstant());
    instance->SetPixelConstant(0, 1,
        new0 MaterialAmbientConstant(material));
    instance->SetPixelConstant(0, 2,
        new0 MaterialSpecularConstant(material));
    instance->SetPixelConstant(0, 3,
        new0 LightModelDVectorConstant(directionalLight));
    instance->SetPixelConstant(0, 4,
        new0 LightAmbientConstant(directionalLight));
    instance->SetPixelTexture(0, 0, diffuseTexture);
    return instance;
}
//----------------------------------------------------------------------------
VisualEffectInstance* LightAmbEffect::CreateInstance (Light* light,
        Material* material) const
{
	VisualEffectInstance* instance = new0 VisualEffectInstance(this, 0);
	instance->SetVertexConstant(0, 0, new0 PVWMatrixConstant());
	instance->SetVertexConstant(0, 1,
	                            new0 MaterialEmissiveConstant(material));
	instance->SetVertexConstant(0, 2,
	                            new0 MaterialAmbientConstant(material));
	instance->SetVertexConstant(0, 3,
	                            new0 LightAmbientConstant(light));
	instance->SetVertexConstant(0, 4,
	                            new0 LightAttenuationConstant(light));
	return instance;
}
//----------------------------------------------------------------------------
void BSplineSurfaceFitter::CreateScene ()
{
	mScene = new0 Node();
	mWireState = new0 WireState();
	mRenderer->SetOverrideWireState(mWireState);
	mCullState = new0 CullState();
	mCullState->Enabled = false;
	mRenderer->SetOverrideCullState(mCullState);

	// Begin with a flat 64x64 height field.
	const int numSamples = 64;
	const float extent = 8.0f;
	VertexFormat* vformat = VertexFormat::Create(2,
	                        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
	                        VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0);
	mHeightField = StandardMesh(vformat).Rectangle(numSamples, numSamples,
	               extent, extent);
	mScene->AttachChild(mHeightField);

	// Set the heights based on a precomputed height field.  Also create a
	// texture image to go with the height field.
	std::string path = Environment::GetPathR("HeightField.wmtf");
	Texture2D* texture = Texture2D::LoadWMTF(path);
	VisualEffectInstance* instance = Texture2DEffect::CreateUniqueInstance(
	                                     texture, Shader::SF_LINEAR, Shader::SC_CLAMP_EDGE,
	                                     Shader::SC_CLAMP_EDGE);
	mHeightField->SetEffectInstance(instance);
	unsigned char* data = (unsigned char*)texture->GetData(0);

	VertexBufferAccessor vba(mHeightField);
	Vector3f** samplePoints = new2<Vector3f>(numSamples, numSamples);
	int i;
	for (i = 0; i < vba.GetNumVertices(); ++i)
	{
		unsigned char value = *data;
		float height = 3.0f*((float)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++;

		vba.Position<Vector3f>(i).Z() = height;
		samplePoints[i % numSamples][i / numSamples] =
		    vba.Position<Vector3f>(i);
	}

	// Compute a B-Spline surface with NxN control points, where N < 64.
	// This surface will be sampled to 64x64 and displayed together with the
	// original height field for comparison.
	const int numCtrlPoints = 32;
	const int degree = 3;
	BSplineSurfaceFitf fitter(degree, numCtrlPoints, numSamples, degree,
	                          numCtrlPoints, numSamples, samplePoints);
	delete2(samplePoints);

	vformat = VertexFormat::Create(2,
	                               VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
	                               VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT4, 0);
	mFittedField = StandardMesh(vformat).Rectangle(numSamples, numSamples,
	               extent, extent);
	mScene->AttachChild(mFittedField);

	vba.ApplyTo(mFittedField);
	Float4 translucent(1.0f, 1.0f, 1.0f, 0.5f);
	for (i = 0; i < vba.GetNumVertices(); ++i)
	{
		float u = 0.5f*(vba.Position<Vector3f>(i).X()/extent + 1.0f);
		float v = 0.5f*(vba.Position<Vector3f>(i).Y()/extent + 1.0f);
		vba.Position<Vector3f>(i) = fitter.GetPosition(u, v);
		vba.Color<Float4>(0,i) = translucent;
	}

	instance = VertexColor4Effect::CreateUniqueInstance();
	mFittedField->SetEffectInstance(instance);
	instance->GetEffect()->GetAlphaState(0, 0)->BlendEnabled = true;
}
//----------------------------------------------------------------------------
void IntersectConvexPolyhedra::CreateScene ()
{
    mScene = new0 Node();
    mMotionObject = mScene;

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

    // Attach a dummy intersection mesh.  If the intersection is nonempty,
    // the Culling flag will be modified to CULL_DYNAMIC.  The intersection
    // is drawn as a solid.
    mMeshIntersection = StandardMesh(vformat).Tetrahedron();
    VertexBufferAccessor vba(mMeshIntersection);
    Float3 green(0.0f, 1.0f, 0.0f);
    int i, j;
    for (i = 0; i < vba.GetNumVertices(); ++i)
    {
        vba.Color<Float3>(0, i) = green;
    }
    mMeshIntersection->SetEffectInstance(
        VertexColor3Effect::CreateUniqueInstance());
    mMeshIntersection->Culling = Spatial::CULL_ALWAYS;
    mScene->AttachChild(mMeshIntersection);

    // The first polyhedron is an ellipsoid.
    ConvexPolyhedronf::CreateEggShape(Vector3f::ZERO, 1.0f, 1.0f, 2.0f, 2.0f,
        4.0f, 4.0f, 3, mWorldPoly0);

    // Build the corresponding mesh.
    int numVertices = mWorldPoly0.GetNumVertices();
    int numTriangles = mWorldPoly0.GetNumTriangles();
    int numIndices = 3*numTriangles;
    VertexBuffer* vbuffer = new0 VertexBuffer(numVertices, vstride);
    IndexBuffer* ibuffer = new0 IndexBuffer(numIndices, sizeof(int));
    Float3 red(1.0f, 0.0f, 0.0f);
    vba.ApplyTo(vformat, vbuffer);
    for (i = 0; i < numVertices; ++i)
    {
        vba.Position<Vector3f>(i) = mWorldPoly0.Point(i);
        vba.Color<Float3>(0,i) = red;
    }
    int* indices = (int*)ibuffer->GetData();
    for (i = 0; i < numTriangles; ++i)
    {
        const MTTriangle& triangle = mWorldPoly0.GetTriangle(i);
        for (j = 0; j < 3; ++j)
        {
            indices[3*i + j] = mWorldPoly0.GetVLabel(triangle.GetVertex(j));
        }
    }

    mMeshPoly0 = new0 TriMesh(vformat, vbuffer, ibuffer);
    VisualEffectInstance* instance =
        VertexColor3Effect::CreateUniqueInstance();
    instance->GetEffect()->GetWireState(0, 0)->Enabled = true;
    mMeshPoly0->SetEffectInstance(instance);
    mMeshPoly0->LocalTransform.SetTranslate(APoint(0.0f, 2.0f, 0.0f));
    mScene->AttachChild(mMeshPoly0);

    // The second polyhedron is egg shaped.
    ConvexPolyhedronf::CreateEggShape(Vector3f::ZERO, 2.0f, 2.0f, 4.0f, 4.0f,
        5.0f, 3.0f, 4, mWorldPoly1);

    // Build the corresponding mesh.
    numVertices = mWorldPoly1.GetNumVertices();
    numTriangles = mWorldPoly1.GetNumTriangles();
    numIndices = 3*numTriangles;
    vbuffer = new0 VertexBuffer(numVertices, vstride);
    ibuffer = new0 IndexBuffer(numIndices, sizeof(int));
    Float3 blue(0.0f, 0.0f, 1.0f);
    vba.ApplyTo(vformat, vbuffer);
    for (i = 0; i < numVertices; ++i)
    {
        vba.Position<Vector3f>(i) = mWorldPoly1.Point(i);
        vba.Color<Float3>(0, i) = blue;
    }
    indices = (int*)ibuffer->GetData();
    for (i = 0; i < numTriangles; ++i)
    {
        const MTTriangle& triangle = mWorldPoly1.GetTriangle(i);
        for (j = 0; j < 3; ++j)
        {
            indices[3*i + j] = mWorldPoly1.GetVLabel(triangle.GetVertex(j));
        }
    }

    mMeshPoly1 = new0 TriMesh(vformat, vbuffer, ibuffer);
    instance = VertexColor3Effect::CreateUniqueInstance();
    instance->GetEffect()->GetWireState(0, 0)->Enabled = true;
    mMeshPoly1->SetEffectInstance(instance);
    mMeshPoly1->LocalTransform.SetTranslate(APoint(0.0f, -2.0f, 0.0f));
    mScene->AttachChild(mMeshPoly1);

    ComputeIntersection();
}
//----------------------------------------------------------------------------
VisualEffectInstance* LightSptPerPixEffect::CreateInstance (Light* light,
    Material* material) const
{
    VisualEffectInstance* instance = new0 VisualEffectInstance(this, 0);
    instance->SetVertexConstant(0, 0,
        new0 PVWMatrixConstant());
    instance->SetPixelConstant(0, 0,
        new0 WMatrixConstant());
    instance->SetPixelConstant(0, 1,
        new0 CameraModelPositionConstant());
    instance->SetPixelConstant(0, 2,
        new0 MaterialEmissiveConstant(material));
    instance->SetPixelConstant(0, 3,
        new0 MaterialAmbientConstant(material));
    instance->SetPixelConstant(0, 4,
        new0 MaterialDiffuseConstant(material));
    instance->SetPixelConstant(0, 5,
        new0 MaterialSpecularConstant(material));
    instance->SetPixelConstant(0, 6,
        new0 LightModelPositionConstant(light));
    instance->SetPixelConstant(0, 7,
        new0 LightModelDVectorConstant(light));
    instance->SetPixelConstant(0, 8,
        new0 LightAmbientConstant(light));
    instance->SetPixelConstant(0, 9,
        new0 LightDiffuseConstant(light));
    instance->SetPixelConstant(0, 10,
        new0 LightSpecularConstant(light));
    instance->SetPixelConstant(0, 11,
        new0 LightSpotConstant(light));
    instance->SetPixelConstant(0, 12,
        new0 LightAttenuationConstant(light));
    return instance;
}
//----------------------------------------------------------------------------
VisualEffectInstance* DefaultEffect::CreateInstance () const
{
    VisualEffectInstance* instance = new0 VisualEffectInstance(this, 0);
    instance->SetVertexConstant(0, 0, new0 PVWMatrixConstant());
    return instance;
}
//----------------------------------------------------------------------------
VisualEffectInstance* GeodesicHeightField::CreateEffectInstance ()
{
	// Create the vertex shader.
	VertexShader* vshader = new0 VertexShader("Wm5.DLight2MatTex",
	                        3, 3, 16, 0, false);
	vshader->SetInput(0, "modelPosition", Shader::VT_FLOAT3,
	                  Shader::VS_POSITION);
	vshader->SetInput(1, "modelNormal", Shader::VT_FLOAT3,
	                  Shader::VS_NORMAL);
	vshader->SetInput(2, "modelTCoord", Shader::VT_FLOAT2,
	                  Shader::VS_TEXCOORD0);
	vshader->SetOutput(0, "clipPosition", Shader::VT_FLOAT4,
	                   Shader::VS_POSITION);
	vshader->SetOutput(1, "vertexColor", Shader::VT_FLOAT4,
	                   Shader::VS_COLOR0);
	vshader->SetOutput(2, "vertexTCoord", Shader::VT_FLOAT2,
	                   Shader::VS_TEXCOORD0);
	vshader->SetConstant( 0, "PVWMatrix", 4);
	vshader->SetConstant( 1, "CameraModelPosition", 1);
	vshader->SetConstant( 2, "MaterialEmissive", 1);
	vshader->SetConstant( 3, "MaterialAmbient", 1);
	vshader->SetConstant( 4, "MaterialDiffuse", 1);
	vshader->SetConstant( 5, "MaterialSpecular", 1);
	vshader->SetConstant( 6, "Light0ModelDirection", 1);
	vshader->SetConstant( 7, "Light0Ambient", 1);
	vshader->SetConstant( 8, "Light0Diffuse", 1);
	vshader->SetConstant( 9, "Light0Specular", 1);
	vshader->SetConstant(10, "Light0Attenuation", 1);
	vshader->SetConstant(11, "Light1ModelDirection", 1);
	vshader->SetConstant(12, "Light1Ambient", 1);
	vshader->SetConstant(13, "Light1Diffuse", 1);
	vshader->SetConstant(14, "Light1Specular", 1);
	vshader->SetConstant(15, "Light1Attenuation", 1);
	vshader->SetBaseRegisters(msVRegisters);
	vshader->SetPrograms(msVPrograms);

	// Create the pixel shader.
	PixelShader* pshader = new0 PixelShader("Wm5.DLight2MatTex",
	                                        2, 1, 0, 1, false);
	pshader->SetInput(0, "vertexColor", Shader::VT_FLOAT4,
	                  Shader::VS_COLOR0);
	pshader->SetInput(1, "vertexTCoord", Shader::VT_FLOAT2,
	                  Shader::VS_TEXCOORD0);
	pshader->SetOutput(0, "pixelColor", Shader::VT_FLOAT4,
	                   Shader::VS_COLOR0);
	pshader->SetSampler(0, "BaseSampler", Shader::ST_2D);
	pshader->SetFilter(0, Shader::SF_LINEAR /*_LINEAR */);
	pshader->SetCoordinate(0, 0, Shader::SC_CLAMP_EDGE);
	pshader->SetCoordinate(0, 1, Shader::SC_CLAMP_EDGE);
	pshader->SetTextureUnits(msPTextureUnits);
	pshader->SetPrograms(msPPrograms);

	VisualPass* pass = new0 VisualPass();
	pass->SetVertexShader(vshader);
	pass->SetPixelShader(pshader);
	pass->SetAlphaState(new0 AlphaState());
	pass->SetCullState(new0 CullState());
	pass->SetDepthState(new0 DepthState());
	pass->SetOffsetState(new0 OffsetState());
	pass->SetStencilState(new0 StencilState());
	pass->SetWireState(new0 WireState());

	// Create the effect.
	VisualTechnique* technique = new0 VisualTechnique();
	technique->InsertPass(pass);
	VisualEffect* effect = new0 VisualEffect();
	effect->InsertTechnique(technique);

	// Create the material for the effect.
	Float4 black(0.0f, 0.0f, 0.0f, 1.0f);
	Float4 white(1.0f, 1.0f, 1.0f, 1.0f);
	Material* material = new0 Material();
	material->Emissive = black;
	material->Ambient = Float4(0.24725f, 0.2245f, 0.0645f, 1.0f);
	material->Diffuse = Float4(0.34615f, 0.3143f, 0.0903f, 1.0f);
	material->Specular = Float4(0.797357f, 0.723991f, 0.208006f, 83.2f);

	// Create the lights for the effect.
	Light* light0 = new0 Light(Light::LT_DIRECTIONAL);
	light0->SetDirection(AVector(0.0f, 0.0f, -1.0f));
	light0->Ambient = white;
	light0->Diffuse = white;
	light0->Specular = black;

	Light* light1 = new0 Light(Light::LT_DIRECTIONAL);
	light1->SetDirection(AVector(0.0f, 0.0f, 1.0f));
	light1->Ambient = white;
	light1->Diffuse = white;
	light1->Specular = black;

	// Create a texture for the effect.
	mTexture = new0 Texture2D(Texture::TF_A8R8G8B8, 512, 512, 0);
	unsigned char* data = (unsigned char*)mTexture->GetData(0);
	memset(data, 0xFF, mTexture->GetNumLevelBytes(0));

	// Create an instance of the effect.
	VisualEffectInstance* instance = new0 VisualEffectInstance(effect, 0);
	instance->SetVertexConstant(0, 0,
	                            new0 PVWMatrixConstant());
	instance->SetVertexConstant(0, 1,
	                            new0 CameraModelPositionConstant());
	instance->SetVertexConstant(0, 2,
	                            new0 MaterialEmissiveConstant(material));
	instance->SetVertexConstant(0, 3,
	                            new0 MaterialAmbientConstant(material));
	instance->SetVertexConstant(0, 4,
	                            new0 MaterialDiffuseConstant(material));
	instance->SetVertexConstant(0, 5,
	                            new0 MaterialSpecularConstant(material));
	instance->SetVertexConstant(0, 6,
	                            new0 LightModelDVectorConstant(light0));
	instance->SetVertexConstant(0, 7,
	                            new0 LightAmbientConstant(light0));
	instance->SetVertexConstant(0, 8,
	                            new0 LightDiffuseConstant(light0));
	instance->SetVertexConstant(0, 9,
	                            new0 LightSpecularConstant(light0));
	instance->SetVertexConstant(0, 10,
	                            new0 LightAttenuationConstant(light0));
	instance->SetVertexConstant(0, 11,
	                            new0 LightModelDVectorConstant(light1));
	instance->SetVertexConstant(0, 12,
	                            new0 LightAmbientConstant(light1));
	instance->SetVertexConstant(0, 13,
	                            new0 LightDiffuseConstant(light1));
	instance->SetVertexConstant(0, 14,
	                            new0 LightSpecularConstant(light1));
	instance->SetVertexConstant(0, 15,
	                            new0 LightAttenuationConstant(light1));

	instance->SetPixelTexture(0, 0, mTexture);

	return instance;
}
//----------------------------------------------------------------------------
void GpuGaussianBlur3::SetBlurInput ()
{
    VisualEffectInstance* instance = mIP->GetMainEffectInstance();
    int bound0M1 = mIP->GetBound0() - 1;
    int bound1M1 = mIP->GetBound1() - 1;
    int bound2M1 = mIP->GetBound2() - 1;

    float dCol = mIP->GetColSpacing();
    float dRow = mIP->GetRowSpacing();

    ShaderFloat* deltaConstant = new0 ShaderFloat(1);
    float* delta = deltaConstant->GetData();
    delta[0] = dCol;
    delta[1] = 0.0f;
    delta[2] = 0.0f;
    delta[3] = dRow;
    instance->SetPixelConstant(0, "Delta", deltaConstant);

    ShaderFloat* weightConstant = new0 ShaderFloat(1);
    float* weight = weightConstant->GetData();
    weight[0] = 0.01f;  // = kappa*DeltaT/DeltaX^2
    weight[1] = 0.01f;  // = kappa*DeltaT/DeltaY^2
    weight[2] = 0.01f;  // = kappa*DeltaT/DeltaZ^2
    weight[3] = 1.0f - 2.0f*(weight[0] + weight[1] + weight[2]);  // w[3] > 0
    instance->SetPixelConstant(0, "Weight", weightConstant);

    Texture2D* offsetTexture = new Texture2D(Texture::TF_A32B32G32R32F,
        1024, 1024, 1);
    Float4* offset = (Float4*)offsetTexture->GetData(0);
    memset(offset, 0, 1024*1024*sizeof(Float4));

    // Interior voxels.  The offsets at the boundary are all zero, so the
    // finite differences are incorrect at those locations.  However, the
    // boundary effect will overwrite those voxels, so it is irrelevant
    // about the finite difference approximations at those locations.
    for (int z = 1; z < bound2M1; ++z)
    {
        for (int y = 1; y < bound1M1; ++y)
        {
            for (int x = 1; x < bound0M1; ++x)
            {
                // Get the 2D location of the voxel.
                int u, v;
                mIP->Map3Dto2D(x, y, z, u, v);

                // Get the 2D location of the z+ neighbor.
                int upos, vpos;
                mIP->Map3Dto2D(x, y, z+1, upos, vpos);

                // Get the 2D location of the z- neighbor.
                int uneg, vneg;
                mIP->Map3Dto2D(x, y, z-1, uneg, vneg);

                Float4& color = offset[mIP->Index(u, v)];
                color[0] = (upos - u)*dCol;
                color[1] = (vpos - v)*dRow;
                color[2] = (uneg - u)*dCol;
                color[3] = (vneg - v)*dRow;
            }
        }
    }

    instance->SetPixelTexture(0, "OffsetSampler", offsetTexture);
}
Exemple #26
0
//----------------------------------------------------------------------------
void MaterialTextures::CreateScene ()
{
    mScene = new0 Node();
    mTrnNode = new0 Node();
    mScene->AttachChild(mTrnNode);
    mWireState = new0 WireState();
    mRenderer->SetOverrideWireState(mWireState);

    // Create a square object.
    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(-1.0f, -1.0f, 0.0f);
    vba.Position<Float3>(1) = Float3(-1.0f,  1.0f, 0.0f);
    vba.Position<Float3>(2) = Float3( 1.0f,  1.0f, 0.0f);
    vba.Position<Float3>(3) = Float3( 1.0f, -1.0f, 0.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] = 3;
    indices[3] = 3;
    indices[4] = 1;
    indices[5] = 2;

    // Create a square with a door texture.
    TriMesh* door = new0 TriMesh(vformat, vbuffer, ibuffer);
    std::string path = Environment::GetPathR("Door.wmtf");
    Texture2D* texture = Texture2D::LoadWMTF(path);
    door->SetEffectInstance(Texture2DEffect::CreateUniqueInstance(texture,
                            Shader::SF_LINEAR, Shader::SC_CLAMP_EDGE, Shader::SC_CLAMP_EDGE));
    mTrnNode->AttachChild(door);

    // Material-texture effect shared by two objects.  The material is
    // semitransparent, so alpha blending must be enabled.
    MaterialTextureEffect* effect =
        new0 MaterialTextureEffect(Shader::SF_LINEAR);
    effect->GetAlphaState(0, 0)->BlendEnabled = true;

    // Create a square with a material-texture effect. The texture is combined
    // with the material to produce a semitransparenteffect on the sand.  You
    // should be able to see the door through it.
    TriMesh* sand = new0 TriMesh(vformat, vbuffer, ibuffer);
    sand->LocalTransform.SetTranslate(APoint(0.25f, 0.25f, -0.25f));
    mTrnNode->AttachChild(sand);

    mMaterial = new0 Material();
    mMaterial->Diffuse = Float4(1.0f, 0.0f, 0.0f, 0.5f);
    path = Environment::GetPathR("Sand.wmtf");
    texture = Texture2D::LoadWMTF(path);
    VisualEffectInstance* instance =
        effect->CreateInstance(mMaterial, texture);
    sand->SetEffectInstance(instance);

    // The material alpha is adjustable during run time, so we must enable
    // the corresponding shader constant to automatically update.
    instance->GetVertexConstant(0, "MaterialDiffuse")->EnableUpdater();

    // Create another square with a material-texture effect.
    TriMesh* water = new0 TriMesh(vformat, vbuffer, ibuffer);
    water->LocalTransform.SetTranslate(APoint(0.5f, 0.5f, -0.5f));
    mTrnNode->AttachChild(water);

    Material* material = new0 Material();
    material->Diffuse = Float4(0.0f, 0.0f, 1.0f, 0.5f);
    path = Environment::GetPathR("Water.wmtf");
    texture = Texture2D::LoadWMTF(path);
    water->SetEffectInstance(effect->CreateInstance(material, texture));
}
//----------------------------------------------------------------------------
Node* SimplePendulumFriction::CreatePendulum ()
{
	VertexFormat* vformat = VertexFormat::Create(2,
	                        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
	                        VertexFormat::AU_NORMAL, VertexFormat::AT_FLOAT3, 0);

	StandardMesh sm(vformat);

	// Pendulum rod.
	TriMesh* rod = sm.Cylinder(2, 8, 0.05f, 12.0f, true);
	rod->LocalTransform.SetTranslate(APoint(0.0f, 0.0f, 10.0f));

	// The pendulum bulb.  Start with a sphere (to get the connectivity) and
	// then adjust the vertices to form a pair of joined cones.
	TriMesh* bulb = sm.Sphere(16, 32, 2.0f);
	VertexBufferAccessor vba(bulb);
	int numVertices = vba.GetNumVertices();
	int i;
	for (i = 0; i < numVertices; ++i)
	{
		Float3& pos = vba.Position<Float3>(i);
		float r = Mathf::Sqrt(pos[0]*pos[0] + pos[1]*pos[1]);
		float z = pos[2] + 2.0f;
		if (z >= 2.0f)
		{
			z = 4.0f - r;
		}
		else
		{
			z = r;
		}
		pos[2] = z;
	}

	// Translate the pendulum joint to the origin for the purpose of
	// rotation.
	for (i = 0; i < numVertices; ++i)
	{
		vba.Position<Float3>(i)[2] -= 16.0f;
	}
	bulb->UpdateModelSpace(Visual::GU_NORMALS);

	vba.ApplyTo(rod);
	numVertices = vba.GetNumVertices();
	for (i = 0; i < numVertices; ++i)
	{
		vba.Position<Float3>(i)[2] -= 16.0f;
	}
	rod->UpdateModelSpace(Visual::GU_NORMALS);

	// Group the objects into a single subtree.
	mPendulum = new0 Node();
	mPendulum->AttachChild(rod);
	mPendulum->AttachChild(bulb);

	// Translate back to original model position.
	mPendulum->LocalTransform.SetTranslate(APoint(0.0f, 0.0f, 16.0f));

	// Add a material for coloring.
	Float4 black(0.0f, 0.0f, 0.0f, 1.0f);
	Float4 white(1.0f, 1.0f, 1.0f, 1.0f);
	Material* material = new0 Material();
	material->Emissive = black;
	material->Ambient = Float4(0.1f, 0.1f, 0.1f, 1.0f);
	material->Diffuse = Float4(0.99607f, 0.83920f, 0.67059f, 1.0f);
	material->Specular = black;

	// Use two lights to illuminate the pendulum.
	Light* light[2];
	light[0] = new0 Light(Light::LT_DIRECTIONAL);
	light[0]->Ambient = white;
	light[0]->Diffuse = white;
	light[0]->Specular = black;
	light[0]->SetDirection(AVector(-1.0f, -1.0f, 0.0f));

	light[1] = new0 Light(Light::LT_DIRECTIONAL);
	light[1]->Ambient = white;
	light[1]->Diffuse = white;
	light[1]->Specular = black;
	light[1]->SetDirection(AVector(+1.0f, -1.0f, 0.0f));

	// TODO:  The following code is used to piece together an effect with
	// two passes.  It is better to write an effect whose vertex shader
	// has constants corresponding to the two lights (for a single-pass
	// effect).
	LightDirPerVerEffect* effect = new0 LightDirPerVerEffect();
	VisualTechnique* technique = effect->GetTechnique(0);
	VisualPass* pass0 = technique->GetPass(0);
	VisualPass* pass1 = new0 VisualPass();
	pass1->SetVertexShader(pass0->GetVertexShader());
	pass1->SetPixelShader(pass0->GetPixelShader());
	AlphaState* astate = new0 AlphaState();
	astate->BlendEnabled = true;
	astate->SrcBlend = AlphaState::SBM_ONE;
	astate->DstBlend = AlphaState::DBM_ONE;
	pass1->SetAlphaState(astate);
	pass1->SetCullState(pass0->GetCullState());
	pass1->SetDepthState(pass0->GetDepthState());
	pass1->SetStencilState(pass0->GetStencilState());
	pass1->SetOffsetState(pass0->GetOffsetState());
	pass1->SetWireState(pass0->GetWireState());
	technique->InsertPass(pass1);

	VisualEffectInstance* instance = new0 VisualEffectInstance(effect, 0);
	for (int pass = 0; pass < 2; ++pass)
	{
		instance->SetVertexConstant(pass, 0,
		                            new0 PVWMatrixConstant());
		instance->SetVertexConstant(pass, 1,
		                            new0 CameraModelPositionConstant());
		instance->SetVertexConstant(pass, 2,
		                            new0 MaterialEmissiveConstant(material));
		instance->SetVertexConstant(pass, 3,
		                            new0 MaterialAmbientConstant(material));
		instance->SetVertexConstant(pass, 4,
		                            new0 MaterialDiffuseConstant(material));
		instance->SetVertexConstant(pass, 5,
		                            new0 MaterialSpecularConstant(material));
		instance->SetVertexConstant(pass, 6,
		                            new0 LightModelDVectorConstant(light[pass]));
		instance->SetVertexConstant(pass, 7,
		                            new0 LightAmbientConstant(light[pass]));
		instance->SetVertexConstant(pass, 8,
		                            new0 LightDiffuseConstant(light[pass]));
		instance->SetVertexConstant(pass, 9,
		                            new0 LightSpecularConstant(light[pass]));
		instance->SetVertexConstant(pass, 10,
		                            new0 LightAttenuationConstant(light[pass]));
	}

	rod->SetEffectInstance(instance);
	bulb->SetEffectInstance(instance);

	return mPendulum;
}
Exemple #28
0
//----------------------------------------------------------------------------
void Fluids3D::CreateScene ()
{
    // Get fluid solver parameters.
    const int bound0M1 = mSmoke->GetIMax();
    const int bound1M1 = mSmoke->GetJMax();
    const int bound2M1 = mSmoke->GetKMax();
    const int bound0 = bound0M1 + 1;
    const int bound1 = bound1M1 + 1;
    const int bound2 = bound2M1 + 1;
    const int quantity = bound0*bound1*bound2;
    const float* x = mSmoke->GetX();
    const float* y = mSmoke->GetY();
    const float* z = mSmoke->GetZ();

#ifdef USE_PARTICLES
    // Create the vertex format.
    VertexFormat* vformat = VertexFormat::Create(3,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0,
        VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT4, 0);
#else
    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT4, 0);
#endif

    // Create the vertex buffer for the cube.
#ifdef USE_PARTICLES
    const int numVertices = 4*quantity;
#else
    const int numVertices = quantity;
#endif

    int vstride = vformat->GetStride();
    VertexBuffer* vbuffer = new0 VertexBuffer(numVertices, vstride);

    int i0, i1, i2, index;

#ifdef USE_PARTICLES
    const float delta = mSmoke->GetDx();
    Float4* posSize = new1<Float4>(quantity);
    for (i2 = 0, index = 0; i2 < bound2; ++i2)
    {
        for (i1 = 0; i1 < bound1; ++i1)
        {
            for (i0 = 0; i0 < bound0; ++i0, ++index)
            {
                posSize[index] = Float4(x[i0], y[i1], z[i2], delta);
            }
        }
    }

    mCube = new0 Particles(vformat, vbuffer, 4, posSize, 1.0f);
    UpdateVertexBuffer();

    IndexBuffer* ibuffer = mCube->GetIndexBuffer();
#else
    VertexBufferAccessor vba(vformat, vbuffer);
    for (i2 = 0, index = 0; i2 < bound2; ++i2)
    {
        for (i1 = 0; i1 < bound1; ++i1)
        {
            for (i0 = 0; i0 < bound0; ++i0, ++index)
            {
                vba.Position<Float3>(index) = Float3(x[i0], y[i1], z[i2]);
            }
        }
    }

    // Create the index buffer for the cube.
    const int numIndices =
        6*bound0M1*bound1M1*bound2 +
        6*bound0M1*bound1*bound2M1 +
        6*bound0*bound1M1*bound2M1;

    IndexBuffer* ibuffer = new0 IndexBuffer(numIndices, sizeof(int));
    int* indices = (int*)ibuffer->GetData();

    const int bound01 = bound0*bound1;
    int j0, j1, j2, j3;
    for (i2 = 0; i2 < bound2; ++i2)
    {
        for (i1 = 0; i1 < bound1M1; ++i1)
        {
            for (i0 = 0; i0 < bound0M1; ++i0)
            {
                j0 = i0 + bound0*(i1 + bound1*i2);
                j1 = j0 + 1;
                j2 = j1 + bound0;
                j3 = j2 - 1;
                *indices++ = j0;
                *indices++ = j1;
                *indices++ = j2;
                *indices++ = j0;
                *indices++ = j2;
                *indices++ = j3;
            }
        }
    }

    for (i1 = 0; i1 < bound1; ++i1)
    {
        for (i2 = 0; i2 < bound2M1; ++i2)
        {
            for (i0 = 0; i0 < bound0M1; ++i0)
            {
                j0 = i0 + bound0*(i1 + bound1*i2);
                j1 = j0 + 1;
                j2 = j1 + bound01;
                j3 = j2 - 1;
                *indices++ = j0;
                *indices++ = j1;
                *indices++ = j2;
                *indices++ = j0;
                *indices++ = j2;
                *indices++ = j3;
            }
        }
    }

    for (i0 = 0; i0 < bound0; ++i0)
    {
        for (i1 = 0; i1 < bound1M1; ++i1)
        {
            for (i2 = 0; i2 < bound2M1; ++i2)
            {
                j0 = i0 + bound0*(i1 + bound1*i2);
                j1 = j0 + bound0;
                j2 = j1 + bound01;
                j3 = j2 - bound0;
                *indices++ = j0;
                *indices++ = j1;
                *indices++ = j2;
                *indices++ = j0;
                *indices++ = j2;
                *indices++ = j3;
            }
        }
    }

    mCube = new0 TriMesh(vformat, vbuffer, ibuffer);
    UpdateVertexBuffer();
#endif

    mNumIndices = ibuffer->GetNumElements();
    mIndices = new1<int>(mNumIndices);
    memcpy(mIndices, ibuffer->GetData(), mNumIndices*sizeof(int));

    // Create the cube effect.
#ifdef USE_PARTICLES
    std::string path = Environment::GetPathR("Disk.wmtf");
    Texture2D* texture = Texture2D::LoadWMTF(path);
    VisualEffectInstance* instance =
        VertexColor4TextureEffect::CreateUniqueInstance(texture,
        Shader::SF_NEAREST, Shader::SC_CLAMP_EDGE, Shader::SC_CLAMP_EDGE);
#else
    VertexColor4Effect* effect = new0 VertexColor4Effect();
    VisualEffectInstance* instance = effect->CreateInstance();
#endif

    const VisualPass* pass = instance->GetPass(0);
    AlphaState* astate = pass->GetAlphaState();
    astate->BlendEnabled = true;

    CullState* cstate = pass->GetCullState();
    cstate->Enabled = false;

    DepthState* dstate = pass->GetDepthState();
    dstate->Enabled = false;
    dstate->Writable = false;

    mCube->SetEffectInstance(instance);

    mScene = new0 Node();
    mScene->AttachChild(mCube);
}