30 #pragma comment( lib, "d2d1.lib" )
31 #pragma comment( lib, "dwrite.lib" )
40 Microsoft::WRL::ComPtr< ID2D1Factory > g_pD2DFactory;
41 Microsoft::WRL::ComPtr< ID2D1HwndRenderTarget > g_pRenderTarget;
42 Microsoft::WRL::ComPtr< ID2D1SolidColorBrush > g_pTextBrush;
44 Microsoft::WRL::ComPtr< IDWriteFactory > g_pDWriteFactory;
45 Microsoft::WRL::ComPtr< IDWriteTextFormat > g_pTextFormat;
47 D2D1_SIZE_U g_bitmapSize = { 0, 0 };
48 Microsoft::WRL::ComPtr< ID2D1Bitmap > g_pBitmap;
55 MOVEMENT_KEY_MOVE_FORWARD = 0,
56 MOVEMENT_KEY_MOVE_BACK,
57 MOVEMENT_KEY_MOVE_DOWN,
59 MOVEMENT_KEY_MOVE_RIGHT,
60 MOVEMENT_KEY_MOVE_LEFT,
61 MOVEMENT_KEY_TURN_COUNTERCLOCKWISE,
62 MOVEMENT_KEY_TURN_CLOCKWISE,
63 MOVEMENT_KEY_TURN_RIGHT,
64 MOVEMENT_KEY_TURN_LEFT,
66 MOVEMENT_KEY_TURN_DOWN,
68 MOVEMENT_KEY_ZOOM_OUT,
72 bool g_movementKeys[ MOVEMENT_KEYS_SIZE ];
82 template<
int t_ColorFormat,
int t_Platform,
int t_RendererPlatform >
84 unsigned int const width,
85 unsigned int const height,
86 Synchronized::Heap< t_Platform >& heap,
87 Synchronized::TextureHeap< t_ColorFormat, t_Platform >& textureHeap,
89 Renderer::State< t_RendererPlatform >
const& renderer,
93 if ( ( g_bitmapSize.height <= 0 ) || ( g_bitmapSize.width <= 0 ) )
96 BYTE* buffer =
new BYTE[ g_bitmapSize.height * g_bitmapSize.width * 4 ];
100 typename Synchronized::Heap< t_Platform >::template Pointer< Octree::Node< t_ColorFormat, t_Platform > >
const pSubtractedRoot = Octree::Subtract(
109 textureHeap.Synchronize();
111 typename Synchronized::Heap< t_Platform >::template Pointer< Octree::Node< t_ColorFormat, t_Platform > >
const& pSubtractedRoot = pRoot;
114 renderer.TraceScreen(
125 CHECK_HRESULT( g_pBitmap->CopyFromMemory( NULL, buffer, g_bitmapSize.width * 4 ) );
129 wchar_t string[ 128 ];
131 unsigned int const threads = omp_get_max_threads();
133 unsigned int const threads = 1;
135 _snwprintf_s(
string,
ARRAYLENGTH(
string ), L
"threads = %u, resolution = %dx%d\n%.2f Mrays / frame\n%.2f frames / sec\n%.2f Mrays / sec", threads, g_bitmapSize.width, g_bitmapSize.height, g_bitmapSize.width * g_bitmapSize.height / 1000000.0, g_fps, g_rps / 1000000 );
137 D2D1_SIZE_F
const targetSize = g_pRenderTarget->GetSize();
138 D2D1_RECT_F
const bitmapTargetRect = { 0, 0, targetSize.width, targetSize.height };
139 D2D1_RECT_F
const textTargetRect = { 8, 8, targetSize.width, targetSize.height };
141 g_pRenderTarget->BeginDraw();
142 g_pRenderTarget->DrawBitmap( g_pBitmap.Get(), bitmapTargetRect );
143 g_pRenderTarget->DrawText(
149 D2D1_DRAW_TEXT_OPTIONS_NONE,
150 DWRITE_MEASURING_MODE_NATURAL
152 g_pRenderTarget->EndDraw();
163 LRESULT CALLBACK WindowProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) {
174 case 'W': { g_movementKeys[ MOVEMENT_KEY_MOVE_FORWARD ] =
false;
break; }
175 case 'S': { g_movementKeys[ MOVEMENT_KEY_MOVE_BACK ] =
false;
break; }
176 case VK_NEXT: { g_movementKeys[ MOVEMENT_KEY_MOVE_DOWN ] =
false;
break; }
177 case VK_PRIOR: { g_movementKeys[ MOVEMENT_KEY_MOVE_UP ] =
false;
break; }
178 case 'D': { g_movementKeys[ MOVEMENT_KEY_MOVE_RIGHT ] =
false;
break; }
179 case 'A': { g_movementKeys[ MOVEMENT_KEY_MOVE_LEFT ] =
false;
break; }
180 case 'Q': { g_movementKeys[ MOVEMENT_KEY_TURN_COUNTERCLOCKWISE ] =
false;
break; }
181 case 'E': { g_movementKeys[ MOVEMENT_KEY_TURN_CLOCKWISE ] =
false;
break; }
182 case VK_RIGHT: { g_movementKeys[ MOVEMENT_KEY_TURN_RIGHT ] =
false;
break; }
183 case VK_LEFT: { g_movementKeys[ MOVEMENT_KEY_TURN_LEFT ] =
false;
break; }
184 case VK_UP: { g_movementKeys[ MOVEMENT_KEY_TURN_UP ] =
false;
break; }
185 case VK_DOWN: { g_movementKeys[ MOVEMENT_KEY_TURN_DOWN ] =
false;
break; }
186 case VK_HOME: { g_movementKeys[ MOVEMENT_KEY_ZOOM_OUT ] =
false;
break; }
187 case VK_END: { g_movementKeys[ MOVEMENT_KEY_ZOOM_IN ] =
false;
break; }
188 case VK_ESCAPE: { DestroyWindow( hWnd );
break; }
196 case 'W': { g_movementKeys[ MOVEMENT_KEY_MOVE_FORWARD ] =
true;
break; }
197 case 'S': { g_movementKeys[ MOVEMENT_KEY_MOVE_BACK ] =
true;
break; }
198 case VK_NEXT: { g_movementKeys[ MOVEMENT_KEY_MOVE_DOWN ] =
true;
break; }
199 case VK_PRIOR: { g_movementKeys[ MOVEMENT_KEY_MOVE_UP ] =
true;
break; }
200 case 'D': { g_movementKeys[ MOVEMENT_KEY_MOVE_RIGHT ] =
true;
break; }
201 case 'A': { g_movementKeys[ MOVEMENT_KEY_MOVE_LEFT ] =
true;
break; }
202 case 'Q': { g_movementKeys[ MOVEMENT_KEY_TURN_COUNTERCLOCKWISE ] =
true;
break; }
203 case 'E': { g_movementKeys[ MOVEMENT_KEY_TURN_CLOCKWISE ] =
true;
break; }
204 case VK_RIGHT: { g_movementKeys[ MOVEMENT_KEY_TURN_RIGHT ] =
true;
break; }
205 case VK_LEFT: { g_movementKeys[ MOVEMENT_KEY_TURN_LEFT ] =
true;
break; }
206 case VK_UP: { g_movementKeys[ MOVEMENT_KEY_TURN_UP ] =
true;
break; }
207 case VK_DOWN: { g_movementKeys[ MOVEMENT_KEY_TURN_DOWN ] =
true;
break; }
208 case VK_HOME: { g_movementKeys[ MOVEMENT_KEY_ZOOM_OUT ] =
true;
break; }
209 case VK_END: { g_movementKeys[ MOVEMENT_KEY_ZOOM_IN ] =
true;
break; }
216 PostQuitMessage( ERROR_SUCCESS );
222 RECT clientRect = { 0, 0, 0, 0 };
223 GetClientRect( hWnd, &clientRect );
224 { D2D1_SIZE_U size = D2D1::SizeU( clientRect.right - clientRect.left, clientRect.bottom - clientRect.top );
228 D2D1_SIZE_U bitmapSize = {
229 clientRect.right - clientRect.left,
230 clientRect.bottom - clientRect.top
233 if ( ( bitmapSize.width != g_bitmapSize.width ) || ( bitmapSize.height != g_bitmapSize.height ) ) {
235 g_bitmapSize = bitmapSize;
237 D2D1_BITMAP_PROPERTIES properties;
238 ZeroMemory( &properties,
sizeof( properties ) );
239 properties.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
240 properties.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
241 properties.dpiX = 96.0;
242 properties.dpiY = 96.0;
244 CHECK_HRESULT( g_pRenderTarget->CreateBitmap( g_bitmapSize, properties, &g_pBitmap ) );
247 result = DefWindowProc( hWnd, message, wParam, lParam );
253 result = DefWindowProc( hWnd, message, wParam, lParam );
258 catch( std::exception& exception ) {
261 char const*
const what8 = exception.what();
263 MultiByteToWideChar( CP_UTF8, 0, what8, -1, what,
ARRAYLENGTH( what ) );
265 char const*
const what = exception.what();
268 MessageBox( NULL, what, TEXT(
"WindowProc - caught exception" ), MB_ICONEXCLAMATION | MB_OK );
269 PostQuitMessage( ERROR_UNHANDLED_EXCEPTION );
273 MessageBox( NULL, TEXT(
"<unknown error>" ), TEXT(
"WindowProc - caught exception" ), MB_ICONEXCLAMATION | MB_OK );
274 PostQuitMessage( ERROR_UNHANDLED_EXCEPTION );
288 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
int nCmdShow ) {
290 LPCTSTR szClassName = TEXT(
"WindowClass" );
291 LPCTSTR szTitle = TEXT(
"Voxel" );
293 int result = ERROR_SUCCESS;
301 #if ( SETTING_OPENCL != 0 )
302 std::shared_ptr< OpenCL::State > pState(
new OpenCL::State() );
304 Synchronized::TextureHeap< COLOR_FORMAT, PLATFORM_OPENCL > textureHeap( pState, 27 );
307 #else // SETTING_OPENCL
309 Synchronized::TextureHeap< COLOR_FORMAT, PLATFORM_HOST > textureHeap;
312 #endif // SETTING_OPENCL
314 textureHeap.Synchronize();
322 std::fill( g_movementKeys, g_movementKeys +
ARRAYLENGTH( g_movementKeys ),
false );
324 double const fpsRate = 0.95;
325 double const rateTurn = 0.8;
326 double const rateZoom = 0.4;
327 double const rateMove = 0.2;
331 WNDCLASSEX windowClass;
332 ZeroMemory( &windowClass,
sizeof( windowClass ) );
333 windowClass.cbSize =
sizeof( windowClass );
334 windowClass.style = CS_HREDRAW | CS_VREDRAW;
335 windowClass.lpfnWndProc = WindowProc;
336 windowClass.cbClsExtra = 0;
337 windowClass.cbWndExtra = 0;
338 windowClass.hInstance = hInstance;
339 windowClass.hIcon = LoadIcon( NULL, IDI_APPLICATION );
340 windowClass.hCursor = LoadCursor( NULL, IDC_ARROW );
341 windowClass.hbrBackground = ( HBRUSH )COLOR_WINDOW;
342 windowClass.lpszMenuName = NULL;
343 windowClass.lpszClassName = szClassName;
344 windowClass.hIconSm = LoadIcon( NULL, IDI_APPLICATION );
345 if ( ! RegisterClassEx( &windowClass ) )
348 RECT windowRect = { 0, 0, 800, 600 };
356 HWND hWnd = CreateWindowEx(
364 windowRect.right - windowRect.left,
365 windowRect.bottom - windowRect.top,
376 D2D1_FACTORY_OPTIONS options;
377 ZeroMemory( &options,
sizeof( options ) );
379 CHECK_HRESULT( D2D1CreateFactory( D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof( ID2D1Factory ), &options, &g_pD2DFactory ) );
381 GetClientRect( hWnd, &windowRect );
382 { D2D1_SIZE_U size = D2D1::SizeU( windowRect.right - windowRect.left, windowRect.bottom - windowRect.top );
383 CHECK_HRESULT( g_pD2DFactory->CreateHwndRenderTarget( D2D1::RenderTargetProperties(), D2D1::HwndRenderTargetProperties( hWnd, size ), &g_pRenderTarget ) );
387 D2D1::ColorF( D2D1::ColorF::White, 1 ),
391 CHECK_HRESULT( DWriteCreateFactory( DWRITE_FACTORY_TYPE_SHARED, __uuidof( IDWriteFactory ), &g_pDWriteFactory ) );
396 DWRITE_FONT_WEIGHT_REGULAR,
397 DWRITE_FONT_STYLE_NORMAL,
398 DWRITE_FONT_STRETCH_NORMAL,
406 ShowWindow( hWnd, nCmdShow );
407 UpdateWindow( hWnd );
412 DWORD ticks = GetTickCount();
415 for (
bool done =
false; ! done; ) {
419 { RECT clientRect = windowRect;
420 GetClientRect( hWnd, &clientRect );
422 Redraw( clientRect.right - clientRect.left, clientRect.bottom - clientRect.top, heap, textureHeap, pRoot, renderer, camera );
423 ValidateRect( hWnd, NULL );
428 DWORD
const ticksOld = ticks;
429 ticks = GetTickCount();
430 double const deltaSeconds =
static_cast< double >( ticks - ticksOld ) / 1000;
432 frames = fpsRate * frames + ( 1 - fpsRate );
433 rays = fpsRate * rays + ( 1 - fpsRate ) * g_bitmapSize.width * g_bitmapSize.height;
434 seconds = fpsRate * seconds + ( 1 - fpsRate ) * deltaSeconds;
436 g_fps = frames / seconds;
437 g_rps = rays / seconds;
443 BOOL peekResult = PeekMessage( &msg, NULL, 0, 0, PM_REMOVE );
444 if ( peekResult < 0 )
446 if ( peekResult == 0 )
449 TranslateMessage( &msg );
450 DispatchMessage( &msg );
452 if ( msg.message == WM_QUIT ) {
462 {
double const move = ( g_movementKeys[ MOVEMENT_KEY_MOVE_FORWARD ] ? 1.0 : 0.0 ) - ( g_movementKeys[ MOVEMENT_KEY_MOVE_BACK ] ? 1.0 : 0.0 );
465 double const rate = move * rateMove * deltaSeconds;
469 {
double const move = ( g_movementKeys[ MOVEMENT_KEY_MOVE_DOWN ] ? 1.0 : 0.0 ) - ( g_movementKeys[ MOVEMENT_KEY_MOVE_UP ] ? 1.0 : 0.0 );
472 double const rate = move * rateMove * deltaSeconds;
476 {
double const move = ( g_movementKeys[ MOVEMENT_KEY_MOVE_RIGHT ] ? 1.0 : 0.0 ) - ( g_movementKeys[ MOVEMENT_KEY_MOVE_LEFT ] ? 1.0 : 0.0 );
479 double const rate = move * rateMove * deltaSeconds;
483 {
double const turn = ( g_movementKeys[ MOVEMENT_KEY_TURN_CLOCKWISE ] ? 1.0 : 0.0 ) - ( g_movementKeys[ MOVEMENT_KEY_TURN_COUNTERCLOCKWISE ] ? 1.0 : 0.0 );
486 double const rate = turn * rateTurn * deltaSeconds;
490 {
double const turn = ( g_movementKeys[ MOVEMENT_KEY_TURN_RIGHT ] ? 1.0 : 0.0 ) - ( g_movementKeys[ MOVEMENT_KEY_TURN_LEFT ] ? 1.0 : 0.0 );
493 double const rate = turn * rateTurn * deltaSeconds;
497 {
double const turn = ( g_movementKeys[ MOVEMENT_KEY_TURN_DOWN ] ? 1.0 : 0.0 ) - ( g_movementKeys[ MOVEMENT_KEY_TURN_UP ] ? 1.0 : 0.0 );
500 double const rate = turn * rateTurn * deltaSeconds;
504 {
double const zoom = ( g_movementKeys[ MOVEMENT_KEY_ZOOM_OUT ] ? 1.0 : 0.0 ) - ( g_movementKeys[ MOVEMENT_KEY_ZOOM_IN ] ? 1.0 : 0.0 );
507 double const rate = zoom * rateZoom * deltaSeconds;
513 catch( std::exception& exception ) {
516 char const*
const what8 = exception.what();
518 MultiByteToWideChar( CP_UTF8, 0, what8, -1, what,
ARRAYLENGTH( what ) );
520 char const*
const what = exception.what();
523 MessageBox( NULL, what, TEXT(
"WinMain - caught exception" ), MB_ICONEXCLAMATION | MB_OK );
524 result = ERROR_UNHANDLED_EXCEPTION;
528 MessageBox( NULL, TEXT(
"<unknown error>" ), TEXT(
"WinMain - caught exception" ), MB_ICONEXCLAMATION | MB_OK );
529 result = ERROR_UNHANDLED_EXCEPTION;