From f56bb35301836e56582a575a75864392a0177875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20P=2E=20Tjern=C3=B8?= Date: Mon, 2 Dec 2013 19:31:46 -0800 Subject: Fix line endings. WHAMMY. --- mp/src/utils/glview/glview.cpp | 2854 ++++++++++++++++++++-------------------- 1 file changed, 1427 insertions(+), 1427 deletions(-) (limited to 'mp/src/utils/glview/glview.cpp') 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 -#if _MSC_VER < 1600 -#include -#endif -#include -#include -#include -#include -#include -#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 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= 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 +#if _MSC_VER < 1600 +#include +#endif +#include +#include +#include +#include +#include +#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 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= 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; +} + -- cgit v1.2.3