heretic2-sdk/Toolkit/Programming/Tools/qe4/xy.c
1998-11-24 00:00:00 +00:00

1024 lines
22 KiB
C

#include "qe3.h"
#include "clip.h"
#include "undo.h"
#define PAGEFLIPS 2
/*
============
XY_Init
============
*/
void XY_Init (void)
{
g_qeglobals.d_xy.origin[0] = 0;
g_qeglobals.d_xy.origin[1] = 20;
g_qeglobals.d_xy.origin[2] = 46;
g_qeglobals.d_xy.scale = 1;
}
/*
============================================================================
MOUSE ACTIONS
============================================================================
*/
static int cursorx, cursory;
static int buttonstate;
static int pressx, pressy;
static vec3_t pressdelta;
static qboolean press_selection;
static vec3_t cliplinestart;
static vec3_t cliplineend;
void XY_ToPoint (int x, int y, vec3_t point)
{
point[0] = g_qeglobals.d_xy.origin[0] + (x - g_qeglobals.d_xy.width/2)/g_qeglobals.d_xy.scale;
point[1] = g_qeglobals.d_xy.origin[1] + (y - g_qeglobals.d_xy.height/2)/g_qeglobals.d_xy.scale;
point[2] = 0;
}
void XY_ToGridPoint (int x, int y, vec3_t point)
{
point[0] = g_qeglobals.d_xy.origin[0] + (x - g_qeglobals.d_xy.width/2)/g_qeglobals.d_xy.scale;
point[1] = g_qeglobals.d_xy.origin[1] + (y - g_qeglobals.d_xy.height/2)/g_qeglobals.d_xy.scale;
point[2] = 0;
point[0] = floor(point[0]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;
point[1] = floor(point[1]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;
}
/*
==============
XY_MouseDown
==============
*/
void Drag_Reset (void);
void XY_MouseDown (int x, int y, int buttons)
{
vec3_t point;
vec3_t origin, dir, right, up;
Drag_Reset();
buttonstate = buttons;
pressx = x;
pressy = y;
VectorCopy (vec3_origin, pressdelta);
XY_ToPoint (x, y, point);
VectorCopy (point, origin);
origin[2] = 8192;
dir[0] = 0; dir[1] = 0; dir[2] = -1;
right[0] = 1/g_qeglobals.d_xy.scale; right[1] = 0; right[2] = 0;
up[0] = 0; up[1] = 1/g_qeglobals.d_xy.scale; up[2] = 0;
press_selection = (selected_brushes.next != &selected_brushes);
Sys_GetCursorPos (&cursorx, &cursory);
// lbutton = manipulate selection
// shift-LBUTTON = select
if ( (buttons == MK_LBUTTON)
|| (buttons == (MK_LBUTTON | MK_SHIFT))
|| (buttons == (MK_LBUTTON | MK_CONTROL))
|| (buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT))
|| (buttons == (MK_LBUTTON | MK_RBUTTON)))
{
Drag_Begin (x, y, buttons,
right, up,
origin, dir);
return;
}
// control mbutton = move camera
if (buttonstate == (MK_CONTROL|MK_MBUTTON) )
{
camera.origin[0] = point[0];
camera.origin[1] = point[1];
Sys_UpdateWindows (W_CAMERA|W_XY_OVERLAY);
}
// mbutton = angle camera
if (buttonstate == MK_MBUTTON)
{
VectorSubtract (point, camera.origin, point);
if (point[1] || point[0])
{
camera.angles[YAW] = 180/Q_PI*atan2 (point[1], point[0]);
Sys_UpdateWindows (W_CAMERA|W_XY_OVERLAY);
}
}
// shift mbutton = move z checker
if (buttonstate == (MK_SHIFT|MK_MBUTTON) )
{
XY_ToPoint (x, y, point);
z.origin[0] = point[0];
z.origin[1] = point[1];
Sys_UpdateWindows (W_XY_OVERLAY|W_Z);
return;
}
// control rbutton = clip brush
if (buttonstate == (MK_CONTROL|MK_RBUTTON))
{
if (!QE_SingleBrush())
{
Sys_Status ("Must have exactly one brush selected.", 0);
Sys_Beep ();
return;
}
XY_ToGridPoint(x, y, cliplinestart);
XY_ToGridPoint(x, y, cliplineend);
Begin_Clip(x, y);
return;
}
}
/*
==============
XY_MouseUp
==============
*/
void XY_MouseUp (int x, int y, int buttons)
{
Drag_MouseUp ();
if (!press_selection)
Sys_UpdateWindows (W_ALL);
if (buttonstate == (MK_CONTROL|MK_RBUTTON))
{
if (!QE_SingleBrush())
{
Sys_Status ("Must have exactly one brush selected.", 0);
Sys_Beep ();
}
else
{
Finish_Clip( x, y);
}
}
buttonstate = 0;
}
qboolean DragDelta (int x, int y, vec3_t move)
{
vec3_t xvec, yvec, delta;
int i;
xvec[0] = 1/g_qeglobals.d_xy.scale;
xvec[1] = xvec[2] = 0;
yvec[1] = 1/g_qeglobals.d_xy.scale;
yvec[0] = yvec[2] = 0;
for (i=0 ; i<3 ; i++)
{
delta[i] = xvec[i]*(x - pressx) + yvec[i]*(y - pressy);
delta[i] = floor(delta[i]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;
}
VectorSubtract (delta, pressdelta, move);
VectorCopy (delta, pressdelta);
if (move[0] || move[1] || move[2])
return true;
return false;
}
/*
==============
NewBrushDrag
==============
*/
void NewBrushDrag (int x, int y)
{
vec3_t mins, maxs, junk;
int i;
float temp;
brush_t *n;
if (!DragDelta (x,y, junk))
return;
// delete the current selection
if (selected_brushes.next != &selected_brushes)
Brush_Free (selected_brushes.next);
XY_ToGridPoint (pressx, pressy, mins);
mins[2] = g_qeglobals.d_gridsize * ((int)(g_qeglobals.d_new_brush_bottom_z/g_qeglobals.d_gridsize));
XY_ToGridPoint (x, y, maxs);
maxs[2] = g_qeglobals.d_gridsize * ((int)(g_qeglobals.d_new_brush_top_z/g_qeglobals.d_gridsize));
if (maxs[2] <= mins[2])
maxs[2] = mins[2] + g_qeglobals.d_gridsize;
for (i=0 ; i<3 ; i++)
{
if (mins[i] == maxs[i])
return; // don't create a degenerate brush
if (mins[i] > maxs[i])
{
temp = mins[i];
mins[i] = maxs[i];
maxs[i] = temp;
}
}
n = Brush_Create (mins, maxs, &g_qeglobals.d_texturewin.texdef);
if (!n)
return;
Brush_AddToList (n, &selected_brushes);
Entity_LinkBrush (world_entity, n);
Brush_Build( n );
UNDO_FinishBrushAdd ("&Undo New Brush");
// Sys_UpdateWindows (W_ALL);
Sys_UpdateWindows (W_XY| W_CAMERA);
}
/*
==============
XY_MouseMoved
==============
*/
void XY_MouseMoved (int x, int y, int buttons)
{
vec3_t point;
if (!buttonstate)
return;
// lbutton without selection = drag new brush
if (buttonstate == MK_LBUTTON && !press_selection)
{
NewBrushDrag (x, y);
return;
}
// lbutton (possibly with control and or shift)
// with selection = drag selection
if (buttonstate & MK_LBUTTON)
{
Drag_MouseMoved (x, y, buttons);
Sys_UpdateWindows (W_XY_OVERLAY | W_CAMERA);
return;
}
// control mbutton = move camera
if (buttonstate == (MK_CONTROL|MK_MBUTTON) )
{
XY_ToPoint (x, y, point);
camera.origin[0] = point[0];
camera.origin[1] = point[1];
Sys_UpdateWindows (W_XY_OVERLAY | W_CAMERA);
return;
}
// shift mbutton = move z checker
if (buttonstate == (MK_SHIFT|MK_MBUTTON) )
{
XY_ToPoint (x, y, point);
z.origin[0] = point[0];
z.origin[1] = point[1];
Sys_UpdateWindows (W_XY_OVERLAY|W_Z);
return;
}
// mbutton = angle camera
if (buttonstate == MK_MBUTTON )
{
XY_ToPoint (x, y, point);
VectorSubtract (point, camera.origin, point);
if (point[1] || point[0])
{
camera.angles[YAW] = 180/Q_PI*atan2 (point[1], point[0]);
Sys_UpdateWindows (W_XY_OVERLAY | W_CAMERA);
}
return;
}
// rbutton = drag xy origin
if (buttonstate == MK_RBUTTON)
{
Sys_GetCursorPos (&x, &y);
if (x != cursorx || y != cursory)
{
g_qeglobals.d_xy.origin[0] -= (x-cursorx)/g_qeglobals.d_xy.scale;
g_qeglobals.d_xy.origin[1] += (y-cursory)/g_qeglobals.d_xy.scale;
Sys_SetCursorPos (cursorx, cursory);
Sys_UpdateWindows (W_XY | W_XY_OVERLAY);
}
return;
}
// control + rbutton, draw line for clipping plane
if (buttonstate == (MK_CONTROL|MK_RBUTTON))
{
XY_ToGridPoint(x, y, cliplineend);
Sys_UpdateWindows (W_XY|W_XY_OVERLAY);
}
}
/*
============================================================================
DRAWING
============================================================================
*/
/*
==============
XY_DrawGrid
==============
*/
void XY_DrawGrid (void)
{
float x, y, xb, xe, yb, ye;
int w, h;
char text[32];
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_1D);
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
w = g_qeglobals.d_xy.width/2 / g_qeglobals.d_xy.scale;
h = g_qeglobals.d_xy.height/2 / g_qeglobals.d_xy.scale;
xb = g_qeglobals.d_xy.origin[0] - w;
if (xb < region_mins[0])
xb = region_mins[0];
xb = 64 * floor (xb/64);
xe = g_qeglobals.d_xy.origin[0] + w;
if (xe > region_maxs[0])
xe = region_maxs[0];
xe = 64 * ceil (xe/64);
yb = g_qeglobals.d_xy.origin[1] - h;
if (yb < region_mins[1])
yb = region_mins[1];
yb = 64 * floor (yb/64);
ye = g_qeglobals.d_xy.origin[1] + h;
if (ye > region_maxs[1])
ye = region_maxs[1];
ye = 64 * ceil (ye/64);
// draw major blocks
glColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR]);
if ( g_qeglobals.d_showgrid )
{
glBegin (GL_LINES);
for (x=xb ; x<=xe ; x+=64)
{
glVertex2f (x, yb);
glVertex2f (x, ye);
}
for (y=yb ; y<=ye ; y+=64)
{
glVertex2f (xb, y);
glVertex2f (xe, y);
}
glEnd ();
}
// draw minor blocks
if ( g_qeglobals.d_showgrid && g_qeglobals.d_gridsize*g_qeglobals.d_xy.scale >= 4)
{
glColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR]);
glBegin (GL_LINES);
for (x=xb ; x<xe ; x += g_qeglobals.d_gridsize)
{
if ( ! ((int)x & 63) )
continue;
glVertex2f (x, yb);
glVertex2f (x, ye);
}
for (y=yb ; y<ye ; y+=g_qeglobals.d_gridsize)
{
if ( ! ((int)y & 63) )
continue;
glVertex2f (xb, y);
glVertex2f (xe, y);
}
glEnd ();
}
// draw coordinate text if needed
if ( g_qeglobals.d_savedinfo.show_coordinates)
{
glColor4f(0, 0, 0, 0);
for (x=xb ; x<xe ; x+=64)
{
glRasterPos2f (x, g_qeglobals.d_xy.origin[1] + h - 6/g_qeglobals.d_xy.scale);
sprintf (text, "%i",(int)x);
glCallLists (strlen(text), GL_UNSIGNED_BYTE, text);
}
for (y=yb ; y<ye ; y+=64)
{
glRasterPos2f (g_qeglobals.d_xy.origin[0] - w + 1, y);
sprintf (text, "%i",(int)y);
glCallLists (strlen(text), GL_UNSIGNED_BYTE, text);
}
}
}
/*
==============
XY_DrawBlockGrid
==============
*/
void XY_DrawBlockGrid (void)
{
float x, y, xb, xe, yb, ye;
int w, h;
char text[32];
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_1D);
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
w = g_qeglobals.d_xy.width/2 / g_qeglobals.d_xy.scale;
h = g_qeglobals.d_xy.height/2 / g_qeglobals.d_xy.scale;
xb = g_qeglobals.d_xy.origin[0] - w;
if (xb < region_mins[0])
xb = region_mins[0];
xb = 1024 * floor (xb/1024);
xe = g_qeglobals.d_xy.origin[0] + w;
if (xe > region_maxs[0])
xe = region_maxs[0];
xe = 1024 * ceil (xe/1024);
yb = g_qeglobals.d_xy.origin[1] - h;
if (yb < region_mins[1])
yb = region_mins[1];
yb = 1024 * floor (yb/1024);
ye = g_qeglobals.d_xy.origin[1] + h;
if (ye > region_maxs[1])
ye = region_maxs[1];
ye = 1024 * ceil (ye/1024);
// draw major blocks
glColor3f(0,0,1);
glLineWidth (2);
glBegin (GL_LINES);
for (x=xb ; x<=xe ; x+=1024)
{
glVertex2f (x, yb);
glVertex2f (x, ye);
}
for (y=yb ; y<=ye ; y+=1024)
{
glVertex2f (xb, y);
glVertex2f (xe, y);
}
glEnd ();
glLineWidth (1);
// draw coordinate text if needed
for (x=xb ; x<xe ; x+=1024)
for (y=yb ; y<ye ; y+=1024)
{
glRasterPos2f (x+512, y+512);
sprintf (text, "%i,%i",(int)floor(x/1024), (int)floor(y/1024) );
glCallLists (strlen(text), GL_UNSIGNED_BYTE, text);
}
glColor4f(0, 0, 0, 0);
}
void DrawCameraIcon (void)
{
float x, y, a;
x = camera.origin[0];
y = camera.origin[1];
a = camera.angles[YAW]/180*Q_PI;
glColor3f (0.0, 0.0, 1.0);
glBegin(GL_LINE_STRIP);
glVertex3f (x-16,y,0);
glVertex3f (x,y+8,0);
glVertex3f (x+16,y,0);
glVertex3f (x,y-8,0);
glVertex3f (x-16,y,0);
glVertex3f (x+16,y,0);
glEnd ();
glBegin(GL_LINE_STRIP);
glVertex3f (x+48*cos(a+Q_PI/4), y+48*sin(a+Q_PI/4), 0);
glVertex3f (x, y, 0);
glVertex3f (x+48*cos(a-Q_PI/4), y+48*sin(a-Q_PI/4), 0);
glEnd ();
}
void DrawZIcon (void)
{
float x, y;
x = z.origin[0];
y = z.origin[1];
glEnable (GL_BLEND);
glDisable (GL_TEXTURE_2D);
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
glDisable (GL_CULL_FACE);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f (0.0, 0.0, 1.0, 0.25);
glBegin(GL_QUADS);
glVertex3f (x-8,y-8,0);
glVertex3f (x+8,y-8,0);
glVertex3f (x+8,y+8,0);
glVertex3f (x-8,y+8,0);
glEnd ();
glDisable (GL_BLEND);
glColor4f (0.0, 0.0, 1.0, 1);
glBegin(GL_LINE_LOOP);
glVertex3f (x-8,y-8,0);
glVertex3f (x+8,y-8,0);
glVertex3f (x+8,y+8,0);
glVertex3f (x-8,y+8,0);
glEnd ();
glBegin(GL_LINE_STRIP);
glVertex3f (x-4,y+4,0);
glVertex3f (x+4,y+4,0);
glVertex3f (x-4,y-4,0);
glVertex3f (x+4,y-4,0);
glEnd ();
}
/*
==================
FilterBrush
==================
*/
BOOL FilterBrush(brush_t *pb)
{
if (!pb->owner)
return FALSE; // during construction
if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CLIP)
{
if (!strncmp(pb->brush_faces->texdef.name, "clip", 4))
return TRUE;
}
if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_WATER)
{
if (pb->brush_faces->texdef.flags == 40)
{
// if (pb->brush_faces->texdef.name[0] == '*')
return TRUE;
}
}
if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_DETAIL)
{
if (pb->brush_faces->texdef.contents & CONTENTS_DETAIL)
return TRUE;
}
if (pb->owner == world_entity)
{
if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_WORLD)
return TRUE;
return FALSE;
}
else if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_ENT)
{
if (g_qeglobals.d_savedinfo.exclude & BUOY_ONLY)
{
if (!strcmp(ValueForKey (pb->owner , "classname"), "info_buoy"))
{
return FALSE;
}
}
return TRUE;
}
if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_LIGHTS)
{
if (!strncmp(pb->owner->eclass->name, "light", 5))
return TRUE;
}
if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_PATHS)
{
if (!strncmp(pb->owner->eclass->name, "path", 4))
return TRUE;
}
return FALSE;
}
/*
=============================================================
PATH LINES
=============================================================
*/
/*
==================
DrawPathLines
Draws connections between entities.
Needs to consider all entities, not just ones on screen,
because the lines can be visible when neither end is.
Called for both camera view and xy view.
==================
*/
void DrawPathLines (void)
{
int i, j, k;
vec3_t mid, mid1;
entity_t *se, *te;
brush_t *sb, *tb;
char *psz;
vec3_t dir, s1, s2;
vec_t len, f;
int arrows;
int num_entities;
char *ent_target[MAX_MAP_ENTITIES];
entity_t *ent_entity[MAX_MAP_ENTITIES];
num_entities = 0;
for (te = entities.next ; te != &entities && num_entities != MAX_MAP_ENTITIES ; te = te->next)
{
ent_target[num_entities] = ValueForKey (te, "target");
ent_target[num_entities + 1] = ValueForKey (te, "target2");
if (ent_target[num_entities][0])
{
ent_entity[num_entities] = te;
num_entities++;
if (ent_target[num_entities][0])
{
ent_entity[num_entities] = te;
num_entities++;
}
}
}
for (se = entities.next ; se != &entities ; se = se->next)
{
psz = ValueForKey(se, "targetname");
if (psz == NULL || psz[0] == '\0')
continue;
sb = se->brushes.onext;
if (sb == &se->brushes)
continue;
for (k=0 ; k<num_entities ; k++)
{
if (strcmp (ent_target[k], psz))
continue;
te = ent_entity[k];
tb = te->brushes.onext;
if (tb == &te->brushes)
continue;
for (i=0 ; i<3 ; i++)
mid[i] = (sb->mins[i] + sb->maxs[i])*0.5;
for (i=0 ; i<3 ; i++)
mid1[i] = (tb->mins[i] + tb->maxs[i])*0.5;
VectorSubtract (mid1, mid, dir);
len = VectorNormalize (dir, dir);
s1[0] = -dir[1]*8 + dir[0]*8;
s2[0] = dir[1]*8 + dir[0]*8;
s1[1] = dir[0]*8 + dir[1]*8;
s2[1] = -dir[0]*8 + dir[1]*8;
glColor3f (se->eclass->color[0], se->eclass->color[1], se->eclass->color[2]);
glBegin(GL_LINES);
glVertex3fv(mid);
glVertex3fv(mid1);
arrows = (int)(len / 256) + 1;
for (i=0 ; i<arrows ; i++)
{
f = len * (i + 0.5) / arrows;
for (j=0 ; j<3 ; j++)
mid1[j] = mid[j] + f*dir[j];
glVertex3fv (mid1);
glVertex3f (mid1[0] + s1[0], mid1[1] + s1[1], mid1[2]);
glVertex3fv (mid1);
glVertex3f (mid1[0] + s2[0], mid1[1] + s2[1], mid1[2]);
}
glEnd();
}
}
return;
}
//=============================================================
/*
==============
XY_Draw
==============
*/
void XY_Draw (void)
{
brush_t *brush;
float w, h;
entity_t *e;
double start, end;
vec3_t mins, maxs;
int drawn, culled;
int i;
if (!active_brushes.next)
return; // not valid yet
if (g_qeglobals.d_xy.timing)
start = Sys_DoubleTime ();
//
// clear
//
g_qeglobals.d_xy.d_dirty = false;
glViewport(0, 0, g_qeglobals.d_xy.width, g_qeglobals.d_xy.height);
glClearColor (
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);
glClear(GL_COLOR_BUFFER_BIT);
//
// set up viewpoint
//
glMatrixMode(GL_PROJECTION);
glLoadIdentity ();
w = g_qeglobals.d_xy.width/2 / g_qeglobals.d_xy.scale;
h = g_qeglobals.d_xy.height/2 / g_qeglobals.d_xy.scale;
mins[0] = g_qeglobals.d_xy.origin[0] - w;
maxs[0] = g_qeglobals.d_xy.origin[0] + w;
mins[1] = g_qeglobals.d_xy.origin[1] - h;
maxs[1] = g_qeglobals.d_xy.origin[1] + h;
glOrtho (mins[0], maxs[0], mins[1], maxs[1], -8000, 8000);
//
// now draw the grid
//
XY_DrawGrid ();
//
// draw stuff
//
glShadeModel (GL_FLAT);
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_1D);
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glColor3f(0, 0, 0);
// glEnable (GL_LINE_SMOOTH);
drawn = culled = 0;
e = NULL;
for (brush = active_brushes.next ; brush != &active_brushes ; brush=brush->next)
{
if (brush->mins[0] > maxs[0]
|| brush->mins[1] > maxs[1]
|| brush->maxs[0] < mins[0]
|| brush->maxs[1] < mins[1] )
{
culled++;
continue; // off screen
}
if (FilterBrush (brush))
continue;
drawn++;
if (brush->owner != e)
{
e = brush->owner;
glColor3fv(e->eclass->color);
}
Brush_DrawXY( brush );
}
DrawPathLines ();
//
// draw pointfile
//
if ( g_qeglobals.d_pointfile_display_list)
glCallList (g_qeglobals.d_pointfile_display_list);
//
// draw block grid
//
if ( g_qeglobals.show_blocks)
XY_DrawBlockGrid ();
//
// now draw selected brushes
//
glTranslatef( g_qeglobals.d_select_translate[0], g_qeglobals.d_select_translate[1], g_qeglobals.d_select_translate[2]);
glColor3f(1.0, 0.0, 0.0);
glEnable (GL_LINE_STIPPLE);
glLineStipple (3, 0xaaaa);
glLineWidth (2);
for (brush = selected_brushes.next ; brush != &selected_brushes ; brush=brush->next)
{
drawn++;
Brush_DrawXY( brush );
}
glDisable (GL_LINE_STIPPLE);
glLineWidth (1);
// edge / vertex flags
if (g_qeglobals.d_select_mode == sel_vertex)
{
glPointSize (4);
glColor3f (0,1,0);
glBegin (GL_POINTS);
for (i=0 ; i<g_qeglobals.d_numpoints ; i++)
glVertex3fv (g_qeglobals.d_points[i]);
glEnd ();
glPointSize (1);
}
else if (g_qeglobals.d_select_mode == sel_edge)
{
float *v1, *v2;
glPointSize (4);
glColor3f (0,0,1);
glBegin (GL_POINTS);
for (i=0 ; i<g_qeglobals.d_numedges ; i++)
{
v1 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p1];
v2 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p2];
glVertex3f ( (v1[0]+v2[0])*0.5,(v1[1]+v2[1])*0.5,(v1[2]+v2[2])*0.5);
}
glEnd ();
glPointSize (1);
}
glTranslatef (-g_qeglobals.d_select_translate[0], -g_qeglobals.d_select_translate[1], -g_qeglobals.d_select_translate[2]);
//
// now draw camera point
//
DrawCameraIcon ();
DrawZIcon ();
glFinish();
QE_CheckOpenGLForErrors();
if (g_qeglobals.d_xy.timing)
{
end = Sys_DoubleTime ();
Sys_Printf ("xy: %i ms\n", (int)(1000*(end-start)));
}
// finally, draw a clipping line if needed
if ( buttonstate == (MK_RBUTTON|MK_CONTROL))
{
if (!QE_SingleBrush())
{
Sys_Status ("Must have exactly one brush selected.", 0);
Sys_Beep ();
return;
}
Draw_Clip(cliplinestart, cliplineend);
}
}
/*
==============
XY_Overlay
==============
*/
void XY_Overlay (void)
{
int w, h;
int r[4];
static vec3_t lastz;
static vec3_t lastcamera;
glViewport(0, 0, g_qeglobals.d_xy.width, g_qeglobals.d_xy.height);
//
// set up viewpoint
//
glMatrixMode(GL_PROJECTION);
glLoadIdentity ();
w = g_qeglobals.d_xy.width/2 / g_qeglobals.d_xy.scale;
h = g_qeglobals.d_xy.height/2 / g_qeglobals.d_xy.scale;
glOrtho (g_qeglobals.d_xy.origin[0] - w, g_qeglobals.d_xy.origin[0] + w
, g_qeglobals.d_xy.origin[1] - h, g_qeglobals.d_xy.origin[1] + h, -8000, 8000);
//
// erase the old camera and z checker positions
// if the entire xy hasn't been redrawn
//
if (g_qeglobals.d_xy.d_dirty)
{
glReadBuffer (GL_BACK);
glDrawBuffer (GL_FRONT);
glRasterPos2f (lastz[0]-9, lastz[1]-9);
glGetIntegerv (GL_CURRENT_RASTER_POSITION,r);
glCopyPixels(r[0], r[1], 18,18, GL_COLOR);
glRasterPos2f (lastcamera[0]-50, lastcamera[1]-50);
glGetIntegerv (GL_CURRENT_RASTER_POSITION,r);
glCopyPixels(r[0], r[1], 100,100, GL_COLOR);
}
g_qeglobals.d_xy.d_dirty = true;
//
// save off underneath where we are about to draw
//
VectorCopy (z.origin, lastz);
VectorCopy (camera.origin, lastcamera);
glReadBuffer (GL_FRONT);
glDrawBuffer (GL_BACK);
glRasterPos2f (lastz[0]-9, lastz[1]-9);
glGetIntegerv (GL_CURRENT_RASTER_POSITION,r);
glCopyPixels(r[0], r[1], 18,18, GL_COLOR);
glRasterPos2f (lastcamera[0]-50, lastcamera[1]-50);
glGetIntegerv (GL_CURRENT_RASTER_POSITION,r);
glCopyPixels(r[0], r[1], 100,100, GL_COLOR);
//
// draw the new icons
//
glDrawBuffer (GL_FRONT);
glShadeModel (GL_FLAT);
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_1D);
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glColor3f(0, 0, 0);
DrawCameraIcon ();
DrawZIcon ();
glDrawBuffer (GL_BACK);
glFinish();
}