1 /*
2 * Rasterizer_Shader.cpp
3 * Created by Clemens Unterkofler on 1/20/09.
4 * for Aleph One
5 *
6 * http://www.gnu.org/licenses/gpl.html
7 */
8
9 #include "OGL_Headers.h"
10
11 #include <iostream>
12
13 #include "Rasterizer_Shader.h"
14
15 #include "lightsource.h"
16 #include "media.h"
17 #include "player.h"
18 #include "weapons.h"
19 #include "AnimatedTextures.h"
20 #include "OGL_Faders.h"
21 #include "OGL_FBO.h"
22 #include "OGL_Textures.h"
23 #include "OGL_Shader.h"
24 #include "ChaseCam.h"
25 #include "preferences.h"
26 #include "fades.h"
27 #include "screen.h"
28
29 #define MAXIMUM_VERTICES_PER_WORLD_POLYGON (MAXIMUM_VERTICES_PER_POLYGON+4)
30
31 const float FixedAngleToDegrees = 360.0/(float(FIXED_ONE)*float(FULL_CIRCLE));
32
33 const GLdouble kViewBaseMatrix[16] = {
34 0, 0, -1, 0,
35 1, 0, 0, 0,
36 0, 1, 0, 0,
37 0, 0, 0, 1
38 };
39
40 const GLdouble kViewBaseMatrixInverse[16] = {
41 0, 1, 0, 0,
42 0, 0, 1, 0,
43 -1, 0, 0, 0,
44 0, 0, 0, 1
45 };
46
47 Rasterizer_Shader_Class::Rasterizer_Shader_Class() = default;
48 Rasterizer_Shader_Class::~Rasterizer_Shader_Class() = default;
49
SetView(view_data & view)50 void Rasterizer_Shader_Class::SetView(view_data& view) {
51 OGL_SetView(view);
52
53 if (view.screen_width != view_width || view.screen_height != view_height) {
54 view_width = view.screen_width;
55 view_height = view.screen_height;
56 swapper.reset();
57 swapper.reset(new FBOSwapper(view_width * MainScreenPixelScale(), view_height * MainScreenPixelScale(), false));
58 }
59
60 float aspect = view.screen_width / float(view.screen_height);
61 float deg2rad = 8.0 * atan(1.0) / 360.0;
62 float xtan, ytan;
63 if (View_FOV_FixHorizontalNotVertical()) {
64 xtan = tan(view.field_of_view * deg2rad / 2.0);
65 ytan = xtan / aspect;
66 } else {
67 ytan = tan(view.field_of_view * deg2rad / 2.0) / 2.0;
68 xtan = ytan * aspect;
69 }
70
71 // Adjust for view distortion during teleport effect
72 ytan *= view.real_world_to_screen_y / double(view.world_to_screen_y);
73 xtan *= view.real_world_to_screen_x / double(view.world_to_screen_x);
74
75 double yaw = view.virtual_yaw * FixedAngleToDegrees;
76 double pitch = view.virtual_pitch * FixedAngleToDegrees;
77 pitch = (pitch > 180.0 ? pitch - 360.0 : pitch);
78
79 glMatrixMode(GL_PROJECTION);
80 glLoadIdentity();
81 float nearVal = 64.0;
82 float farVal = 128.0 * 1024.0;
83 float x = xtan * nearVal;
84 float y = ytan * nearVal;
85 float yoff = 0.0;
86 if (view.mimic_sw_perspective)
87 yoff = y * tan(pitch * M_PI/360.0) * 4.8;
88 glFrustum(-x, x, -y + yoff, y + yoff, nearVal, farVal);
89
90 glMatrixMode(GL_MODELVIEW);
91
92 // setup a rotation matrix for the landscape texture shader
93 // this aligns the landscapes to the center of the screen for standard
94 // pitch ranges, so that they don't need to be stretched
95
96 glLoadIdentity();
97 glTranslated(view.origin.x, view.origin.y, view.origin.z);
98 glRotated(yaw, 0.0, 0.0, 1.0);
99 glRotated(-pitch, 0.0, 1.0, 0.0);
100 glMultMatrixd(kViewBaseMatrixInverse);
101
102 GLfloat landscapeInverseMatrix[16];
103 glGetFloatv(GL_MODELVIEW_MATRIX, landscapeInverseMatrix);
104
105 Shader *s;
106
107 s = Shader::get(Shader::S_Landscape);
108 s->enable();
109 s->setMatrix4(Shader::U_LandscapeInverseMatrix, landscapeInverseMatrix);
110
111 s = Shader::get(Shader::S_LandscapeBloom);
112 s->enable();
113 s->setMatrix4(Shader::U_LandscapeInverseMatrix, landscapeInverseMatrix);
114
115 Shader::disable();
116
117 // setup the normal view matrix
118
119 glLoadMatrixd(kViewBaseMatrix);
120 if (!view.mimic_sw_perspective)
121 glRotated(pitch, 0.0, 1.0, 0.0);
122 // apperently 'roll' is not what i think it is
123 // rubicon sets it to some strange value
124 // double roll = view.roll * 360.0 / float(NUMBER_OF_ANGLES);
125 // glRotated(roll, 1.0, 0.0, 0.0);
126 glRotated(-yaw, 0.0, 0.0, 1.0);
127 glTranslated(-view.origin.x, -view.origin.y, -view.origin.z);
128 }
129
setupGL()130 void Rasterizer_Shader_Class::setupGL()
131 {
132 view_width = 0;
133 view_height = 0;
134 swapper.reset();
135
136 smear_the_void = false;
137 OGL_ConfigureData& ConfigureData = Get_OGL_ConfigureData();
138 if (!TEST_FLAG(ConfigureData.Flags,OGL_Flag_VoidColor))
139 smear_the_void = true;
140 }
141
Begin()142 void Rasterizer_Shader_Class::Begin()
143 {
144 Rasterizer_OGL_Class::Begin();
145 swapper->activate();
146 if (smear_the_void)
147 swapper->current_contents().draw_full();
148 }
149
End()150 void Rasterizer_Shader_Class::End()
151 {
152 swapper->deactivate();
153 swapper->swap();
154
155 float gamma_adj = get_actual_gamma_adjust(graphics_preferences->screen_mode.gamma_level);
156 if (gamma_adj < 0.99f || gamma_adj > 1.01f) {
157 Shader *s = Shader::get(Shader::S_Gamma);
158 s->enable();
159 s->setFloat(Shader::U_GammaAdjust, gamma_adj);
160 }
161 swapper->draw();
162 Shader::disable();
163
164 SetForeground();
165 glColor3f(0, 0, 0);
166 OGL_RenderFrame(0, 0, view_width, view_height, 1);
167
168 Rasterizer_OGL_Class::End();
169 }
170
171