#pragma once #include #include #include #include #include #include #include #include /** @brief This class represents a particle system that uses the Illumination Networks technique. This particle system can be lit with two dinamic directional light sources and a sky light color. The direction and color of the light sources can freely change. */ class PreIllumSystem { public: PreIllumSystem(void) { m_IterateCount=0; m_Symmetry=0.0; m_Albedo=0.9; m_Opacity=0.5; m_LightWindowSize=64; m_LRendVisMap=NULL; } ~PreIllumSystem(void); /** @brief a system that stores particle positions and can render them as sprites */ ParticleSystem m_System; /** @brief the number of directions the technique should use */ int m_DirectionCount; /** @brief the number of particles in the system */ int m_ParticleCount; /** @brief the albedo of one particle */ float m_Albedo; /** @brief the desirer opacity of the medium */ float m_Opacity; /** @brief the symmetry of scattering used in the phase function */ float m_Symmetry; /** @brief resolution of the lightsources viewports */ int m_LightWindowSize; /** @brief number of iterations in a frame As the result of the last frame is used, this should be set to one. */ int m_IterateCount; private: /** @brief color of the sky */ Vector m_SkyColor; /** @brief used for fullscreen quad rendering */ Impostor m_ScreenQuad; Impostor m_CameraImpostor; Impostor m_LightImpostor; /** @brief view camera */ Camera *m_EyeCamera; Camera m_TempCamera; /** @brief position of the first lightsource */ Vector m_LightPosition; /** @brief color of the first lightsource */ Vector m_LightColor; /** @brief position of the second lightsource */ Vector m_LightPosition2; /** @brief color of the second lightsource */ Vector m_LightColor2; /** @brief the closest direction from the predefined directions to the light's direction */ int m_NearestDir; /** @brief the second closest direction from the predefined directions to the light's direction */ int m_NearestDir2; /** @brief weight of m_NearestDir m_NearestDir and m_NearestDir2 will be interpolated */ float m_Weight1; /** @brief weight of m_NearestDir2 m_NearestDir and m_NearestDir2 will be interpolated */ float m_Weight2; // helper members Particle* m_ParticleArray; float* m_PositionArray; float* m_DirectionData; Vector* m_Directions; float* m_DirectionArray; unsigned char* m_LVisMap; unsigned char* m_LRendVisMap; float* m_Pixels; //texture id's /** @brief stores the visibility information of the particles For each particle for each direction the first visible (from that direction) particle's id is stored. */ GLuint m_VisibilityTexID; /** @brief stores predefined directions to use */ GLuint m_DirectionsTexID; /** @brief a look-up texture to speed up phase function calculation */ GLuint m_PhaseTextureID; /** @brief a texture that can be used to determine which particles are visible from the lightsource */ GLuint m_LVisMapID; /** @brief used when determining licible particles @see FindVisiblesWithRendering */ GLuint m_RenderedVisID; /** @brief stores tau value for each particle */ GLuint m_TauTextureID; // Cg programs CgProgram m_TexRectPrograms; CgProgram m_LightIllumPrograms; CgProgram m_IllumIteratePrograms; CgProgram m_EyeRadPrograms; CgProgram m_LVisPrograms; CgProgram m_FinalRenderPrograms; //render textures, textures //direct illumination of the lightsource RenderTexture m_DirectIlumTexture; //two illumtextures are used, must ping-pong between them RenderTexture m_IllumTexture; RenderTexture m_IllumTexture2; RenderTexture* m_IllumColorTex; RenderTexture* m_IllumRenderTex; // radiance to eye RenderTexture m_EyeRadTexture; RenderTexture m_Target; Texture m_BillboardTexture; Texture m_Bbtex; //helper RenderTexture m_ImpostorTexture; /** @brief generates directions equally along the unit sphere */ void CreateGivenDirections(); /** @brief generates random directions */ void CreateRandomDirections(bool fillarray); void Calculate_Up_Right_Vector(Vector viewdir,Vector& UpVector,Vector& RightVector); /** @brief calculates the scattering phase function value for two directions and a symmetry value */ float Phase(Vector diri,Vector dirj,float symmetry); /** @brief searches the stored directions and returns the one closest to a given direction */ GetNearestDirection(Vector LightPosition); /** @brief Initializator function. */ void InitSystem(int particlecount,int directioncount); /** @brief Creates a texture that stores the visibility information of the particles. For each particle for each direction the first visible (from that direction) particle's id is stored. */ void CreateVisibilityTexture(); /** @brief Creates a texture that stores */ void CreateNearestDirectionTexture(); /** @brief Creates a look-up texture to speed up phase function calculation. */ void CreatePhaseTexture(); /** @brief Creates a texture that can be used to determine which particles are visible from the lightsource */ void CreateLVisMap(); /** @brief Creates a texture tha stores the tau value for each particle. The tau values are calculated from the given desired opacity and the size of the particle. */ void CreateTauTexture(); /** @brief Refreshes the texture that stores direct illumination information. Direct illumination is the amount of light coming directly from the lightsource. */ void RefreshDirectIllumTexture(); /** @brief Updates the illumination texture. */ void Iterate(); /** @brief Updates the eye radiance texture. The eye radiance texture stores the amount of light headig from each particle to the eye. */ void CreateEyeRadTexture(); /** @brief Finds the visible particles from a point of view. The light visibility texture stores the id of the visible particles (with occlusion) from the light sources. The param "row" means the id of the lightsource ( 0 or 1). The visibility is calculated with rendering the particles from the lightsource. Each particle has a color corresponding it's id. The resulting image is read back, and the pixels are counted. If the number of pixels with a particle's id found is greather than some limit, the particle is visible. */ void FindVisiblesWithRendering(Vector LightPosition,int row); /** @brief not used */ void RenderToImpostor(); public: void SetEyeCamera(Camera* theCam) { m_EyeCamera=theCam; m_CameraImpostor.setViewCamera(theCam); } /** @brief Initializator function. */ void Init(int particlecount,int directioncount); /** @brief Render the particle system. */ void Display(); /** @brief Refreshes the system in a frame. The actual light positions and colors should be passed. */ void Refresh(Vector lightpos,Vector lightpos2,Vector lightcolor,Vector lightcolor2); /** @brief Displays one of the textures used by the system. Used for debugging and presentation. */ char* DisplayTexture(int tex); void getNearest(Vector* positions) { positions[0]=m_Directions[m_NearestDir]*3; positions[1]=m_Directions[m_NearestDir2]*3; } void IncreaseOpacity() { m_Opacity+=0.02; if(m_Opacity>1)m_Opacity=1; } void DecreaseOpacity() { m_Opacity-=0.02; if(m_Opacity<0)m_Opacity=0; } void IncreaseAlbedo() { m_Albedo+=0.02; if(m_Albedo>1)m_Albedo=1; } void DecreaseAlbedo() { m_Albedo-=0.02; if(m_Albedo<0)m_Albedo=0; } float getAlbedo(){return m_Albedo;} float getOpacity(){return m_Opacity;} void ResetIllumTexture() { m_IllumColorTex->EnablewithColorRelease(); glClearColor(0,0,0,1); glClear(GL_COLOR_BUFFER_BIT); m_IllumColorTex->DisablewithColorBind(); } void setSkyColor(Vector skyC){m_SkyColor=skyC;} };