Guest User

Untitled

a guest
Jun 28th, 2016
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.93 KB | None | 0 0
  1. /*
  2. Copyright (C) 1996-2001 Id Software, Inc.
  3. Copyright (C) 2002-2009 John Fitzgibbons and others
  4.  
  5. This program is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU General Public License
  7. as published by the Free Software Foundation; either version 2
  8. of the License, or (at your option) any later version.
  9.  
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13.  
  14. See the GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  19. */
  20. //gl_fog.c -- global and volumetric fog
  21.  
  22. #include "quakedef.h"
  23.  
  24. //==============================================================================
  25. //
  26. //  GLOBAL FOG
  27. //
  28. //==============================================================================
  29.  
  30. float fog_density;
  31. float fog_red;
  32. float fog_green;
  33. float fog_blue;
  34.  
  35. float old_density;
  36. float old_red;
  37. float old_green;
  38. float old_blue;
  39.  
  40. float fade_time; //duration of fade
  41. float fade_done; //time when fade will be done
  42.  
  43. /*
  44. =============
  45. Fog_Update
  46.  
  47. update internal variables
  48. =============
  49. */
  50. void Fog_Update (float density, float red, float green, float blue, float time)
  51. {
  52.     //save previous settings for fade
  53.     if (time > 0)
  54.     {
  55.         //check for a fade in progress
  56.         if (fade_done > cl.time)
  57.         {
  58.             float f, d;
  59.  
  60.             f = (fade_done - cl.time) / fade_time;
  61.             old_density = f * old_density + (1.0 - f) * fog_density;
  62.             old_red = f * old_red + (1.0 - f) * fog_red;
  63.             old_green = f * old_green + (1.0 - f) * fog_green;
  64.             old_blue = f * old_blue + (1.0 - f) * fog_blue;
  65.         }
  66.         else
  67.         {
  68.             old_density = fog_density;
  69.             old_red = fog_red;
  70.             old_green = fog_green;
  71.             old_blue = fog_blue;
  72.         }
  73.     }
  74.  
  75.     fog_density = density;
  76.     fog_red = red;
  77.     fog_green = green;
  78.     fog_blue = blue;
  79.     fade_time = time;
  80.     fade_done = cl.time + time;
  81. }
  82.  
  83. /*
  84. =============
  85. Fog_ParseServerMessage
  86.  
  87. handle an SVC_FOG message from server
  88. =============
  89. */
  90. void Fog_ParseServerMessage (void)
  91. {
  92.     float density, red, green, blue, time;
  93.  
  94.     density = MSG_ReadByte() / 255.0;
  95.     red = MSG_ReadByte() / 255.0;
  96.     green = MSG_ReadByte() / 255.0;
  97.     blue = MSG_ReadByte() / 255.0;
  98.     time = max(0.0, MSG_ReadShort() / 100.0);
  99.  
  100.     Fog_Update (density, red, green, blue, time);
  101. }
  102.  
  103. /*
  104. =============
  105. Fog_FogCommand_f
  106.  
  107. handle the 'fog' console command
  108. =============
  109. */
  110. void Fog_FogCommand_f (void)
  111. {
  112.     switch (Cmd_Argc())
  113.     {
  114.     default:
  115.     case 1:
  116.         Con_Printf("usage:\n");
  117.         Con_Printf("   fog <density>\n");
  118.         Con_Printf("   fog <red> <green> <blue>\n");
  119.         Con_Printf("   fog <density> <red> <green> <blue>\n");
  120.         Con_Printf("current values:\n");
  121.         Con_Printf("   \"density\" is \"%f\"\n", fog_density);
  122.         Con_Printf("   \"red\" is \"%f\"\n", fog_red);
  123.         Con_Printf("   \"green\" is \"%f\"\n", fog_green);
  124.         Con_Printf("   \"blue\" is \"%f\"\n", fog_blue);
  125.         break;
  126.     case 2:
  127.         Fog_Update(max(0.0, atof(Cmd_Argv(1))),
  128.                    fog_red,
  129.                    fog_green,
  130.                    fog_blue,
  131.                    0.0);
  132.         break;
  133.     case 3: //TEST
  134.         Fog_Update(max(0.0, atof(Cmd_Argv(1))),
  135.                    fog_red,
  136.                    fog_green,
  137.                    fog_blue,
  138.                    atof(Cmd_Argv(2)));
  139.         break;
  140.     case 4:
  141.         Fog_Update(fog_density,
  142.                    CLAMP(0.0, atof(Cmd_Argv(1)), 1.0),
  143.                    CLAMP(0.0, atof(Cmd_Argv(2)), 1.0),
  144.                    CLAMP(0.0, atof(Cmd_Argv(3)), 1.0),
  145.                    0.0);
  146.         break;
  147.     case 5:
  148.         Fog_Update(max(0.0, atof(Cmd_Argv(1))),
  149.                    CLAMP(0.0, atof(Cmd_Argv(2)), 1.0),
  150.                    CLAMP(0.0, atof(Cmd_Argv(3)), 1.0),
  151.                    CLAMP(0.0, atof(Cmd_Argv(4)), 1.0),
  152.                    0.0);
  153.         break;
  154.     case 6: //TEST
  155.         Fog_Update(max(0.0, atof(Cmd_Argv(1))),
  156.                    CLAMP(0.0, atof(Cmd_Argv(2)), 1.0),
  157.                    CLAMP(0.0, atof(Cmd_Argv(3)), 1.0),
  158.                    CLAMP(0.0, atof(Cmd_Argv(4)), 1.0),
  159.                    atof(Cmd_Argv(5)));
  160.         break;
  161.     }
  162. }
  163.  
  164. /*
  165. =============
  166. Fog_ParseWorldspawn
  167.  
  168. called at map load
  169. =============
  170. */
  171. void Fog_ParseWorldspawn (void)
  172. {
  173.     char key[128], value[4096];
  174.     char *data;
  175.  
  176.     //initially no fog
  177.     fog_density = 0.0;
  178.     old_density = 0.0;
  179.     fade_time = 0.0;
  180.     fade_done = 0.0;
  181.  
  182.     data = COM_Parse(cl.worldmodel->entities);
  183.     if (!data)
  184.         return; // error
  185.     if (com_token[0] != '{')
  186.         return; // error
  187.     while (1)
  188.     {
  189.         data = COM_Parse(data);
  190.         if (!data)
  191.             return; // error
  192.         if (com_token[0] == '}')
  193.             break; // end of worldspawn
  194.         if (com_token[0] == '_')
  195.             strcpy(key, com_token + 1);
  196.         else
  197.             strcpy(key, com_token);
  198.         while (key[strlen(key)-1] == ' ') // remove trailing spaces
  199.             key[strlen(key)-1] = 0;
  200.         data = COM_Parse(data);
  201.         if (!data)
  202.             return; // error
  203.         strcpy(value, com_token);
  204.  
  205.         if (!strcmp("fog", key))
  206.         {
  207.             sscanf(value, "%f %f %f %f", &fog_density, &fog_red, &fog_green, &fog_blue);
  208.         }
  209.     }
  210. }
  211.  
  212. /*
  213. =============
  214. Fog_GetColor
  215.  
  216. calculates fog color for this frame, taking into account fade times
  217. =============
  218. */
  219. float *Fog_GetColor (void)
  220. {
  221.     static float c[4];
  222.     float f;
  223.     int i;
  224.  
  225.     if (fade_done > cl.time)
  226.     {
  227.         f = (fade_done - cl.time) / fade_time;
  228.         c[0] = f * old_red + (1.0 - f) * fog_red;
  229.         c[1] = f * old_green + (1.0 - f) * fog_green;
  230.         c[2] = f * old_blue + (1.0 - f) * fog_blue;
  231.         c[3] = 1.0;
  232.     }
  233.     else
  234.     {
  235.         c[0] = fog_red;
  236.         c[1] = fog_green;
  237.         c[2] = fog_blue;
  238.         c[3] = 1.0;
  239.     }
  240.  
  241.     //find closest 24-bit RGB value, so solid-colored sky can match the fog perfectly
  242.     for (i=0;i<3;i++)
  243.         c[i] = (float)(Q_rint(c[i] * 255)) / 255.0f;
  244.  
  245.     return c;
  246. }
  247.  
  248. /*
  249. =============
  250. Fog_GetDensity
  251.  
  252. returns current density of fog
  253. =============
  254. */
  255. float Fog_GetDensity (void)
  256. {
  257.     float f;
  258.  
  259.     if (fade_done > cl.time)
  260.     {
  261.         f = (fade_done - cl.time) / fade_time;
  262.         return f * old_density + (1.0 - f) * fog_density;
  263.     }
  264.     else
  265.         return fog_density;
  266. }
  267.  
  268. /*
  269. =============
  270. Fog_SetupFrame
  271.  
  272. called at the beginning of each frame
  273. =============
  274. */
  275. void Fog_SetupFrame (void)
  276. {
  277.     glFogfv(GL_FOG_COLOR, Fog_GetColor());
  278.     glFogf(GL_FOG_DENSITY, Fog_GetDensity() / 64.0);
  279. }
  280.  
  281. /*
  282. =============
  283. Fog_EnableGFog
  284.  
  285. called before drawing stuff that should be fogged
  286. =============
  287. */
  288. void Fog_EnableGFog (void)
  289. {
  290.     if (Fog_GetDensity() > 0)
  291.         glEnable(GL_FOG);
  292. }
  293.  
  294. /*
  295. =============
  296. Fog_DisableGFog
  297.  
  298. called after drawing stuff that should be fogged
  299. =============
  300. */
  301. void Fog_DisableGFog (void)
  302. {
  303.     if (Fog_GetDensity() > 0)
  304.         glDisable(GL_FOG);
  305. }
  306.  
  307. /*
  308. =============
  309. Fog_StartAdditive
  310.  
  311. called before drawing stuff that is additive blended -- sets fog color to black
  312. =============
  313. */
  314. void Fog_StartAdditive (void)
  315. {
  316.     vec3_t color = {0,0,0};
  317.  
  318.     if (Fog_GetDensity() > 0)
  319.         glFogfv(GL_FOG_COLOR, color);
  320. }
  321.  
  322. /*
  323. =============
  324. Fog_StopAdditive
  325.  
  326. called after drawing stuff that is additive blended -- restores fog color
  327. =============
  328. */
  329. void Fog_StopAdditive (void)
  330. {
  331.     if (Fog_GetDensity() > 0)
  332.         glFogfv(GL_FOG_COLOR, Fog_GetColor());
  333. }
  334.  
  335. //==============================================================================
  336. //
  337. //  VOLUMETRIC FOG
  338. //
  339. //==============================================================================
  340.  
  341. cvar_t r_vfog = {"r_vfog", "1"};
  342.  
  343. void Fog_DrawVFog (void){}
  344. void Fog_MarkModels (void){}
  345.  
  346. //==============================================================================
  347. //
  348. //  INIT
  349. //
  350. //==============================================================================
  351.  
  352. /*
  353. =============
  354. Fog_NewMap
  355.  
  356. called whenever a map is loaded
  357. =============
  358. */
  359. void Fog_NewMap (void)
  360. {
  361.     Fog_ParseWorldspawn (); //for global fog
  362.     Fog_MarkModels (); //for volumetric fog
  363. }
  364.  
  365. /*
  366. =============
  367. Fog_Init
  368.  
  369. called when quake initializes
  370. =============
  371. */
  372. void Fog_Init (void)
  373. {
  374.     Cmd_AddCommand ("fog",Fog_FogCommand_f);
  375.  
  376.     //Cvar_RegisterVariable (&r_vfog, NULL);
  377.  
  378.     //set up global fog
  379.     fog_density = 0.0;
  380.     fog_red = 0.3;
  381.     fog_green = 0.3;
  382.     fog_blue = 0.3;
  383.  
  384.     glFogi(GL_FOG_MODE, GL_EXP2);
  385. }
Add Comment
Please, Sign In to add comment