The Dirtchamber
A mixed reality testing environment for real-time global illumination algorithms
common_renderer.h
Go to the documentation of this file.
1 /*
2  * The Dirtchamber - Tobias Alexander Franke 2014
3  * For copyright and license see LICENSE
4  * http://www.tobias-franke.eu
5  */
6 
9 #ifndef COMMON_RENDERER_H
10 #define COMMON_RENDERER_H
11 
12 #undef NOMINMAX
13 #include <DXUT.h>
14 #include <dune/dune.h>
15 
16 #include "../shader/common.h"
17 
18 #include "pppipe.h"
19 #include "skydome.h"
20 
21 extern std::vector<dune::tstring> files_scene;
22 extern float z_near;
23 extern float z_far;
24 
26 namespace dc
27 {
44  {
45  protected:
46  struct per_frame
47  {
48  float time;
49  float time_delta;
50  DirectX::XMFLOAT2 pad0;
51  };
52 
53  struct onetime
54  {
55  DirectX::XMFLOAT4 scene_dim_max;
56  DirectX::XMFLOAT4 scene_dim_min;
57  };
58 
59  protected:
60  dune::camera camera_;
61  dune::cbuffer<per_frame> cb_per_frame_;
62  dune::cbuffer<onetime> cb_onetime_;
63  dune::gilga_mesh debug_box_;
64  dune::composite_mesh scene_;
65  dune::gbuffer def_;
66  skydome sky_;
67 
68  DirectX::XMFLOAT3 bb_min_;
69  DirectX::XMFLOAT3 bb_max_;
70 
71  pppipe postprocessor_;
72  ID3D11ShaderResourceView* noise_srv_;
73 
74  protected:
76  virtual void do_render_scene(ID3D11DeviceContext* context);
77 
79  void reset_omrtv(ID3D11DeviceContext* context);
80 
81  protected:
83  void update_bbox(ID3D11DeviceContext* context, dune::d3d_mesh& mesh);
84 
86  void update_camera_parameters(ID3D11DeviceContext* context);
87 
89  void update_scene(ID3D11DeviceContext* context, const DirectX::XMMATRIX& world /* = DirectX::XMMatrixIdentity() */);
90 
92  void update_onetime_parameters(ID3D11DeviceContext* context, dune::d3d_mesh& mesh);
93 
95  void render_scene(ID3D11DeviceContext* context, float* clear_color, ID3D11DepthStencilView* dsv);
96 
97  public:
98  virtual void create(ID3D11Device* device);
99  virtual void destroy();
100  virtual void resize(UINT width, UINT height);
101  virtual void render(ID3D11DeviceContext* context, ID3D11RenderTargetView* backbuffer, ID3D11DepthStencilView* dsv);
102 
104  virtual void update_postprocessing_parameters(ID3D11DeviceContext* context);
105 
107  virtual void update_frame(ID3D11DeviceContext* context, double time, float elapsed_time);
108 
110  virtual void update_camera(ID3D11DeviceContext* context, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
111 
113  virtual void reload_shader(ID3D11Device* device, ID3D11DeviceContext* context) {}
114 
133  void set_shader(ID3D11Device* device,
134  ID3DBlob* input_binary,
135  ID3D11VertexShader* vs_deferred,
136  ID3D11PixelShader* ps_deferred,
137  ID3D11PixelShader* ps_overlay,
138  UINT start_slot,
139  UINT overlay_slot,
140  UINT postprocessing_slot);
141 
142  inline pppipe& postprocessor() { return postprocessor_; }
143  inline dune::camera& camera() { return camera_; }
144  inline dune::composite_mesh& scene() { return scene_; }
145 
147  virtual void save(dune::serializer& s);
148 
150  virtual void load(ID3D11DeviceContext* context, const dune::serializer& s);
151  };
152 
160  template<typename L = dune::directional_light>
162  {
163  protected:
164  L main_light_;
165  dune::render_target rsm_depth_;
166  dune::render_target dummy_spec_;
167  bool update_rsm_;
168 
169  protected:
171  void update_rsm_camera_parameters(ID3D11DeviceContext* context, dune::directional_light& l)
172  {
173  auto cb = &camera_.parameters().data();
174  {
175  XMStoreFloat4x4(&cb->vp,
176  DirectX::XMLoadFloat4x4(&l.parameters().data().vp));
177 
178  XMStoreFloat4x4(&cb->vp_inv,
179  XMLoadFloat4x4(&l.parameters().data().vp_inv));
180 
181  cb->camera_pos = DirectX::XMFLOAT3
182  (
183  l.parameters().data().position.x,
184  l.parameters().data().position.y,
185  l.parameters().data().position.z
186  );
187 
188  cb->z_far = z_far;
189  }
190  camera_.parameters().to_vs(context, SLOT_CAMERA_VS);
191  }
192 
194  void render_rsm(ID3D11DeviceContext* context, float* clear_color, dune::gbuffer& rsm)
195  {
196  // render rsm
197  ID3D11RenderTargetView* rsm_views[] = {
198  rsm[L"colors"]->rtv(),
199  rsm[L"normals"]->rtv(),
200  rsm[L"lineardepth"]->rtv(),
201  dummy_spec_.rtv()
202  };
203 
204  ID3D11DepthStencilView* dsv = rsm_depth_.dsv();
205 
206  context->ClearDepthStencilView(dsv, D3D11_CLEAR_DEPTH, 1.0, 0);
207  dune::clear_rtvs(context, rsm_views, 2, clear_color);
208 
209  float cc[4] = { z_far, z_far, z_far, z_far };
210  dune::clear_rtvs(context, rsm_views + 2, 1, cc);
211 
212  DirectX::XMFLOAT2 size = rsm[L"colors"]->size();
213  dune::set_viewport(context,
214  static_cast<size_t>(size.x),
215  static_cast<size_t>(size.y));
216 
217  context->OMSetRenderTargets(4, rsm_views, dsv);
218 
219  do_render_rsm(context);
220 
221  reset_omrtv(context);
222  }
223 
225  virtual void do_render_rsm(ID3D11DeviceContext* context)
226  {
227  scene_.set_shader_slots(SLOT_TEX_DIFFUSE, SLOT_TEX_NORMAL);
228 
229  for (size_t x = 0; x < scene_.size(); ++x)
230  {
231  dune::gilga_mesh* m = dynamic_cast<dune::gilga_mesh*>(scene_[x].get());
232  if (m) m->set_alpha_slot(SLOT_TEX_ALPHA);
233  }
234 
235  scene_.render(context);
236  }
237 
238  public:
239  virtual void create(ID3D11Device* device)
240  {
241  common_renderer::create(device);
242 
243  auto ld_color = def_[L"colors"]->desc();
244  auto ld_normal = def_[L"normals"]->desc();
245  auto ld_ldepth = def_[L"lineardepth"]->desc();
246  auto ld_spec = def_[L"specular"]->desc();
247 
248  // setup reflective shadow map
249  ld_color.Width = ld_normal.Width = ld_ldepth.Width = ld_spec.Width =
250  ld_color.Height = ld_normal.Height = ld_ldepth.Height = ld_spec.Height = 1024;
251 
252  dummy_spec_.create(device, ld_spec);
253 
254  main_light_.create(device, L"rsm", ld_color, ld_normal, ld_ldepth);
255 
256  DXGI_SURFACE_DESC ld_rsmdepth;
257  ld_rsmdepth.Format = DXGI_FORMAT_R32_TYPELESS;
258  ld_rsmdepth.Width = 1024;
259  ld_rsmdepth.Height = 1024;
260  ld_rsmdepth.SampleDesc.Count = 1;
261  ld_rsmdepth.SampleDesc.Quality = 0;
262  rsm_depth_.create(device, ld_rsmdepth);
263 
264  // add buffers to deferred renderer
265  add_buffer(*main_light_.rsm()[L"lineardepth"], SLOT_TEX_SVO_RSM_RHO_START);
266  }
267 
269  void update_light_parameters(ID3D11DeviceContext* context, dune::directional_light& l)
270  {
271  DirectX::XMMATRIX world = DirectX::XMLoadFloat4x4(&scene_.world());
272 
273  // TODO: make better
274  DirectX::XMVECTOR up = { -1.f, 0.f, 0.f, 0.f };
275  DirectX::XMVECTOR upt;
276  upt = DirectX::XMVector4Transform(up, world);
277  upt = DirectX::XMVector4Normalize(upt);
278 
279  DirectX::XMFLOAT4 upt_vec;
280  DirectX::XMStoreFloat4(&upt_vec, upt);
281 
282  // projection matrix
283  auto light_proj = dune::make_projection(z_near, z_far);
284 
285  l.update(upt_vec, light_proj);
286 
287  l.parameters().to_ps(context, SLOT_LIGHT_PS);
288 
289  update_rsm_ = true;
290  }
291 
292  virtual void destroy()
293  {
294  common_renderer::destroy();
295  main_light_.destroy();
296  rsm_depth_.destroy();
297  dummy_spec_.destroy();
298  }
299 
300  inline dune::directional_light& main_light()
301  {
302  return main_light_;
303  }
304 
305  virtual void save(dune::serializer& s)
306  {
308  s << main_light_;
309  }
310 
311  virtual void load(ID3D11DeviceContext* context, const dune::serializer& s)
312  {
313  common_renderer::load(context, s);
314 
315  s >> main_light_;
316  }
317  };
318 }
319 
320 #endif
void set_alpha_slot(INT alpha_tex=-1)
Set the texture register for alpha textures.
Definition: assimp_mesh.h:212
cb_param & parameters()
Return local cbuffer parameters.
Definition: camera.h:47
void update_bbox(ID3D11DeviceContext *context, dune::d3d_mesh &mesh)
Upload the bounding box of a mesh to the pixel shader.
Definition: common_renderer.cpp:136
A common_renderer also rendering an RSM.
Definition: common_renderer.h:161
virtual void update_camera(ID3D11DeviceContext *context, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Update function called for the camera.
Definition: common_renderer.cpp:206
Seralizer to read/write Dune objects from/into JSON/XML.
Definition: serializer.h:41
virtual void resize(UINT width, UINT height)
Resize the deferred_renderer's output to a new width/height .
Definition: common_renderer.cpp:113
The deferred renderer base class.
Definition: deferred_renderer.h:40
virtual void load(ID3D11DeviceContext *context, const dune::serializer &s)
Load dune objects used in the common_renderer. Overload to add more.
Definition: common_renderer.cpp:281
void create(ID3D11Device *device, D3D11_TEXTURE2D_DESC desc, D3D11_SUBRESOURCE_DATA *subresource=nullptr)
Create an empty texture from given descriptor, other resource or single parameters.
Definition: texture.cpp:58
virtual void update_postprocessing_parameters(ID3D11DeviceContext *context)
Upload postprocessing paraemters from the postporcessing pipeline.
Definition: common_renderer.cpp:123
A mesh composed from other meshes.
Definition: composite_mesh.h:28
void update_rsm_camera_parameters(ID3D11DeviceContext *context, dune::directional_light &l)
Update and upload RSM camera parameters (i.e. light view projection matrix etc.). ...
Definition: common_renderer.h:171
A simple skydome mesh.
Definition: skydome.h:20
void set_shader(ID3D11Device *device, ID3DBlob *input_binary, ID3D11VertexShader *vs_deferred, ID3D11PixelShader *ps_deferred, ID3D11PixelShader *ps_overlay, UINT start_slot, UINT overlay_slot, UINT postprocessing_slot)
Set deferred rendering shaders.
Definition: common_renderer.cpp:82
void update(const DirectX::XMFLOAT4 &upt, const DirectX::XMMATRIX &light_proj)
Update the view-projection matrix in the parameter cbuffer for shadowmap/RSM rendering.
Definition: light.cpp:14
void to_ps(ID3D11DeviceContext *context, UINT start_slot)
Upload the shader resource to register slot of a pixel shader.
Definition: cbuffer.h:98
A simple directional light source with an RSM.
Definition: light.h:28
Default implementation of assimp_mesh (pun intended).
Definition: assimp_mesh.h:113
void reset_omrtv(ID3D11DeviceContext *context)
Resets all render target views to nullptr.
Definition: common_renderer.cpp:269
void render(ID3D11DeviceContext *context, DirectX::XMFLOAT4X4 *to_clip=nullptr)
Renders the mesh using the shaders previously set.
Definition: composite_mesh.cpp:80
virtual void save(dune::serializer &s)
Saves dune objects used in the common_renderer. Overload to add more.
Definition: common_renderer.h:305
void clear_rtvs(ID3D11DeviceContext *context, ID3D11RenderTargetView **rtvs, size_t num_rtvs, FLOAT *clear_color)
Clear a list of render targets with a color.
Definition: d3d_tools.cpp:154
void update_camera_parameters(ID3D11DeviceContext *context)
Upload camera parameters to the respective shaders.
Definition: common_renderer.cpp:128
void update_onetime_parameters(ID3D11DeviceContext *context, dune::d3d_mesh &mesh)
Upload one-time parameters (really just once) such as noise textures.
Definition: common_renderer.cpp:167
void set_viewport(ID3D11DeviceContext *context, size_t w, size_t h)
Resize the current viewport.
Definition: d3d_tools.cpp:112
const DirectX::XMFLOAT4X4 & world()
Returns the current world matrix of this mesh.
Definition: mesh.h:79
cb_param & parameters()
Return local cbuffer parameters.
Definition: light.h:60
size_t size()
Returns the number of submeshes.
Definition: composite_mesh.h:66
A simple perspective camera.
Definition: camera.h:26
virtual void destroy()
Destroy the shader_resource and free all memory.
Definition: render_target.cpp:98
void add_buffer(gbuffer &buffer, UINT slot)
Add a gbuffer to the deferred renderer buffer map.
Definition: deferred_renderer.cpp:370
void render_scene(ID3D11DeviceContext *context, float *clear_color, ID3D11DepthStencilView *dsv)
Clear the GBufer and render the scene.
Definition: common_renderer.cpp:225
virtual void do_render_scene(ID3D11DeviceContext *context)
Derived classes can overload this method to call render() on more dune objects. Buffers etc...
Definition: common_renderer.cpp:252
A common, simple deferred renderer.
Definition: common_renderer.h:43
virtual void set_shader_slots(INT diffuse_tex=-1, INT specular_tex=-1, INT normal_tex=-1)
Sets three register numbers to identify the slots the pixel shader is looking for surface textures...
Definition: composite_mesh.cpp:112
virtual void save(dune::serializer &s)
Saves dune objects used in the common_renderer. Overload to add more.
Definition: common_renderer.cpp:275
virtual void do_render_rsm(ID3D11DeviceContext *context)
Virtual function to render more stuff for the RSM.
Definition: common_renderer.h:225
A render target wrapper.
Definition: render_target.h:30
A default implementation of the postprocessor.
Definition: pppipe.h:27
void render_rsm(ID3D11DeviceContext *context, float *clear_color, dune::gbuffer &rsm)
Render a scene from a directional_light position into an RSM.
Definition: common_renderer.h:194
virtual void reload_shader(ID3D11Device *device, ID3D11DeviceContext *context)
A function called if the shaders should be reloaded.
Definition: common_renderer.h:113
A geometry buffer (collection of render_target objects).
Definition: gbuffer.h:30
virtual void update_frame(ID3D11DeviceContext *context, double time, float elapsed_time)
Update function for everything called once a frame.
Definition: common_renderer.cpp:187
void update_light_parameters(ID3D11DeviceContext *context, dune::directional_light &l)
Update and upload parameters (view projection matrix, flux etc.) of a directional light...
Definition: common_renderer.h:269
Main D3D mesh interface class.
Definition: mesh.h:129
void update_scene(ID3D11DeviceContext *context, const DirectX::XMMATRIX &world)
Update the scene with a new model matrix to move/scale/... stuff.
Definition: common_renderer.cpp:174
void to_vs(ID3D11DeviceContext *context, UINT start_slot)
Upload the shader resource to register slot of a vertex shader.
Definition: cbuffer.h:86
virtual void load(ID3D11DeviceContext *context, const dune::serializer &s)
Load dune objects used in the common_renderer. Overload to add more.
Definition: common_renderer.h:311