Пример #1
0
//----------------------------------------------------------------------------
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));
}
Пример #2
0
	//------------------------------------------------------------------------------------------------------
	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] );
	}
Пример #3
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;
    }
}
Пример #6
0
//----------------------------------------------------------------------------
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));
}
Пример #7
0
//----------------------------------------------------------------------------
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);
}
Пример #8
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();
Пример #9
0
	//--------------------------------------------------------------------------------------------------------------------------------------
	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;

		//计算绑定盒子
		//由于喷射角度关系,绑定盒子很难精确计算,将采用随机测试的方法在编辑器中输出

	}
Пример #10
0
//----------------------------------------------------------------------------
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);
}
Пример #11
0
//----------------------------------------------------------------------------
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));
}
Пример #12
0
//----------------------------------------------------------------------------
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;
}
Пример #13
0
//----------------------------------------------------------------------------
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);
}
Пример #14
0
//----------------------------------------------------------------------------
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);
}
Пример #15
0
//----------------------------------------------------------------------------
void Fluids3D::CreateScene ()
{
    // Get fluid solver parameters.
    const int bound0M1 = mSmoke->GetIMax();
    const int bound1M1 = mSmoke->GetJMax();
    const int bound2M1 = mSmoke->GetKMax();
    const int bound0 = bound0M1 + 1;
    const int bound1 = bound1M1 + 1;
    const int bound2 = bound2M1 + 1;
    const int quantity = bound0*bound1*bound2;
    const float* x = mSmoke->GetX();
    const float* y = mSmoke->GetY();
    const float* z = mSmoke->GetZ();

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

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

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

    int i0, i1, i2, index;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    mCube->SetEffectInstance(instance);

    mScene = new0 Node();
    mScene->AttachChild(mCube);
}
Пример #16
0
//----------------------------------------------------------------------------
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
}
Пример #17
0
//----------------------------------------------------------------------------
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);
	}
}
Пример #18
0
//----------------------------------------------------------------------------
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
}
Пример #19
0
//----------------------------------------------------------------------------
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);
}
Пример #20
0
//----------------------------------------------------------------------------
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);
}
Пример #21
0
//----------------------------------------------------------------------------
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));
}
Пример #22
0
//----------------------------------------------------------------------------
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;
}
Пример #23
0
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;
	}
}
Пример #24
0
//----------------------------------------------------------------------------
void MaterialTextures::CreateScene ()
{
    mScene = new0 Node();
    mTrnNode = new0 Node();
    mScene->AttachChild(mTrnNode);
    mWireState = new0 WireState();
    mRenderer->SetOverrideWireState(mWireState);

    // Create a square object.
    VertexFormat* vformat = VertexFormat::Create(2,
                            VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
                            VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0);
    int vstride = vformat->GetStride();

    VertexBuffer* vbuffer = new0 VertexBuffer(4, vstride);
    VertexBufferAccessor vba(vformat, vbuffer);

    vba.Position<Float3>(0) = Float3(-1.0f, -1.0f, 0.0f);
    vba.Position<Float3>(1) = Float3(-1.0f,  1.0f, 0.0f);
    vba.Position<Float3>(2) = Float3( 1.0f,  1.0f, 0.0f);
    vba.Position<Float3>(3) = Float3( 1.0f, -1.0f, 0.0f);
    vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f);
    vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f);
    vba.TCoord<Float2>(0, 2) = Float2(1.0f, 1.0f);
    vba.TCoord<Float2>(0, 3) = Float2(0.0f, 1.0f);

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

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

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

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

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

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

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

    Material* material = new0 Material();
    material->Diffuse = Float4(0.0f, 0.0f, 1.0f, 0.5f);
    path = Environment::GetPathR("Water.wmtf");
    texture = Texture2D::LoadWMTF(path);
    water->SetEffectInstance(effect->CreateInstance(material, texture));
}
//----------------------------------------------------------------------------
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();
}
Пример #26
0
//----------------------------------------------------------------------------
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();
}
Пример #27
0
//----------------------------------------------------------------------------
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);
            }
        }
    }
}