📄 3dvideo.cpp
字号:
goto L_EXIT;
}
GUID subtype = GUID_NULL;
SIZE sz = {0, 0};
float fps = 0.0f;
hr = g_vg->GetVideoCaptureFormat(&subtype, &sz, &fps);
char szFormat[64];
GUIDToFriendlyStr(subtype, szFormat);
char str[256];
sprintf(str, "Format: %s\r\n"
"Width: %u\r\n"
"Height: %u\r\n"
"FPS: %.2f",
szFormat, sz.cx, sz.cy, fps);
MessageBox(g_hwndMain, str, "Actual Capture Format", MB_OK | MB_ICONINFORMATION);
IMediaControl *mc = (IMediaControl*)g_vg->GetMediaControl();
if(mc)
mc->Run();
g_bLocked = FALSE;
}
L_EXIT:
g_bLocked = FALSE;
}
//
//
void UpdateCaption()
{
char str[128];
GetProcessTimes(GetCurrentProcess(), &t, &t, &k2, &u2);
__int64 dt = (*(__int64*)&k2.dwLowDateTime - *(__int64*)&k1.dwLowDateTime) +
(*(__int64*)&u2.dwLowDateTime - *(__int64*)&u1.dwLowDateTime);
k1 = k2;
u1 = u2;
if(!dt)
dt = 1;
sprintf(str, "Estimated fps: %.2f", (float)(long)n_frames / (0.0000001f * dt));
n_frames = 0;
SetWindowText(g_hwndMain, str);
}
//
//
void ReleaseDeviceObjects()
{
SAFE_RELEASE(surf_video);
SAFE_RELEASE(tx_video);
}
//
//
HRESULT CreateDeviceObjects()
{
ReleaseDeviceObjects();
device->SetRenderState(D3DRS_LIGHTING, FALSE);
device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
device->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);
device->SetRenderState(D3DRS_ALPHAREF, 0x00);
device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
return S_OK;
}
//
//
void D3DCleanup()
{
ReleaseDeviceObjects();
SAFE_RELEASE(device);
SAFE_RELEASE(d3d);
}
//
//
HRESULT ResetDevice()
{
WaitForSingleObject(mutex, INFINITE);
ReleaseDeviceObjects();
if(!d3d)
{
d3d = Direct3DCreate9(D3D_SDK_VERSION);
if(!d3d)
{
hr = E_FAIL;
goto L_EXIT;
}
}
RECT rc;
GetClientRect(g_hwndMain, &rc);
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.BackBufferWidth = rc.right - rc.left;
d3dpp.BackBufferHeight = rc.bottom - rc.top;
if((!d3dpp.BackBufferWidth) || (!d3dpp.BackBufferHeight))
{
hr = E_FAIL;
goto L_EXIT;
}
d3dpp.BackBufferCount = 1;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
d3dpp.Windowed = TRUE;
if(!device)
hr = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hwndMain,
D3DCREATE_PUREDEVICE | D3DCREATE_HARDWARE_VERTEXPROCESSING,
&d3dpp, &device);
else
hr = device->Reset(&d3dpp);
if(FAILED(hr))
goto L_EXIT;
hr = CreateDeviceObjects();
if(FAILED(hr))
{
D3DCleanup();
goto L_EXIT;
}
repaint = TRUE;
L_EXIT:
ReleaseMutex(mutex);
return hr;
}
//
//
HRESULT ProcessInput()
{
repaint = TRUE;
return S_OK;
}
//
// TexelToFloat
inline float TexelToFloat(long tx, long mx)
{
return (0.5f + tx) / mx;
}
//
//
void Draw3DScene()
{
D3DXMATRIX mxProj;
float aspect = (float)(long)d3dpp.BackBufferWidth / (long)d3dpp.BackBufferHeight;
D3DXMatrixPerspectiveFovLH(&mxProj, fovy, aspect, zNear, zFar);
device->SetTransform(D3DTS_PROJECTION, &mxProj);
D3DXMATRIX mxView;
D3DXVECTOR3 Eye(0.0f, 0.0f, -2.1f),
At(0.0f, 0.0f, 0.0f),
Up(0.0f, 1.0f, 0.0f);
D3DXMatrixLookAtLH(&mxView, &Eye, &At, &Up);
device->SetTransform(D3DTS_VIEW, &mxView);
if((g_bLocked) || (!tx_video))
{
device->Clear(0, NULL, D3DCLEAR_TARGET, back_color, 1.0f, 0);
return;
}
long cx = g_vg->GetCX(),
cy = g_vg->GetCY();
long aspect_x = g_vg->GetAspectX(),
aspect_y = g_vg->GetAspectY();
device->Clear(0, NULL, D3DCLEAR_TARGET, back_color, 1.0f, 0);
struct V_3D
{
D3DXVECTOR3 position;
DWORD color;
float u, v;
} vx[4];
float u0, u1, v0, v1;
u0 = TexelToFloat(0, cx);
u1 = TexelToFloat(cx - 1, cx);
v0 = TexelToFloat(0, cy);
v1 = TexelToFloat(cy - 1, cy);
RECT rc_frame = {0, 0, d3dpp.BackBufferWidth, d3dpp.BackBufferHeight};
RECT rc_top, rc_bottom;
FindRects(cx, cy, aspect_x, aspect_y, rc_frame, rc_top, rc_bottom);
float x, y;
if(rc_frame.right - rc_frame.left >= rc_frame.bottom - rc_frame.top)
{
x = 1.0f;
y = (float)(rc_frame.bottom - rc_frame.top) / (rc_frame.right - rc_frame.left);
}
else
{
y = 1.0f;
x = (float)(rc_frame.right - rc_frame.left) / (rc_frame.bottom - rc_frame.top);
}
vx[0].position = D3DXVECTOR3(-x, -y, 0.0f);
vx[0].color = 0xffffffff;
vx[0].u = u0;
vx[0].v = v1;
vx[1].position = D3DXVECTOR3(-x, y, 0.0f);
vx[1].color = 0xffffffff;
vx[1].u = u0;
vx[1].v = v0;
vx[2].position = D3DXVECTOR3( x, -y, 0.0f);
vx[2].color = 0xffffffff;
vx[2].u = u1;
vx[2].v = v1;
vx[3].position = D3DXVECTOR3( x, y, 0.0f);
vx[3].color = 0xffffffff;
vx[3].u = u1;
vx[3].v = v0;
angle += 20 * 1.74532925E-2f / fps; // 20 angles / second
if(angle >= D3DX_PI * 2)
angle = 0.0f;
D3DXMATRIX mxWorld;
D3DXMatrixRotationY(&mxWorld, angle);
device->SetTransform(D3DTS_WORLD, &mxWorld);
device->SetTexture(0, tx_video);
struct V_2D
{
D3DXVECTOR4 position;
float u, v;
} vxx[4];
vxx[0].position = D3DXVECTOR4((float)rc_frame.left, (float)rc_frame.bottom, 1.0f, 1.0f);
vxx[0].u = u0;
vxx[0].v = v1;
vxx[1].position = D3DXVECTOR4((float)rc_frame.left, (float)rc_frame.top, 1.0f, 1.0f);
vxx[1].u = u0;
vxx[1].v = v0;
vxx[2].position = D3DXVECTOR4((float)rc_frame.right, (float)rc_frame.bottom, 1.0f, 1.0f);
vxx[2].u = u1;
vxx[2].v = v1;
vxx[3].position = D3DXVECTOR4((float)rc_frame.right, (float)rc_frame.top, 1.0f, 1.0f);
vxx[3].u = u1;
vxx[3].v = v0;
device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, &vxx[0], sizeof(V_2D));
device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
device->SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, &vx[0], sizeof(V_3D));
device->SetTexture(0, NULL);
}
//
//
HRESULT DrawScene()
{
RECT rc;
GetClientRect(g_hwndMain, &rc);
hr = D3DERR_DEVICENOTRESET;
if((!device) || (FAILED(hr = device->TestCooperativeLevel())) ||
(d3dpp.BackBufferWidth != rc.right - rc.left) ||
(d3dpp.BackBufferHeight != rc.bottom - rc.top))
{
if((FAILED(hr)) && (hr != D3DERR_DEVICENOTRESET))
return hr;
hr = ResetDevice();
if(FAILED(hr))
return hr;
}
hr = ProcessInput();
if(FAILED(hr))
return hr;
if(!repaint)
return S_FALSE;
// Starting Drawing
WaitForSingleObject(mutex, INFINITE);
hr = device->BeginScene();
if(FAILED(hr))
{
ReleaseMutex(mutex);
return hr;
}
Draw3DScene();
device->EndScene();
ReleaseMutex(mutex);
device->Present(NULL, NULL, g_hwndMain, NULL);
repaint = FALSE;
t2 = GetTickCount();
n_frames++;
if(t2 - t1 >= threshold)
{
t1 = t2;
UpdateCaption();
}
return S_OK;
}
//
//
LRESULT CALLBACK MainWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_CREATE:
SetTimer(hwnd, 1, 1000 / fps, NULL);
break;
case WM_DESTROY:
KillTimer(hwnd, 1);
break;
case WM_NCDESTROY:
PostQuitMessage(0);
break;
case WM_TIMER:
// In this sample scene repaints by timer.
// When writing media player, perhaps it will be better to repaint scene directly from callback function.
DrawScene();
return 0;
case WM_PAINT:
if(device)
repaint = TRUE;
else
{
HDC dc = GetDC(hwnd);
RECT rc;
GetClientRect(hwnd, &rc);
FillRect(dc, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
ReleaseDC(hwnd, dc);
}
ValidateRect(hwnd, NULL);
return 0;
case WM_LBUTTONDOWN:
OpenClip();
return 0;
case WM_KEYDOWN:
switch(wParam)
{
case VK_F1:
MessageBox(hwnd, "3DVideo - sample program that uses \"grabberds\" library.\r\n"
"(c) 2005 - 2007 Aleksei Kazantsev (ajk.xyz@gmail.com)\r\n\r\n"
"It is free software and is distributed under\r\n"
"the terms of the GNU General Public License (Version 2).\r\n"
"This software comes with ABSOLUTELY NO WARRANTY.", "About", MB_OK | MB_ICONINFORMATION);
}
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
//
//
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR szCmdLine, int nCmdShow)
{
wchar_t szFile[2048];
g_szFileName = &szFile[0];
g_szFileName[0] = 0;
mutex = CreateMutex(NULL, FALSE, NULL);
t1 = GetTickCount();
GetProcessTimes(GetCurrentProcess(), &t, &t, &k1, &u1);
n_frames = 0;
WNDCLASS wnd;
ZeroMemory(&wnd, sizeof(wnd));
wnd.lpfnWndProc = MainWindowProc;
wnd.lpszClassName = "3DVideo";
wnd.style = CS_BYTEALIGNWINDOW | CS_BYTEALIGNCLIENT | CS_HREDRAW | CS_VREDRAW;
wnd.hCursor = LoadCursor(NULL, IDC_ARROW);
RegisterClass(&wnd);
g_hwndMain = CreateWindowEx(0, wnd.lpszClassName, "3DVideo",
WS_OVERLAPPEDWINDOW, 0, 0,
800 + (GetSystemMetrics(SM_CXFRAME) << 1),
600 + GetSystemMetrics(SM_CYCAPTION) +
(GetSystemMetrics(SM_CYFRAME) << 1), NULL, NULL, NULL, NULL);
CoInitializeEx(NULL, COINIT_MULTITHREADED);
OpenClip();
ShowWindow(g_hwndMain, SW_SHOW);
MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{
DispatchMessage(&msg);
}
CloseClip();
D3DCleanup();
CoUninitialize();
UnregisterClass(wnd.lpszClassName, wnd.hInstance);
CloseHandle(mutex);
ExitProcess(0);
}
//
// End
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -