26 #include "../../Include/OVR.h"
30 #if defined(OVR_OS_WIN32)
36 typedef HRESULT (WINAPI *D2D1CreateFactoryFn)(
37 _In_ D2D1_FACTORY_TYPE,
39 _In_opt_
const D2D1_FACTORY_OPTIONS*,
43 typedef HRESULT (WINAPI *DWriteCreateFactoryFn)(
44 _In_ DWRITE_FACTORY_TYPE factoryType,
46 _Out_ IUnknown **factory
50 namespace OVR {
namespace Util {
52 ID2D1Factory* ImageWindow::pD2DFactory =
NULL;
53 IDWriteFactory* ImageWindow::pDWriteFactory =
NULL;
57 LRESULT CALLBACK MainWndProc(
70 LONG_PTR ptr = GetWindowLongPtr( hwnd, GWLP_USERDATA );
73 ImageWindow* iw = (ImageWindow*)ptr;
93 return DefWindowProc(hwnd, uMsg, wParam, lParam);
99 frontBufferMutex( new Mutex() )
102 HINSTANCE hInst = LoadLibrary( L
"d2d1.dll" );
103 HINSTANCE hInstWrite = LoadLibrary( L
"Dwrite.dll" );
105 D2D1CreateFactoryFn createFactory =
NULL;
106 DWriteCreateFactoryFn writeFactory =
NULL;
110 createFactory = (D2D1CreateFactoryFn)GetProcAddress( hInst,
"D2D1CreateFactory" );
115 writeFactory = (DWriteCreateFactoryFn)GetProcAddress( hInstWrite,
"DWriteCreateFactory" );
118 globalWindow[windowCount] =
this;
122 if( pD2DFactory ==
NULL && createFactory && writeFactory )
125 D2D1_FACTORY_TYPE_MULTI_THREADED,
126 __uuidof(ID2D1Factory),
133 DWRITE_FACTORY_TYPE_SHARED,
134 __uuidof(pDWriteFactory),
135 reinterpret_cast<IUnknown **>(&pDWriteFactory)
140 resolution = D2D1::SizeU( width, height );
142 SetWindowLongPtr( hWindow, GWLP_USERDATA, (LONG_PTR)
this );
149 ImageWindow::~ImageWindow()
151 for(
int i = 0; i < MaxWindows; ++i )
153 if( globalWindow[i] ==
this )
155 globalWindow[i] =
NULL;
161 greyBitmap->Release();
164 colorBitmap->Release();
170 Mutex::Locker locker( frontBufferMutex );
172 while( frames.GetSize() )
174 Ptr<Frame> aFrame = frames.PopBack();
178 delete frontBufferMutex;
180 ShowWindow( hWindow, SW_HIDE );
181 DestroyWindow( hWindow );
184 void ImageWindow::AssociateSurface(
void* surface )
187 IUnknown* unknown = (IUnknown*)surface;
189 IDXGISurface *pDxgiSurface =
NULL;
190 HRESULT hr = unknown->QueryInterface(&pDxgiSurface);
193 D2D1_RENDER_TARGET_PROPERTIES props =
194 D2D1::RenderTargetProperties(
195 D2D1_RENDER_TARGET_TYPE_DEFAULT,
196 D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED),
203 ID2D1RenderTarget* tmpTarget;
205 hr = pD2DFactory->CreateDxgiSurfaceRenderTarget( pDxgiSurface, &props, &tmpTarget );
209 DXGI_SURFACE_DESC desc = {0};
210 pDxgiSurface->GetDesc( &desc );
211 int width = desc.Width;
212 int height = desc.Height;
214 D2D1_SIZE_U size = D2D1::SizeU( width, height );
216 D2D1_PIXEL_FORMAT pixelFormat = D2D1::PixelFormat(
217 DXGI_FORMAT_A8_UNORM,
218 D2D1_ALPHA_MODE_PREMULTIPLIED
221 D2D1_PIXEL_FORMAT colorPixelFormat = D2D1::PixelFormat(
222 DXGI_FORMAT_B8G8R8A8_UNORM,
223 D2D1_ALPHA_MODE_PREMULTIPLIED
226 D2D1_BITMAP_PROPERTIES bitmapProps;
227 bitmapProps.dpiX = 96;
228 bitmapProps.dpiY = 96;
229 bitmapProps.pixelFormat = pixelFormat;
231 D2D1_BITMAP_PROPERTIES colorBitmapProps;
232 colorBitmapProps.dpiX = 96;
233 colorBitmapProps.dpiY = 96;
234 colorBitmapProps.pixelFormat = colorPixelFormat;
236 HRESULT result = tmpTarget->CreateBitmap( size, bitmapProps, &greyBitmap );
239 tmpTarget->Release();
243 result = tmpTarget->CreateBitmap( size, colorBitmapProps, &colorBitmap );
246 greyBitmap->Release();
249 tmpTarget->Release();
257 void ImageWindow::Process()
259 if( pRT && greyBitmap )
267 void ImageWindow::Complete()
269 Mutex::Locker locker( frontBufferMutex );
271 if( frames.IsEmpty() )
274 if( frames.PeekBack(0)->ready )
277 Ptr<Frame> frame = frames.PeekBack(0);
282 void ImageWindow::OnPaint()
284 Mutex::Locker locker( frontBufferMutex );
287 if( frames.IsEmpty() )
290 if( !frames.PeekFront(0)->ready )
293 Ptr<Frame> currentFrame = frames.PopFront();
295 Ptr<Frame> nextFrame =
NULL;
297 if( !frames.IsEmpty() )
298 nextFrame = frames.PeekFront(0);
300 while( nextFrame && nextFrame->ready )
303 currentFrame = frames.PopFront();
305 if( frames.IsEmpty() )
308 nextFrame = frames.PeekFront(0);
311 if( currentFrame->imageData )
312 greyBitmap->CopyFromMemory(
NULL, currentFrame->imageData, currentFrame->width );
314 if( currentFrame->colorImageData )
315 colorBitmap->CopyFromMemory(
NULL, currentFrame->colorImageData, currentFrame->colorPitch );
319 pRT->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
321 pRT->Clear( D2D1::ColorF(D2D1::ColorF::Black) );
325 m._11 = -1; m._12 = 0;
326 m._21 = 0; m._22 = 1;
327 m._31 = 0; m._32 = 0;
328 pRT->SetTransform( m );
330 ID2D1SolidColorBrush* whiteBrush;
332 pRT->CreateSolidColorBrush( D2D1::ColorF(D2D1::ColorF::White, 1.0f), &whiteBrush );
334 if( currentFrame->imageData )
336 pRT->FillOpacityMask( greyBitmap, whiteBrush,
337 D2D1_OPACITY_MASK_CONTENT_TEXT_NATURAL,
338 D2D1::RectF( -(FLOAT)resolution.width, 0.0f, (FLOAT)0.0f, (FLOAT)resolution.height ),
340 D2D1::RectF( 0.0f, 0.0f, (FLOAT)resolution.width, (FLOAT)resolution.height ) );
342 else if( currentFrame->colorImageData )
344 pRT->DrawBitmap( colorBitmap,
345 D2D1::RectF( -(FLOAT)resolution.width, 0.0f, (FLOAT)0.0f, (FLOAT)resolution.height ) );
349 pRT->SetTransform(D2D1::Matrix3x2F::Identity());
351 whiteBrush->Release();
353 Array<CirclePlot>::Iterator it;
355 for( it = currentFrame->plots.Begin(); it != currentFrame->plots.End(); ++it )
357 ID2D1SolidColorBrush* aBrush;
359 pRT->CreateSolidColorBrush( D2D1::ColorF( it->r, it->g, it->b), &aBrush );
361 D2D1_ELLIPSE ellipse;
362 ellipse.point.x = it->x;
363 ellipse.point.y = it->y;
364 ellipse.radiusX = it->radius;
365 ellipse.radiusY = it->radius;
368 pRT->FillEllipse( &ellipse, aBrush );
370 pRT->DrawEllipse( &ellipse, aBrush );
375 static const WCHAR msc_fontName[] = L
"Verdana";
376 static const FLOAT msc_fontSize = 20;
378 IDWriteTextFormat* textFormat =
NULL;
381 pDWriteFactory->CreateTextFormat(
384 DWRITE_FONT_WEIGHT_NORMAL,
385 DWRITE_FONT_STYLE_NORMAL,
386 DWRITE_FONT_STRETCH_NORMAL,
392 D2D1_SIZE_F renderTargetSize = pRT->GetSize();
394 Array<TextPlot>::Iterator textIt;
395 for( textIt = currentFrame->textLines.Begin(); textIt != currentFrame->textLines.End(); ++textIt )
397 ID2D1SolidColorBrush* aBrush;
399 pRT->CreateSolidColorBrush( D2D1::ColorF( textIt->r, textIt->g, textIt->b), &aBrush );
401 WCHAR* tmpString = (WCHAR*)calloc( textIt->text.GetLength(),
sizeof( WCHAR ) );
402 for(
unsigned i = 0; i < textIt->text.GetLength(); ++i )
404 tmpString[i] = (WCHAR)textIt->text.GetCharAt( i );
407 pRT->DrawTextW( tmpString, (UINT32)textIt->text.GetLength(), textFormat,
408 D2D1::RectF(textIt->x, textIt->y, renderTargetSize.width, renderTargetSize.height), aBrush );
416 textFormat->Release();
423 Ptr<Frame> ImageWindow::lastUnreadyFrame()
425 static int framenumber = 0;
427 if( frames.GetSize() && !frames.PeekBack( 0 )->ready )
428 return frames.PeekBack( 0 );
431 Ptr<Frame> tmpFrame = *
new Frame( framenumber );
432 frames.PushBack( tmpFrame );
439 void ImageWindow::UpdateImageBW(
const uint8_t* imageData, uint32_t width, uint32_t height )
441 if( pRT && greyBitmap )
443 Mutex::Locker locker( frontBufferMutex );
445 Ptr<Frame> frame = lastUnreadyFrame();
446 frame->imageData = malloc( width * height );
447 frame->width = width;
448 frame->height = height;
449 memcpy( frame->imageData, imageData, width * height );
453 void ImageWindow::UpdateImageRGBA(
const uint8_t* imageData, uint32_t width, uint32_t height, uint32_t pitch )
455 if( pRT && colorBitmap )
457 Mutex::Locker locker( frontBufferMutex );
459 Ptr<Frame> frame = lastUnreadyFrame();
460 frame->colorImageData = malloc( pitch * height );
461 frame->width = width;
462 frame->height = height;
463 frame->colorPitch = pitch;
464 memcpy( frame->colorImageData, imageData, pitch * height );
468 void ImageWindow::addCircle(
float x,
float y,
float radius,
float r,
float g,
float b,
bool fill )
482 Mutex::Locker locker( frontBufferMutex );
484 Ptr<Frame> frame = lastUnreadyFrame();
485 frame->plots.PushBack( cp );
490 void ImageWindow::addText(
float x,
float y,
float r,
float g,
float b,
OVR::String text )
503 Mutex::Locker locker( frontBufferMutex );
504 Ptr<Frame> frame = lastUnreadyFrame();
505 frame->textLines.PushBack( tp );
511 #endif //defined(OVR_OS_WIN32)
__BEGIN_NAMESPACE_STD void * memcpy(void *__restrict __dest, const void *__restrict __src, size_t __n) __THROW __nonnull((1
static ImageWindow * globalWindow[4]