⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bmpmix9.cpp

📁 最近在学习directshow, Directshow实务精选的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//------------------------------------------------------------------------------
// File: BmpMix9.cpp
//
// Desc: DirectShow sample code - a bitmap-mixing VMR9 media file player
//       using Direct3D9 surfaces
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//------------------------------------------------------------------------------

#include "bmpmix9.h"
#include "vmrutil.h"

// Constants
#define MAX_LOADSTRING 100
#define TIMER_INTERVAL 500      // Refresh bitmap every 500ms
#define ALPHA_VALUE    0.6f     // Alpha value for bitmap (0.0 to 1.0)
#define BMP_SIZE_X     0.3f     // Width of bitmap in comp. space
#define BMP_SIZE_Y     0.3f     // Height of bitmap in comp. space
#define MOVE_TOLERANCE 0.05f    // Min. distance for mouse move before refresh
#define BMP_INIT_X     0.6f
#define BMP_INIT_Y     0.6f

// Global Variables
HINSTANCE hInst;                         // current instance
TCHAR szTitle[MAX_LOADSTRING];           // title bar text
TCHAR szWindowClass[MAX_LOADSTRING];
UINT_PTR g_nTimerID = 0xFCDCACCC;
int g_nCurrentImage=0;
float g_fCurrentX=BMP_INIT_X, g_fCurrentY=BMP_INIT_Y;
BOOL g_bRunning=FALSE;

// Foward declarations of functions included in this code module
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int, HWND& );
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK    AboutDlgProc(HWND, UINT, WPARAM, LPARAM);
void OnPaint(HWND hwnd);
void OnFileClose( HWND hWnd );
void HandleMouseClick(LPARAM lParam);

// DirectShow and D3D routines
HRESULT             StartGraph(HWND window);
HRESULT             D3DStart( HWND hWnd );
BOOL                GetImageDimensions(long& lHeight, long& lWidth);
HRESULT             SetInitialAlphaBitmap();
HRESULT             UpdateAlphaBitmap(int nIndex);
HRESULT             SetUpAlphaBitmap( VMR9AlphaBitmap& alphaBitmap, int nIndex );
void                ClearD3D(void);
void                ClearDirectShow(void);

// DirectShow objects
HWND                            g_hWnd;
CComPtr<IGraphBuilder>          g_pGB;
CComPtr<IBaseFilter>            g_pVMR;
CComPtr<IVMRFilterConfig9>      g_pFilterConfig;
CComPtr<IVMRWindowlessControl9> g_pWC;
CComPtr<IMediaControl>          g_pMC;
CComPtr<IVMRMixerBitmap9>       g_pMixerBitmap;

// D3D objects
CComPtr<IDirect3D9>             g_pD3D;
CComPtr<IDirect3DDevice9>       g_pD3DDevice;

const int   NUMBITMAPS          = 3;
CComPtr<IDirect3DSurface9>      g_pSurfaces[NUMBITMAPS];



int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
    int nReturn = -1;

    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    // Verify that the VMR9 is present on this system
    if(!VerifyVMR9())
    {
        CoUninitialize();
        return FALSE;
    }

    __try 
    {
        MSG msg;
        HACCEL hAccelTable;

        // Initialize global strings
        LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
        LoadString(hInstance, IDC_BMPMIX9, szWindowClass, MAX_LOADSTRING);
        if (!MyRegisterClass(hInstance)) 
        {
            MessageBox(NULL, TEXT("Failed to register main window class!"), 
                       TEXT("BmpMix9"), MB_ICONERROR | MB_OK);
            __leave;
        }

        // Perform application initialization
        if (!InitInstance (hInstance, nCmdShow, g_hWnd)) 
        {
            MessageBox(NULL, TEXT("Failed to initialize main window!"), 
                       TEXT("BmpMix9"), MB_ICONERROR | MB_OK);
            __leave;
        }

        hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_BMPMIX9);

        // Main message loop
        while (GetMessage(&msg, NULL, 0, 0)) 
        {
            if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }

        nReturn = (int) msg.wParam;
    }
    __finally
    {
        // Delete resources
        // Release the CComPtr interfaces before uninitializing COM
        ClearD3D();
        ClearDirectShow();
        CoUninitialize();
    }
    
    return nReturn;
}

_bstr_t GetMoviePath()
{
    OPENFILENAME ofn;
    ZeroMemory(&ofn, sizeof(ofn));

    TCHAR szBuffer[MAX_PATH];
    szBuffer[0] = NULL;

    // Initialize the open file dialog structure
    static const TCHAR szFilter[]  
                            = TEXT("Video Files (.ASF, .AVI, .MPG, .MPEG, .VOB, .QT, .WMV)\0*.ASF;*.AVI;*.MPG;*.MPEG;*.VOB;*.QT;*.WMV\0") \
                              TEXT("All Files (*.*)\0*.*\0\0");
    ofn.lStructSize         = sizeof(OPENFILENAME);
    ofn.hwndOwner           = g_hWnd;
    ofn.hInstance           = NULL;
    ofn.lpstrFilter         = szFilter;
    ofn.nFilterIndex        = 1;
    ofn.lpstrCustomFilter   = NULL;
    ofn.nMaxCustFilter      = 0;
    ofn.lpstrFile           = szBuffer;
    ofn.nMaxFile            = MAX_PATH;
    ofn.lpstrFileTitle      = NULL;
    ofn.nMaxFileTitle       = 0;
    ofn.lpstrInitialDir     = NULL;
    ofn.lpstrTitle          = TEXT("Select a video file to play...");
    ofn.Flags               = OFN_HIDEREADONLY;
    ofn.nFileOffset         = 0;
    ofn.nFileExtension      = 0;
    ofn.lpstrDefExt         = TEXT("AVI");
    ofn.lCustData           = 0L;
    ofn.lpfnHook            = NULL;
    ofn.lpTemplateName  = NULL; 
    
    if (GetOpenFileName (&ofn))  // user specified a file
        return _bstr_t( szBuffer );
    else    
        return "";
}

void ClearD3D(void)
{
    // Initialize global data
    for( int i = 0; i < NUMBITMAPS; ++i )
        g_pSurfaces[i] = NULL;

    // Zero CComPtrs to release interfaces and free memory
    g_pD3DDevice = NULL;
    g_pD3D = NULL;
}

void ClearDirectShow(void)
{
    // Zero CComPtrs to release interfaces and free memory
    g_pMixerBitmap  = NULL;
    g_pFilterConfig = NULL;

    g_pMC  = NULL;
    g_pWC  = NULL;
    g_pVMR = NULL;
    g_pGB  = NULL;

    g_fCurrentX = BMP_INIT_X;
    g_fCurrentY = BMP_INIT_Y;
}

HRESULT StartGraph(HWND hwnd)
{
    HRESULT hr;

    // Prompt the user for a media file name
    _bstr_t path = GetMoviePath();
    if( ! path.length() )
    {
        return E_FAIL;
    }

    // Stop any currently running timer
    KillTimer(g_hWnd, g_nTimerID);
    UpdateWindow(g_hWnd);

    // Initialize global data
    ClearDirectShow();

    // Create a filter graph   
    FAIL_RET( g_pGB.CoCreateInstance(CLSID_FilterGraph) )

    // Create a VMR9 rendering filter and add it to the empty graph
    FAIL_RET( g_pVMR.CoCreateInstance(CLSID_VideoMixingRenderer9, 
                                      NULL, CLSCTX_INPROC_SERVER) )

    FAIL_RET( g_pGB->AddFilter(g_pVMR, L"Video Mixing Renderer 9") )
    
    // Get the filter configuration interface and set VMR to Windowless rendering
    FAIL_RET( g_pVMR->QueryInterface(IID_IVMRFilterConfig9, 
              reinterpret_cast<void**>(&g_pFilterConfig)) )

    FAIL_RET( g_pFilterConfig->SetRenderingMode( VMR9Mode_Windowless ) )
    
    // Bound the video clipping region to our application window
    FAIL_RET( g_pVMR->QueryInterface(IID_IVMRWindowlessControl9, 
              reinterpret_cast<void**>(&g_pWC)) )

    FAIL_RET( g_pWC->SetVideoClippingWindow( g_hWnd ) )

    // Position the video within our application window
    RECT clientRect;
    if( ::GetClientRect(g_hWnd, &clientRect ) )
    {
        FAIL_RET( g_pWC->SetVideoPosition( NULL, &clientRect ) )
    }

    // Get the remaining necessary COM interfaces
    FAIL_RET( g_pGB->QueryInterface(IID_IMediaControl, 
              reinterpret_cast<void**>(&g_pMC)) )

    FAIL_RET( g_pVMR->QueryInterface(IID_IVMRMixerBitmap9, 
              reinterpret_cast<void**>(&g_pMixerBitmap)) )

    // Initialize Direct3D 9
    FAIL_RET( D3DStart( hwnd ) )

    // Render and run the user-selected media file.
    FAIL_RET( RenderFileToVMR9(g_pGB, path, g_pVMR));

    // Associate an alpha-blended bitmap with the VMR
    FAIL_RET( SetInitialAlphaBitmap( ) );

    FAIL_RET( g_pMC->Run() )

    // Start the timer for updating the alpha-blended bitmap
    SetTimer( g_hWnd, g_nTimerID, TIMER_INTERVAL, NULL ); 

    g_bRunning = TRUE;
    return hr;
}

HRESULT D3DStart(HWND hWnd)
{
    HRESULT hr;

    ClearD3D();

    // Initialize D3D
    g_pD3D.Release();  // just in case this is called twice
    g_pD3D.Attach(Direct3DCreate9( D3D_SDK_VERSION ) );
    if( g_pD3D == NULL )
        return E_FAIL;

    D3DDISPLAYMODE d3ddm;
    FAIL_RET( g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) );

    D3DPRESENT_PARAMETERS d3dpp; 
    ZeroMemory( &d3dpp, sizeof(d3dpp) );
    d3dpp.Windowed         = TRUE;
    d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = d3ddm.Format;
    d3dpp.hDeviceWindow    = g_hWnd;

    FAIL_RET( g_pD3D->CreateDevice( 
        D3DADAPTER_DEFAULT, // always the primary display adapter
        D3DDEVTYPE_HAL,
        NULL,
        D3DCREATE_SOFTWARE_VERTEXPROCESSING,
        &d3dpp,
        &g_pD3DDevice) )

    // Read the dimensions of our alpha-blended bitmap
    long lWidth, lHeight;
    if( ! GetImageDimensions( lHeight, lWidth ) )
        return E_FAIL;

    // Create an offscreen D3D surface for each bitmap (in the set of 3)
    for( int i = 0; i < NUMBITMAPS; ++i )
    {
        FAIL_RET( g_pD3DDevice->CreateOffscreenPlainSurface( 
            lWidth, lHeight,
            D3DFMT_X8R8G8B8,
            D3DPOOL_SYSTEMMEM,
            &g_pSurfaces[i], NULL ) );
    }

    // Load the bitmaps into memory
    FAIL_RET( D3DXLoadSurfaceFromResource (
            g_pSurfaces[0],
            NULL,       // palette
            NULL,       // entire surface - created to be the proper height
            GetModuleHandle(NULL), // current module
            MAKEINTRESOURCE(IDB_BITMAP1),
            NULL,       // entire image
            D3DX_DEFAULT, 
            0,          // disable color key
            NULL        // source info
            ));

    FAIL_RET( D3DXLoadSurfaceFromResource (
            g_pSurfaces[1],
            NULL,
            NULL,
            GetModuleHandle(NULL),
            MAKEINTRESOURCE(IDB_BITMAP2),
            NULL, // entire image
            D3DX_DEFAULT, 
            0,
            NULL
            ));

    FAIL_RET( D3DXLoadSurfaceFromResource (
            g_pSurfaces[2],
            NULL,
            NULL,
            GetModuleHandle(NULL),
            MAKEINTRESOURCE(IDB_BITMAP3),
            NULL, // entire image
            D3DX_DEFAULT, 
            0,
            NULL
            ));

    return hr;
}

BOOL GetImageDimensions(long& lHeight, long& lWidth)
{
    BOOL ret = false;

    HANDLE hBitmap = LoadImage(::GetModuleHandle(NULL),
                              MAKEINTRESOURCE(IDB_BITMAP1),
                              IMAGE_BITMAP,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -