//---------------------------------------------------------------------------- void ExtremalQuery::CreateScene () { mScene = new0 Node(); mWireState = new0 WireState(); mRenderer->SetOverrideWireState(mWireState); mCullState = new0 CullState(); mCullState->Enabled = false; mRenderer->SetOverrideCullState(mCullState); const int numVertices = 32; CreateConvexPolyhedron(numVertices); mScene->AttachChild(CreateVisualConvexPolyhedron()); // Use small spheres to show the extreme points in the camera's right // direction. VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0); StandardMesh sm(vformat); VertexColor3Effect* effect = new0 VertexColor3Effect(); // maximum sphere mMaxSphere = sm.Sphere(8, 8, 0.05f); mMaxSphere->SetEffectInstance(effect->CreateInstance()); mScene->AttachChild(mMaxSphere); // minimum sphere mMinSphere = sm.Sphere(8, 8, 0.05f); mMinSphere->SetEffectInstance(effect->CreateInstance()); mScene->AttachChild(mMinSphere); UpdateExtremePoints(); }
//---------------------------------------------------------------------------- bool FxCompiler::CreateEffect (const Program& vProgram, const Program& pProgram) { InputArray vInputs, pInputs; OutputArray vOutputs, pOutputs; ConstantArray vConstants, pConstants; SamplerArray vSamplers, pSamplers; if (!Process(vProgram, vInputs, vOutputs, vConstants, vSamplers)) { return false; } if (!Process(pProgram, pInputs, pOutputs, pConstants, pSamplers)) { return false; } mVShader = (VertexShader*)CreateShader(true, vProgram, vInputs, vOutputs, vConstants, vSamplers); mPShader = (PixelShader*)CreateShader(false, pProgram, pInputs, pOutputs, pConstants, pSamplers); VisualPass* pass = new0 VisualPass(); pass->SetVertexShader(mVShader); pass->SetPixelShader(mPShader); // TODO. Once Cg FX files are parsed, the global state from each pass // should be set here. For now, the application is responsible for // setting the global state after the *.wmfx file is loaded. pass->SetAlphaState(new0 AlphaState()); pass->SetCullState(new0 CullState()); pass->SetDepthState(new0 DepthState()); pass->SetOffsetState(new0 OffsetState()); pass->SetStencilState(new0 StencilState()); pass->SetWireState(new0 WireState()); // TODO. Once Cg FX files are parsed, we might have multiple techniques // or multiple passes per technique. VisualTechnique* technique = new0 VisualTechnique(); technique->InsertPass(pass); mEffect = new0 VisualEffect(); mEffect->InsertTechnique(technique); return true; }
//---------------------------------------------------------------------------- void IntersectTriangleCylinder::CreateScene () { mScene = new0 Node(); mCullState = new0 CullState(); mCullState->Enabled = false; mRenderer->SetOverrideCullState(mCullState); mWireState = new0 WireState(); mRenderer->SetOverrideWireState(mWireState); 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(3, vstride); VertexBufferAccessor vba(vformat, vbuffer); vba.Position<Vector3f>(0) = (const Vector3f&)mTriangleMVertex0; vba.Color<Float3>(0, 0) = Float3(0.0f, 0.0f, 1.0f); vba.Position<Vector3f>(1) = (const Vector3f&)mTriangleMVertex1; vba.Color<Float3>(0, 1) = Float3(0.0f, 0.0f, 1.0f); vba.Position<Vector3f>(2) = (const Vector3f&)mTriangleMVertex2; vba.Color<Float3>(0, 2) = Float3(0.0f, 0.0f, 1.0f); IndexBuffer* ibuffer = new0 IndexBuffer(3, sizeof(int)); int* indices = (int*)ibuffer->GetData(); indices[0] = 0; indices[1] = 1; indices[2] = 2; mTMesh = new0 TriMesh(vformat, vbuffer, ibuffer); mTMesh->SetEffectInstance( VertexColor3Effect::CreateUniqueInstance()); mTMesh->LocalTransform.SetTranslate(APoint(0.0f, 1.125f, 0.0f)); mCMesh = StandardMesh(vformat).Cylinder(8, 16, mCylinderRadius, mCylinderHeight, false); vba.ApplyTo(mCMesh); for (int i = 0; i < vba.GetNumVertices(); ++i) { vba.Color<Float3>(0, i) = Float3(1.0f, 0.0f, 0.0f); } mCMesh->SetEffectInstance( VertexColor3Effect::CreateUniqueInstance()); mScene->AttachChild(mTMesh); mScene->AttachChild(mCMesh); }
//---------------------------------------------------------------------------- void ConvexHull3D::CreateScene () { mScene = new0 Node(); mTrnNode = new0 Node(); mScene->AttachChild(mTrnNode); mWireState = new0 WireState(); mRenderer->SetOverrideWireState(mWireState); mCullState = new0 CullState(); mCullState->Enabled = false; mRenderer->SetOverrideCullState(mCullState); VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0); TriMesh* sphere = StandardMesh(vformat).Sphere(8, 8, 0.01f); sphere->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance()); mTrnNode->SetChild(1, sphere); // The current file is "Data/data01.txt". LoadData(); }
//---------------------------------------------------------------------------- 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 GeodesicHeightField::CreateScene () { mScene = new0 Node(); mWireState = new0 WireState(); mRenderer->SetOverrideWireState(mWireState); mCullState = new0 CullState(); mCullState->Enabled = false; mRenderer->SetOverrideCullState(mCullState); // Create the ground. It covers a square with vertices (1,1,0), (1,-1,0), // (-1,1,0), and (-1,-1,0). VertexFormat* vformat = VertexFormat::Create(3, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_NORMAL, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0); const int xSize = 64; const int ySize = 64; const float xExtent = 1.0f; const float yExtent = 1.0f; mMesh = StandardMesh(vformat).Rectangle(xSize, ySize, xExtent, yExtent); // Create a B-Spline height field. The heights of the control point are // defined in an input file. The input file is structured as // // numUCtrlPoints numVCtrlPoints UDegree VDegree // z[0][0] z[0][1] ... z[0][numV-1] // z[1][0] z[1][1] ... z[1][numV_1] // : // z[numU-1][0] z[numU-1][1] ... z[numU-1][numV-1] std::string path = Environment::GetPathR("ControlPoints.txt"); std::ifstream inFile(path.c_str()); int numUCtrlPoints, numVCtrlPoints, uDegree, vDegree; double height; inFile >> numUCtrlPoints; inFile >> numVCtrlPoints; inFile >> uDegree; inFile >> vDegree; Vector3d** ctrlPoints = new2<Vector3d>(numUCtrlPoints, numVCtrlPoints); int i; for (i = 0; i < numUCtrlPoints; ++i) { double u = (double)(xExtent*(-1.0f + 2.0f*i/(numUCtrlPoints-1))); for (int j = 0; j < numVCtrlPoints; ++j) { double v = (double)(yExtent*(-1.0f + 2.0f*j/(numVCtrlPoints-1))); inFile >> height; ctrlPoints[i][j] = Vector3d(u, v, height); } } inFile.close(); mSurface = new0 BSplineRectangled(numUCtrlPoints, numVCtrlPoints, ctrlPoints, uDegree, vDegree, false, false, true, true); delete2(ctrlPoints); VertexBufferAccessor vba(mMesh); for (i = 0; i < vba.GetNumVertices(); ++i) { Vector3f& position = vba.Position<Vector3f>(i); double u = (double)((position.X() + xExtent)/(2.0f*xExtent)); double v = (double)((position.Y() + yExtent)/(2.0f*yExtent)); position.Z() = (float)mSurface->P(u,v).Z(); } mMesh->UpdateModelSpace(Visual::GU_NORMALS); // Attach an effect that uses lights, material, and texture. mMesh->SetEffectInstance(CreateEffectInstance()); mScene->AttachChild(mMesh); // Create the geodesic calculator. mGeodesic = new0 BSplineGeodesicd(*mSurface); mGeodesic->Subdivisions = 6; mGeodesic->Refinements = 1; mGeodesic->SearchRadius = 0.1; mGeodesic->RefineCallback = &GeodesicHeightField::RefineCallback; mPQuantity = (1 << mGeodesic->Subdivisions) + 1; }
//---------------------------------------------------------------------------- void VolumeTextures::CreateScene () { mScene = new0 Node(); mAlphaState = new0 AlphaState(); mAlphaState->BlendEnabled = true; mRenderer->SetOverrideAlphaState(mAlphaState); mCullState = new0 CullState(); mCullState->Enabled = false; mRenderer->SetOverrideCullState(mCullState); // Create the grid of square meshes. const int numSlices = 64; const int numSamples = 32; // The vertex format that is shared by all square meshes. VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT3, 0); int vstride = vformat->GetStride(); // The index buffer that is shared by all square meshes. int numIndices = 6*(numSamples-1)*(numSamples-1); IndexBuffer* ibuffer = new0 IndexBuffer(numIndices, sizeof(int)); int* indices = (int*)ibuffer->GetData(); for (int i1 = 0; i1 < numSamples - 1; ++i1) { for (int i0 = 0; i0 < numSamples - 1; ++i0) { int v0 = i0 + numSamples * i1; int v1 = v0 + 1; int v2 = v1 + numSamples; int v3 = v0 + numSamples; *indices++ = v0; *indices++ = v1; *indices++ = v2; *indices++ = v0; *indices++ = v2; *indices++ = v3; } } // Create the volume texture. Three Gaussian distributions are used for // the RGB color channels. The alpha channel is constant. const int bound = 64; Texture3D* texture = new0 Texture3D(Texture::TF_A8R8G8B8, bound, bound, bound, 1); unsigned char* data = (unsigned char*)texture->GetData(0); const float mult = 1.0f/(bound - 1.0f); const float rParam = 0.01f; const float gParam = 0.01f; const float bParam = 0.01f; const float extreme = 8.0f; APoint rCenter( 0.5f*extreme, 0.0f, 0.0f); APoint gCenter(-0.5f*extreme, -0.5f*extreme, 0.0f); APoint bCenter(-0.5f*extreme, +0.5f*extreme, 0.0f); unsigned char commonAlpha = 12; APoint point; for (int z = 0; z < bound; ++z) { point[2] = -extreme + 2.0f*extreme*mult*z; for (int y = 0; y < bound; ++y) { point[1] = -extreme + 2.0f*extreme*mult*y; for (int x = 0; x < bound; ++x) { point[0] = -extreme + 2.0f*extreme*mult*x; AVector diff = point - rCenter; float sqrLength = diff.SquaredLength(); float rGauss = 1.0f - rParam*sqrLength; if (rGauss < 0.0f) { rGauss = 0.0f; } diff = point - gCenter; sqrLength = diff.SquaredLength(); float gGauss = 1.0f - gParam*sqrLength; if (gGauss < 0.0f) { gGauss = 0.0f; } diff = point - bCenter; sqrLength = diff.SquaredLength(); float bGauss = 1.0f - bParam*sqrLength; if (bGauss < 0.0f) { bGauss = 0.0f; } *data++ = (unsigned char)(255.0f*bGauss); *data++ = (unsigned char)(255.0f*gGauss); *data++ = (unsigned char)(255.0f*rGauss); *data++ = commonAlpha; } } } // The volume texture effect that is shared by all square meshes. std::string effectFile = Environment::GetPathR("VolumeTextures.wmfx"); VolumeTextureEffect* effect = new0 VolumeTextureEffect(effectFile); VisualEffectInstance* instance = effect->CreateInstance(texture); // The grid of squares. const int numVertices = numSamples*numSamples; float inv = 1.0f/(numSamples - 1.0f); VertexBufferAccessor vba; for (int slice = 0; slice < numSlices; ++slice) { VertexBuffer* vbuffer = new0 VertexBuffer(numVertices, vstride); vba.ApplyTo(vformat, vbuffer); float w = slice/(numSlices - 1.0f); float z = 2.0f*w - 1.0f; for (int i1 = 0, i = 0; i1 < numSamples; ++i1) { float v = i1*inv; float y = 2.0f*v - 1.0f; for (int i0 = 0; i0 < numSamples; ++i0, ++i) { float u = i0*inv; float x = 2.0f*u - 1.0f; vba.Position<Float3>(i) = Float3(x, y, z); vba.TCoord<Float3>(0, i) = Float3(u, v, w); } } TriMesh* mesh = new0 TriMesh(vformat, vbuffer, ibuffer); mesh->SetEffectInstance(instance); mScene->AttachChild(mesh); } }
//---------------------------------------------------------------------------- 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 CollisionsBoundTree::CreateScene () { // The root of the scene will have two cylinders as children. mScene = new0 Node(); mWireState = new0 WireState(); mRenderer->SetOverrideWireState(mWireState); mCullState = new0 CullState(); mCullState->Enabled = false; mRenderer->SetOverrideCullState(mCullState); // Create a texture image to be used by both cylinders. Texture2D* texture = new0 Texture2D(Texture::TF_A8R8G8B8, 2, 2, 1); unsigned int* data = (unsigned int*)texture->GetData(0); data[0] = Color::MakeR8G8B8(0, 0, 255); // blue data[1] = Color::MakeR8G8B8(0, 255, 255); // cyan data[2] = Color::MakeR8G8B8(255, 0, 0); // red data[3] = Color::MakeR8G8B8(255, 255, 0); // yellow Texture2DEffect* effect = new0 Texture2DEffect(Shader::SF_LINEAR); // Create two cylinders, one short and thick, one tall and thin. VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0); StandardMesh sm(vformat); VertexBufferAccessor vba; int i; mCylinder0 = sm.Cylinder(8, 16, 1.0f, 2.0f, false); vba.ApplyTo(mCylinder0); for (i = 0; i < vba.GetNumVertices(); ++i) { vba.TCoord<Float2>(0, i) = mBlueUV; } mCylinder0->SetEffectInstance(effect->CreateInstance(texture)); mScene->AttachChild(mCylinder0); mCylinder1 = sm.Cylinder(16,8,0.25,4.0,false); vba.ApplyTo(mCylinder1); for (i = 0; i < vba.GetNumVertices(); ++i) { vba.TCoord<Float2>(0, i) = mRedUV; } mCylinder1->SetEffectInstance(effect->CreateInstance(texture)); mScene->AttachChild(mCylinder1); mScene->Update(); // Set up the collision system. Record0 handles the collision response. // Record1 is not given a callback so that 'double processing' of the // events does not occur. CTree* tree0 = new0 CTree(mCylinder0, 1, false); CRecord* record0 = new0 CRecord(tree0, 0, Response, this); CTree* tree1 = new0 CTree(mCylinder1, 1, false); CRecord* record1 = new0 CRecord(tree1, 0, 0, 0); mGroup = new0 CGroup(); mGroup->Add(record0); mGroup->Add(record1); ResetColors(); mGroup->TestIntersection(); }
//---------------------------------------------------------------------------- void BillboardNodes::CreateScene () { mScene = new0 Node(); mCullState = new0 CullState(); mRenderer->SetOverrideCullState(mCullState); mWireState = new0 WireState(); mRenderer->SetOverrideWireState(mWireState); // All triangle meshes have this common vertex format. Use StandardMesh // to create these meshes. VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0); StandardMesh stdMesh(vformat); // Create the ground. It covers a square with vertices (1,1,0), (1,-1,0), // (-1,1,0), and (-1,-1,0). Multiply the texture coordinates by a factor // to enhance the wrap-around. mGround = stdMesh.Rectangle(2, 2, 16.0f, 16.0f); VertexBufferAccessor vba(mGround); int i; for (i = 0; i < vba.GetNumVertices(); ++i) { Float2& tcoord = vba.TCoord<Float2>(0, i); tcoord[0] *= 128.0f; tcoord[1] *= 128.0f; } // Create a texture effect for the ground. std::string path = Environment::GetPathR("Horizontal.wmtf"); Texture2D* texture = Texture2D::LoadWMTF(path); VisualEffectInstance* instance = Texture2DEffect::CreateUniqueInstance( texture, Shader::SF_LINEAR_LINEAR, Shader::SC_REPEAT, Shader::SC_REPEAT); mGround->SetEffectInstance(instance); mScene->AttachChild(mGround); // Create a rectangle mesh. The mesh is in the xy-plane. Do not apply // local transformations to the mesh. Use the billboard node transforms // to control the mesh location and orientation. mRectangle = stdMesh.Rectangle(2, 2, 0.125f, 0.25f); // Create a texture effect for the rectangle and for the torus. Texture2DEffect* geomEffect = new0 Texture2DEffect(Shader::SF_LINEAR); path = Environment::GetPathR("RedSky.wmtf"); texture = Texture2D::LoadWMTF(path); mRectangle->SetEffectInstance(geomEffect->CreateInstance(texture)); // Create a billboard node that causes a rectangle to always be facing // the camera. This is the type of billboard for an avatar. mBillboard0 = new0 BillboardNode(mCamera); mBillboard0->AttachChild(mRectangle); mScene->AttachChild(mBillboard0); // The billboard rotation is about its model-space up-vector (0,1,0). In // this application, world-space up is (0,0,1). Locally rotate the // billboard so it's up-vector matches the world's. mBillboard0->LocalTransform.SetTranslate(APoint(-0.25f, 0.0f, 0.25f)); mBillboard0->LocalTransform.SetRotate(HMatrix(AVector::UNIT_X, Mathf::HALF_PI)); // Create a torus mesh. Do not apply local transformations to the mesh. // Use the billboard node transforms to control the mesh location and // orientation. mTorus = StandardMesh(vformat, false).Torus(16, 16, 1.0f, 0.25f); mTorus->LocalTransform.SetUniformScale(0.1f); // Create a texture effect for the torus. It uses the RedSky image that // the rectangle uses. mTorus->SetEffectInstance(geomEffect->CreateInstance(texture)); // Create a billboard node that causes an object to always be oriented // the same way relative to the camera. mBillboard1 = new0 BillboardNode(mCamera); mBillboard1->AttachChild(mTorus); mScene->AttachChild(mBillboard1); // The billboard rotation is about its model-space up-vector (0,1,0). In // this application, world-space up is (0,0,1). Locally rotate the // billboard so it's up-vector matches the world's. mBillboard1->LocalTransform.SetTranslate(APoint(0.25f, 0.0f, 0.25f)); mBillboard1->LocalTransform.SetRotate(HMatrix(AVector::UNIT_X, Mathf::HALF_PI)); #ifdef DEMONSTRATE_VIEWPORT_BOUNDING_RECTANGLE // The screen camera is designed to map (x,y,z) in [0,1]^3 to (x',y,'z') // in [-1,1]^2 x [0,1]. mSSCamera = new0 Camera(false); mSSCamera->SetFrustum(0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f); mSSCamera->SetFrame(APoint::ORIGIN, AVector::UNIT_Z, AVector::UNIT_Y, AVector::UNIT_X); // Create a semitransparent screen rectangle. VertexFormat* ssVFormat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT4, 0); int ssVStride = ssVFormat->GetStride(); VertexBuffer* ssVBuffer = new0 VertexBuffer(4, ssVStride); VertexBufferAccessor ssVba(ssVFormat, ssVBuffer); Float4 ssColor(0.0f, 0.0f, 1.0f, 0.25f); ssVba.Position<Float3>(0) = Float3(0.0f, 0.0f, 0.0f); ssVba.Position<Float3>(1) = Float3(1.0f, 0.0f, 0.0f); ssVba.Position<Float3>(2) = Float3(1.0f, 1.0f, 0.0f); ssVba.Position<Float3>(3) = Float3(0.0f, 1.0f, 0.0f); ssVba.Color<Float4>(0, 0) = ssColor; ssVba.Color<Float4>(0, 1) = ssColor; ssVba.Color<Float4>(0, 2) = ssColor; ssVba.Color<Float4>(0, 3) = ssColor; IndexBuffer* ssIBuffer = new0 IndexBuffer(6, sizeof(int)); int* indices = (int*)ssIBuffer->GetData(); indices[0] = 0; indices[1] = 1; indices[2] = 2; indices[3] = 0; indices[4] = 2; indices[5] = 3; mSSRectangle = new0 TriMesh(ssVFormat, ssVBuffer, ssIBuffer); mSSRectangle->Update(); // Create a vertex color effect for the screen rectangle. VertexColor4Effect* ssEffect = new0 VertexColor4Effect(); mSSRectangle->SetEffectInstance(ssEffect->CreateInstance()); // Alpha blending must be enabled to obtain the semitransparency. ssEffect->GetAlphaState(0, 0)->BlendEnabled = true; #endif }
RenderPass RenderStage::createRenderPassFromJson(const JSONValue& renderPassJSON) { GraphicSystem& graphicSystem = renderer.getGraphicSystem(); RenderPass renderPass; auto clearColorJSON = renderPassJSON.getJSONValue("clearColor"); auto colorWriteJSON = renderPassJSON.getJSONValue("colorWrite"); auto depthWriteJSON = renderPassJSON.getJSONValue("depthWrite"); auto renderTargetLayerJSON = renderPassJSON.getJSONValue("renderTargetLayer"); auto flagsJSON = renderPassJSON.getJSONValue("flags"); if(!clearColorJSON.isNull()) renderPass.clearColor = clearColorJSON.getVector4(); if(!colorWriteJSON.isNull()) renderPass.colorWrite = colorWriteJSON.getBool(); if(!depthWriteJSON.isNull()) renderPass.depthWrite = depthWriteJSON.getBool(); if(!renderTargetLayerJSON.isNull()) renderPass.renderTargetLayer = renderTargetLayerJSON.getInt(); if(!flagsJSON.isNull()) { unsigned int flags = 0; for(unsigned int i = 0; i < flagsJSON.getSize(); ++i) { if(flagsJSON.getJSONArrayItem(i).getString().compare("CLEAR_COLOR") == 0) flags |= CLEAR_COLOR; if(flagsJSON.getJSONArrayItem(i).getString().compare("CLEAR_DEPTH") == 0) flags |= CLEAR_DEPTH; } renderPass.flags = flags; } auto viewPortJSON = renderPassJSON.getJSONValue("viewPort"); if(!viewPortJSON.isNull()) { FixedArray<int, 4> viewPort = viewPortJSON.getInt4(); renderPass.viewPort.set(viewPort[0], viewPort[1], viewPort[2], viewPort[3]); } else renderPass.viewPort = renderer.getScreenViewPort(); auto renderTargetJSON = renderPassJSON.getJSONValue("renderTarget"); renderPass.renderTarget = graphicSystem.createRenderTarget(renderTargetJSON); auto shaderPasses = renderPassJSON.getJSONValue("shaderPasses"); if(!shaderPasses.isNull()) { for(unsigned int i = 0; i < shaderPasses.getSize(); ++i) { auto shaderPassJSON = shaderPasses.getJSONArrayItem(i); auto programJSON = shaderPassJSON.getJSONValue("shaderProgram"); auto vertexDataJSON = shaderPassJSON.getJSONValue("vertexData"); auto rasterStateJSON = shaderPassJSON.getJSONValue("rasterState"); auto shaderParameterBlocksJSON = shaderPassJSON.getJSONValue("shaderParameterBlocks"); auto texturesJSON = shaderPassJSON.getJSONValue("textures"); ShaderPass shaderPass; if(!vertexDataJSON.isNull()) { if(vertexDataJSON.getString().compare("fullScreenQuad") == 0) shaderPass.vertexData = renderer.getFullScreenQuad(); } if(!rasterStateJSON.isNull()) { auto blendFunctionJSON = rasterStateJSON.getJSONValue("blendFunction"); auto compareFunctionJSON = rasterStateJSON.getJSONValue("compareFunction"); auto cullFaceJSON = rasterStateJSON.getJSONValue("cullFace"); auto blendState = !blendFunctionJSON.isNull() ? BlendState(true, enumFromString<BlendFunction>(blendFunctionJSON.getString())) : BlendState(false, BlendFunction::Replace); auto compareState = !compareFunctionJSON.isNull() ? CompareState(true, enumFromString<CompareFunction>(compareFunctionJSON.getString())) : CompareState(false, CompareFunction::Never); auto cullState = !cullFaceJSON.isNull() ? CullState(true, enumFromString<CullFace>(cullFaceJSON.getString())) : CullState(false, CullFace::Back); shaderPass.rasterState = RasterState(blendState, compareState, cullState); } if(!shaderParameterBlocksJSON.isNull()) { for(unsigned int j = 0; j < shaderParameterBlocksJSON.getSize(); ++j) { ShaderParameterBlock* block = graphicSystem.createShaderParameterBlock(shaderParameterBlocksJSON.getJSONArrayItem(j)); if(block) shaderPass.shaderParameterBlocks.pushBack(block); } } if(!texturesJSON.isNull()) { for(unsigned int j = 0; j < texturesJSON.getSize(); ++j) { Texture* texture = graphicSystem.createTexture(texturesJSON.getJSONArrayItem(j)); if(texture) shaderPass.textures.pushBack(texture); } } if(!programJSON.isNull()) shaderPass.program = graphicSystem.createShaderProgram(programJSON); renderPass.shaderPasses.pushBack(shaderPass); } } return renderPass; }
//---------------------------------------------------------------------------- void Delaunay3D::CreateScene () { int i, numVertices; Vector3f* vertices; #if 0 // test a cube numVertices = 8; vertices = new1<Vector3f>(numVertices); vertices[0] = Vector3f(0.0f, 0.0f, 0.0f); vertices[1] = Vector3f(1.0f, 0.0f, 0.0f); vertices[2] = Vector3f(1.0f, 1.0f, 0.0f); vertices[3] = Vector3f(0.0f, 1.0f, 0.0f); vertices[4] = Vector3f(0.0f, 0.0f, 1.0f); vertices[5] = Vector3f(1.0f, 0.0f, 1.0f); vertices[6] = Vector3f(1.0f, 1.0f, 1.0f); vertices[7] = Vector3f(0.0f, 1.0f, 1.0f); #endif #if 1 // randomly generated points numVertices = 128; vertices = new1<Vector3f>(numVertices); vertices[0] = Vector3f::ZERO; for (i = 1; i < numVertices; ++i) { vertices[i].X() = Mathf::SymmetricRandom(); vertices[i].Y() = Mathf::SymmetricRandom(); vertices[i].Z() = Mathf::SymmetricRandom(); } #endif mMin = vertices[0]; mMax = vertices[0]; for (i = 1; i < numVertices; ++i) { for (int j = 0; j < 3; ++j) { float value = vertices[i][j]; if (value < mMin[j]) { mMin[j] = value; } else if (value > mMax[j]) { mMax[j] = value; } } } mDelaunay = new0 Delaunay3f(numVertices, vertices, 0.001f, true, Query::QT_REAL); mScene = new0 Node(); mCullState = new0 CullState(); mCullState->Enabled = false; mRenderer->SetOverrideCullState(mCullState); mScene->AttachChild(CreateSphere()); for (int j = 0; j < mDelaunay->GetNumSimplices(); ++j) { mScene->AttachChild(CreateTetra(j)); } }