/* Copyright (C) 1999-2007 id Software, Inc. and contributors. For a list of contributors, see the accompanying CONTRIBUTORS file. This file is part of GtkRadiant. GtkRadiant is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. GtkRadiant is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GtkRadiant; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "stdafx.h" //#include "qe3.h" #define PAGEFLIPS 2 z_t z; /* ============ Z_Init ============ */ void Z_Init( void ){ z.origin[0] = 0; z.origin[1] = 20; z.origin[2] = 46; z.scale = 1; } /* ============================================================================ MOUSE ACTIONS ============================================================================ */ static int cursorx, cursory; /* ============== Z_MouseDown ============== */ void Z_MouseDown( int x, int y, int buttons ){ vec3_t org, dir, vup, vright; brush_t *b; Sys_GetCursorPos( &cursorx, &cursory ); vup[0] = 0; vup[1] = 0; vup[2] = 1 / z.scale; VectorCopy( z.origin, org ); org[2] += ( y - ( z.height / 2 ) ) / z.scale; org[1] = g_MinWorldCoord; b = selected_brushes.next; if ( b != &selected_brushes ) { org[0] = ( b->mins[0] + b->maxs[0] ) / 2; } dir[0] = 0; dir[1] = 1; dir[2] = 0; vright[0] = 0; vright[1] = 0; vright[2] = 0; // LBUTTON = manipulate selection // shift-LBUTTON = select // middle button = grab texture // ctrl-middle button = set entire brush to texture // ctrl-shift-middle button = set single face to texture int nMouseButton = g_PrefsDlg.m_nMouseButtons == 2 ? MK_RBUTTON : MK_MBUTTON; if ( ( buttons == MK_LBUTTON ) || ( buttons == ( MK_LBUTTON | MK_SHIFT ) ) || ( buttons == MK_MBUTTON ) // || (buttons == (MK_MBUTTON|MK_CONTROL)) || ( buttons == ( nMouseButton | MK_SHIFT | MK_CONTROL ) ) ) { Drag_Begin( x, y, buttons, vright, vup, org, dir ); return; } // control mbutton = move camera if ( ( buttons == ( MK_CONTROL | nMouseButton ) ) || ( buttons == ( MK_CONTROL | MK_LBUTTON ) ) ) { g_pParentWnd->GetCamWnd()->Camera()->origin[2] = org[2] ; Sys_UpdateWindows( W_CAMERA | W_XY_OVERLAY | W_Z ); } } /* ============== Z_MouseUp ============== */ void Z_MouseUp( int x, int y, int buttons ){ Drag_MouseUp(); } /* ============== Z_MouseMoved ============== */ void Z_MouseMoved( int x, int y, int buttons ){ if ( !buttons ) { return; } if ( buttons == MK_LBUTTON ) { Drag_MouseMoved( x, y, buttons ); Sys_UpdateWindows( W_Z | W_CAMERA_IFON | W_XY ); return; } // rbutton = drag z origin if ( buttons == MK_RBUTTON ) { Sys_GetCursorPos( &x, &y ); if ( y != cursory ) { z.origin[2] += y - cursory; Sys_SetCursorPos( cursorx, cursory ); Sys_UpdateWindows( W_Z ); } return; } // control mbutton = move camera int nMouseButton = g_PrefsDlg.m_nMouseButtons == 2 ? MK_RBUTTON : MK_MBUTTON; if ( ( buttons == ( MK_CONTROL | nMouseButton ) ) || ( buttons == ( MK_CONTROL | MK_LBUTTON ) ) ) { g_pParentWnd->GetCamWnd()->Camera()->origin[2] = ( y - ( z.height / 2 ) ) / z.scale; Sys_UpdateWindows( W_CAMERA | W_XY_OVERLAY | W_Z ); } } /* ============================================================================ DRAWING ============================================================================ */ /* ============== Z_DrawGrid ============== */ void Z_DrawGrid( void ){ float zz, zb, ze; float w, h; char text[32]; w = ( z.width / 2 / z.scale ); h = ( z.height / 2 / z.scale ); zb = z.origin[2] - h; if ( zb < region_mins[2] ) { zb = region_mins[2]; } zb = 64 * floor( zb / 64 ); ze = z.origin[2] + h; if ( ze > region_maxs[2] ) { ze = region_maxs[2]; } ze = 64 * ceil( ze / 64 ); // draw major blocks qglColor3fv( g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR] ); if ( g_qeglobals.d_showgrid ) { if ( g_qeglobals.d_gridsize < 128 ) { qglBegin( GL_LINES ); qglVertex2f( 0, zb ); qglVertex2f( 0, ze ); for ( zz = zb ; zz < ze ; zz += 64 ) { qglVertex2f( -w, zz ); qglVertex2f( w, zz ); } qglEnd(); } else { qglBegin( GL_LINES ); qglVertex2f( 0, zb ); qglVertex2f( 0, ze ); for ( zz = zb ; zz < ze ; zz += 64 ) { // d_gridsize >= 128 .. it's an int for sure if ( ( (int)zz & ( (int)g_qeglobals.d_gridsize - 1 ) ) != 0 ) { continue; } qglVertex2f( -w, zz ); qglVertex2f( w, zz ); } qglEnd(); } } // draw minor blocks if ( g_qeglobals.d_showgrid && g_qeglobals.d_gridsize * z.scale >= 4 && g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR] != g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK] ) { qglColor3fv( g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR] ); qglBegin( GL_LINES ); for ( zz = zb ; zz < ze ; zz += g_qeglobals.d_gridsize ) { if ( !( (int)zz & 63 ) ) { continue; } qglVertex2f( -w, zz ); qglVertex2f( w, zz ); } qglEnd(); } // draw coordinate text if needed if ( g_qeglobals.d_savedinfo.show_coordinates ) { qglColor3fv( g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT] ); int step = (int)( g_qeglobals.d_gridsize > 64 ? g_qeglobals.d_gridsize : 64 ); zb = z.origin[2] - h; if ( zb < region_mins[2] ) { zb = region_mins[2]; } zb = step * floor( zb / step ); for ( zz = zb ; zz < ze ; zz += step ) { qglRasterPos2f( -w + ( 1 / z.scale ), zz ); sprintf( text, "%i",(int)zz ); gtk_glwidget_print_string( text ); } } } void ZDrawCameraIcon( void ){ float x, y; float xCam = z.width / 4 / z.scale, gizmo = 8 / z.scale, height = 48 / z.scale; x = 0; y = g_pParentWnd->GetCamWnd()->Camera()->origin[2]; qglColor3f( 0.0, 0.0, 1.0 ); qglBegin( GL_LINE_STRIP ); qglVertex3f( x - xCam,y,0 ); qglVertex3f( x,y + gizmo,0 ); qglVertex3f( x + xCam,y,0 ); qglVertex3f( x,y - gizmo,0 ); qglVertex3f( x - xCam,y,0 ); qglVertex3f( x + xCam,y,0 ); qglVertex3f( x + xCam,y - height,0 ); qglVertex3f( x - xCam,y - height,0 ); qglVertex3f( x - xCam,y,0 ); qglEnd(); } GLbitfield glbitClear = GL_COLOR_BUFFER_BIT; //HACK /* ============== Z_Draw ============== */ void Z_Draw( void ){ #ifdef DBG_WINDOWPOS CheckWatchit( "Z_Draw" ); #endif brush_t *brush; float w, h; double start, end; qtexture_t *q; float top, bottom; vec3_t org_top, org_bottom, dir_up, dir_down; int xCam = z.width / 3; if ( !active_brushes.next ) { return; // not valid yet } if ( z.timing ) { start = Sys_DoubleTime(); } // // clear // qglViewport( 0, 0, z.width, z.height ); qglClearColor( g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][0], g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][1], g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][2], 0 ); /* GL Bug */ /* When not using hw acceleration, gl will fault if we clear the depth buffer bit on the first pass. The hack fix is to set the GL_DEPTH_BUFFER_BIT only after Z_Draw() has been called once. Yeah, right. */ qglClear( glbitClear ); glbitClear |= GL_DEPTH_BUFFER_BIT; qglMatrixMode( GL_PROJECTION ); qglLoadIdentity(); w = z.width / 2 / z.scale; h = z.height / 2 / z.scale; qglOrtho( -w, w, z.origin[2] - h, z.origin[2] + h, -8, 8 ); qglDisable( GL_TEXTURE_2D ); qglDisable( GL_TEXTURE_1D ); qglDisable( GL_DEPTH_TEST ); qglDisable( GL_BLEND ); // // now draw the grid // Z_DrawGrid(); // // draw stuff // qglDisable( GL_CULL_FACE ); qglShadeModel( GL_FLAT ); qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); qglDisable( GL_TEXTURE_2D ); qglDisable( GL_BLEND ); qglDisable( GL_DEPTH_TEST ); // draw filled interiors and edges dir_up[0] = 0 ; dir_up[1] = 0; dir_up[2] = 1; dir_down[0] = 0 ; dir_down[1] = 0; dir_down[2] = -1; VectorCopy( z.origin, org_top ); org_top[2] = g_MaxWorldCoord; VectorCopy( z.origin, org_bottom ); org_bottom[2] = g_MinWorldCoord; for ( brush = active_brushes.next ; brush != &active_brushes ; brush = brush->next ) { if ( brush->bFiltered ) { continue; } if ( brush->mins[0] >= z.origin[0] || brush->maxs[0] <= z.origin[0] || brush->mins[1] >= z.origin[1] || brush->maxs[1] <= z.origin[1] ) { continue; } if ( !Brush_Ray( org_top, dir_down, brush, &top ) ) { continue; } top = org_top[2] - top; if ( !Brush_Ray( org_bottom, dir_up, brush, &bottom ) ) { continue; } bottom = org_bottom[2] + bottom; q = brush->brush_faces->pShader->getTexture(); qglColor3f( q->color[0], q->color[1], q->color[2] ); qglBegin( GL_QUADS ); qglVertex2f( -xCam, bottom ); qglVertex2f( xCam, bottom ); qglVertex2f( xCam, top ); qglVertex2f( -xCam, top ); qglEnd(); qglColor3f( 1,1,1 ); qglBegin( GL_LINE_LOOP ); qglVertex2f( -xCam, bottom ); qglVertex2f( xCam, bottom ); qglVertex2f( xCam, top ); qglVertex2f( -xCam, top ); qglEnd(); } // // now draw selected brushes // for ( brush = selected_brushes.next ; brush != &selected_brushes ; brush = brush->next ) { if ( !( brush->mins[0] >= z.origin[0] || brush->maxs[0] <= z.origin[0] || brush->mins[1] >= z.origin[1] || brush->maxs[1] <= z.origin[1] ) ) { if ( Brush_Ray( org_top, dir_down, brush, &top ) ) { top = org_top[2] - top; if ( Brush_Ray( org_bottom, dir_up, brush, &bottom ) ) { bottom = org_bottom[2] + bottom; q = brush->brush_faces->pShader->getTexture(); qglColor3f( q->color[0], q->color[1], q->color[2] ); qglBegin( GL_QUADS ); qglVertex2f( -xCam, bottom ); qglVertex2f( xCam, bottom ); qglVertex2f( xCam, top ); qglVertex2f( -xCam, top ); qglEnd(); } } } qglColor3fv( g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES] ); qglBegin( GL_LINE_LOOP ); qglVertex2f( -xCam, brush->mins[2] ); qglVertex2f( xCam, brush->mins[2] ); qglVertex2f( xCam, brush->maxs[2] ); qglVertex2f( -xCam, brush->maxs[2] ); qglEnd(); } ZDrawCameraIcon(); qglFinish(); QE_CheckOpenGLForErrors(); if ( z.timing ) { end = Sys_DoubleTime(); Sys_Printf( "z: %i ms\n", (int)( 1000 * ( end - start ) ) ); } }