예제 #1
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);
}
예제 #2
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);
    }
}
//----------------------------------------------------------------------------
bool StructuredBuffersWindow::CreateScene()
{
    // Create the shaders and associated resources
    HLSLDefiner definer;
    definer.SetInt("WINDOW_WIDTH", mXSize);
    std::shared_ptr<VertexShader> vshader(ShaderFactory::CreateVertex(
        mEnvironment.GetPath("StructuredBuffers.hlsl"), definer));
    if (!vshader)
    {
        return false;
    }

    std::shared_ptr<PixelShader> pshader(ShaderFactory::CreatePixel(
        mEnvironment.GetPath("StructuredBuffers.hlsl"), definer));
    if (!pshader)
    {
        return false;
    }

    std::shared_ptr<ConstantBuffer> cbuffer(new ConstantBuffer(
        sizeof(Matrix4x4<float>), true));
    vshader->Set("PVWMatrix", cbuffer);

    // Create the pixel shader and associated resources.
    std::string path = mEnvironment.GetPath("StoneWall.png");
    std::shared_ptr<Texture2> baseTexture(WICFileIO::Load(path, false));
    pshader->Set("baseTexture", baseTexture);

    std::shared_ptr<SamplerState> baseSampler(new SamplerState());
    baseSampler->filter = SamplerState::MIN_L_MAG_L_MIP_P;
    baseSampler->mode[0] = SamplerState::CLAMP;
    baseSampler->mode[1] = SamplerState::CLAMP;
    pshader->Set("baseSampler", baseSampler);

    mDrawnPixels.reset(new StructuredBuffer(mXSize*mYSize,
        sizeof(Vector4<float>)));
    mDrawnPixels->SetUsage(Resource::SHADER_OUTPUT);
    mDrawnPixels->SetCopyType(Resource::COPY_BIDIRECTIONAL);
    memset(mDrawnPixels->GetData(), 0, mDrawnPixels->GetNumBytes());
    pshader->Set("drawnPixels", mDrawnPixels);

    // Create the visual effect for the square.
    std::shared_ptr<VisualEffect> effect(new VisualEffect(vshader, pshader));

    // Create a vertex buffer for a single triangle.  The PNG is stored in
    // left-handed coordinates.  The texture coordinates are chosen to reflect
    // the texture in the y-direction.
    struct Vertex
    {
        Vector3<float> position;
        Vector2<float> tcoord;
    };
    VertexFormat vformat;
    vformat.Bind(VA_POSITION, DF_R32G32B32_FLOAT, 0);
    vformat.Bind(VA_TEXCOORD, DF_R32G32_FLOAT, 0);
    std::shared_ptr<VertexBuffer> vbuffer(new VertexBuffer(vformat, 4));
    Vertex* vertex = vbuffer->Get<Vertex>();
    vertex[0].position = Vector3<float>(0.0f, 0.0f, 0.0f);
    vertex[0].tcoord = Vector2<float>(0.0f, 1.0f);
    vertex[1].position = Vector3<float>(1.0f, 0.0f, 0.0f);
    vertex[1].tcoord = Vector2<float>(1.0f, 1.0f);
    vertex[2].position = Vector3<float>(0.0f, 1.0f, 0.0f);
    vertex[2].tcoord = Vector2<float>(0.0f, 0.0f);
    vertex[3].position = Vector3<float>(1.0f, 1.0f, 0.0f);
    vertex[3].tcoord = Vector2<float>(1.0f, 0.0f);

    // Create an indexless buffer for a triangle mesh with two triangles.
    std::shared_ptr<IndexBuffer> ibuffer(new IndexBuffer(IP_TRISTRIP, 2));

    // Create the geometric object for drawing.  Translate it so that its
    // center of mass is at the origin.  This supports virtual trackball
    // motion about the object "center".
    mSquare.reset(new Visual(vbuffer, ibuffer, effect));
    mSquare->localTransform.SetTranslation(-0.5f, -0.5f, 0.0f);
    mSquare->Update();

    // Enable automatic updates of pvw-matrices and w-matrices.
    SubscribeCW(mSquare, cbuffer);

    // The structured buffer is written in the pixel shader.  This texture
    // will receive a copy of it so that we can write the results to disk
    // as a PNG file.
    mDrawnPixelsTexture = new Texture2(DF_R8G8B8A8_UNORM, mXSize, mYSize);
    return true;
}
예제 #4
0
    bool ModelDefinition::Deserialize(Deserializer &deserializer)
    {
        // Clear everything.
        this->ClearMeshes();
        this->ClearBones();
        this->ClearAnimations(true);        // <-- 'true' = clear animation segments, too.
        this->ClearConvexHulls();


        // We keep looping until we hit the null or unknown chunk.
        Serialization::ChunkHeader header;
        while (deserializer.Peek(&header, sizeof(header)) == sizeof(header))
        {
            bool finished = false;

            switch (header.id)
            {
            case Serialization::ChunkID_Model_Bones:
                {
                    deserializer.Seek(sizeof(header));

                    if (header.version == 1)
                    {
                        uint32_t boneCount;
                        deserializer.Read(boneCount);

                        for (uint32_t iBone = 0; iBone < boneCount; ++iBone)
                        {
                            // Name.
                            String name;
                            deserializer.ReadString(name);

                            // Local transform.
                            glm::vec3 position;
                            glm::quat rotation;
                            glm::vec3 scale;

                            deserializer.Read(position);
                            deserializer.Read(rotation);
                            deserializer.Read(scale);

                            // 4x4 offset matrix.
                            glm::mat4 offsetMatrix;
                            deserializer.Read(offsetMatrix);


                            auto bone = new Bone;
                            bone->SetName(name.c_str());
                            bone->SetPosition(position);
                            bone->SetRotation(rotation);
                            bone->SetScale(scale);
                            bone->SetOffsetMatrix(offsetMatrix);
                            this->AddBone(bone);


                            // We need to create a channel for this bone. We then need to map that channel to a bone.
                            auto &channel = m_animation.CreateChannel();
                            this->animationChannelBones.Add(bone, &channel);
                        }


                        // Parents.
                        auto boneParentIndices = static_cast<uint32_t*>(malloc(boneCount * sizeof(uint32_t)));
                        deserializer.Read(boneParentIndices, boneCount * sizeof(uint32_t));

                        for (uint32_t iBone = 0; iBone < boneCount; ++iBone)
                        {
                            uint32_t parentIndex = boneParentIndices[iBone];

                            if (parentIndex != static_cast<uint32_t>(-1))
                            {
                                m_bones[parentIndex]->AttachChild(*m_bones[iBone]);
                            }
                        }

                        free(boneParentIndices);
                    }
                    else
                    {
                        // Unsupported Version.
                        deserializer.Seek(header.sizeInBytes);
                    }

                    break;
                }

            case Serialization::ChunkID_Model_Meshes:
                {
                    deserializer.Seek(sizeof(header));

                    if (header.version == 1)
                    {
                        uint32_t meshCount;
                        deserializer.Read(meshCount);

                        for (uint32_t iMesh = 0; iMesh < meshCount; ++iMesh)
                        {
                            ModelDefinition::Mesh newMesh(m_context);

                            // Name.
                            deserializer.ReadString(newMesh.name);


                            // Material
                            String materialName;
                            deserializer.ReadString(materialName);

                            newMesh.material = m_context.GetMaterialLibrary().Create(materialName.c_str());



                            // Geometry
                            VertexFormat vertexFormat;
                            vertexFormat.Deserialize(deserializer);
                            newMesh.geometry = Renderer::CreateVertexArray(VertexArrayUsage_Static, vertexFormat);
                            
                            // Vertices.
                            uint32_t vertexCount;
                            deserializer.Read(vertexCount);

                            if (vertexCount > 0)
                            {
                                newMesh.geometry->SetVertexData(nullptr, static_cast<size_t>(vertexCount));
                                auto vertexData = newMesh.geometry->MapVertexData();
                                {
                                    deserializer.Read(vertexData, vertexCount * vertexFormat.GetSizeInBytes());
                                }
                                newMesh.geometry->UnmapVertexData();
                            }

                            // Indices.
                            uint32_t indexCount;
                            deserializer.Read(indexCount);

                            if (indexCount > 0)
                            {
                                newMesh.geometry->SetIndexData(nullptr, static_cast<size_t>(indexCount));
                                auto indexData = newMesh.geometry->MapIndexData();
                                {
                                    deserializer.Read(indexData, indexCount * sizeof(uint32_t));
                                }
                                newMesh.geometry->UnmapIndexData();
                            }



                            // Skinning Vertex Attributes
                            uint32_t skinningVertexAttributeCount;
                            deserializer.Read(skinningVertexAttributeCount);

                            if (skinningVertexAttributeCount > 0)
                            {
                                newMesh.skinningVertexAttributes = new SkinningVertexAttribute[skinningVertexAttributeCount];

                                auto counts = static_cast<uint16_t*>(malloc(skinningVertexAttributeCount * sizeof(uint16_t)));
                                deserializer.Read(counts, skinningVertexAttributeCount * sizeof(uint16_t));

                                uint32_t totalBoneWeights;
                                deserializer.Read(totalBoneWeights);

                                auto boneWeights = static_cast<BoneWeightPair*>(malloc(totalBoneWeights * sizeof(BoneWeightPair)));
                                deserializer.Read(boneWeights, totalBoneWeights * sizeof(BoneWeightPair));


                                auto currentBoneWeight = boneWeights;
                                for (uint32_t iVertex = 0; iVertex < skinningVertexAttributeCount; ++iVertex)
                                {
                                    auto count = counts[iVertex];

                                    // Here we allocate the buffer for the bones. We trick the vector here by modifying attributes directly.
                                    newMesh.skinningVertexAttributes[iVertex].bones.Reserve(count);
                                    newMesh.skinningVertexAttributes[iVertex].bones.count = count;

                                    for (uint16_t iBone = 0; iBone < count; ++iBone)
                                    {
                                        newMesh.skinningVertexAttributes[iVertex].bones[iBone] = *currentBoneWeight++;
                                    }
                                }

                                free(counts);
                                free(boneWeights);
                            }


                            // Uniforms.
                            newMesh.defaultUniforms.Deserialize(deserializer);


                            // Finally, add the mesh.
                            this->AddMesh(newMesh);
                        }
                    }
                    else
                    {
                        // Unsupported Version.
                        deserializer.Seek(header.sizeInBytes);
                    }

                    break;
                }

            case Serialization::ChunkID_Model_Animation:
                {
                    deserializer.Seek(sizeof(header));

                    if (header.version == 1)
                    {
                        uint32_t keyFrameCount;
                        deserializer.Read(keyFrameCount);

                        for (size_t iKeyFrame = 0; iKeyFrame < keyFrameCount; ++iKeyFrame)
                        {
                            float time;
                            deserializer.Read(time);

                            size_t keyFrameIndex = m_animation.AppendKeyFrame(static_cast<double>(time));


                            // With the key frame added, we now need to iterate over each channel in the key frame.
                            uint32_t channelCount;
                            deserializer.Read(channelCount);

                            for (uint32_t iChannel = 0; iChannel < channelCount; ++iChannel)
                            {
                                uint32_t boneIndex;
                                deserializer.Read(boneIndex);

                                auto bone = m_bones[boneIndex];
                                assert(bone != nullptr);
                                {
                                    auto iChannelBone = this->animationChannelBones.Find(bone);
                                    assert(iChannelBone != nullptr);
                                    {
                                        auto channel = iChannelBone->value;

                                        glm::vec3 position;
                                        glm::quat rotation;
                                        glm::vec3 scale;
                                        
                                        deserializer.Read(position);
                                        deserializer.Read(rotation);
                                        deserializer.Read(scale);

                                        auto key = new TransformAnimationKey(position, rotation, scale);
                                        channel->SetKey(keyFrameIndex, key);


                                        // We need to cache the key.
                                        this->animationKeyCache.PushBack(key);
                                    }
                                }
                            }
                        }

                        deserializer.Read(this->animationAABBPadding);
                    }
                    else
                    {
                        // Unsupported Version.
                        deserializer.Seek(header.sizeInBytes);
                    }

                    break;
                }

            case Serialization::ChunkID_Model_AnimationSegments:
                {
                    deserializer.Seek(sizeof(header));

                    if (header.version == 1)
                    {
                        uint32_t animationSegmentCount;
                        deserializer.Read(animationSegmentCount);
                        
                        for (uint32_t iSegment = 0; iSegment < animationSegmentCount; ++iSegment)
                        {
                            String name;
                            uint32_t startKeyFrame;
                            uint32_t endKeyFrame;

                            deserializer.ReadString(name);
                            deserializer.Read(startKeyFrame);
                            deserializer.Read(endKeyFrame);

                            m_animation.AddNamedSegment(name.c_str(), static_cast<size_t>(startKeyFrame), static_cast<size_t>(endKeyFrame));
                        }
                    }
                    else
                    {
                        // Unsupported Version.
                        deserializer.Seek(header.sizeInBytes);
                    }

                    break;
                }

            case Serialization::ChunkID_Model_AnimationSequences:
                {
                    deserializer.Seek(sizeof(header));

                    if (header.version == 1)
                    {
                    }
                    else
                    {
                        // Unsupported Version.
                        deserializer.Seek(header.sizeInBytes);
                    }

                    break;
                }

            case Serialization::ChunkID_Model_ConvexHulls:
                {
                    deserializer.Seek(sizeof(header));

                    if (header.version == 1)
                    {
                        uint32_t convexHullCount;
                        deserializer.Read(convexHullCount);

                        uint32_t* vertexCounts = static_cast<uint32_t*>(malloc(convexHullCount * sizeof(uint32_t)));
                        uint32_t* indexCounts  = static_cast<uint32_t*>(malloc(convexHullCount * sizeof(uint32_t)));

                        deserializer.Read(vertexCounts, convexHullCount * sizeof(uint32_t));
                        deserializer.Read(indexCounts,  convexHullCount * sizeof(uint32_t));


                        uint32_t totalVertexCount;
                        deserializer.Read(totalVertexCount);

                        uint32_t totalIndexCount;
                        deserializer.Read(totalIndexCount);


                        auto vertices = static_cast<float*   >(malloc(totalVertexCount * sizeof(float)));
                        auto indices  = static_cast<uint32_t*>(malloc(totalIndexCount  * sizeof(uint32_t)));

                        deserializer.Read(vertices, totalVertexCount * sizeof(float));
                        deserializer.Read(indices,  totalIndexCount  * sizeof(uint32_t));


                        auto currentVertices = vertices;
                        auto currentIndices  = indices;

                        for (uint32_t iConvexHull = 0; iConvexHull < convexHullCount; ++iConvexHull)
                        {
                            size_t vertexCount = static_cast<size_t>(vertexCounts[iConvexHull]);
                            size_t indexCount  = static_cast<size_t>(indexCounts[iConvexHull]);

                            m_convexHulls.PushBack(new ConvexHull(currentVertices, vertexCount, currentIndices, indexCount));

                            // Now we need to move our pointers forward.
                            currentVertices += vertexCount * 3;
                            currentIndices  += indexCount;
                        }


                        // Build Settings.
                        deserializer.Read(this->convexHullBuildSettings);


                        free(vertexCounts);
                        free(indexCounts);
                        free(vertices);
                        free(indices);
                    }
                    else
                    {
                        // Unsupported Version.
                        deserializer.Seek(header.sizeInBytes);
                    }

                    break;
                }

            case Serialization::ChunkID_Null:
                {
                    deserializer.Seek(sizeof(header));

                    finished = true;
                    break;
                }

            default:
                {
                    // Unknown chunk = Error.
                    finished = true;
                    return false;
                }
            }


            if (finished)
            {
                break;
            }
        }


        // If we get here, we were successful.
        return true;
    }
예제 #5
0
int WINAPI WinMain( HINSTANCE inst, HINSTANCE, LPSTR cmdLine, int cmdShow )
{
	Window wnd;

	P(Context)				context		= 0;
	int						sw			= 640;
	int						sh			= 480;
	int						sbpp		= 0;
	bool					fullscreen	= (0 != sbpp);
	P(Scene)				root		= 0;

	try
	{
		// args
		String fxname = cmdLine;
		if ( fxname == "" )
			fxname = "bump.fx";

		// init window
		DWORD style = WS_VISIBLE;
		DWORD styleEx = 0;
		if ( fullscreen )
		{
			style |= WS_POPUP;
			styleEx |= WS_EX_TOPMOST;
		}
		else
		{
			style |= WS_OVERLAPPEDWINDOW;
		}
		wnd.create( "sgtestclass", "sg test", style, styleEx, 0, 0, sw, sh, inst, 0 );

		// init context
		context = new Context( "gd_dx8" );
		context->open( sw, sh, sbpp, 75,
			Context::SURFACE_TARGET + 
			Context::SURFACE_DEPTH + 
			Context::SURFACE_STENCIL,
			Context::RASTERIZER_HW, 
			Context::VERTEXP_HW,
			Context::TC_DISABLED );

		// scene
		root = new Scene;
		root->setName( "root" );

		// camera
		P(Camera) cam = new Camera;
		cam->setName( "cam" );
		cam->setPosition( Vector3(0,1.5f,-3) );
		Matrix3x3 rot = Matrix3x3( Vector3(1,0,0), Math::toRadians(30.f) );
		cam->setRotation( rot );
		cam->setHorizontalFov( Math::toRadians(100.f) );
		cam->setFront( 0.2f );
		cam->setBack( 100.f );
		cam->linkTo( root );

		// light
		P(DirectLight) lt = new DirectLight;
		lt->setName( "keylight" );
		lt->setIntensity( 0.5f );
		lt->linkTo( root );
		lt->lookAt( Vector3(-0.5f,-1,0) );

		// resources
		P(Texture) difmap = loadTex( "diffuse_map.tga" );
		P(Texture) normmap = loadTex( "normal_map.tga" );
		P(CubeTexture) envmap = loadCubeTex( "TestCubeTexture1.dds" );

		// read vb and ib data
		FileInputStream vbin( "vb.dat" );
		Array<uint8_t> vbbytes( vbin.available() );
		vbin.read( vbbytes.begin(), vbbytes.size() );
		int vertexSize = 4*3*4;
		int vertices = vbbytes.size() / vertexSize;
		FileInputStream ibin( "ib.dat" );
		Array<uint8_t> ibbytes( ibin.available() );
		ibin.read( ibbytes.begin(), ibbytes.size() );
		int indexSize = 2;
		int indices = ibbytes.size() / indexSize;

		// geometry (indirectly from vb and ib dat)
		VertexFormat vf; 
		vf.addNormal().addTextureCoordinate(3);
		P(Model) model = new Model( vertices, indices, vf );
		{
			VertexAndIndexLock<Model> lk( model, Model::LOCK_READWRITE );

			for ( int i = 0 ; i < vertices ; ++i )
			{
				model->setVertexPositions( i, (Vector3*)(vbbytes.begin()+i*vertexSize) );
				model->setVertexNormals( i, (Vector3*)(vbbytes.begin()+12+i*vertexSize) );
				model->setVertexTextureCoordinates( i, 0, 3, (float*)(vbbytes.begin()+24+i*vertexSize) );
			}

			void* idata;
			int istride;
			model->getIndexData( &idata, &istride );
			memcpy( idata, ibbytes.begin(), ibbytes.size() );
		}

		// env transform
		Matrix4x4 textm(0);
		textm(0,0) = 1.f;
		textm(1,1) = 1.f;
		textm(2,2) = 1.f;
		textm(0,3) = 0.f;
		textm(1,3) = 0.f;		
		textm(2,3) = 0.f;

		// material
		P(Material) mat = new Material;

		mat->setTexture( 0, difmap );
		
		mat->setTexture( 1, envmap );
		mat->setTextureColorCombine( 1, Material::TA_TEXTURE, Material::TOP_ADD, Material::TA_CURRENT );		
		mat->setTextureCoordinateTransform( 1, Material::TTFF_COUNT3, textm );
		mat->setTextureCoordinateSource( 1, Material::TCS_CAMERASPACENORMAL );

		mat->setVertexFormat( model->vertexFormat() );
		model->setShader( mat );

		// mesh
		P(Mesh) mesh = new Mesh;
		mesh->setName( "mesh" );
		mesh->linkTo( root );
		mesh->addPrimitive( model );
		cam->setRotationController( new sgu::LookAtControl(cam,mesh) );

		// floor
		vf = VertexFormat();
		vf.addNormal().addTextureCoordinate(2).addTextureCoordinate(2);
		P(Model) floormodel = createCube( 10, 0.01f, 10, vf );
		mat = new Material;
		mat->setDiffuseColor( Colorf(0,0,0) );
		mat->setEmissiveColor( Colorf(0.2f,0.2f,0.2f) );
		mat->setVertexFormat( floormodel->vertexFormat() );
		floormodel->setShader( mat );
		P(Mesh) floor = new Mesh;
		floor->setName( "floor" );
		floor->linkTo( root );
		floor->setPosition( Vector3(0,-2,0) );
		floor->addPrimitive( floormodel );

		// mesh position animation
		int keys = 8;
		{P(VectorInterpolator) anim = new VectorInterpolator(3);
		anim->setKeys( keys );
		for ( int i = 0 ; i < keys ; ++i )
		{
			float f = (float)i / (keys-1);
			float v[3] = { Math::sin(f*Math::PI*2.f)*2.f, 0, 0 };
			anim->setKeyValue( i, v, 3 );
			anim->setKeyTime( i, f * 4.f );
		}
		anim->sortKeys();
		mesh->setPositionController( anim );}

		// mesh rotation animation
		{P(QuaternionInterpolator) anim = new QuaternionInterpolator;
		anim->setKeys( keys );
		for ( int i = 0 ; i < keys ; ++i )
		{
			float f = (float)i / (keys-1);
			float ang = f * Math::PI*2.f;
			Quaternion quat( Vector3(0,1,0), ang );
			float v[] = {quat.x, quat.y, quat.z, quat.w};
			anim->setKeyValue( i, v, 4 );
			anim->setKeyTime( i, f * 3.f );
		}
		anim->sortKeys();
		mesh->setRotationController( anim );}

		// mesh scale animation
		/*{P(VectorInterpolator) anim = new VectorInterpolator(3);
		anim->setKeys( keys );
		for ( int i = 0 ; i < keys ; ++i )
		{
			float f = (float)i / (keys-1);
			float v[3] = { Math::abs(Math::sin(f*Math::PI*2.f))+.5f, 1.f, 1.f };
			anim->setKeyValue( i, v, 3 );
			anim->setKeyTime( i, f * 5.f );
		}
		anim->sortKeys();
		mesh->setScaleController( anim );}*/

		// shadow volume
		P(ShadowVolume) shadow = new ShadowVolume( model, lt->worldDirection(), 20.f );
		shadow->setShader( new ShadowShader );
		mesh->addPrimitive( shadow );

		// shadow filler
		VertexFormat fillvf;
		fillvf.addRHW().addDiffuse();
		P(Material) fillmat = new Material;
		fillmat->setDepthEnabled( false );
		fillmat->setDepthWrite( false );
		fillmat->setBlend( Material::BLEND_SRCALPHA, Material::BLEND_INVSRCALPHA );
		fillmat->setTextureColorCombine( 0, Material::TA_DIFFUSE, Material::TOP_SELECTARG1, Material::TextureArgument() );
		fillmat->setTextureAlphaCombine( 0, Material::TA_DIFFUSE, Material::TOP_SELECTARG1, Material::TextureArgument() );
		fillmat->setLighting( false );
		fillmat->setVertexColor( true );
		fillmat->setStencil( true );
		fillmat->setStencilRef( 1 );
		fillmat->setStencilFunc( Material::CMP_LESSEQUAL );
		fillmat->setStencilPass( Material::STENCILOP_KEEP );
		fillmat->setPass( ShadowShader::DEFAULT_SHADOW_FILL_PASS );
		fillmat->setVertexFormat( fillvf );

		// shadow filler geometry
		P(Model) fillgeom = new Model( 4, 6, fillvf );
		{VertexAndIndexLock<Model> lock( fillgeom, Model::LOCK_WRITE );
		Vector4 fillpos[4] = { Vector4(0,0,0,0), Vector4(sw,0,0,0), Vector4(sw,sh,0,0), Vector4(0,sh,0,0) };
		Color fillcolr[4] = { Color(0,0,0,80), Color(0,0,0,80), Color(0,0,0,80), Color(0,0,0,80) };
		int fillind[6] = { 0,1,2, 0,2,3 };
		fillgeom->setVertexPositionsRHW( 0, fillpos, 4 );
		fillgeom->setVertexDiffuseColors( 0, fillcolr, 4 );
		fillgeom->setIndices( 0, fillind, 6 );}

		fillgeom->setShader( fillmat );
		mesh->addPrimitive( fillgeom );

		// mainloop
		long prevTime = System::currentTimeMillis();
		float time = 0.f;
		while ( Window::flushWindowMessages() )
		{
			long curTime = System::currentTimeMillis();
			float dt = 1e-3f * (float)(curTime - prevTime);
			prevTime = curTime;

			if ( wnd.active() )
			{
				if ( GetKeyState('S') < 0 )
					dt *= 0.1f;
				if ( GetKeyState('R') < 0 )
					time = 0.f;
				if ( GetKeyState(VK_ESCAPE) < 0 )
					break;
				time += dt;

				for ( Node* node = root ; node ; node = node->nextInHierarchy() )
					node->setState( time );

				context->beginScene();
				cam->render();
				context->endScene();
				context->present();
				context->clear();
			}
		}

		context->destroy();
		wnd.destroy();
	}
	catch ( Throwable& e )
	{
		if ( context )
			context->destroy();

		MoveWindow( wnd.handle(), 0, 0, 0, 0, TRUE );
		char msg[1024] = "";
		e.getMessage().format().getBytes( msg, sizeof(msg), "ASCII-7" );
 		MessageBox( 0, msg, "Error", MB_OK );

		wnd.destroy();
	}
	return 0;
}
예제 #6
0
//----------------------------------------------------------------------------
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;
    }
}
예제 #7
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
}
예제 #8
0
bool ConvexHull3DWindow::LoadData()
{
    std::string filename = "data";
    if (mCurrentFile < 10)
    {
        filename += "0";
    }
    filename += std::to_string(mCurrentFile) + ".txt";
    std::string path = mEnvironment.GetPath(filename);
    if (path == "")
    {
        return false;
    }

    std::ifstream input(path);
    if (!input)
    {
        return false;
    }

    Vector3<float> center{ 0.0f, 0.0f, 0.0f };
    unsigned int numVertices;
    input >> numVertices;
    std::vector<Vector3<float>> vertices(numVertices);
    for (auto& v : vertices)
    {
        for (int j = 0; j < 3; ++j)
        {
            input >> v[j];
        }
        center += v;
    }
    input.close();
    center /= static_cast<float>(numVertices);

    float radius = 0.0f;
    for (auto const& v : vertices)
    {
        Vector3<float> diff = v - center;
        float length = Length(diff);
        if (length > radius)
        {
            radius = length;
        }
    }

    // The worst-case number of words for UIntegerFP32<N> for 'float' input
    // to ConvexHull3 is N = 27.  For 'double', it is 'N = 197'.
    ConvexHull3<float, BSNumber<UIntegerFP32<27>>> ch;
    if (numVertices < 4 || !ch(numVertices, &vertices[0], 0.0f))
    {
        if (mMesh)
        {
            mTrackball.Detach(mMesh);
            mTrackball.Update();
            mCameraRig.Unsubscribe(mMesh->worldTransform);
            mMesh = nullptr;
        }

        mMessage = "File = " + std::to_string(mCurrentFile) +
            " has intrinsic dimension " + std::to_string(ch.GetDimension());
        return false;
    }
#if defined(GTE_COLLECT_BSNUMBER_STATISTICS)
    std::cout << "max size = " << gte::gBSNumberMaxSize << std::endl;
#endif

    std::vector<TriangleKey<true>> const& triangles = ch.GetHullUnordered();

    std::mt19937 mte;
    std::uniform_real_distribution<float> rnd(0.0f, 1.0f);

    struct Vertex
    {
        Vector3<float> position;
        Vector4<float> color;
    };
    VertexFormat vformat;
    vformat.Bind(VA_POSITION, DF_R32G32B32_FLOAT, 0);
    vformat.Bind(VA_COLOR, DF_R32G32B32A32_FLOAT, 0);
    std::shared_ptr<VertexBuffer> vbuffer(new VertexBuffer(vformat,
        numVertices));
    Vertex* vertex = vbuffer->Get<Vertex>();
    for (unsigned int i = 0; i < numVertices; ++i)
    {
        vertex[i].position = vertices[i];
        vertex[i].color[0] = rnd(mte);
        vertex[i].color[1] = rnd(mte);
        vertex[i].color[2] = rnd(mte);
        vertex[i].color[3] = 1.0f;
    }

    unsigned int numPrimitives = static_cast<unsigned int>(triangles.size());
    std::shared_ptr<IndexBuffer> ibuffer(new IndexBuffer(IP_TRIMESH,
        numPrimitives, sizeof(unsigned int)));
    Memcpy(ibuffer->GetData(), &triangles[0], ibuffer->GetNumBytes());

    // Update all information associated with the mesh transforms.
    if (mMesh)
    {
        mTrackball.Detach(mMesh);
        mTrackball.Update();
        mCameraRig.Unsubscribe(mMesh->worldTransform);
    }
    mMesh = std::make_shared<Visual>(vbuffer, ibuffer, mEffect);
    mMesh->localTransform.SetTranslation(-center);
    mMesh->worldTransform = mMesh->localTransform;
    mCameraRig.Subscribe(mMesh->worldTransform,
        mEffect->GetPVWMatrixConstant());

    // Move the camera for a centered view of the mesh.
    Vector4<float> camPosition = Vector4<float>{0.0f, 0.0f, 0.0f, 1.0f}
        - 2.5f*radius*mCamera->GetDVector();
    mCamera->SetPosition(camPosition);

    // Update the message for display.
    mMessage =
        "File = " + std::to_string(mCurrentFile) + " , " +
        "Vertices = " + std::to_string(numVertices) + " , " +
        "Triangles =" + std::to_string(numPrimitives);

    mTrackball.Attach(mMesh);
    mTrackball.Update();
    mCameraRig.UpdatePVWMatrices();
    return true;
}
예제 #9
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));
}
예제 #10
0
void Vertex::Init(const VertexFormat &vf)
{
    int totalVertexSize = vf.GetStride();
    if(totalVertexSize > 0) data = malloc(totalVertexSize);
    else data = nullptr;
}
예제 #11
0
bool Vertex::HasAttribute(string name, const VertexFormat &vf) const
{
    int offset = vf.GetOffsetOf(name);
    return (offset != -1);
}
예제 #12
0
bool GeometryShadersWindow::CreateScene()
{
    std::string filename;
#if defined(USE_DRAW_DIRECT)
    filename = mEnvironment.GetPath("RandomSquares.hlsl");
#else
    filename = mEnvironment.GetPath("RandomSquaresIndirect.hlsl");
#endif
    std::shared_ptr<VisualProgram> program =
        mProgramFactory.CreateFromFiles(filename, filename, filename);
    if (!program)
    {
        return false;
    }

    // Create particles used by direct and indirect drawing.
    struct Vertex
    {
        Vector3<float> position;
        Vector3<float> color;
        float size;
    };

    // Use a Mersenne twister engine for random numbers.
    std::mt19937 mte;
    std::uniform_real_distribution<float> symr(-1.0f, 1.0f);
    std::uniform_real_distribution<float> unir(0.0f, 1.0f);
    std::uniform_real_distribution<float> posr(0.01f, 0.1f);

    int const numParticles = 128;
    std::vector<Vertex> particles(numParticles);
    for (auto& particle : particles)
    {
        particle.position = { symr(mte), symr(mte), symr(mte) };
        particle.color = { unir(mte), unir(mte), unir(mte) };
        particle.size = posr(mte);
    }

    // Create the constant buffer used by direct and indirect drawing.
    mMatrices = std::make_shared<ConstantBuffer>(
        2 * sizeof(Matrix4x4<float>), true);
    program->GetGShader()->Set("Matrices", mMatrices);

#if defined(USE_DRAW_DIRECT)
    // Create a mesh for direct drawing.
    VertexFormat vformat;
    vformat.Bind(VA_POSITION, DF_R32G32B32_FLOAT, 0);
    vformat.Bind(VA_COLOR, DF_R32G32B32_FLOAT, 0);
    vformat.Bind(VA_TEXCOORD, DF_R32_FLOAT, 0);
    std::shared_ptr<VertexBuffer> vbuffer(new VertexBuffer(vformat,
        numParticles));
    Memcpy(vbuffer->GetData(), &particles[0], numParticles*sizeof(Vertex));
#else
    // Create a mesh for indirect drawing.
    std::shared_ptr<VertexBuffer> vbuffer(new VertexBuffer(numParticles));
    mParticles = std::make_shared<StructuredBuffer>(numParticles,
        sizeof(Vertex));
    Memcpy(mParticles->GetData(), &particles[0], numParticles*sizeof(Vertex));
    gshader->Set("particles", mParticles);
#endif

    std::shared_ptr<IndexBuffer> ibuffer(new IndexBuffer(IP_POLYPOINT,
        numParticles));

    std::shared_ptr<VisualEffect> effect =
        std::make_shared<VisualEffect>(program);

    mMesh = std::make_shared<Visual>(vbuffer, ibuffer, effect);
    return true;
}
예제 #13
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));
}
예제 #14
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_TEXCOORD, VertexFormat::AT_FLOAT3, 2,  // normals
                            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.TCoord<Float3>(2, 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);
}
예제 #15
0
void ShaderGenerator::generateShaders(Material& mat, const RenderState& rs, const VertexFormat& vf, const FogParameters fogParams) {

	bool hasNormalMap = false;
	bool hasParallaxMap = false;

	ctemplate::TemplateDictionary vertexShaderDict("vertexShader");
	ctemplate::TemplateDictionary fragmentShaderDict("fragmentShader");

	ctemplate::TemplateDictionary* vertexIoDict = vertexShaderDict.AddIncludeDictionary("VERTEX_INPUTS");
	vertexIoDict->SetFilename("shader_templates/ft_vertex_inout.tpl");

	ctemplate::TemplateDictionary* fragmentOutDict = vertexShaderDict.AddIncludeDictionary("FRAGMENT_INPUTS");
	fragmentOutDict->SetFilename("shader_templates/ft_fragment_inout.tpl");
	fragmentOutDict->ShowSection("OUT_DIRECTION");

	ctemplate::TemplateDictionary* uniformsDict = vertexShaderDict.AddIncludeDictionary("UNIFORMS");
	uniformsDict->SetFilename("shader_templates/uniforms.tpl");

	// emit the fog uniforms if necessary
	if (fogParams.m_fogMode != FOG_NONE) {
		uniformsDict->ShowSection("FOG");
	}

	// use lighting when material uses shading and we have normals
	bool useLighting = !mat.m_shadeless && vf.getAttributeBySemantic(Vertex_Normal);
	if (useLighting) {
		uniformsDict->ShowSection("USE_LIGHTING");
	}

	if (vf.getAttributeBySemantic(Vertex_Normal)) {
		vertexShaderDict.ShowSection("HAS_NORMALS");
		vertexShaderDict.ShowSection("NORMALIZE_NORMALS");

		vertexIoDict->ShowSection("HAS_NORMALS");
		vertexIoDict->ShowSection("NORMALIZE_NORMALS");

		fragmentOutDict->ShowSection("HAS_NORMALS");

		uniformsDict->ShowSection("HAS_NORMALS");
	}

	if (vf.getAttributeBySemantic(Vertex_Tangent)) {
		fragmentOutDict->ShowSection("HAS_TANGENTS");
		vertexIoDict->ShowSection("HAS_TANGENTS");
	}

	if (vf.getAttributeBySemantic(Vertex_BiNormal)) {
		fragmentOutDict->ShowSection("HAS_BINORMALS");
		vertexIoDict->ShowSection("HAS_BINORMALS");
	}

	if (vf.getAttributeBySemantic(Vertex_Color)) {
		vertexShaderDict.ShowSection("HAS_COLORS");
		vertexIoDict->ShowSection("HAS_COLORS");
		fragmentOutDict->ShowSection("HAS_COLORS");
	}

	// indicates if the tex coords generation functions declarations template has already been
	// included in the vertex shader template
	bool texGenDeclIncluded = false;

	// number of active texture units
	uint activeTextures = 0;

	ctemplate::TemplateDictionary* texGenDict = vertexShaderDict.AddIncludeDictionary("TEX_COORDS_GEN");
	texGenDict->SetFilename("shader_templates/ft_tex_coords_gen.tpl");

	// Loops over all material textures and performs the following:
	//	1. Declares a respective uniform sampler object which will be named as u_sampler#,
	//     where # is the active texture index.
	//  2. Emits code for any texture coordinates generation scheme, if not simple UV.

	ctemplate::TemplateDictionary* parallaxMapDict = 0;

	for (int i = 0; i < MAX_TEXTURES_STACK; i++) {
		TexturePtr tex = mat.m_texStack->textures[i];
		if (tex) {
			// for the fragment shader, here we can fill in the dictionary for the texture application section
			// that takes into account the texture's mapTo, environment color, uvset, etc.
			ctemplate::TemplateDictionary* texUnitDict = fragmentShaderDict.AddIncludeDictionary(
					"SINGLE_TEXTURE_STACK_ENTRY");
			texUnitDict->SetFilename("shader_templates/ft_tex_stack_application.tpl");

			ctemplate::TemplateDictionary* alphaMapDict = 0;
			ctemplate::TemplateDictionary* tangentNormalMapDict = 0;
			ctemplate::TemplateDictionary* offsetMappingDict = 0;

			// depending on the texture's mapTo, we will emit different sections in the template
			ctemplate::TemplateDictionary* texMapToDict = 0;
			switch (mat.m_texStack->texOutputs[i].mapTo) {
			case TexMapTo_Diffuse:
				texMapToDict = texUnitDict->AddSectionDictionary("TEX_MAP_TO_DIFFUSE");
				break;
			case TexMapTo_CSpecular:
				texMapToDict = texUnitDict->AddSectionDictionary("TEX_MAP_TO_SPECULAR");
				break;
			case TexMapTo_Shininess:
				texMapToDict = texUnitDict->AddSectionDictionary("TEX_MAP_TO_SHININESS");
				break;
			case TexMapTo_Alpha:
				alphaMapDict = fragmentShaderDict.AddSectionDictionary("ALPHA_MAP_APPLICATION");
				break;
			case TexMapTo_Normal:
				tangentNormalMapDict = fragmentShaderDict.AddIncludeDictionary("TANGENT_SPACE_NORMAL_MAP");
				tangentNormalMapDict->SetFilename(TANGENT_SPACE_NMAP_TPL);
				parallaxMapDict = tangentNormalMapDict;
				hasNormalMap = true;
				break;
			case TexMapTo_Parallax:
				/* IMPORTANT: Parallax maps must come after the normal maps */
				if (parallaxMapDict) {
					offsetMappingDict = parallaxMapDict->AddSectionDictionary("PARALLAX_OFFSET_MAPPING");
				}
				hasParallaxMap = true;
				break;
			default:
				SAFE_THROW(GLException(E_NOTIMPL, "Unimplemented texture output mapping mode"))
			}

			texUnitDict->SetIntValue(TEX_INDEX, activeTextures);
			texUnitDict->SetIntValue(UV_SET_INDEX, mat.m_texStack->texInputs[i].uvSet);

			if (alphaMapDict) {
				alphaMapDict->SetIntValue(TEX_INDEX, activeTextures);
				alphaMapDict->SetIntValue(UV_SET_INDEX, mat.m_texStack->texInputs[i].uvSet);
			}

			if (tangentNormalMapDict) {
				tangentNormalMapDict->SetIntValue(TEX_INDEX, activeTextures);
				tangentNormalMapDict->SetIntValue(UV_SET_INDEX, mat.m_texStack->texInputs[i].uvSet);
			}
			if (offsetMappingDict) {
				offsetMappingDict->SetIntValue(TEX_INDEX, activeTextures);
				offsetMappingDict->SetIntValue(UV_SET_INDEX, mat.m_texStack->texInputs[i].uvSet);
			}

			switch (mat.m_texStack->texOutputs[i].blendOp) {
			case TexBlendOp_Mix:
				texUnitDict->ShowSection("TEX_BLENDOP_BLEND");
				break;
			case TexBlendOp_Add:
				texUnitDict->ShowSection("TEX_BLENDOP_ADD");
				break;
			case TexBlendOp_Multiply:
				texUnitDict->ShowSection("TEX_BLENDOP_MULTIPLY");
				break;
			case TexBlendOp_Decal:
				texUnitDict->ShowSection("TEX_BLENDOP_DECAL");
				break;
			default:
				SAFE_THROW(GLException(E_NOTIMPL, "Unimplemented texture blending mode"))
			}

			// this is the dictionary for a single uniform sampler declaration
			ctemplate::TemplateDictionary* samplerDict = uniformsDict->AddSectionDictionary("SINGLE_SAMPLER_DECL");
			samplerDict->SetIntValue(TEX_INDEX, activeTextures);

			const char* samplerToken;
			const char* coordsToken;
			switch (tex->getTextureTarget()) {
			case GL_TEXTURE_1D:
				samplerToken = "sampler1D";
				coordsToken = S_COORD;
				break;
			case GL_TEXTURE_CUBE_MAP:
				samplerToken = "samplerCube";
				coordsToken = STP_COORDS;
				break;
			case GL_TEXTURE_2D:
			default:
				samplerToken = "sampler2D";
				coordsToken = ST_COORDS;
				break;
			}

			samplerDict->SetValue("SAMPLER_SPEC", samplerToken);
			texUnitDict->SetValue(TEX_COORDS, coordsToken);

			if (alphaMapDict) {
				alphaMapDict->SetValue(TEX_COORDS, coordsToken);
			}
			if (tangentNormalMapDict) {
				tangentNormalMapDict->SetValue(TEX_COORDS, coordsToken);
			}
			if (offsetMappingDict) {
				offsetMappingDict->SetValue(TEX_COORDS, coordsToken);
			}

			// When a special texture coordinate generation system is used, we have to include
			// the TEX_COORDS_GEN_DECL template which contains function declarations for the various
			// tex gen systems. Then for each texture unit that uses custom tex gen, we need to
			// instantiate a SINGLE_TEX_COORDS_GEN section with an appropriately initialized dictionary
			ctemplate::TemplateDictionary* singleTexGen = texGenDict->AddSectionDictionary("SINGLE_TEXCOORDS_ASSIGN");
			singleTexGen->SetIntValue(UV_SET_INDEX, mat.m_texStack->texInputs[i].uvSet);
			singleTexGen->SetValue(TEX_COORDS, coordsToken);

			TexMapInput inputMapping = mat.m_texStack->texInputs[i].mapping;
			if (inputMapping != TexMapInput_UV) {
				if (!texGenDeclIncluded) {
					ctemplate::TemplateDictionary* texGenDecl = vertexShaderDict.AddIncludeDictionary(
							"TEX_COORDS_GEN_DECL");
					texGenDecl->SetFilename("shader_templates/ft_tex_coords_gen_decl.tpl");
					texGenDeclIncluded = true;
				}
				switch (inputMapping) {
				case TexMapInput_Normal:
					singleTexGen->ShowSection("NORMAL_TEXGEN");
					break;
				case TexMapInput_Refl:
					singleTexGen->ShowSection("REFLECTION_TEXGEN");
					break;
				case TexMapInput_Spherical:
					singleTexGen->ShowSection("SPHERE_TEXGEN");
					break;
				case TexMapInput_EyeSpace:
					singleTexGen->ShowSection("EYE_TEXGEN");
					break;
				case TexMapInput_ObjectSpace:
					singleTexGen->ShowSection("OBJECT_TEXGEN");
					break;
				case TexMapInput_Cube:
					singleTexGen->ShowSection("CUBE_TEXGEN");
					break;
				default:
					SAFE_THROW(GLException(E_NOTIMPL, "Unimplemented texture mapping mode"))
				}
			} else {
				singleTexGen->ShowSection("UV_MAPPING");
			}

			++activeTextures;
		}
	}
예제 #16
0
void MassSprings3DWindow::CreateBoxFaces()
{
    // The vertex buffer will use the mass-spring position array for its
    // CPU data.
    int const numVertices = mDimension[0] * mDimension[1] * mDimension[2];

#if defined(DO_CPU_MASS_SPRING)
    VertexFormat vformat;
    vformat.Bind(VA_POSITION, DF_R32G32B32_FLOAT, 0);
    mVBuffer = std::make_shared<VertexBuffer>(vformat, numVertices, false);
    mVBuffer->SetUsage(Resource::DYNAMIC_UPDATE);
#else
    mVBuffer = std::make_shared<VertexBuffer>(numVertices);
#endif
    
    size_t const idxsize = sizeof(unsigned int);
    std::shared_ptr<IndexBuffer> ibuffer;
    int numTriangles, t, x, y, z, v0, v1, v2, v3;

    // box face z = 1
    numTriangles = 2 * (mDimension[0] - 1) * (mDimension[1] - 1);
    ibuffer = std::make_shared<IndexBuffer>(IP_TRIMESH, numTriangles,
        idxsize);
    for (y = 1, t = 0; y < mDimension[1] - 2; ++y)
    {
        for (x = 1; x < mDimension[0] - 2; ++x)
        {
            v0 = GetIndex(x, y, 1);
            v1 = GetIndex(x + 1, y, 1);
            v2 = GetIndex(x, y + 1, 1);
            v3 = GetIndex(x + 1, y + 1, 1);
            ibuffer->SetTriangle(t++, v0, v2, v3);
            ibuffer->SetTriangle(t++, v0, v3, v1);
        }
    }
    mBoxFace[0] = std::make_shared<Visual>(mVBuffer, ibuffer);

    // box face z = dim2 - 2
    numTriangles = 2 * (mDimension[0] - 1) * (mDimension[1] - 1);
    ibuffer = std::make_shared<IndexBuffer>(IP_TRIMESH, numTriangles,
        idxsize);
    for (y = 1, t = 0; y < mDimension[1] - 2; ++y)
    {
        for (x = 1; x < mDimension[0] - 2; ++x)
        {
            v0 = GetIndex(x, y, mDimension[2] - 2);
            v1 = GetIndex(x + 1, y, mDimension[2] - 2);
            v2 = GetIndex(x, y + 1, mDimension[2] - 2);
            v3 = GetIndex(x + 1, y + 1, mDimension[2] - 2);
            ibuffer->SetTriangle(t++, v0, v3, v2);
            ibuffer->SetTriangle(t++, v0, v1, v3);
        }
    }
    mBoxFace[1] = std::make_shared<Visual>(mVBuffer, ibuffer);

    // box face y = 1
    numTriangles = 2 * (mDimension[0] - 1) * (mDimension[2] - 1);
    ibuffer = std::make_shared<IndexBuffer>(IP_TRIMESH, numTriangles,
        idxsize);
    for (z = 1, t = 0; z < mDimension[2] - 2; ++z)
    {
        for (x = 1; x < mDimension[0] - 2; ++x)
        {
            v0 = GetIndex(x, 1, z);
            v1 = GetIndex(x + 1, 1, z);
            v2 = GetIndex(x, 1, z + 1);
            v3 = GetIndex(x + 1, 1, z + 1);
            ibuffer->SetTriangle(t++, v0, v3, v2);
            ibuffer->SetTriangle(t++, v0, v1, v3);
        }
    }
    mBoxFace[2] = std::make_shared<Visual>(mVBuffer, ibuffer);

    // box face y = dim1 - 2
    numTriangles = 2 * (mDimension[0] - 1) * (mDimension[2] - 1);
    ibuffer = std::make_shared<IndexBuffer>(IP_TRIMESH, numTriangles,
        idxsize);
    for (z = 1, t = 0; z < mDimension[2] - 2; ++z)
    {
        for (x = 1; x < mDimension[0] - 2; ++x)
        {
            v0 = GetIndex(x, mDimension[1] - 2, z);
            v1 = GetIndex(x + 1, mDimension[1] - 2, z);
            v2 = GetIndex(x, mDimension[1] - 2, z + 1);
            v3 = GetIndex(x + 1, mDimension[1] - 2, z + 1);
            ibuffer->SetTriangle(t++, v0, v2, v3);
            ibuffer->SetTriangle(t++, v0, v3, v1);
        }
    }
    mBoxFace[3] = std::make_shared<Visual>(mVBuffer, ibuffer);

    // box face x = 1
    numTriangles = 2 * (mDimension[1] - 1) * (mDimension[2] - 1);
    ibuffer = std::make_shared<IndexBuffer>(IP_TRIMESH, numTriangles,
        idxsize);
    for (z = 1, t = 0; z < mDimension[2] - 2; ++z)
    {
        for (y = 1; y < mDimension[1] - 2; ++y)
        {
            v0 = GetIndex(1, y, z);
            v1 = GetIndex(1, y + 1, z);
            v2 = GetIndex(1, y, z + 1);
            v3 = GetIndex(1, y + 1, z + 1);
            ibuffer->SetTriangle(t++, v0, v2, v3);
            ibuffer->SetTriangle(t++, v0, v3, v1);
        }
    }
    mBoxFace[4] = std::make_shared<Visual>(mVBuffer, ibuffer);

    // box face x = dim0 - 2
    numTriangles = 2 * (mDimension[1] - 1) * (mDimension[2] - 1);
    ibuffer = std::make_shared<IndexBuffer>(IP_TRIMESH, numTriangles,
        idxsize);
    for (z = 1, t = 0; z < mDimension[2] - 2; ++z)
    {
        for (y = 1; y < mDimension[1] - 2; ++y)
        {
            v0 = GetIndex(mDimension[0] - 2, y, z);
            v1 = GetIndex(mDimension[0] - 2, y + 1, z);
            v2 = GetIndex(mDimension[0] - 2, y, z + 1);
            v3 = GetIndex(mDimension[0] - 2, y + 1, z + 1);
            ibuffer->SetTriangle(t++, v0, v3, v2);
            ibuffer->SetTriangle(t++, v0, v1, v3);
        }
    }
    mBoxFace[5] = std::make_shared<Visual>(mVBuffer, ibuffer);

    Vector4<float> const color[6] =
    {
        { 1.0f, 0.0f, 0.0f, 1.0f },
        { 0.0f, 1.0f, 0.0f, 1.0f },
        { 0.0f, 0.0f, 1.0f, 1.0f },
        { 0.0f, 1.0f, 1.0f, 1.0f },
        { 1.0f, 0.0f, 1.0f, 1.0f },
        { 1.0f, 1.0f, 0.0f, 1.0f }
    };

#if defined(DO_CPU_MASS_SPRING)
    for (int i = 0; i < 6; ++i)
    {
        mEffect[i] = std::make_shared<ConstantColorEffect>(color[i]);
        mBoxFace[i]->SetEffect(mEffect[i]);
    }
#else
    std::string path = mEnvironment.GetPath("DrawUsingVertexID.hlsl");
    std::shared_ptr<ConstantBuffer> pvwMatrixBuffer;
    std::shared_ptr<ConstantBuffer> colorBuffer;
    std::shared_ptr<VisualProgram> program;
    std::shared_ptr<VertexShader> vshader;
    std::shared_ptr<PixelShader> pshader;
    for (int i = 0; i < 6; ++i)
    {
        pvwMatrixBuffer = std::make_shared<ConstantBuffer>(
            sizeof(Matrix4x4<float>), true);
        colorBuffer = std::make_shared<ConstantBuffer>(
            sizeof(Vector4<float>), false);
        *colorBuffer->Get<Vector4<float>>() = color[i];
        // TODO: Need to terminate application if 'program' is null.
        program = mProgramFactory.CreateFromFiles(path, path, "");
        vshader = program->GetVShader();
        vshader->Set("PVWMatrix", pvwMatrixBuffer);
        vshader->Set("ConstantColor", colorBuffer);
        vshader->Set("position", mMassSprings->GetPosition());
        mEffect[i] = std::make_shared<VisualEffect>(program);
        mBoxFace[i]->SetEffect(mEffect[i]);
    }
#endif
}
예제 #17
0
//----------------------------------------------------------------------------
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();
}
예제 #18
0
//----------------------------------------------------------------------------
void FramesMesh::_Cal(const std::string &texPackFilename)
{
	const TexPack &texPack = PX2_RM.GetTexPack(texPackFilename);
	if (!texPack.IsValid()) return;

	std::string outPath;
	std::string outBaseFilename;
	StringHelp::SplitFilename(texPackFilename, outPath, outBaseFilename);

	std::string outBaseName;
	std::string outExt;
	StringHelp::SplitBaseFilename(outBaseFilename, outBaseName, outExt);

	VertexFormat *vf = PX2_GR.GetVertexFormat(GraphicsRoot::VFT_PCT1);
	SetVertexFormat(vf);

	mNumAllFrames = (int)texPack.Elements.size();
	mNumFramesPerDir = mNumAllFrames / mNumDir;
	if (0 == mNumFramesPerDir)
	{
		//assertion(false, "no frames");
		//return;
	}

	VBIBObj &obj = VBIBManager::GetSingleton().GetVBID(texPackFilename);
	if (obj.IsValued)
	{
		SetVertexBuffer(obj.mVB);
		SetIndexBuffer(obj.mIB);
	}
	else
	{
		int numVertex = mNumAllFrames * 4;
		int numIndex = mNumAllFrames * 6;

		int frameIndex = 0;
		VertexBuffer *vb = new0 VertexBuffer(numVertex, vf->GetStride());
		VertexBufferAccessor vba(vf, vb);
		for (int i = 0; i < mNumDir; i++)
		{
			for (int j = 0; j < mNumFramesPerDir; j++)
			{
				std::string eleName = outBaseName + "_" + StringHelp::IntToString(i * 45) + "_" + StringHelp::IntToString(j + 1);

				const TexPackElement &ele = PX2_RM.GetTexPackElement(texPackFilename, eleName);

				float xPlusPer = 0.0f;
				float widthPer = 0.0f;
				float zPlusPer = 0.0f;
				float heightPer = 0.0f;
				if (0 != ele.OW)
				{
					xPlusPer = (float)ele.OX / (float)ele.OW;
					widthPer = (float)ele.W / (float)ele.OW;
				}
				if (0 != ele.OH)
				{
					zPlusPer = 1.0f - (float)(ele.OY + ele.H) / (float)ele.OH;
					heightPer = (float)ele.H / (float)ele.OH;
				}

				float width = mSize;
				float height = mSize;

				float xPos = 0.0f - width * 0.5f;
				float zPos = 0.0f - height * 0.5f;
				xPos += xPlusPer * width;
				zPos += zPlusPer * height;

				width *= widthPer;
				height *= heightPer;

				Float3 p0 = Float3(xPos, zPos, 0.0f);
				Float3 p1 = Float3(xPos + width, zPos, 0.0f);
				Float3 p2 = Float3(xPos, zPos + height, 0.0f);
				Float3 p3 = Float3(xPos + width, zPos + height, 0.0f);

				float uBegin = (float)ele.X / (float)ele.TexWidth;
				float uEnd = (float)(ele.X + ele.W) / (float)ele.TexWidth;
				float vBegin = (float)(ele.TexHeight - ele.Y - ele.H) / (float)ele.TexHeight;
				float vEnd = (float)(ele.TexHeight - ele.Y) / (float)ele.TexHeight;

				vba.Position<Float3>(frameIndex * 4 + 0) = p0;
				vba.Position<Float3>(frameIndex * 4 + 1) = p1;
				vba.Position<Float3>(frameIndex * 4 + 2) = p2;
				vba.Position<Float3>(frameIndex * 4 + 3) = p3;

				vba.TCoord<Float2>(0, frameIndex * 4 + 0) = Float2(uBegin, vBegin);
				vba.TCoord<Float2>(0, frameIndex * 4 + 1) = Float2(uEnd, vBegin);
				vba.TCoord<Float2>(0, frameIndex * 4 + 2) = Float2(uBegin, vEnd);
				vba.TCoord<Float2>(0, frameIndex * 4 + 3) = Float2(uEnd, vEnd);

				frameIndex++;
			}
		}

		IndexBuffer *ib = new0 IndexBuffer(numIndex, 2);
		for (int i = 0; i < mNumAllFrames; i++)
		{
			unsigned short *indices = (unsigned short*)ib->GetData();
			indices[i * 6 + 0] = (uint16_t)(i * 4 + 0);
			indices[i * 6 + 1] = (uint16_t)(i * 4 + 1);
			indices[i * 6 + 2] = (uint16_t)(i * 4 + 2);
			indices[i * 6 + 3] = (uint16_t)(i * 4 + 1);
			indices[i * 6 + 4] = (uint16_t)(i * 4 + 3);
			indices[i * 6 + 5] = (uint16_t)(i * 4 + 2);
		}

		SetVertexBuffer(vb);
		SetIndexBuffer(ib);

		VBIBManager::GetSingleton().AddVBIB(texPackFilename, vb, ib);
	}

	Texture2D *tex = (Texture2D*)PX2_RM.BlockLoad(texPack.ImageFullPath);

	MaterialInstance *mi = new0 MaterialInstance(
		"Data/engine_mtls/tex2d/tex2d.px2obj", "tex2d", false);
	mi->SetPixelTexture(0, "SampleBase", tex);
	SetMaterialInstance(mi);

	mi->GetMaterial()->GetCullProperty(0, 0)->Enabled = false;

	mIsNeedReCal = false;
}
예제 #19
0
//----------------------------------------------------------------------------
CurveCtrl::CurveCtrl (Curve *curve, CurveCtrlType type, int index)
    :
    mIndex(index),
    mSelected(false),
    mCurve(curve),
    mCtrlType(type),
    mXScale(1.0f),
    mZScale(1.0f),
    mDragLength(1.0f),
    mInVal(-1.0f),
    mSelectMode(SM_MAX_MODE)
{
    mCtrlNode = new0 Node();

    float dragSize = 0.1f;

    VertexFormat *vFormat = PX2_GR.GetVertexFormat(GraphicsRoot::VFT_PC);
    StandardMesh sm(vFormat);

    Float3 curveColor = mCurve->GetCurveColor();

    VertexColor4MaterialPtr mtl = new0 VertexColor4Material();
    MaterialInstancePtr mtlInst = mtl->CreateInstance();

    sm.SetVertexColor(Float4(curveColor[0], curveColor[1], curveColor[2], 1.0f));
    mDragBox = sm.Box(dragSize, dragSize, dragSize);
    mDragBox->SetMaterialInstance(mtlInst);

    sm.SetVertexColor(Float4::WHITE);

    mDragBoxArrive = sm.Box(dragSize, dragSize, dragSize);
    mDragBoxArrive->SetMaterialInstance(mtlInst);

    mDragBoxLeave = sm.Box(dragSize, dragSize, dragSize);
    mDragBoxLeave->SetMaterialInstance(mtlInst);

    VertexBuffer *vBuffer = new0 VertexBuffer(2, vFormat->GetStride(),
                            Buffer::BU_DYNAMIC);
    mDragLineArrive = new0 Polysegment(vFormat, vBuffer, true);
    mDragLineArrive->SetMaterialInstance(mtlInst);

    VertexBuffer *vBuffer1 = new0 VertexBuffer(2, vFormat->GetStride(),
                             Buffer::BU_DYNAMIC);
    mDragLineLeave = new0 Polysegment(vFormat, vBuffer1, true);
    mDragLineLeave->SetMaterialInstance(mtlInst);

    sm.SetVertexColor(Float4::YELLOW);

    mCtrlNode->AttachChild(mDragBox);
    mCtrlNode->AttachChild(mDragBoxArrive);
    mCtrlNode->AttachChild(mDragBoxLeave);
    mCtrlNode->AttachChild(mDragLineArrive);
    mCtrlNode->AttachChild(mDragLineLeave);

    mDragBoxArrive->Culling = Movable::CULL_ALWAYS;
    mDragBoxLeave->Culling = Movable::CULL_ALWAYS;
    mDragLineArrive->Culling = Movable::CULL_ALWAYS;
    mDragLineLeave->Culling = Movable::CULL_ALWAYS;

    mCtrlNode->Update();
}
bool MultipleRenderTargetsWindow::CreateScene()
{
    // Create a visual effect that populates the draw target.
    std::string filename = mEnvironment.GetPath("MultipleRenderTargets.hlsl");
    std::shared_ptr<VisualProgram> program =
        mProgramFactory.CreateFromFiles(filename, filename, "");
    if (!program)
    {
        return false;
    }

    std::shared_ptr<ConstantBuffer> cbuffer(new ConstantBuffer(
        sizeof(Matrix4x4<float>), true));
    program->GetVShader()->Set("PVWMatrix", cbuffer);

    std::shared_ptr<PixelShader> pshader = program->GetPShader();
    std::shared_ptr<ConstantBuffer> farNearRatio(new ConstantBuffer(
        sizeof(float), false));
    pshader->Set("FarNearRatio", farNearRatio);
    farNearRatio->SetMember("farNearRatio",
        mCamera->GetDMax() / mCamera->GetDMin());

    std::string path = mEnvironment.GetPath("StoneWall.png");
    std::shared_ptr<Texture2> baseTexture(WICFileIO::Load(path, true));
    baseTexture->AutogenerateMipmaps();
    pshader->Set("baseTexture", baseTexture);

    std::shared_ptr<SamplerState> baseSampler(new SamplerState());
    baseSampler->filter = SamplerState::MIN_L_MAG_L_MIP_L;
    baseSampler->mode[0] = SamplerState::CLAMP;
    baseSampler->mode[1] = SamplerState::CLAMP;
    pshader->Set("baseSampler", baseSampler);

    std::shared_ptr<VisualEffect> effect =
        std::make_shared<VisualEffect>(program);

    // Create a vertex buffer for a two-triangle square.  The PNG is stored
    // in left-handed coordinates.  The texture coordinates are chosen to
    // reflect the texture in the y-direction.
    struct Vertex
    {
        Vector3<float> position;
        Vector2<float> tcoord;
    };
    VertexFormat vformat;
    vformat.Bind(VA_POSITION, DF_R32G32B32_FLOAT, 0);
    vformat.Bind(VA_TEXCOORD, DF_R32G32_FLOAT, 0);
    std::shared_ptr<VertexBuffer> vbuffer(new VertexBuffer(vformat, 4));
    Vertex* vertex = vbuffer->Get<Vertex>();
    vertex[0].position = { -1.0f, -1.0f, 0.0f };
    vertex[0].tcoord = { 0.0f, 1.0f };
    vertex[1].position = { 1.0f, -1.0f, 0.0f };
    vertex[1].tcoord = { 1.0f, 1.0f };
    vertex[2].position = { -1.0f, 1.0f, 0.0f };
    vertex[2].tcoord = { 0.0f, 0.0f };
    vertex[3].position = { 1.0f, 1.0f, 0.0f };
    vertex[3].tcoord = { 1.0f, 0.0f };

    // Create an indexless buffer for a triangle mesh with two triangles.
    std::shared_ptr<IndexBuffer> ibuffer(new IndexBuffer(IP_TRISTRIP, 2));

    // Create the geometric object for drawing and enable automatic updates
    // of pvw-matrices and w-matrices.
    mSquare = std::make_shared<Visual>(vbuffer, ibuffer, effect);
    mTrackball.Attach(mSquare);
    mTrackball.Update();
    mCameraRig.Subscribe(mSquare->worldTransform, cbuffer);
    return true;
}
예제 #21
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
}
예제 #22
0
//----------------------------------------------------------------------------
TriMesh *UniMaterialMesh::ToTriMesh()
{
	if (mVertexMapQuantity == 0)
		return 0;

	// VertexBuffer
	VertexFormat *vFormat = new0 VertexFormat();
	vFormat->Add(VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0);
	if (mNormalMap)
	{
		vFormat->Add(VertexFormat::AU_NORMAL, VertexFormat::AT_FLOAT3, 0);
	}
	if (mExportTargentBinormal)
	{
		vFormat->Add(VertexFormat::AU_TANGENT, VertexFormat::AT_FLOAT3, 0);
		vFormat->Add(VertexFormat::AU_BINORMAL, VertexFormat::AT_FLOAT3, 0);
	}
	if (mExportColor)
	{
		vFormat->Add(VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT4, 0);
	}
	if (mTextureCoordMap)
	{
		if (1 == mNumTexcoordToExport)
		{
			vFormat->Add(VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0);
		}
		else if (2 == mNumTexcoordToExport)
		{
			vFormat->Add(VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0);
			vFormat->Add(VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 1);
		}
	}
	if (mExportSkin)
	{
		vFormat->Add(VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT4, 1);
		vFormat->Add(VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT4, 2);
	}

	vFormat->Create();

	PX2::VertexBuffer *vBuffer = new0 PX2::VertexBuffer(mVertexMapQuantity, 
		vFormat->GetStride());

	VertexBufferAccessor vBA(vFormat, vBuffer);

	for (int i=0; i<mVertexMapQuantity; i++)
	{
		vBA.Position<Float3>(i) = mVertexMap[i];

		if (mNormalMap)
		{
			vBA.Normal<Float3>(i) = mNormalMap[i];
		}

		if (mColorMap)
		{
			vBA.Color<Float4>(0, i) = Float4(mColorMap[i][0], mColorMap[i][1],
				mColorMap[i][2], mColorMap[i][3]);
		}
		else
		{
			if (mExportColor)
				vBA.Color<Float4>(0, i) = Float4::WHITE;
		}

		if (mAlphaMap)
		{
			vBA.Color<Float4>(0, i) = Float4(mColorMap[i][0], mColorMap[i][1],
				mColorMap[i][2], mAlphaMap[i]);
		}

		if (mTextureCoordMap)
		{
			if (mNumTexcoordToExport == 1)
			{
				vBA.TCoord<Float2>(0, i) = Float2(mTextureCoordMap[i][0], 1.0f-mTextureCoordMap[i][1]);
			}
			else if (mNumTexcoordToExport == 2)
			{
				Float2 texCoord0 = Float2(mTextureCoordMap[i][0], 1.0f-mTextureCoordMap[i][1]);

				vBA.TCoord<Float2>(0, i) = texCoord0;

				if (mTextureCoordMap1)
				{
					vBA.TCoord<Float2>(1, i) = Float2(mTextureCoordMap1[i][0], 1.0f-mTextureCoordMap1[i][1]);
				}
				else
				{
					vBA.TCoord<Float2>(1, i) = texCoord0;
				}
			}
		}
	}
	
	// IndexBuffer
	IndexBuffer *iBuffer = new0 IndexBuffer(3*mFQuantity, 2);
	unsigned short *iData = (unsigned short*)iBuffer->GetData();
	for (int i=0; i<(int)3*mFQuantity; i++)
	{
		iData[i] = (unsigned short)mVFace[i];
	}

	// 创建Mesh
	TriMesh *triMesh = new0 TriMesh(vFormat, vBuffer, iBuffer);
	triMesh->UpdateModelSpace(Renderable::GU_MODEL_BOUND_ONLY);
	if (mExportTargentBinormal)
	{
		triMesh->UpdateModelSpace(Renderable::GU_USE_GEOMETRY);
	}

	MaterialInstance *mi = 0;
	mi = mMaterialInstance;

	triMesh->SetMaterialInstance(mi);
	triMesh->SetShine(mShine);

	return triMesh;
}
예제 #23
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);
}
예제 #24
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);
}
예제 #25
0
//----------------------------------------------------------------------------
void Font::RenderText (TriMesh *mesh, float depth)
{
	VertexFormat *vFormat = mesh->GetVertexFormat();
	VertexBuffer *vBuffer = mesh->GetVertexBuffer();
	IndexBuffer *iBuffer = mesh->GetIndexBuffer();
	if (!vBuffer)
	{
		vBuffer = new0 VertexBuffer(4*mShowNum, vFormat->GetStride(), 
			Buffer::BU_DYNAMIC);
		iBuffer = new0 IndexBuffer(6*mShowNum, 2);
		unsigned short *indices = (unsigned short*)iBuffer->GetData();
		for (int i=0; i<mShowNum; i++)
		{
			unsigned short v0 = i*4 + 0;
			unsigned short v1 = i*4 + 1;
			unsigned short v2 = i*4 + 2;
			unsigned short v3 = i*4 + 3;
			*indices++ = v0;
			*indices++ = v1;
			*indices++ = v2;
			*indices++ = v0;
			*indices++ = v2;
			*indices++ = v3;
		}

		mesh->SetVertexBuffer(vBuffer);
		mesh->SetIndexBuffer(iBuffer);
	}
	else
	{
		int vertexNum = vBuffer->GetNumElements();
		if (vertexNum < 4*mShowNum)
		{
			vBuffer = new0 VertexBuffer(4*mShowNum, vFormat->GetStride(), 
				Buffer::BU_DYNAMIC);
			iBuffer = new0 IndexBuffer(6*mShowNum, 2);
			unsigned short *indices = (unsigned short*)iBuffer->GetData();
			for (int i=0; i<mShowNum; i++)
			{
				unsigned short v0 = i*4 + 0;
				unsigned short v1 = i*4 + 1;
				unsigned short v2 = i*4 + 2;
				unsigned short v3 = i*4 + 3;
				*indices++ = v0;
				*indices++ = v1;
				*indices++ = v2;
				*indices++ = v0;
				*indices++ = v2;
				*indices++ = v3;
			}

			mesh->SetVertexBuffer(vBuffer);
			mesh->SetIndexBuffer(iBuffer);
		}
	}

	VertexBufferAccessor vba(vFormat, vBuffer);

	for (int i=0; i<mShowNum; i++)
	{
		FontDrawRect &rect = mDrawRects[i];

		vba.Position<Float3>(4*i)	= Float3(rect.Rect.Left, depth, rect.Rect.Bottom);
		vba.Color<Float4>(0, 4*i)	= rect.Color;
		vba.TCoord<Float2>(0, 4*i)	= Float2(rect.RectUV.Left, rect.RectUV.Bottom);

		vba.Position<Float3>(4*i+1) = Float3(rect.Rect.Right, depth, rect.Rect.Bottom);
		vba.Color<Float4>(0, 4*i+1) = rect.Color;
		vba.TCoord<Float2>(0, 4*i+1)= Float2(rect.RectUV.Right, rect.RectUV.Bottom);

		vba.Position<Float3>(4*i+2) = Float3(rect.Rect.Right, depth, rect.Rect.Top);
		vba.Color<Float4>(0, 4*i+2) = rect.Color;
		vba.TCoord<Float2>(0, 4*i+2)= Float2(rect.RectUV.Right, rect.RectUV.Top);

		vba.Position<Float3>(4*i+3) = Float3(rect.Rect.Left, depth, rect.Rect.Top);
		vba.Color<Float4>(0, 4*i+3) = rect.Color;
		vba.TCoord<Float2>(0, 4*i+3)= Float2(rect.RectUV.Left, rect.RectUV.Top);
	}
	vBuffer->SetNumElements(4*mShowNum);
	iBuffer->SetNumElements(6*mShowNum);
	mesh->UpdateModelSpace(Renderable::GU_MODEL_BOUND_ONLY);
	Renderer::UpdateAll(vBuffer);
	Renderer::UpdateAll(iBuffer);

	mShowNum = 0;
}
예제 #26
0
//----------------------------------------------------------------------------
ImageProcessing::ImageProcessing (int numCols, int numRows, int numTargets)
:
mNumCols(numCols),
mNumRows(numRows),
mNumTargets(numTargets)
{
	assertion(mNumCols > 1 && mNumRows > 0, "Invalid bound.\n");
	assertion(mNumTargets > 0, "Invalid number of targets.\n");

	mColSpacing = 1.0f/(float)(mNumCols - 1);
	mRowSpacing = 1.0f/(float)(mNumRows - 1);

	// 将相机从[-1,-1]^2 x [0,1]匹配到[0,1]^3
	mCamera = new0 Camera(false);
	mCamera->SetFrustum(0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f);
	mCamera->SetFrame(APoint::ORIGIN, AVector::UNIT_Z, AVector::UNIT_Y,
		AVector::UNIT_X);

	// 创建顶点格式
	VertexFormat* vformat = new0 VertexFormat(2);
	vformat->SetAttribute(0, 0, 0, VertexFormat::AT_FLOAT3,
		VertexFormat::AU_POSITION, 0);
	vformat->SetAttribute(1, 0, 3*sizeof(float), VertexFormat::AT_FLOAT2,
		VertexFormat::AU_TEXCOORD, 0);
	vformat->SetStride(5*sizeof(float));

	// 创建顶点缓冲区
	int vstride = vformat->GetStride();
	VertexBuffer* vbuffer = new0 VertexBuffer(4, vstride);
	VertexBufferAccessor vba(vformat, vbuffer);

	float xmin, xmax, ymin, ymax;
	Float2 tc0, tc1, tc2, tc3;
	if (VertexShader::GetProfile() == VertexShader::VP_ARBVP1)
	{
		xmin = 0.0f;
		xmax = 1.0f;
		ymin = 0.0f;
		ymax = 1.0f;
		tc0 = Float2(0.0f, 0.0f);
		tc1 = Float2(1.0f, 0.0f);
		tc2 = Float2(1.0f, 1.0f);
		tc3 = Float2(0.0f, 1.0f);
	}
	else
	{
		xmin = -0.5f*mColSpacing;
		xmax = 1.0f - 0.5f*mColSpacing;
		ymin = +0.5f*mRowSpacing;
		ymax = 1.0f + 0.5f*mRowSpacing;
		tc0 = Float2(0.0f, 1.0f);
		tc1 = Float2(1.0f, 1.0f);
		tc2 = Float2(1.0f, 0.0f);
		tc3 = Float2(0.0f, 0.0f);
	}

	vba.Position<Float3>(0) = Float3(xmin, ymin, 0.0f);
	vba.Position<Float3>(1) = Float3(xmax, ymin, 0.0f);
	vba.Position<Float3>(2) = Float3(xmax, ymax, 0.0f);
	vba.Position<Float3>(3) = Float3(xmin, ymax, 0.0f);
	vba.TCoord<Float2>(0, 0) = tc0;
	vba.TCoord<Float2>(0, 1) = tc1;
	vba.TCoord<Float2>(0, 2) = tc2;
	vba.TCoord<Float2>(0, 3) = tc3;

	// 创建顶点索引缓冲区
	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;

	// 创建网格
	mRectangle = new0 TriMesh(vformat, vbuffer, ibuffer);

	// 创建顶点着色器
	CreateVertexShader();

	// 创建RT
	mTargets = new1<RenderTargetPtr>(mNumTargets);
	for (int i = 0; i < mNumTargets; ++i)
	{
		mTargets[i] = new0 RenderTarget(1, Texture::TF_A32B32G32R32F,
			mNumCols, mNumRows, false, false, false);
	}
}
예제 #27
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);
}
예제 #28
0
//----------------------------------------------------------------------------
void PlanarShadows::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 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));
}
예제 #30
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();
}