//---------------------------------------------------------------------------- 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); }
//---------------------------------------------------------------------------- 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; }
//---------------------------------------------------------------------------- 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(); }
//---------------------------------------------------------------------------- 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); }
//---------------------------------------------------------------------------- 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; }
//---------------------------------------------------------------------------- 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); }
//---------------------------------------------------------------------------- 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; }
//---------------------------------------------------------------------------- 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); }