diff --git a/Code/OysterGraphics/FileLoader/ModelLoader.cpp b/Code/OysterGraphics/FileLoader/ModelLoader.cpp index 0fe623a9..8a2d52b8 100644 --- a/Code/OysterGraphics/FileLoader/ModelLoader.cpp +++ b/Code/OysterGraphics/FileLoader/ModelLoader.cpp @@ -2,6 +2,7 @@ #include "..\Core\Dx11Includes.h" #include "..\Core\Core.h" #include "ObjReader.h" +#include "..\..\Misc\Resource\OysterResource.h" HRESULT CreateWICTextureFromFileEx( ID3D11Device* d3dDevice, ID3D11DeviceContext* d3dContext, @@ -38,10 +39,27 @@ void Oyster::Graphics::Loading::UnloadTexture(void* data) void Oyster::Graphics::Loading::LoadOBJ(const wchar_t filename[], Oyster::Resource::CustomData& out) { - OBJReader obj; - obj.readOBJFile(filename); - Model::ModelInfo* info; - info = obj.toModel(); + FileLoaders::ObjReader* obj = FileLoaders::ObjReader::LoadFile(filename); + Model::ModelInfo* info = new Model::ModelInfo(); + Oyster::FileLoaders::ObjReader::Vertex* vdata; + int count; + obj->GetVertexData(&vdata, count); + info->Vertices = new Core::Buffer(); + Core::Buffer::BUFFER_INIT_DESC desc; + desc.ElementSize = sizeof(FileLoaders::ObjReader::Vertex); + desc.NumElements = count; + desc.InitData = vdata; + desc.Type = Core::Buffer::VERTEX_BUFFER; + desc.Usage = Core::Buffer::BUFFER_USAGE_IMMUTABLE; + + info->VertexCount = count; + info->Vertices->Init(desc); + info->Indexed = false; + + void* texture = Oyster::Resource::OysterResource::LoadResource((std::wstring(filename)+ L".png").c_str(),Graphics::Loading::LoadTexture); + + info->Material.push_back((ID3D11ShaderResourceView*)texture); + out.loadedData = info; out.resourceUnloadFnc = Oyster::Graphics::Loading::UnloadOBJ; } diff --git a/Code/OysterGraphics/FileLoader/ObjReader.cpp b/Code/OysterGraphics/FileLoader/ObjReader.cpp index 923f0747..e34ca8fd 100644 --- a/Code/OysterGraphics/FileLoader/ObjReader.cpp +++ b/Code/OysterGraphics/FileLoader/ObjReader.cpp @@ -1,152 +1,285 @@ -#include "OBJReader.h" -#include "..\Definitions\GraphicalDefinition.h" -#include +#include "ObjReader.h" +#include "Utilities.h" +#include "..\Core\Core.h" #include -#include "GeneralLoader.h" +#include using namespace std; -OBJReader::OBJReader() +using namespace Oyster::FileLoaders; +using namespace Oyster; +using namespace Oyster::Math; + +ObjReader *ObjReader::LoadFile(std::wstring fileName, Oyster::Math::Float4x4 transform) { - _mPos = 0; - _mNormal = 0; - _mTexel = 0; -} + static std::map cache; -OBJReader::~OBJReader() -{ + ObjReader *reader = NULL; -} - -void OBJReader::readOBJFile( std::wstring fileName ) -{ - std::fstream inStream; - std::string typeOfData = " "; - float vertexData; - std::string face1, face2, face3; - - inStream.open( fileName + L".obj", std::fstream::in ); - - if( inStream.is_open() ) + if (cache.count(fileName)) { - while( !inStream.eof() ) + reader = cache[fileName]; + } + else + { + reader = new ObjReader(); + reader->ParseFile(fileName + L".obj", transform); + + cache[fileName] = reader; + } + + return reader; +} + +ObjReader::ObjReader(void) +{ +} + + +ObjReader::~ObjReader(void) +{ +} + +void ObjReader::ParseFile(std::wstring fileName, Float4x4 transform) +{ + wifstream input; + input.open(fileName.c_str()); + + if(!input.is_open()) + { + return; + } + + wstring path; + //Utility::String::ExtractDirPath(path,fileName,'\\'); + + std::vector VertexList; + std::vector vList; + std::vector nList; + std::vector uvList; + Vertex vertex1, vertex2, vertex3; + Float3 face[3]; + Float3 position, normal; + Float2 uv; + wstring s; + + while(!input.eof()) + { + getline(input,s); + int offset = (int)s.find(' '); + + if(offset!=-1) { - inStream >> typeOfData; + wstring c = s.substr(0,offset); - if( typeOfData == "v" ) + if(c==L"v") { - Oyster::Math::Float3 position; - - inStream >> vertexData; - position.x = vertexData; - - inStream >> vertexData; - position.y = vertexData; - - inStream >> vertexData; - position.z = vertexData; - - _mVertexCoord.push_back( position ); - + position = readVertex(offset,s); + vList.push_back(position); } - else if( typeOfData == "vt" ) + else if(c==L"vt") { - Oyster::Math::Float2 texel; - inStream >> vertexData; - texel.x = vertexData; - - inStream >> vertexData; - texel.y = 1 - vertexData; - - _mVertexTexture.push_back( texel ); + uv = readUV(offset,s); + uvList.push_back(uv); } - else if( typeOfData == "vn" ) + else if(c==L"vn") { - Oyster::Math::Float3 normal; - inStream >> vertexData; - normal.x = vertexData; - - inStream >> vertexData; - normal.y = vertexData; - - inStream >> vertexData; - normal.z = vertexData; - - _mVertexNormal.push_back( normal ); + normal = readNormal(offset,s); + nList.push_back(normal); } - else if( typeOfData == "f" ) + else if(c==L"f") { - inStream >> face1; - stringSplit( face1 ); - - addToOBJarray(); + readFace(offset, s, face); - inStream >> face2; - stringSplit( face2 ); + vertex1.Position = vList[(int)face[0].x]; + vertex1.UV = uvList[(int)face[0].y]; + vertex1.Normal = nList[(int)face[0].z]; - addToOBJarray(); + vertex2.Position = vList[(int)face[1].x]; + vertex2.UV = uvList[(int)face[1].y]; + vertex2.Normal = nList[(int)face[1].z]; - inStream >> face3; - stringSplit( face3 ); + vertex3.Position = vList[(int)face[2].x]; + vertex3.UV = uvList[(int)face[2].y]; + vertex3.Normal = nList[(int)face[2].z]; - addToOBJarray(); + VertexList.push_back(vertex1); + VertexList.push_back(vertex2); + VertexList.push_back(vertex3); + } + else if(c==L"mtllib") + { + //this->materials = GetMaterials(path + s.substr(offset+1)); } } } - inStream.close(); + input.close(); - Mat = Oyster::Resource::OysterResource::LoadResource((fileName + L".png").c_str(),Oyster::Graphics::Loading::LoadTexture); -} + this->numVertices = VertexList.size(); + this->vertices = new Vertex[this->numVertices]; -Oyster::Graphics::Model::ModelInfo* OBJReader::toModel() -{ - Oyster::Graphics::Core::Buffer* b = new Oyster::Graphics::Core::Buffer(); - Oyster::Graphics::Core::Buffer::BUFFER_INIT_DESC desc; - Oyster::Graphics::Model::ModelInfo* modelInfo = new Oyster::Graphics::Model::ModelInfo(); - - desc.ElementSize = 32; - desc.InitData = &this->_myOBJ[0]; - desc.NumElements = this->_myOBJ.size(); - desc.Type = Oyster::Graphics::Core::Buffer::BUFFER_TYPE::VERTEX_BUFFER; - desc.Usage = Oyster::Graphics::Core::Buffer::BUFFER_DEFAULT; - HRESULT hr = S_OK; - - hr = b->Init(desc); - if(FAILED(hr)) + for(size_t i=0;inumVertices;++i) { - //Something isn't okay here + vertices[i].Position=Math::Float4(VertexList[i].Position,1); + vertices[i].Normal=Math::Float4(VertexList[i].Normal,0); + vertices[i].UV = VertexList[i].UV; } - modelInfo->Indexed = false; - modelInfo->VertexCount = (int)desc.NumElements; - modelInfo->Vertices = b; - modelInfo->Material.push_back((ID3D11ShaderResourceView*)Mat); - - return modelInfo; } -//Private functions -void OBJReader::stringSplit( std::string strToSplit ) +void ObjReader::GetVertexData(Vertex **vertex,int &numVertex, std::map &Textures) { - char delim = '/'; - std::string vPos, vNormal, vTexel; - std::stringstream aStream(strToSplit); - getline( aStream, vPos, delim ); - getline( aStream, vTexel, delim ); - getline( aStream, vNormal ); - - _mPos = atoi( vPos.c_str() ); - _mNormal = atoi( vNormal.c_str() ); - _mTexel = atoi( vTexel.c_str() ); - + numVertex=(int)this->numVertices; + (*vertex)=this->vertices; + //Textures = this->materials; } -void OBJReader::addToOBJarray() +void ObjReader::GetVertexData(Vertex **vertex,int &numVertex) { - OBJFormat temp; + numVertex=(int)this->numVertices; + (*vertex)=this->vertices; +} - temp._d3VertexCoord = _mVertexCoord.at( _mPos - 1 ); - temp._d3VertexNormal = _mVertexNormal.at( _mNormal - 1 ); - temp._d3VertexTexture = _mVertexTexture.at( _mTexel - 1 ); +Float3 ObjReader::extract(std::string d1) +{ + Float3 data; + int offset=(int)d1.find('/'); + //string d1 = Utility::String::WStringToString(d,d1); + data.x=(float)atoi(d1.substr(1,offset).c_str())-1; - _myOBJ.push_back( temp ); -} \ No newline at end of file + int newOffset = (int)d1.find('/',offset+1); + string d2=d1.substr(offset+1,newOffset-offset-1); + data.y=(float)atoi(d2.c_str())-1; + offset=newOffset; + + newOffset = (int)d1.find('/',offset+1); + string d3=d1.substr(offset+1,newOffset-offset-1); + data.z=(float)atoi(d3.c_str())-1; + + return data; +} + +Float3 ObjReader::readVertex(int offset,wstring s) +{ + int newOffset = (int)s.find(' ',offset+1); + Float3 vertex; + string d; + Utility::String::WStringToString(s.substr(offset,newOffset-offset), d); + vertex.x = (float)atof(d.c_str()); + offset=newOffset; + + newOffset = (int)s.find(' ',offset+1); + Utility::String::WStringToString(s.substr(offset,newOffset-offset), d); + vertex.y = (float)atof(d.c_str()); + offset=newOffset; + + newOffset = (int)s.find(' ',offset+1); + Utility::String::WStringToString(s.substr(offset,newOffset-offset), d); + vertex.z = (float)atof(d.c_str()); + + return vertex; +} + +Float2 ObjReader::readUV(int offset,wstring s) +{ + int newOffset = (int)s.find(' ',offset+1); + Float2 uv; + string d; + Utility::String::WStringToString(s.substr(offset,newOffset-offset), d); + uv.x =(float)atof(d.c_str()); + offset=newOffset; + + newOffset = (int)s.find(' ',offset+1); + Utility::String::WStringToString(s.substr(offset,newOffset-offset), d); + uv.y =1- (float)atof(d.c_str()); + offset=newOffset; + + return uv; +} + +Float3 ObjReader::readNormal(int offset,wstring s) +{ + int newOffset = (int)s.find(' ',offset+1); + Float3 vertex; + string d; + Utility::String::WStringToString(s.substr(offset,newOffset-offset), d); + vertex.x = (float)atof(d.c_str()); + offset=newOffset; + + newOffset = (int)s.find(' ',offset+1); + Utility::String::WStringToString(s.substr(offset,newOffset-offset), d); + vertex.y = (float)atof(d.c_str()); + offset=newOffset; + + newOffset = (int)s.find(' ',offset+1); + Utility::String::WStringToString(s.substr(offset,newOffset-offset), d); + vertex.z = (float)atof(d.c_str()); + + return vertex; +} + +void ObjReader::readFace(int offset,wstring s1, Oyster::Math::Float3 face[3]) +{ + string s; + Utility::String::WStringToString(s1,s); + + int newOffset = (int)s.find(' ',offset+1); + string point1 = s.substr(offset,newOffset-offset); + + offset = newOffset; + newOffset = (int)s.find(' ',offset+1); + string point2 = s.substr(offset,newOffset-offset); + + offset = newOffset; + newOffset = (int)s.find(' ',offset+1); + string point3 = s.substr(offset,newOffset-offset); + + face[0] = extract(point1); + face[1] = extract(point2); + face[2] = extract(point3); +} + +std::map ObjReader::GetMaterials(std::wstring fileName) +{ + ifstream input; + input.open(fileName.c_str()); + + std::map materials; + ID3D11ShaderResourceView *srv; + string texture; + string s; + string path; + //Utility::String::extractDirPath(path,fileName,'\\'); + if(!input.is_open()) + return materials; + + while(!input.eof()) + { + getline(input,s); + int offset = (int)s.find(' '); + if(offset!=-1) + { + string c = s.substr(0,offset); + if(c=="map_Kd") + { + texture = path+s.substr(offset+1); + //D3DX11CreateShaderResourceViewFromFile(Oyster::Core::Device,texture.c_str(), NULL, NULL, &srv, NULL); + //materials["Diffuse"] = srv; + } + if(c=="map_G") + { + texture = path+s.substr(offset+1); + //D3DX11CreateShaderResourceViewFromFile(Oyster::Core::Device,texture.c_str(), NULL, NULL, &srv, NULL); + //materials["Glow"] = srv; + } + if(c=="map_Ks") + { + texture = path+s.substr(offset+1); + //D3DX11CreateShaderResourceViewFromFile(Oyster::Core::Device,texture.c_str(), NULL, NULL, &srv, NULL); + //materials["Specular"] = srv; + } + } + } + input.close(); + + return materials; +} diff --git a/Code/OysterGraphics/FileLoader/ObjReader.h b/Code/OysterGraphics/FileLoader/ObjReader.h index c4a2e399..bb361b07 100644 --- a/Code/OysterGraphics/FileLoader/ObjReader.h +++ b/Code/OysterGraphics/FileLoader/ObjReader.h @@ -1,56 +1,43 @@ -#ifndef OBJREADER_H -#define OBJREADER_H -#include "..\..\Misc\Utilities.h" -#include "..\..\OysterMath\OysterMath.h" -#include "..\Model\ModelInfo.h" +#pragma once +#include "../Model/ModelInfo.h" +#include "../../OysterMath/OysterMath.h" -//#include - - - -class OBJReader +namespace Oyster { - public: - struct OBJFormat + namespace FileLoaders + { + class ObjReader { - Oyster::Math::Float3 _d3VertexCoord; - Oyster::Math::Float2 _d3VertexTexture; - Oyster::Math::Float3 _d3VertexNormal; - }; - - struct OBJMaterialData - { - std::string _name; - std::string _mapKd; - float _kd[3]; - float _ka[3]; - float _tf[3]; - float _ni; - - OBJMaterialData() + public: + struct Vertex { - _name = " "; - _mapKd = " "; - } + Oyster::Math::Float3 Position; + Oyster::Math::Float2 UV; + Oyster::Math::Float3 Normal; + }; + + static ObjReader *LoadFile(std::wstring fileName, Oyster::Math::Float4x4 transform = Oyster::Math::Float4x4::identity); + + ObjReader(void); + ~ObjReader(void); + + void GetVertexData(Vertex **vertex,int &numVertex, std::map &textures); + void GetVertexData(Vertex **vertex,int &numVertex); + + private: + Vertex *vertices; + size_t numVertices; + std::map materials; + + void ParseFile(std::wstring fileName, Oyster::Math::Float4x4 transform = Oyster::Math::Float4x4::identity); + + Oyster::Math::Float3 extract(std::string d); + Oyster::Math::Float3 readVertex(int offset,std::wstring s); + Oyster::Math::Float2 readUV(int offset,std::wstring s); + Oyster::Math::Float3 readNormal(int offset,std::wstring s); + void readFace(int offset,std::wstring s, Oyster::Math::Float3 face[3]); + + std::map GetMaterials(std::wstring fileName); }; - std::vector _myOBJ; - private: - - std::vector _mVertexCoord, _mVertexNormal; - std::vector _mVertexTexture; - - int _mNrOfCoords, _mNrOfNormals, _mNrOfTexels, _mNrOfFaces; - int _mPos, _mNormal, _mTexel; - void stringSplit( std::string strToSplit ); - void addToOBJarray(); - void* Mat; - - public: - OBJReader(); - ~OBJReader(); - - void readOBJFile( std::wstring fileName); - Oyster::Graphics::Model::ModelInfo* toModel(); - -}; -#endif \ No newline at end of file + } +} \ No newline at end of file