Beispiel #1
0
void FW::profilePush(const char* id)
{
    if (!s_profileStarted)
        return;
    if (!Thread::isMain())
        fail("profilePush() can only be used in the main thread!");

    // Find or create token.

    S32 token;
    S32* found = s_profilePointerToToken.search(id);
    if (found)
        token = *found;
    else
    {
        found = s_profileStringToToken.search(id);
        if (found)
            token = *found;
        else
        {
            token = s_profileStringToToken.getSize();
            s_profileStringToToken.add(id, token);
        }
        s_profilePointerToToken.add(id, token);
    }

    // Find or create timer.

    Vec2i timerKey(-1, token);
    if (s_profileStack.getSize())
        timerKey.x = s_profileStack.getLast();

    S32 timerIdx;
    found = s_profileTimerHash.search(timerKey);
    if (found)
        timerIdx = *found;
    else
    {
        timerIdx = s_profileTimers.getSize();
        s_profileTimerHash.add(timerKey, timerIdx);
        ProfileTimer& timer = s_profileTimers.add();
        timer.id = id;
        timer.parent = timerKey.x;
        if (timerKey.x != -1)
            s_profileTimers[timerKey.x].children.add(timerIdx);
    }

    // Push timer.

    if (s_profileStack.getSize() == 1)
        s_profileTimers[s_profileStack[0]].timer.start();
    s_profileStack.add(timerIdx);
    if (s_profileStack.getSize() > 1)
        s_profileTimers[timerIdx].timer.start();
}
Beispiel #2
0
void FW::popMemOwner(void)
{
#if FW_MEM_DEBUG
    U32 threadID = Thread::getID();
    Array<const char*>* stack = s_memOwnerStacks.search(threadID);
    if (stack)
    {
        stack->removeLast();
        if (!stack->getSize())
        {
            s_memOwnerStacks.remove(threadID);
            if (!s_memOwnerStacks.getSize())
                s_memOwnerStacks.reset();
        }
    }
#endif
}
void FW::exportWavefrontMesh(BufferedOutputStream& stream, const MeshBase* mesh, const String& fileName)
{
    FW_ASSERT(mesh);
    Mesh<VertexPNT> pnt(*mesh);

    // Extract base name.

    String dirName = fileName.getDirName();
    String baseName = fileName.getFileName();
    int idx = baseName.indexOf('.');
    if (idx != -1)
        baseName = baseName.substring(0, idx);

    // Write OBJ file.

    if (baseName.getLength())
    {
        stream.writef("mtllib %s.mtl\n", baseName.getPtr());
        stream.writef("\n");
    }

    for (int i = 0; i < pnt.numVertices(); i++)
    {
        const VertexPNT& v = pnt.vertex(i);
        stream.writef("v %g %g %g\n", v.p.x, v.p.y, v.p.z);
    }
    stream.writef("\n");

    for (int i = 0; i < pnt.numVertices(); i++)
    {
        const VertexPNT& v = pnt.vertex(i);
        stream.writef("vt %g %g\n", v.t.x, 1.0f - v.t.y);
    }
    stream.writef("\n");

    for (int i = 0; i < pnt.numVertices(); i++)
    {
        const VertexPNT& v = pnt.vertex(i);
        stream.writef("vn %g %g %g\n", v.n.x, v.n.y, v.n.z);
    }

    for (int i = 0; i < pnt.numSubmeshes(); i++)
    {
        stream.writef("\n");
        if (baseName.getLength())
            stream.writef("usemtl %d\n", i);

        const Array<Vec3i>& tris = pnt.indices(i);
        for (int j = 0; j < tris.getSize(); j++)
        {
            Vec3i v = tris[j] + 1;
            stream.writef("f %d/%d/%d %d/%d/%d %d/%d/%d\n",
                v.x, v.x, v.x,
                v.y, v.y, v.y,
                v.z, v.z, v.z);
        }
    }

    // No base name => do not write materials.

    if (!baseName.getLength())
        return;

    // Hash textures and determine file names.

    Hash<const Image*, String> texImageHash;
    Set<String> texNameSet;

    for (int i = 0; i < pnt.numSubmeshes(); i++)
    {
        const MeshBase::Material& mat = pnt.material(i);
        for (int j = 0; j < MeshBase::TextureType_Max; j++)
        {
            const Texture& tex = mat.textures[j];
            if (!tex.exists() || texImageHash.contains(tex.getImage()))
                continue;

            // Extract name from ID.

            String name = tex.getID().getFileName();
            int idx = name.indexOf('.');
            if (idx != -1)
                name = name.substring(0, idx);

            // No name => generate one.

            if (!name.getLength())
                name = sprintf("tex%d", texImageHash.getSize());

            // Ensure that the name is unique.

            String oldName = name;
            for (int k = 0; texNameSet.contains(name); k++)
                name = sprintf("%s_%d", oldName.getPtr(), k);

            // Append format postfix.

            name += ".png";

            // Record.

            texImageHash.add(tex.getImage(), name);
            texNameSet.add(name);
        }
    }

    // Write MTL file.

    File mtlFile(dirName + '/' + baseName +  ".mtl", File::Create);
    BufferedOutputStream mtlOut(mtlFile);
    for (int i = 0; i < pnt.numSubmeshes(); i++)
    {
        if (i)
            mtlOut.writef("\n");

        const MeshBase::Material& mat = pnt.material(i);
        mtlOut.writef("newmtl %d\n", i);
        mtlOut.writef("Ka 0 0 0\n");
        mtlOut.writef("Kd %g %g %g\n", mat.diffuse.x, mat.diffuse.y, mat.diffuse.z);
        mtlOut.writef("d %g\n", mat.diffuse.w);
        mtlOut.writef("Ks %g %g %g\n", mat.specular.x, mat.specular.y, mat.specular.z);
        mtlOut.writef("Ns %g\n", mat.glossiness);

        if (texImageHash.contains(mat.textures[MeshBase::TextureType_Diffuse].getImage()))
            mtlOut.writef("map_Kd %s\n", texImageHash[mat.textures[MeshBase::TextureType_Diffuse].getImage()].getPtr());

        if (texImageHash.contains(mat.textures[MeshBase::TextureType_Alpha].getImage()))
            mtlOut.writef("map_d %s\n", texImageHash[mat.textures[MeshBase::TextureType_Alpha].getImage()].getPtr());

        if (texImageHash.contains(mat.textures[MeshBase::TextureType_Displacement].getImage()))
            mtlOut.writef("disp -mm %g %g %s\n",
                mat.displacementBias / mat.displacementCoef, mat.displacementCoef,
                texImageHash[mat.textures[MeshBase::TextureType_Displacement].getImage()].getPtr());

        if (texImageHash.contains(mat.textures[MeshBase::TextureType_Normal].getImage()))
            mtlOut.writef("bump %s\n", texImageHash[mat.textures[MeshBase::TextureType_Normal].getImage()].getPtr());

        if (texImageHash.contains(mat.textures[MeshBase::TextureType_Environment].getImage()))
            mtlOut.writef("refl -type sphere %s\n", texImageHash[mat.textures[MeshBase::TextureType_Environment].getImage()].getPtr());
    }
    mtlOut.flush();

    // Write textures.

    for (int i = texImageHash.firstSlot(); i != -1; i = texImageHash.nextSlot(i))
    {
        const Image* texImage = texImageHash.getSlot(i).key;
        const String& texName = texImageHash.getSlot(i).value;
        exportImage(dirName + '/' + texName, texImage);
    }
}