1 /*
2  * Copyright 2011-2012 Arx Libertatis Team (see the AUTHORS file)
3  *
4  * This file is part of Arx Libertatis.
5  *
6  * Arx Libertatis is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Arx Libertatis is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Arx Libertatis.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 /* Based on:
20 ===========================================================================
21 ARX FATALIS GPL Source Code
22 Copyright (C) 1999-2010 Arkane Studios SA, a ZeniMax Media company.
23 
24 This file is part of the Arx Fatalis GPL Source Code ('Arx Fatalis Source Code').
25 
26 Arx Fatalis Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
27 License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
28 
29 Arx Fatalis Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
30 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
31 
32 You should have received a copy of the GNU General Public License along with Arx Fatalis Source Code.  If not, see
33 <http://www.gnu.org/licenses/>.
34 
35 In addition, the Arx Fatalis Source Code is also subject to certain additional terms. You should have received a copy of these
36 additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Arx
37 Fatalis Source Code. If not, please request a copy in writing from Arkane Studios at the address below.
38 
39 If you have questions concerning this license or the applicable additional terms, you may contact in writing Arkane Studios, c/o
40 ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
41 ===========================================================================
42 */
43 
44 #include "graphics/GraphicsModes.h"
45 
46 #include <cstring>
47 #include <algorithm>
48 
49 #include "core/Application.h"
50 #include "core/Config.h"
51 #include "core/Core.h"
52 #include "graphics/BaseGraphicsTypes.h"
53 #include "graphics/Renderer.h"
54 #include "graphics/data/Mesh.h"
55 
56 using std::min;
57 
58 GLOBAL_MODS current;
59 GLOBAL_MODS desired;
60 GLOBAL_MODS stacked;
61 
62 // change the clipping Z max & min
63 #define DEFAULT_ZCLIP		6400.f
64 #define DEFAULT_MINZCLIP	1200.f
65 
66 Color ulBKGColor = Color::none;
67 
ARX_GLOBALMODS_Reset()68 void ARX_GLOBALMODS_Reset() {
69 	memset(&desired, 0, sizeof(GLOBAL_MODS));
70 	memset(&current, 0, sizeof(GLOBAL_MODS));
71 	current.zclip = DEFAULT_ZCLIP;
72 	memset(&stacked, 0, sizeof(GLOBAL_MODS));
73 	stacked.zclip = DEFAULT_ZCLIP;
74 	desired.zclip = DEFAULT_ZCLIP;
75 	desired.depthcolor = Color3f::black;
76 }
77 
Approach(float current,float desired,float increment)78 float Approach(float current, float desired, float increment)
79 {
80 	if (desired > current)
81 	{
82 		current += increment;
83 
84 		if (desired < current)
85 			current = desired;
86 	}
87 	else if (desired < current)
88 	{
89 		current -= increment;
90 
91 		if (desired > current)
92 			current = desired;
93 	}
94 
95 	return current;
96 }
97 
ARX_GLOBALMODS_Stack()98 void ARX_GLOBALMODS_Stack() {
99 	memcpy(&stacked, &desired, sizeof(GLOBAL_MODS));
100 	desired.depthcolor = Color3f::black;
101 	desired.zclip = DEFAULT_ZCLIP;
102 }
ARX_GLOBALMODS_UnStack()103 void ARX_GLOBALMODS_UnStack()
104 {
105 	memcpy(&desired, &stacked, sizeof(GLOBAL_MODS));
106 }
107 
ARX_GLOBALMODS_Apply()108 void ARX_GLOBALMODS_Apply()
109 {
110 	if (EDITMODE) return;
111 
112 	float baseinc = framedelay;
113 	float incdiv1000 = framedelay * ( 1.0f / 1000 );
114 
115 	if (desired.flags & GMOD_ZCLIP)
116 	{
117 		current.zclip = Approach(current.zclip, desired.zclip, baseinc * 2);
118 	}
119 	else // return to default...
120 	{
121 		desired.zclip = current.zclip = Approach(current.zclip, DEFAULT_ZCLIP, baseinc * 2);
122 	}
123 
124 	// Now goes for RGB mods
125 	if (desired.flags & GMOD_DCOLOR)
126 	{
127 		current.depthcolor.r = Approach(current.depthcolor.r, desired.depthcolor.r, incdiv1000);
128 		current.depthcolor.g = Approach(current.depthcolor.g, desired.depthcolor.g, incdiv1000);
129 		current.depthcolor.b = Approach(current.depthcolor.b, desired.depthcolor.b, incdiv1000);
130 	}
131 	else
132 	{
133 		current.depthcolor.r = Approach(current.depthcolor.r, 0, incdiv1000);
134 		current.depthcolor.g = Approach(current.depthcolor.g, 0, incdiv1000);
135 		current.depthcolor.b = Approach(current.depthcolor.b, 0, incdiv1000);
136 	}
137 
138 	ModeLight &= ~MODE_DEPTHCUEING;
139 
140 	float fZclipp = ((((float)config.video.fogDistance) * 1.2f) * (DEFAULT_ZCLIP - DEFAULT_MINZCLIP) / 10.f) + DEFAULT_MINZCLIP;
141 	fZclipp += (ACTIVECAM->focal - 310.f) * 5.f;
142 	SetCameraDepth(min(current.zclip, fZclipp));
143 
144 	ulBKGColor = current.depthcolor.to<u8>();
145 	GRenderer->SetFogColor(ulBKGColor);
146 
147 	float fogEnd = fZFogEnd;
148 	float fogStart = fZFogStart;
149 
150 	if(GRenderer->isFogInEyeCoordinates()) {
151 		fogEnd *= ACTIVECAM->cdepth;
152 		fogStart *= ACTIVECAM->cdepth;
153 	}
154 
155 	GRenderer->SetFogParams(Renderer::FogLinear, fogStart, fogEnd);
156 }
157