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

📄 3dvideo.cpp

📁 Handle Videos in Forms Delphi... Play/Stop/Pause/FullScreen
💻 CPP
📖 第 1 页 / 共 2 页
字号:
   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 + -