]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - radiant/z.cpp
Merge pull request #27 from freemancw/master
[xonotic/netradiant.git] / radiant / z.cpp
1 /*
2    Copyright (C) 1999-2007 id Software, Inc. and contributors.
3    For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5    This file is part of GtkRadiant.
6
7    GtkRadiant is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    GtkRadiant is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GtkRadiant; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21
22 #include "stdafx.h"
23 //#include "qe3.h"
24
25 #define PAGEFLIPS   2
26
27 z_t z;
28
29 /*
30    ============
31    Z_Init
32    ============
33  */
34 void Z_Init( void ){
35         z.origin[0] = 0;
36         z.origin[1] = 20;
37         z.origin[2] = 46;
38
39         z.scale = 1;
40 }
41
42
43
44 /*
45    ============================================================================
46
47    MOUSE ACTIONS
48
49    ============================================================================
50  */
51
52 static int cursorx, cursory;
53
54 /*
55    ==============
56    Z_MouseDown
57    ==============
58  */
59 void Z_MouseDown( int x, int y, int buttons ){
60         vec3_t org, dir, vup, vright;
61         brush_t *b;
62
63         Sys_GetCursorPos( &cursorx, &cursory );
64
65         vup[0] = 0; vup[1] = 0; vup[2] = 1 / z.scale;
66
67         VectorCopy( z.origin, org );
68         org[2] += ( y - ( z.height / 2 ) ) / z.scale;
69         org[1] = g_MinWorldCoord;
70
71         b = selected_brushes.next;
72         if ( b != &selected_brushes ) {
73                 org[0] = ( b->mins[0] + b->maxs[0] ) / 2;
74         }
75
76         dir[0] = 0; dir[1] = 1; dir[2] = 0;
77
78         vright[0] = 0; vright[1] = 0; vright[2] = 0;
79
80         // LBUTTON = manipulate selection
81         // shift-LBUTTON = select
82         // middle button = grab texture
83         // ctrl-middle button = set entire brush to texture
84         // ctrl-shift-middle button = set single face to texture
85
86         int nMouseButton = g_PrefsDlg.m_nMouseButtons == 2 ? MK_RBUTTON : MK_MBUTTON;
87         if ( ( buttons == MK_LBUTTON )
88                  || ( buttons == ( MK_LBUTTON | MK_SHIFT ) )
89                  || ( buttons == MK_MBUTTON )
90 //              || (buttons == (MK_MBUTTON|MK_CONTROL))
91                  || ( buttons == ( nMouseButton | MK_SHIFT | MK_CONTROL ) ) ) {
92                 Drag_Begin( x, y, buttons,
93                                         vright, vup,
94                                         org, dir );
95                 return;
96         }
97
98         // control mbutton = move camera
99         if ( ( buttons == ( MK_CONTROL | nMouseButton ) ) || ( buttons == ( MK_CONTROL | MK_LBUTTON ) ) ) {
100                 g_pParentWnd->GetCamWnd()->Camera()->origin[2] = org[2] ;
101                 Sys_UpdateWindows( W_CAMERA | W_XY_OVERLAY | W_Z );
102         }
103
104
105 }
106
107 /*
108    ==============
109    Z_MouseUp
110    ==============
111  */
112 void Z_MouseUp( int x, int y, int buttons ){
113         Drag_MouseUp();
114 }
115
116 /*
117    ==============
118    Z_MouseMoved
119    ==============
120  */
121 void Z_MouseMoved( int x, int y, int buttons ){
122         if ( !buttons ) {
123                 return;
124         }
125         if ( buttons == MK_LBUTTON ) {
126                 Drag_MouseMoved( x, y, buttons );
127                 Sys_UpdateWindows( W_Z | W_CAMERA_IFON | W_XY );
128                 return;
129         }
130         // rbutton = drag z origin
131         if ( buttons == MK_RBUTTON ) {
132                 Sys_GetCursorPos( &x, &y );
133                 if ( y != cursory ) {
134                         z.origin[2] += y - cursory;
135                         Sys_SetCursorPos( cursorx, cursory );
136                         Sys_UpdateWindows( W_Z );
137                 }
138                 return;
139         }
140         // control mbutton = move camera
141         int nMouseButton = g_PrefsDlg.m_nMouseButtons == 2 ? MK_RBUTTON : MK_MBUTTON;
142         if ( ( buttons == ( MK_CONTROL | nMouseButton ) ) || ( buttons == ( MK_CONTROL | MK_LBUTTON ) ) ) {
143                 g_pParentWnd->GetCamWnd()->Camera()->origin[2] = ( y - ( z.height / 2 ) ) / z.scale;
144                 Sys_UpdateWindows( W_CAMERA | W_XY_OVERLAY | W_Z );
145         }
146
147 }
148
149
150 /*
151    ============================================================================
152
153    DRAWING
154
155    ============================================================================
156  */
157
158
159 /*
160    ==============
161    Z_DrawGrid
162    ==============
163  */
164 void Z_DrawGrid( void ){
165         float zz, zb, ze;
166         float w, h;
167         char text[32];
168
169         w = ( z.width / 2 / z.scale );
170         h = ( z.height / 2 / z.scale );
171
172         zb = z.origin[2] - h;
173         if ( zb < region_mins[2] ) {
174                 zb = region_mins[2];
175         }
176         zb = 64 * floor( zb / 64 );
177
178         ze = z.origin[2] + h;
179         if ( ze > region_maxs[2] ) {
180                 ze = region_maxs[2];
181         }
182         ze = 64 * ceil( ze / 64 );
183
184         // draw major blocks
185
186         qglColor3fv( g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR] );
187
188         if ( g_qeglobals.d_showgrid ) {
189                 if ( g_qeglobals.d_gridsize < 128 ) {
190                         qglBegin( GL_LINES );
191
192                         qglVertex2f( 0, zb );
193                         qglVertex2f( 0, ze );
194
195                         for ( zz = zb ; zz < ze ; zz += 64 )
196                         {
197                                 qglVertex2f( -w, zz );
198                                 qglVertex2f( w, zz );
199                         }
200
201                         qglEnd();
202                 }
203                 else
204                 {
205                         qglBegin( GL_LINES );
206
207                         qglVertex2f( 0, zb );
208                         qglVertex2f( 0, ze );
209
210                         for ( zz = zb ; zz < ze ; zz += 64 )
211                         {
212                                 // d_gridsize >= 128 .. it's an int for sure
213                                 if ( ( (int)zz & ( (int)g_qeglobals.d_gridsize - 1 ) ) != 0 ) {
214                                         continue;
215                                 }
216
217                                 qglVertex2f( -w, zz );
218                                 qglVertex2f( w, zz );
219                         }
220
221                         qglEnd();
222                 }
223         }
224
225         // draw minor blocks
226         if ( g_qeglobals.d_showgrid && g_qeglobals.d_gridsize * z.scale >= 4 &&
227                  g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR] != g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK] ) {
228                 qglColor3fv( g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR] );
229
230                 qglBegin( GL_LINES );
231                 for ( zz = zb ; zz < ze ; zz += g_qeglobals.d_gridsize )
232                 {
233                         if ( !( (int)zz & 63 ) ) {
234                                 continue;
235                         }
236                         qglVertex2f( -w, zz );
237                         qglVertex2f( w, zz );
238                 }
239                 qglEnd();
240         }
241
242         // draw coordinate text if needed
243
244         if ( g_qeglobals.d_savedinfo.show_coordinates ) {
245                 qglColor3fv( g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT] );
246
247                 int step = (int)( g_qeglobals.d_gridsize > 64 ? g_qeglobals.d_gridsize : 64 );
248                 zb = z.origin[2] - h;
249                 if ( zb < region_mins[2] ) {
250                         zb = region_mins[2];
251                 }
252                 zb = step * floor( zb / step );
253
254                 for ( zz = zb ; zz < ze ; zz += step )
255                 {
256                         qglRasterPos2f( -w + ( 1 / z.scale ), zz );
257                         sprintf( text, "%i",(int)zz );
258                         gtk_glwidget_print_string( text );
259                 }
260         }
261 }
262
263 void ZDrawCameraIcon( void ){
264         float x, y;
265         float xCam = z.width / 4 / z.scale, gizmo = 8 / z.scale, height = 48 / z.scale;
266
267         x = 0;
268         y = g_pParentWnd->GetCamWnd()->Camera()->origin[2];
269
270         qglColor3f( 0.0, 0.0, 1.0 );
271         qglBegin( GL_LINE_STRIP );
272         qglVertex3f( x - xCam,y,0 );
273         qglVertex3f( x,y + gizmo,0 );
274         qglVertex3f( x + xCam,y,0 );
275         qglVertex3f( x,y - gizmo,0 );
276         qglVertex3f( x - xCam,y,0 );
277         qglVertex3f( x + xCam,y,0 );
278         qglVertex3f( x + xCam,y - height,0 );
279         qglVertex3f( x - xCam,y - height,0 );
280         qglVertex3f( x - xCam,y,0 );
281         qglEnd();
282
283 }
284
285 GLbitfield glbitClear = GL_COLOR_BUFFER_BIT; //HACK
286
287 /*
288    ==============
289    Z_Draw
290    ==============
291  */
292 void Z_Draw( void ){
293 #ifdef DBG_WINDOWPOS
294         CheckWatchit( "Z_Draw" );
295 #endif
296         brush_t   *brush;
297         float w, h;
298         double start, end;
299         qtexture_t  *q;
300         float top, bottom;
301         vec3_t org_top, org_bottom, dir_up, dir_down;
302         int xCam = z.width / 3;
303
304         if ( !active_brushes.next ) {
305                 return; // not valid yet
306
307         }
308         if ( z.timing ) {
309                 start = Sys_DoubleTime();
310         }
311
312         //
313         // clear
314         //
315         qglViewport( 0, 0, z.width, z.height );
316
317         qglClearColor(
318                 g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][0],
319                 g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][1],
320                 g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][2],
321                 0 );
322
323         /* GL Bug */
324         /* When not using hw acceleration, gl will fault if we clear the depth
325            buffer bit on the first pass. The hack fix is to set the GL_DEPTH_BUFFER_BIT
326            only after Z_Draw() has been called once. Yeah, right. */
327         qglClear( glbitClear );
328         glbitClear |= GL_DEPTH_BUFFER_BIT;
329         qglMatrixMode( GL_PROJECTION );
330
331         qglLoadIdentity();
332         w = z.width / 2 / z.scale;
333         h = z.height / 2 / z.scale;
334         qglOrtho( -w, w, z.origin[2] - h, z.origin[2] + h, -8, 8 );
335
336         qglDisable( GL_TEXTURE_2D );
337         qglDisable( GL_TEXTURE_1D );
338         qglDisable( GL_DEPTH_TEST );
339         qglDisable( GL_BLEND );
340
341
342         //
343         // now draw the grid
344         //
345         Z_DrawGrid();
346
347         //
348         // draw stuff
349         //
350
351         qglDisable( GL_CULL_FACE );
352
353         qglShadeModel( GL_FLAT );
354
355         qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
356
357         qglDisable( GL_TEXTURE_2D );
358         qglDisable( GL_BLEND );
359         qglDisable( GL_DEPTH_TEST );
360
361
362         // draw filled interiors and edges
363         dir_up[0] = 0 ; dir_up[1] = 0; dir_up[2] = 1;
364         dir_down[0] = 0 ; dir_down[1] = 0; dir_down[2] = -1;
365         VectorCopy( z.origin, org_top );
366         org_top[2] = g_MaxWorldCoord;
367         VectorCopy( z.origin, org_bottom );
368         org_bottom[2] = g_MinWorldCoord;
369
370         for ( brush = active_brushes.next ; brush != &active_brushes ; brush = brush->next )
371         {
372                 if ( brush->bFiltered ) {
373                         continue;
374                 }
375
376                 if ( brush->mins[0] >= z.origin[0]
377                          || brush->maxs[0] <= z.origin[0]
378                          || brush->mins[1] >= z.origin[1]
379                          || brush->maxs[1] <= z.origin[1] ) {
380                         continue;
381                 }
382
383                 if ( !Brush_Ray( org_top, dir_down, brush, &top ) ) {
384                         continue;
385                 }
386                 top = org_top[2] - top;
387                 if ( !Brush_Ray( org_bottom, dir_up, brush, &bottom ) ) {
388                         continue;
389                 }
390                 bottom = org_bottom[2] + bottom;
391
392                 q = brush->brush_faces->pShader->getTexture();
393                 qglColor3f( q->color[0], q->color[1], q->color[2] );
394                 qglBegin( GL_QUADS );
395                 qglVertex2f( -xCam, bottom );
396                 qglVertex2f( xCam, bottom );
397                 qglVertex2f( xCam, top );
398                 qglVertex2f( -xCam, top );
399                 qglEnd();
400
401                 qglColor3f( 1,1,1 );
402                 qglBegin( GL_LINE_LOOP );
403                 qglVertex2f( -xCam, bottom );
404                 qglVertex2f( xCam, bottom );
405                 qglVertex2f( xCam, top );
406                 qglVertex2f( -xCam, top );
407                 qglEnd();
408         }
409
410         //
411         // now draw selected brushes
412         //
413         for ( brush = selected_brushes.next ; brush != &selected_brushes ; brush = brush->next )
414         {
415                 if ( !( brush->mins[0] >= z.origin[0]
416                                 || brush->maxs[0] <= z.origin[0]
417                                 || brush->mins[1] >= z.origin[1]
418                                 || brush->maxs[1] <= z.origin[1] ) ) {
419                         if ( Brush_Ray( org_top, dir_down, brush, &top ) ) {
420                                 top = org_top[2] - top;
421                                 if ( Brush_Ray( org_bottom, dir_up, brush, &bottom ) ) {
422                                         bottom = org_bottom[2] + bottom;
423
424                                         q = brush->brush_faces->pShader->getTexture();
425                                         qglColor3f( q->color[0], q->color[1], q->color[2] );
426                                         qglBegin( GL_QUADS );
427                                         qglVertex2f( -xCam, bottom );
428                                         qglVertex2f( xCam, bottom );
429                                         qglVertex2f( xCam, top );
430                                         qglVertex2f( -xCam, top );
431                                         qglEnd();
432                                 }
433                         }
434                 }
435
436                 qglColor3fv( g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES] );
437                 qglBegin( GL_LINE_LOOP );
438                 qglVertex2f( -xCam, brush->mins[2] );
439                 qglVertex2f( xCam, brush->mins[2] );
440                 qglVertex2f( xCam, brush->maxs[2] );
441                 qglVertex2f( -xCam, brush->maxs[2] );
442                 qglEnd();
443         }
444
445
446         ZDrawCameraIcon();
447
448         qglFinish();
449         QE_CheckOpenGLForErrors();
450
451         if ( z.timing ) {
452                 end = Sys_DoubleTime();
453                 Sys_Printf( "z: %i ms\n", (int)( 1000 * ( end - start ) ) );
454         }
455 }