[2197] | 1 | #pragma once
|
---|
| 2 | #include <vector>
|
---|
| 3 | #include "Parameters.h"
|
---|
| 4 | #include "Vector.hpp"
|
---|
| 5 | #include "Uniform.hpp"
|
---|
| 6 | #include "Radion.hpp"
|
---|
| 7 | #include "KDTree.hpp"
|
---|
| 8 | #include "xmlParser.h"
|
---|
| 9 |
|
---|
| 10 | class Material;
|
---|
| 11 | class TriangleMesh;
|
---|
| 12 | class Transformed;
|
---|
| 13 | class KDTree;
|
---|
| 14 | class RenderStrategy;
|
---|
| 15 |
|
---|
| 16 | /*!
|
---|
| 17 | \brief Main class for the PRM computation and usage application.
|
---|
| 18 | This class encapsulates all resources needed for computing PRMs and
|
---|
| 19 | using them in the final rendering. PRM resources may be generated,
|
---|
| 20 | saved to files, or restored.
|
---|
| 21 | */
|
---|
| 22 | class PathMapEffect
|
---|
| 23 | {
|
---|
| 24 | int NRADIONS;
|
---|
| 25 | int NCLUSTERS;
|
---|
| 26 | int DEPTHMAPRES;
|
---|
| 27 |
|
---|
| 28 | int testClusterId;
|
---|
| 29 |
|
---|
| 30 | friend class SubEntity;
|
---|
| 31 | friend class SubMesh;
|
---|
| 32 | friend class Entity;
|
---|
| 33 | friend class Mesh;
|
---|
| 34 | friend class DepthRenderStrategy;
|
---|
| 35 | friend class FinalCompositionRenderStrategy;
|
---|
| 36 |
|
---|
| 37 | float clusterSweepCurrentIndex; //!< test, cycling displayed entry point clusters
|
---|
| 38 |
|
---|
| 39 | //! pointer to global user-adjustable application parameters object
|
---|
| 40 | static Parameters* parameters;
|
---|
| 41 |
|
---|
| 42 | //! pointer to main DX device
|
---|
| 43 | LPDIRECT3DDEVICE9 device;
|
---|
| 44 | //! pointer to main DX effect
|
---|
| 45 | LPD3DXEFFECT effect;
|
---|
| 46 |
|
---|
| 47 | //! frame color buffer surface
|
---|
| 48 | //! saved before render-to-texture, and restored as the render target for the final rendering to the screen
|
---|
| 49 | LPDIRECT3DSURFACE9 frameColorBuffer;
|
---|
| 50 | //! frame depth buffer surface
|
---|
| 51 | //! saved before render-to-texture, and restored as the render target for the final rendering to the screen
|
---|
| 52 | LPDIRECT3DSURFACE9 frameDepthStencilBuffer;
|
---|
| 53 |
|
---|
| 54 | LPDIRECT3DTEXTURE9 depthMapTexture; //!< depth map texture
|
---|
| 55 | LPDIRECT3DSURFACE9 depthMapDepthStencilBuffer; //!< depth map texture's surface
|
---|
| 56 | LPDIRECT3DTEXTURE9 fakeTexture; //!< depth map dummy render texture
|
---|
| 57 | LPDIRECT3DSURFACE9 fakeSurface; //!< depth map dummy render surface
|
---|
| 58 |
|
---|
| 59 | LPDIRECT3DVERTEXBUFFER9 starterVertexBuffer; //!< vertex buffer with entry point positions, for entry point visualization
|
---|
| 60 |
|
---|
| 61 | LPDIRECT3DTEXTURE9 weightsTexture; //!< render target texture to which current entry point weights are computed
|
---|
| 62 | LPDIRECT3DSURFACE9 weightsSurface; //!< weights texture's surface
|
---|
| 63 | LPDIRECT3DTEXTURE9 sysMemWeightsTexture; //!< weights texture copy in system mem
|
---|
| 64 | LPDIRECT3DSURFACE9 sysMemWeightsSurface; //!< surface of weights texture copy in system mem
|
---|
| 65 | LPDIRECT3DTEXTURE9 radionTexture; //!< texture containing entry point data, input for weight computation
|
---|
| 66 | LPDIRECT3DSURFACE9 radionSurface; //!< entry point texture's surface
|
---|
| 67 |
|
---|
| 68 | KDTree* kdtree; //!< the kd-tree that contains the scene geometry in raytraceable format
|
---|
| 69 |
|
---|
| 70 | //! clever enum for supported final rendering methods
|
---|
| 71 | class Method{
|
---|
| 72 | unsigned int mid;
|
---|
| 73 | Method(unsigned int mid) {this->mid = mid;}
|
---|
| 74 | static const wchar_t * methodNames[10];
|
---|
| 75 | public:
|
---|
| 76 | Method(const Method& o) {mid = o.mid;}
|
---|
| 77 | const Method& operator=(const Method& o) {mid = o.mid; return *this;}
|
---|
| 78 | bool operator==(const Method& o) const {return mid == o.mid;}
|
---|
| 79 | bool operator!=(const Method& o) const {return mid != o.mid;}
|
---|
| 80 | const static Method PRM;
|
---|
| 81 | const static Method SHOWTEX;
|
---|
| 82 | const static Method LAST;
|
---|
| 83 | const Method& next() {mid = (mid + 1)%LAST.mid; return *this;}
|
---|
| 84 | const Method& prev() {mid = (mid + LAST.mid - 1)%LAST.mid; return *this;}
|
---|
| 85 | const wchar_t* getName() {return methodNames[mid];}
|
---|
| 86 | }method;
|
---|
| 87 | public:
|
---|
| 88 | void nextMethod() {method.next();}
|
---|
| 89 | void prevMethod() {method.prev();}
|
---|
| 90 | const wchar_t* getCurrentMethodName();
|
---|
| 91 |
|
---|
| 92 | //! camera
|
---|
| 93 | CFirstPersonCamera* camera;
|
---|
| 94 | //! primary light source (can be moved just like the real camera, and can be used as the camera)
|
---|
| 95 | CFirstPersonCamera* lightCamera;
|
---|
| 96 | private:
|
---|
| 97 |
|
---|
| 98 | //! xml data with material name -> texture reference
|
---|
| 99 | XMLNode xMaterials;
|
---|
| 100 |
|
---|
| 101 | std::vector<Mesh*> meshes;
|
---|
| 102 | //! vector of loaded textures (textures specified in mesh's material/bumpmap will be loaded here)
|
---|
| 103 | std::vector<LPDIRECT3DTEXTURE9> materialTextures;
|
---|
| 104 | std::vector<wchar_t*> materialTextureFileNames;
|
---|
| 105 | //! vector of ray trace materials
|
---|
| 106 | std::vector<Material*> rayTraceMaterials;
|
---|
| 107 |
|
---|
| 108 | //! for materials with no texture we will render with this texture
|
---|
| 109 | LPDIRECT3DTEXTURE9 emptyTexture;
|
---|
| 110 |
|
---|
| 111 | //! private method that loads a mesh and its textures
|
---|
| 112 | void loadMesh(DWORD fileType, LPCWSTR fileName, LPCWSTR ogreName, int prmAtlasSize, const char* name, int dividePcs, bool generateUV, bool generateTBN);
|
---|
| 113 |
|
---|
| 114 | //! private method to load a texture
|
---|
| 115 | LPDIRECT3DTEXTURE9 loadTexture(LPCWSTR fileName, Material** rayTraceMaterial=NULL);
|
---|
| 116 |
|
---|
| 117 | //! private method make a CPU Material out of a D3D texture
|
---|
| 118 | Material* createRayTraceMaterial(LPDIRECT3DTEXTURE9 texture);
|
---|
| 119 |
|
---|
| 120 | //! release material texture resources
|
---|
| 121 | void releaseTextures();
|
---|
| 122 | //! release mesh resources
|
---|
| 123 | void releaseMeshes();
|
---|
| 124 | //! release entities
|
---|
| 125 | void releaseEntities();
|
---|
| 126 |
|
---|
| 127 | //! struct that represents a virtual world object: a mesh and a model-world transformation matrix
|
---|
| 128 |
|
---|
| 129 | //! renders a full screen quad, invoking the pixel shader for all pixels
|
---|
| 130 | //! used for rendering the environment map to the background
|
---|
| 131 | void renderFullScreen(float depth = 0.0f);
|
---|
| 132 |
|
---|
| 133 | //! vector of virtual world objects
|
---|
| 134 | std::vector<Entity*> entities;
|
---|
| 135 | public:
|
---|
| 136 | //! constructor: allocates all resources
|
---|
| 137 | PathMapEffect(LPDIRECT3DDEVICE9 device,
|
---|
| 138 | char* prmDirectory,
|
---|
| 139 | char* meshDirectory,
|
---|
| 140 | char* mediaDirectory,
|
---|
| 141 | char* levelFileName,
|
---|
| 142 | char* materialFileName,
|
---|
| 143 | bool segmentMeshes,
|
---|
| 144 | bool computePRM,
|
---|
| 145 | unsigned int nEntryPoints,
|
---|
| 146 | unsigned int nClusters,
|
---|
| 147 | unsigned int depthMapResolution);
|
---|
| 148 |
|
---|
| 149 | wchar_t prmDirectory[256];
|
---|
| 150 | wchar_t meshDirectory[256];
|
---|
| 151 | wchar_t mediaDirectory[256];
|
---|
| 152 | wchar_t levelFileName[256];
|
---|
| 153 | wchar_t materialFileName[256];
|
---|
| 154 | bool SEGMENTMESHES;
|
---|
| 155 |
|
---|
| 156 | //! destructor: releases all resources
|
---|
| 157 | ~PathMapEffect(void);
|
---|
| 158 |
|
---|
| 159 | //! renders the scene using the currently selected method
|
---|
| 160 | void render();
|
---|
| 161 |
|
---|
| 162 | //! renders the scene, using the PRMs for indirect illumination
|
---|
| 163 | void renderWithPRM();
|
---|
| 164 |
|
---|
| 165 | //! displays a part of a PRM texture
|
---|
| 166 | // void showPRMTexture();
|
---|
| 167 |
|
---|
| 168 | //! moves the virtual world objects (camera, light)
|
---|
| 169 | void move(float fElapsedTime);
|
---|
| 170 |
|
---|
| 171 | LRESULT handleMessage( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
---|
| 172 |
|
---|
| 173 | //! adds controls for the user-adjustable application parameters
|
---|
| 174 | static void addUiParameters(Parameters* parameters);
|
---|
| 175 | static void setUiParameterDefaults(Parameters* parameters);
|
---|
| 176 |
|
---|
| 177 | LPDIRECT3DDEVICE9 getDevice() {return device;}
|
---|
| 178 |
|
---|
| 179 | const wchar_t* getWeightsString();
|
---|
| 180 | private:
|
---|
| 181 | float* weights; //!< the array of averaged cluster weights
|
---|
| 182 | unsigned int* clusterLenghts; //!< array thet contasins the number of entry points in every cluster (entry points are stored continously [bushStarters, starterVertexBuffer])
|
---|
| 183 |
|
---|
| 184 | float sumSurfaceArea; //!< summed surface area of all entities
|
---|
| 185 |
|
---|
| 186 | void createPRMTextures(); //!< allocates PRM resources for every entity
|
---|
| 187 |
|
---|
| 188 | //! generates a random direction (cosine distribution) near a normal vector
|
---|
| 189 | static void sampleShootingDiffuseDirection(int depth, const Vector& normal, Vector& outDir);
|
---|
| 190 | //! generates a random direction an the unit sphere
|
---|
| 191 | static void sampleSphereDirection(Vector& outDir);
|
---|
| 192 |
|
---|
| 193 | //! finds a random entry point (all entities considered with equal probability)
|
---|
| 194 | void sampleSurfaceRadion(Radion& starter);
|
---|
| 195 | //! finds a random entry point (all entities considered with probability proporstional to surface area)
|
---|
| 196 | void sampleSurfaceRadionUniform(Radion& starter);
|
---|
| 197 |
|
---|
| 198 | //! shoot virtual light sources from original entry point and add them to the vector
|
---|
| 199 | void shootRadionBush(Radion& starter, std::vector<Radion>& bushRadions);
|
---|
| 200 |
|
---|
| 201 | //! sort radions into initial, uniform length clusters
|
---|
| 202 | int clusterRadions(Radion* partition, int psize, char axis);
|
---|
| 203 |
|
---|
| 204 | //! use K-means clustering to cluster radions
|
---|
| 205 | void clusterRadionsKMeans();
|
---|
| 206 |
|
---|
| 207 | //! perform computaions: generate entry points, render PRMs
|
---|
| 208 | void precompute();
|
---|
| 209 |
|
---|
| 210 | int getNBushes() {return NRADIONS; }
|
---|
| 211 | int getNClusters() {return NCLUSTERS;}
|
---|
| 212 |
|
---|
| 213 | //! entry points
|
---|
| 214 | std::vector<Radion> bushStarters;
|
---|
| 215 |
|
---|
| 216 | int rayId;
|
---|
| 217 | Ray ray;
|
---|
| 218 | HitRec hitRec;
|
---|
| 219 |
|
---|
| 220 | //! fill 'radionsTexture' from 'bushStarters'
|
---|
| 221 | void uploadRadions();
|
---|
| 222 | //! fill *pData (will point to locked 'starterVertexBuffer') from 'bushStarters'
|
---|
| 223 | void fillRadionPosArray(void* pData);
|
---|
| 224 |
|
---|
| 225 | public:
|
---|
| 226 | //! store all precomputed data for the scene in folder prm
|
---|
| 227 | void savePathMaps();
|
---|
| 228 | //! restore all precomputed data for the scene from folder prm
|
---|
| 229 | void loadPathMaps();
|
---|
| 230 |
|
---|
| 231 | void exportEntityData();
|
---|
| 232 |
|
---|
| 233 | void loadScene(const char* sceneFileName);
|
---|
| 234 | void saveScene(const char* sceneFileName);
|
---|
| 235 |
|
---|
| 236 | void renderScene(const RenderStrategy& renderStrategy);
|
---|
| 237 | };
|
---|