Reputation: 11
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