Commits (27)
...@@ -51,7 +51,7 @@ artifacts/ ...@@ -51,7 +51,7 @@ artifacts/
*.ilk *.ilk
*.meta *.meta
*.obj *.obj
!hw3d/Models/*.obj !hw3d/Models/**/*.obj
!hw3d/assimp/bin/* !hw3d/assimp/bin/*
*.pch *.pch
*.pdb *.pdb
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "Surface.h" #include "Surface.h"
#include "GDIPlusManager.h" #include "GDIPlusManager.h"
#include "imgui/imgui.h" #include "imgui/imgui.h"
#include "VertexBuffer.h"
namespace dx = DirectX; namespace dx = DirectX;
...@@ -26,6 +27,7 @@ void App::DoFrame() ...@@ -26,6 +27,7 @@ void App::DoFrame()
light.Bind( wnd.Gfx(),cam.GetMatrix() ); light.Bind( wnd.Gfx(),cam.GetMatrix() );
nano.Draw( wnd.Gfx() ); nano.Draw( wnd.Gfx() );
nano2.Draw( wnd.Gfx() );
light.Draw( wnd.Gfx() ); light.Draw( wnd.Gfx() );
while( const auto e = wnd.kbd.ReadKey() ) while( const auto e = wnd.kbd.ReadKey() )
...@@ -95,7 +97,8 @@ void App::DoFrame() ...@@ -95,7 +97,8 @@ void App::DoFrame()
cam.SpawnControlWindow(); cam.SpawnControlWindow();
light.SpawnControlWindow(); light.SpawnControlWindow();
ShowImguiDemoWindow(); ShowImguiDemoWindow();
nano.ShowWindow(); nano.ShowWindow( "Model 1" );
nano2.ShowWindow( "Model 2" );
// present // present
wnd.Gfx().EndFrame(); wnd.Gfx().EndFrame();
......
...@@ -25,5 +25,6 @@ private: ...@@ -25,5 +25,6 @@ private:
float speed_factor = 1.0f; float speed_factor = 1.0f;
Camera cam; Camera cam;
PointLight light; PointLight light;
Model nano{ wnd.Gfx(),"Models\\nano.gltf" }; Model nano{ wnd.Gfx(),"Models\\nano_textured\\nanosuit.obj" };
Model nano2{ wnd.Gfx(),"Models\\nano_textured\\nanosuit.obj" };
}; };
\ No newline at end of file
...@@ -8,6 +8,11 @@ namespace Bind ...@@ -8,6 +8,11 @@ namespace Bind
{ {
public: public:
virtual void Bind( Graphics& gfx ) noexcept = 0; virtual void Bind( Graphics& gfx ) noexcept = 0;
virtual std::string GetUID() const noexcept
{
assert( false );
return "";
}
virtual ~Bindable() = default; virtual ~Bindable() = default;
protected: protected:
static ID3D11DeviceContext* GetContext( Graphics& gfx ) noexcept; static ID3D11DeviceContext* GetContext( Graphics& gfx ) noexcept;
......
#pragma once
#include "Bindable.h"
#include "BindableCodex.h"
#include <type_traits>
#include <memory>
#include <unordered_map>
namespace Bind
{
class Codex
{
public:
template<class T,typename...Params>
static std::shared_ptr<T> Resolve( Graphics& gfx,Params&&...p ) noxnd
{
static_assert( std::is_base_of<Bindable,T>::value,"Can only resolve classes derived from Bindable" );
return Get().Resolve_<T>( gfx,std::forward<Params>( p )... );
}
private:
template<class T,typename...Params>
std::shared_ptr<T> Resolve_( Graphics& gfx,Params&&...p ) noxnd
{
const auto key = T::GenerateUID( std::forward<Params>( p )... );
const auto i = binds.find( key );
if( i == binds.end() )
{
auto bind = std::make_shared<T>( gfx,std::forward<Params>( p )... );
binds[key] = bind;
return bind;
}
else
{
return std::static_pointer_cast<T>( i->second );
}
}
static Codex& Get()
{
static Codex codex;
return codex;
}
private:
std::unordered_map<std::string,std::shared_ptr<Bindable>> binds;
};
}
\ No newline at end of file
...@@ -7,4 +7,6 @@ ...@@ -7,4 +7,6 @@
#include "Topology.h" #include "Topology.h"
#include "TransformCbuf.h" #include "TransformCbuf.h"
#include "VertexBuffer.h" #include "VertexBuffer.h"
#include "VertexShader.h" #include "VertexShader.h"
\ No newline at end of file #include "Texture.h"
#include "Sampler.h"
\ No newline at end of file
#pragma once #pragma once
#include "Bindable.h" #include "Bindable.h"
#include "GraphicsThrowMacros.h" #include "GraphicsThrowMacros.h"
#include "BindableCodex.h"
namespace Bind namespace Bind
{ {
...@@ -71,6 +72,27 @@ namespace Bind ...@@ -71,6 +72,27 @@ namespace Bind
{ {
GetContext( gfx )->VSSetConstantBuffers( slot,1u,pConstantBuffer.GetAddressOf() ); GetContext( gfx )->VSSetConstantBuffers( slot,1u,pConstantBuffer.GetAddressOf() );
} }
static std::shared_ptr<VertexConstantBuffer> Resolve( Graphics& gfx,const C& consts,UINT slot = 0 )
{
return Codex::Resolve<VertexConstantBuffer>( gfx,consts,slot );
}
static std::shared_ptr<VertexConstantBuffer> Resolve( Graphics& gfx,UINT slot = 0 )
{
return Codex::Resolve<VertexConstantBuffer>( gfx,slot );
}
static std::string GenerateUID( const C&,UINT slot )
{
return GenerateUID( slot );
}
static std::string GenerateUID( UINT slot = 0 )
{
using namespace std::string_literals;
return typeid(VertexConstantBuffer).name() + "#"s + std::to_string( slot );
}
std::string GetUID() const noexcept override
{
return GenerateUID( slot );
}
}; };
template<typename C> template<typename C>
...@@ -85,5 +107,26 @@ namespace Bind ...@@ -85,5 +107,26 @@ namespace Bind
{ {
GetContext( gfx )->PSSetConstantBuffers( slot,1u,pConstantBuffer.GetAddressOf() ); GetContext( gfx )->PSSetConstantBuffers( slot,1u,pConstantBuffer.GetAddressOf() );
} }
static std::shared_ptr<PixelConstantBuffer> Resolve( Graphics& gfx,const C& consts,UINT slot = 0 )
{
return Codex::Resolve<PixelConstantBuffer>( gfx,consts,slot );
}
static std::shared_ptr<PixelConstantBuffer> Resolve( Graphics& gfx,UINT slot = 0 )
{
return Codex::Resolve<PixelConstantBuffer>( gfx,slot );
}
static std::string GenerateUID( const C&,UINT slot )
{
return GenerateUID( slot );
}
static std::string GenerateUID( UINT slot = 0 )
{
using namespace std::string_literals;
return typeid(PixelConstantBuffer).name() + "#"s + std::to_string( slot );
}
std::string GetUID() const noexcept override
{
return GenerateUID( slot );
}
}; };
} }
\ No newline at end of file
...@@ -11,22 +11,16 @@ void Drawable::Draw( Graphics& gfx ) const noxnd ...@@ -11,22 +11,16 @@ void Drawable::Draw( Graphics& gfx ) const noxnd
{ {
b->Bind( gfx ); b->Bind( gfx );
} }
for( auto& b : GetStaticBinds() )
{
b->Bind( gfx );
}
gfx.DrawIndexed( pIndexBuffer->GetCount() ); gfx.DrawIndexed( pIndexBuffer->GetCount() );
} }
void Drawable::AddBind( std::unique_ptr<Bindable> bind ) noxnd void Drawable::AddBind( std::shared_ptr<Bindable> bind ) noxnd
{ {
assert( "*Must* use AddIndexBuffer to bind index buffer" && typeid(*bind) != typeid(IndexBuffer) ); // special case for index buffer
if( typeid(*bind) == typeid(IndexBuffer) )
{
assert( "Binding multiple index buffers not allowed" && pIndexBuffer == nullptr );
pIndexBuffer = &static_cast<IndexBuffer&>(*bind);
}
binds.push_back( std::move( bind ) ); binds.push_back( std::move( bind ) );
}
void Drawable::AddIndexBuffer( std::unique_ptr<IndexBuffer> ibuf ) noxnd
{
assert( "Attempting to add index buffer a second time" && pIndexBuffer == nullptr );
pIndexBuffer = ibuf.get();
binds.push_back( std::move( ibuf ) );
} }
\ No newline at end of file
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#include "Graphics.h" #include "Graphics.h"
#include <DirectXMath.h> #include <DirectXMath.h>
#include "ConditionalNoexcept.h" #include "ConditionalNoexcept.h"
#include <memory>
namespace Bind namespace Bind
{ {
...@@ -11,15 +12,11 @@ namespace Bind ...@@ -11,15 +12,11 @@ namespace Bind
class Drawable class Drawable
{ {
template<class T>
friend class DrawableBase;
public: public:
Drawable() = default; Drawable() = default;
Drawable( const Drawable& ) = delete; Drawable( const Drawable& ) = delete;
virtual DirectX::XMMATRIX GetTransformXM() const noexcept = 0; virtual DirectX::XMMATRIX GetTransformXM() const noexcept = 0;
void Draw( Graphics& gfx ) const noxnd; void Draw( Graphics& gfx ) const noxnd;
virtual void Update( float dt ) noexcept
{}
virtual ~Drawable() = default; virtual ~Drawable() = default;
protected: protected:
template<class T> template<class T>
...@@ -34,11 +31,8 @@ protected: ...@@ -34,11 +31,8 @@ protected:
} }
return nullptr; return nullptr;
} }
void AddBind( std::unique_ptr<Bind::Bindable> bind ) noxnd; void AddBind( std::shared_ptr<Bind::Bindable> bind ) noxnd;
void AddIndexBuffer( std::unique_ptr<Bind::IndexBuffer> ibuf ) noxnd;
private:
virtual const std::vector<std::unique_ptr<Bind::Bindable>>& GetStaticBinds() const noexcept = 0;
private: private:
const Bind::IndexBuffer* pIndexBuffer = nullptr; const Bind::IndexBuffer* pIndexBuffer = nullptr;
std::vector<std::unique_ptr<Bind::Bindable>> binds; std::vector<std::shared_ptr<Bind::Bindable>> binds;
}; };
\ No newline at end of file
#pragma once
#include "Drawable.h"
#include "IndexBuffer.h"
#include "ConditionalNoexcept.h"
template<class T>
class DrawableBase : public Drawable
{
protected:
static bool IsStaticInitialized() noexcept
{
return !staticBinds.empty();
}
static void AddStaticBind( std::unique_ptr<Bind::Bindable> bind ) noxnd
{
assert( "*Must* use AddStaticIndexBuffer to bind index buffer" && typeid(*bind) != typeid(Bind::IndexBuffer) );
staticBinds.push_back( std::move( bind ) );
}
void AddStaticIndexBuffer( std::unique_ptr<Bind::IndexBuffer> ibuf ) noxnd
{
assert( "Attempting to add index buffer a second time" && pIndexBuffer == nullptr );
pIndexBuffer = ibuf.get();
staticBinds.push_back( std::move( ibuf ) );
}
void SetIndexFromStatic() noxnd
{
assert( "Attempting to add index buffer a second time" && pIndexBuffer == nullptr );
for( const auto& b : staticBinds )
{
if( const auto p = dynamic_cast<Bind::IndexBuffer*>(b.get()) )
{
pIndexBuffer = p;
return;
}
}
assert( "Failed to find index buffer in static binds" && pIndexBuffer != nullptr );
}
private:
const std::vector<std::unique_ptr<Bind::Bindable>>& GetStaticBinds() const noexcept override
{
return staticBinds;
}
private:
static std::vector<std::unique_ptr<Bind::Bindable>> staticBinds;
};
template<class T>
std::vector<std::unique_ptr<Bind::Bindable>> DrawableBase<T>::staticBinds;
\ No newline at end of file
#include "IndexBuffer.h" #include "IndexBuffer.h"
#include "GraphicsThrowMacros.h" #include "GraphicsThrowMacros.h"
#include "BindableCodex.h"
namespace Bind namespace Bind
{ {
IndexBuffer::IndexBuffer( Graphics& gfx,const std::vector<unsigned short>& indices ) IndexBuffer::IndexBuffer( Graphics& gfx,const std::vector<unsigned short>& indices )
: :
IndexBuffer( gfx,"?",indices )
{}
IndexBuffer::IndexBuffer( Graphics& gfx,std::string tag,const std::vector<unsigned short>& indices )
:
tag( tag ),
count( (UINT)indices.size() ) count( (UINT)indices.size() )
{ {
INFOMAN( gfx ); INFOMAN( gfx );
...@@ -30,4 +36,19 @@ namespace Bind ...@@ -30,4 +36,19 @@ namespace Bind
{ {
return count; return count;
} }
std::shared_ptr<IndexBuffer> IndexBuffer::Resolve( Graphics& gfx,const std::string& tag,
const std::vector<unsigned short>& indices )
{
assert( tag != "?" );
return Codex::Resolve<IndexBuffer>( gfx,tag,indices );
}
std::string IndexBuffer::GenerateUID_( const std::string& tag )
{
using namespace std::string_literals;
return typeid(IndexBuffer).name() + "#"s + tag;
}
std::string IndexBuffer::GetUID() const noexcept
{
return GenerateUID_( tag );
}
} }
...@@ -7,9 +7,21 @@ namespace Bind ...@@ -7,9 +7,21 @@ namespace Bind
{ {
public: public:
IndexBuffer( Graphics& gfx,const std::vector<unsigned short>& indices ); IndexBuffer( Graphics& gfx,const std::vector<unsigned short>& indices );
IndexBuffer( Graphics& gfx,std::string tag,const std::vector<unsigned short>& indices );
void Bind( Graphics& gfx ) noexcept override; void Bind( Graphics& gfx ) noexcept override;
UINT GetCount() const noexcept; UINT GetCount() const noexcept;
static std::shared_ptr<IndexBuffer> Resolve( Graphics& gfx,const std::string& tag,
const std::vector<unsigned short>& indices );
template<typename...Ignore>
static std::string GenerateUID( const std::string& tag,Ignore&&...ignore )
{
return GenerateUID_( tag );
}
std::string GetUID() const noexcept override;
private:
static std::string GenerateUID_( const std::string& tag );
protected: protected:
std::string tag;
UINT count; UINT count;
Microsoft::WRL::ComPtr<ID3D11Buffer> pIndexBuffer; Microsoft::WRL::ComPtr<ID3D11Buffer> pIndexBuffer;
}; };
......
#pragma once #pragma once
#include "Vertex.h"
#include <vector> #include <vector>
#include <DirectXMath.h> #include <DirectXMath.h>
template<class T>
class IndexedTriangleList class IndexedTriangleList
{ {
public: public:
IndexedTriangleList() = default; IndexedTriangleList() = default;
IndexedTriangleList( std::vector<T> verts_in,std::vector<unsigned short> indices_in ) IndexedTriangleList( Dvtx::VertexBuffer verts_in,std::vector<unsigned short> indices_in )
: :
vertices( std::move( verts_in ) ), vertices( std::move( verts_in ) ),
indices( std::move( indices_in ) ) indices( std::move( indices_in ) )
{ {
assert( vertices.size() > 2 ); assert( vertices.Size() > 2 );
assert( indices.size() % 3 == 0 ); assert( indices.size() % 3 == 0 );
} }
void Transform( DirectX::FXMMATRIX matrix ) void Transform( DirectX::FXMMATRIX matrix )
{ {
for( auto& v : vertices ) using Elements = Dvtx::VertexLayout::ElementType;
for( int i = 0; i < vertices.Size(); i++ )
{ {
const DirectX::XMVECTOR pos = DirectX::XMLoadFloat3( &v.pos ); auto& pos = vertices[i].Attr<Elements::Position3D>();
DirectX::XMStoreFloat3( DirectX::XMStoreFloat3(
&v.pos, &pos,
DirectX::XMVector3Transform( pos,matrix ) DirectX::XMVector3Transform( DirectX::XMLoadFloat3( &pos ),matrix )
); );
} }
} }
// asserts face-independent vertices w/ normals cleared to zero //// asserts face-independent vertices w/ normals cleared to zero
void SetNormalsIndependentFlat() noxnd //void SetNormalsIndependentFlat() noxnd
{ //{
using namespace DirectX; // using namespace DirectX;
assert( indices.size() % 3 == 0 && indices.size() > 0 ); // for( size_t i = 0; i < indices.size(); i += 3 )
for( size_t i = 0; i < indices.size(); i += 3 ) // {
{ // auto& v0 = vertices[indices[i]];
auto& v0 = vertices[indices[i]]; // auto& v1 = vertices[indices[i + 1]];
auto& v1 = vertices[indices[i + 1]]; // auto& v2 = vertices[indices[i + 2]];
auto& v2 = vertices[indices[i + 2]]; // const auto p0 = XMLoadFloat3( &v0.pos );
const auto p0 = XMLoadFloat3( &v0.pos ); // const auto p1 = XMLoadFloat3( &v1.pos );
const auto p1 = XMLoadFloat3( &v1.pos ); // const auto p2 = XMLoadFloat3( &v2.pos );
const auto p2 = XMLoadFloat3( &v2.pos );
const auto n = XMVector3Normalize( XMVector3Cross( (p1 - p0),(p2 - p0) ) ); // const auto n = XMVector3Normalize( XMVector3Cross( (p1 - p0),(p2 - p0) ) );
//
XMStoreFloat3( &v0.n,n ); // XMStoreFloat3( &v0.n,n );
XMStoreFloat3( &v1.n,n ); // XMStoreFloat3( &v1.n,n );
XMStoreFloat3( &v2.n,n ); // XMStoreFloat3( &v2.n,n );
} // }
} //}
public: public:
std::vector<T> vertices; Dvtx::VertexBuffer vertices;
std::vector<unsigned short> indices; std::vector<unsigned short> indices;
}; };
\ No newline at end of file
#include "InputLayout.h" #include "InputLayout.h"
#include "GraphicsThrowMacros.h" #include "GraphicsThrowMacros.h"
#include "BindableCodex.h"
#include "Vertex.h"
namespace Bind namespace Bind
{ {
InputLayout::InputLayout( Graphics& gfx, InputLayout::InputLayout( Graphics& gfx,
const std::vector<D3D11_INPUT_ELEMENT_DESC>& layout, Dvtx::VertexLayout layout_in,
ID3DBlob* pVertexShaderBytecode ) ID3DBlob* pVertexShaderBytecode )
:
layout( std::move( layout_in ) )
{ {
INFOMAN( gfx ); INFOMAN( gfx );
const auto d3dLayout = layout.GetD3DLayout();
GFX_THROW_INFO( GetDevice( gfx )->CreateInputLayout( GFX_THROW_INFO( GetDevice( gfx )->CreateInputLayout(
layout.data(),(UINT)layout.size(), d3dLayout.data(),(UINT)d3dLayout.size(),
pVertexShaderBytecode->GetBufferPointer(), pVertexShaderBytecode->GetBufferPointer(),
pVertexShaderBytecode->GetBufferSize(), pVertexShaderBytecode->GetBufferSize(),
&pInputLayout &pInputLayout
...@@ -21,4 +27,18 @@ namespace Bind ...@@ -21,4 +27,18 @@ namespace Bind
{ {
GetContext( gfx )->IASetInputLayout( pInputLayout.Get() ); GetContext( gfx )->IASetInputLayout( pInputLayout.Get() );
} }
std::shared_ptr<InputLayout> InputLayout::Resolve( Graphics& gfx,
const Dvtx::VertexLayout& layout,ID3DBlob* pVertexShaderBytecode )
{
return Codex::Resolve<InputLayout>( gfx,layout,pVertexShaderBytecode );
}
std::string InputLayout::GenerateUID( const Dvtx::VertexLayout& layout,ID3DBlob* pVertexShaderBytecode )
{
using namespace std::string_literals;
return typeid(InputLayout).name() + "#"s + layout.GetCode();
}
std::string InputLayout::GetUID() const noexcept
{
return GenerateUID( layout );
}
} }
#pragma once #pragma once
#include "Bindable.h" #include "Bindable.h"
#include "Vertex.h"
namespace Bind namespace Bind
{ {
...@@ -7,10 +8,15 @@ namespace Bind ...@@ -7,10 +8,15 @@ namespace Bind
{ {
public: public:
InputLayout( Graphics& gfx, InputLayout( Graphics& gfx,
const std::vector<D3D11_INPUT_ELEMENT_DESC>& layout, Dvtx::VertexLayout layout,
ID3DBlob* pVertexShaderBytecode ); ID3DBlob* pVertexShaderBytecode );
void Bind( Graphics& gfx ) noexcept override; void Bind( Graphics& gfx ) noexcept override;
static std::shared_ptr<InputLayout> Resolve( Graphics& gfx,
const Dvtx::VertexLayout& layout,ID3DBlob* pVertexShaderBytecode );
static std::string GenerateUID( const Dvtx::VertexLayout& layout,ID3DBlob* pVertexShaderBytecode = nullptr );
std::string GetUID() const noexcept override;
protected: protected:
Dvtx::VertexLayout layout;
Microsoft::WRL::ComPtr<ID3D11InputLayout> pInputLayout; Microsoft::WRL::ComPtr<ID3D11InputLayout> pInputLayout;
}; };
} }
\ No newline at end of file
#include "Mesh.h" #include "Mesh.h"
#include "imgui/imgui.h" #include "imgui/imgui.h"
#include "Surface.h"
#include <unordered_map> #include <unordered_map>
#include <sstream> #include <sstream>
...@@ -31,27 +32,16 @@ const std::string& ModelException::GetNote() const noexcept ...@@ -31,27 +32,16 @@ const std::string& ModelException::GetNote() const noexcept
} }
// Mesh // Mesh
Mesh::Mesh( Graphics& gfx,std::vector<std::unique_ptr<Bind::Bindable>> bindPtrs ) Mesh::Mesh( Graphics& gfx,std::vector<std::shared_ptr<Bind::Bindable>> bindPtrs )
{ {
if( !IsStaticInitialized() ) AddBind( Bind::Topology::Resolve( gfx,D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ) );
{
AddStaticBind( std::make_unique<Bind::Topology>( gfx,D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ) );
}
for( auto& pb : bindPtrs ) for( auto& pb : bindPtrs )
{ {
if( auto pi = dynamic_cast<Bind::IndexBuffer*>(pb.get()) ) AddBind( std::move( pb ) );
{
AddIndexBuffer( std::unique_ptr<Bind::IndexBuffer>{ pi } );
pb.release();
}
else
{
AddBind( std::move( pb ) );
}
} }
AddBind( std::make_unique<Bind::TransformCbuf>( gfx,*this ) ); AddBind( std::make_shared<Bind::TransformCbuf>( gfx,*this ) );
} }
void Mesh::Draw( Graphics& gfx,DirectX::FXMMATRIX accumulatedTransform ) const noxnd void Mesh::Draw( Graphics& gfx,DirectX::FXMMATRIX accumulatedTransform ) const noxnd
{ {
...@@ -212,7 +202,7 @@ Model::Model( Graphics& gfx,const std::string fileName ) ...@@ -212,7 +202,7 @@ Model::Model( Graphics& gfx,const std::string fileName )
for( size_t i = 0; i < pScene->mNumMeshes; i++ ) for( size_t i = 0; i < pScene->mNumMeshes; i++ )
{ {
meshPtrs.push_back( ParseMesh( gfx,*pScene->mMeshes[i] ) ); meshPtrs.push_back( ParseMesh( gfx,*pScene->mMeshes[i],pScene->mMaterials ) );
} }
int nextId = 0; int nextId = 0;
...@@ -236,21 +226,24 @@ void Model::ShowWindow( const char* windowName ) noexcept ...@@ -236,21 +226,24 @@ void Model::ShowWindow( const char* windowName ) noexcept
Model::~Model() noexcept Model::~Model() noexcept
{} {}
std::unique_ptr<Mesh> Model::ParseMesh( Graphics& gfx,const aiMesh& mesh ) std::unique_ptr<Mesh> Model::ParseMesh( Graphics& gfx,const aiMesh& mesh,const aiMaterial* const* pMaterials )
{ {
using Dvtx::VertexLayout; using Dvtx::VertexLayout;
using namespace Bind;
Dvtx::VertexBuffer vbuf( std::move( Dvtx::VertexBuffer vbuf( std::move(
VertexLayout{} VertexLayout{}
.Append( VertexLayout::Position3D ) .Append( VertexLayout::Position3D )
.Append( VertexLayout::Normal ) .Append( VertexLayout::Normal )
.Append( VertexLayout::Texture2D )
) ); ) );
for( unsigned int i = 0; i < mesh.mNumVertices; i++ ) for( unsigned int i = 0; i < mesh.mNumVertices; i++ )
{ {
vbuf.EmplaceBack( vbuf.EmplaceBack(
*reinterpret_cast<dx::XMFLOAT3*>(&mesh.mVertices[i]), *reinterpret_cast<dx::XMFLOAT3*>(&mesh.mVertices[i]),
*reinterpret_cast<dx::XMFLOAT3*>(&mesh.mNormals[i]) *reinterpret_cast<dx::XMFLOAT3*>(&mesh.mNormals[i]),
*reinterpret_cast<dx::XMFLOAT2*>(&mesh.mTextureCoords[0][i])
); );
} }
...@@ -265,28 +258,66 @@ std::unique_ptr<Mesh> Model::ParseMesh( Graphics& gfx,const aiMesh& mesh ) ...@@ -265,28 +258,66 @@ std::unique_ptr<Mesh> Model::ParseMesh( Graphics& gfx,const aiMesh& mesh )
indices.push_back( face.mIndices[2] ); indices.push_back( face.mIndices[2] );
} }
std::vector<std::unique_ptr<Bind::Bindable>> bindablePtrs; std::vector<std::shared_ptr<Bindable>> bindablePtrs;
bindablePtrs.push_back( std::make_unique<Bind::VertexBuffer>( gfx,vbuf ) ); using namespace std::string_literals;
const auto base = "Models\\nano_textured\\"s;
bindablePtrs.push_back( std::make_unique<Bind::IndexBuffer>( gfx,indices ) ); bool hasSpecularMap = false;
float shininess = 35.0f;
if( mesh.mMaterialIndex >= 0 )
{
auto& material = *pMaterials[mesh.mMaterialIndex];
aiString texFileName;
auto pvs = std::make_unique<Bind::VertexShader>( gfx,L"PhongVS.cso" ); material.GetTexture( aiTextureType_DIFFUSE,0,&texFileName );
bindablePtrs.push_back( Texture::Resolve( gfx,base + texFileName.C_Str() ) );
if( material.GetTexture( aiTextureType_SPECULAR,0,&texFileName ) == aiReturn_SUCCESS )
{
bindablePtrs.push_back( Texture::Resolve( gfx,base + texFileName.C_Str(),1 ) );
hasSpecularMap = true;
}
else
{
material.Get( AI_MATKEY_SHININESS,shininess );
}
bindablePtrs.push_back( Bind::Sampler::Resolve( gfx ) );
}
auto meshTag = base + "%" + mesh.mName.C_Str();
bindablePtrs.push_back( VertexBuffer::Resolve( gfx,meshTag,vbuf ) );
bindablePtrs.push_back( IndexBuffer::Resolve( gfx,meshTag,indices ) );
auto pvs = VertexShader::Resolve( gfx,"PhongVS.cso" );
auto pvsbc = pvs->GetBytecode(); auto pvsbc = pvs->GetBytecode();
bindablePtrs.push_back( std::move( pvs ) ); bindablePtrs.push_back( std::move( pvs ) );
bindablePtrs.push_back( std::make_unique<Bind::PixelShader>( gfx,L"PhongPS.cso" ) ); bindablePtrs.push_back( InputLayout::Resolve( gfx,vbuf.GetLayout(),pvsbc ) );
bindablePtrs.push_back( std::make_unique<Bind::InputLayout>( gfx,vbuf.GetLayout().GetD3DLayout(),pvsbc ) ); if( hasSpecularMap )
{
struct PSMaterialConstant bindablePtrs.push_back( PixelShader::Resolve( gfx,"PhongPSSpecMap.cso" ) );
}
else
{ {
DirectX::XMFLOAT3 color = { 0.6f,0.6f,0.8f }; bindablePtrs.push_back( PixelShader::Resolve( gfx,"PhongPS.cso" ) );
float specularIntensity = 0.6f;
float specularPower = 30.0f; struct PSMaterialConstant
float padding[3]; {
} pmc; float specularIntensity = 0.8f;
bindablePtrs.push_back( std::make_unique<Bind::PixelConstantBuffer<PSMaterialConstant>>( gfx,pmc,1u ) ); float specularPower;
float padding[2];
} pmc;
pmc.specularPower = shininess;
// this is CLEARLY an issue... all meshes will share same mat const, but may have different
// Ns (specular power) specified for each in the material properties... bad conflict
bindablePtrs.push_back( PixelConstantBuffer<PSMaterialConstant>::Resolve( gfx,pmc,1u ) );
}
return std::make_unique<Mesh>( gfx,std::move( bindablePtrs ) ); return std::make_unique<Mesh>( gfx,std::move( bindablePtrs ) );
} }
......
#pragma once #pragma once
#include "DrawableBase.h" #include "Drawable.h"
#include "BindableCommon.h" #include "BindableCommon.h"
#include "Vertex.h" #include "Vertex.h"
#include <optional> #include <optional>
...@@ -20,10 +20,10 @@ private: ...@@ -20,10 +20,10 @@ private:
std::string note; std::string note;
}; };
class Mesh : public DrawableBase<Mesh> class Mesh : public Drawable
{ {
public: public:
Mesh( Graphics& gfx,std::vector<std::unique_ptr<Bind::Bindable>> bindPtrs ); Mesh( Graphics& gfx,std::vector<std::shared_ptr<Bind::Bindable>> bindPtrs );
void Draw( Graphics& gfx,DirectX::FXMMATRIX accumulatedTransform ) const noxnd; void Draw( Graphics& gfx,DirectX::FXMMATRIX accumulatedTransform ) const noxnd;
DirectX::XMMATRIX GetTransformXM() const noexcept override; DirectX::XMMATRIX GetTransformXM() const noexcept override;
private: private:
...@@ -58,7 +58,7 @@ public: ...@@ -58,7 +58,7 @@ public:
void ShowWindow( const char* windowName = nullptr ) noexcept; void ShowWindow( const char* windowName = nullptr ) noexcept;
~Model() noexcept; ~Model() noexcept;
private: private:
static std::unique_ptr<Mesh> ParseMesh( Graphics& gfx,const aiMesh& mesh ); static std::unique_ptr<Mesh> ParseMesh( Graphics& gfx,const aiMesh& mesh,const aiMaterial* const* pMaterials );
std::unique_ptr<Node> ParseNode( int& nextId,const aiNode& node ) noexcept; std::unique_ptr<Node> ParseNode( int& nextId,const aiNode& node ) noexcept;
private: private:
std::unique_ptr<Node> pRoot; std::unique_ptr<Node> pRoot;
......
Original Nanosuit model by ForrestPL:
http://tf3dm.com/3d-model/crysis-2-nanosuit-2-97837.html
Slightly modified for use in the LearnOpenGL.com tutorials (by Joey de Vries)
For personal use only
\ No newline at end of file