mirror of
https://github.com/celisej567/source-engine.git
synced 2026-01-05 22:09:59 +03:00
1
This commit is contained in:
806
utils/hlfaceposer/matsyswin.cpp
Normal file
806
utils/hlfaceposer/matsyswin.cpp
Normal file
@@ -0,0 +1,806 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include <mxtk/mx.h>
|
||||
#include <mxtk/mxMessageBox.h>
|
||||
#include <mxtk/mxTga.h>
|
||||
#include <mxtk/mxPcx.h>
|
||||
#include <mxtk/mxBmp.h>
|
||||
#include <mxtk/mxMatSysWindow.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include "MatSysWin.h"
|
||||
#include "MDLViewer.h"
|
||||
#include "StudioModel.h"
|
||||
#include "ControlPanel.h"
|
||||
#include "ViewerSettings.h"
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
#include "materialsystem/imaterialproxyfactory.h"
|
||||
#include "filesystem.h"
|
||||
#include <keyvalues.h>
|
||||
#include "materialsystem/imesh.h"
|
||||
#include "expressions.h"
|
||||
#include "hlfaceposer.h"
|
||||
#include "ifaceposersound.h"
|
||||
#include "materialsystem/IMaterialSystemHardwareConfig.h"
|
||||
#include "materialsystem/itexture.h"
|
||||
#include "materialsystem/MaterialSystem_Config.h"
|
||||
#include "istudiorender.h"
|
||||
#include "choreowidgetdrawhelper.h"
|
||||
#include "faceposer_models.h"
|
||||
#include "tier0/icommandline.h"
|
||||
#include "mathlib/vmatrix.h"
|
||||
#include "vstdlib/cvar.h"
|
||||
|
||||
IFileSystem *filesystem = NULL;
|
||||
|
||||
extern char g_appTitle[];
|
||||
|
||||
// FIXME: move all this to mxMatSysWin
|
||||
|
||||
class DummyMaterialProxyFactory : public IMaterialProxyFactory
|
||||
{
|
||||
public:
|
||||
virtual IMaterialProxy *CreateProxy( const char *proxyName ) {return NULL;}
|
||||
virtual void DeleteProxy( IMaterialProxy *pProxy ) {}
|
||||
};
|
||||
DummyMaterialProxyFactory g_DummyMaterialProxyFactory;
|
||||
|
||||
|
||||
static void ReleaseMaterialSystemObjects()
|
||||
{
|
||||
StudioModel::ReleaseStudioModel();
|
||||
models->ReleaseModels();
|
||||
}
|
||||
|
||||
static void RestoreMaterialSystemObjects( int nChangeFlags )
|
||||
{
|
||||
StudioModel::RestoreStudioModel();
|
||||
models->RestoreModels();
|
||||
}
|
||||
|
||||
void InitMaterialSystemConfig(MaterialSystem_Config_t *pConfig)
|
||||
{
|
||||
pConfig->SetFlag( MATSYS_VIDCFG_FLAGS_USING_MULTIPLE_WINDOWS, true );
|
||||
}
|
||||
|
||||
Vector g_vright( 50, 50, 0 ); // needs to be set to viewer's right in order for chrome to work
|
||||
|
||||
IMaterial *g_materialBackground = NULL;
|
||||
IMaterial *g_materialWireframe = NULL;
|
||||
IMaterial *g_materialWireframeVertexColor = NULL;
|
||||
IMaterial *g_materialWireframeVertexColorNoCull = NULL;
|
||||
IMaterial *g_materialDebugCopyBaseTexture = NULL;
|
||||
IMaterial *g_materialFlatshaded = NULL;
|
||||
IMaterial *g_materialSmoothshaded = NULL;
|
||||
IMaterial *g_materialBones = NULL;
|
||||
IMaterial *g_materialLines = NULL;
|
||||
IMaterial *g_materialFloor = NULL;
|
||||
IMaterial *g_materialVertexColor = NULL;
|
||||
IMaterial *g_materialShadow = NULL;
|
||||
|
||||
MatSysWindow *g_pMatSysWindow = 0;
|
||||
|
||||
#define MATSYSWIN_NAME "3D View"
|
||||
|
||||
MatSysWindow::MatSysWindow (mxWindow *parent, int x, int y, int w, int h, const char *label, int style)
|
||||
: IFacePoserToolWindow( "3D View", "3D View" ), mxMatSysWindow ( parent, x, y, w, h, label, style )
|
||||
{
|
||||
g_pMaterialSystem->SetMaterialProxyFactory( &g_DummyMaterialProxyFactory );
|
||||
|
||||
SetAutoProcess( true );
|
||||
|
||||
setLabel( MATSYSWIN_NAME );
|
||||
|
||||
m_bSuppressSwap = false;
|
||||
|
||||
m_hWnd = (HWND)getHandle();
|
||||
|
||||
Con_Printf( "Setting material system video mode\n" );
|
||||
|
||||
MaterialSystem_Config_t config;
|
||||
config = g_pMaterialSystem->GetCurrentConfigForVideoCard();
|
||||
InitMaterialSystemConfig(&config);
|
||||
g_pMaterialSystem->OverrideConfig( config, false );
|
||||
|
||||
// config.m_VideoMode.m_Width = config.m_VideoMode.m_Height = 0;
|
||||
config.SetFlag( MATSYS_VIDCFG_FLAGS_WINDOWED, true );
|
||||
config.SetFlag( MATSYS_VIDCFG_FLAGS_RESIZING, true );
|
||||
|
||||
if (!g_pMaterialSystem->SetMode( ( void * )m_hWnd, config ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
g_pMaterialSystem->AddReleaseFunc( ReleaseMaterialSystemObjects );
|
||||
g_pMaterialSystem->AddRestoreFunc( RestoreMaterialSystemObjects );
|
||||
|
||||
Con_Printf( "Loading debug materials\n" );
|
||||
|
||||
ITexture *pCubemapTexture = g_pMaterialSystem->FindTexture( "hlmv/cubemap", NULL, true );
|
||||
pCubemapTexture->IncrementReferenceCount();
|
||||
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
||||
pRenderContext->BindLocalCubemap( pCubemapTexture );
|
||||
|
||||
g_materialBackground = g_pMaterialSystem->FindMaterial("particle/particleapp_background", TEXTURE_GROUP_OTHER, true);
|
||||
g_materialWireframe = g_pMaterialSystem->FindMaterial("debug/debugmrmwireframe", TEXTURE_GROUP_OTHER, true);
|
||||
g_materialWireframeVertexColor = g_pMaterialSystem->FindMaterial("debug/debugwireframevertexcolor", TEXTURE_GROUP_OTHER, true);
|
||||
|
||||
// test: create this from code - you need a vmt to make $nocull 1 happen, can't do it from the render context
|
||||
{
|
||||
KeyValues *pVMTKeyValues = new KeyValues( "Wireframe" );
|
||||
pVMTKeyValues->SetInt("$ignorez", 1);
|
||||
pVMTKeyValues->SetInt("$nocull", 1);
|
||||
pVMTKeyValues->SetInt("$vertexcolor", 1);
|
||||
pVMTKeyValues->SetInt("$decal", 1);
|
||||
g_materialWireframeVertexColorNoCull = g_pMaterialSystem->CreateMaterial( "debug/wireframenocull", pVMTKeyValues );
|
||||
}
|
||||
{
|
||||
KeyValues *pVMTKeyValues = new KeyValues( "UnlitGeneric" );
|
||||
pVMTKeyValues->SetString("$basetexture", "vgui/white" );
|
||||
g_materialDebugCopyBaseTexture = g_pMaterialSystem->CreateMaterial( "debug/copybasetexture", pVMTKeyValues );
|
||||
|
||||
}
|
||||
|
||||
g_materialFlatshaded = g_pMaterialSystem->FindMaterial("debug/debugdrawflatpolygons", TEXTURE_GROUP_OTHER, true);
|
||||
g_materialSmoothshaded = g_pMaterialSystem->FindMaterial("debug/debugmrmfullbright2", TEXTURE_GROUP_OTHER, true);
|
||||
g_materialBones = g_pMaterialSystem->FindMaterial("debug/debugmrmwireframe", TEXTURE_GROUP_OTHER, true);
|
||||
g_materialLines = g_pMaterialSystem->FindMaterial("debug/debugwireframevertexcolor", TEXTURE_GROUP_OTHER, true);
|
||||
g_materialFloor = g_pMaterialSystem->FindMaterial("hlmv/floor", TEXTURE_GROUP_OTHER, true);
|
||||
g_materialVertexColor = g_pMaterialSystem->FindMaterial("debug/debugvertexcolor", TEXTURE_GROUP_OTHER, true);
|
||||
g_materialShadow = g_pMaterialSystem->FindMaterial("hlmv/shadow", TEXTURE_GROUP_OTHER, true);
|
||||
|
||||
if (!parent)
|
||||
setVisible (true);
|
||||
else
|
||||
mx::setIdleWindow (this);
|
||||
|
||||
m_bSuppressResize = false;
|
||||
|
||||
m_stickyDepth = 0;
|
||||
m_bIsSticky = false;
|
||||
m_snapshotDepth = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
MatSysWindow::~MatSysWindow ()
|
||||
{
|
||||
mx::setIdleWindow (0);
|
||||
}
|
||||
|
||||
void MatSysWindow::redraw()
|
||||
{
|
||||
BaseClass::redraw();
|
||||
return;
|
||||
if ( IsLocked() )
|
||||
{
|
||||
RECT bounds;
|
||||
GetClientRect( (HWND)getHandle(), &bounds );
|
||||
bounds.bottom = bounds.top + GetCaptionHeight();
|
||||
CChoreoWidgetDrawHelper helper( this, bounds );
|
||||
HandleToolRedraw( helper );
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_FPS 250.0f
|
||||
#define MIN_TIMESTEP ( 1.0f / MAX_FPS )
|
||||
|
||||
double realtime = 0.0f;
|
||||
|
||||
void MatSysWindow::Frame( void )
|
||||
{
|
||||
static bool recursion_guard = false;
|
||||
|
||||
static double prev = 0.0;
|
||||
double curr = (double) mx::getTickCount () / 1000.0;
|
||||
double dt = ( curr - prev );
|
||||
|
||||
if ( recursion_guard )
|
||||
return;
|
||||
|
||||
recursion_guard = true;
|
||||
|
||||
// clamp to MAX_FPS
|
||||
if ( dt >= 0.0 && dt < MIN_TIMESTEP )
|
||||
{
|
||||
Sleep( max( 0, (int)( ( MIN_TIMESTEP - dt ) * 1000.0f ) ) );
|
||||
|
||||
recursion_guard = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( prev != 0.0 )
|
||||
{
|
||||
dt = min( 0.1, dt );
|
||||
|
||||
g_MDLViewer->Think( dt );
|
||||
|
||||
realtime += dt;
|
||||
}
|
||||
|
||||
prev = curr;
|
||||
|
||||
DrawFrame();
|
||||
|
||||
recursion_guard = false;
|
||||
}
|
||||
|
||||
void MatSysWindow::DrawFrame( void )
|
||||
{
|
||||
if (!g_viewerSettings.pause)
|
||||
{
|
||||
redraw ();
|
||||
}
|
||||
}
|
||||
|
||||
int MatSysWindow::handleEvent (mxEvent *event)
|
||||
{
|
||||
MDLCACHE_CRITICAL_SECTION_( g_pMDLCache );
|
||||
|
||||
int iret = 0;
|
||||
|
||||
if ( HandleToolEvent( event ) )
|
||||
{
|
||||
return iret;
|
||||
}
|
||||
|
||||
static float oldrx = 0, oldry = 0, oldtz = 50, oldtx = 0, oldty = 0;
|
||||
static float oldlrx = 0, oldlry = 0;
|
||||
static int oldx, oldy;
|
||||
|
||||
switch (event->event)
|
||||
{
|
||||
case mxEvent::Idle:
|
||||
{
|
||||
iret = 1;
|
||||
|
||||
Frame();
|
||||
}
|
||||
break;
|
||||
|
||||
case mxEvent::MouseDown:
|
||||
{
|
||||
StudioModel *pModel = models->GetActiveStudioModel();
|
||||
if (!pModel)
|
||||
break;
|
||||
oldrx = pModel->m_angles[0];
|
||||
oldry = pModel->m_angles[1];
|
||||
oldtx = pModel->m_origin[0];
|
||||
oldty = pModel->m_origin[1];
|
||||
oldtz = pModel->m_origin[2];
|
||||
oldx = (short)event->x;
|
||||
oldy = (short)event->y;
|
||||
oldlrx = g_viewerSettings.lightrot[0];
|
||||
oldlry = g_viewerSettings.lightrot[1];
|
||||
g_viewerSettings.pause = false;
|
||||
|
||||
float r = 1.0/3.0 * min( w(), h() );
|
||||
|
||||
float d = sqrt( ( float )( (event->x - w()/2) * (event->x - w()/2) + (event->y - h()/2) * (event->y - h()/2) ) );
|
||||
|
||||
if (d < r)
|
||||
g_viewerSettings.rotating = false;
|
||||
else
|
||||
g_viewerSettings.rotating = true;
|
||||
|
||||
iret = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case mxEvent::MouseDrag:
|
||||
{
|
||||
StudioModel *pModel = models->GetActiveStudioModel();
|
||||
if (!pModel)
|
||||
break;
|
||||
|
||||
if (event->buttons & mxEvent::MouseLeftButton)
|
||||
{
|
||||
if (event->modifiers & mxEvent::KeyShift)
|
||||
{
|
||||
pModel->m_origin[1] = oldty - (float) ((short)event->x - oldx) * 0.1;
|
||||
pModel->m_origin[2] = oldtz + (float) ((short)event->y - oldy) * 0.1;
|
||||
}
|
||||
else if (event->modifiers & mxEvent::KeyCtrl)
|
||||
{
|
||||
float ry = (float) (event->y - oldy);
|
||||
float rx = (float) (event->x - oldx);
|
||||
oldx = event->x;
|
||||
oldy = event->y;
|
||||
|
||||
QAngle movement = QAngle( ry, rx, 0 );
|
||||
|
||||
matrix3x4_t tmp1, tmp2, tmp3;
|
||||
AngleMatrix( g_viewerSettings.lightrot, tmp1 );
|
||||
AngleMatrix( movement, tmp2 );
|
||||
ConcatTransforms( tmp2, tmp1, tmp3 );
|
||||
MatrixAngles( tmp3, g_viewerSettings.lightrot );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!g_viewerSettings.rotating)
|
||||
{
|
||||
float ry = (float) (event->y - oldy);
|
||||
float rx = (float) (event->x - oldx);
|
||||
oldx = event->x;
|
||||
oldy = event->y;
|
||||
|
||||
QAngle movement;
|
||||
matrix3x4_t tmp1, tmp2, tmp3;
|
||||
|
||||
movement = QAngle( 0, rx, 0 );
|
||||
AngleMatrix( pModel->m_angles, tmp1 );
|
||||
AngleMatrix( movement, tmp2 );
|
||||
ConcatTransforms( tmp1, tmp2, tmp3 );
|
||||
MatrixAngles( tmp3, pModel->m_angles );
|
||||
|
||||
movement = QAngle( ry, 0, 0 );
|
||||
AngleMatrix( pModel->m_angles, tmp1 );
|
||||
AngleMatrix( movement, tmp2 );
|
||||
ConcatTransforms( tmp2, tmp1, tmp3 );
|
||||
MatrixAngles( tmp3, pModel->m_angles );
|
||||
}
|
||||
else
|
||||
{
|
||||
float ang1 = (180 / 3.1415) * atan2( oldx - w()/2.0, oldy - h()/2.0 );
|
||||
float ang2 = (180 / 3.1415) * atan2( event->x - w()/2.0, event->y - h()/2.0 );
|
||||
oldx = event->x;
|
||||
oldy = event->y;
|
||||
|
||||
QAngle movement = QAngle( 0, 0, ang2 - ang1 );
|
||||
|
||||
matrix3x4_t tmp1, tmp2, tmp3;
|
||||
AngleMatrix( pModel->m_angles, tmp1 );
|
||||
AngleMatrix( movement, tmp2 );
|
||||
ConcatTransforms( tmp2, tmp1, tmp3 );
|
||||
MatrixAngles( tmp3, pModel->m_angles );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (event->buttons & mxEvent::MouseRightButton)
|
||||
{
|
||||
pModel->m_origin[0] = oldtx + (float) ((short)event->y - oldy) * 0.1;
|
||||
pModel->m_origin[0] = clamp( pModel->m_origin[0], 8.0f, 1024.0f );
|
||||
}
|
||||
redraw ();
|
||||
|
||||
iret = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case mxEvent::KeyDown:
|
||||
{
|
||||
iret = 1;
|
||||
switch (event->key)
|
||||
{
|
||||
default:
|
||||
iret = 0;
|
||||
break;
|
||||
case 116: // F5
|
||||
{
|
||||
g_MDLViewer->Refresh();
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
{
|
||||
int iSeq = models->GetActiveStudioModel()->GetSequence();
|
||||
if (iSeq == models->GetActiveStudioModel()->SetSequence (iSeq + 1))
|
||||
{
|
||||
g_pControlPanel->setSequence( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pControlPanel->setSequence( iSeq + 1 );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 27:
|
||||
if (!getParent ()) // fullscreen mode ?
|
||||
mx::quit ();
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
g_viewerSettings.showGround = !g_viewerSettings.showGround;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
g_viewerSettings.showHitBoxes = !g_viewerSettings.showHitBoxes;
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
g_viewerSettings.showBones = !g_viewerSettings.showBones;
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
g_viewerSettings.showBackground = !g_viewerSettings.showBackground;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
g_viewerSettings.showMovement = !g_viewerSettings.showMovement;
|
||||
break;
|
||||
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
g_viewerSettings.renderMode = event->key - '1';
|
||||
break;
|
||||
|
||||
case '-':
|
||||
g_viewerSettings.speedScale -= 0.1f;
|
||||
if (g_viewerSettings.speedScale < 0.0f)
|
||||
g_viewerSettings.speedScale = 0.0f;
|
||||
break;
|
||||
|
||||
case '+':
|
||||
g_viewerSettings.speedScale += 0.1f;
|
||||
if (g_viewerSettings.speedScale > 5.0f)
|
||||
g_viewerSettings.speedScale = 5.0f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
} // switch (event->event)
|
||||
|
||||
return iret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
drawFloor ()
|
||||
{
|
||||
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
||||
pRenderContext->Bind(g_materialFloor);
|
||||
pRenderContext->MatrixMode(MATERIAL_MODEL);
|
||||
pRenderContext->PushMatrix();
|
||||
pRenderContext->LoadIdentity();
|
||||
pRenderContext->MatrixMode(MATERIAL_VIEW);
|
||||
pRenderContext->PushMatrix();
|
||||
pRenderContext->LoadIdentity();
|
||||
{
|
||||
IMesh* pMesh = pRenderContext->GetDynamicMesh();
|
||||
CMeshBuilder meshBuilder;
|
||||
meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
|
||||
|
||||
float dist=-15000.0f;
|
||||
float tMin=0, tMax=1;
|
||||
|
||||
meshBuilder.Position3f(-dist, dist, dist);
|
||||
meshBuilder.TexCoord2f( 0, tMin,tMax );
|
||||
meshBuilder.Color4ub( 255, 255, 255, 255 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3f( dist, dist, dist);
|
||||
meshBuilder.TexCoord2f( 0, tMax,tMax );
|
||||
meshBuilder.Color4ub( 255, 255, 255, 255 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3f( dist,-dist, dist);
|
||||
meshBuilder.TexCoord2f( 0, tMax,tMin );
|
||||
meshBuilder.Color4ub( 255, 255, 255, 255 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3f(-dist,-dist, dist);
|
||||
meshBuilder.TexCoord2f( 0, tMin,tMin );
|
||||
meshBuilder.Color4ub( 255, 255, 255, 255 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.End();
|
||||
pMesh->Draw();
|
||||
}
|
||||
pRenderContext->MatrixMode(MATERIAL_MODEL);
|
||||
pRenderContext->PopMatrix();
|
||||
pRenderContext->MatrixMode(MATERIAL_VIEW);
|
||||
pRenderContext->PopMatrix();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
setupRenderMode ()
|
||||
{
|
||||
}
|
||||
|
||||
void MatSysWindow::SuppressBufferSwap( bool bSuppress )
|
||||
{
|
||||
m_bSuppressSwap = bSuppress;
|
||||
}
|
||||
|
||||
void MatSysWindow::draw ()
|
||||
{
|
||||
int i;
|
||||
|
||||
g_pMaterialSystem->BeginFrame( 0 );
|
||||
CUtlVector< StudioModel * > modellist;
|
||||
|
||||
modellist.AddToTail( models->GetActiveStudioModel() );
|
||||
|
||||
if ( models->CountVisibleModels() > 0 )
|
||||
{
|
||||
modellist.RemoveAll();
|
||||
for ( i = 0; i < models->Count(); i++ )
|
||||
{
|
||||
if ( models->IsModelShownIn3DView( i ) )
|
||||
{
|
||||
modellist.AddToTail( models->GetStudioModel( i ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
||||
pRenderContext->ClearBuffers(true, true);
|
||||
|
||||
int captiony = GetCaptionHeight();
|
||||
int viewh = h2() - captiony;
|
||||
|
||||
g_pMaterialSystem->SetView( (HWND)getHandle() );
|
||||
|
||||
pRenderContext->Viewport( 0, captiony, w2(), viewh );
|
||||
|
||||
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
|
||||
pRenderContext->LoadIdentity( );
|
||||
pRenderContext->PerspectiveX(20.0f, (float)w2() / (float)viewh, 1.0f, 20000.0f);
|
||||
|
||||
pRenderContext->MatrixMode( MATERIAL_VIEW );
|
||||
pRenderContext->LoadIdentity( );
|
||||
// FIXME: why is this needed? Doesn't SetView() override this?
|
||||
pRenderContext->Rotate( -90, 1, 0, 0 ); // put Z going up
|
||||
pRenderContext->Rotate( -90, 0, 0, 1 );
|
||||
|
||||
int modelcount = modellist.Count();
|
||||
int countover2 = modelcount / 2;
|
||||
int ydelta = g_pControlPanel->GetModelGap();
|
||||
int yoffset = -countover2 * ydelta;
|
||||
for ( i = 0 ; i < modelcount; i++ )
|
||||
{
|
||||
modellist[ i ]->IncrementFramecounter( );
|
||||
|
||||
Vector oldtrans = modellist[ i ]->m_origin;
|
||||
|
||||
modellist[ i ]->m_origin[ 1 ] = oldtrans[ 1 ] + yoffset;
|
||||
yoffset += ydelta;
|
||||
|
||||
modellist[ i ]->GetStudioRender()->BeginFrame();
|
||||
modellist[ i ]->DrawModel();
|
||||
modellist[ i ]->GetStudioRender()->EndFrame();
|
||||
|
||||
modellist[ i ]->m_origin = oldtrans;
|
||||
}
|
||||
|
||||
//
|
||||
// draw ground
|
||||
//
|
||||
if (g_viewerSettings.showGround)
|
||||
{
|
||||
drawFloor ();
|
||||
}
|
||||
|
||||
if (!m_bSuppressSwap)
|
||||
{
|
||||
g_pMaterialSystem->SwapBuffers();
|
||||
}
|
||||
|
||||
g_pMaterialSystem->EndFrame();
|
||||
}
|
||||
|
||||
void MatSysWindow::EnableStickySnapshotMode( )
|
||||
{
|
||||
m_stickyDepth++;
|
||||
}
|
||||
|
||||
void MatSysWindow::DisableStickySnapshotMode( )
|
||||
{
|
||||
if (--m_stickyDepth == 0)
|
||||
{
|
||||
if (m_bIsSticky)
|
||||
{
|
||||
m_bIsSticky = false;
|
||||
|
||||
HWND wnd = (HWND)getHandle();
|
||||
|
||||
// Move back to original position
|
||||
SetWindowPlacement( wnd, &m_wp );
|
||||
|
||||
SuppressResize( false );
|
||||
|
||||
SetCursor( m_hPrevCursor );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MatSysWindow::PushSnapshotMode( int nSnapShotSize )
|
||||
{
|
||||
if (m_snapshotDepth++ == 0)
|
||||
{
|
||||
if (m_stickyDepth)
|
||||
{
|
||||
if (m_bIsSticky)
|
||||
return;
|
||||
|
||||
m_bIsSticky = true;
|
||||
m_hPrevCursor = SetCursor( LoadCursor( NULL, IDC_WAIT ) );
|
||||
}
|
||||
|
||||
SuppressResize( true );
|
||||
|
||||
RECT rcClient;
|
||||
HWND wnd = (HWND)getHandle();
|
||||
|
||||
GetWindowPlacement( wnd, &m_wp );
|
||||
|
||||
GetClientRect( wnd, &rcClient );
|
||||
|
||||
MoveWindow( wnd, 0, 0, nSnapShotSize + 16, nSnapShotSize + 16, TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MatSysWindow::PopSnapshotMode( )
|
||||
{
|
||||
if (--m_snapshotDepth == 0)
|
||||
{
|
||||
if (m_stickyDepth == 0)
|
||||
{
|
||||
HWND wnd = (HWND)getHandle();
|
||||
|
||||
// Move back to original position
|
||||
SetWindowPlacement( wnd, &m_wp );
|
||||
|
||||
SuppressResize( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MatSysWindow::TakeSnapshotRect( const char *pFilename, int x, int y, int w, int h )
|
||||
{
|
||||
int i;
|
||||
HANDLE hf;
|
||||
BITMAPFILEHEADER hdr;
|
||||
BITMAPINFOHEADER bi;
|
||||
DWORD dwTmp, imageSize;
|
||||
byte *hp, b, *pBlue, *pRed;
|
||||
|
||||
w = ( w + 3 ) & ~3;
|
||||
|
||||
imageSize = w * h * 3;
|
||||
// Create the file
|
||||
hf = CreateFile( pFilename, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
|
||||
if( hf == INVALID_HANDLE_VALUE )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// file header
|
||||
hdr.bfType = 0x4d42; // 'BM'
|
||||
hdr.bfSize = (DWORD) ( sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + imageSize );
|
||||
hdr.bfReserved1 = 0;
|
||||
hdr.bfReserved2 = 0;
|
||||
hdr.bfOffBits = (DWORD) ( sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) );
|
||||
|
||||
if( !WriteFile( hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER), (LPDWORD) &dwTmp, NULL ) )
|
||||
Error( "Couldn't write file header to snapshot.\n" );
|
||||
|
||||
// bitmap header
|
||||
bi.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bi.biWidth = w;
|
||||
bi.biHeight = h;
|
||||
bi.biPlanes = 1;
|
||||
bi.biBitCount = 24;
|
||||
bi.biCompression = BI_RGB;
|
||||
bi.biSizeImage = 0; //vid.rowbytes * vid.height;
|
||||
bi.biXPelsPerMeter = 0;
|
||||
bi.biYPelsPerMeter = 0;
|
||||
bi.biClrUsed = 0;
|
||||
bi.biClrImportant = 0;
|
||||
|
||||
if( !WriteFile( hf, (LPVOID) &bi, sizeof(BITMAPINFOHEADER), (LPDWORD) &dwTmp, NULL ) )
|
||||
Error( "Couldn't write bitmap header to snapshot.\n" );
|
||||
|
||||
// bitmap bits
|
||||
hp = (byte *) malloc(imageSize);
|
||||
|
||||
if (hp == NULL)
|
||||
Error( "Couldn't allocate bitmap header to snapshot.\n" );
|
||||
|
||||
// Get Bits from the renderer
|
||||
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
||||
pRenderContext->ReadPixels( x, y, w, h, hp, IMAGE_FORMAT_RGB888 );
|
||||
|
||||
// Invert vertically for BMP format
|
||||
for (i = 0; i < h / 2; i++)
|
||||
{
|
||||
byte *top = hp + i * w * 3;
|
||||
byte *bottom = hp + (h - i - 1) * w * 3;
|
||||
for (int j = 0; j < w * 3; j++)
|
||||
{
|
||||
b = *top;
|
||||
*top = *bottom;
|
||||
*bottom = b;
|
||||
top++;
|
||||
bottom++;
|
||||
}
|
||||
}
|
||||
|
||||
// Reverse Red and Blue
|
||||
pRed = hp;
|
||||
pBlue = pRed + 2;
|
||||
for(i = 0; i < w * h;i++)
|
||||
{
|
||||
b = *pRed;
|
||||
*pRed = *pBlue;
|
||||
*pBlue = b;
|
||||
pBlue += 3;
|
||||
pRed += 3;
|
||||
}
|
||||
|
||||
if( !WriteFile( hf, (LPVOID)hp, imageSize, (LPDWORD) &dwTmp, NULL ) )
|
||||
Error( "Couldn't write bitmap data snapshot.\n" );
|
||||
|
||||
free(hp);
|
||||
|
||||
// clean up
|
||||
if( !CloseHandle( hf ) )
|
||||
Error( "Couldn't close file for snapshot.\n" );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool MatSysWindow::IsSuppressingResize( void )
|
||||
{
|
||||
return m_bSuppressResize;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : suppress -
|
||||
//-----------------------------------------------------------------------------
|
||||
void MatSysWindow::SuppressResize( bool suppress )
|
||||
{
|
||||
m_bSuppressResize = suppress;
|
||||
}
|
||||
|
||||
void
|
||||
MatSysWindow::TakeScreenShot (const char *filename)
|
||||
{
|
||||
redraw ();
|
||||
int w = w2 ();
|
||||
int h = h2 ();
|
||||
|
||||
mxImage *image = new mxImage ();
|
||||
if (image->create (w, h, 24))
|
||||
{
|
||||
#if 0
|
||||
glReadBuffer (GL_FRONT);
|
||||
glReadPixels (0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, image->data);
|
||||
#else
|
||||
HDC hdc = GetDC ((HWND) getHandle ());
|
||||
byte *data = (byte *) image->data;
|
||||
int i = 0;
|
||||
for (int y = 0; y < h; y++)
|
||||
{
|
||||
for (int x = 0; x < w; x++)
|
||||
{
|
||||
COLORREF cref = GetPixel (hdc, x, y);
|
||||
data[i++] = (byte) ((cref >> 0)& 0xff);
|
||||
data[i++] = (byte) ((cref >> 8) & 0xff);
|
||||
data[i++] = (byte) ((cref >> 16) & 0xff);
|
||||
}
|
||||
}
|
||||
ReleaseDC ((HWND) getHandle (), hdc);
|
||||
#endif
|
||||
if (!mxTgaWrite (filename, image))
|
||||
mxMessageBox (this, "Error writing screenshot.", g_appTitle, MX_MB_OK | MX_MB_ERROR);
|
||||
|
||||
delete image;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user