diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /utils/hlfaceposer/matsyswin.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'utils/hlfaceposer/matsyswin.cpp')
| -rw-r--r-- | utils/hlfaceposer/matsyswin.cpp | 806 |
1 files changed, 806 insertions, 0 deletions
diff --git a/utils/hlfaceposer/matsyswin.cpp b/utils/hlfaceposer/matsyswin.cpp new file mode 100644 index 0000000..7675ddf --- /dev/null +++ b/utils/hlfaceposer/matsyswin.cpp @@ -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; + } +} |