diff options
author | Brad Davis <[email protected]> | 2014-05-23 01:49:32 -0700 |
---|---|---|
committer | Brad Davis <[email protected]> | 2014-05-23 01:49:32 -0700 |
commit | 46acc0e194ff3c1f120199eeca8324b4502118e9 (patch) | |
tree | b1030198d3ee4698445d1fc5161cebe4158e45d1 /LibOVR/Src/Util/Util_ImageWindow.cpp | |
parent | 07d0f4d0bbf3477ac6a9584f726e8ec6ab285707 (diff) |
Updating to 0.3.2 (windows version)
Diffstat (limited to 'LibOVR/Src/Util/Util_ImageWindow.cpp')
-rw-r--r-- | LibOVR/Src/Util/Util_ImageWindow.cpp | 290 |
1 files changed, 164 insertions, 126 deletions
diff --git a/LibOVR/Src/Util/Util_ImageWindow.cpp b/LibOVR/Src/Util/Util_ImageWindow.cpp index e038d1f..cb091c7 100644 --- a/LibOVR/Src/Util/Util_ImageWindow.cpp +++ b/LibOVR/Src/Util/Util_ImageWindow.cpp @@ -27,8 +27,12 @@ limitations under the License. #include "Util_ImageWindow.h" +#if defined(OVR_OS_WIN32) + #include <Windows.h> +#include "DWrite.h" + typedef HRESULT (WINAPI *D2D1CreateFactoryFn)( _In_ D2D1_FACTORY_TYPE, _In_ REFIID, @@ -36,11 +40,19 @@ typedef HRESULT (WINAPI *D2D1CreateFactoryFn)( _Out_ ID2D1Factory ** ); +typedef HRESULT (WINAPI *DWriteCreateFactoryFn)( + _In_ DWRITE_FACTORY_TYPE factoryType, + _In_ REFIID iid, + _Out_ IUnknown **factory + ); + namespace OVR { namespace Util { ID2D1Factory* ImageWindow::pD2DFactory = NULL; -ImageWindow* ImageWindow::globalWindow = NULL; +IDWriteFactory* ImageWindow::pDWriteFactory = NULL; +ImageWindow* ImageWindow::globalWindow[4]; +int ImageWindow::windowCount = 0; LRESULT CALLBACK MainWndProc( HWND hwnd, @@ -83,25 +95,31 @@ LRESULT CALLBACK MainWndProc( //return 0; } -ImageWindow::ImageWindow() : +ImageWindow::ImageWindow( uint32_t width, uint32_t height ) : frontBufferMutex( new Mutex() ) { HINSTANCE hInst = LoadLibrary( L"d2d1.dll" ); + HINSTANCE hInstWrite = LoadLibrary( L"Dwrite.dll" ); D2D1CreateFactoryFn createFactory = NULL; + DWriteCreateFactoryFn writeFactory = NULL; if( hInst ) { createFactory = (D2D1CreateFactoryFn)GetProcAddress( hInst, "D2D1CreateFactory" ); } - globalWindow = this; + if( hInstWrite ) + { + writeFactory = (DWriteCreateFactoryFn)GetProcAddress( hInstWrite, "DWriteCreateFactory" ); + } + + globalWindow[windowCount] = this; - int width = 752; - int height = 480; + ++windowCount; - if( pD2DFactory == NULL && createFactory ) + if( pD2DFactory == NULL && createFactory && writeFactory ) { createFactory( D2D1_FACTORY_TYPE_MULTI_THREADED, @@ -109,6 +127,14 @@ ImageWindow::ImageWindow() : NULL, &pD2DFactory ); + + // Create a DirectWrite factory. + writeFactory( + DWRITE_FACTORY_TYPE_SHARED, + __uuidof(pDWriteFactory), + reinterpret_cast<IUnknown **>(&pDWriteFactory) + ); + } resolution = D2D1::SizeU( width, height ); @@ -120,84 +146,17 @@ ImageWindow::ImageWindow() : colorBitmap = NULL; } -ImageWindow::ImageWindow( UINT width, UINT height ) : - frontBufferMutex( new Mutex() ) +ImageWindow::~ImageWindow() { - - - HINSTANCE hInstance = GetModuleHandle( NULL ); - - WNDCLASS wc; - wc.lpszClassName = L"ImageWindowClass"; - wc.lpfnWndProc = MainWndProc; - wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW; - wc.hInstance = hInstance; - wc.hIcon = LoadIcon( NULL, IDI_APPLICATION ); - wc.hCursor = LoadCursor( NULL, IDC_ARROW ); - wc.hbrBackground = (HBRUSH)( COLOR_WINDOW+1 ); - wc.lpszMenuName = L""; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - - RegisterClass(&wc); - - hWindow = CreateWindow( - L"ImageWindowClass", - L"ImageWindow", - WS_OVERLAPPEDWINDOW & ~WS_SYSMENU, - CW_USEDEFAULT, - CW_USEDEFAULT, - width, - height, - NULL, - NULL, - hInstance, - NULL); - - resolution = D2D1::SizeU( width, height ); - - SetWindowLongPtr( hWindow, GWLP_USERDATA, (LONG_PTR)this ); - - ShowWindow( hWindow, SW_SHOW ); - - RECT rc = {0}; - GetClientRect( hWindow, &rc ); - - D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(); - D2D1_HWND_RENDER_TARGET_PROPERTIES hwndProps = D2D1::HwndRenderTargetProperties( - hWindow, - resolution - ); - - ID2D1HwndRenderTarget* hwndTarget = NULL; - // Create a Direct2D render target - pRT = NULL; - pD2DFactory->CreateHwndRenderTarget( - &props, - &hwndProps, - &hwndTarget - ); - - pRT = hwndTarget; - - D2D1_SIZE_U size = D2D1::SizeU( width, height ); - - D2D1_PIXEL_FORMAT pixelFormat = D2D1::PixelFormat( - DXGI_FORMAT_A8_UNORM, - D2D1_ALPHA_MODE_PREMULTIPLIED - ); - - D2D1_BITMAP_PROPERTIES bitmapProps; - bitmapProps.dpiX = 72; - bitmapProps.dpiY = 72; - bitmapProps.pixelFormat = pixelFormat; - - HRESULT result = pRT->CreateBitmap( size, bitmapProps, &greyBitmap ); - result = pRT->CreateBitmap( size, bitmapProps, &colorBitmap ); + for( int i = 0; i < MaxWindows; ++i ) + { + if( globalWindow[i] == this ) + { + globalWindow[i] = NULL; + break; + } } -ImageWindow::~ImageWindow() -{ if( greyBitmap ) greyBitmap->Release(); @@ -207,6 +166,15 @@ ImageWindow::~ImageWindow() if( pRT ) pRT->Release(); + { + Mutex::Locker locker( frontBufferMutex ); + + while( frames.GetSize() ) + { + Ptr<Frame> aFrame = frames.PopBack(); + } + } + delete frontBufferMutex; ShowWindow( hWindow, SW_HIDE ); @@ -291,6 +259,8 @@ void ImageWindow::Process() if( pRT && greyBitmap ) { OnPaint(); + + pRT->Flush(); } } @@ -301,55 +271,48 @@ void ImageWindow::Complete() if( frames.IsEmpty() ) return; - if( frames.PeekBack(0).ready ) + if( frames.PeekBack(0)->ready ) return; - Frame& frame = frames.PeekBack(0); + Ptr<Frame> frame = frames.PeekBack(0); - frame.ready = true; + frame->ready = true; } void ImageWindow::OnPaint() { - static float mover = -752.0f; - Mutex::Locker locker( frontBufferMutex ); // Nothing to do if( frames.IsEmpty() ) return; - if( !frames.PeekFront(0).ready ) + if( !frames.PeekFront(0)->ready ) return; - Frame currentFrame = frames.PopFront(); - Frame dummyFrame = {0}; + Ptr<Frame> currentFrame = frames.PopFront(); - Frame& nextFrame = dummyFrame; + Ptr<Frame> nextFrame = NULL; if( !frames.IsEmpty() ) nextFrame = frames.PeekFront(0); - while( nextFrame.ready ) + while( nextFrame && nextFrame->ready ) { // Free up the current frame since it's been removed from the deque - free( currentFrame.imageData ); - if( currentFrame.colorImageData ) - free( currentFrame.colorImageData ); - currentFrame = frames.PopFront(); if( frames.IsEmpty() ) - return; + break; nextFrame = frames.PeekFront(0); } - if( currentFrame.imageData ) - greyBitmap->CopyFromMemory( NULL, currentFrame.imageData, currentFrame.width ); + if( currentFrame->imageData ) + greyBitmap->CopyFromMemory( NULL, currentFrame->imageData, currentFrame->width ); - if( currentFrame.colorImageData ) - colorBitmap->CopyFromMemory( NULL, currentFrame.colorImageData, currentFrame.colorPitch ); + if( currentFrame->colorImageData ) + colorBitmap->CopyFromMemory( NULL, currentFrame->colorImageData, currentFrame->colorPitch ); pRT->BeginDraw(); @@ -368,14 +331,15 @@ void ImageWindow::OnPaint() pRT->CreateSolidColorBrush( D2D1::ColorF(D2D1::ColorF::White, 1.0f), &whiteBrush ); - if( currentFrame.imageData ) + if( currentFrame->imageData ) { pRT->FillOpacityMask( greyBitmap, whiteBrush, D2D1_OPACITY_MASK_CONTENT_TEXT_NATURAL, D2D1::RectF( -(FLOAT)resolution.width, 0.0f, (FLOAT)0.0f, (FLOAT)resolution.height ), + //D2D1::RectF( 0.0f, 0.0f, (FLOAT)0.0f, (FLOAT)resolution.height ), D2D1::RectF( 0.0f, 0.0f, (FLOAT)resolution.width, (FLOAT)resolution.height ) ); } - else if( currentFrame.colorImageData ) + else if( currentFrame->colorImageData ) { pRT->DrawBitmap( colorBitmap, D2D1::RectF( -(FLOAT)resolution.width, 0.0f, (FLOAT)0.0f, (FLOAT)resolution.height ) ); @@ -388,7 +352,7 @@ void ImageWindow::OnPaint() Array<CirclePlot>::Iterator it; - for( it = currentFrame.plots.Begin(); it != currentFrame.plots.End(); ++it ) + for( it = currentFrame->plots.Begin(); it != currentFrame->plots.End(); ++it ) { ID2D1SolidColorBrush* aBrush; @@ -408,44 +372,96 @@ void ImageWindow::OnPaint() aBrush->Release(); } + static const WCHAR msc_fontName[] = L"Verdana"; + static const FLOAT msc_fontSize = 20; + + IDWriteTextFormat* textFormat = NULL; + + // Create a DirectWrite text format object. + pDWriteFactory->CreateTextFormat( + msc_fontName, + NULL, + DWRITE_FONT_WEIGHT_NORMAL, + DWRITE_FONT_STYLE_NORMAL, + DWRITE_FONT_STRETCH_NORMAL, + msc_fontSize, + L"", //locale + &textFormat + ); + + D2D1_SIZE_F renderTargetSize = pRT->GetSize(); + + Array<TextPlot>::Iterator textIt; + for( textIt = currentFrame->textLines.Begin(); textIt != currentFrame->textLines.End(); ++textIt ) + { + ID2D1SolidColorBrush* aBrush; + + pRT->CreateSolidColorBrush( D2D1::ColorF( textIt->r, textIt->g, textIt->b), &aBrush ); + + WCHAR* tmpString = (WCHAR*)calloc( textIt->text.GetLength(), sizeof( WCHAR ) ); + for( unsigned i = 0; i < textIt->text.GetLength(); ++i ) + { + tmpString[i] = (WCHAR)textIt->text.GetCharAt( i ); + } + + pRT->DrawTextW( tmpString, (UINT32)textIt->text.GetLength(), textFormat, + D2D1::RectF(textIt->x, textIt->y, renderTargetSize.width, renderTargetSize.height), aBrush ); + + free( tmpString ); + + aBrush->Release(); + } + + if( textFormat ) + textFormat->Release(); + pRT->EndDraw(); - if( currentFrame.imageData ) - free( currentFrame.imageData ); - if( currentFrame.colorImageData ) - free( currentFrame.colorImageData ); + pRT->Flush(); } -void ImageWindow::UpdateImageBW( const UINT8* imageData, UINT width, UINT height ) +Ptr<Frame> ImageWindow::lastUnreadyFrame() +{ + static int framenumber = 0; + + if( frames.GetSize() && !frames.PeekBack( 0 )->ready ) + return frames.PeekBack( 0 ); + + // Create a new frame if an unready one doesn't already exist + Ptr<Frame> tmpFrame = *new Frame( framenumber ); + frames.PushBack( tmpFrame ); + + ++framenumber; + + return tmpFrame; +} + +void ImageWindow::UpdateImageBW( const uint8_t* imageData, uint32_t width, uint32_t height ) { if( pRT && greyBitmap ) { Mutex::Locker locker( frontBufferMutex ); - Frame frame = {0}; - frame.imageData = malloc( width * height ); - frame.width = width; - frame.height = height; - memcpy( frame.imageData, imageData, width * height ); - - frames.PushBack( frame ); + Ptr<Frame> frame = lastUnreadyFrame(); + frame->imageData = malloc( width * height ); + frame->width = width; + frame->height = height; + memcpy( frame->imageData, imageData, width * height ); } } -void ImageWindow::UpdateImageRGBA( const UINT8* imageData, UINT width, UINT height, UINT pitch ) +void ImageWindow::UpdateImageRGBA( const uint8_t* imageData, uint32_t width, uint32_t height, uint32_t pitch ) { if( pRT && colorBitmap ) { Mutex::Locker locker( frontBufferMutex ); - Frame frame = {0}; - frame.colorImageData = malloc( pitch * height ); - frame.width = width; - frame.height = height; - frame.colorPitch = pitch; - memcpy( frame.colorImageData, imageData, pitch * height ); - - frames.PushBack( frame ); + Ptr<Frame> frame = lastUnreadyFrame(); + frame->colorImageData = malloc( pitch * height ); + frame->width = width; + frame->height = height; + frame->colorPitch = pitch; + memcpy( frame->colorImageData, imageData, pitch * height ); } } @@ -464,10 +480,32 @@ void ImageWindow::addCircle( float x, float y, float radius, float r, float g, f cp.fill = fill; Mutex::Locker locker( frontBufferMutex ); - Frame& frame = frames.PeekBack( 0 ); - frame.plots.PushBack( cp ); + + Ptr<Frame> frame = lastUnreadyFrame(); + frame->plots.PushBack( cp ); } } +void ImageWindow::addText( float x, float y, float r, float g, float b, OVR::String text ) +{ + if( pRT ) + { + TextPlot tp; + + tp.x = x; + tp.y = y; + tp.r = r; + tp.g = g; + tp.b = b; + tp.text = text; + + Mutex::Locker locker( frontBufferMutex ); + Ptr<Frame> frame = lastUnreadyFrame(); + frame->textLines.PushBack( tp ); + } +} + }} + +#endif //defined(OVR_OS_WIN32)
\ No newline at end of file |