Воспроизведение bink видео
GameDev.ru / Страницы / Воспроизведение bink видео [Форум / Инфо]

Воспроизведение bink видео


Воспроизведение Bink видео (.bik)

Привет.
Я долго искал в сети статьи о том, как воспроизводить в своих программах Bink видео. Статей не нашел, но нашел сам Bink SDK. И сейчас я поделюсь решением этой проблемы.
Нам нужны
      Visual Studio (C++), Direct3D9 и Bink SDK.
Чтобы увидеть, что должно получиться качаем пример.

В настройках Visual Studio в указании директорий в Includes и Library указываем на распакованную папку Bink SDK.

Далее создаем пустой проект Win32. Добавляем файл binktextures.cpp (он находится в директории Bink SDK).
Создаем cpp файл, где будет функция WinMain.

Объявляем директиву D3D_OVERLOAD

#define D3D_OVERLOAD

Включаем все необходимые библиотеки и объявляем переменные

#include <windows.h>
#include <d3d9.h>
#include <bink.h>
#include <binktextures.h>

#pragma comment (lib, “d3d9.lib”)
#pragma comment (lib, “d3dx9.lib”)
#pragma comment (lib, “binkw32.lib”)

BINK * Bink = 0;
BINKTEXTURESET TexSet = {0};

IDirect3D9 * pD3D = Direct3DCreate9(D3D_SDK_VERSION);
IDirect3DDevice9 * Device = 0;
D3DPRESENT_PARAMETERS  d3dpp = {0};

float xSc = 1.0f, ysc = 1.0f;

Объявим функции

void Render();
bool InitBink();
void Decompress_Frame(BINKTEXTURESET * ts);

Теперь инициализируем Direct3D и создадим наше окно

LRESULT CALLBACK WndProc(HWND h, UINT m, WPARAM w, LPARAM l)
{
  switch(m)
  {
  case WM_DESTROY:
    PostQuitMessage(0);
    break;
  }

  return DefWindowProc(h, m, w, l);
}

bool Init3D(HWND hWnd)
{
  ZeroMemory(&d3dpp, sizeof d3dpp);
  d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
  d3dpp.BackBufferCount = 1;
  d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
  d3dpp.BackBufferWidth = 800;
  d3dpp.BackBufferHeight = 600;
  d3dpp.EnableAutoDepthStencil = true;
  d3dpp.SwapEffect = D3DSWAPEFFECT_FLIP;
  d3dpp.Windowed = false;

  if(FAILED(pD3D9->CreateDevice(0, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &Device)))
  {
    MessageBox(hWnd, "Error create Direct3D", 0, 0);
    PostQuitMessage(0);
    return false;
  }

  return true;
}
bool Init(HWND hWnd)
{
  Init3D(hWnd);
  InitBink();

  return true;
}
int PASCAL WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int)
{
  MSG msg;
  HWND hWnd;
  WNDCLASSEX wcex;

  ZeroMemory(&wcex, sizeof(wcex));
  wcex.cbClsExtra = 0;
  wcex.cbSize = sizeof(wcex);
  wcex.cbWndExtra = 0;
  wcex.hbrBackground = 0;
  wcex.hCursor = 0;
  wcex.hIcon = 0;
  wcex.hIconSm = 0;
  wcex.hInstance = hInst;
  wcex.lpfnWndProc = (WNDPROC)WndProc;
  wcex.lpszClassName = "bink";
  wcex.lpszMenuName = 0;
  wcex.style = CS_CLASSDC;
  
  RegisterClassEx(&wcex);

  hWnd = CreateWindow("bink", "bink", WS_SYSMENU|WS_CAPTION, 0, 0, 800, 600, 0, 0, hInst, 0);
  ShowWindow(hWnd, 1);
  UpdateWindow(hWnd);

  if(Init(hWnd))
  {
    if(Create_Bink_textures(Device, &TexSet))
    {
      while(true)
      {
        if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
        {
          TranslateMessage(&msg);
          DispatchMessage(&msg);
          if(msg.message == WM_QUIT)
            break;
        }
        else
        {
          if(!BinkWait(Bink))
          {
            Decompress_Frame(&TexSet);
            Render();
          }
          else
            Sleep(1);
        }
      }
    }
  }

  return 0;
}

Теперь сами функции Render(), InitBink(), Decompress_Frame(BINKTEXTURESET * ts).

bool InitBink()
{
  BinkSoundUseDirectSound(0);

  Bink = BinkOpen("Intro.bik", BINKSNDTRACK|BINKNOFRAMEBUFFERS);
  if(!Bink)
        {
          MessageBox(hWnd, "Error create Bink", 0, 0);
          PostQuitMessage(0);
          return false;
        }

  xSc = (float)800 / (float)Bink->Width;
  ySc = (float)600 / (float)Bink->Height;

  if(Create_Bink_shaders(Device))
  {
    BinkGetFrameBuffersInfo(Bink, &TexSet.bink_buffers);
  }
  else
    {
      PostQuitMessage(0);
      return false;
    }

  ShowCursor(false);

  return true;
}

void Decompress_Frame(BINKTEXTURESET * ts)
{
  Lock_Bink_textures(ts);
  BinkRegisterFrameBuffers(Bink, &ts->bink_buffers);
  BinkDoFrame(Bink);
  while(BinkShouldSkip(Bink))
  {
    BinkNextFrame(Bink);
    BinkDoFrame(Bink);
  }
  Unlock_Bink_textures(Device, ts, Bink);
  BinkNextFrame(Bink);
}

void Render()
{
  Device->Clear(0, 0, D3DCLEAR_ZBUFFER|D3DCLEAR_TARGET|D3DCLEAR_STENCIL, D3DCOLOR_XRGB(0, 1, 0), 1.0f, 0);
  Device->BeginScene();
  if(Bink->FrameNum != Bink->Frames)
    Draw_Bink_textures(Device, &TexSet, Bink->Width, Bink->Height, 0, 0, xSc, ySc, 1.0f, 0 );
  else
  {
    BinkPause(Bink, 1);
    BinkClose(Bink);
    PostQuitMessage(0);
  }
  Device->EndScene();
  Device->Present(0, 0, 0, 0);
}

Для работы программы необходимо наличие binkw32.dll в папке с программой.
Пока

2001—2017 © GameDev.ru — Разработка игр