0

我正在创建一个应用程序,该应用程序使用 directx 在来自网络摄像头的 win32 捕获窗口上渲染图像,但我的窗口每隔一帧闪烁一次。(这似乎来自directx每帧清屏,闪烁颜色与清除颜色相同)

有什么办法可以解决这个问题吗?(我无法弄清楚如何在不使用 win32 的情况下提供摄像头供稿)

这是我的项目代码:

Windows.cpp:

#include <windows.h>
#include <vfw.h>
#include <wchar.h>
#include "Game.h"
#include "resource.h"
#include "Mouse.h"

LRESULT CALLBACK WindowProc (HWND, UINT, WPARAM, LPARAM);

static KeyboardServer kServ;
static MouseServer mServ;

char szAppName [] = TEXT("Webcam");
HWND camhwnd;
HDC hdc ;
HDC hdcMem;
PAINTSTRUCT ps;
HBITMAP hbm;
RECT rc;

//WinMain -- Main Window
int WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) {

    HWND hwnd;
    MSG msg;

    WNDCLASS wc;
    wc.style = CS_HREDRAW|CS_VREDRAW;
    wc.lpfnWndProc = WindowProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(GetModuleHandle(NULL), IDI_APPLICATION);
    wc.hCursor = LoadCursor (NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH) (COLOR_WINDOW+1);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = szAppName;

    RegisterClass (&wc);


    hwnd = CreateWindow (szAppName,szAppName,WS_POPUP | WS_VISIBLE,0,0,1920,1080,0,0,hInstance,0);


    ShowWindow (hwnd,SW_SHOW);
    UpdateWindow (hwnd);

    ShowWindow(camhwnd,SW_SHOW);
    SendMessage(camhwnd,WM_CAP_DRIVER_CONNECT,0,0);
    SendMessage(camhwnd, WM_CAP_SET_SCALE, true , 0);
    SendMessage(camhwnd, WM_CAP_SET_PREVIEWRATE, 66, 0);
    SendMessage(camhwnd, WM_CAP_SET_PREVIEW, true , 0);



    Game theGame( hwnd,kServ,mServ );


    while( msg.message != WM_QUIT ) {
        if( PeekMessage( &msg,NULL,0,0,PM_REMOVE ) ) {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
        else {
            theGame.Go();
        }
    }

    return msg.wParam;
}

//Main Window Procedure WindowProc
LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
    HINSTANCE hInstance = GetModuleHandle(NULL);

    switch (message) {
        case WM_CREATE: {

            camhwnd = capCreateCaptureWindow ("camera window", WS_CHILD , 0, 0, 1920, 1080, hwnd, 0);
            SendMessage(camhwnd,WM_CAP_DRIVER_CONNECT,0,0);
            SendMessage(camhwnd,WM_CAP_DLG_VIDEOSOURCE,0,0);

            break;

        }

        case WM_DESTROY: {
            SendMessage(camhwnd, WM_CAP_DRIVER_DISCONNECT, 0, 0);
            PostQuitMessage(0);
            break;
        }

        default:
            return DefWindowProc(hwnd, message, wParam, lParam);
    }
    return 0;
}

Game.cpp 的一部分:

void Game::Go()
{
    gfx.BeginFrame();
    ComposeFrame();
    gfx.EndFrame();
}

最后,一段 D3DGraphics.cpp:

D3DGraphics::D3DGraphics( HWND hWnd )
{
    HRESULT result;

    backRect.pBits = NULL;

    pDirect3D = Direct3DCreate9( D3D_SDK_VERSION );
    assert( pDirect3D != NULL );

    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory( &d3dpp,sizeof( d3dpp ) );
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
    d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
    d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;

    result = pDirect3D->CreateDevice( D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd,
        D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE,&d3dpp,&pDevice );
    assert( !FAILED( result ) );

    result = pDevice->GetBackBuffer( 0,0,D3DBACKBUFFER_TYPE_MONO,&pBackBuffer );
    assert( !FAILED( result ) );
}

void D3DGraphics::BeginFrame()
{
    HRESULT result;

    result = pDevice->Clear( 0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(255,255,255),0.0f,0 );
    assert( !FAILED( result ) );

    result = pBackBuffer->LockRect( &backRect,NULL,NULL );
    assert( !FAILED( result ) );
}

void D3DGraphics::EndFrame()
{
    HRESULT result;

    result = pBackBuffer->UnlockRect();
    assert( !FAILED( result ) );

    result = pDevice->Present( NULL,NULL,NULL,NULL );
    assert( !FAILED( result ) );
}
4

1 回答 1

0

您可以尝试将WS_CLIPSIBLINGS和添加WS_CLIPCHILDREN到主窗口。有关这些窗口样式的更多信息,请点击此处

于 2013-05-25T16:28:41.947 回答