#include "advancedparticlesystem.h" #include using namespace glh; #include AdvancedParticleSystem::AdvancedParticleSystem(void) { object_shadows=false; depthcalc=true; m_PSys_RenderMode=3; albedo=0.91; symmetry=0.02; transparency=0.55; m_HasSceneTransformMatrix=false; } 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"); cgGLSetParameter3fv(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->SetViewandProjectionNew(); 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::displaytexture(int tex) { unsigned int texID; int u=256,v=256; if(tex==0)//composite texture { texID=m_FrontDepthTexture.getColorTextureID(); } if(tex==1)//illumination texture { texID=m_IllumTexture.getColorTextureID(); } if(tex==2)//illumination texture { texID=m_ScatteredIlumTexture.getColorTextureID(); } m_TempProg.SetFragmentTexParam("Texture",texID); m_TempProg.Enable(); m_DisplayImpostor.DisplayScreenQuad(u,v); m_TempProg.DisableFragmentTexParam("Texture"); m_TempProg.Disable(); } void AdvancedParticleSystem::Refresh(Camera* cam,Vector LightPos,unsigned int Dt,unsigned int TimefromSecond) { static int r=0; 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) { Camera viewcam; viewcam.setNearClipDistance(0); viewcam.setFarClipDistance(2*m_LittleParticleSystem.getBoundingRadius()); viewcam.setCorners(-m_LittleParticleSystem.getBoundingRadius(), m_LittleParticleSystem.getBoundingRadius(), m_LittleParticleSystem.getBoundingRadius(), -m_LittleParticleSystem.getBoundingRadius()); viewcam.SetUpVector(cam->getUpVector()); viewcam.setRightVector(cam->getRightVector()); viewcam.setLookAt(m_LittleParticleSystem.getPosition()); Vector dir=(cam->getPosition()-cam->getLookAt()).Normalize(); viewcam.SetPosition(viewcam.getLookAt()+dir*m_LittleParticleSystem.getBoundingRadius()); CGparameter param; //FRONT DEPTH CgProgram* ActualProgram; if(depthcalc) { ActualProgram=&m_FrontDepthProgram; ActualProgram->SetFragmentTexParam("frontTexture",m_BbFrontDepthTexture.getTextureHandler()); } else ActualProgram=&m_DensityOnlyProgram; ActualProgram->SetFragmentTexParam("Texture",m_BillboardTexture.getTextureHandler()); // Enable Depth Render Target m_FrontDepthTexture.EnablewithColorRelease(); //enable cg programs ActualProgram->Enable(); //Render System glClearColor(1,1,0,0); glDisable(GL_DEPTH_TEST); //m_DisplayImpostor.ApplyCameraTransformOrto(); viewcam.SetViewandProjectionOrto(); 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)ActualProgram->DisableFragmentTexParam("frontTexture"); ActualProgram->Disable(); //ilutGLScreenie(); m_FrontDepthTexture.DisablewithColorBind(); } void AdvancedParticleSystem::Initialize() { InitSystems(); m_FrontDepthTexture.Initialize(256,256,"rgba textureRECT",true,true); 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",true,true); 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",true,true); m_ScatterIllumProgram.SetProgramFiles("ScatterIllumPrograms.cg","ScatterIllumPrograms.cg"); m_ScatterIllumProgram.SetProgramEntries("VertexProgram","FragmentProgram"); m_ScatterIllumProgram.InitPrograms(); m_ScatteredIlumTexture.EnablewithColorRelease(); glClearColor(0,0,0,0); glClear(GL_COLOR_BUFFER_BIT); m_ScatteredIlumTexture.DisablewithColorBind(); //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.m_Emitter.setPositionsFile("cloud.txt"); m_ParticleSystem.m_Emitter.setOffset(0.01); m_ParticleSystem.setQuota(100); m_ParticleSystem.m_Emitter.setSize(4.2); m_ParticleSystem.m_Emitter.setSizevariation(0.5); m_ParticleSystem.m_Emitter.setDirection(Vector(0,0,1)); m_ParticleSystem.m_Emitter.setVelocity(0); m_ParticleSystem.m_Emitter.setRadius(1.0); m_ParticleSystem.m_Emitter.setTimeToLive(0); m_ParticleSystem.m_Emitter.setEmissionRate(0); //SmallerSystem m_LittleParticleSystem.setQuota(400); m_LittleParticleSystem.m_Emitter.setTimeToLive(6000); m_LittleParticleSystem.m_Emitter.setTimeToLiveVariation(2000); m_LittleParticleSystem.m_Emitter.setSize(0.2); m_LittleParticleSystem.m_Emitter.setRadius(0.92); m_LittleParticleSystem.m_Emitter.setSizevariation(0.8); m_LittleParticleSystem.m_Emitter.setVelocity(0.07); m_LittleParticleSystem.m_Emitter.setVelocityVariation(0.5); m_LittleParticleSystem.m_Emitter.setEmissionRate(150); } void AdvancedParticleSystem::RefreshIllumTextures(Vector LightPos) { // refresh IllumImpostor //refresh camera m_ParticleSystem.RefrBRadius_Dist(true); m_LightCamera.setLookAt(m_ParticleSystem.getPosition()); Vector tolight=LightPos-m_ParticleSystem.getPosition(); tolight.Normalize(); tolight=tolight*m_ParticleSystem.getBoundingRadius(); Vector newpos=m_ParticleSystem.getPosition()+tolight; m_LightCamera.SetPosition(newpos); m_LightCamera.setNearClipDistance(0); m_LightCamera.setFarClipDistance(2*m_ParticleSystem.getBoundingRadius()); m_LightCamera.setCorners(-m_ParticleSystem.getBoundingRadius(), m_ParticleSystem.getBoundingRadius(), m_ParticleSystem.getBoundingRadius(), -m_ParticleSystem.getBoundingRadius()); //cg parameters m_IllumProgram.SetFragmentTexParam("Texture",m_BillboardTexture.getTextureHandler()); m_IllumProgram.SetFragmentTexParam("PhaseTexture",PhaseTexID); m_IllumProgram.SetFragmentParam1f("Albedo",albedo); m_IllumProgram.SetVertexParam1f("transparency",transparency); m_IllumProgram.SetFragmentParam1f("Symmetry",symmetry2); //Enable illumrendertarget m_IllumTexture.EnablewithColorRelease(); glClearColor(1,1,1,1); glClear(GL_COLOR_BUFFER_BIT); m_IllumProgram.Enable(); CGparameter param; //sort: front to back m_ParticleSystem.SortFromCamera(&m_LightCamera, false,false,true); //render glEnable(GL_BLEND); glBlendFunc(GL_NONE,GL_SRC_COLOR); //apply transform m_LightCamera.SetViewandProjectionOrto(); m_ParticleSystem.RenderAsBillboard(); m_IllumProgram.DisableFragmentTexParam("Texture"); m_IllumProgram.DisableFragmentTexParam("PhaseTexture"); m_IllumProgram.Disable(); //Disable illurendertargets m_IllumTexture.DisablewithColorBind(); //here should come the filtering pass but it is not working properly so: //just blend the new image with the previous result to avoid abrupt changes (some kind of motion blur) //so m_ScatteredIlumTexture is not the filtered but the motion blurred illumination texture m_TempProg.SetFragmentTexParam("Texture",m_IllumTexture.getColorTextureID()); m_ScatteredIlumTexture.EnablewithColorRelease(); glBlendColorEXT(1,1,1,0.08); glEnable(GL_BLEND); glBlendFunc(GL_CONSTANT_ALPHA_EXT,GL_ONE_MINUS_CONSTANT_ALPHA_EXT); m_TempProg.Enable(); m_DisplayImpostor.DisplayScreenQuad(256,256); m_TempProg.Disable(); m_ScatteredIlumTexture.DisablewithColorBind(); m_TempProg.DisableFragmentTexParam("Texture"); } 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->SetViewandProjectionNew(); glDisable(GL_LIGHTING); glDisable(GL_BLEND); //render scene if(m_HasSceneTransformMatrix) { glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadMatrixf(m_SceneTransformMatrix); this->theScene->Display(true); glPopMatrix(); } else { this->theScene->Display(true); } m_ObjDepthProg.Disable(); m_ObjectsTexture.DisableTarget(); m_ObjectsTexture.BindColorBuffer(); }