summaryrefslogtreecommitdiff
path: root/model.hpp
blob: 190b2b688a97aacad1b6622e2999d71fd00948c6 (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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#ifndef model_hpp
#define model_hpp

#include "asset.hpp"
#include "maths.hpp"
#include "video.hpp"

#include <tuple>

struct Material : public Asset {
	float metalness, roughness, ao;
	v3f albedo;
	struct {
		Texture_Id albedo;
		Texture_Id ao;
		Texture_Id metal;
		Texture_Id rough;
		Texture_Id normal;
	} tex;
	void use(
		Pipeline_Builder& pb,
		Sampler_Id sampler,
		Shader& shader
	);
};

struct Model;
struct Mesh {
	int offset, vbo_offset, count;
	int parent, mesh_binding, mvp_binding, mat_binding;
	int env_cube_binding;
	int mvp_binding_depth;
	bool world_dirty;
	m4f world, local;
	AABB bound;
	Shader_Id shader, depth_shader;
	Material* material;
	const m4f& get_world(Model& m);
};

struct Model : public Asset {
	Buffer_Id vbo;
	Buffer_Id ibo;
	int mesh_count;

	Mesh* get_meshes() {
		return (Mesh*)&this[1];
	}

	void destroy(Device* dev);
	void update_transforms();
	void update_cbuffers(
		Device* dev,
		const m4f& transform,
		const m4f& view_projection
	);
};

struct Model_Loader : public Asset_Loader {
	Device* dev;
	Asset_Arena* shaders;
	void init(Device* device, Asset_Arena* shader_arena);
	Asset* load(
		Arena* a,
		Arena* s,
		const char* filename,
		Pack_File* f
	) override;
	void unload(Asset* a) override;
};

struct Material_Loader : public Asset_Loader {
	Asset_Arena* textures;
	Texture_Id default_tex;
	void init(Asset_Arena* texture_arena, Texture_Id dt);
	Asset* load(
		Arena* a,
		Arena* s,
		const char* filename,
		Pack_File* f
	) override;
	void unload(Asset* a) override;
};

struct Camera {
	float fov, near, far, asp;
	v3f forward, position;
	void init(float vfov, const v3f& f, const v3f& p);
	m4f get_view() const;
	m4f get_proj() const;
};

struct Model_Instance {
	Buffer_Id mvp;
	Buffer_Id mat;
	m4f transform;
	Model* m;
	AABB* bounds;

	void init(Device* dev, Heap* h, Model* model);
	void destroy(Device* dev, Heap* h);
	void update();
	void update_cbuffers(Device* dev, const Camera& cam);
	void render(
		Device* dev,
		Arena* a,
		Render_Pass& pass,
		Texture_Id env_cubemap,
		Sampler_Id sampler
	);
	int pick(const v3f& o, const v3f& d);
};

struct Model_Scene {
	Heap* h;
	Model_Instance* instances;
	int count, max;
	Sampler_Id sampler;

	Model_Instance* instantiate(Device* dev, Model* model);
	void uninstantiate(Device* dev, Model_Instance* model);
	void destroy(Device* dev);

	void init(Arena* arena, int max_instances, Sampler_Id s);
	void update(const Camera& cam, Device* dev);
	void render(
		Device* dev,
		Arena* a,
		Render_Pass& pass,
		Texture_Id env_cubemap,
		Sampler_Id sampler
	);
	std::pair<Model_Instance*, int> pick(
		const Camera& cam,
		int w,
		int h,
		int mx,
		int my
	);
};

#endif