1 /*
2 ===========================================================================
3
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6
7 This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
8
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
21
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
23
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25
26 ===========================================================================
27 */
28
29 #include "sys/platform.h"
30 #include "renderer/GuiModel.h"
31 #include "ui/UserInterface.h"
32
33 #include "renderer/tr_local.h"
34
35 /*
36 ==========================================================================================
37
38 GUI SHADERS
39
40 ==========================================================================================
41 */
42
43 /*
44 ================
45 R_SurfaceToTextureAxis
46
47 Calculates two axis for the surface sutch that a point dotted against
48 the axis will give a 0.0 to 1.0 range in S and T when inside the gui surface
49 ================
50 */
R_SurfaceToTextureAxis(const srfTriangles_t * tri,idVec3 & origin,idVec3 axis[3])51 void R_SurfaceToTextureAxis( const srfTriangles_t *tri, idVec3 &origin, idVec3 axis[3] ) {
52 float area, inva;
53 float d0[5], d1[5];
54 idDrawVert *a, *b, *c;
55 float bounds[2][2];
56 float boundsOrg[2];
57 int i, j;
58 float v;
59
60 // find the bounds of the texture
61 bounds[0][0] = bounds[0][1] = 999999;
62 bounds[1][0] = bounds[1][1] = -999999;
63 for ( i = 0 ; i < tri->numVerts ; i++ ) {
64 for ( j = 0 ; j < 2 ; j++ ) {
65 v = tri->verts[i].st[j];
66 if ( v < bounds[0][j] ) {
67 bounds[0][j] = v;
68 }
69 if ( v > bounds[1][j] ) {
70 bounds[1][j] = v;
71 }
72 }
73 }
74
75 // use the floor of the midpoint as the origin of the
76 // surface, which will prevent a slight misalignment
77 // from throwing it an entire cycle off
78 boundsOrg[0] = floor( ( bounds[0][0] + bounds[1][0] ) * 0.5 );
79 boundsOrg[1] = floor( ( bounds[0][1] + bounds[1][1] ) * 0.5 );
80
81
82 // determine the world S and T vectors from the first drawSurf triangle
83 a = tri->verts + tri->indexes[0];
84 b = tri->verts + tri->indexes[1];
85 c = tri->verts + tri->indexes[2];
86
87 VectorSubtract( b->xyz, a->xyz, d0 );
88 d0[3] = b->st[0] - a->st[0];
89 d0[4] = b->st[1] - a->st[1];
90 VectorSubtract( c->xyz, a->xyz, d1 );
91 d1[3] = c->st[0] - a->st[0];
92 d1[4] = c->st[1] - a->st[1];
93
94 area = d0[3] * d1[4] - d0[4] * d1[3];
95 if ( area == 0.0 ) {
96 origin.Zero();
97 axis[0].Zero();
98 axis[1].Zero();
99 axis[2].Zero();
100 return; // degenerate
101 }
102 inva = 1.0 / area;
103
104 axis[0][0] = (d0[0] * d1[4] - d0[4] * d1[0]) * inva;
105 axis[0][1] = (d0[1] * d1[4] - d0[4] * d1[1]) * inva;
106 axis[0][2] = (d0[2] * d1[4] - d0[4] * d1[2]) * inva;
107
108 axis[1][0] = (d0[3] * d1[0] - d0[0] * d1[3]) * inva;
109 axis[1][1] = (d0[3] * d1[1] - d0[1] * d1[3]) * inva;
110 axis[1][2] = (d0[3] * d1[2] - d0[2] * d1[3]) * inva;
111
112 idPlane plane;
113 plane.FromPoints( a->xyz, b->xyz, c->xyz );
114 axis[2][0] = plane[0];
115 axis[2][1] = plane[1];
116 axis[2][2] = plane[2];
117
118 // take point 0 and project the vectors to the texture origin
119 VectorMA( a->xyz, boundsOrg[0] - a->st[0], axis[0], origin );
120 VectorMA( origin, boundsOrg[1] - a->st[1], axis[1], origin );
121 }
122
123 /*
124 =================
125 R_RenderGuiSurf
126
127 Create a texture space on the given surface and
128 call the GUI generator to create quads for it.
129 =================
130 */
R_RenderGuiSurf(idUserInterface * gui,drawSurf_t * drawSurf)131 void R_RenderGuiSurf( idUserInterface *gui, drawSurf_t *drawSurf ) {
132 idVec3 origin, axis[3];
133
134 // for testing the performance hit
135 if ( r_skipGuiShaders.GetInteger() == 1 ) {
136 return;
137 }
138
139 // don't allow an infinite recursion loop
140 if ( tr.guiRecursionLevel == 4 ) {
141 return;
142 }
143
144 tr.pc.c_guiSurfs++;
145
146 // create the new matrix to draw on this surface
147 R_SurfaceToTextureAxis( drawSurf->geo, origin, axis );
148
149 float guiModelMatrix[16];
150 float modelMatrix[16];
151
152 guiModelMatrix[0] = axis[0][0] / 640.0;
153 guiModelMatrix[4] = axis[1][0] / 480.0;
154 guiModelMatrix[8] = axis[2][0];
155 guiModelMatrix[12] = origin[0];
156
157 guiModelMatrix[1] = axis[0][1] / 640.0;
158 guiModelMatrix[5] = axis[1][1] / 480.0;
159 guiModelMatrix[9] = axis[2][1];
160 guiModelMatrix[13] = origin[1];
161
162 guiModelMatrix[2] = axis[0][2] / 640.0;
163 guiModelMatrix[6] = axis[1][2] / 480.0;
164 guiModelMatrix[10] = axis[2][2];
165 guiModelMatrix[14] = origin[2];
166
167 guiModelMatrix[3] = 0;
168 guiModelMatrix[7] = 0;
169 guiModelMatrix[11] = 0;
170 guiModelMatrix[15] = 1;
171
172 myGlMultMatrix( guiModelMatrix, drawSurf->space->modelMatrix,
173 modelMatrix );
174
175 tr.guiRecursionLevel++;
176
177 // call the gui, which will call the 2D drawing functions
178 tr.guiModel->Clear();
179 gui->Redraw( tr.viewDef->renderView.time );
180 tr.guiModel->EmitToCurrentView( modelMatrix, drawSurf->space->weaponDepthHack );
181 tr.guiModel->Clear();
182
183 tr.guiRecursionLevel--;
184 }
185
186
187
188
189 /*
190 ================,
191 R_ReloadGuis_f
192
193 Reloads any guis that have had their file timestamps changed.
194 An optional "all" parameter will cause all models to reload, even
195 if they are not out of date.
196
197 Should we also reload the map models?
198 ================
199 */
R_ReloadGuis_f(const idCmdArgs & args)200 void R_ReloadGuis_f( const idCmdArgs &args ) {
201 bool all;
202
203 if ( !idStr::Icmp( args.Argv(1), "all" ) ) {
204 all = true;
205 common->Printf( "Reloading all gui files...\n" );
206 } else {
207 all = false;
208 common->Printf( "Checking for changed gui files...\n" );
209 }
210
211 uiManager->Reload( all );
212 }
213
214 /*
215 ================,
216 R_ListGuis_f
217
218 ================
219 */
R_ListGuis_f(const idCmdArgs & args)220 void R_ListGuis_f( const idCmdArgs &args ) {
221 uiManager->ListGuis();
222 }
223