]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/renderer/tr_guisurf.cpp
Use the same OpenAL headers on all platforms.
[icculus/iodoom3.git] / neo / renderer / tr_guisurf.cpp
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 #include "../idlib/precompiled.h"
29 #pragma hdrstop
30
31 #include "tr_local.h"
32
33 /*
34 ==========================================================================================
35
36 GUI SHADERS
37
38 ==========================================================================================
39 */
40
41 /*
42 ================
43 R_SurfaceToTextureAxis
44
45 Calculates two axis for the surface sutch that a point dotted against
46 the axis will give a 0.0 to 1.0 range in S and T when inside the gui surface
47 ================
48 */
49 void R_SurfaceToTextureAxis( const srfTriangles_t *tri, idVec3 &origin, idVec3 axis[3] ) {
50         float           area, inva;
51         float           d0[5], d1[5];
52         idDrawVert      *a, *b, *c;
53         float           bounds[2][2];
54         float           boundsOrg[2];
55         int                     i, j;
56         float           v;
57         
58         // find the bounds of the texture
59         bounds[0][0] = bounds[0][1] = 999999;
60         bounds[1][0] = bounds[1][1] = -999999;
61         for ( i = 0 ; i < tri->numVerts ; i++ ) {
62                 for ( j = 0 ; j < 2 ; j++ ) {
63                         v = tri->verts[i].st[j];
64                         if ( v < bounds[0][j] ) {
65                                 bounds[0][j] = v;
66                         }
67                         if ( v > bounds[1][j] ) {
68                                 bounds[1][j] = v;
69                         }
70                 }
71         }
72
73         // use the floor of the midpoint as the origin of the
74         // surface, which will prevent a slight misalignment
75         // from throwing it an entire cycle off
76         boundsOrg[0] = floor( ( bounds[0][0] + bounds[1][0] ) * 0.5 );
77         boundsOrg[1] = floor( ( bounds[0][1] + bounds[1][1] ) * 0.5 );
78
79
80         // determine the world S and T vectors from the first drawSurf triangle
81         a = tri->verts + tri->indexes[0];
82         b = tri->verts + tri->indexes[1];
83         c = tri->verts + tri->indexes[2];
84
85         VectorSubtract( b->xyz, a->xyz, d0 );
86         d0[3] = b->st[0] - a->st[0];
87         d0[4] = b->st[1] - a->st[1];
88         VectorSubtract( c->xyz, a->xyz, d1 );
89         d1[3] = c->st[0] - a->st[0];
90         d1[4] = c->st[1] - a->st[1];
91
92         area = d0[3] * d1[4] - d0[4] * d1[3];
93         if ( area == 0.0 ) {
94                 axis[0].Zero();
95                 axis[1].Zero();
96                 axis[2].Zero();
97                 return; // degenerate
98         }
99         inva = 1.0 / area;
100
101     axis[0][0] = (d0[0] * d1[4] - d0[4] * d1[0]) * inva;
102     axis[0][1] = (d0[1] * d1[4] - d0[4] * d1[1]) * inva;
103     axis[0][2] = (d0[2] * d1[4] - d0[4] * d1[2]) * inva;
104     
105     axis[1][0] = (d0[3] * d1[0] - d0[0] * d1[3]) * inva;
106     axis[1][1] = (d0[3] * d1[1] - d0[1] * d1[3]) * inva;
107     axis[1][2] = (d0[3] * d1[2] - d0[2] * d1[3]) * inva;
108
109         idPlane plane;
110         plane.FromPoints( a->xyz, b->xyz, c->xyz );
111         axis[2][0] = plane[0];
112         axis[2][1] = plane[1];
113         axis[2][2] = plane[2];
114
115         // take point 0 and project the vectors to the texture origin
116         VectorMA( a->xyz, boundsOrg[0] - a->st[0], axis[0], origin );
117         VectorMA( origin, boundsOrg[1] - a->st[1], axis[1], origin );
118 }
119
120 /*
121 =================
122 R_RenderGuiSurf
123
124 Create a texture space on the given surface and
125 call the GUI generator to create quads for it.
126 =================
127 */
128 void R_RenderGuiSurf( idUserInterface *gui, drawSurf_t *drawSurf ) {
129         idVec3  origin, axis[3];
130
131         // for testing the performance hit
132         if ( r_skipGuiShaders.GetInteger() == 1 ) {
133                 return;
134         }
135
136         // don't allow an infinite recursion loop
137         if ( tr.guiRecursionLevel == 4 ) {
138                 return;
139         }
140
141         tr.pc.c_guiSurfs++;
142
143         // create the new matrix to draw on this surface
144         R_SurfaceToTextureAxis( drawSurf->geo, origin, axis );
145
146         float   guiModelMatrix[16];
147         float   modelMatrix[16];
148
149         guiModelMatrix[0] = axis[0][0] / 640.0;
150         guiModelMatrix[4] = axis[1][0] / 480.0;
151         guiModelMatrix[8] = axis[2][0];
152         guiModelMatrix[12] = origin[0];
153
154         guiModelMatrix[1] = axis[0][1] / 640.0;
155         guiModelMatrix[5] = axis[1][1] / 480.0;
156         guiModelMatrix[9] = axis[2][1];
157         guiModelMatrix[13] = origin[1];
158
159         guiModelMatrix[2] = axis[0][2] / 640.0;
160         guiModelMatrix[6] = axis[1][2] / 480.0;
161         guiModelMatrix[10] = axis[2][2];
162         guiModelMatrix[14] = origin[2];
163
164         guiModelMatrix[3] = 0;
165         guiModelMatrix[7] = 0;
166         guiModelMatrix[11] = 0;
167         guiModelMatrix[15] = 1;
168
169         myGlMultMatrix( guiModelMatrix, drawSurf->space->modelMatrix, 
170                         modelMatrix );
171
172         tr.guiRecursionLevel++;
173
174         // call the gui, which will call the 2D drawing functions
175         tr.guiModel->Clear();
176         gui->Redraw( tr.viewDef->renderView.time );
177         tr.guiModel->EmitToCurrentView( modelMatrix, drawSurf->space->weaponDepthHack );
178         tr.guiModel->Clear();
179
180         tr.guiRecursionLevel--;
181 }
182
183
184
185
186 /*
187 ================,
188 R_ReloadGuis_f
189
190 Reloads any guis that have had their file timestamps changed.
191 An optional "all" parameter will cause all models to reload, even
192 if they are not out of date.
193
194 Should we also reload the map models?
195 ================
196 */
197 void R_ReloadGuis_f( const idCmdArgs &args ) {
198         bool all;
199
200         if ( !idStr::Icmp( args.Argv(1), "all" ) ) {
201                 all = true;
202                 common->Printf( "Reloading all gui files...\n" );
203         } else {
204                 all = false;
205                 common->Printf( "Checking for changed gui files...\n" );
206         }
207
208         uiManager->Reload( all );
209 }
210
211 /*
212 ================,
213 R_ListGuis_f
214
215 ================
216 */
217 void R_ListGuis_f( const idCmdArgs &args ) {
218         uiManager->ListGuis();
219 }