gtkradiant/radiant/z.cpp

456 lines
10 KiB
C++

/*
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 ) ) );
}
}