0

我正在尝试通过 DirectX 教程学习 SharpDX。我正在使用的 C++ 项目中有这行代码:

std::ifstream fin("Models/skull.txt");

if(!fin)
{
    MessageBox(0, L"Models/skull.txt not found.", 0, 0);
    return;
}

UINT vcount = 0;
UINT tcount = 0;
std::string ignore;

fin >> ignore >> vcount;
fin >> ignore >> tcount;
fin >> ignore >> ignore >> ignore >> ignore;

float nx, ny, nz;
XMFLOAT4 black(0.0f, 0.0f, 0.0f, 1.0f);

std::vector<Vertex> vertices(vcount);
for(UINT i = 0; i < vcount; ++i)
{
    fin >> vertices[i].Pos.x >> vertices[i].Pos.y >> vertices[i].Pos.z;

    vertices[i].Color = black;

    // Normal not used in this demo.
    fin >> nx >> ny >> nz;
}

fin >> ignore;
fin >> ignore;
fin >> ignore;

mSkullIndexCount = 3*tcount;
std::vector<UINT> indices(mSkullIndexCount);
for(UINT i = 0; i < tcount; ++i)
{
    fin >> indices[i*3+0] >> indices[i*3+1] >> indices[i*3+2];
}

fin.close();

我想知道如何将其转换为 C#。我 99% 确定我需要使用System.IO.FileStream,但我不确定所有 C++ 的东西是如何工作的。真正让我困惑的是fin >> ignore >> vcount;如果有人可以向我解释如何在 C# 中做同样的事情,我可能可以从那里弄清楚。

根据要求,文本文件类似于:

VertexCount: 31076
TriangleCount: 60339
VertexList (pos, normal)
{
0.592978 1.92413 -2.62486 0.572276 0.816877 0.0721907
0.571224 1.94331 -2.66948 0.572276 0.816877 0.0721907
0.609047 1.90942 -2.58578 0.572276 0.816877 0.0721907
…
}
TriangleList
{
0 1 2
3 4 5
6 7 8
…
}
4

2 回答 2

1

ignore被声明为std::string. 您正在查看的代码的原始作者似乎不知道该std::istream::ignore函数,并且正在使用局部变量来读取他们只是丢弃的文件元素(也就是说,他并不关心)。所以这些行如下:

fin >> ignore >> vcount;

正在读取字符串元素(基本上直到第一个空格)并将其转储到他忽略的本地字符串中,然后读取vcount值(他将其存储为unsigned int)。

如果您要将其移植到 C#,您可以做同样的事情(读取文件的某些部分并简单地丢弃它们),这将是一个相当直接的移植。

例如(未测试):

using (FileStream file = new FileStream("File.txt", FileMode.Open))
using (StreamReader reader = new StreamReader(file))
{
    // with your sample, this will read "VertexCount: 31076"
    string line = reader.ReadLine();
    string sVCount = line.Substring(line.IndexOf(": ") + 2);
    uint vcount = int.Parse(sVCount);
    // ... read of your code
}
于 2013-10-28T21:56:22.687 回答
0

感谢 Zac Howland 的回答,我能够让一切正常工作。对于其他试图将 Frank Luna 的书从 DirectX 转换为 SharpDX 的人,我希望这会有所帮助。这是我最终做的事情:

private void _buildGeometryBuffers()
{
    System.IO.FileStream fs = new System.IO.FileStream(@"Chapter6/Content/skull.txt", System.IO.FileMode.Open);

    int vcount = 0;
    int tcount = 0;
    //string ignore = string.Empty; // this is not needed for my C# version

    using (System.IO.StreamReader reader = new System.IO.StreamReader(fs))
    {
        // Get the vertice count
        string currentLine = reader.ReadLine();
        string extractedLine = currentLine.Substring(currentLine.IndexOf(" ") + 1);
        vcount = int.Parse(extractedLine);

        // Get the indice count
        currentLine = reader.ReadLine();
        extractedLine = currentLine.Substring(currentLine.IndexOf(" ") + 1);
        tcount = int.Parse(extractedLine);

        // Create vertex buffer
        // Skip over the first 2 lines (these are not the lines we are looking for)
        currentLine = reader.ReadLine();
        currentLine = reader.ReadLine();

        string[] positions = new string[6];
        List<VertexPosCol> vertices = new List<VertexPosCol>(vcount);
        for (int i = 0; i < vcount; ++i)
        {
            currentLine = reader.ReadLine();
            extractedLine = currentLine.Substring(currentLine.IndexOf("\t") + 1);
            positions = extractedLine.Split(' ');
            // We only use the first 3, the last 3 are normals which are not used.
            vertices.Add(new VertexPosCol(
                new Vector3(float.Parse(positions[0]), float.Parse(positions[1]), float.Parse(positions[2])),
                Color.Black)
            );
        }

        BufferDescription vbd = new BufferDescription();
        vbd.Usage = ResourceUsage.Immutable;
        vbd.SizeInBytes = Utilities.SizeOf<VertexPosCol>() * vcount;
        vbd.BindFlags = BindFlags.VertexBuffer;
        vbd.StructureByteStride = 0;
        _vBuffer = Buffer.Create(d3dDevice, vertices.ToArray(), vbd);

        // Create the index buffer
        // Skip over the next 3 lines (these are not the lines we are looking for)
        currentLine = reader.ReadLine();
        currentLine = reader.ReadLine();
        currentLine = reader.ReadLine();

        string[] indexes = new string[6];
        _meshIndexCount = 3 * tcount;
        List<int> indices = new List<int>(_meshIndexCount);
        for (int i = 0; i < tcount; ++i)
        {
            currentLine = reader.ReadLine();
            extractedLine = currentLine.Substring(currentLine.IndexOf("\t") + 1);
            indexes = extractedLine.Split(' ');
            indices.Add(int.Parse(indexes[0]));
            indices.Add(int.Parse(indexes[1]));
            indices.Add(int.Parse(indexes[2]));
        }

        BufferDescription ibd = new BufferDescription();
        ibd.Usage = ResourceUsage.Immutable;
        ibd.SizeInBytes = Utilities.SizeOf<int>() * _meshIndexCount;
        ibd.BindFlags = BindFlags.IndexBuffer;
        _iBuffer = Buffer.Create(d3dDevice, indices.ToArray(), ibd);
    }

    fs.Close();
}

与往常一样,有人看到代码有问题或做某事的更好方法,我总是对想法持开放态度。

于 2013-10-30T18:51:54.913 回答