//---------------------------------------------------------------------------- void BouncingBall::CreateWall () { 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); const float xValue = -8.0f; const float yExtent = 16.0f; const float zExtent = 16.0f; vba.Position<Float3>(0) = Float3(xValue, -yExtent, 0.0f); vba.Position<Float3>(1) = Float3(xValue, +yExtent, 0.0f); vba.Position<Float3>(2) = Float3(xValue, +yExtent, zExtent); vba.Position<Float3>(3) = Float3(xValue, -yExtent, zExtent); const float maxValue = 4.0f; vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f); vba.TCoord<Float2>(0, 1) = Float2(maxValue, 0.0f); vba.TCoord<Float2>(0, 2) = Float2(maxValue, maxValue); vba.TCoord<Float2>(0, 3) = Float2(0.0f, maxValue); IndexBuffer* ibuffer = new0 IndexBuffer(6, sizeof(int)); int* indices = (int*)ibuffer->GetData(); indices[0] = 0; indices[1] = 1; indices[2] = 2; indices[3] = 0; indices[4] = 2; indices[5] = 3; mWall = new0 TriMesh(vformat, vbuffer, ibuffer); std::string path = Environment::GetPathR("Wall1.wmtf"); Texture2D* texture = Texture2D::LoadWMTF(path); mWall->SetEffectInstance(Texture2DEffect::CreateUniqueInstance(texture, Shader::SF_LINEAR, Shader::SC_REPEAT, Shader::SC_REPEAT)); }
//------------------------------------------------------------------------------------------------------ Rect3D::Rect3D(const vector3f& ulb, const vector3f& drf, const Color& color) { m_pVertexArray = NEW VertexColor[COUNT_OF_VERTEX]; m_pVertexArray[0] = VertexColor( vector4f(ulb.m_x, ulb.m_y, drf.m_z), color ) ; m_pVertexArray[1] = VertexColor( vector4f(drf.m_x, ulb.m_y, drf.m_z), color ) ; m_pVertexArray[2] = VertexColor( vector4f(drf.m_x, drf.m_y, drf.m_z), color ) ; m_pVertexArray[3] = VertexColor( vector4f(ulb.m_x, drf.m_y, drf.m_z), color ) ; m_pVertexArray[4] = VertexColor( vector4f(ulb.m_x, ulb.m_y, ulb.m_z), color ) ; m_pVertexArray[5] = VertexColor( vector4f(drf.m_x, ulb.m_y, ulb.m_z), color ) ; m_pVertexArray[6] = VertexColor( vector4f(drf.m_x, drf.m_y, ulb.m_z), color ) ; m_pVertexArray[7] = VertexColor( vector4f(ulb.m_x, drf.m_y, ulb.m_z), color ) ; static ushort Indies[COUNT_OF_INDIES]={ 0,1, 1,2, 2,3, 3,0, 0,4, 1,5, 2,6, 3,7, 4,5, 5,6, 6,7, 7,4}; m_pRendBuffer = NEW RendBuffer( Device::RM_LINES ); m_pVertexBuffer = NEW VertexBuffer( Device::MU_DYNAMIC ); m_pIndicesBuffer = NEW IndicesBuffer( Device::MU_STATIC ); m_pRendBuffer->SetVertexBuffer( m_pVertexBuffer ); m_pRendBuffer->SetIndicesBuffer( m_pIndicesBuffer ); m_pVertexBuffer->FlushVertexBuffer( COUNT_OF_VERTEX, m_pVertexArray ); m_pIndicesBuffer->FlushIndiesBuffer( COUNT_OF_INDIES, &Indies[0] ); }
//---------------------------------------------------------------------------- void PolygonOffsets::CreateScene () { mScene = new0 Node(); 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(); // Vertices to be shared by rectangles 1 and 3. VertexBuffer* vbuffer0 = new0 VertexBuffer(4, vstride); VertexBufferAccessor vba(vformat, vbuffer0); vba.Position<Float3>(0) = Float3(-1.0f, 0.0f, -1.0f); vba.Position<Float3>(1) = Float3(-1.0f, 0.0f, +1.0f); vba.Position<Float3>(2) = Float3(+1.0f, 0.0f, +1.0f); vba.Position<Float3>(3) = Float3(+1.0f, 0.0f, -1.0f); vba.Color<Float3>(0, 0) = Float3(1.0f, 0.0f, 0.0f); vba.Color<Float3>(0, 1) = Float3(1.0f, 0.0f, 0.0f); vba.Color<Float3>(0, 2) = Float3(1.0f, 0.0f, 0.0f); vba.Color<Float3>(0, 3) = Float3(1.0f, 0.0f, 0.0f); // Vertices to be shared by rectangles 2 and 4. VertexBuffer* vbuffer1 = new0 VertexBuffer(4, vstride); vba.ApplyTo(vformat, vbuffer1); vba.Position<Float3>(0) = Float3(-1.0f, 0.0f, -1.0f); vba.Position<Float3>(1) = Float3(-1.0f, 0.0f, +1.0f); vba.Position<Float3>(2) = Float3(+1.0f, 0.0f, +1.0f); vba.Position<Float3>(3) = Float3(+1.0f, 0.0f, -1.0f); vba.Color<Float3>(0, 0) = Float3(0.0f, 1.0f, 0.0f); vba.Color<Float3>(0, 1) = Float3(0.0f, 1.0f, 0.0f); vba.Color<Float3>(0, 2) = Float3(0.0f, 1.0f, 0.0f); vba.Color<Float3>(0, 3) = Float3(0.0f, 1.0f, 0.0f); // Indices to be shared by all rectangles. 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; // Effect to be shared by the first three rectangles. VertexColor3Effect* effect = new0 VertexColor3Effect(); // rectangle 1 TriMesh* mesh = new0 TriMesh(vformat, vbuffer0, ibuffer); mesh->SetEffectInstance(effect->CreateInstance()); mesh->LocalTransform.SetTranslate(APoint(+2.0f, -4.0f, 0.0f)); mScene->AttachChild(mesh); // rectangle 2 mesh = new0 TriMesh(vformat, vbuffer1, ibuffer); mesh->SetEffectInstance(effect->CreateInstance()); mesh->LocalTransform.SetTranslate(APoint(+2.0f, -4.0f, 0.0f)); mesh->LocalTransform.SetUniformScale(0.5f); mScene->AttachChild(mesh); // rectangle 3 mesh = new0 TriMesh(vformat, vbuffer0, ibuffer); mesh->SetEffectInstance(effect->CreateInstance()); mesh->LocalTransform.SetTranslate(APoint(-2.0f, -4.0f, 0.0f)); mScene->AttachChild(mesh); // rectangle 4 mesh = new0 TriMesh(vformat, vbuffer1, ibuffer); mesh->LocalTransform.SetTranslate(APoint(-2.0f, -4.0f, 0.0f)); mesh->LocalTransform.SetUniformScale(0.5f); mScene->AttachChild(mesh); // Set up the polygon offset for rectangle 4. effect = new0 VertexColor3Effect(); OffsetState* ostate = effect->GetOffsetState(0, 0); ostate->FillEnabled = true; ostate->Scale = -1.0f; ostate->Bias = -2.0f; mesh->SetEffectInstance(effect->CreateInstance()); }
//---------------------------------------------------------------------------- void FreeFormDeformation::CreateControlBoxes () { // Generate small boxes to represent the control points. mControlRoot = new0 Node(); mTrnNode->AttachChild(mControlRoot); // Create a single box to be shared by each control point box. const float halfWidth = 0.02f; VertexFormat* vformat = VertexFormat::Create(1, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0); int vstride = vformat->GetStride(); VertexBuffer* vbuffer = new0 VertexBuffer(8, vstride); VertexBufferAccessor vba(vformat, vbuffer); vba.Position<Vector3f>(0) = Vector3f(-halfWidth, -halfWidth, -halfWidth); vba.Position<Vector3f>(1) = Vector3f(+halfWidth, -halfWidth, -halfWidth); vba.Position<Vector3f>(2) = Vector3f(+halfWidth, +halfWidth, -halfWidth); vba.Position<Vector3f>(3) = Vector3f(-halfWidth, +halfWidth, -halfWidth); vba.Position<Vector3f>(4) = Vector3f(-halfWidth, -halfWidth, +halfWidth); vba.Position<Vector3f>(5) = Vector3f(+halfWidth, -halfWidth, +halfWidth); vba.Position<Vector3f>(6) = Vector3f(+halfWidth, +halfWidth, +halfWidth); vba.Position<Vector3f>(7) = Vector3f(-halfWidth, +halfWidth, +halfWidth); IndexBuffer* ibuffer = new0 IndexBuffer(36, sizeof(int)); int* indices = (int*)ibuffer->GetData(); indices[ 0] = 0; indices[ 1] = 2; indices[ 2] = 1; indices[ 3] = 0; indices[ 4] = 3; indices[ 5] = 2; indices[ 6] = 4; indices[ 7] = 5; indices[ 8] = 6; indices[ 9] = 4; indices[10] = 6; indices[11] = 7; indices[12] = 0; indices[13] = 5; indices[14] = 4; indices[15] = 0; indices[16] = 1; indices[17] = 5; indices[18] = 3; indices[19] = 7; indices[20] = 6; indices[21] = 3; indices[22] = 6; indices[23] = 2; indices[24] = 1; indices[25] = 2; indices[26] = 6; indices[27] = 1; indices[28] = 6; indices[29] = 5; indices[30] = 0; indices[31] = 4; indices[32] = 7; indices[33] = 0; indices[34] = 7; indices[35] = 3; // Create the materials and light to be attached to each box. Material* materialActive = new0 Material(); materialActive->Emissive = Float4(0.0f, 0.0f, 0.0f, 1.0f); materialActive->Ambient = Float4(1.0f, 0.0f, 0.0f, 1.0f); materialActive->Diffuse = Float4(1.0f, 0.0f, 0.0f, 1.0f); materialActive->Specular = Float4(0.0f, 0.0f, 0.0f, 1.0f); Material* materialInactive = new0 Material(); materialInactive->Emissive = Float4(0.0f, 0.0f, 0.0f, 1.0f); materialInactive->Ambient = Float4(0.75f, 0.75f, 0.75f, 1.0f); materialInactive->Diffuse = Float4(0.75f, 0.75f, 0.75f, 1.0f); materialInactive->Specular = Float4(0.0f, 0.0f, 0.0f, 1.0f); Light* light = new0 Light(Light::LT_AMBIENT); light->Ambient = Float4(1.0f, 1.0f, 1.0f, 1.0f); light->Diffuse = Float4(1.0f, 1.0f, 1.0f, 1.0f); light->Specular = Float4(0.0f, 0.0f, 0.0f, 1.0f); LightAmbEffect* effect = new0 LightAmbEffect(); mControlActive = effect->CreateInstance(light, materialActive); mControlInactive = effect->CreateInstance(light, materialInactive); for (int i0 = 0; i0 < mQuantity; ++i0) { for (int i1 = 0; i1 < mQuantity; ++i1) { for (int i2 = 0; i2 < mQuantity; ++i2) { TriMesh* box = new0 TriMesh(vformat, vbuffer, ibuffer); Vector3f ctrl = mVolume->GetControlPoint(i0, i1, i2); box->LocalTransform.SetTranslate(ctrl); // Encode the indices in the name for later use. This will // allow fast lookup of volume control points. char name[32]; sprintf(name, "%d %d %d", i0, i1, i2); box->SetName(name); box->SetEffectInstance(mControlInactive); mControlRoot->AttachChild(box); } } } }
//---------------------------------------------------------------------------- void IntersectConvexPolyhedra::ComputeIntersection () { // Transform the model-space vertices to world space. VertexBufferAccessor vba(mMeshPoly0); int i; for (i = 0; i < vba.GetNumVertices(); ++i) { APoint modPos = vba.Position<Float3>(i); APoint locPos = mMeshPoly0->LocalTransform*modPos; mWorldPoly0.Point(i) = Vector3f(locPos[0], locPos[1], locPos[2]); } mWorldPoly0.UpdatePlanes(); vba.ApplyTo(mMeshPoly1); for (i = 0; i < vba.GetNumVertices(); ++i) { APoint modPos = vba.Position<Float3>(i); APoint locPos = mMeshPoly1->LocalTransform*modPos; mWorldPoly1.Point(i) = Vector3f(locPos[0], locPos[1], locPos[2]); } mWorldPoly1.UpdatePlanes(); // Compute the intersection (if any) in world space. bool hasIntersection = mWorldPoly0.FindIntersection(mWorldPoly1, mIntersection); if (hasIntersection) { // Build the corresponding mesh. int numVertices = mIntersection.GetNumVertices(); int numTriangles = mIntersection.GetNumTriangles(); int numIndices = 3*numTriangles; VertexFormat* vformat = mMeshPoly0->GetVertexFormat(); int vstride = vformat->GetStride(); VertexBuffer* vbuffer = new0 VertexBuffer(numVertices, vstride); IndexBuffer* ibuffer = new0 IndexBuffer(numIndices, sizeof(int)); Float3 green(0.0f, 1.0f, 0.0f); vba.ApplyTo(vformat, vbuffer); for (i = 0; i < numVertices; ++i) { vba.Position<Vector3f>(i) = mIntersection.Point(i); vba.Color<Float3>(0, i) = green; } int* indices = (int*)ibuffer->GetData(); for (i = 0; i < numTriangles; ++i) { const MTTriangle& triangle = mIntersection.GetTriangle(i); for (int j = 0; j < 3; ++j) { indices[3*i + j] = mIntersection.GetVLabel(triangle.GetVertex(j)); } } mMeshIntersection = new0 TriMesh(vformat, vbuffer, ibuffer); mMeshIntersection->SetEffectInstance( VertexColor3Effect::CreateUniqueInstance()); mScene->SetChild(0, mMeshIntersection); mMeshIntersection->Culling = Spatial::CULL_DYNAMIC; } else { mMeshIntersection->Culling = Spatial::CULL_ALWAYS; } }
//---------------------------------------------------------------------------- void Skinning::CreateScene () { mScene = new0 Node(); mTrnNode = new0 Node(); mScene->AttachChild(mTrnNode); // The skinned object is a cylinder. const int radialSamples = 10; const int axisSamples = 7; const float radius = 10.0f; const float height = 80.0f; const float invRS = 1.0f/(float)radialSamples; const float invASm1 = 1.0f/(float)(axisSamples - 1); const float halfHeight = 0.5f*height; const APoint center(0.0f, 0.0f, 100.0f); const AVector u(0.0f,0.0f,-1.0f); const AVector v(0.0f,1.0f,0.0f); const AVector axis(1.0f,0.0f,0.0f); // Generate geometry. VertexFormat* vformat = VertexFormat::Create(3, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT4, 0); int vstride = vformat->GetStride(); const int numVertices = axisSamples*(radialSamples + 1); VertexBuffer* vbuffer = new0 VertexBuffer(numVertices, vstride); VertexBufferAccessor vba(vformat, vbuffer); // Generate points on the unit circle to be used in computing the mesh // points on a cylinder slice. int r, a, aStart, i; float* sn = new1<float>(radialSamples + 1); float* cs = new1<float>(radialSamples + 1); for (r = 0; r < radialSamples; ++r) { float angle = Mathf::TWO_PI*invRS*r; cs[r] = Mathf::Cos(angle); sn[r] = Mathf::Sin(angle); } sn[radialSamples] = sn[0]; cs[radialSamples] = cs[0]; // Generate the cylinder itself. for (a = 0, i = 0; a < axisSamples; ++a, ++i) { float axisFraction = a*invASm1; // in [0,1] float z = -halfHeight + height*axisFraction; // Compute center of slice. APoint sliceCenter = center + z*axis; // Compute slice vertices with duplication at end point. Float3 color(axisFraction, 1.0f - axisFraction, 0.3f); Float4 tcoord; int save = i; for (r = 0; r < radialSamples; ++r, ++i) { AVector normal = cs[r]*u + sn[r]*v; vba.Position<Float3>(i) = sliceCenter + radius*normal; vba.Color<Float3>(0,i) = color; vba.TCoord<Float4>(0, i) = ComputeWeights(a); } vba.Position<Float3>(i) = vba.Position<Float3>(save); vba.Color<Float3>(0, i) = color; vba.TCoord<Float4>(0, i) = ComputeWeights(a); } // Generate connectivity. int numTriangles = 2*(axisSamples - 1)*radialSamples; int numIndices = 3*numTriangles; IndexBuffer* ibuffer = new0 IndexBuffer(numIndices, sizeof(int)); int* indices = (int*)ibuffer->GetData(); for (a = 0, aStart = 0; a < axisSamples - 1; ++a) { int i0 = aStart; int i1 = i0 + 1; aStart += radialSamples + 1; int i2 = aStart; int i3 = i2 + 1; for (i = 0; i < radialSamples; ++i, indices += 6) { indices[0] = i0++; indices[1] = i1; indices[2] = i2; indices[3] = i1++; indices[4] = i3++; indices[5] = i2++; } } delete1(cs); delete1(sn); TriMesh* mesh = new0 TriMesh(vformat, vbuffer, ibuffer); mTrnNode->AttachChild(mesh); std::string effectFile = Environment::GetPathR("Skinning.wmfx"); SkinningEffect* effect = new0 SkinningEffect(effectFile); ShaderFloat* skinningMatrix[4] = { new0 ShaderFloat(4), new0 ShaderFloat(4), new0 ShaderFloat(4), new0 ShaderFloat(4) }; for (i = 0; i < 4; ++i) { mSkinningMatrix[i] = skinningMatrix[i]->GetData(); } mesh->SetEffectInstance(effect->CreateInstance(skinningMatrix)); }
//---------------------------------------------------------------------------- void CubeMaps::CreateScene () { // Create the root of the scene. mScene = new0 Node(); mWireState = new0 WireState(); mRenderer->SetOverrideWireState(mWireState); // Create the walls of the cube room. Each of the six texture images is // RGBA 64-by-64. Node* room = new0 Node(); mScene->AttachChild(room); // Index buffer shared by the room walls. IndexBuffer* ibuffer = new0 IndexBuffer(6, sizeof(int)); int* indices = (int*)ibuffer->GetData(); indices[0] = 0; indices[1] = 1; indices[2] = 3; indices[3] = 0; indices[4] = 3; indices[5] = 2; // The vertex format shared by the room walls. VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0); int vstride = vformat->GetStride(); VertexBufferAccessor vba; // The texture effect shared by the room walls. Texture2DEffect* effect = new0 Texture2DEffect(Shader::SF_LINEAR); VertexBuffer* vbuffer; TriMesh* wall; std::string textureName; // +x wall vbuffer = new0 VertexBuffer(4, vstride); vba.ApplyTo(vformat, vbuffer); vba.Position<Float3>(0) = Float3(+1.0f, -1.0f, -1.0f); vba.Position<Float3>(1) = Float3(+1.0f, -1.0f, +1.0f); vba.Position<Float3>(2) = Float3(+1.0f, +1.0f, -1.0f); vba.Position<Float3>(3) = Float3(+1.0f, +1.0f, +1.0f); vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f); vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f); vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f); vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f); wall = new0 TriMesh(vformat, vbuffer, ibuffer); room->AttachChild(wall); textureName = Environment::GetPathR("XpFace.wmtf"); Texture2D* xpTexture = Texture2D::LoadWMTF(textureName); wall->SetEffectInstance(effect->CreateInstance(xpTexture)); // -x wall vbuffer = new0 VertexBuffer(4, vstride); vba.ApplyTo(vformat, vbuffer); vba.Position<Float3>(0) = Float3(-1.0f, -1.0f, +1.0f); vba.Position<Float3>(1) = Float3(-1.0f, -1.0f, -1.0f); vba.Position<Float3>(2) = Float3(-1.0f, +1.0f, +1.0f); vba.Position<Float3>(3) = Float3(-1.0f, +1.0f, -1.0f); vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f); vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f); vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f); vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f); wall = new0 TriMesh(vformat, vbuffer, ibuffer); room->AttachChild(wall); textureName = Environment::GetPathR("XmFace.wmtf"); Texture2D* xmTexture = Texture2D::LoadWMTF(textureName); wall->SetEffectInstance(effect->CreateInstance(xmTexture)); // +y wall vbuffer = new0 VertexBuffer(4, vstride); vba.ApplyTo(vformat, vbuffer); vba.Position<Float3>(0) = Float3(+1.0f, +1.0f, +1.0f); vba.Position<Float3>(1) = Float3(-1.0f, +1.0f, +1.0f); vba.Position<Float3>(2) = Float3(+1.0f, +1.0f, -1.0f); vba.Position<Float3>(3) = Float3(-1.0f, +1.0f, -1.0f); vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f); vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f); vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f); vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f); wall = new0 TriMesh(vformat, vbuffer, ibuffer); room->AttachChild(wall); textureName = Environment::GetPathR("YpFace.wmtf"); Texture2D* ypTexture = Texture2D::LoadWMTF(textureName); wall->SetEffectInstance(effect->CreateInstance(ypTexture)); // -y wall vbuffer = new0 VertexBuffer(4, vstride); vba.ApplyTo(vformat, vbuffer); vba.Position<Float3>(0) = Float3(+1.0f, -1.0f, -1.0f); vba.Position<Float3>(1) = Float3(-1.0f, -1.0f, -1.0f); vba.Position<Float3>(2) = Float3(+1.0f, -1.0f, +1.0f); vba.Position<Float3>(3) = Float3(-1.0f, -1.0f, +1.0f); vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f); vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f); vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f); vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f); wall = new0 TriMesh(vformat, vbuffer, ibuffer); room->AttachChild(wall); textureName = Environment::GetPathR("YmFace.wmtf"); Texture2D* ymTexture = Texture2D::LoadWMTF(textureName); wall->SetEffectInstance(effect->CreateInstance(ymTexture)); // +z wall vbuffer = new0 VertexBuffer(4, vstride); vba.ApplyTo(vformat, vbuffer); vba.Position<Float3>(0) = Float3(+1.0f, -1.0f, +1.0f); vba.Position<Float3>(1) = Float3(-1.0f, -1.0f, +1.0f); vba.Position<Float3>(2) = Float3(+1.0f, +1.0f, +1.0f); vba.Position<Float3>(3) = Float3(-1.0f, +1.0f, +1.0f); vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f); vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f); vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f); vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f); wall = new0 TriMesh(vformat, vbuffer, ibuffer); room->AttachChild(wall); textureName = Environment::GetPathR("ZpFace.wmtf"); Texture2D* zpTexture = Texture2D::LoadWMTF(textureName); wall->SetEffectInstance(effect->CreateInstance(zpTexture)); // -z wall vbuffer = new0 VertexBuffer(4, vstride); vba.ApplyTo(vformat, vbuffer); vba.Position<Float3>(0) = Float3(-1.0f, -1.0f, -1.0f); vba.Position<Float3>(1) = Float3(+1.0f, -1.0f, -1.0f); vba.Position<Float3>(2) = Float3(-1.0f, +1.0f, -1.0f); vba.Position<Float3>(3) = Float3(+1.0f, +1.0f, -1.0f); vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f); vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f); vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f); vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f); wall = new0 TriMesh(vformat, vbuffer, ibuffer); room->AttachChild(wall); textureName = Environment::GetPathR("ZmFace.wmtf"); Texture2D* zmTexture = Texture2D::LoadWMTF(textureName); wall->SetEffectInstance(effect->CreateInstance(zmTexture)); // A sphere to reflect the environment via a cube map. The colors will // be used to modulate the cube map texture. vformat = VertexFormat::Create(3, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_NORMAL, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0); vstride = vformat->GetStride(); mSphere = StandardMesh(vformat).Sphere(64, 64, 0.125f); room->AttachChild(mSphere); // Generate random vertex colors for the sphere. The StandardMesh class // produces a sphere with duplicated vertices along a longitude line. // This allows texture coordinates to be assigned in a manner that treats // the sphere as if it were a rectangle mesh. For vertex colors, we want // the duplicated vertices to have the same color, so a hash table is used // to look up vertex colors for the duplicates. vba.ApplyTo(mSphere); std::map<Float3,Float3> dataMap; for (int i = 0; i < vba.GetNumVertices(); ++i) { Float3& position = vba.Position<Float3>(i); Float3& color = vba.Color<Float3>(0, i); std::map<Float3,Float3>::iterator iter = dataMap.find(position); if (iter != dataMap.end()) { color = iter->second; } else { color[0] = 0.0f; color[1] = Mathf::IntervalRandom(0.5f, 0.75f); color[2] = Mathf::IntervalRandom(0.75f, 1.0f); dataMap.insert(std::make_pair(position, color)); } } // Create the cube map and attach it to the sphere. std::string effectFile = Environment::GetPathR("CubeMap.wmfx"); CubeMapEffect* cubeMapEffect = new0 CubeMapEffect(effectFile); ShaderFloat* reflectivity = new0 ShaderFloat(1); (*reflectivity)[0] = 0.5f; std::string cubeName = Environment::GetPathR("CubeMap.wmtf"); TextureCube* cubeTexture = TextureCube::LoadWMTF(cubeName); cubeTexture->GenerateMipmaps(); mCubeMapInstance = cubeMapEffect->CreateInstance(cubeTexture, reflectivity, false); mSphere->SetEffectInstance(mCubeMapInstance); // Allow culling to be disabled on the sphere so when you move inside // the sphere, you can see the previously hidden facets and verify that // the cube image for those facets is correctly oriented. mSphereCullState = cubeMapEffect->GetCullState(0, 0); }
//============================================================ // <T>加载资源。</T> // // @param pResource 资源对象 //============================================================ TResult FModel3dGeometry::LoadResource(FRs3dGeometry* pResource){ MO_CHECK(pResource, return ENull); _pResource = pResource; FRenderDevice* pRenderDevice = RDeviceManager::Instance().Find<FRenderDevice>(); //............................................................ FRenderableGeometry* pRenderableGeometry = FRenderableGeometry::InstanceCreate(); SetGeometry(pRenderableGeometry); //............................................................ // 获得顶点数据 FRs3dVertexBuffer* pRsVertexBuffer = pResource->VertexBuffer(); TInt vertexCount = pRsVertexBuffer->Count(); TInt vertexStride = pRsVertexBuffer->Stride(); FBytes* pVertexData = pRsVertexBuffer->Data(); // 创建顶点缓冲 FRenderVertexBuffer* pVertexBuffer = pRenderDevice->CreateVertexBuffer(); pVertexBuffer->SetOwner(this); pVertexBuffer->SetCount(vertexCount); pVertexBuffer->SetStride(vertexStride); pVertexBuffer->Setup(); pVertexBuffer->BuildData(); pVertexBuffer->Upload(pVertexData->MemoryC(), pVertexData->Length()); pVertexBuffer->DataStream()->Assign(pVertexData->MemoryC(), pVertexData->Length()); // 创建流集合 GRs3dVertexStreamPtrs& rsVertexStreams = pRsVertexBuffer->Streams(); TInt vertexStreamCount = rsVertexStreams.Count();
//-------------------------------------------------------------------------------------------------------------------------------------- Emitter::Emitter(const vector3f& pos, const vector3f& posNoise, const vector3f& dir, const vector3f& acce, const vector2f& speedPmill, float endspeed, const vector3f& angle, const Color& begin1, const Color& begin2, const Color& end1, const Color& end2, const vector2f& clrpow, const vector2d& life, const vector2f& alphaPow, const vector2f& sizebegin, const vector2f& sizeend, const vector2f& sizepow, const vector2d& countSec, const int emitterlife, std::string texName) :ISceneNode( ISceneNode::RS_TRANSPARENT ), LocatableObject( this ), m_PositionNoise(posNoise), m_Speed(speedPmill), m_Direction(dir), m_Acceleration(acce), m_Angle(angle), m_BeginColorA(begin1), m_BeginColorB(begin2), m_EndColorA(end1), m_EndColorB(end2), m_LifeSpan(life), m_BeginSize(sizebegin), m_EndSize(sizeend), m_CountSec(countSec), m_uTimeSpan(0), m_uLifedTime(0), m_ActiveTime(0), m_EmitterLife(emitterlife), m_isEmit(true), m_isForceStop(false), m_isInview(false), m_ColorPow(clrpow), m_AlphaPow(alphaPow), m_SizePow(sizepow), m_EndSpeed(endspeed), m_fResistance(((endspeed / speedPmill.m_y) - 1.0f )/static_cast<float>(life.m_y)) { SetLocalPosition( pos ); m_Direction.NormalizeSelf(); float maxlife = Math::GetMax(life.m_x, life.m_y); float maxcount = Math::GetMax(countSec.m_x, countSec.m_y); //int maxParticle = static_cast<int>( ( ceil(TO_SEC( maxlife )) ) * maxcount ); int maxParticle = 0; if ( -1 != emitterlife ) { maxParticle = static_cast<int>( ( TO_SEC( emitterlife ) ) * ( TO_SEC( maxlife ) ) * maxcount ); } else { maxParticle = static_cast<int>( ( TO_SEC( maxlife ) ) * maxcount ); } m_ArraySize = maxParticle; m_Index.SetMax(maxParticle); m_pParticle = NEW Particle_ColorSizeForce[maxParticle+1];//此处分配的时候一定要多分配一个,防止glEnableVertexAttribArray越界访问,造成堆栈损坏 m_pRendBuffer = NEW RendBuffer( Device::RM_POINTS ); m_pVertexBuffer = NEW VertexBuffer( Device::MU_DYNAMIC ); m_pRendBuffer->SetVertexBuffer( m_pVertexBuffer ); m_pVertexBuffer->FlushVertexBuffer( m_ArraySize, &m_pParticle[0] ); //ushort* indies = NEW ushort[maxParticle]; //for ( int i = 0;i < maxParticle ; i ++ ) //{ // indies[i] = i; //} //m_pRendBuffer->MakeIndiesBuffer(indies, maxParticle, Device::MU_STATIC); //SAFE_DELETE_ARRAY(indies); //m_Tex = NEW Texture2D(); //m_Tex->LoadTexture( Device::PF_A8, texName); m_isBeginChangeColor = m_BeginColorA == m_BeginColorB ? false : true; m_isEndChangeColor = m_EndColorA == m_EndColorB ? false : true; //材质 m_pMaterial = NEW Material; m_pMaterial->SetNode( this ); m_pMaterial->SetShader( Pipeline::PT_LIGHTING, ShaderManage::ParticleShader ); m_pMaterial->LoadTexture( Material::ATT_TEX_DIFFUSE, Device::PF_R8G8B8A8, texName ); m_pMaterial->GetDrawState( Pipeline::PT_LIGHTING ).m_isDepthMask = false; m_pMaterial->GetAlpahState( Pipeline::PT_LIGHTING ).m_isAlphaEnable = true; //计算绑定盒子 //由于喷射角度关系,绑定盒子很难精确计算,将采用随机测试的方法在编辑器中输出 }
//---------------------------------------------------------------------------- RigidTetra::RigidTetra (float size, float mass, const Vector3f& position, const Vector3f& linearMomentum, const Vector3f& angularMomentum) : Moved(false) { Moved = false; 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(4, vstride); VertexBufferAccessor vba(vformat, vbuffer); vba.Position<Vector3f>(0) = -(size/3.0f)*Vector3f(1.0f, 1.0f, 1.0f); vba.Position<Vector3f>(1) = Vector3f(size, 0.0f, 0.0f); vba.Position<Vector3f>(2) = Vector3f(0.0f, size, 0.0f); vba.Position<Vector3f>(3) = Vector3f(0.0f, 0.0f, size); vba.Color<Float3>(0, 0) = Float3(1.0f, 1.0f, 1.0f); vba.Color<Float3>(0, 1) = Float3(1.0f, 0.0f, 0.0f); vba.Color<Float3>(0, 2) = Float3(0.0f, 1.0f, 0.0f); vba.Color<Float3>(0, 3) = Float3(0.0f, 0.0f, 1.0f); IndexBuffer* ibuffer = new0 IndexBuffer(12, sizeof(int)); int* indices = (int*)ibuffer->GetData(); indices[ 0] = 0; indices[ 1] = 2; indices[ 2] = 1; indices[ 3] = 0; indices[ 4] = 3; indices[ 5] = 2; indices[ 6] = 0; indices[ 7] = 1; indices[ 8] = 3; indices[ 9] = 1; indices[10] = 2; indices[11] = 3; mMesh = new0 TriMesh(vformat, vbuffer, ibuffer); mMesh->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance()); // Compute the inertia tensor. Matrix3f inertia; int j; for (int i = 0; i < 3; ++i) { inertia[i][i] = 0.0f; for (j = 0; j < 3; ++j) { if (i != j) { inertia[i][j] = 0.0f; for (int k = 0; k < 4; ++k) { Vector3f pos = vba.Position<Vector3f>(k); inertia[i][i] += 0.25f*mass*pos[j]*pos[j]; inertia[i][j] -= 0.25f*mass*pos[i]*pos[j]; } } } } // Compute the radius of a sphere bounding the tetrahedron. Vector3f centroid = (size/6.0f)*Vector3f(1.0f, 1.0f, 1.0f); mRadius = 0.0f; for (j = 0; j < 4; ++j) { vba.Position<Vector3f>(j) -= centroid; float temp = (vba.Position<Vector3f>(j) - centroid).Length(); if (temp > mRadius) { mRadius = temp; } } SetMass(mass); SetBodyInertia(inertia); SetPosition(position); SetQOrientation(Quaternionf::IDENTITY); SetLinearMomentum(linearMomentum); SetAngularMomentum(angularMomentum); }
//---------------------------------------------------------------------------- void ParticleSystems::CreateScene () { mScene = new0 Node(); mWireState = new0 WireState(); mRenderer->SetOverrideWireState(mWireState); VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0); int vstride = vformat->GetStride(); const int numParticles = 32; VertexBuffer* vbuffer = new0 VertexBuffer(4*numParticles, vstride); Float4* positionSizes = new1<Float4>(numParticles); for (int i = 0; i < numParticles; ++i) { positionSizes[i][0] = Mathf::SymmetricRandom(); positionSizes[i][1] = Mathf::SymmetricRandom(); positionSizes[i][2] = Mathf::SymmetricRandom(); positionSizes[i][3] = 0.25f*Mathf::UnitRandom(); } Particles* particles = new0 Particles(vformat, vbuffer, sizeof(int), positionSizes, 1.0f); particles->AttachController(new0 BloodCellController()); mScene->AttachChild(particles); // Create an image with transparency. const int xsize = 32, ysize = 32; Texture2D* texture = new0 Texture2D(Texture::TF_A8R8G8B8, xsize, ysize, 1); unsigned char* data = (unsigned char*)texture->GetData(0); float factor = 1.0f/(xsize*xsize + ysize*ysize); for (int y = 0, i = 0; y < ysize; ++y) { for (int x = 0; x < xsize; ++x) { // The image is red. data[i++] = 0; data[i++] = 0; data[i++] = 255; // Semitransparent within a disk, dropping off to zero outside the // disk. int dx = 2*x - xsize; int dy = 2*y - ysize; float value = factor*(dx*dx + dy*dy); if (value < 0.125f) { value = Mathf::Cos(4.0f*Mathf::PI*value); } else { value = 0.0f; } data[i++] = (unsigned char)(255.0f*value); } } Texture2DEffect* effect = new0 Texture2DEffect(Shader::SF_LINEAR); effect->GetAlphaState(0, 0)->BlendEnabled = true; effect->GetDepthState(0, 0)->Enabled = false; particles->SetEffectInstance(effect->CreateInstance(texture)); }
//---------------------------------------------------------------------------- TriMesh* SkinnedBiped::GetMesh (const std::string& name, Node* biped) { // Load the triangle indices and material. std::string filename = name + ".triangle.raw"; std::string path = Environment::GetPathR(filename); FileIO inFile(path, FileIO::FM_DEFAULT_READ); int numTriangles; inFile.Read(sizeof(int), &numTriangles); int numIndices = 3*numTriangles; IndexBuffer* ibuffer = new0 IndexBuffer(numIndices, sizeof(int)); int* indices = (int*)ibuffer->GetData(); inFile.Read(sizeof(int), numIndices, indices); Material* material = new0 Material(); Float4 emissive, ambient, diffuse, specular; inFile.Read(sizeof(float), 3, &material->Emissive); material->Emissive[3] = 1.0f; inFile.Read(sizeof(float), 3, &material->Ambient); material->Ambient[3] = 1.0f; inFile.Read(sizeof(float), 3, &material->Diffuse); material->Diffuse[3] = 1.0f; inFile.Read(sizeof(float), 3, &material->Specular); material->Specular[3] = 0.0f; inFile.Close(); // Load the skin controller. filename = name + ".skin.raw"; path = Environment::GetPathR(filename); inFile.Open(path, FileIO::FM_DEFAULT_READ); int repeat; float minTime, maxTime, phase, frequency; inFile.Read(sizeof(float), &repeat); inFile.Read(sizeof(float), &minTime); inFile.Read(sizeof(float), &maxTime); inFile.Read(sizeof(float), &phase); inFile.Read(sizeof(float), &frequency); int numVertices, numBones; inFile.Read(sizeof(int), &numVertices); inFile.Read(sizeof(int), &numBones); SkinController* ctrl = new0 SkinController(numVertices, numBones); ctrl->Repeat = (Controller::RepeatType)repeat; ctrl->MinTime = (double)minTime; ctrl->MaxTime = (double)maxTime; ctrl->Phase = (double)phase; ctrl->Frequency = (double)frequency; Node** bones = ctrl->GetBones(); int i; for (i = 0; i < numBones; ++i) { int length; inFile.Read(sizeof(int), &length); char* boneName = new1<char>(length + 1); inFile.Read(sizeof(char), length, boneName); boneName[length] = 0; bones[i] = (Node*)biped->GetObjectByName(boneName); assertion(bones[i] != 0, "Failed to find bone.\n"); delete1(boneName); } float** weights = ctrl->GetWeights(); APoint** offsets = ctrl->GetOffsets(); for (int j = 0; j < numVertices; ++j) { for (i = 0; i < numBones; ++i) { inFile.Read(sizeof(float), &weights[j][i]); inFile.Read(sizeof(float), 3, &offsets[j][i]); } } inFile.Close(); int vstride = mVFormat->GetStride(); VertexBuffer* vbuffer = new0 VertexBuffer(numVertices, vstride); // Set positions and normals to zero for now. The controller update // will set the initial values. memset(vbuffer->GetData(), 0, numVertices*vstride); TriMesh* mesh = new0 TriMesh(mVFormat, vbuffer, ibuffer); mesh->SetName(name); mesh->AttachController(ctrl); mesh->SetEffectInstance(LightDirPerVerEffect::CreateUniqueInstance( mLight, material)); return mesh; }
//---------------------------------------------------------------------------- void RenderToTexture::CreateScene () { // Create the root of the scene. mScene = new0 Node(); mTrnNode = new0 Node(); mScene->AttachChild(mTrnNode); mWireState = new0 WireState(); mRenderer->SetOverrideWireState(mWireState); // Create a screen-space camera to use with the render target. mScreenCamera = ScreenTarget::CreateCamera(); // Create a screen polygon to use with the render target. VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0); const int rtWidth = 256, rtHeight = 256; mScreenPolygon = ScreenTarget::CreateRectangle(vformat, rtWidth, rtHeight, 0.0f, 0.2f, 0.0f, 0.2f, 0.0f); // Create the render target. //Texture::Format tformat = Texture::TF_A8B8G8R8; // DX9 fails Texture::Format tformat = Texture::TF_A8R8G8B8; //Texture::Format tformat = Texture::TF_A16B16G16R16; //Texture::Format tformat = Texture::TF_A16B16G16R16F; //Texture::Format tformat = Texture::TF_A32B32G32R32F; mRenderTarget = new0 RenderTarget(1, tformat, rtWidth, rtHeight, false, false); // Attach the render target texture to the screen polygon mesh. mScreenPolygon->SetEffectInstance(Texture2DEffect::CreateUniqueInstance( mRenderTarget->GetColorTexture(0), Shader::SF_LINEAR, Shader::SC_CLAMP_EDGE, Shader::SC_CLAMP_EDGE)); // Load the face model and use multitexturing. #ifdef WM5_LITTLE_ENDIAN std::string path = Environment::GetPathR("FacePN.wmof"); #else std::string path = Environment::GetPathR("FacePN.be.wmof"); #endif InStream inStream; inStream.Load(path); TriMeshPtr mesh = DynamicCast<TriMesh>(inStream.GetObjectAt(0)); // Create texture coordinates for the face. Based on knowledge of the // mesh, the (x,z) values of the model-space vertices may be mapped to // (s,t) in [0,1]^2. VertexBufferAccessor vba0(mesh); const int numVertices = vba0.GetNumVertices(); float xmin = Mathf::MAX_REAL, xmax = -Mathf::MAX_REAL; float zmin = Mathf::MAX_REAL, zmax = -Mathf::MAX_REAL; int i; for (i = 1; i < numVertices; ++i) { Float3 position = vba0.Position<Float3>(i); float x = position[0]; if (x < xmin) { xmin = x; } if (x > xmax) { xmax = x; } float z = position[2]; if (z < zmin) { zmin = z; } if (z > zmax) { zmax = z; } } float invXRange = 1.0f/(xmax - xmin); float invZRange = 1.0f/(zmax - zmin); // Strip out the normal vectors, because there is no lighting in this // sample. Add in two texture coordinate channels for a multiplicative // texture effect. vformat = VertexFormat::Create(3, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0, VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 1); int vstride = vformat->GetStride(); VertexBuffer* vbuffer = new0 VertexBuffer(numVertices, vstride); VertexBufferAccessor vba1(vformat, vbuffer); for (i = 0; i < numVertices; ++i) { Float3 position = vba0.Position<Float3>(i); Float2 tcoord( (position[0] - xmin)*invXRange, (position[2] - zmin)*invZRange); vba1.Position<Float3>(i) = position; vba1.TCoord<Float2>(0, i) = tcoord; vba1.TCoord<Float2>(1, i) = tcoord; } mesh->SetVertexFormat(vformat); mesh->SetVertexBuffer(vbuffer); path = Environment::GetPathR("Leaf.wmtf"); Texture2D* texture0 = Texture2D::LoadWMTF(path); path = Environment::GetPathR("Water.wmtf"); Texture2D* texture1 = Texture2D::LoadWMTF(path); VisualEffectInstance* instance = Texture2AddEffect::CreateUniqueInstance( texture0, Shader::SF_LINEAR, Shader::SC_CLAMP_EDGE, Shader::SC_CLAMP_EDGE, texture1, Shader::SF_LINEAR, Shader::SC_CLAMP_EDGE, Shader::SC_CLAMP_EDGE); mesh->SetEffectInstance(instance); mTrnNode->AttachChild(mesh); }
//---------------------------------------------------------------------------- void IntersectInfiniteCylinders::CreateScene () { mScene = new0 Node(); 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(); StandardMesh sm(vformat); VertexBufferAccessor vba; int i; // Create the canonical cylinder. mCylinder0 = sm.Cylinder(32, 128, mRadius0, mHeight, true); mScene->AttachChild(mCylinder0); mVisible.Insert(mCylinder0); vba.ApplyTo(mCylinder0); for (i = 0; i < vba.GetNumVertices(); ++i) { vba.Color<Float3>(0, i) = Float3(0.5f, 0.0f, 0.0f); } mCylinder0->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance()); // Create the other cylinder. mCylinder1 = sm.Cylinder(32, 128, mRadius1, mHeight, true); mScene->AttachChild(mCylinder1); mVisible.Insert(mCylinder1); vba.ApplyTo(mCylinder1); for (i = 0; i < vba.GetNumVertices(); ++i) { vba.Color<Float3>(0, i) = Float3(0.0f, 0.0f, 0.5f); } mCylinder1->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance()); mCylinder1->LocalTransform.SetRotate(HMatrix(AVector::UNIT_X, -mAngle)); mCylinder1->LocalTransform.SetTranslate(APoint(mC0, 0.0f, 0.0f)); // Create the intersection curve. const float minTheta = 2.0f*Mathf::PI/3.0f; const float maxTheta = 4.0f*Mathf::PI/3.0f; float theta, cs, sn, t, tmp, discr; VertexBuffer* vbuffer = new0 VertexBuffer(1024, vstride); mCurve0 = new0 Polysegment(vformat, vbuffer, true); mScene->AttachChild(mCurve0); vba.ApplyTo(mCurve0); int numPoints = vba.GetNumVertices(); float multiplier = (maxTheta - minTheta)/(float)(numPoints - 1); for (i = 0; i < numPoints; ++i) { theta = minTheta + multiplier*i; cs = Mathf::Cos(theta); sn = Mathf::Sin(theta); tmp = mC0 + mRadius1*cs; discr = Mathf::FAbs(mRadius0*mRadius0 - tmp*tmp); t = (-mRadius1*mW2*sn - Mathf::Sqrt(discr))/mW1; Float3& position = vba.Position<Float3>(i); position[0] = mC0 + mRadius1*cs; position[1] = +mRadius1*sn*mW2 + t*mW1; position[2] = -mRadius1*sn*mW1 + t*mW2; vba.Color<Float3>(0, i) = Float3(0.0f, 0.5f, 0.0f); } mCurve0->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance()); mVisible.Insert(mCurve0); vbuffer = new0 VertexBuffer(1024, vstride); mCurve1 = new0 Polysegment(vformat, vbuffer, true); mScene->AttachChild(mCurve1); vba.ApplyTo(mCurve1); numPoints = vba.GetNumVertices(); multiplier = (maxTheta - minTheta)/(float)(numPoints - 1); for (i = 0; i < numPoints; ++i) { theta = minTheta + multiplier*i; cs = Mathf::Cos(theta); sn = Mathf::Sin(theta); tmp = mC0 + mRadius1*cs; discr = Mathf::FAbs(mRadius0*mRadius0 - tmp*tmp); t = (-mRadius1*mW2*sn + Mathf::Sqrt(discr))/mW1; Float3& position = vba.Position<Float3>(i); position[0] = mC0 + mRadius1*cs; position[1] = +mRadius1*sn*mW2 + t*mW1; position[2] = -mRadius1*sn*mW1 + t*mW2; vba.Color<Float3>(0, i) = Float3(0.0f, 0.5f, 0.0f); } mCurve1->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance()); mVisible.Insert(mCurve1); }
//---------------------------------------------------------------------------- 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); }
//---------------------------------------------------------------------------- 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 }
//---------------------------------------------------------------------------- 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 ClodMeshes::CreateScene () { mScene = new0 Node(); mTrnNode = new0 Node(); mScene->AttachChild(mTrnNode); mWireState = new0 WireState(); mRenderer->SetOverrideWireState(mWireState); // Load the face model. #ifdef WM5_LITTLE_ENDIAN std::string path = Environment::GetPathR("FacePN.wmof"); #else std::string path = Environment::GetPathR("FacePN.be.wmof"); #endif InStream inStream; inStream.Load(path); TriMeshPtr mesh = StaticCast<TriMesh>(inStream.GetObjectAt(0)); VertexBufferAccessor vba0(mesh); // Remove the normals and add texture coordinates. VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0); int vstride = vformat->GetStride(); VertexBuffer* vbuffer = new0 VertexBuffer(vba0.GetNumVertices(), vstride); VertexBufferAccessor vba1(vformat, vbuffer); float xmin = Mathf::MAX_REAL, xmax = -Mathf::MAX_REAL; float ymin = Mathf::MAX_REAL, ymax = -Mathf::MAX_REAL; int i; for (i = 0; i < vba0.GetNumVertices(); ++i) { Float3 position = vba0.Position<Float3>(i); vba1.Position<Float3>(i) = position; float x = position[0]; float y = position[2]; vba1.TCoord<Float2>(0, i) = Float2(x, y); if (x < xmin) { xmin = x; } if (x > xmax) { xmax = x; } if (y < ymin) { ymin = y; } if (y > ymax) { ymax = y; } } float xmult = 1.0f/(xmax - xmin); float ymult = 1.0f/(ymax - ymin); for (i = 0; i < vba1.GetNumVertices(); ++i) { Float2 tcoord = vba1.TCoord<Float2>(0, i); vba1.TCoord<Float2>(0,i) = Float2( (tcoord[0] - xmin)*xmult, (tcoord[1] - ymin)*ymult); } mesh->SetVertexFormat(vformat); mesh->SetVertexBuffer(vbuffer); // Create a texture for the face. Use the generated texture coordinates. Texture2DEffect* effect = new0 Texture2DEffect(Shader::SF_LINEAR); path = Environment::GetPathR("Magician.wmtf"); Texture2D* texture = Texture2D::LoadWMTF(path); #ifdef USE_CLOD_MESH // Create the collapse records to be shared by two CLOD meshes. int numRecords = 0; CollapseRecord* records = 0; CreateClodMesh ccm(mesh, numRecords, records); CollapseRecordArray* recordArray = new0 CollapseRecordArray(numRecords, records); mClod[0] = new0 ClodMesh(mesh, recordArray); mClod[0]->LocalTransform = mesh->LocalTransform; mClod[0]->LocalTransform.SetTranslate(mesh->LocalTransform.GetTranslate() - 150.0f*AVector::UNIT_X); mClod[0]->SetEffectInstance(effect->CreateInstance(texture)); mTrnNode->AttachChild(mClod[0]); mClod[1] = new0 ClodMesh(mesh, recordArray); mClod[1]->LocalTransform = mesh->LocalTransform; mClod[1]->LocalTransform.SetTranslate(mesh->LocalTransform.GetTranslate() + 150.0f*AVector::UNIT_X - 100.0f*AVector::UNIT_Y); mClod[1]->SetEffectInstance(effect->CreateInstance(texture)); mTrnNode->AttachChild(mClod[1]); mActive = mClod[0]; #else IndexBuffer* ibuffer = mesh->GetIndexBuffer(); TriMesh* face = new0 TriMesh(vformat, vbuffer,ibuffer); face->LocalTransform = mesh->LocalTransform; face->LocalTransform.SetTranslate(mesh->LocalTransform.GetTranslate() - 150.0f*AVector::UNIT_X); face->SetEffectInstance(effect->CreateInstance(texture)); mTrnNode->AttachChild(face); face = new0 TriMesh(vformat, vbuffer, ibuffer); face->LocalTransform = mesh->LocalTransform; face->LocalTransform.SetTranslate(mesh->LocalTransform.GetTranslate() + 150.0f*AVector::UNIT_X); face->SetEffectInstance(effect->CreateInstance(texture)); mTrnNode->AttachChild(face); #endif }
//---------------------------------------------------------------------------- TriMesh* Castle::LoadMeshPNT2 (const std::string& name) { // Get the vertex format. VertexFormat* vformat = VertexFormat::Create(4, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_NORMAL, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0, VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 1); int vstride = vformat->GetStride(); // Get the positions. std::string filename = Environment::GetPathR(name); std::ifstream inFile(filename.c_str()); int numPositions; Float3* positions; GetFloat3(inFile, numPositions, positions); // Get the normals. int numNormals; Float3* normals; GetFloat3(inFile, numNormals, normals); // Get the texture coordinates for unit 0. int numTCoords0; Float2* tcoords0; GetFloat2(inFile, numTCoords0, tcoords0); // Get the texture coordinates for unit 1. int numTCoords1; Float2* tcoords1; GetFloat2(inFile, numTCoords1, tcoords1); // Get the vertices and indices. int numTriangles; inFile >> numTriangles; VertexPNT2* vertices = new1<VertexPNT2>(3*numTriangles); std::vector<VertexPNT2> PNT2Array; std::map<VertexPNT2,int> PNT2Map; std::vector<int> indices; for (int t = 0; t < numTriangles; ++t) { for (int j = 0, k = 3*t; j < 3; ++j, ++k) { VertexPNT2& vertex = vertices[k]; inFile >> vertex.PIndex; inFile >> vertex.NIndex; inFile >> vertex.T0Index; inFile >> vertex.T1Index; std::map<VertexPNT2,int>::iterator miter = PNT2Map.find(vertex); int index; if (miter != PNT2Map.end()) { // Second or later time the vertex is encountered. index = miter->second; } else { // First time the vertex is encountered. index = (int)PNT2Array.size(); PNT2Map.insert(std::make_pair(vertex, index)); PNT2Array.push_back(vertex); } indices.push_back(index); } } inFile.close(); // Build the mesh. int numVertices = (int)PNT2Array.size(); VertexBuffer* vbuffer = new0 VertexBuffer(numVertices, vstride); VertexBufferAccessor vba(vformat, vbuffer); for (int i = 0; i < numVertices; ++i) { VertexPNT2& vertex = PNT2Array[i]; vba.Position<Float3>(i) = positions[vertex.PIndex]; vba.Normal<Float3>(i) = normals[vertex.NIndex]; vba.TCoord<Float2>(0, i) = tcoords0[vertex.T0Index]; vba.TCoord<Float2>(1, i) = tcoords1[vertex.T1Index]; } int numIndices = (int)indices.size(); IndexBuffer* ibuffer = new0 IndexBuffer(numIndices, sizeof(int)); memcpy(ibuffer->GetData(), &indices[0], numIndices*sizeof(int)); delete1(vertices); delete1(tcoords1); delete1(tcoords0); delete1(normals); delete1(positions); return new0 TriMesh(vformat, vbuffer, ibuffer); }
//---------------------------------------------------------------------------- void ConvexHull3D::CreateHull () { int numVertices = mLimitedQuantity; 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(numVertices, vstride); VertexBufferAccessor vba(vformat, vbuffer); int i; for (i = 0; i < numVertices; ++i) { vba.Position<Vector3f>(i) = mVertices[i]; vba.Color<Float3>(0, i) = mColors[i]; } RegenerateHull(); int numTriangles = 0; TriMesh* mesh = 0; switch (mHull->GetDimension()) { case 0: sprintf(mFooter, "point: v = %d, t = %d", numVertices, numTriangles); return; case 1: sprintf(mFooter, "linear: v = %d, t = %d", numVertices, numTriangles); return; case 2: { numTriangles = mHull->GetNumSimplices() - 2; const int* hullIndices = mHull->GetIndices(); IndexBuffer* ibuffer = new0 IndexBuffer(3*numTriangles, sizeof(int)); int* indices = (int*)ibuffer->GetData(); for (int t = 0, i0 = 1, i1 = 2; t < numTriangles; ++t, ++i0, ++i1) { *indices++ = hullIndices[0]; *indices++ = hullIndices[i0]; *indices++ = hullIndices[i1]; } mesh = new0 TriMesh(vformat, vbuffer, ibuffer); mesh->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance()); sprintf(mFooter, "planar: v = %d, t = %d", numVertices, numTriangles); break; } case 3: numTriangles = mHull->GetNumSimplices(); const int* hullIndices = mHull->GetIndices(); IndexBuffer* ibuffer = new0 IndexBuffer(3*numTriangles, sizeof(int)); int* indices = (int*)ibuffer->GetData(); memcpy(indices, hullIndices, 3*numTriangles*sizeof(int)); mesh = new0 TriMesh(vformat, vbuffer, ibuffer); mesh->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance()); sprintf(mFooter, "spatial: v = %d, t = %d", numVertices, numTriangles); break; } // Translate to center of mass. Vector3f center = mVertices[0]; for (i = 1; i < mLimitedQuantity; ++i) { center += mVertices[i]; } center /= (float)mLimitedQuantity; mesh->LocalTransform.SetTranslate(-center); mTrnNode->SetChild(0, mesh); for (i = 2; i < mLimitedQuantity + 2; ++i) { mTrnNode->SetChild(i, CreateSphere()); } TriMesh* sphere = StaticCast<TriMesh>(mTrnNode->GetChild(1)); sphere->LocalTransform.SetTranslate( mVertices[mLimitedQuantity - 1] - center); // Update the scene, center-and-fit to frustum. mScene->Update(); mTrnNode->LocalTransform.SetTranslate(-mScene->WorldBound.GetCenter()); APoint camPosition = APoint::ORIGIN - 2.5f*mScene->WorldBound.GetRadius()*mCamera->GetDVector(); mCamera->SetPosition(camPosition); mCuller.ComputeVisibleSet(mScene); }
//---------------------------------------------------------------------------- void GlossMaps::CreateScene () { mScene = new0 Node(); mTrnNode = new0 Node(); mScene->AttachChild(mTrnNode); // Create vertex and index buffers to be shared by two meshes. 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); int vstride = vformat->GetStride(); VertexBuffer* vbuffer = new0 VertexBuffer(4, vstride); VertexBufferAccessor vba(vformat, vbuffer); Float3 yVector(0.0f, 1.0f, 0.0f); vba.Position<Float3>(0) = Float3(-0.5f, 0.0f, -0.5f); vba.Position<Float3>(1) = Float3(-0.5f, 0.0f, 0.5f); vba.Position<Float3>(2) = Float3( 0.5f, 0.0f, 0.5f); vba.Position<Float3>(3) = Float3( 0.5f, 0.0f, -0.5f); vba.Normal<Float3>(0) = yVector; vba.Normal<Float3>(1) = yVector; vba.Normal<Float3>(2) = yVector; vba.Normal<Float3>(3) = yVector; vba.TCoord<Float2>(0, 0) = Float2(1.0f, 0.0f); vba.TCoord<Float2>(0, 1) = Float2(1.0f, 1.0f); vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f); vba.TCoord<Float2>(0, 3) = Float2(0.0f, 0.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; // The light and material are used by both the gloss and non-gloss // objects. Light* light = new0 Light(Light::LT_DIRECTIONAL); light->Ambient = Float4(0.1f, 0.1f, 0.1f, 1.0f); light->Diffuse = Float4(0.6f, 0.6f, 0.6f, 1.0f); light->Specular = Float4(1.0f, 1.0f, 1.0f, 1.0f); light->DVector = AVector(0.0f, -1.0f, 0.0f); Material* material = new0 Material(); material->Ambient = Float4(0.2f, 0.2f, 0.2f, 1.0f); material->Diffuse = Float4(0.7f, 0.7f, 0.7f, 1.0f); material->Specular = Float4(1.0f, 1.0f, 1.0f, 25.0f); // Create a non-gloss-mapped square. TriMesh* squareNoGloss = new0 TriMesh(vformat, vbuffer, ibuffer); squareNoGloss->LocalTransform.SetRotate(HMatrix(AVector::UNIT_X, -0.25f*Mathf::PI)); squareNoGloss->LocalTransform.SetTranslate(APoint(1.0f, -1.0f, 0.0f)); squareNoGloss->SetEffectInstance( LightDirPerVerEffect::CreateUniqueInstance(light, material)); mTrnNode->AttachChild(squareNoGloss); // Create a gloss-mapped square. TriMesh* squareGloss = new0 TriMesh(vformat, vbuffer, ibuffer); squareGloss->LocalTransform.SetRotate(HMatrix(AVector::UNIT_X, -0.25f*Mathf::PI)); squareGloss->LocalTransform.SetTranslate(APoint(-1.0f, -1.0f, 0.0f)); mTrnNode->AttachChild(squareGloss); std::string effectFile = Environment::GetPathR("GlossMap.wmfx"); GlossMapEffect* effect = new0 GlossMapEffect(effectFile); std::string baseName = Environment::GetPathR("Magic.wmtf"); Texture2D* baseTexture = Texture2D::LoadWMTF(baseName); squareGloss->SetEffectInstance(effect->CreateInstance(baseTexture, light, material)); }
//---------------------------------------------------------------------------- void ScreenPolygons::CreateScene () { // The screen camera is designed to map (x,y,z) in [0,1]^3 to (x',y,'z') // in [-1,1]^2 x [0,1]. mScreenCamera = new0 Camera(false); mScreenCamera->SetFrustum(0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f); mScreenCamera->SetFrame(APoint::ORIGIN, AVector::UNIT_Z, AVector::UNIT_Y, AVector::UNIT_X); // Load the biped just for some model to display. #ifdef WM5_LITTLE_ENDIAN std::string path = Environment::GetPathR("SkinnedBipedPN.wmof"); #else std::string path = Environment::GetPathR("SkinnedBipedPN.be.wmof"); #endif InStream source; source.Load(path); mScene = DynamicCast<Node>(source.GetObjectAt(0)); assertion(mScene != 0, "Error in biped stream.\n"); // The background is a textured screen polygon (z = 1). VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0); int vstride = vformat->GetStride(); VertexBuffer* vbuffer = new0 VertexBuffer(4, vstride); VertexBufferAccessor vba(vformat, vbuffer); vba.Position<Float3>(0) = Float3(0.0f, 0.0f, 1.0f); vba.Position<Float3>(1) = Float3(1.0f, 0.0f, 1.0f); vba.Position<Float3>(2) = Float3(1.0f, 1.0f, 1.0f); vba.Position<Float3>(3) = Float3(0.0f, 1.0f, 1.0f); vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f); vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f); vba.TCoord<Float2>(0, 2) = Float2(1.0f, 1.0f); vba.TCoord<Float2>(0, 3) = Float2(0.0f, 1.0f); IndexBuffer* ibuffer = new0 IndexBuffer(6, sizeof(int)); int* indices = (int*)ibuffer->GetData(); indices[0] = 0; indices[1] = 1; indices[2] = 2; indices[3] = 0; indices[4] = 2; indices[5] = 3; mBackPoly = new0 TriMesh(vformat, vbuffer, ibuffer); path = Environment::GetPathR("RedSky.wmtf"); Texture2DEffect* effect = new0 Texture2DEffect(Shader::SF_LINEAR); Texture2D* texture = Texture2D::LoadWMTF(path); mBackPoly->SetEffectInstance(effect->CreateInstance(texture)); // The middle polygon, which may be translated via '+' or '-'. vbuffer = new0 VertexBuffer(4, vstride); vba.ApplyTo(vformat, vbuffer); vba.Position<Float3>(0) = Float3(0.0f, 0.3f, 0.0f); vba.Position<Float3>(1) = Float3(1.0f, 0.3f, 0.0f); vba.Position<Float3>(2) = Float3(1.0f, 0.7f, 0.0f); vba.Position<Float3>(3) = Float3(0.0f, 0.7f, 0.0f); vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.3f); vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.3f); vba.TCoord<Float2>(0, 2) = Float2(1.0f, 0.7f); vba.TCoord<Float2>(0, 3) = Float2(0.0f, 0.7f); mMidPoly = new0 TriMesh(vformat, vbuffer, ibuffer); path = Environment::GetPathR("BallTexture.wmtf"); texture = Texture2D::LoadWMTF(path); mMidPoly->SetEffectInstance(effect->CreateInstance(texture)); mLinearZ = 1.0f; mDepthZ = 1.0f; mMidPoly->LocalTransform.SetTranslate(APoint(0.0f, 0.0f, mLinearZ)); // A portion of the foreground is a textured screen polygon (z = 0). vbuffer = new0 VertexBuffer(5, vstride); vba.ApplyTo(vformat, vbuffer); vba.Position<Float3>(0) = Float3(0.0f, 0.0f, 0.0f); vba.Position<Float3>(1) = Float3(0.5f, 0.0f, 0.0f); vba.Position<Float3>(2) = Float3(0.75f, 0.5f, 0.0f); vba.Position<Float3>(3) = Float3(0.5f, 0.75f, 0.0f); vba.Position<Float3>(4) = Float3(0.0f, 0.5f, 0.0f); vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f); vba.TCoord<Float2>(0, 1) = Float2(0.67f, 0.0f); vba.TCoord<Float2>(0, 2) = Float2(1.0f, 0.67f); vba.TCoord<Float2>(0, 3) = Float2(0.67f, 1.0f); vba.TCoord<Float2>(0, 4) = Float2(0.0f, 0.67f); ibuffer = new0 IndexBuffer(9, sizeof(int)); indices = (int*)ibuffer->GetData(); indices[0] = 0; indices[1] = 1; indices[2] = 2; indices[3] = 0; indices[4] = 2; indices[5] = 3; indices[6] = 0; indices[7] = 3; indices[8] = 4; mForePoly = new0 TriMesh(vformat, vbuffer, ibuffer); path = Environment::GetPathR("Flower.wmtf"); Texture2DEffect* foreEffect = new0 Texture2DEffect(Shader::SF_LINEAR); texture = Texture2D::LoadWMTF(path); mForePoly->SetEffectInstance(foreEffect->CreateInstance(texture)); // Make the foreground semitransparent. foreEffect->GetAlphaState(0, 0)->BlendEnabled = true; }
void vsDisplayList::AppendOp(vsDisplayList::op * o) { OpCode type = o->type; switch( type ) { case OpCode_SetColor: SetColor( o->data.GetColor() ); break; case OpCode_SetColors: SetColors( (vsColor*)o->data.p, o->data.GetUInt() ); break; case OpCode_SetColorsBuffer: SetColorsBuffer( (vsRenderBuffer*)o->data.p ); break; case OpCode_VertexArray: VertexArray( (vsVector3D *)o->data.p, o->data.GetUInt() ); break; case OpCode_NormalArray: NormalArray( (vsVector3D *)o->data.p, o->data.GetUInt() ); break; case OpCode_TexelArray: TexelArray( (vsVector2D *)o->data.p, o->data.GetUInt() ); break; case OpCode_ColorArray: ColorArray( (vsColor *)o->data.p, o->data.GetUInt() ); break; case OpCode_VertexBuffer: VertexBuffer( (vsRenderBuffer *)o->data.p ); break; case OpCode_TexelBuffer: TexelBuffer( (vsRenderBuffer *)o->data.p ); break; case OpCode_ColorBuffer: ColorBuffer( (vsRenderBuffer *)o->data.p ); break; case OpCode_BindBuffer: BindBuffer( (vsRenderBuffer *)o->data.p ); break; case OpCode_UnbindBuffer: UnbindBuffer( (vsRenderBuffer *)o->data.p ); break; case OpCode_ClearVertexArray: ClearVertexArray(); break; case OpCode_ClearNormalArray: ClearNormalArray(); break; case OpCode_ClearTexelArray: ClearTexelArray(); break; case OpCode_ClearColorArray: ClearColorArray(); break; case OpCode_ClearArrays: ClearArrays(); break; case OpCode_LineListArray: LineListArray( (int *)o->data.p, o->data.GetUInt() ); break; case OpCode_LineStripArray: LineStripArray( (int *)o->data.p, o->data.GetUInt() ); break; case OpCode_TriangleListArray: TriangleListArray( (int *)o->data.p, o->data.GetUInt() ); break; case OpCode_TriangleStripArray: TriangleStripArray( (int *)o->data.p, o->data.GetUInt() ); break; case OpCode_PointsArray: PointsArray( (int *)o->data.p, o->data.GetUInt() ); break; case OpCode_LineListBuffer: LineListBuffer( (vsRenderBuffer *)o->data.p ); break; case OpCode_LineStripBuffer: LineStripBuffer( (vsRenderBuffer *)o->data.p ); break; case OpCode_TriangleStripBuffer: TriangleStripBuffer( (vsRenderBuffer *)o->data.p ); break; case OpCode_TriangleFanArray: TriangleFanArray( (int *)o->data.p, o->data.GetUInt() ); break; case OpCode_PushTransform: PushTransform( o->data.GetTransform() ); break; case OpCode_SetCameraTransform: SetCameraTransform( o->data.GetTransform() ); break; case OpCode_SetMatrix4x4: SetMatrix4x4( o->data.GetMatrix4x4() ); break; case OpCode_PushMatrix4x4: PushMatrix4x4( o->data.GetMatrix4x4() ); break; case OpCode_SetMatrices4x4: SetMatrices4x4( (vsMatrix4x4*)o->data.p, o->data.i ); break; case OpCode_SetMatrices4x4Buffer: SetMatrices4x4Buffer( (vsRenderBuffer*)o->data.p ); break; case OpCode_SetWorldToViewMatrix4x4: SetWorldToViewMatrix4x4( o->data.GetMatrix4x4() ); break; case OpCode_Set3DProjection: Set3DProjection( o->data.fov, o->data.nearPlane, o->data.farPlane ); break; case OpCode_SetProjectionMatrix4x4: SetProjectionMatrix4x4( o->data.GetMatrix4x4() ); break; case OpCode_PopTransform: PopTransform(); break; case OpCode_EnableStencil: EnableStencil(); break; case OpCode_DisableStencil: DisableStencil(); break; case OpCode_EnableScissor: EnableScissor( o->data.GetBox2D() ); break; case OpCode_DisableScissor: DisableScissor(); break; case OpCode_ClearStencil: ClearStencil(); break; case OpCode_SetViewport: SetViewport( o->data.GetBox2D() ); break; case OpCode_ClearViewport: ClearViewport(); break; case OpCode_Debug: Debug( o->data.GetString() ); break; default: break; } }
//---------------------------------------------------------------------------- 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)); }
//---------------------------------------------------------------------------- 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(); }
//---------------------------------------------------------------------------- void WrigglingSnake::CreateSnakeHead () { VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0); int vstride = vformat->GetStride(); // Create the snake head as a paraboloid that is attached to the last // ring of vertices on the snake body. These vertices are generated // for t = 1. int numSliceSamples = mSnakeBody->GetNumSliceSamples(); mSlice = new1<Vector3f>(numSliceSamples + 1); // Number of rays (determined by slice samples of tube surface). int numRays = numSliceSamples - 1; // Number of shells less one (your choice, specified in application // constructor). int numShellsM1 = mNumShells - 1; // Generate vertices (positions to be filled in by UpdateSnakeHead). int numVertices = 1 + numRays*numShellsM1; VertexBuffer* vbuffer = new0 VertexBuffer(numVertices, vstride); VertexBufferAccessor vba(vformat, vbuffer); Float3 darkGreen(0.0f, 0.25f, 0.0f); for (int i = 0; i < numVertices; ++i) { vba.Color<Float3>(0, i) = darkGreen; } // Generate triangles. int numTriangles = numRays*(2*numShellsM1 - 1); int numIndices = 3*numTriangles; IndexBuffer* ibuffer = new0 IndexBuffer(numIndices, sizeof(int)); int* indices = (int*)ibuffer->GetData(); for (int r0 = numRays - 1, r1 = 0, t = 0; r1 < numRays; r0 = r1++) { *indices++ = 0; *indices++ = 1 + numShellsM1*r0; *indices++ = 1 + numShellsM1*r1; ++t; for (int s = 1; s < numShellsM1; ++s) { int i00 = s + numShellsM1*r0; int i01 = s + numShellsM1*r1; int i10 = i00 + 1; int i11 = i01 + 1; *indices++ = i00; *indices++ = i10; *indices++ = i11; *indices++ = i00; *indices++ = i11; *indices++ = i01; t += 2; } } mSnakeHead = new0 TriMesh(vformat, vbuffer, ibuffer); mSnakeHead->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance()); mSnakeRoot->AttachChild(mSnakeHead); UpdateSnake(); }
//---------------------------------------------------------------------------- void ReflectionsAndShadows::CreatePlanes () { VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0); int vstride = vformat->GetStride(); // Create the floor mesh. VertexBuffer* vbuffer = new0 VertexBuffer(4, vstride); VertexBufferAccessor floor(vformat, vbuffer); float xValue = 128.0f; float yValue = 256.0f; float zValue = 0.0f; floor.Position<Float3>(0) = Float3(-xValue, -yValue, zValue); floor.Position<Float3>(1) = Float3(+xValue, -yValue, zValue); floor.Position<Float3>(2) = Float3(+xValue, +yValue, zValue); floor.Position<Float3>(3) = Float3(-xValue, +yValue, zValue); floor.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f); floor.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f); floor.TCoord<Float2>(0, 2) = Float2(1.0f, 1.0f); floor.TCoord<Float2>(0, 3) = Float2(0.0f, 1.0f); IndexBuffer* ibuffer = new0 IndexBuffer(6, sizeof(int)); int* indices = (int*)ibuffer->GetData(); indices[0] = 0; indices[1] = 1; indices[2] = 2; indices[3] = 0; indices[4] = 2; indices[5] = 3; mPlane0 = new0 TriMesh(vformat, vbuffer, ibuffer); Texture2DEffect* effect = new0 Texture2DEffect(Shader::SF_LINEAR_LINEAR, Shader::SC_REPEAT, Shader::SC_REPEAT); std::string path = Environment::GetPathR("Sand.wmtf"); Texture2D* texture = Texture2D::LoadWMTF(path); mPlane0->SetEffectInstance(effect->CreateInstance(texture)); mScene->AttachChild(mPlane0); // Create the wall mesh. vbuffer = new0 VertexBuffer(4, vstride); VertexBufferAccessor wall(vformat, vbuffer); xValue = -128.0f; yValue = 256.0f; zValue = 128.0f; wall.Position<Float3>(0) = Float3(xValue, -yValue, 0.0f); wall.Position<Float3>(1) = Float3(xValue, +yValue, 0.0f); wall.Position<Float3>(2) = Float3(xValue, +yValue, zValue); wall.Position<Float3>(3) = Float3(xValue, -yValue, zValue); wall.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f); wall.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f); wall.TCoord<Float2>(0, 2) = Float2(1.0f, 1.0f); wall.TCoord<Float2>(0, 3) = Float2(0.0f, 1.0f); mPlane1 = new0 TriMesh(vformat, vbuffer, ibuffer); path = Environment::GetPathR("Stone.wmtf"); texture = Texture2D::LoadWMTF(path); mPlane1->SetEffectInstance(effect->CreateInstance(texture)); mScene->AttachChild(mPlane1); }
//---------------------------------------------------------------------------- void FreeFormDeformation::CreatePolylines () { // Generate the polylines that connect adjacent control points. mPolysegmentRoot = new0 Node(); mTrnNode->AttachChild(mPolysegmentRoot); VertexColor3Effect* effect = new0 VertexColor3Effect(); VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0); int vstride = vformat->GetStride(); VertexBufferAccessor vba; VertexBuffer* vbuffer; Polysegment* segment; int i0, i1, i2; for (i0 = 0; i0 < mQuantity; ++i0) { for (i1 = 0; i1 < mQuantity; ++i1) { for (i2 = 0; i2 < mQuantity-1; ++i2) { vbuffer = new0 VertexBuffer(2, vstride); vba.ApplyTo(vformat, vbuffer); vba.Position<Vector3f>(0) = mVolume->GetControlPoint(i0, i1, i2); vba.Position<Vector3f>(1) = mVolume->GetControlPoint(i0, i1, i2+1); vba.Color<Float3>(0, 0) = Float3(0.0f, 0.0f, 0.75f); vba.Color<Float3>(0, 1) = Float3(0.0f, 0.0f, 0.75f); segment = new0 Polysegment(vformat, vbuffer, true); segment->SetEffectInstance(effect->CreateInstance()); mPolysegmentRoot->AttachChild(segment); } } for (i2 = 0; i2 < mQuantity; ++i2) { for (i1 = 0; i1 < mQuantity-1; ++i1) { vbuffer = new0 VertexBuffer(2, vstride); vba.ApplyTo(vformat, vbuffer); vba.Position<Vector3f>(0) = mVolume->GetControlPoint(i0, i1, i2); vba.Position<Vector3f>(1) = mVolume->GetControlPoint(i0, i1+1, i2); vba.Color<Float3>(0, 0) = Float3(0.0f, 0.75f, 0.0f); vba.Color<Float3>(0, 1) = Float3(0.0f, 0.75f, 0.0f); segment = new0 Polysegment(vformat, vbuffer, true); segment->SetEffectInstance(effect->CreateInstance()); mPolysegmentRoot->AttachChild(segment); } } } for (i0 = 0; i0 < mQuantity-1; ++i0) { for (i1 = 0; i1 < mQuantity; ++i1) { for (i2 = 0; i2 < mQuantity; ++i2) { vbuffer = new0 VertexBuffer(2, vstride); vba.ApplyTo(vformat, vbuffer); vba.Position<Vector3f>(0) = mVolume->GetControlPoint(i0, i1, i2); vba.Position<Vector3f>(1) = mVolume->GetControlPoint(i0+1, i1, i2); vba.Color<Float3>(0,0) = Float3(0.75f, 0.0f, 0.0f); vba.Color<Float3>(0,1) = Float3(0.75f, 0.0f, 0.0f); segment = new0 Polysegment(vformat, vbuffer, true); segment->SetEffectInstance(effect->CreateInstance()); mPolysegmentRoot->AttachChild(segment); } } } }