diff options
| author | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:31:46 -0800 |
|---|---|---|
| committer | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:46:31 -0800 |
| commit | f56bb35301836e56582a575a75864392a0177875 (patch) | |
| tree | de61ddd39de3e7df52759711950b4c288592f0dc /mp/src/utils/glview/glview.cpp | |
| parent | Mark some more files as text. (diff) | |
| download | source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip | |
Fix line endings. WHAMMY.
Diffstat (limited to 'mp/src/utils/glview/glview.cpp')
| -rw-r--r-- | mp/src/utils/glview/glview.cpp | 2854 |
1 files changed, 1427 insertions, 1427 deletions
diff --git a/mp/src/utils/glview/glview.cpp b/mp/src/utils/glview/glview.cpp index d60a6556..d7da07b3 100644 --- a/mp/src/utils/glview/glview.cpp +++ b/mp/src/utils/glview/glview.cpp @@ -1,1427 +1,1427 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//=============================================================================//
-#include "glos.h"
-#include <gl/gl.h>
-#if _MSC_VER < 1600
-#include <gl/glaux.h>
-#endif
-#include <gl/glu.h>
-#include <stdarg.h>
-#include <string.h>
-#include <stdio.h>
-#include <math.h>
-#include "cmdlib.h"
-#include "mathlib/mathlib.h"
-#include "cmodel.h"
-#include "tier1/strtools.h"
-#include "physdll.h"
-#include "phyfile.h"
-#include "vphysics_interface.h"
-#include "tier0/icommandline.h"
-#include "tier0/vprof.h"
-
-HDC camdc;
-HGLRC baseRC;
-HWND camerawindow;
-HANDLE main_instance;
-
-/* YWB: 3/13/98
- You run the program like normal with any file. If you want to read portals for the
- file type, you type: glview -portal filename.gl0 (or whatever). glview will then
- try to read in the .prt file filename.prt.
-
- The portals are shown as white lines superimposed over your image. You can toggle the
- view between showing portals or not by hitting the '2' key. The '1' key toggles
- world polygons.
-
- The 'b' key toggles blending modes.
-
- If you don't want to depth buffer the portals, hit 'p'.
-
- The command line parsing is inelegant but functional.
-
- I sped up the KB movement and turn speed, too.
- */
-
-// Vars added by YWB
-Vector g_Center; // Center of all read points, so camera is in a sensible place
-int g_nTotalPoints = 0; // Total points read, for calculating center
-int g_UseBlending = 0; // Toggle to use blending mode or not
-BOOL g_bReadPortals = 0; // Did we read in a portal file?
-BOOL g_bNoDepthPortals = 0; // Do we zbuffer the lines of the portals?
-int g_nPortalHighlight = -1; // The leaf we're viewing
-int g_nLeafHighlight = -1; // The leaf we're viewing
-BOOL g_bShowList1 = 1; // Show regular polygons?
-BOOL g_bShowList2 = 1; // Show portals?
-BOOL g_bShowLines = 0; // Show outlines of faces
-BOOL g_Active = TRUE;
-BOOL g_Update = TRUE;
-BOOL g_bDisp = FALSE;
-IPhysicsCollision *physcollision = NULL;
-// -----------
-static int g_Keys[255];
-void AppKeyDown( int key );
-void AppKeyUp( int key );
-
-
-BOOL ReadDisplacementFile( const char *filename );
-void DrawDisplacementData( void );
-
-#define BENCHMARK_PHY 0
-
-/*
-=================
-Error
-
-For abnormal program terminations
-=================
-*/
-void Error (char *error, ...)
-{
- va_list argptr;
- char text[1024];
-
- va_start (argptr,error);
- vsprintf (text, error,argptr);
- va_end (argptr);
-
- MessageBox(NULL, text, "Error", 0 /* MB_OK */ );
-
- exit (1);
-}
-
-float origin[3] = {32, 32, 48};
-float angles[3];
-float forward[3], right[3], vup[3], vpn[3], vright[3];
-float width = 1024;
-float height = 768;
-
-float g_flMovementSpeed = 320.f; // Units / second (run speed of HL)
-#define SPEED_TURN 90 // Degrees / second
-
-#define VK_COMMA 188
-#define VK_PERIOD 190
-
-
-void KeyDown (int key)
-{
- switch (key)
- {
- case VK_ESCAPE:
- g_Active = FALSE;
- break;
-
- case VK_F1:
- glEnable (GL_CULL_FACE);
- glCullFace (GL_FRONT);
- break;
- case 'B':
- g_UseBlending ^= 1;
- if (g_UseBlending)
- glEnable(GL_BLEND);// YWB TESTING
- else
- glDisable(GL_BLEND);
- break;
-
- case '1':
- g_bShowList1 ^= 1;
- break;
- case '2':
- g_bShowList2 ^= 1;
- break;
- case 'P':
- g_bNoDepthPortals ^= 1;
- break;
- case 'L':
- g_bShowLines ^= 1;
- break;
- }
- g_Update = TRUE;
-}
-
-static BOOL g_Capture = FALSE;
-
-#define MOUSE_SENSITIVITY 0.2f
-#define MOUSE_SENSITIVITY_X (MOUSE_SENSITIVITY*1)
-#define MOUSE_SENSITIVITY_Y (MOUSE_SENSITIVITY*1)
-
-void Cam_MouseMoved( void )
-{
- if ( g_Capture )
- {
- RECT rect;
- int centerx, centery;
- float deltax, deltay;
- POINT cursorPoint;
-
- GetWindowRect( camerawindow, &rect );
-
- if ( rect.top < 0)
- rect.top = 0;
- if ( rect.left < 0)
- rect.left = 0;
-
- centerx = ( rect.left + rect.right ) / 2;
- centery = ( rect.top + rect.bottom ) / 2;
-
- GetCursorPos( &cursorPoint );
- SetCursorPos( centerx, centery );
-
- deltax = (cursorPoint.x - centerx) * MOUSE_SENSITIVITY_X;
- deltay = (cursorPoint.y - centery) * MOUSE_SENSITIVITY_Y;
-
- angles[1] -= deltax;
- angles[0] -= deltay;
-
- g_Update = TRUE;
- }
-}
-
-int Test_Key( int key )
-{
- int r = (g_Keys[ key ] != 0);
-
- g_Keys[ key ] &= 0x01; // clear out debounce bit
-
- if (r)
- g_Update = TRUE;
-
- return r;
-}
-
-// UNDONE: Probably should change the controls to match the game - but I don't know who relies on them
-// as of now.
-void Cam_Update( float frametime )
-{
- if ( Test_Key( 'W' ) )
- {
- VectorMA (origin, g_flMovementSpeed*frametime, vpn, origin);
- }
- if ( Test_Key( 'S' ) )
- {
- VectorMA (origin, -g_flMovementSpeed*frametime, vpn, origin);
- }
- if ( Test_Key( 'A' ) )
- {
- VectorMA (origin, -g_flMovementSpeed*frametime, vright, origin);
- }
- if ( Test_Key( 'D' ) )
- {
- VectorMA (origin, g_flMovementSpeed*frametime, vright, origin);
- }
-
- if ( Test_Key( VK_UP ) )
- {
- VectorMA (origin, g_flMovementSpeed*frametime, forward, origin);
- }
- if ( Test_Key( VK_DOWN ) )
- {
- VectorMA (origin, -g_flMovementSpeed*frametime, forward, origin);
- }
-
- if ( Test_Key( VK_LEFT ) )
- {
- angles[1] += SPEED_TURN * frametime;
- }
- if ( Test_Key( VK_RIGHT ) )
- {
- angles[1] -= SPEED_TURN * frametime;
- }
- if ( Test_Key( 'F' ) )
- {
- origin[2] += g_flMovementSpeed*frametime;
- }
- if ( Test_Key( 'C' ) )
- {
- origin[2] -= g_flMovementSpeed*frametime;
- }
- if ( Test_Key( VK_INSERT ) )
- {
- angles[0] += SPEED_TURN * frametime;
- if (angles[0] > 85)
- angles[0] = 85;
- }
- if ( Test_Key( VK_DELETE ) )
- {
- angles[0] -= SPEED_TURN * frametime;
- if (angles[0] < -85)
- angles[0] = -85;
- }
- Cam_MouseMoved();
-}
-
-void Cam_BuildMatrix (void)
-{
- float xa, ya;
- float matrix[4][4];
- int i;
-
- xa = angles[0]/180*M_PI;
- ya = angles[1]/180*M_PI;
-
- // the movement matrix is kept 2d ?? do we want this?
-
- forward[0] = cos(ya);
- forward[1] = sin(ya);
- right[0] = forward[1];
- right[1] = -forward[0];
-
- glGetFloatv (GL_PROJECTION_MATRIX, &matrix[0][0]);
-
- for (i=0 ; i<3 ; i++)
- {
- vright[i] = matrix[i][0];
- vup[i] = matrix[i][1];
- vpn[i] = matrix[i][2];
- }
-
- VectorNormalize (vright);
- VectorNormalize (vup);
- VectorNormalize (vpn);
-}
-
-void Draw (void)
-{
- float screenaspect;
- float yfov;
-
- //glClearColor (0.5, 0.5, 0.5, 0);
- glClearColor(0.0, 0.0, 0.0, 0); // Black Clearing YWB
- glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- //
- // set up viewpoint
- //
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity ();
-
- screenaspect = (float)width/height;
- yfov = 2*atan((float)height/width)*180/M_PI;
- gluPerspective (yfov, screenaspect, 6, 20000);
-
- glRotatef (-90, 1, 0, 0); // put Z going up
- glRotatef (90, 0, 0, 1); // put Z going up
- glRotatef (angles[0], 0, 1, 0);
- glRotatef (-angles[1], 0, 0, 1);
- glTranslatef (-origin[0], -origin[1], -origin[2]);
-
- Cam_BuildMatrix ();
-
- //
- // set drawing parms
- //
- glShadeModel (GL_SMOOTH);
-
- glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
- glFrontFace(GL_CW); // YWB Carmack goes backward
- glCullFace(GL_BACK); // Cull backfaces (qcsg used to spit out two sides, doesn't for -glview now)
- glEnable(GL_CULL_FACE); // Enable face culling, just in case...
- glDisable(GL_TEXTURE_2D);
-
- // Blending function if enabled..
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- if (g_UseBlending)
- {
- glEnable(GL_BLEND);// YWB TESTING
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_CULL_FACE); // Enable face culling, just in case...
- }
- else
- {
- glDisable(GL_BLEND);
- glEnable(GL_DEPTH_TEST);
- }
- glDepthFunc (GL_LEQUAL);
-
- if( g_bDisp )
- {
- DrawDisplacementData();
- }
- else
- {
- //
- // draw the list
- //
- if (g_bShowList1)
- glCallList (1);
-
- if (g_bReadPortals)
- {
- if (g_bNoDepthPortals)
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_CULL_FACE); // Disable face culling
- if (g_bShowList2)
- glCallList(2);
- };
-
- if (g_bShowLines)
- glCallList(3);
- }
-}
-
-void ReadPolyFileType(const char *name, int nList, BOOL drawLines)
-{
- FILE *f;
- int i, j, numverts;
- float v[8];
- int c;
- int r;
- float divisor;
-
- f = fopen (name, "rt");
- if (!f)
- Error ("Couldn't open %s", name);
-
- if (g_bReadPortals)
- divisor = 2.0f;
- else
- divisor = 1.0f;
-
- c = 0;
- glNewList (nList, GL_COMPILE);
-
- for (i = 0; i < 3; i++) // Find the center point so we can put the viewer there by default
- g_Center[i] = 0.0f;
-
- if (drawLines) // Slight hilite
- glLineWidth(1.5);
-
- while (1)
- {
- r = fscanf( f, "%i\n", &numverts);
- if (!r || r == EOF)
- break;
-
- if ( c > 65534*8)
- break;
-
- if (drawLines || numverts == 2)
- glBegin(GL_LINE_LOOP);
- else
- glBegin (GL_POLYGON);
-
- for (i=0 ; i<numverts ; i++)
- {
- r = fscanf( f, "%f %f %f %f %f %f\n", &v[0], &v[1],
- &v[2], &v[3], &v[4], &v[5]);
-
- /*
- if (!(fabs( v[0] ) < 32768.0&& fabs( v[1] ) < 32768.0 && fabs( v[2] ) < 32768.0 ) )
- Error( "Out of range data\n");
- */
-
- /*
- if (v[3] <= 0.1 && v[4] <= 0.1 && v[5] <= 0.1 )
- continue;
- */
-
- if (drawLines) // YELLOW OUTLINES
- glColor4f(1.0, 1.0, 0.0, 0.5);
- else
- {
- if (g_bReadPortals) // Gray scale it, leave portals blue
- {
- if (fabs(fabs(v[5]) - 1.0f) < 0.01) // Is this a detail brush (color 0,0,1 blue)
- {
- glColor4f (v[3],v[4],v[5],0.5);
- }
- else // Normal brush, gray scale it...
- {
- v[3] += v[4] + v[5];
- v[3]/= 3.0f;
- glColor4f (v[3]/divisor, v[3]/divisor, v[3]/divisor, 0.6);
- }
- }
- else
- {
- v[3] = pow( v[3], (float)(1.0 / 2.2) );
- v[4] = pow( v[4], (float)(1.0 / 2.2) );
- v[5] = pow( v[5], (float)(1.0 / 2.2) );
-
- glColor4f (v[3]/divisor, v[4]/divisor, v[5]/divisor, 0.6); // divisor is one, bright colors
- };
- };
- glVertex3f (v[0], v[1], v[2]);
-
- for (j = 0; j < 3; j++)
- {
- g_Center[j] += v[j];
- }
-
- g_nTotalPoints++;
- }
- glEnd ();
- c++;
- }
-
- if (f)
- fclose(f);
-
- glEndList ();
-
- if (g_nTotalPoints > 0) // Avoid division by zero
- {
- for (i = 0; i < 3; i++)
- {
- g_Center[i] = g_Center[i]/(float)g_nTotalPoints; // Calculate center...
- origin[i] = g_Center[i];
- }
- }
-}
-
-#if BENCHMARK_PHY
-#define NUM_COLLISION_TESTS 2500
-#include "gametrace.h"
-#include "fmtstr.h"
-
-
-struct testlist_t
-{
- Vector start;
- Vector end;
- Vector normal;
- bool hit;
-};
-
-const float baselineTotal = 120.16f;
-const float baselineRay = 28.25f;
-const float baselineBox = 91.91f;
-#define IMPROVEMENT_FACTOR(x,baseline) (baseline/(x))
-#define IMPROVEMENT_PERCENT(x,baseline) (((baseline-(x)) / baseline) * 100.0f)
-
-testlist_t g_Traces[NUM_COLLISION_TESTS];
-void Benchmark_PHY( const CPhysCollide *pCollide )
-{
- int i;
- Msg( "Testing collision system\n" );
- Vector start = vec3_origin;
- static Vector *targets = NULL;
- static bool first = true;
- static float test[2] = {1,1};
- if ( first )
- {
- float radius = 0;
- float theta = 0;
- float phi = 0;
- for ( int i = 0; i < NUM_COLLISION_TESTS; i++ )
- {
- radius += NUM_COLLISION_TESTS * 123.123f;
- radius = fabs(fmod(radius, 128));
- theta += NUM_COLLISION_TESTS * 0.76f;
- theta = fabs(fmod(theta, DEG2RAD(360)));
- phi += NUM_COLLISION_TESTS * 0.16666666f;
- phi = fabs(fmod(phi, DEG2RAD(180)));
-
- float st, ct, sp, cp;
- SinCos( theta, &st, &ct );
- SinCos( phi, &sp, &cp );
- st = sin(theta);
- ct = cos(theta);
- sp = sin(phi);
- cp = cos(phi);
-
- g_Traces[i].start.x = radius * ct * sp;
- g_Traces[i].start.y = radius * st * sp;
- g_Traces[i].start.z = radius * cp;
- }
- first = false;
- }
-
- float duration = 0;
- Vector size[2];
- size[0].Init(0,0,0);
- size[1].Init(16,16,16);
- unsigned int dots = 0;
-
-#if VPROF_LEVEL > 0
- g_VProfCurrentProfile.Reset();
- g_VProfCurrentProfile.ResetPeaks();
- g_VProfCurrentProfile.Start();
-#endif
- unsigned int hitCount = 0;
- double startTime = Plat_FloatTime();
- trace_t tr;
- for ( i = 0; i < NUM_COLLISION_TESTS; i++ )
- {
- physcollision->TraceBox( g_Traces[i].start, start, -size[0], size[0], pCollide, vec3_origin, vec3_angle, &tr );
- if ( tr.DidHit() )
- {
- g_Traces[i].end = tr.endpos;
- g_Traces[i].normal = tr.plane.normal;
- g_Traces[i].hit = true;
- hitCount++;
- }
- else
- {
- g_Traces[i].hit = false;
- }
- }
- for ( i = 0; i < NUM_COLLISION_TESTS; i++ )
- {
- physcollision->TraceBox( g_Traces[i].start, start, -size[1], size[1], pCollide, vec3_origin, vec3_angle, &tr );
- }
- duration = Plat_FloatTime() - startTime;
- {
- unsigned int msSupp = physcollision->ReadStat( 100 );
- unsigned int msGJK = physcollision->ReadStat( 101 );
- unsigned int msMesh = physcollision->ReadStat( 102 );
- CFmtStr str("%d ms total %d ms gjk %d mesh solve\n", msSupp, msGJK, msMesh );
- OutputDebugStr( str.Access() );
- }
-
-#if VPROF_LEVEL > 0
- g_VProfCurrentProfile.MarkFrame();
- g_VProfCurrentProfile.Stop();
- g_VProfCurrentProfile.Reset();
- g_VProfCurrentProfile.ResetPeaks();
- g_VProfCurrentProfile.Start();
-#endif
- hitCount = 0;
- startTime = Plat_FloatTime();
- for ( i = 0; i < NUM_COLLISION_TESTS; i++ )
- {
- physcollision->TraceBox( g_Traces[i].start, start, -size[0], size[0], pCollide, vec3_origin, vec3_angle, &tr );
- if ( tr.DidHit() )
- {
- g_Traces[i].end = tr.endpos;
- g_Traces[i].normal = tr.plane.normal;
- g_Traces[i].hit = true;
- hitCount++;
- }
- else
- {
- g_Traces[i].hit = false;
- }
-#if VPROF_LEVEL > 0
- g_VProfCurrentProfile.MarkFrame();
-#endif
- }
- double midTime = Plat_FloatTime();
- for ( i = 0; i < NUM_COLLISION_TESTS; i++ )
- {
- physcollision->TraceBox( g_Traces[i].start, start, -size[1], size[1], pCollide, vec3_origin, vec3_angle, &tr );
-#if VPROF_LEVEL > 0
- g_VProfCurrentProfile.MarkFrame();
-#endif
- }
- double endTime = Plat_FloatTime();
- duration = endTime - startTime;
- {
- CFmtStr str("%d collisions in %.2f ms [%.2f X] %d hits\n", NUM_COLLISION_TESTS, duration*1000, IMPROVEMENT_FACTOR(duration*1000.0f, baselineTotal), hitCount );
- OutputDebugStr( str.Access() );
- }
- {
- float rayTime = (midTime - startTime) * 1000.0f;
- float boxTime = (endTime - midTime)*1000.0f;
- CFmtStr str("%.2f ms rays [%.2f X] %.2f ms boxes [%.2f X]\n", rayTime, IMPROVEMENT_FACTOR(rayTime, baselineRay), boxTime, IMPROVEMENT_FACTOR(boxTime, baselineBox));
- OutputDebugStr( str.Access() );
- }
-
- {
- unsigned int msSupp = physcollision->ReadStat( 100 );
- unsigned int msGJK = physcollision->ReadStat( 101 );
- unsigned int msMesh = physcollision->ReadStat( 102 );
- CFmtStr str("%d ms total %d ms gjk %d mesh solve\n", msSupp, msGJK, msMesh );
- OutputDebugStr( str.Access() );
- }
-#if VPROF_LEVEL > 0
- g_VProfCurrentProfile.Stop();
- g_VProfCurrentProfile.OutputReport( VPRT_FULL & ~VPRT_HIERARCHY, NULL );
-#endif
-
- // draw the traces in yellow
- glColor3f( 1.0f, 1.0f, 0.0f );
- glBegin( GL_LINES );
- for ( int i = 0; i < NUM_COLLISION_TESTS; i++ )
- {
- if ( !g_Traces[i].hit )
- continue;
- glVertex3fv( g_Traces[i].end.Base() );
- Vector tmp = g_Traces[i].end + g_Traces[i].normal * 10.0f;
- glVertex3fv( tmp.Base() );
- }
- glEnd();
-}
-#endif
-
-struct phyviewparams_t
-{
- Vector mins;
- Vector maxs;
- Vector offset;
- QAngle angles;
- int outputType;
-
- void Defaults()
- {
- ClearBounds(mins, maxs);
- offset.Init();
- outputType = GL_POLYGON;
- angles.Init();
- }
-};
-
-
-void AddVCollideToList( phyheader_t &header, vcollide_t &collide, phyviewparams_t ¶ms )
-{
- matrix3x4_t xform;
- AngleMatrix( params.angles, params.offset, xform );
- ClearBounds( params.mins, params.maxs );
- for ( int i = 0; i < header.solidCount; i++ )
- {
- ICollisionQuery *pQuery = physcollision->CreateQueryModel( collide.solids[i] );
- for ( int j = 0; j < pQuery->ConvexCount(); j++ )
- {
- for ( int k = 0; k < pQuery->TriangleCount(j); k++ )
- {
- Vector verts[3];
- pQuery->GetTriangleVerts( j, k, verts );
- Vector v0,v1,v2;
- VectorTransform( verts[0], xform, v0 );
- VectorTransform( verts[1], xform, v1 );
- VectorTransform( verts[2], xform, v2 );
- AddPointToBounds( v0, params.mins, params.maxs );
- AddPointToBounds( v1, params.mins, params.maxs );
- AddPointToBounds( v2, params.mins, params.maxs );
-
- glBegin(params.outputType);
- glColor3ub( 255, 0, 0 );
- glVertex3fv( v0.Base() );
- glColor3ub( 0, 255, 0 );
- glVertex3fv( v1.Base() );
- glColor3ub( 0, 0, 255 );
- glVertex3fv( v2.Base() );
- glEnd();
- }
- }
- physcollision->DestroyQueryModel( pQuery );
- }
-}
-
-void GL_DrawLine( const Vector &start, const Vector &dir, float length, int r, int g, int b )
-{
- Vector end = start + (dir*length);
- glBegin( GL_LINES );
- glColor3ub(r,g,b);
- glVertex3fv( start.Base() );
- glVertex3fv( end.Base() );
- glEnd();
-}
-
-void GL_DrawBox( Vector origin, float size, int r, int g, int b )
-{
- Vector mins = origin - Vector(size,size,size);
- Vector maxs = origin + Vector(size,size,size);
- const float *v[2] = {mins.Base(), maxs.Base()};
-
- Vector start, end;
- {
- for ( int i = 0; i < 3; i++ )
- {
- int a0 = i;
- int a1 = (i+1)%3;
- int a2 = (i+2)%3;
- for ( int j = 0; j < 2; j++ )
- {
- for ( int k = 0; k < 2; k++ )
- {
- start[a0] = v[0][a0];
- end[a0] = v[1][a0];
- start[a1] = v[j][a1];
- end[a1] = v[j][a1];
- start[a2] = v[k][a2];
- end[a2] = v[k][a2];
- GL_DrawLine( start, end-start, 1, r, g, b );
- }
- }
- }
- }
- for ( int axis = 0; axis < 3; axis++ )
- {
- int a0 = axis;
- int a1 = (axis+1)%3;
- int a2 = (axis+2)%3;
- start[a0] = v[0][a0];
- end[a0] = v[1][a0];
- start[a1] = 0.5f *(v[0][a1]+v[1][a1]);
- end[a1] = 0.5f *(v[0][a1]+v[1][a1]);
- start[a2] = 0.5f *(v[0][a2]+v[1][a2]);
- end[a2] = 0.5f *(v[0][a2]+v[1][a2]);
- GL_DrawLine( start, end-start, 1, r, g, b );
- }
-}
-
-
-void ReadPHYFile(const char *name, phyviewparams_t ¶ms )
-{
- FILE *fp = fopen (name, "rb");
- if (!fp)
- Error ("Couldn't open %s", name);
-
- phyheader_t header;
-
- fread( &header, sizeof(header), 1, fp );
- if ( header.size != sizeof(header) || header.solidCount <= 0 )
- return;
-
- int pos = ftell( fp );
- fseek( fp, 0, SEEK_END );
- int fileSize = ftell(fp) - pos;
- fseek( fp, pos, SEEK_SET );
-
- char *buf = (char *)_alloca( fileSize );
- fread( buf, fileSize, 1, fp );
- fclose( fp );
-
- vcollide_t collide;
- physcollision->VCollideLoad( &collide, header.solidCount, (const char *)buf, fileSize );
-#if 0
- Vector start0( -3859.1199, -2050.8674, 64.031250 );
- Vector end0(-3859.2246, -2051.2817, 64.031250 );
- Vector modelPosition(-3840,-2068.0000, 82.889099);
- QAngle modelAngles(0,90,0);
-
- {
- Ray_t ray;
- ray.Init( start0, end0, Vector(-16,-16,0), Vector(16,16,72));
- trace_t tr;
- physcollision->TraceBox( ray, collide.solids[0], modelPosition, modelAngles, &tr );
- Assert(!tr.startsolid);
- if ( tr.DidHit() )
- {
- Ray_t ray2;
- ray2.Init( tr.endpos, tr.endpos, Vector(-16,-16,0), Vector(16,16,72));
- trace_t tr2;
- physcollision->TraceBox( ray2, collide.solids[0], modelPosition, modelAngles, &tr2 );
- Assert(!tr2.startsolid);
- }
- }
-#endif
-#if BENCHMARK_PHY
- Benchmark_PHY( collide.solids[0] );
-#endif
- AddVCollideToList( header, collide, params );
-}
-
-void ReadPolyFile (const char *name)
-{
- char ext[4];
- Q_ExtractFileExtension( name, ext, 4 );
-
- bool isPHY = !Q_stricmp( ext, "phy" );
- if ( isPHY )
- {
- CreateInterfaceFn physicsFactory = GetPhysicsFactory();
- physcollision = (IPhysicsCollision *)physicsFactory( VPHYSICS_COLLISION_INTERFACE_VERSION, NULL );
- if ( physcollision )
- {
- phyviewparams_t params;
- params.Defaults();
- glNewList (1, GL_COMPILE);
- ReadPHYFile( name, params );
- Vector tmp = (params.mins + params.maxs) * 0.5;
- tmp.CopyToArray(origin);
- glEndList ();
- }
- }
- else
- {
- // Read in polys...
- ReadPolyFileType(name, 1, false);
-
- // Make list 3 just the lines... so we can draw outlines
- ReadPolyFileType(name, 3, true);
- }
-}
-
-void ReadPortalFile (char *name)
-{
- FILE *f;
- int i, numverts;
- float v[8];
- int c;
- int r;
-
- // For Portal type reading...
- char szDummy[80];
- int nNumLeafs;
- int nNumPortals;
- int nLeafIndex[2];
-
- f = fopen (name, "r");
- if (!f)
- Error ("Couldn't open %s", name);
-
- c = 0;
-
- glNewList (2, GL_COMPILE);
-
- // Read in header
- fscanf(f, "%79s\n", szDummy);
- fscanf(f, "%i\n", &nNumLeafs);
- fscanf(f, "%i\n", &nNumPortals);
-
- glLineWidth(1.5);
-
- while (1)
- {
- r = fscanf(f, "%i %i %i ", &numverts, &nLeafIndex[0], &nLeafIndex[1]);
- if (!r || r == EOF)
- break;
-
- glBegin(GL_LINE_LOOP);
- for (i=0 ; i<numverts ; i++)
- {
- r = fscanf (f, "(%f %f %f )\n", &v[0], &v[1],
- &v[2]);
- if (!r || (r != 3) || r == EOF)
- break;
-
- if ( c == g_nPortalHighlight || nLeafIndex[0] == g_nLeafHighlight || nLeafIndex[1] == g_nLeafHighlight )
- {
- glColor4f (1.0, 0.0, 0.0, 1.0);
- }
- else
- {
- glColor4f (1.0f, 1.0f, 1.0f, 1.0f); // WHITE portals
- }
- glVertex3f (v[0], v[1], v[2]);
- }
-
- glEnd ();
- c++;
- }
-
- if (f)
- fclose(f);
-
- glEndList ();
-}
-
-#define MAX_DISP_COUNT 4096
-static Vector dispPoints[MAX_DISP_COUNT];
-static Vector dispNormals[MAX_DISP_COUNT];
-static int dispPointCount = 0;
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-BOOL ReadDisplacementFile( const char *filename )
-{
- FILE *pFile;
- int fileCount;
-
- //
- // open the file
- //
- pFile = fopen( filename, "r" );
- if( !pFile )
- Error( "Couldn't open %s", filename );
-
- //
- // read data in file
- //
- while( 1 )
- {
- // overflow test
- if( dispPointCount >= MAX_DISP_COUNT )
- break;
-
- fileCount = fscanf( pFile, "%f %f %f %f %f %f",
- &dispPoints[dispPointCount][0], &dispPoints[dispPointCount][1], &dispPoints[dispPointCount][2],
- &dispNormals[dispPointCount][0], &dispNormals[dispPointCount][1], &dispNormals[dispPointCount][2] );
- dispPointCount++;
-
- // end of file check
- if( !fileCount || ( fileCount == EOF ) )
- break;
- }
-
- fclose( pFile );
-
- return TRUE;
-}
-
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-void DrawDisplacementData( void )
-{
- int i, j;
- int width, halfCount;
-
- GLUquadricObj *pObject = gluNewQuadric();
-
- glEnable( GL_DEPTH_TEST );
-
- for( i = 0; i < dispPointCount; i++ )
- {
- // draw a sphere where the point is (in red)
- glColor3f( 1.0f, 0.0f, 0.0f );
- glPushMatrix();
- glTranslatef( dispPoints[i][0], dispPoints[i][1], dispPoints[i][2] );
- gluSphere( pObject, 5, 5, 5 );
- glPopMatrix();
-
- // draw the normal (in yellow)
- glColor3f( 1.0f, 1.0f, 0.0f );
- glBegin( GL_LINES );
- glVertex3f( dispPoints[i][0], dispPoints[i][1], dispPoints[i][2] );
- glVertex3f( dispPoints[i][0] + ( dispNormals[i][0] * 50.0f ), dispPoints[i][1] + ( dispNormals[i][1] * 50.0f ), dispPoints[i][2] + ( dispNormals[i][2] * 50.0f ) );
- glEnd();
- }
-
- halfCount = dispPointCount / 2;
-
- width = sqrt( (float)halfCount );
-
- glDisable( GL_CULL_FACE );
-
- glColor3f( 0.0f, 0.0f, 1.0f );
- for( i = 0; i < width - 1; i++ )
- {
- for( j = 0; j < width - 1; j++ )
- {
- glBegin( GL_POLYGON );
- glVertex3f( dispPoints[i*width+j][0], dispPoints[i*width+j][1], dispPoints[i*width+j][2] );
- glVertex3f( dispPoints[(i+1)*width+j][0], dispPoints[(i+1)*width+j][1], dispPoints[(i+1)*width+j][2] );
- glVertex3f( dispPoints[(i+1)*width+(j+1)][0], dispPoints[(i+1)*width+(j+1)][1], dispPoints[(i+1)*width+(j+1)][2] );
- glVertex3f( dispPoints[i*width+(j+1)][0], dispPoints[i*width+(j+1)][1], dispPoints[i*width+(j+1)][2] );
- glEnd();
- }
- }
-
-#if 0
- for( i = 0; i < width - 1; i++ )
- {
- for( j = 0; j < width - 1; j++ )
- {
- glBegin( GL_POLYGON );
- glVertex3f( dispPoints[halfCount+(i*width+j)][0], dispPoints[halfCount+(i*width+j)][1], dispPoints[halfCount+(i*width+j)][2] );
- glVertex3f( dispPoints[halfCount+((i+1)*width+j)][0], dispPoints[halfCount+(i+1)*width+j][1], dispPoints[halfCount+((i+1)*width+j)][2] );
- glVertex3f( dispPoints[halfCount+((i+1)*width+(j+1))][0], dispPoints[halfCount+(i+1)*width+(j+1)][1], dispPoints[halfCount+((i+1)*width+(j+1))][2] );
- glVertex3f( dispPoints[halfCount+(i*width+(j+1))][0], dispPoints[halfCount+(i*width+(j+1))][1], dispPoints[halfCount+(i*width+(j+1))][2] );
- glEnd();
- }
- }
-#endif
-
- glColor3f( 0.0f, 1.0f, 0.0f );
- for( i = 0; i < width - 1; i++ )
- {
- for( j = 0; j < width - 1; j++ )
- {
- glBegin( GL_POLYGON );
- glVertex3f( dispPoints[i*width+j][0] + ( dispNormals[i*width+j][0] * 150.0f ),
- dispPoints[i*width+j][1] + ( dispNormals[i*width+j][1] * 150.0f ),
- dispPoints[i*width+j][2] + ( dispNormals[i*width+j][2] * 150.0f ) );
-
- glVertex3f( dispPoints[(i+1)*width+j][0] + ( dispNormals[(i+1)*width+j][0] * 150.0f ),
- dispPoints[(i+1)*width+j][1] + ( dispNormals[(i+1)*width+j][1] * 150.0f ),
- dispPoints[(i+1)*width+j][2] + ( dispNormals[(i+1)*width+j][2] * 150.0f ) );
-
- glVertex3f( dispPoints[(i+1)*width+(j+1)][0] + ( dispNormals[(i+1)*width+(j+1)][0] * 150.0f ),
- dispPoints[(i+1)*width+(j+1)][1] + ( dispNormals[(i+1)*width+(j+1)][1] * 150.0f ),
- dispPoints[(i+1)*width+(j+1)][2] + ( dispNormals[(i+1)*width+(j+1)][2] * 150.0f ) );
-
- glVertex3f( dispPoints[i*width+(j+1)][0] + ( dispNormals[i*width+(j+1)][0] * 150.0f ),
- dispPoints[i*width+(j+1)][1] + ( dispNormals[i*width+(j+1)][1] * 150.0f ),
- dispPoints[i*width+(j+1)][2] + ( dispNormals[i*width+(j+1)][2] * 150.0f ) );
- glEnd();
- }
- }
-
- glDisable( GL_DEPTH_TEST );
-
- glColor3f( 0.0f, 0.0f, 1.0f );
- for( i = 0; i < width - 1; i++ )
- {
- for( j = 0; j < width - 1; j++ )
- {
- glBegin( GL_LINE_LOOP );
- glVertex3f( dispPoints[i*width+j][0] + ( dispNormals[i*width+j][0] * 150.0f ),
- dispPoints[i*width+j][1] + ( dispNormals[i*width+j][1] * 150.0f ),
- dispPoints[i*width+j][2] + ( dispNormals[i*width+j][2] * 150.0f ) );
-
- glVertex3f( dispPoints[(i+1)*width+j][0] + ( dispNormals[(i+1)*width+j][0] * 150.0f ),
- dispPoints[(i+1)*width+j][1] + ( dispNormals[(i+1)*width+j][1] * 150.0f ),
- dispPoints[(i+1)*width+j][2] + ( dispNormals[(i+1)*width+j][2] * 150.0f ) );
-
- glVertex3f( dispPoints[(i+1)*width+(j+1)][0] + ( dispNormals[(i+1)*width+(j+1)][0] * 150.0f ),
- dispPoints[(i+1)*width+(j+1)][1] + ( dispNormals[(i+1)*width+(j+1)][1] * 150.0f ),
- dispPoints[(i+1)*width+(j+1)][2] + ( dispNormals[(i+1)*width+(j+1)][2] * 150.0f ) );
-
- glVertex3f( dispPoints[i*width+(j+1)][0] + ( dispNormals[i*width+(j+1)][0] * 150.0f ),
- dispPoints[i*width+(j+1)][1] + ( dispNormals[i*width+(j+1)][1] * 150.0f ),
- dispPoints[i*width+(j+1)][2] + ( dispNormals[i*width+(j+1)][2] * 150.0f ) );
- glEnd();
- }
- }
-
-
- gluDeleteQuadric( pObject );
-}
-
-
-//=====================================================================
-
-BOOL bSetupPixelFormat(HDC hDC)
-{
- static PIXELFORMATDESCRIPTOR pfd = {
- sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
- 1, // version number
- PFD_DRAW_TO_WINDOW | // support window
- PFD_SUPPORT_OPENGL | // support OpenGL
- PFD_DOUBLEBUFFER, // double buffered
- PFD_TYPE_RGBA, // RGBA type
- 24, // 24-bit color depth
- 0, 0, 0, 0, 0, 0, // color bits ignored
- 0, // no alpha buffer
- 0, // shift bit ignored
- 0, // no accumulation buffer
- 0, 0, 0, 0, // accum bits ignored
- 32, // 32-bit z-buffer
- 0, // no stencil buffer
- 0, // no auxiliary buffer
- PFD_MAIN_PLANE, // main layer
- 0, // reserved
- 0, 0, 0 // layer masks ignored
- };
-
- int pixelformat = 0;
-
- if ( (pixelformat = ChoosePixelFormat(hDC, &pfd)) == 0 )
- Error ("ChoosePixelFormat failed");
-
- if (!SetPixelFormat(hDC, pixelformat, &pfd))
- Error ("SetPixelFormat failed");
-
- return TRUE;
-}
-
-/*
-============
-CameraWndProc
-============
-*/
-LONG WINAPI WCam_WndProc (
- HWND hWnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam)
-{
- LONG lRet = 1;
- RECT rect;
-
- GetClientRect(hWnd, &rect);
-
- switch (uMsg)
- {
- case WM_CREATE:
- {
- camdc = GetDC(hWnd);
- bSetupPixelFormat(camdc);
-
- baseRC = wglCreateContext( camdc );
- if (!baseRC)
- Error ("wglCreateContext failed");
- if (!wglMakeCurrent( camdc, baseRC ))
- Error ("wglMakeCurrent failed");
- glCullFace(GL_FRONT);
- glEnable(GL_CULL_FACE);
- }
- break;
- case WM_PAINT:
- {
- PAINTSTRUCT ps;
-
- BeginPaint(hWnd, &ps);
- if (!wglMakeCurrent( camdc, baseRC ))
- Error ("wglMakeCurrent failed");
- Draw ();
- SwapBuffers(camdc);
- EndPaint(hWnd, &ps);
- }
- break;
-
- case WM_KEYDOWN:
- KeyDown (wParam);
- AppKeyDown( wParam );
- break;
-
- case WM_KEYUP:
- AppKeyUp( wParam );
- break;
-
- case WM_MBUTTONDOWN:
- case WM_RBUTTONDOWN:
- case WM_LBUTTONDOWN:
- SetCapture (camerawindow);
- ShowCursor( FALSE );
- g_Capture = TRUE;
- break;
-
- case WM_MBUTTONUP:
- case WM_RBUTTONUP:
- case WM_LBUTTONUP:
- if (! (wParam & (MK_LBUTTON|MK_RBUTTON|MK_MBUTTON)))
- {
- g_Capture = FALSE;
- ReleaseCapture ();
- ShowCursor( TRUE );
- }
- break;
-
- case WM_SIZE:
- InvalidateRect(camerawindow, NULL, false);
- break;
- case WM_NCCALCSIZE:// don't let windows copy pixels
- lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
- return WVR_REDRAW;
- case WM_CLOSE:
- /* call destroy window to cleanup and go away */
- DestroyWindow (hWnd);
- break;
-
- case WM_DESTROY:
- {
- HGLRC hRC;
- HDC hDC;
-
- /* release and free the device context and rendering context */
- hRC = wglGetCurrentContext();
- hDC = wglGetCurrentDC();
-
- wglMakeCurrent(NULL, NULL);
-
- if (hRC)
- wglDeleteContext(hRC);
- if (hDC)
- ReleaseDC(hWnd, hDC);
-
- PostQuitMessage (0);
- }
- break;
-
- default:
- /* pass all unhandled messages to DefWindowProc */
- lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
- break;
- }
-
- /* return 1 if handled message, 0 if not */
- return lRet;
-}
-
-
-/*
-==============
-WCam_Register
-==============
-*/
-void WCam_Register (HINSTANCE hInstance)
-{
- WNDCLASS wc;
-
- /* Register the camera class */
- memset (&wc, 0, sizeof(wc));
-
- wc.style = 0;
- wc.lpfnWndProc = (WNDPROC)WCam_WndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = hInstance;
- wc.hIcon = 0;
- wc.hCursor = LoadCursor (NULL,IDC_ARROW);
- wc.hbrBackground = NULL;
- wc.lpszMenuName = 0;
- wc.lpszClassName = "camera";
-
- if (!RegisterClass (&wc) )
- Error ("WCam_Register: failed");
-}
-
-
-void WCam_Create (HINSTANCE hInstance)
-{
- // Center it
- int nScx, nScy;
- int w, h;
- int x, y;
-
- WCam_Register (hInstance);
-
- w = ::width;
- h = ::height;
-
- nScx = GetSystemMetrics(SM_CXSCREEN);
- nScy = GetSystemMetrics(SM_CYSCREEN);
-
-
- x = (nScx - w)/2;
- y = (nScy - h)/2;
-
- camerawindow = CreateWindow ("camera" ,
- "Camera View",
- WS_OVERLAPPED |
- WS_CAPTION |
- WS_SYSMENU |
- WS_THICKFRAME |
- WS_MAXIMIZEBOX |
- WS_CLIPSIBLINGS |
- WS_CLIPCHILDREN,
-
- x,
- y,
- w,
- h, // size
-
- NULL, // parent window
- 0, // no menu
- hInstance,
- 0);
- if (!camerawindow)
- Error ("Couldn't create camerawindow");
-
- ShowWindow (camerawindow, SW_SHOWDEFAULT);
-}
-
-
-void AppKeyDown( int key )
-{
- key &= 0xFF;
-
- g_Keys[key] = 0x03; // add debounce bit
-}
-
-void AppKeyUp( int key )
-{
- key &= 0xFF;
-
- g_Keys[key] &= 0x02;
-}
-
-void AppRender( void )
-{
- static double lastTime = 0;
- double time = timeGetTime() * 0.001f;
- double frametime = time - lastTime;
-
- // clamp too large frames (like first frame)
- if ( frametime > 0.2 )
- frametime = 0.2;
- lastTime = time;
-
- if (!wglMakeCurrent( camdc, baseRC ))
- Error ("wglMakeCurrent failed");
-
- Cam_Update( frametime );
-
- if (g_Update)
- {
- Draw ();
- SwapBuffers(camdc);
- g_Update = FALSE;
- }
- else
- {
- Sleep( 1.0 );
- }
-}
-
-SpewRetval_t Sys_SpewFunc( SpewType_t type, const char *pMsg )
-{
- OutputDebugString( pMsg );
- if( type == SPEW_ASSERT )
- return SPEW_DEBUGGER;
- else if( type == SPEW_ERROR )
- return SPEW_ABORT;
- else
- return SPEW_CONTINUE;
-}
-
-
-/*
-==================
-WinMain
-
-==================
-*/
-int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance
- ,LPSTR lpCmdLine, int nCmdShow)
-{
- CommandLine()->CreateCmdLine( Plat_GetCommandLine() );
-
- MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f );
- MSG msg;
-
- if (!lpCmdLine || !lpCmdLine[0])
- Error ("No file specified");
-
- main_instance = hInstance;
-
- WCam_Create (hInstance);
-
- // Last argument is the file name
- const char *pFileName = CommandLine()->GetParm( CommandLine()->ParmCount() - 1 );
- CmdLib_InitFileSystem( pFileName );
-
- if ( CommandLine()->CheckParm( "-portal") )
- {
- g_bReadPortals = 1;
- g_nPortalHighlight = CommandLine()->ParmValue( "-portalhighlight", -1 );
- g_nLeafHighlight = CommandLine()->ParmValue( "-leafhighlight", -1 );
- }
- g_flMovementSpeed = CommandLine()->ParmValue( "-speed", 320 );
-
- if( CommandLine()->CheckParm( "-disp") )
- {
- ReadDisplacementFile( pFileName );
- g_bDisp = TRUE;
- }
- SpewOutputFunc( Sys_SpewFunc );
-
- // Any chunk of original left is the filename.
- if (pFileName && pFileName[0] && !g_bDisp )
- {
- ReadPolyFile( pFileName );
- }
-
- if (g_bReadPortals)
- {
- // Copy file again and this time look for the . from .gl? so we can concatenate .prt
- // and open the portal file.
- char szTempCmd[MAX_PATH];
- strcpy(szTempCmd, pFileName);
- char *pTmp = szTempCmd;
- while (pTmp && *pTmp && *pTmp != '.')
- {
- pTmp++;
- }
-
- *pTmp = '\0';
- strcat(szTempCmd, ".prt");
-
- ReadPortalFile(szTempCmd);
- };
-
- /* main window message loop */
- while (g_Active)
- {
- while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
- {
- TranslateMessage (&msg);
- DispatchMessage (&msg);
- }
- AppRender();
- }
-
- /* return success of application */
- return TRUE;
-}
-
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +#include "glos.h" +#include <gl/gl.h> +#if _MSC_VER < 1600 +#include <gl/glaux.h> +#endif +#include <gl/glu.h> +#include <stdarg.h> +#include <string.h> +#include <stdio.h> +#include <math.h> +#include "cmdlib.h" +#include "mathlib/mathlib.h" +#include "cmodel.h" +#include "tier1/strtools.h" +#include "physdll.h" +#include "phyfile.h" +#include "vphysics_interface.h" +#include "tier0/icommandline.h" +#include "tier0/vprof.h" + +HDC camdc; +HGLRC baseRC; +HWND camerawindow; +HANDLE main_instance; + +/* YWB: 3/13/98 + You run the program like normal with any file. If you want to read portals for the + file type, you type: glview -portal filename.gl0 (or whatever). glview will then + try to read in the .prt file filename.prt. + + The portals are shown as white lines superimposed over your image. You can toggle the + view between showing portals or not by hitting the '2' key. The '1' key toggles + world polygons. + + The 'b' key toggles blending modes. + + If you don't want to depth buffer the portals, hit 'p'. + + The command line parsing is inelegant but functional. + + I sped up the KB movement and turn speed, too. + */ + +// Vars added by YWB +Vector g_Center; // Center of all read points, so camera is in a sensible place +int g_nTotalPoints = 0; // Total points read, for calculating center +int g_UseBlending = 0; // Toggle to use blending mode or not +BOOL g_bReadPortals = 0; // Did we read in a portal file? +BOOL g_bNoDepthPortals = 0; // Do we zbuffer the lines of the portals? +int g_nPortalHighlight = -1; // The leaf we're viewing +int g_nLeafHighlight = -1; // The leaf we're viewing +BOOL g_bShowList1 = 1; // Show regular polygons? +BOOL g_bShowList2 = 1; // Show portals? +BOOL g_bShowLines = 0; // Show outlines of faces +BOOL g_Active = TRUE; +BOOL g_Update = TRUE; +BOOL g_bDisp = FALSE; +IPhysicsCollision *physcollision = NULL; +// ----------- +static int g_Keys[255]; +void AppKeyDown( int key ); +void AppKeyUp( int key ); + + +BOOL ReadDisplacementFile( const char *filename ); +void DrawDisplacementData( void ); + +#define BENCHMARK_PHY 0 + +/* +================= +Error + +For abnormal program terminations +================= +*/ +void Error (char *error, ...) +{ + va_list argptr; + char text[1024]; + + va_start (argptr,error); + vsprintf (text, error,argptr); + va_end (argptr); + + MessageBox(NULL, text, "Error", 0 /* MB_OK */ ); + + exit (1); +} + +float origin[3] = {32, 32, 48}; +float angles[3]; +float forward[3], right[3], vup[3], vpn[3], vright[3]; +float width = 1024; +float height = 768; + +float g_flMovementSpeed = 320.f; // Units / second (run speed of HL) +#define SPEED_TURN 90 // Degrees / second + +#define VK_COMMA 188 +#define VK_PERIOD 190 + + +void KeyDown (int key) +{ + switch (key) + { + case VK_ESCAPE: + g_Active = FALSE; + break; + + case VK_F1: + glEnable (GL_CULL_FACE); + glCullFace (GL_FRONT); + break; + case 'B': + g_UseBlending ^= 1; + if (g_UseBlending) + glEnable(GL_BLEND);// YWB TESTING + else + glDisable(GL_BLEND); + break; + + case '1': + g_bShowList1 ^= 1; + break; + case '2': + g_bShowList2 ^= 1; + break; + case 'P': + g_bNoDepthPortals ^= 1; + break; + case 'L': + g_bShowLines ^= 1; + break; + } + g_Update = TRUE; +} + +static BOOL g_Capture = FALSE; + +#define MOUSE_SENSITIVITY 0.2f +#define MOUSE_SENSITIVITY_X (MOUSE_SENSITIVITY*1) +#define MOUSE_SENSITIVITY_Y (MOUSE_SENSITIVITY*1) + +void Cam_MouseMoved( void ) +{ + if ( g_Capture ) + { + RECT rect; + int centerx, centery; + float deltax, deltay; + POINT cursorPoint; + + GetWindowRect( camerawindow, &rect ); + + if ( rect.top < 0) + rect.top = 0; + if ( rect.left < 0) + rect.left = 0; + + centerx = ( rect.left + rect.right ) / 2; + centery = ( rect.top + rect.bottom ) / 2; + + GetCursorPos( &cursorPoint ); + SetCursorPos( centerx, centery ); + + deltax = (cursorPoint.x - centerx) * MOUSE_SENSITIVITY_X; + deltay = (cursorPoint.y - centery) * MOUSE_SENSITIVITY_Y; + + angles[1] -= deltax; + angles[0] -= deltay; + + g_Update = TRUE; + } +} + +int Test_Key( int key ) +{ + int r = (g_Keys[ key ] != 0); + + g_Keys[ key ] &= 0x01; // clear out debounce bit + + if (r) + g_Update = TRUE; + + return r; +} + +// UNDONE: Probably should change the controls to match the game - but I don't know who relies on them +// as of now. +void Cam_Update( float frametime ) +{ + if ( Test_Key( 'W' ) ) + { + VectorMA (origin, g_flMovementSpeed*frametime, vpn, origin); + } + if ( Test_Key( 'S' ) ) + { + VectorMA (origin, -g_flMovementSpeed*frametime, vpn, origin); + } + if ( Test_Key( 'A' ) ) + { + VectorMA (origin, -g_flMovementSpeed*frametime, vright, origin); + } + if ( Test_Key( 'D' ) ) + { + VectorMA (origin, g_flMovementSpeed*frametime, vright, origin); + } + + if ( Test_Key( VK_UP ) ) + { + VectorMA (origin, g_flMovementSpeed*frametime, forward, origin); + } + if ( Test_Key( VK_DOWN ) ) + { + VectorMA (origin, -g_flMovementSpeed*frametime, forward, origin); + } + + if ( Test_Key( VK_LEFT ) ) + { + angles[1] += SPEED_TURN * frametime; + } + if ( Test_Key( VK_RIGHT ) ) + { + angles[1] -= SPEED_TURN * frametime; + } + if ( Test_Key( 'F' ) ) + { + origin[2] += g_flMovementSpeed*frametime; + } + if ( Test_Key( 'C' ) ) + { + origin[2] -= g_flMovementSpeed*frametime; + } + if ( Test_Key( VK_INSERT ) ) + { + angles[0] += SPEED_TURN * frametime; + if (angles[0] > 85) + angles[0] = 85; + } + if ( Test_Key( VK_DELETE ) ) + { + angles[0] -= SPEED_TURN * frametime; + if (angles[0] < -85) + angles[0] = -85; + } + Cam_MouseMoved(); +} + +void Cam_BuildMatrix (void) +{ + float xa, ya; + float matrix[4][4]; + int i; + + xa = angles[0]/180*M_PI; + ya = angles[1]/180*M_PI; + + // the movement matrix is kept 2d ?? do we want this? + + forward[0] = cos(ya); + forward[1] = sin(ya); + right[0] = forward[1]; + right[1] = -forward[0]; + + glGetFloatv (GL_PROJECTION_MATRIX, &matrix[0][0]); + + for (i=0 ; i<3 ; i++) + { + vright[i] = matrix[i][0]; + vup[i] = matrix[i][1]; + vpn[i] = matrix[i][2]; + } + + VectorNormalize (vright); + VectorNormalize (vup); + VectorNormalize (vpn); +} + +void Draw (void) +{ + float screenaspect; + float yfov; + + //glClearColor (0.5, 0.5, 0.5, 0); + glClearColor(0.0, 0.0, 0.0, 0); // Black Clearing YWB + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // + // set up viewpoint + // + glMatrixMode(GL_PROJECTION); + glLoadIdentity (); + + screenaspect = (float)width/height; + yfov = 2*atan((float)height/width)*180/M_PI; + gluPerspective (yfov, screenaspect, 6, 20000); + + glRotatef (-90, 1, 0, 0); // put Z going up + glRotatef (90, 0, 0, 1); // put Z going up + glRotatef (angles[0], 0, 1, 0); + glRotatef (-angles[1], 0, 0, 1); + glTranslatef (-origin[0], -origin[1], -origin[2]); + + Cam_BuildMatrix (); + + // + // set drawing parms + // + glShadeModel (GL_SMOOTH); + + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + glFrontFace(GL_CW); // YWB Carmack goes backward + glCullFace(GL_BACK); // Cull backfaces (qcsg used to spit out two sides, doesn't for -glview now) + glEnable(GL_CULL_FACE); // Enable face culling, just in case... + glDisable(GL_TEXTURE_2D); + + // Blending function if enabled.. + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + if (g_UseBlending) + { + glEnable(GL_BLEND);// YWB TESTING + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); // Enable face culling, just in case... + } + else + { + glDisable(GL_BLEND); + glEnable(GL_DEPTH_TEST); + } + glDepthFunc (GL_LEQUAL); + + if( g_bDisp ) + { + DrawDisplacementData(); + } + else + { + // + // draw the list + // + if (g_bShowList1) + glCallList (1); + + if (g_bReadPortals) + { + if (g_bNoDepthPortals) + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); // Disable face culling + if (g_bShowList2) + glCallList(2); + }; + + if (g_bShowLines) + glCallList(3); + } +} + +void ReadPolyFileType(const char *name, int nList, BOOL drawLines) +{ + FILE *f; + int i, j, numverts; + float v[8]; + int c; + int r; + float divisor; + + f = fopen (name, "rt"); + if (!f) + Error ("Couldn't open %s", name); + + if (g_bReadPortals) + divisor = 2.0f; + else + divisor = 1.0f; + + c = 0; + glNewList (nList, GL_COMPILE); + + for (i = 0; i < 3; i++) // Find the center point so we can put the viewer there by default + g_Center[i] = 0.0f; + + if (drawLines) // Slight hilite + glLineWidth(1.5); + + while (1) + { + r = fscanf( f, "%i\n", &numverts); + if (!r || r == EOF) + break; + + if ( c > 65534*8) + break; + + if (drawLines || numverts == 2) + glBegin(GL_LINE_LOOP); + else + glBegin (GL_POLYGON); + + for (i=0 ; i<numverts ; i++) + { + r = fscanf( f, "%f %f %f %f %f %f\n", &v[0], &v[1], + &v[2], &v[3], &v[4], &v[5]); + + /* + if (!(fabs( v[0] ) < 32768.0&& fabs( v[1] ) < 32768.0 && fabs( v[2] ) < 32768.0 ) ) + Error( "Out of range data\n"); + */ + + /* + if (v[3] <= 0.1 && v[4] <= 0.1 && v[5] <= 0.1 ) + continue; + */ + + if (drawLines) // YELLOW OUTLINES + glColor4f(1.0, 1.0, 0.0, 0.5); + else + { + if (g_bReadPortals) // Gray scale it, leave portals blue + { + if (fabs(fabs(v[5]) - 1.0f) < 0.01) // Is this a detail brush (color 0,0,1 blue) + { + glColor4f (v[3],v[4],v[5],0.5); + } + else // Normal brush, gray scale it... + { + v[3] += v[4] + v[5]; + v[3]/= 3.0f; + glColor4f (v[3]/divisor, v[3]/divisor, v[3]/divisor, 0.6); + } + } + else + { + v[3] = pow( v[3], (float)(1.0 / 2.2) ); + v[4] = pow( v[4], (float)(1.0 / 2.2) ); + v[5] = pow( v[5], (float)(1.0 / 2.2) ); + + glColor4f (v[3]/divisor, v[4]/divisor, v[5]/divisor, 0.6); // divisor is one, bright colors + }; + }; + glVertex3f (v[0], v[1], v[2]); + + for (j = 0; j < 3; j++) + { + g_Center[j] += v[j]; + } + + g_nTotalPoints++; + } + glEnd (); + c++; + } + + if (f) + fclose(f); + + glEndList (); + + if (g_nTotalPoints > 0) // Avoid division by zero + { + for (i = 0; i < 3; i++) + { + g_Center[i] = g_Center[i]/(float)g_nTotalPoints; // Calculate center... + origin[i] = g_Center[i]; + } + } +} + +#if BENCHMARK_PHY +#define NUM_COLLISION_TESTS 2500 +#include "gametrace.h" +#include "fmtstr.h" + + +struct testlist_t +{ + Vector start; + Vector end; + Vector normal; + bool hit; +}; + +const float baselineTotal = 120.16f; +const float baselineRay = 28.25f; +const float baselineBox = 91.91f; +#define IMPROVEMENT_FACTOR(x,baseline) (baseline/(x)) +#define IMPROVEMENT_PERCENT(x,baseline) (((baseline-(x)) / baseline) * 100.0f) + +testlist_t g_Traces[NUM_COLLISION_TESTS]; +void Benchmark_PHY( const CPhysCollide *pCollide ) +{ + int i; + Msg( "Testing collision system\n" ); + Vector start = vec3_origin; + static Vector *targets = NULL; + static bool first = true; + static float test[2] = {1,1}; + if ( first ) + { + float radius = 0; + float theta = 0; + float phi = 0; + for ( int i = 0; i < NUM_COLLISION_TESTS; i++ ) + { + radius += NUM_COLLISION_TESTS * 123.123f; + radius = fabs(fmod(radius, 128)); + theta += NUM_COLLISION_TESTS * 0.76f; + theta = fabs(fmod(theta, DEG2RAD(360))); + phi += NUM_COLLISION_TESTS * 0.16666666f; + phi = fabs(fmod(phi, DEG2RAD(180))); + + float st, ct, sp, cp; + SinCos( theta, &st, &ct ); + SinCos( phi, &sp, &cp ); + st = sin(theta); + ct = cos(theta); + sp = sin(phi); + cp = cos(phi); + + g_Traces[i].start.x = radius * ct * sp; + g_Traces[i].start.y = radius * st * sp; + g_Traces[i].start.z = radius * cp; + } + first = false; + } + + float duration = 0; + Vector size[2]; + size[0].Init(0,0,0); + size[1].Init(16,16,16); + unsigned int dots = 0; + +#if VPROF_LEVEL > 0 + g_VProfCurrentProfile.Reset(); + g_VProfCurrentProfile.ResetPeaks(); + g_VProfCurrentProfile.Start(); +#endif + unsigned int hitCount = 0; + double startTime = Plat_FloatTime(); + trace_t tr; + for ( i = 0; i < NUM_COLLISION_TESTS; i++ ) + { + physcollision->TraceBox( g_Traces[i].start, start, -size[0], size[0], pCollide, vec3_origin, vec3_angle, &tr ); + if ( tr.DidHit() ) + { + g_Traces[i].end = tr.endpos; + g_Traces[i].normal = tr.plane.normal; + g_Traces[i].hit = true; + hitCount++; + } + else + { + g_Traces[i].hit = false; + } + } + for ( i = 0; i < NUM_COLLISION_TESTS; i++ ) + { + physcollision->TraceBox( g_Traces[i].start, start, -size[1], size[1], pCollide, vec3_origin, vec3_angle, &tr ); + } + duration = Plat_FloatTime() - startTime; + { + unsigned int msSupp = physcollision->ReadStat( 100 ); + unsigned int msGJK = physcollision->ReadStat( 101 ); + unsigned int msMesh = physcollision->ReadStat( 102 ); + CFmtStr str("%d ms total %d ms gjk %d mesh solve\n", msSupp, msGJK, msMesh ); + OutputDebugStr( str.Access() ); + } + +#if VPROF_LEVEL > 0 + g_VProfCurrentProfile.MarkFrame(); + g_VProfCurrentProfile.Stop(); + g_VProfCurrentProfile.Reset(); + g_VProfCurrentProfile.ResetPeaks(); + g_VProfCurrentProfile.Start(); +#endif + hitCount = 0; + startTime = Plat_FloatTime(); + for ( i = 0; i < NUM_COLLISION_TESTS; i++ ) + { + physcollision->TraceBox( g_Traces[i].start, start, -size[0], size[0], pCollide, vec3_origin, vec3_angle, &tr ); + if ( tr.DidHit() ) + { + g_Traces[i].end = tr.endpos; + g_Traces[i].normal = tr.plane.normal; + g_Traces[i].hit = true; + hitCount++; + } + else + { + g_Traces[i].hit = false; + } +#if VPROF_LEVEL > 0 + g_VProfCurrentProfile.MarkFrame(); +#endif + } + double midTime = Plat_FloatTime(); + for ( i = 0; i < NUM_COLLISION_TESTS; i++ ) + { + physcollision->TraceBox( g_Traces[i].start, start, -size[1], size[1], pCollide, vec3_origin, vec3_angle, &tr ); +#if VPROF_LEVEL > 0 + g_VProfCurrentProfile.MarkFrame(); +#endif + } + double endTime = Plat_FloatTime(); + duration = endTime - startTime; + { + CFmtStr str("%d collisions in %.2f ms [%.2f X] %d hits\n", NUM_COLLISION_TESTS, duration*1000, IMPROVEMENT_FACTOR(duration*1000.0f, baselineTotal), hitCount ); + OutputDebugStr( str.Access() ); + } + { + float rayTime = (midTime - startTime) * 1000.0f; + float boxTime = (endTime - midTime)*1000.0f; + CFmtStr str("%.2f ms rays [%.2f X] %.2f ms boxes [%.2f X]\n", rayTime, IMPROVEMENT_FACTOR(rayTime, baselineRay), boxTime, IMPROVEMENT_FACTOR(boxTime, baselineBox)); + OutputDebugStr( str.Access() ); + } + + { + unsigned int msSupp = physcollision->ReadStat( 100 ); + unsigned int msGJK = physcollision->ReadStat( 101 ); + unsigned int msMesh = physcollision->ReadStat( 102 ); + CFmtStr str("%d ms total %d ms gjk %d mesh solve\n", msSupp, msGJK, msMesh ); + OutputDebugStr( str.Access() ); + } +#if VPROF_LEVEL > 0 + g_VProfCurrentProfile.Stop(); + g_VProfCurrentProfile.OutputReport( VPRT_FULL & ~VPRT_HIERARCHY, NULL ); +#endif + + // draw the traces in yellow + glColor3f( 1.0f, 1.0f, 0.0f ); + glBegin( GL_LINES ); + for ( int i = 0; i < NUM_COLLISION_TESTS; i++ ) + { + if ( !g_Traces[i].hit ) + continue; + glVertex3fv( g_Traces[i].end.Base() ); + Vector tmp = g_Traces[i].end + g_Traces[i].normal * 10.0f; + glVertex3fv( tmp.Base() ); + } + glEnd(); +} +#endif + +struct phyviewparams_t +{ + Vector mins; + Vector maxs; + Vector offset; + QAngle angles; + int outputType; + + void Defaults() + { + ClearBounds(mins, maxs); + offset.Init(); + outputType = GL_POLYGON; + angles.Init(); + } +}; + + +void AddVCollideToList( phyheader_t &header, vcollide_t &collide, phyviewparams_t ¶ms ) +{ + matrix3x4_t xform; + AngleMatrix( params.angles, params.offset, xform ); + ClearBounds( params.mins, params.maxs ); + for ( int i = 0; i < header.solidCount; i++ ) + { + ICollisionQuery *pQuery = physcollision->CreateQueryModel( collide.solids[i] ); + for ( int j = 0; j < pQuery->ConvexCount(); j++ ) + { + for ( int k = 0; k < pQuery->TriangleCount(j); k++ ) + { + Vector verts[3]; + pQuery->GetTriangleVerts( j, k, verts ); + Vector v0,v1,v2; + VectorTransform( verts[0], xform, v0 ); + VectorTransform( verts[1], xform, v1 ); + VectorTransform( verts[2], xform, v2 ); + AddPointToBounds( v0, params.mins, params.maxs ); + AddPointToBounds( v1, params.mins, params.maxs ); + AddPointToBounds( v2, params.mins, params.maxs ); + + glBegin(params.outputType); + glColor3ub( 255, 0, 0 ); + glVertex3fv( v0.Base() ); + glColor3ub( 0, 255, 0 ); + glVertex3fv( v1.Base() ); + glColor3ub( 0, 0, 255 ); + glVertex3fv( v2.Base() ); + glEnd(); + } + } + physcollision->DestroyQueryModel( pQuery ); + } +} + +void GL_DrawLine( const Vector &start, const Vector &dir, float length, int r, int g, int b ) +{ + Vector end = start + (dir*length); + glBegin( GL_LINES ); + glColor3ub(r,g,b); + glVertex3fv( start.Base() ); + glVertex3fv( end.Base() ); + glEnd(); +} + +void GL_DrawBox( Vector origin, float size, int r, int g, int b ) +{ + Vector mins = origin - Vector(size,size,size); + Vector maxs = origin + Vector(size,size,size); + const float *v[2] = {mins.Base(), maxs.Base()}; + + Vector start, end; + { + for ( int i = 0; i < 3; i++ ) + { + int a0 = i; + int a1 = (i+1)%3; + int a2 = (i+2)%3; + for ( int j = 0; j < 2; j++ ) + { + for ( int k = 0; k < 2; k++ ) + { + start[a0] = v[0][a0]; + end[a0] = v[1][a0]; + start[a1] = v[j][a1]; + end[a1] = v[j][a1]; + start[a2] = v[k][a2]; + end[a2] = v[k][a2]; + GL_DrawLine( start, end-start, 1, r, g, b ); + } + } + } + } + for ( int axis = 0; axis < 3; axis++ ) + { + int a0 = axis; + int a1 = (axis+1)%3; + int a2 = (axis+2)%3; + start[a0] = v[0][a0]; + end[a0] = v[1][a0]; + start[a1] = 0.5f *(v[0][a1]+v[1][a1]); + end[a1] = 0.5f *(v[0][a1]+v[1][a1]); + start[a2] = 0.5f *(v[0][a2]+v[1][a2]); + end[a2] = 0.5f *(v[0][a2]+v[1][a2]); + GL_DrawLine( start, end-start, 1, r, g, b ); + } +} + + +void ReadPHYFile(const char *name, phyviewparams_t ¶ms ) +{ + FILE *fp = fopen (name, "rb"); + if (!fp) + Error ("Couldn't open %s", name); + + phyheader_t header; + + fread( &header, sizeof(header), 1, fp ); + if ( header.size != sizeof(header) || header.solidCount <= 0 ) + return; + + int pos = ftell( fp ); + fseek( fp, 0, SEEK_END ); + int fileSize = ftell(fp) - pos; + fseek( fp, pos, SEEK_SET ); + + char *buf = (char *)_alloca( fileSize ); + fread( buf, fileSize, 1, fp ); + fclose( fp ); + + vcollide_t collide; + physcollision->VCollideLoad( &collide, header.solidCount, (const char *)buf, fileSize ); +#if 0 + Vector start0( -3859.1199, -2050.8674, 64.031250 ); + Vector end0(-3859.2246, -2051.2817, 64.031250 ); + Vector modelPosition(-3840,-2068.0000, 82.889099); + QAngle modelAngles(0,90,0); + + { + Ray_t ray; + ray.Init( start0, end0, Vector(-16,-16,0), Vector(16,16,72)); + trace_t tr; + physcollision->TraceBox( ray, collide.solids[0], modelPosition, modelAngles, &tr ); + Assert(!tr.startsolid); + if ( tr.DidHit() ) + { + Ray_t ray2; + ray2.Init( tr.endpos, tr.endpos, Vector(-16,-16,0), Vector(16,16,72)); + trace_t tr2; + physcollision->TraceBox( ray2, collide.solids[0], modelPosition, modelAngles, &tr2 ); + Assert(!tr2.startsolid); + } + } +#endif +#if BENCHMARK_PHY + Benchmark_PHY( collide.solids[0] ); +#endif + AddVCollideToList( header, collide, params ); +} + +void ReadPolyFile (const char *name) +{ + char ext[4]; + Q_ExtractFileExtension( name, ext, 4 ); + + bool isPHY = !Q_stricmp( ext, "phy" ); + if ( isPHY ) + { + CreateInterfaceFn physicsFactory = GetPhysicsFactory(); + physcollision = (IPhysicsCollision *)physicsFactory( VPHYSICS_COLLISION_INTERFACE_VERSION, NULL ); + if ( physcollision ) + { + phyviewparams_t params; + params.Defaults(); + glNewList (1, GL_COMPILE); + ReadPHYFile( name, params ); + Vector tmp = (params.mins + params.maxs) * 0.5; + tmp.CopyToArray(origin); + glEndList (); + } + } + else + { + // Read in polys... + ReadPolyFileType(name, 1, false); + + // Make list 3 just the lines... so we can draw outlines + ReadPolyFileType(name, 3, true); + } +} + +void ReadPortalFile (char *name) +{ + FILE *f; + int i, numverts; + float v[8]; + int c; + int r; + + // For Portal type reading... + char szDummy[80]; + int nNumLeafs; + int nNumPortals; + int nLeafIndex[2]; + + f = fopen (name, "r"); + if (!f) + Error ("Couldn't open %s", name); + + c = 0; + + glNewList (2, GL_COMPILE); + + // Read in header + fscanf(f, "%79s\n", szDummy); + fscanf(f, "%i\n", &nNumLeafs); + fscanf(f, "%i\n", &nNumPortals); + + glLineWidth(1.5); + + while (1) + { + r = fscanf(f, "%i %i %i ", &numverts, &nLeafIndex[0], &nLeafIndex[1]); + if (!r || r == EOF) + break; + + glBegin(GL_LINE_LOOP); + for (i=0 ; i<numverts ; i++) + { + r = fscanf (f, "(%f %f %f )\n", &v[0], &v[1], + &v[2]); + if (!r || (r != 3) || r == EOF) + break; + + if ( c == g_nPortalHighlight || nLeafIndex[0] == g_nLeafHighlight || nLeafIndex[1] == g_nLeafHighlight ) + { + glColor4f (1.0, 0.0, 0.0, 1.0); + } + else + { + glColor4f (1.0f, 1.0f, 1.0f, 1.0f); // WHITE portals + } + glVertex3f (v[0], v[1], v[2]); + } + + glEnd (); + c++; + } + + if (f) + fclose(f); + + glEndList (); +} + +#define MAX_DISP_COUNT 4096 +static Vector dispPoints[MAX_DISP_COUNT]; +static Vector dispNormals[MAX_DISP_COUNT]; +static int dispPointCount = 0; + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +BOOL ReadDisplacementFile( const char *filename ) +{ + FILE *pFile; + int fileCount; + + // + // open the file + // + pFile = fopen( filename, "r" ); + if( !pFile ) + Error( "Couldn't open %s", filename ); + + // + // read data in file + // + while( 1 ) + { + // overflow test + if( dispPointCount >= MAX_DISP_COUNT ) + break; + + fileCount = fscanf( pFile, "%f %f %f %f %f %f", + &dispPoints[dispPointCount][0], &dispPoints[dispPointCount][1], &dispPoints[dispPointCount][2], + &dispNormals[dispPointCount][0], &dispNormals[dispPointCount][1], &dispNormals[dispPointCount][2] ); + dispPointCount++; + + // end of file check + if( !fileCount || ( fileCount == EOF ) ) + break; + } + + fclose( pFile ); + + return TRUE; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void DrawDisplacementData( void ) +{ + int i, j; + int width, halfCount; + + GLUquadricObj *pObject = gluNewQuadric(); + + glEnable( GL_DEPTH_TEST ); + + for( i = 0; i < dispPointCount; i++ ) + { + // draw a sphere where the point is (in red) + glColor3f( 1.0f, 0.0f, 0.0f ); + glPushMatrix(); + glTranslatef( dispPoints[i][0], dispPoints[i][1], dispPoints[i][2] ); + gluSphere( pObject, 5, 5, 5 ); + glPopMatrix(); + + // draw the normal (in yellow) + glColor3f( 1.0f, 1.0f, 0.0f ); + glBegin( GL_LINES ); + glVertex3f( dispPoints[i][0], dispPoints[i][1], dispPoints[i][2] ); + glVertex3f( dispPoints[i][0] + ( dispNormals[i][0] * 50.0f ), dispPoints[i][1] + ( dispNormals[i][1] * 50.0f ), dispPoints[i][2] + ( dispNormals[i][2] * 50.0f ) ); + glEnd(); + } + + halfCount = dispPointCount / 2; + + width = sqrt( (float)halfCount ); + + glDisable( GL_CULL_FACE ); + + glColor3f( 0.0f, 0.0f, 1.0f ); + for( i = 0; i < width - 1; i++ ) + { + for( j = 0; j < width - 1; j++ ) + { + glBegin( GL_POLYGON ); + glVertex3f( dispPoints[i*width+j][0], dispPoints[i*width+j][1], dispPoints[i*width+j][2] ); + glVertex3f( dispPoints[(i+1)*width+j][0], dispPoints[(i+1)*width+j][1], dispPoints[(i+1)*width+j][2] ); + glVertex3f( dispPoints[(i+1)*width+(j+1)][0], dispPoints[(i+1)*width+(j+1)][1], dispPoints[(i+1)*width+(j+1)][2] ); + glVertex3f( dispPoints[i*width+(j+1)][0], dispPoints[i*width+(j+1)][1], dispPoints[i*width+(j+1)][2] ); + glEnd(); + } + } + +#if 0 + for( i = 0; i < width - 1; i++ ) + { + for( j = 0; j < width - 1; j++ ) + { + glBegin( GL_POLYGON ); + glVertex3f( dispPoints[halfCount+(i*width+j)][0], dispPoints[halfCount+(i*width+j)][1], dispPoints[halfCount+(i*width+j)][2] ); + glVertex3f( dispPoints[halfCount+((i+1)*width+j)][0], dispPoints[halfCount+(i+1)*width+j][1], dispPoints[halfCount+((i+1)*width+j)][2] ); + glVertex3f( dispPoints[halfCount+((i+1)*width+(j+1))][0], dispPoints[halfCount+(i+1)*width+(j+1)][1], dispPoints[halfCount+((i+1)*width+(j+1))][2] ); + glVertex3f( dispPoints[halfCount+(i*width+(j+1))][0], dispPoints[halfCount+(i*width+(j+1))][1], dispPoints[halfCount+(i*width+(j+1))][2] ); + glEnd(); + } + } +#endif + + glColor3f( 0.0f, 1.0f, 0.0f ); + for( i = 0; i < width - 1; i++ ) + { + for( j = 0; j < width - 1; j++ ) + { + glBegin( GL_POLYGON ); + glVertex3f( dispPoints[i*width+j][0] + ( dispNormals[i*width+j][0] * 150.0f ), + dispPoints[i*width+j][1] + ( dispNormals[i*width+j][1] * 150.0f ), + dispPoints[i*width+j][2] + ( dispNormals[i*width+j][2] * 150.0f ) ); + + glVertex3f( dispPoints[(i+1)*width+j][0] + ( dispNormals[(i+1)*width+j][0] * 150.0f ), + dispPoints[(i+1)*width+j][1] + ( dispNormals[(i+1)*width+j][1] * 150.0f ), + dispPoints[(i+1)*width+j][2] + ( dispNormals[(i+1)*width+j][2] * 150.0f ) ); + + glVertex3f( dispPoints[(i+1)*width+(j+1)][0] + ( dispNormals[(i+1)*width+(j+1)][0] * 150.0f ), + dispPoints[(i+1)*width+(j+1)][1] + ( dispNormals[(i+1)*width+(j+1)][1] * 150.0f ), + dispPoints[(i+1)*width+(j+1)][2] + ( dispNormals[(i+1)*width+(j+1)][2] * 150.0f ) ); + + glVertex3f( dispPoints[i*width+(j+1)][0] + ( dispNormals[i*width+(j+1)][0] * 150.0f ), + dispPoints[i*width+(j+1)][1] + ( dispNormals[i*width+(j+1)][1] * 150.0f ), + dispPoints[i*width+(j+1)][2] + ( dispNormals[i*width+(j+1)][2] * 150.0f ) ); + glEnd(); + } + } + + glDisable( GL_DEPTH_TEST ); + + glColor3f( 0.0f, 0.0f, 1.0f ); + for( i = 0; i < width - 1; i++ ) + { + for( j = 0; j < width - 1; j++ ) + { + glBegin( GL_LINE_LOOP ); + glVertex3f( dispPoints[i*width+j][0] + ( dispNormals[i*width+j][0] * 150.0f ), + dispPoints[i*width+j][1] + ( dispNormals[i*width+j][1] * 150.0f ), + dispPoints[i*width+j][2] + ( dispNormals[i*width+j][2] * 150.0f ) ); + + glVertex3f( dispPoints[(i+1)*width+j][0] + ( dispNormals[(i+1)*width+j][0] * 150.0f ), + dispPoints[(i+1)*width+j][1] + ( dispNormals[(i+1)*width+j][1] * 150.0f ), + dispPoints[(i+1)*width+j][2] + ( dispNormals[(i+1)*width+j][2] * 150.0f ) ); + + glVertex3f( dispPoints[(i+1)*width+(j+1)][0] + ( dispNormals[(i+1)*width+(j+1)][0] * 150.0f ), + dispPoints[(i+1)*width+(j+1)][1] + ( dispNormals[(i+1)*width+(j+1)][1] * 150.0f ), + dispPoints[(i+1)*width+(j+1)][2] + ( dispNormals[(i+1)*width+(j+1)][2] * 150.0f ) ); + + glVertex3f( dispPoints[i*width+(j+1)][0] + ( dispNormals[i*width+(j+1)][0] * 150.0f ), + dispPoints[i*width+(j+1)][1] + ( dispNormals[i*width+(j+1)][1] * 150.0f ), + dispPoints[i*width+(j+1)][2] + ( dispNormals[i*width+(j+1)][2] * 150.0f ) ); + glEnd(); + } + } + + + gluDeleteQuadric( pObject ); +} + + +//===================================================================== + +BOOL bSetupPixelFormat(HDC hDC) +{ + static PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd + 1, // version number + PFD_DRAW_TO_WINDOW | // support window + PFD_SUPPORT_OPENGL | // support OpenGL + PFD_DOUBLEBUFFER, // double buffered + PFD_TYPE_RGBA, // RGBA type + 24, // 24-bit color depth + 0, 0, 0, 0, 0, 0, // color bits ignored + 0, // no alpha buffer + 0, // shift bit ignored + 0, // no accumulation buffer + 0, 0, 0, 0, // accum bits ignored + 32, // 32-bit z-buffer + 0, // no stencil buffer + 0, // no auxiliary buffer + PFD_MAIN_PLANE, // main layer + 0, // reserved + 0, 0, 0 // layer masks ignored + }; + + int pixelformat = 0; + + if ( (pixelformat = ChoosePixelFormat(hDC, &pfd)) == 0 ) + Error ("ChoosePixelFormat failed"); + + if (!SetPixelFormat(hDC, pixelformat, &pfd)) + Error ("SetPixelFormat failed"); + + return TRUE; +} + +/* +============ +CameraWndProc +============ +*/ +LONG WINAPI WCam_WndProc ( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + LONG lRet = 1; + RECT rect; + + GetClientRect(hWnd, &rect); + + switch (uMsg) + { + case WM_CREATE: + { + camdc = GetDC(hWnd); + bSetupPixelFormat(camdc); + + baseRC = wglCreateContext( camdc ); + if (!baseRC) + Error ("wglCreateContext failed"); + if (!wglMakeCurrent( camdc, baseRC )) + Error ("wglMakeCurrent failed"); + glCullFace(GL_FRONT); + glEnable(GL_CULL_FACE); + } + break; + case WM_PAINT: + { + PAINTSTRUCT ps; + + BeginPaint(hWnd, &ps); + if (!wglMakeCurrent( camdc, baseRC )) + Error ("wglMakeCurrent failed"); + Draw (); + SwapBuffers(camdc); + EndPaint(hWnd, &ps); + } + break; + + case WM_KEYDOWN: + KeyDown (wParam); + AppKeyDown( wParam ); + break; + + case WM_KEYUP: + AppKeyUp( wParam ); + break; + + case WM_MBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_LBUTTONDOWN: + SetCapture (camerawindow); + ShowCursor( FALSE ); + g_Capture = TRUE; + break; + + case WM_MBUTTONUP: + case WM_RBUTTONUP: + case WM_LBUTTONUP: + if (! (wParam & (MK_LBUTTON|MK_RBUTTON|MK_MBUTTON))) + { + g_Capture = FALSE; + ReleaseCapture (); + ShowCursor( TRUE ); + } + break; + + case WM_SIZE: + InvalidateRect(camerawindow, NULL, false); + break; + case WM_NCCALCSIZE:// don't let windows copy pixels + lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); + return WVR_REDRAW; + case WM_CLOSE: + /* call destroy window to cleanup and go away */ + DestroyWindow (hWnd); + break; + + case WM_DESTROY: + { + HGLRC hRC; + HDC hDC; + + /* release and free the device context and rendering context */ + hRC = wglGetCurrentContext(); + hDC = wglGetCurrentDC(); + + wglMakeCurrent(NULL, NULL); + + if (hRC) + wglDeleteContext(hRC); + if (hDC) + ReleaseDC(hWnd, hDC); + + PostQuitMessage (0); + } + break; + + default: + /* pass all unhandled messages to DefWindowProc */ + lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); + break; + } + + /* return 1 if handled message, 0 if not */ + return lRet; +} + + +/* +============== +WCam_Register +============== +*/ +void WCam_Register (HINSTANCE hInstance) +{ + WNDCLASS wc; + + /* Register the camera class */ + memset (&wc, 0, sizeof(wc)); + + wc.style = 0; + wc.lpfnWndProc = (WNDPROC)WCam_WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = 0; + wc.hCursor = LoadCursor (NULL,IDC_ARROW); + wc.hbrBackground = NULL; + wc.lpszMenuName = 0; + wc.lpszClassName = "camera"; + + if (!RegisterClass (&wc) ) + Error ("WCam_Register: failed"); +} + + +void WCam_Create (HINSTANCE hInstance) +{ + // Center it + int nScx, nScy; + int w, h; + int x, y; + + WCam_Register (hInstance); + + w = ::width; + h = ::height; + + nScx = GetSystemMetrics(SM_CXSCREEN); + nScy = GetSystemMetrics(SM_CYSCREEN); + + + x = (nScx - w)/2; + y = (nScy - h)/2; + + camerawindow = CreateWindow ("camera" , + "Camera View", + WS_OVERLAPPED | + WS_CAPTION | + WS_SYSMENU | + WS_THICKFRAME | + WS_MAXIMIZEBOX | + WS_CLIPSIBLINGS | + WS_CLIPCHILDREN, + + x, + y, + w, + h, // size + + NULL, // parent window + 0, // no menu + hInstance, + 0); + if (!camerawindow) + Error ("Couldn't create camerawindow"); + + ShowWindow (camerawindow, SW_SHOWDEFAULT); +} + + +void AppKeyDown( int key ) +{ + key &= 0xFF; + + g_Keys[key] = 0x03; // add debounce bit +} + +void AppKeyUp( int key ) +{ + key &= 0xFF; + + g_Keys[key] &= 0x02; +} + +void AppRender( void ) +{ + static double lastTime = 0; + double time = timeGetTime() * 0.001f; + double frametime = time - lastTime; + + // clamp too large frames (like first frame) + if ( frametime > 0.2 ) + frametime = 0.2; + lastTime = time; + + if (!wglMakeCurrent( camdc, baseRC )) + Error ("wglMakeCurrent failed"); + + Cam_Update( frametime ); + + if (g_Update) + { + Draw (); + SwapBuffers(camdc); + g_Update = FALSE; + } + else + { + Sleep( 1.0 ); + } +} + +SpewRetval_t Sys_SpewFunc( SpewType_t type, const char *pMsg ) +{ + OutputDebugString( pMsg ); + if( type == SPEW_ASSERT ) + return SPEW_DEBUGGER; + else if( type == SPEW_ERROR ) + return SPEW_ABORT; + else + return SPEW_CONTINUE; +} + + +/* +================== +WinMain + +================== +*/ +int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance + ,LPSTR lpCmdLine, int nCmdShow) +{ + CommandLine()->CreateCmdLine( Plat_GetCommandLine() ); + + MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f ); + MSG msg; + + if (!lpCmdLine || !lpCmdLine[0]) + Error ("No file specified"); + + main_instance = hInstance; + + WCam_Create (hInstance); + + // Last argument is the file name + const char *pFileName = CommandLine()->GetParm( CommandLine()->ParmCount() - 1 ); + CmdLib_InitFileSystem( pFileName ); + + if ( CommandLine()->CheckParm( "-portal") ) + { + g_bReadPortals = 1; + g_nPortalHighlight = CommandLine()->ParmValue( "-portalhighlight", -1 ); + g_nLeafHighlight = CommandLine()->ParmValue( "-leafhighlight", -1 ); + } + g_flMovementSpeed = CommandLine()->ParmValue( "-speed", 320 ); + + if( CommandLine()->CheckParm( "-disp") ) + { + ReadDisplacementFile( pFileName ); + g_bDisp = TRUE; + } + SpewOutputFunc( Sys_SpewFunc ); + + // Any chunk of original left is the filename. + if (pFileName && pFileName[0] && !g_bDisp ) + { + ReadPolyFile( pFileName ); + } + + if (g_bReadPortals) + { + // Copy file again and this time look for the . from .gl? so we can concatenate .prt + // and open the portal file. + char szTempCmd[MAX_PATH]; + strcpy(szTempCmd, pFileName); + char *pTmp = szTempCmd; + while (pTmp && *pTmp && *pTmp != '.') + { + pTmp++; + } + + *pTmp = '\0'; + strcat(szTempCmd, ".prt"); + + ReadPortalFile(szTempCmd); + }; + + /* main window message loop */ + while (g_Active) + { + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + AppRender(); + } + + /* return success of application */ + return TRUE; +} + |