ゲーム > DX11 > 背景のクリア

//  WinMain.cpp
 
#include <windows.h>
 
#include "MyApp.h"
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
  // Enable run-time memory check for debug builds.
  _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
 
  std::auto_ptr<MyApp> p(new MyApp(hInstance, hPrevInstance, lpCmdLine, nCmdShow));
  p->Run();
  return 0;
}
 
/*_________EOF_______________________________________________________________*/
 

// MyApp.h
 
#ifndef MYAPP_H_20110221
#define MYAPP_H_20110221
 
#include <windows.h>
 
class MyApp{
 
public:
 
  MyApp(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);
 
  virtual ~MyApp();
 
  void Run();
 
private:
 
  bool Init();
  void Terminate();
 
  void MainLoop();
  void RunOneFrame();
 
  HINSTANCE hInstance, hPrevInstance;
  LPSTR lpCmdLine;
  int nCmdShow;
 
};
 
#endif  //  MYAPP_H_20110221
/*__________EOF______________________________________________________________*/
 

// MyApp.cpp
 
#include "MyApp.h"
 
#include "Window.h"
#include "Renderer.h"
 
MyApp::MyApp(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
 :  hInstance(hInstance), hPrevInstance(hPrevInstance), lpCmdLine(lpCmdLine), nCmdShow(nCmdShow)
{
}
 
MyApp::~MyApp()
{
}
 
void MyApp::Run()
{
  if(!Init()){
    Terminate();
    return;
  }
 
  MainLoop();
  Terminate();
}
 
bool MyApp::Init()
{
  Window* window = Window::Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow, 1280, 720);
  if(!window){
    return false;
  }
 
  if(!Renderer::Create(window->WindowHandle(), window->WindowWidth(), window->WindowHeight())){
    return false;
  }
 
  window->UpdateWindow();
  return true;
}
 
void MyApp::Terminate()
{
  Renderer::Delete();
  Window::Delete();
}
 
void MyApp::MainLoop()
{
  HWND hWnd = Window::Get()->WindowHandle();
 
  bool bGotMsg;
  MSG msg;
  msg.message = WM_NULL;
  PeekMessage( &msg, NULL, 0U, 0U, PM_NOREMOVE );
 
  while( WM_QUIT != msg.message )
  {
    // Use PeekMessage() so we can use idle time to render the scene. 
    bGotMsg = ( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) != 0 );
 
    if( bGotMsg )
    {
      // Translate and dispatch the message
      if( hWnd == NULL ||
        0 == TranslateAccelerator( hWnd, 0, &msg ) )
      {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
      }
    }
    else
    {
      // Render a frame during idle time (no messages are waiting)
      RunOneFrame();
    }
    Sleep(1);
  }
}
 
void MyApp::RunOneFrame()
{
  Renderer* renderer = Renderer::Get();
  renderer->Clear();
  renderer->Swap();
}
 
/*_________EOF_______________________________________________________________*/
 

// Window.h
 
#ifndef SYSTEM_KERNEL_H_20101123
#define SYSTEM_KERNEL_H_20101123
 
#include <windows.h>
 
class Window{
 
public:
 
  virtual ~Window();
 
  void UpdateWindow();
 
  HWND WindowHandle() const{ return hWnd; }
  int WindowWidth() const{ return mWidth; }
  int WindowHeight() const{ return mHeight; }
 
  static Window* Create(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow, int w, int h);
  static void Delete();
  static Window* Get();
 
private:
 
  Window(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow, int w, int h);
 
  bool Init();
 
  static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
 
  static char const* const sWindowName;
 
  HINSTANCE hInstance, hPrevInstance;
  LPSTR lpCmdLine;
  int nCmdShow;
 
  HWND hWnd;
  int const mWidth, mHeight;
 
};
 
#endif  //  SYSTEM_KERNEL_H_20101123
/*__________EOF______________________________________________________________*/
 

// Window.cpp
 
#include "Window.h"
 
namespace{
std::auto_ptr<Window> sInstance;
}  //  namespace
 
char const* const Window::sWindowName = "MyDX11";
 
/*___________________________________________________________________________*/
 
Window::Window(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow, int w, int h)
 :  hInstance(hInstance), hPrevInstance(hPrevInstance), lpCmdLine(lpCmdLine), nCmdShow(nCmdShow),
    hWnd(0), mWidth(w), mHeight(h)
{
}
 
Window::~Window()
{
}
 
bool Window::Init()
{
  WNDCLASS wndClass;
  memset(&wndClass, 0, sizeof(wndClass));
 
  wndClass.style = CS_DBLCLKS;
  wndClass.lpfnWndProc = WndProc;
  wndClass.hInstance = hInstance;
  wndClass.hIcon = 0;
  wndClass.hCursor = LoadCursor(0, IDC_ARROW);
  wndClass.hbrBackground = static_cast<HBRUSH>(GetStockObject(BLACK_BRUSH));
  wndClass.lpszMenuName = 0;
  wndClass.lpszClassName = sWindowName;
 
  if(!RegisterClass(&wndClass)){
    return false;
  }
 
  RECT rc;
  SetRect(&rc, 0, 0, mWidth, mHeight);
  AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
 
  hWnd = CreateWindow(sWindowName, sWindowName, WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        rc.right - rc.left, rc.bottom - rc.top,
        0, 0, hInstance, 0);
  return true;
}
 
void Window::UpdateWindow()
{
  ShowWindow(hWnd, nCmdShow);
  ::UpdateWindow(hWnd);
}
 
LRESULT CALLBACK Window::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  switch(uMsg){
 
  case WM_KEYDOWN:
    switch(wParam){
    case VK_ESCAPE:
      SendMessage(hWnd, WM_CLOSE, 0, 0);
      break;
    }
    break;
 
  case WM_CLOSE:
    DestroyWindow(hWnd);
    UnregisterClass(sWindowName, 0);
    return 0;
 
  case WM_DESTROY:
    PostQuitMessage(0);
    break;
  }
  return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
 
Window* Window::Create(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow, int w, int h)
{
  sInstance.reset(new Window(hInstance, hPrevInstance, lpCmdLine, nCmdShow, w, h));
  if(!sInstance->Init()){
    sInstance.reset();
    return 0;
  }
  return sInstance.get();
}
 
void Window::Delete()
{
  sInstance.reset();
}
 
Window* Window::Get()
{
  return sInstance.get();
}
 
/*_________EOF_______________________________________________________________*/
 

// Renderer.h
 
#ifndef SYSTEM_RENDER_RENDERER_20101123
#define SYSTEM_RENDER_RENDERER_20101123
 
#include <windows.h>
#include <D3D11.h>
 
class Renderer{
 
public:
 
  virtual ~Renderer();
 
  void Clear();
  void Swap();
 
  int ScreenWidth() const{ return mWidth; }
  int ScreenHeight() const{ return mHeight; }
 
  static Renderer* Create(HWND, int, int);
  static void Delete();
  static Renderer* Get();
 
private:
 
  Renderer(HWND, int, int);
 
  bool Init();
  HRESULT CreateDeviceAndSwapChain();
  HRESULT CreateRenderTargetView();
  void SetViewport();
 
  HWND const hWnd;
  int const mWidth, mHeight;
 
  ID3D11Device* mDevice;
  ID3D11DeviceContext* mDeviceContext;
  IDXGISwapChain* mSwapChain;
  ID3D11RenderTargetView* mRenderTargetView;
 
};
 
#endif  //  SYSTEM_RENDER_RENDERER_20101123
/*__________EOF______________________________________________________________*/
 

// Renderer.cpp
 
#include "Renderer.h"  //  Renderer
 
namespace{
std::auto_ptr<Renderer> sInstance;
}  //  namespace
 
/*___________________________________________________________________________*/
 
Renderer::Renderer(HWND hWnd, int w, int h)
 :  hWnd(hWnd), mWidth(w), mHeight(h),
  mDevice(0), mDeviceContext(0), mSwapChain(0), mRenderTargetView(0)
{
}
 
Renderer::~Renderer()
{
  SafeRelease(mRenderTargetView);
  SafeRelease(mSwapChain);
  SafeRelease(mDeviceContext);
  SafeRelease(mDevice);
}
 
void Renderer::Clear()
{
  static FLOAT const sColor[4] = {0.2f, 0.2f, 0.2f, 1.0f};
  mDeviceContext->ClearRenderTargetView(mRenderTargetView, sColor);
}
 
void Renderer::Swap()
{
  mSwapChain->Present(1, 0);
}
 
bool Renderer::Init()
{
  if(FAILED(CreateDeviceAndSwapChain())){
    return false;
  }
  if(FAILED(CreateRenderTargetView())){
    return false;
  }
  SetViewport();
  return true;
}
 
HRESULT Renderer::CreateDeviceAndSwapChain()
{
  DXGI_SWAP_CHAIN_DESC desc;
  ZeroMemory(&desc, sizeof(desc));
 
  desc.BufferDesc.Width = mWidth;
  desc.BufferDesc.Height = mHeight;
  desc.BufferDesc.RefreshRate.Numerator = 60;
  desc.BufferDesc.RefreshRate.Denominator = 1;
  desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
  desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
  desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
  desc.SampleDesc.Count = 1;
  desc.SampleDesc.Quality = 0;
  desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  desc.BufferCount = 2;
  desc.OutputWindow = hWnd;
  desc.Windowed = TRUE;
  desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
  desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
 
  D3D_FEATURE_LEVEL const LevelIn = D3D_FEATURE_LEVEL_11_0;
  D3D_FEATURE_LEVEL LevelOut;
 
  HRESULT hr = D3D11CreateDeviceAndSwapChain(
    0, D3D_DRIVER_TYPE_HARDWARE, 0, D3D11_CREATE_DEVICE_DEBUG,
    &LevelIn, 1, D3D11_SDK_VERSION, &desc,
    &mSwapChain, &mDevice, &LevelOut, &mDeviceContext);
  return hr;
}
 
HRESULT Renderer::CreateRenderTargetView()
{
  ID3D11Texture2D* back;
  HRESULT hr = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&back));
  if(FAILED(hr)){
    return hr;
  }
 
  hr = mDevice->CreateRenderTargetView(back, 0, &mRenderTargetView);
  SafeRelease(back);
  return hr;
}
 
void Renderer::SetViewport()
{
  D3D11_VIEWPORT vp;
 
  vp.TopLeftX = 0.0f;
  vp.TopLeftY = 0.0f;
  vp.Width = static_cast<FLOAT>(mWidth);
  vp.Height = static_cast<FLOAT>(mHeight);
  vp.MinDepth = 0.0f;
  vp.MaxDepth = 1.0f;
 
  mDeviceContext->RSSetViewports(1, &vp);
}
 
Renderer* Renderer::Create(HWND hWnd, int w, int h)
{
  sInstance.reset(new Renderer(hWnd, w, h));
  if(!sInstance->Init()){
    sInstance.reset();
    return 0;
  }
  return sInstance.get();
}
 
void Renderer::Delete()
{
  sInstance.reset();
}
 
Renderer* Renderer::Get()
{
  return sInstance.get();
}
 
/*_________EOF_______________________________________________________________*/
 

// PreCompile.h
 
#ifndef PRECOMPILE_H_20110222
#define PRECOMPILE_H_20110222
 
#include <memory>
#include <string>
 
#include "typedef.h"
#include "Utility.h"
 
#endif	//	PRECOMPILE_H_20110222
/*__________EOF______________________________________________________________*/
 

// PreCompile.cpp
 
#include "PreCompile.h"	//	PreCompile
 
/*_________EOF_______________________________________________________________*/
 

// typeder.h
 
#ifndef SYSTEM_TYPEDEF_H_20110221
#define SYSTEM_TYPEDEF_H_20110221
 
typedef char           s8;
typedef unsigned char  u8;
typedef short          s16;
typedef unsigned short u16;
typedef int            s32;
typedef unsigned int   u32;
 
typedef float          f32;
typedef double         f64;
 
#endif  // SYSTEM_TYPEDEF_H_20110221
/*__________EOF______________________________________________________________*/
 

// Utility.h
 
#ifndef SYSTEM_UTILITY_H_20101124
#define SYSTEM_UTILITY_H_20101124
 
#include <DXGI.h>
 
template<typename T> void SafeDelete(T*& p){ delete p; p = 0; }
template<typename T> void SafeDeleteArray(T*& p){ delete[] p; p = 0; }
 
template<typename T> void SafeRelease(T*& p){ if(p){ p->Release(); p = 0; } }
 
#endif  // SYSTEM_UTILITY_H_20101124
/*__________EOF______________________________________________________________*/
 

|新しいページ|検索|ページ一覧|RSS|@ウィキご利用ガイド | 管理者にお問合せ
|ログイン|