#include "advancedparticlesystem.h" #include using namespace glh; #include AdvancedParticleSystem::AdvancedParticleSystem(void) { object_shadows=false; depthcalc=true; m_PSys_RenderMode=3; albedo=0.8; symmetry=0; transparency=0.5; } AdvancedParticleSystem::~AdvancedParticleSystem(void) { } void AdvancedParticleSystem::displayLittle(Camera* cam) { m_LittleParticleSystem.RefreshCamera(cam); m_LittleParticleSystem.RefreshBuffer(); cam->SetViewandProjection(); glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_RECTANGLE_NV); glBindTexture(GL_TEXTURE_2D,m_BillboardTexture.getTextureHandler()); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); m_LittleParticleSystem.RenderAsBillboard(); glDisable(GL_BLEND); //glDisable(GL_TEXTURE_2D); } void AdvancedParticleSystem::Display(Camera* cam,Vector LightPos) { //refresh Particle System m_ParticleSystem.RefreshCamera(cam); m_ParticleSystem.RefrBRadius_Dist(); m_ParticleSystem.SortParticles(true); m_ParticleSystem.RefreshBuffer(); CgProgram* ActualProgram; if(depthcalc) { if(m_PSys_RenderMode==0)ActualProgram=&m_Psys_Depth_Default_Program; if(m_PSys_RenderMode==1)ActualProgram=&m_Psys_Depth_Single_Phase_Program; if(m_PSys_RenderMode>1)ActualProgram=&m_Psys_Depth_Multiple_Forward_Program; } else { if(m_PSys_RenderMode==0)ActualProgram=&m_Psys_Default_Program; if(m_PSys_RenderMode==1)ActualProgram=&m_Psys_Single_Phase_Program; if(m_PSys_RenderMode>1)ActualProgram=&m_Psys_Multiple_Forward_Program; } ActualProgram->Enable(); CGparameter param; if(depthcalc) { param=cgGetNamedParameter(*ActualProgram->m_FragmentProgram,"ObjTexture"); cgGLSetTextureParameter(param,m_ObjectsTexture.getColorTextureID()); cgGLEnableTextureParameter(param); } param=cgGetNamedParameter(*ActualProgram->m_FragmentProgram,"FrontTexture"); cgGLSetTextureParameter(param,m_FrontDepthTexture.getColorTextureID()); cgGLEnableTextureParameter(param); if(m_PSys_RenderMode>0) { param=cgGetNamedParameter(*ActualProgram->m_FragmentProgram,"PhaseTexture"); cgGLSetTextureParameter(param,PhaseTexID); cgGLEnableTextureParameter(param); param = cgGetNamedParameter(*ActualProgram->m_FragmentProgram, "Albedo"); cgGLSetParameter1d(param,albedo); param = cgGetNamedParameter(*ActualProgram->m_FragmentProgram, "Symmetry"); cgGLSetParameter1d(param,symmetry2); param = cgGetNamedParameter(*ActualProgram->m_VertexProgram, "LightPosition"); cgGLSetParameter3fv(param,LightPos.GetArrayf()); param = cgGetNamedParameter(*ActualProgram->m_VertexProgram, "EyePosition"); cgGLSetParameter3fv(param,cam->getPosition().GetArrayf()); if(m_PSys_RenderMode>1) { m_LightCamera.SetViewandProjectionOrto(); cgGLSetStateMatrixParameter(cgGetNamedParameter(*ActualProgram->m_VertexProgram, "LightModelViewProj"), CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY); param=cgGetNamedParameter(*ActualProgram->m_FragmentProgram,"Illum1"); if(m_PSys_RenderMode==3) cgGLSetTextureParameter(param,m_ScatteredIlumTexture.getColorTextureID()); else cgGLSetTextureParameter(param,m_IllumTexture.getColorTextureID()); cgGLEnableTextureParameter(param); } } param = cgGetNamedParameter(*ActualProgram->m_FragmentProgram, "Transparency"); cgGLSetParameter1d(param,transparency); param = cgGetNamedParameter(*ActualProgram->m_FragmentProgram, "LightColor"); cgGLSetParameter3dv(param,m_LightColor.GetArray()); if(depthcalc) { glDisable(GL_DEPTH_TEST); } else { glDepthMask(GL_FALSE); } glEnable(GL_BLEND); glBlendFunc(GL_ONE,GL_SRC_ALPHA); //glBlendEquationSeparateEXT(GL_FUNC_ADD,GL_FUNC_ADD); cam->SetViewandProjection(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glTranslatef(m_ParticleSystem.getPosition().x, m_ParticleSystem.getPosition().y, m_ParticleSystem.getPosition().z); /* glDisable(GL_BLEND); glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_RECTANGLE_NV); glDisable(GL_DEPTH_TEST); */ m_ParticleSystem.RenderAsBillboard(); glPopMatrix(); glDisable(GL_BLEND); glDepthMask(GL_TRUE); glEnable(GL_DEPTH_TEST); /* if(depthcalc)cgGLDisableTextureParameter(cgGetNamedParameter(*ActualProgram->m_FragmentProgram,"ObjTexture")); cgGLDisableTextureParameter(cgGetNamedParameter(*ActualProgram->m_FragmentProgram,"FrontTexture")); if(m_PSys_RenderMode>1)cgGLDisableTextureParameter(cgGetNamedParameter(*ActualProgram->m_FragmentProgram,"Illum1")); */ m_Psys_Depth_Multiple_Forward_Program.Disable(); } void AdvancedParticleSystem::displayillum(Camera* cam) { m_TempProg.Enable(); m_DisplayImpostor.setObjSphereRadius(m_ParticleSystem.getBoundingRadius()); m_DisplayImpostor.setObjPosition(Vector(0,0,0)); m_DisplayImpostor.setViewCamera(cam); m_DisplayImpostor.updateCamera(true); CGparameter param=cgGetNamedParameter(*m_TempProg.m_FragmentProgram,"Texture"); cgGLSetTextureParameter(param,m_IllumTexture.getColorTextureID()); cgGLEnableTextureParameter(param); glDisable(GL_BLEND); //glEnable(GL_BLEND); //glBlendFunc(GL_SRC_ALPHA,GL_NONE); cam->SetViewandProjection(); glPushMatrix(); glTranslatef(-1.1*m_ParticleSystem.getBoundingRadius(),0,0); m_DisplayImpostor.Display(); glPopMatrix(); glPushMatrix(); param=cgGetNamedParameter(*m_TempProg.m_FragmentProgram,"Texture"); cgGLSetTextureParameter(param,m_ScatteredIlumTexture.getColorTextureID()); cgGLEnableTextureParameter(param); glTranslatef(1.1*m_ParticleSystem.getBoundingRadius(),0,0); m_DisplayImpostor.Display(); glPopMatrix(); m_TempProg.Disable(); } void AdvancedParticleSystem::Refresh(Camera* cam,Vector LightPos,unsigned int Dt,unsigned int TimefromSecond) { symmetry2=(symmetry+1)/2; //refresh Particle System m_LittleParticleSystem.RefreshCamera(cam); m_LittleParticleSystem.RefreshParticles(Dt,TimefromSecond); m_LittleParticleSystem.RefrBRadius_Dist(); m_LittleParticleSystem.RefreshBuffer(); m_ParticleSystem.m_LittleSystemRadius=m_LittleParticleSystem.getBoundingRadius(); m_ParticleSystem.RefreshParticles(Dt,TimefromSecond); RefreshDepths(cam); if(m_PSys_RenderMode>1)RefreshIllumTextures(LightPos); else m_ParticleSystem.RefrBRadius_Dist(); //render objects inside bounding sphere if(depthcalc)RenderObjectDepths(cam); } void AdvancedParticleSystem::RefreshDepths(Camera* cam) { m_DisplayImpostor.setObjSphereRadius(m_LittleParticleSystem.getBoundingRadius()); m_DisplayImpostor.setObjPosition(m_LittleParticleSystem.getPosition()); Camera* viewcam; Vector dir=cam->getPosition()-m_LittleParticleSystem.getPosition(); double length=dir.Length(); if(lengthSetPosition(position); } else { viewcam=cam; } viewcam=cam; m_DisplayImpostor.setViewCamera(viewcam); m_DisplayImpostor.updateCamera(true); CGparameter param; //FRONT DEPTH // Enable Depth Render Target m_FrontDepthTexture.ReleaseColorBuffer(); m_FrontDepthTexture.EnableTarget(); CgProgram* ActualProgram; if(depthcalc)ActualProgram=&m_FrontDepthProgram; else ActualProgram=&m_DensityOnlyProgram; //enable cg programs ActualProgram->Enable(); //bind textures to programs if(depthcalc) { param=cgGetNamedParameter(*ActualProgram->m_FragmentProgram,"frontTexture"); cgGLSetTextureParameter(param,m_BbFrontDepthTexture.getTextureHandler()); cgGLEnableTextureParameter(param); } param=cgGetNamedParameter(*ActualProgram->m_FragmentProgram,"Texture"); cgGLSetTextureParameter(param,m_BillboardTexture.getTextureHandler()); cgGLEnableTextureParameter(param); //Render System glClearColor(1,1,0,0); glDisable(GL_DEPTH_TEST); m_DisplayImpostor.ApplyCameraTransformOrto(); glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_COLOR); glBlendEquationSeparateEXT(GL_MIN_EXT,GL_FUNC_ADD); m_LittleParticleSystem.RenderAsBillboard(); //disable cg programs if(depthcalc)cgGLDisableTextureParameter(cgGetNamedParameter(*ActualProgram->m_FragmentProgram,"frontTexture")); cgGLDisableTextureParameter(cgGetNamedParameter(*ActualProgram->m_FragmentProgram,"Texture")); ActualProgram->Disable(); m_FrontDepthTexture.DisableTarget(); m_FrontDepthTexture.BindColorBuffer(); } void AdvancedParticleSystem::Initialize() { InitSystems(); m_FrontDepthTexture.Initialize(256,256,"rgba textureRECT"); m_FrontDepthProgram.SetProgramFiles("PSystemFrontDepthPrograms.cg","PSystemFrontDepthPrograms.cg"); m_FrontDepthProgram.SetProgramEntries("VertexProgram","FragmentProgram"); m_FrontDepthProgram.InitPrograms(); m_DensityOnlyProgram.SetProgramFiles("PSystemDensityOnlyPrograms.cg","PSystemDensityOnlyPrograms.cg"); m_DensityOnlyProgram.SetProgramEntries("VertexProgram","FragmentProgram"); m_DensityOnlyProgram.InitPrograms(); //m_IllumTexture.Initialize(256,256,"rgba depth aux=4 textureRECT=aux"); m_IllumTexture.Initialize(256,256,"rgba textureRECT"); m_IllumProgram.SetProgramFiles("IllumPrograms.cg","IllumPrograms.cg"); m_IllumProgram.SetProgramEntries("VertexProgram","FragmentProgram"); m_IllumProgram.InitPrograms(); m_TempProg.SetProgramFiles("SimplePrograms.cg","SimplePrograms.cg"); m_TempProg.SetProgramEntries("VertexProgram","FragmentProgram"); m_TempProg.InitPrograms(); m_TempProg2.SetProgramFiles("SimplePrograms2.cg","SimplePrograms2.cg"); m_TempProg2.SetProgramEntries("VertexProgram","FragmentProgram"); m_TempProg2.InitPrograms(); m_ObjectsTexture.Initialize(512,512,"r float=16 depth textureRECT"); m_ObjDepthProg.SetProgramFiles("ObjDepthPrograms.cg","ObjDepthPrograms.cg"); m_ObjDepthProg.SetProgramEntries("VertexProgram","FragmentProgram"); m_ObjDepthProg.InitPrograms(); m_ScatteredIlumTexture.Initialize(256,256,"rgba textureRECT"); m_ScatterIllumProgram.SetProgramFiles("ScatterIllumPrograms.cg","ScatterIllumPrograms.cg"); m_ScatterIllumProgram.SetProgramEntries("VertexProgram","FragmentProgram"); m_ScatterIllumProgram.InitPrograms(); //Particle system rendering programs m_Psys_Multiple_Forward_Program.SetProgramFiles("Psystem_Multiply_Forward.cg","Psystem_Multiply_Forward.cg"); m_Psys_Multiple_Forward_Program.SetProgramEntries("VertexProgram","FragmentProgram"); m_Psys_Multiple_Forward_Program.InitPrograms(); m_Psys_Depth_Multiple_Forward_Program.SetProgramFiles("Psystem_Multiply_Forward_Depth.cg","Psystem_Multiply_Forward_Depth.cg"); m_Psys_Depth_Multiple_Forward_Program.SetProgramEntries("VertexProgram","FragmentProgram"); m_Psys_Depth_Multiple_Forward_Program.InitPrograms(); m_Psys_Single_Phase_Program.SetProgramFiles("Psystem_Single_Phase.cg","Psystem_Single_Phase.cg"); m_Psys_Single_Phase_Program.SetProgramEntries("VertexProgram","FragmentProgram"); m_Psys_Single_Phase_Program.InitPrograms(); m_Psys_Depth_Single_Phase_Program.SetProgramFiles("Psystem_Single_Phase_Depth.cg","Psystem_Single_Phase_Depth.cg"); m_Psys_Depth_Single_Phase_Program.SetProgramEntries("VertexProgram","FragmentProgram"); m_Psys_Depth_Single_Phase_Program.InitPrograms(); m_Psys_Default_Program.SetProgramFiles("Psystem_Default.cg","Psystem_Default.cg"); m_Psys_Default_Program.SetProgramEntries("VertexProgram","FragmentProgram"); m_Psys_Default_Program.InitPrograms(); m_Psys_Depth_Default_Program.SetProgramFiles("Psystem_Default_Depth.cg","Psystem_Default_Depth.cg"); m_Psys_Depth_Default_Program.SetProgramEntries("VertexProgram","FragmentProgram"); m_Psys_Depth_Default_Program.InitPrograms(); } void AdvancedParticleSystem::InitSystems() { //BiggerSystem m_ParticleSystem.setPosition(Vector(0,0,0)); m_ParticleSystem.setQuota(30); //m_ParticleSystem.m_Emitter.setPosition(Vector(0,-1.2,0)); m_ParticleSystem.m_Emitter.setSize(0.5); m_ParticleSystem.m_Emitter.setSizevariation(0.5); m_ParticleSystem.m_Emitter.setDirection(Vector(0,1,0)); m_ParticleSystem.m_Emitter.setVelocity(0); m_ParticleSystem.m_Emitter.setRadius(1.2); m_ParticleSystem.m_Emitter.setTimeToLive(0); m_ParticleSystem.m_Emitter.setEmissionRate(0); //SmallerSystem m_LittleParticleSystem.setQuota(500); m_LittleParticleSystem.m_Emitter.setTimeToLive(8000); m_LittleParticleSystem.m_Emitter.setTimeToLiveVariation(0); m_LittleParticleSystem.m_Emitter.setSize(0.3); m_LittleParticleSystem.m_Emitter.setRadius(0.5); m_LittleParticleSystem.m_Emitter.setSizevariation(0.3); m_LittleParticleSystem.m_Emitter.setVelocity(0.1); m_LittleParticleSystem.m_Emitter.setVelocityVariation(0.5); //m_LittleParticleSystem.m_Emitter.setDirection(Vector(0,1,0)); m_LittleParticleSystem.m_Emitter.setEmissionRate(40); //m_LittleParticleSystem.m_refreshonce=true; //m_LittleParticleSystem.m_Emitter.setEmissionRate(0);//emit as much as possible } void AdvancedParticleSystem::RefreshIllumTextures(Vector LightPos) { // refresh IllumImpostor //create camera m_LightCamera.SetPosition(LightPos); m_IllumImpostor.setObjPosition(m_ParticleSystem.getPosition()); m_IllumImpostor.setObjSphereRadius(m_ParticleSystem.getBoundingRadius()); m_IllumImpostor.setViewCamera(&m_LightCamera); m_IllumImpostor.updateCamera(true); m_LightCamera=m_IllumImpostor.getOwnCamera(); //Enable illumrendertargets m_IllumTexture.ReleaseColorBuffer(); m_IllumTexture.EnableTarget(); glClearColor(1,1,1,1); glClear(GL_COLOR_BUFFER_BIT); /* if(object_shadows) { glDisable(GL_LIGHTING); glColor4f(0.2,0.2,0.2,0.2); glutSolidTeapot(0.2); }*/ m_IllumProgram.Enable(); CGparameter param; //render particle system param=cgGetNamedParameter(*m_IllumProgram.m_FragmentProgram,"Texture"); cgGLSetTextureParameter(param,m_BillboardTexture.getTextureHandler()); cgGLEnableTextureParameter(param); param=cgGetNamedParameter(*m_IllumProgram.m_FragmentProgram,"PhaseTexture"); cgGLSetTextureParameter(param,PhaseTexID); cgGLEnableTextureParameter(param); param = cgGetNamedParameter(*m_IllumProgram.m_FragmentProgram, "Albedo"); cgGLSetParameter1d(param,albedo); param = cgGetNamedParameter(*m_IllumProgram.m_VertexProgram, "transparency"); cgGLSetParameter1d(param,transparency); param = cgGetNamedParameter(*m_IllumProgram.m_FragmentProgram, "Symmetry"); cgGLSetParameter1d(param,symmetry2); m_ParticleSystem.RefreshCamera(&m_LightCamera); m_ParticleSystem.RefrBRadius_Dist(); m_ParticleSystem.SortParticles(false); m_ParticleSystem.RefreshBuffer(); //render glEnable(GL_BLEND); glBlendFunc(GL_NONE,GL_SRC_COLOR); //apply transform m_LightCamera.SetViewandProjectionOrto(); m_ParticleSystem.RenderAsBillboard(); cgGLDisableTextureParameter(cgGetNamedParameter(*m_IllumProgram.m_FragmentProgram,"Texture")); m_IllumProgram.Disable(); //Disable illurendertargets m_IllumTexture.DisableTarget(); m_IllumTexture.BindColorBuffer(); if(m_PSys_RenderMode>2) { //Compute scattering m_ScatteredIlumTexture.ReleaseColorBuffer(); m_ScatteredIlumTexture.EnableTarget(); glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); m_ScatterIllumProgram.Enable(); param = cgGetNamedParameter(*m_ScatterIllumProgram.m_FragmentProgram, "Transparency"); cgGLSetParameter1f(param,transparency); param = cgGetNamedParameter(*m_ScatterIllumProgram.m_FragmentProgram, "Albedo"); cgGLSetParameter1f(param,albedo); param = cgGetNamedParameter(*m_ScatterIllumProgram.m_FragmentProgram, "Symmetry"); cgGLSetParameter1f(param,symmetry2); param=cgGetNamedParameter(*m_ScatterIllumProgram.m_FragmentProgram,"IllumTexture"); cgGLSetTextureParameter(param,m_IllumTexture.getColorTextureID()); cgGLEnableTextureParameter(param); param=cgGetNamedParameter(*m_ScatterIllumProgram.m_FragmentProgram,"PhaseTexture"); cgGLSetTextureParameter(param,PhaseTexID); cgGLEnableTextureParameter(param); param=cgGetNamedParameter(*m_ScatterIllumProgram.m_FragmentProgram,"AngleTexture"); cgGLSetTextureParameter(param,AngleTexID); cgGLEnableTextureParameter(param); m_IllumImpostor.DisplayScreenQuad(); m_ScatterIllumProgram.Disable(); m_ScatteredIlumTexture.DisableTarget(); m_ScatteredIlumTexture.BindColorBuffer(); } } /* void AdvancedParticleSystem::RefreshIllumTextures(Vector LightPos) { // refresh IllumImpostor //create camera m_LightCamera.SetPosition(LightPos); m_IllumImpostor.setObjPosition(m_ParticleSystem.getPosition()); m_IllumImpostor.setObjSphereRadius(m_ParticleSystem.getBoundingRadius()); m_IllumImpostor.setViewCamera(&m_LightCamera); m_IllumImpostor.updateCamera(true); m_LightCamera=m_IllumImpostor.getOwnCamera(); //Enable illumrendertargets m_IllumTexture.EnableTarget(); //set and clear bacground color and depth const GLenum buffers[] = { GL_AUX0, GL_AUX1, GL_AUX2, GL_AUX3 }; for(int i=0;i<4;i++) { glDrawBuffer(buffers[i]); glClearColor(1,1,1,1); glClearDepth(1.0); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT ); } glDrawBuffersATI(4, buffers); m_IllumProgram.Enable(); CGparameter param;float transparency; if(object_shadows) { //render objects inside bounding sphere glEnable(GL_DEPTH_TEST); glColor4f(0,0,0,1); param=cgGetNamedParameter(*m_IllumProgram.m_FragmentProgram,"Texture"); cgGLSetTextureParameter(param,0); cgGLEnableTextureParameter(param); transparency=0.3; param= cgGetNamedParameter(*m_IllumProgram.m_VertexProgram, "transparency"); cgGLSetParameter1f(param,transparency); glutSolidTeapot(0.73); glDisable(GL_DEPTH_TEST); } //render particle system param=cgGetNamedParameter(*m_IllumProgram.m_FragmentProgram,"Texture"); cgGLSetTextureParameter(param,m_BillboardTexture.getTextureHandler()); cgGLEnableTextureParameter(param); transparency=0.12; param = cgGetNamedParameter(*m_IllumProgram.m_VertexProgram, "transparency"); cgGLSetParameter1f(param,transparency); m_ParticleSystem.RefreshCamera(&m_LightCamera); m_ParticleSystem.SortParticles(true); m_ParticleSystem.RefreshBuffer(); //render glEnable(GL_BLEND); glBlendFunc(GL_NONE,GL_ONE_MINUS_SRC_ALPHA); //apply transform m_LightCamera.SetViewandProjectionOrto(); m_ParticleSystem.RenderAsBillboard(); cgGLDisableTextureParameter(cgGetNamedParameter(*m_IllumProgram.m_FragmentProgram,"Texture")); m_IllumProgram.Disable(); glFinish(); //Disable illurendertargets m_IllumTexture.DisableTarget(); } */ void AdvancedParticleSystem::RenderObjectDepths(Camera* cam) { m_ObjectsTexture.ReleaseColorBuffer(); m_ObjectsTexture.EnableTarget(); m_ObjDepthProg.Enable(); glClearColor(-100.0f,-100.0f,-100.0f,0.0f); //glClearColor(0.0f,0.0f,1.0f,0.0f); glEnable(GL_DEPTH_TEST); glClearDepth(1.0); glDepthFunc(GL_LEQUAL); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); cam->SetViewandProjection(); glDisable(GL_LIGHTING); glDisable(GL_BLEND); //render scene this->theScene->Display(true); m_ObjDepthProg.Disable(); m_ObjectsTexture.DisableTarget(); m_ObjectsTexture.BindColorBuffer(); }