Question

I am attempting to learn SharpDX via DirectX tutorials. I have this line of code in the C++ project I am working from:

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();

And I would like to know how to covert this over to C#. I am 99% sure I need to be using System.IO.FileStream but I am unsure how all the C++ stuff works. What is really messing me up is the fin >> ignore >> vcount; If someone can explain to me how to do the same thing in C# I can probably figure it out from there.

As requested the text file resembles this:

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
…
}
Was it helpful?

Solution

ignore is declared as a std::string. It appears that the original author of the code you are looking at was not aware of the std::istream::ignore function and is using a local variable to read in elements of the file they are simply discarding (that is, he didn't care about). So the lines like:

fin >> ignore >> vcount;

Are reading in a string element (basically up to the first whitespace) and dumping it into the local string he is ignoring, and then reading in the vcount value (which he is storing as an unsigned int).

If you are going to port this to C#, you could do the same thing (read in parts of the file and simply discard them) and it would be a fairly direct port.

As an example (not tested):

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
}

OTHER TIPS

Thanks to Zac Howland's answer I was able to get everything working. For anyone else trying to convert Frank Luna's book from DirectX to SharpDX I hope this helps. Here is what I ended up doing:

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();
}

As always is someone sees a problem with the code or a better way of doing something I am always open to ideas.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top