d3d11binding-0.0.0.1: examples/HelloWorld.hs
{-# LANGUAGE ScopedTypeVariables #-}
module Main where
import System.Exit
import Data.Int
import Control.Exception
import Control.Monad
import Foreign (peekByteOff)
import Foreign.Ptr
import Graphics.Win32
import System.Win32.DLL (getModuleHandle)
import Graphics.D3D11Binding
foreign import stdcall "PostQuitMessage" postQuitMessage :: Int32 -> IO ()
main :: IO ()
main = do
hWnd <- createDefaultWindow 800 600 wndProc
(s, d, dc, r) <- initDevice hWnd
use s $ \swapChain -> use d $ \device -> use dc $ \deviceContext -> use r $ \renderTargetView -> do
messagePump hWnd deviceContext swapChain renderTargetView
wndProc :: WindowClosure
wndProc hWnd msg wParam lParam
| msg == wM_DESTROY = postQuitMessage 0 >> return 0
| otherwise = defWindowProc (Just hWnd) msg wParam lParam
initDevice :: HWND -> IO (Ptr IDxgiSwapChain, Ptr ID3D11Device, Ptr ID3D11DeviceContext, Ptr ID3D11RenderTargetView)
initDevice hWnd = do
let bd = DxgiModeDesc
800
600
(DxgiRational 60 1)
DxgiFormatR8G8B8A8Unorm
DxgiModeScanlineOrderUnspecified
DxgiModeScalingUnspecified
let sd = DxgiSwapChainDesc
bd
(DxgiSampleDesc 1 0)
dxgiUsageRenderTargetOutput
1
hWnd
True
DxgiSwapEffectDiscard
0
Right (swapChain, device, featureLevel, deviceContext) <- d3d11CreateDeviceAndSwapChain
nullPtr
D3DDriverTypeHardware
nullPtr
[D3D11CreateDeviceDebug]
[D3DFeatureLevel11_0, D3DFeatureLevel10_1, D3DFeatureLevel10_0]
sd
Right (backBuffer :: Ptr ID3D11Texture2D) <- getBuffer swapChain (fromIntegral 0)
Right renderTargetView <- use backBuffer $ \b -> createRenderTargetView device b Nothing
omSetRenderTargets deviceContext [renderTargetView] nullPtr
rsSetViewports deviceContext [D3D11Viewport 0 0 800 600 0 1]
return (swapChain, device, deviceContext, renderTargetView)
createDefaultWindow :: Int -> Int -> WindowClosure -> IO HWND
createDefaultWindow width height wndProc = do
let winClass = mkClassName "HelloWorld"
icon <- loadIcon Nothing iDI_APPLICATION
cursor <- loadCursor Nothing iDC_ARROW
bgBrush <- createSolidBrush (rgb 255 255 255)
mainInstance <- getModuleHandle Nothing
registerClass
( cS_VREDRAW + cS_HREDRAW
, mainInstance
, Just icon
, Just cursor
, Just bgBrush
, Nothing
, winClass )
w <- createWindow
winClass
"Hello, World"
wS_OVERLAPPEDWINDOW
Nothing Nothing
(Just width)
(Just height)
Nothing
Nothing
mainInstance
wndProc
showWindow w sW_SHOWNORMAL
updateWindow w
return w
pM_NOREMOVE, pM_REMOVE, pM_NOYIELD :: UINT
pM_NOREMOVE = 0x0000
pM_REMOVE = 0x0001
pM_NOYIELD = 0x0002
messagePump :: HWND -> Ptr ID3D11DeviceContext -> Ptr IDxgiSwapChain -> Ptr ID3D11RenderTargetView -> IO ()
messagePump hwnd deviceContext swapChain renderTargetView = Graphics.Win32.allocaMessage $ \ msg ->
let pump = do
m <- peekByteOff msg 4 :: IO WindowMessage
when (m /= wM_QUIT) $ do
r <- c_PeekMessage msg (maybePtr Nothing) 0 0 pM_REMOVE
if r /= 0
then do
translateMessage msg
dispatchMessage msg
return ()
else do
render deviceContext swapChain renderTargetView
pump
in pump
render :: Ptr ID3D11DeviceContext -> Ptr IDxgiSwapChain -> Ptr ID3D11RenderTargetView -> IO ()
render deviceContext swapChain renderTargetView = do
clearRenderTargetView deviceContext renderTargetView $ Color 0.0 0.125 0.3 1.0
present swapChain 0 0
return ()