Marko
Marko

Reputation: 11

Bug in loading OBJ file to project not using Assimp

can somebody please help me with my program? I have a problem with loading normals from obj file, when i load my file without normals it displays correctly the obj in worldspace, but when i try to load it with normals it changes the shape of my obj... Here is my code for all this:

myFile.open("3dModels/Box.obj");
        struct  Vertex
        {
            XMFLOAT4 Pos;
            XMFLOAT3 Normal;
            //XMFLOAT2 Texture;
        };  
        std::vector<Vertex> vertices(14);

        std::vector<unsigned int> indices;
        std::vector<UINT> normalIndice;

        std::string Space_delimeter = " ";
        int index=0;
        int index1 = 0;
        int index2= 0;
        while (std::getline(myFile, line)) {
            std::istringstream lineStream(line);
            std::string lineType;
            lineStream >> lineType;
            if (line.starts_with("v "))
            {
                
                Vertex vertex;
                lineStream >> vertex.Pos.x >> vertex.Pos.y >> vertex.Pos.z;
                vertices[index1].Pos.x = vertex.Pos.x;
                vertices[index1].Pos.y = vertex.Pos.y;
                vertices[index1].Pos.z = vertex.Pos.z;
                vertices[index1].Pos.w = 1.0f;
                index1++;
            }
            else if (lineType == "vn") {
                // vertex normal line
                
                float nx, ny, nz;
                lineStream >> nx >> ny >> nz;
                vertices[index].Normal.x = nx;
                vertices[index].Normal.y = ny;
                vertices[index].Normal.z = nz;
                index++;

            }
            else if (lineType == "vt") {
                //CURENTLY NOT USING TEXTURES
                // vertex texture line
                float u, v;
                lineStream >> u >> v;
                //vertices[index2].Texture.x = u;
                //vertices[index2].Texture.y = v;
                index2++;
            }
            else if (line.starts_with("f "))
            {
                std::vector<std::string> values{};
                size_t pos = 0;
                while ((pos = line.find(Space_delimeter)) != string::npos) {
                    pos = line.find(Space_delimeter);
                    values.push_back(line.substr(0, pos));
                    line.erase(0, pos + Space_delimeter.length());
                }
                values.push_back(line.substr(0, pos));
                
                for (int i=1;i<values.size();i++)
                {
                    std::string Slash_delimeter = "/";
                    std::string linePart = values[i];

                    size_t pos1 = linePart.find(Slash_delimeter);
                    std::string valueStr = linePart.substr(0, pos1);
                    //Converting from string to int (vertices)
                    unsigned int indice = 0;
                    for (int j = 0; j < valueStr.length(); j++) {
                        indice = indice * 10 + (valueStr[j] - '0');
                    }
                    indices.push_back(indice - 1);
                    //Setting normals indices
                    
                    linePart= linePart.erase(0, linePart.find(Slash_delimeter) + Slash_delimeter.length());
                    linePart = linePart.erase(0, linePart.find(Slash_delimeter) + Slash_delimeter.length());
                    linePart = linePart.erase(0, linePart.find(Slash_delimeter) + Slash_delimeter.length());
                    //Converting from string to int (normals)
                    unsigned int indice1=0;
                    for (int j = 0; j < linePart.length(); j++) {
                        indice1 = indice1 * 10 + (linePart[j] - '0');
                    }
                    normalIndice.push_back(indice1-1);
                }
            }

        }
    
        AddStaticBind(std::make_unique<PlaneVertexBuffer>(gfx, vertices));

        auto pvs = std::make_unique<VertexShader>(gfx, L"VertexShader.cso");
        auto pvsbc = pvs->GetBytecode();
        AddStaticBind(std::move(pvs));
        
        AddStaticBind(std::make_unique<PixelShader>(gfx, L"PixelShader.cso"));

               
        AddStaticIndexBuffer(std::make_unique<IndexBuffer>(gfx, indices,normalIndice));

        //auto type =IndexBuffer::IndiceType::NormalIndice;
        //AddStaticNormalIndexBuffer(std::make_unique<IndexBuffer>(gfx, normalIndice,type));

        const std::vector<D3D11_INPUT_ELEMENT_DESC> ied =
        {
            {"Position", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,D3D11_INPUT_PER_VERTEX_DATA, 0},
            {"Normal", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0,D3D11_APPEND_ALIGNED_ELEMENT,D3D11_INPUT_PER_VERTEX_DATA, 0}
        };
        AddStaticBind(std::make_unique<InputLayout>(gfx, ied, pvsbc));

        AddStaticBind(std::make_unique<Topology>(gfx, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST));

Here is index Buffer

IndexBuffer::IndexBuffer(Graphics& gfx, const std::vector<unsigned int>& indices, const std::vector<unsigned int>& normalIndices)
    :
    count((UINT)indices.size()+normalIndices.size())
{
    
    std::vector<Face> faces(indices.size());
    for (int i = 0; i < indices.size(); i++) {
        faces[i]=(Face(indices[i], normalIndices[i]));
    }
    D3D11_BUFFER_DESC ibd = {};
    ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
    ibd.Usage = D3D11_USAGE_DEFAULT;
    ibd.CPUAccessFlags = 0u;
    ibd.MiscFlags = 0u;
    ibd.ByteWidth = UINT(count * sizeof(unsigned int));
    ibd.StructureByteStride = sizeof(unsigned int);
    D3D11_SUBRESOURCE_DATA isd = {};
    isd.pSysMem = faces.data();
    GetDevice(gfx)->CreateBuffer(&ibd, &isd, &pIndexBuffer);
}

And Here is my Vertex Shader

cbuffer CBuf
{
    matrix transform;
    matrix model;
    matrix modelViewProj;
};

struct VSOut
{
    float4 worldPos : Position;
    float3 normal : Normal;
    float4 position : SV_Position;
};

struct VS_INPUT
{
    float3 position : Position;
    float3 normal : Normal;
};

VSOut main(VS_INPUT input )
{
    VSOut vso;
    vso.position = mul(float4(input.position,1.0f), transform);
    vso.normal = input.normal;
    return vso;
}
```[With normals](https://i.sstatic.net/cezHG.png)
[Without normals](https://i.sstatic.net/4AcpB.png)



I have tried bunch of things. Like Creating one more indexbuffer for normals...when i did this the program just overrited indices with normals. I created the struct Faces and added three UINTs and tried to pass it into my IndexBuffer but i end up in error LNK2019 error that i could't solve thats why i did pass vectors to my function of creating index buffer.Thanks in advance!

Upvotes: 1

Views: 107

Answers (0)

Related Questions