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