mirror of
https://github.com/mii443/rust-openvr.git
synced 2025-08-25 17:49:24 +00:00
added linux makefile
This commit is contained in:
511
modules/oculus_sdk_linux/LibOVR/Src/Util/Util_ImageWindow.cpp
Normal file
511
modules/oculus_sdk_linux/LibOVR/Src/Util/Util_ImageWindow.cpp
Normal file
@ -0,0 +1,511 @@
|
||||
/************************************************************************************
|
||||
|
||||
Filename : Util_ImageWindow.cpp
|
||||
Content : An output object for windows that can display raw images for testing
|
||||
Created : March 13, 2014
|
||||
Authors : Dean Beeler
|
||||
|
||||
Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
|
||||
|
||||
Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License");
|
||||
you may not use the Oculus VR Rift SDK except in compliance with the License,
|
||||
which is provided at the time of installation or download, or which
|
||||
otherwise accompanies this software in either electronic or hard copy form.
|
||||
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.oculusvr.com/licenses/LICENSE-3.1
|
||||
|
||||
Unless required by applicable law or agreed to in writing, the Oculus VR SDK
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*************************************************************************************/
|
||||
#include "../../Include/OVR.h"
|
||||
|
||||
#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,
|
||||
_In_opt_ const D2D1_FACTORY_OPTIONS*,
|
||||
_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;
|
||||
IDWriteFactory* ImageWindow::pDWriteFactory = NULL;
|
||||
ImageWindow* ImageWindow::globalWindow[4];
|
||||
int ImageWindow::windowCount = 0;
|
||||
|
||||
LRESULT CALLBACK MainWndProc(
|
||||
HWND hwnd,
|
||||
UINT uMsg,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam)
|
||||
{
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_CREATE:
|
||||
return 0;
|
||||
|
||||
case WM_PAINT:
|
||||
{
|
||||
LONG_PTR ptr = GetWindowLongPtr( hwnd, GWLP_USERDATA );
|
||||
if( ptr )
|
||||
{
|
||||
ImageWindow* iw = (ImageWindow*)ptr;
|
||||
iw->OnPaint();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
case WM_SIZE:
|
||||
// Set the size and position of the window.
|
||||
return 0;
|
||||
|
||||
case WM_DESTROY:
|
||||
// Clean up window-specific data objects.
|
||||
return 0;
|
||||
|
||||
//
|
||||
// Process other messages.
|
||||
//
|
||||
|
||||
default:
|
||||
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
//return 0;
|
||||
}
|
||||
|
||||
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" );
|
||||
}
|
||||
|
||||
if( hInstWrite )
|
||||
{
|
||||
writeFactory = (DWriteCreateFactoryFn)GetProcAddress( hInstWrite, "DWriteCreateFactory" );
|
||||
}
|
||||
|
||||
globalWindow[windowCount] = this;
|
||||
|
||||
++windowCount;
|
||||
|
||||
if( pD2DFactory == NULL && createFactory && writeFactory )
|
||||
{
|
||||
createFactory(
|
||||
D2D1_FACTORY_TYPE_MULTI_THREADED,
|
||||
__uuidof(ID2D1Factory),
|
||||
NULL,
|
||||
&pD2DFactory
|
||||
);
|
||||
|
||||
// Create a DirectWrite factory.
|
||||
writeFactory(
|
||||
DWRITE_FACTORY_TYPE_SHARED,
|
||||
__uuidof(pDWriteFactory),
|
||||
reinterpret_cast<IUnknown **>(&pDWriteFactory)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
resolution = D2D1::SizeU( width, height );
|
||||
|
||||
SetWindowLongPtr( hWindow, GWLP_USERDATA, (LONG_PTR)this );
|
||||
|
||||
pRT = NULL;
|
||||
greyBitmap = NULL;
|
||||
colorBitmap = NULL;
|
||||
}
|
||||
|
||||
ImageWindow::~ImageWindow()
|
||||
{
|
||||
for( int i = 0; i < MaxWindows; ++i )
|
||||
{
|
||||
if( globalWindow[i] == this )
|
||||
{
|
||||
globalWindow[i] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( greyBitmap )
|
||||
greyBitmap->Release();
|
||||
|
||||
if( colorBitmap )
|
||||
colorBitmap->Release();
|
||||
|
||||
if( pRT )
|
||||
pRT->Release();
|
||||
|
||||
{
|
||||
Mutex::Locker locker( frontBufferMutex );
|
||||
|
||||
while( frames.GetSize() )
|
||||
{
|
||||
Ptr<Frame> aFrame = frames.PopBack();
|
||||
}
|
||||
}
|
||||
|
||||
delete frontBufferMutex;
|
||||
|
||||
ShowWindow( hWindow, SW_HIDE );
|
||||
DestroyWindow( hWindow );
|
||||
}
|
||||
|
||||
void ImageWindow::AssociateSurface( void* surface )
|
||||
{
|
||||
// Assume an IUnknown
|
||||
IUnknown* unknown = (IUnknown*)surface;
|
||||
|
||||
IDXGISurface *pDxgiSurface = NULL;
|
||||
HRESULT hr = unknown->QueryInterface(&pDxgiSurface);
|
||||
if( hr == S_OK )
|
||||
{
|
||||
D2D1_RENDER_TARGET_PROPERTIES props =
|
||||
D2D1::RenderTargetProperties(
|
||||
D2D1_RENDER_TARGET_TYPE_DEFAULT,
|
||||
D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED),
|
||||
96,
|
||||
96
|
||||
);
|
||||
|
||||
|
||||
pRT = NULL;
|
||||
ID2D1RenderTarget* tmpTarget;
|
||||
|
||||
hr = pD2DFactory->CreateDxgiSurfaceRenderTarget( pDxgiSurface, &props, &tmpTarget );
|
||||
|
||||
if( hr == S_OK )
|
||||
{
|
||||
DXGI_SURFACE_DESC desc = {0};
|
||||
pDxgiSurface->GetDesc( &desc );
|
||||
int width = desc.Width;
|
||||
int height = desc.Height;
|
||||
|
||||
D2D1_SIZE_U size = D2D1::SizeU( width, height );
|
||||
|
||||
D2D1_PIXEL_FORMAT pixelFormat = D2D1::PixelFormat(
|
||||
DXGI_FORMAT_A8_UNORM,
|
||||
D2D1_ALPHA_MODE_PREMULTIPLIED
|
||||
);
|
||||
|
||||
D2D1_PIXEL_FORMAT colorPixelFormat = D2D1::PixelFormat(
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
D2D1_ALPHA_MODE_PREMULTIPLIED
|
||||
);
|
||||
|
||||
D2D1_BITMAP_PROPERTIES bitmapProps;
|
||||
bitmapProps.dpiX = 96;
|
||||
bitmapProps.dpiY = 96;
|
||||
bitmapProps.pixelFormat = pixelFormat;
|
||||
|
||||
D2D1_BITMAP_PROPERTIES colorBitmapProps;
|
||||
colorBitmapProps.dpiX = 96;
|
||||
colorBitmapProps.dpiY = 96;
|
||||
colorBitmapProps.pixelFormat = colorPixelFormat;
|
||||
|
||||
HRESULT result = tmpTarget->CreateBitmap( size, bitmapProps, &greyBitmap );
|
||||
if( result != S_OK )
|
||||
{
|
||||
tmpTarget->Release();
|
||||
tmpTarget = NULL;
|
||||
}
|
||||
|
||||
result = tmpTarget->CreateBitmap( size, colorBitmapProps, &colorBitmap );
|
||||
if( result != S_OK )
|
||||
{
|
||||
greyBitmap->Release();
|
||||
greyBitmap = NULL;
|
||||
|
||||
tmpTarget->Release();
|
||||
tmpTarget = NULL;
|
||||
}
|
||||
pRT = tmpTarget;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ImageWindow::Process()
|
||||
{
|
||||
if( pRT && greyBitmap )
|
||||
{
|
||||
OnPaint();
|
||||
|
||||
pRT->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
void ImageWindow::Complete()
|
||||
{
|
||||
Mutex::Locker locker( frontBufferMutex );
|
||||
|
||||
if( frames.IsEmpty() )
|
||||
return;
|
||||
|
||||
if( frames.PeekBack(0)->ready )
|
||||
return;
|
||||
|
||||
Ptr<Frame> frame = frames.PeekBack(0);
|
||||
|
||||
frame->ready = true;
|
||||
}
|
||||
|
||||
void ImageWindow::OnPaint()
|
||||
{
|
||||
Mutex::Locker locker( frontBufferMutex );
|
||||
|
||||
// Nothing to do
|
||||
if( frames.IsEmpty() )
|
||||
return;
|
||||
|
||||
if( !frames.PeekFront(0)->ready )
|
||||
return;
|
||||
|
||||
Ptr<Frame> currentFrame = frames.PopFront();
|
||||
|
||||
Ptr<Frame> nextFrame = NULL;
|
||||
|
||||
if( !frames.IsEmpty() )
|
||||
nextFrame = frames.PeekFront(0);
|
||||
|
||||
while( nextFrame && nextFrame->ready )
|
||||
{
|
||||
// Free up the current frame since it's been removed from the deque
|
||||
currentFrame = frames.PopFront();
|
||||
|
||||
if( frames.IsEmpty() )
|
||||
break;
|
||||
|
||||
nextFrame = frames.PeekFront(0);
|
||||
}
|
||||
|
||||
if( currentFrame->imageData )
|
||||
greyBitmap->CopyFromMemory( NULL, currentFrame->imageData, currentFrame->width );
|
||||
|
||||
if( currentFrame->colorImageData )
|
||||
colorBitmap->CopyFromMemory( NULL, currentFrame->colorImageData, currentFrame->colorPitch );
|
||||
|
||||
pRT->BeginDraw();
|
||||
|
||||
pRT->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
|
||||
|
||||
pRT->Clear( D2D1::ColorF(D2D1::ColorF::Black) );
|
||||
|
||||
// This will mirror our image
|
||||
D2D1_MATRIX_3X2_F m;
|
||||
m._11 = -1; m._12 = 0;
|
||||
m._21 = 0; m._22 = 1;
|
||||
m._31 = 0; m._32 = 0;
|
||||
pRT->SetTransform( m );
|
||||
|
||||
ID2D1SolidColorBrush* whiteBrush;
|
||||
|
||||
pRT->CreateSolidColorBrush( D2D1::ColorF(D2D1::ColorF::White, 1.0f), &whiteBrush );
|
||||
|
||||
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 )
|
||||
{
|
||||
pRT->DrawBitmap( colorBitmap,
|
||||
D2D1::RectF( -(FLOAT)resolution.width, 0.0f, (FLOAT)0.0f, (FLOAT)resolution.height ) );
|
||||
|
||||
}
|
||||
|
||||
pRT->SetTransform(D2D1::Matrix3x2F::Identity());
|
||||
|
||||
whiteBrush->Release();
|
||||
|
||||
Array<CirclePlot>::Iterator it;
|
||||
|
||||
for( it = currentFrame->plots.Begin(); it != currentFrame->plots.End(); ++it )
|
||||
{
|
||||
ID2D1SolidColorBrush* aBrush;
|
||||
|
||||
pRT->CreateSolidColorBrush( D2D1::ColorF( it->r, it->g, it->b), &aBrush );
|
||||
|
||||
D2D1_ELLIPSE ellipse;
|
||||
ellipse.point.x = it->x;
|
||||
ellipse.point.y = it->y;
|
||||
ellipse.radiusX = it->radius;
|
||||
ellipse.radiusY = it->radius;
|
||||
|
||||
if( it->fill )
|
||||
pRT->FillEllipse( &ellipse, aBrush );
|
||||
else
|
||||
pRT->DrawEllipse( &ellipse, aBrush );
|
||||
|
||||
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();
|
||||
|
||||
pRT->Flush();
|
||||
}
|
||||
|
||||
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 );
|
||||
|
||||
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_t* imageData, uint32_t width, uint32_t height, uint32_t pitch )
|
||||
{
|
||||
if( pRT && colorBitmap )
|
||||
{
|
||||
Mutex::Locker locker( frontBufferMutex );
|
||||
|
||||
Ptr<Frame> frame = lastUnreadyFrame();
|
||||
frame->colorImageData = malloc( pitch * height );
|
||||
frame->width = width;
|
||||
frame->height = height;
|
||||
frame->colorPitch = pitch;
|
||||
memcpy( frame->colorImageData, imageData, pitch * height );
|
||||
}
|
||||
}
|
||||
|
||||
void ImageWindow::addCircle( float x, float y, float radius, float r, float g, float b, bool fill )
|
||||
{
|
||||
if( pRT )
|
||||
{
|
||||
CirclePlot cp;
|
||||
|
||||
cp.x = x;
|
||||
cp.y = y;
|
||||
cp.radius = radius;
|
||||
cp.r = r;
|
||||
cp.g = g;
|
||||
cp.b = b;
|
||||
cp.fill = fill;
|
||||
|
||||
Mutex::Locker locker( frontBufferMutex );
|
||||
|
||||
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)
|
Reference in New Issue
Block a user