aboutsummaryrefslogtreecommitdiff
path: root/NvCloth/samples/SampleBase/renderer/RenderMaterial.h
blob: 3f95389b043ac64748ec29a9663e69c2e9fa41b5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*
* Copyright (c) 2008-2017, NVIDIA CORPORATION.  All rights reserved.
*
* NVIDIA CORPORATION and its licensors retain all intellectual property
* and proprietary rights in and to this software, related documentation
* and any modifications thereto.  Any use, reproduction, disclosure or
* distribution of this software and related documentation without an express
* license agreement from NVIDIA CORPORATION is strictly prohibited.
*/

#ifndef RENDER_MATERIAL_H
#define RENDER_MATERIAL_H

#include "Utils.h"
#include "DirectXTex.h"

#include <string>
#include <vector>
#include <list>
#include <map>
#include <memory>


class IRenderMesh;
class ResourceManager;
struct TextureResource;


class RenderMaterial
{
  public:

	enum BlendMode
	{
		BLEND_NONE,
		BLEND_ALPHA_BLENDING,
		BLEND_ADDITIVE
	};

	RenderMaterial(ResourceManager& resourceProvider, const char* shaderFileName, const char* textureFileName = "", BlendMode blendMode = BLEND_NONE);
	~RenderMaterial();

	void setBlending(BlendMode blendMode);
	BlendMode getBlending() const { return mBlendMode; }

	void reload();

	class Instance
	{
	public:
		Instance(RenderMaterial& material, ID3D11InputLayout* inputLayout, uint32_t shaderNum = 0) : mMaterial(material), mInputLayout(inputLayout), mShaderNum(shaderNum) {}
		~Instance() { SAFE_RELEASE(mInputLayout); }

		bool isValid();
		void bind(ID3D11DeviceContext& context, uint32_t slot, bool depthStencilOnly = false);
		RenderMaterial& getMaterial() const { return mMaterial; }
	private:
		RenderMaterial& mMaterial;
		ID3D11InputLayout* mInputLayout;
		uint32_t mShaderNum;
	};

	typedef std::shared_ptr<Instance> InstancePtr;

	InstancePtr getMaterialInstance(const IRenderMesh* mesh);
	InstancePtr getMaterialInstance(const D3D11_INPUT_ELEMENT_DESC* elementDescs, uint32_t numElements);

  private:
	void initialize(ResourceManager& resourceCallback, const char* shaderFileName, const char* textureFileName, BlendMode blendMode);
	void initialize(ResourceManager&resourceProvider, std::vector<std::string> shaderFileNames, const char* textureFileName, BlendMode blendMode);

	void releaseReloadableResources();

	std::string mShaderFileName;
	std::string mTextureFileName;

	struct ShaderGroup
	{
		ShaderGroup() : vs(nullptr), gs(nullptr), ps(nullptr), buffer(nullptr)
		{
		}
		~ShaderGroup()
		{
			Release();
		}
		void Release()
		{
			SAFE_RELEASE(vs);
			SAFE_RELEASE(gs);
			SAFE_RELEASE(ps);
			SAFE_RELEASE(buffer);
		}
		void Set(ID3D11DeviceContext* c, bool setPixelShader = true)
		{
			c->VSSetShader(vs, nullptr, 0);
			c->GSSetShader(gs, nullptr, 0);
			c->PSSetShader(setPixelShader  ? ps : nullptr, nullptr, 0);
		}
		bool IsValid()
		{
			return vs != nullptr;
		}
		ID3D11VertexShader* vs;
		ID3D11GeometryShader* gs;
		ID3D11PixelShader* ps;
		ID3DBlob* buffer;
	};

	std::map<const IRenderMesh*, std::weak_ptr<Instance>> mRenderMeshToInstanceMap;
	const TextureResource*					mTexture;
	ID3D11ShaderResourceView*               mTextureSRV;
	std::vector<std::string>                mShaderFilePathes;
	std::vector<ShaderGroup*>               mShaderGroups;
	ID3D11BlendState*                       mBlendState;
	BlendMode                               mBlendMode;
};

#endif