Exemplo n.º 1
0
//----------------------------------------------------------------------------
VisualEffectInstance::VisualEffectInstance (const VisualEffect* effect,
    int techniqueIndex)
    :
    mEffect((VisualEffect*)effect),  // conceptual constness
    mTechniqueIndex(techniqueIndex)
{
    assertion(effect != 0, "Effect must be specified.\n");
    assertion(
        0 <= techniqueIndex && techniqueIndex < effect->GetNumTechniques(),
        "Invalid technique index.\n");

    VisualTechnique* technique = mEffect->GetTechnique(mTechniqueIndex);
    mNumPasses = technique->GetNumPasses();
    mVertexParameters = new1<ShaderParametersPtr>(mNumPasses);
    mPixelParameters = new1<ShaderParametersPtr>(mNumPasses);
    int p;
    for (p = 0; p < mNumPasses; ++p)
    {
        VisualPass* pass = technique->GetPass(p);
        mVertexParameters[p] =
            new0 ShaderParameters(pass->GetVertexShader());
        mPixelParameters[p] =
            new0 ShaderParameters(pass->GetPixelShader());
    }
}
Exemplo n.º 2
0
//----------------------------------------------------------------------------
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;
}