This commit is contained in:
jim 2012-11-02 00:09:06 -07:00
parent d7c413cd58
commit 8021e7c49b
19 changed files with 714 additions and 85 deletions

View File

@ -1,6 +1,26 @@
(yyyy-mm-dd) (yyyy-mm-dd)
-------------------------------
2012-11-02 - 0.432 (alpha)
* Fixed GDI+ output not displaying on some computers
* Changed text source so that text extents do not cut off
text
* Added color key option to software capture
* Changed color key in directshow plugin to chroma key, made
it not suck (thanks to muf, he pointed out important
equations)
* Changed the way framerate works in directshow plugin, it
now internally works on frame intervals instead of trying
to (incorrectly) input intervals -- will always use the
closest valid interval available. FPS now functions in
floating point units instead of integers.
* Added a feature to allow the user to select the output type
from his/her device, which is useful is many cases
apparently.
* Changed hotkeys so that you can now bind Alt/Shift/Ctrl
by themselves.
------------------------------- -------------------------------
2012-10-28 - 0.43 (alpha) 2012-10-28 - 0.43 (alpha)
* Added text output source * Added text output source

View File

@ -782,6 +782,8 @@ void DeviceSource::UpdateSettings()
if(renderCX != newCX || renderCY != newCY || frameInterval != newFrameInterval || newPreferredType != preferredOutputType || !strDevice.CompareI(strNewDevice) || bNewCustom != bUseCustomResolution) if(renderCX != newCX || renderCY != newCY || frameInterval != newFrameInterval || newPreferredType != preferredOutputType || !strDevice.CompareI(strNewDevice) || bNewCustom != bUseCustomResolution)
{ {
API->EnterSceneMutex();
bool bWasCapturing = bCapturing; bool bWasCapturing = bCapturing;
if(bWasCapturing) Stop(); if(bWasCapturing) Stop();
@ -789,6 +791,8 @@ void DeviceSource::UpdateSettings()
LoadFilters(); LoadFilters();
if(bWasCapturing) Start(); if(bWasCapturing) Start();
API->LeaveSceneMutex();
} }
traceOut; traceOut;

37
OBS.rc
View File

@ -190,7 +190,7 @@ BEGIN
PUSHBUTTON "Cancel",IDCANCEL,209,28,50,14 PUSHBUTTON "Cancel",IDCANCEL,209,28,50,14
END END
IDD_CONFIGUREDESKTOPSOURCE DIALOGEX 0, 0, 379, 212 IDD_CONFIGUREDESKTOPSOURCE DIALOGEX 0, 0, 379, 300
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Sources.SoftwareCaptureSource" CAPTION "Sources.SoftwareCaptureSource"
FONT 8, "MS Shell Dlg", 400, 0, 0x1 FONT 8, "MS Shell Dlg", 400, 0, 0x1
@ -215,12 +215,24 @@ BEGIN
RTEXT "Sources.SoftwareCaptureSource.Position",IDC_STATIC,7,151,96,8 RTEXT "Sources.SoftwareCaptureSource.Position",IDC_STATIC,7,151,96,8
EDITTEXT IDC_POSX,107,148,40,14,ES_AUTOHSCROLL EDITTEXT IDC_POSX,107,148,40,14,ES_AUTOHSCROLL
EDITTEXT IDC_POSY,149,148,40,14,ES_AUTOHSCROLL EDITTEXT IDC_POSY,149,148,40,14,ES_AUTOHSCROLL
PUSHBUTTON "Sources.SoftwareCaptureSource.SelectRegion",IDC_SELECTREGION,193,148,77,14
RTEXT "Sources.SoftwareCaptureSource.Size",IDC_STATIC,7,168,96,8 RTEXT "Sources.SoftwareCaptureSource.Size",IDC_STATIC,7,168,96,8
EDITTEXT IDC_SIZEX,107,166,40,14,ES_AUTOHSCROLL | ES_NUMBER EDITTEXT IDC_SIZEX,107,166,40,14,ES_AUTOHSCROLL | ES_NUMBER
EDITTEXT IDC_SIZEY,149,166,40,14,ES_AUTOHSCROLL | ES_NUMBER EDITTEXT IDC_SIZEY,149,166,40,14,ES_AUTOHSCROLL | ES_NUMBER
PUSHBUTTON "Sources.SoftwareCaptureSource.SelectRegion",IDC_SELECTREGION,193,148,77,14 GROUPBOX "Sources.SoftwareCaptureSource.ColorKey",IDC_STATIC,7,187,274,87
DEFPUSHBUTTON "OK",IDOK,268,191,50,14 CONTROL "Sources.SoftwareCaptureSource.UseColorKey",IDC_USECOLORKEY,
PUSHBUTTON "Cancel",IDCANCEL,322,191,50,14 "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,201,130,10,WS_EX_RIGHT
RTEXT "Color",IDC_STATIC,18,219,117,8
CONTROL "",IDC_COLOR,"OBSColorControl",WS_TABSTOP,138,216,28,14
PUSHBUTTON "Sources.SoftwareCaptureSource.Select",IDC_SELECT,169,216,64,14
RTEXT "Sources.SoftwareCaptureSource.Similarity",IDC_STATIC,18,237,117,8
EDITTEXT IDC_BASETHRESHOLD_EDIT,137,235,40,14,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "",IDC_BASETHRESHOLD,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,178,235,11,14
RTEXT "Sources.SoftwareCaptureSource.Blend",IDC_STATIC,17,254,117,8
EDITTEXT IDC_BLEND_EDIT,137,252,40,14,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "",IDC_BLEND,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,177,252,11,14
DEFPUSHBUTTON "OK",IDOK,268,279,50,14
PUSHBUTTON "Cancel",IDCANCEL,322,279,50,14
END END
IDD_CONFIGUREBITMAPSOURCE DIALOGEX 0, 0, 244, 85 IDD_CONFIGUREBITMAPSOURCE DIALOGEX 0, 0, 244, 85
@ -450,7 +462,7 @@ BEGIN
LEFTMARGIN, 7 LEFTMARGIN, 7
RIGHTMARGIN, 372 RIGHTMARGIN, 372
TOPMARGIN, 7 TOPMARGIN, 7
BOTTOMMARGIN, 205 BOTTOMMARGIN, 293
END END
IDD_CONFIGUREBITMAPSOURCE, DIALOG IDD_CONFIGUREBITMAPSOURCE, DIALOG
@ -578,8 +590,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,4,3,0 FILEVERSION 0,4,3,2
PRODUCTVERSION 0,4,3,0 PRODUCTVERSION 0,4,3,2
FILEFLAGSMASK 0x17L FILEFLAGSMASK 0x17L
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -595,12 +607,12 @@ BEGIN
BLOCK "041104b0" BLOCK "041104b0"
BEGIN BEGIN
VALUE "FileDescription", "Open Broadcaster Software" VALUE "FileDescription", "Open Broadcaster Software"
VALUE "FileVersion", "0, 4, 3, 0" VALUE "FileVersion", "0, 4, 3, 2"
VALUE "InternalName", "OBS" VALUE "InternalName", "OBS"
VALUE "LegalCopyright", "Copyright (C) 2012" VALUE "LegalCopyright", "Copyright (C) 2012"
VALUE "OriginalFilename", "OBS.exe" VALUE "OriginalFilename", "OBS.exe"
VALUE "ProductName", "Open Broadcaster Software" VALUE "ProductName", "Open Broadcaster Software"
VALUE "ProductVersion", "0, 4, 3, 0" VALUE "ProductVersion", "0, 4, 3, 2"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"
@ -635,6 +647,13 @@ BEGIN
END END
END END
/////////////////////////////////////////////////////////////////////////////
//
// Cursor
//
IDC_COLORPICKER CURSOR "cursor1.cur"
#endif // “ú–{Œê resources #endif // “ú–{Œê resources
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

View File

@ -518,6 +518,10 @@
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
> >
<File
RelativePath=".\cursor1.cur"
>
</File>
<File <File
RelativePath=".\ui\mic2-muted.ico" RelativePath=".\ui\mic2-muted.ico"
> >

View File

@ -463,6 +463,8 @@ public:
virtual void SetViewport(float x, float y, float width, float height)=0; virtual void SetViewport(float x, float y, float width, float height)=0;
virtual void SetScissorRect(XRect *pRect=NULL)=0;
protected: protected:
//manual coordinate generation //manual coordinate generation
VBData *vbd; VBData *vbd;
@ -570,6 +572,7 @@ inline void Frustum(float left, float right, float top, float bottom, float zne
{GS->Frustum(left, right, top, bottom, znear, zfar);} {GS->Frustum(left, right, top, bottom, znear, zfar);}
inline void SetViewport(float x, float y, float width, float height) {GS->SetViewport(x, y, width, height);} inline void SetViewport(float x, float y, float width, float height) {GS->SetViewport(x, y, width, height);}
inline void SetScissorRect(XRect *pRect=NULL) {GS->SetScissorRect(pRect);}
inline void DrawSprite(Texture *texture, DWORD color, float x, float y, float x2 = -998.0f, float y2 = -998.0f) inline void DrawSprite(Texture *texture, DWORD color, float x, float y, float x2 = -998.0f, float y2 = -998.0f)
{GS->DrawSprite(texture, color, x, y, x2, y2);} {GS->DrawSprite(texture, color, x, y, x2, y2);}

View File

@ -102,12 +102,6 @@ LRESULT CALLBACK HotkeyExProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
control->bHasFocus = false; control->bHasFocus = false;
DestroyCaret(); DestroyCaret();
if(!control->hotkeyVK)
{
control->modifiers = 0;
control->bExtendedKey = false;
}
InvalidateRect(hwnd, NULL, TRUE); InvalidateRect(hwnd, NULL, TRUE);
break; break;
} }
@ -306,24 +300,35 @@ void HotkeyControlExData::DrawHotkeyControlEx(HWND hwnd, HDC hDC)
if(hotkeyVK || modifiers) if(hotkeyVK || modifiers)
{ {
bool bAdd = false;
if(modifiers & HOTKEYF_CONTROL) if(modifiers & HOTKEYF_CONTROL)
{ {
GetKeyNameText((LONG)MapVirtualKey(VK_CONTROL, 0) << 16, lpName, 127); GetKeyNameText((LONG)MapVirtualKey(VK_CONTROL, 0) << 16, lpName, 127);
strText << lpName << TEXT(" + "); strText << lpName;
bAdd = true;
} }
if(modifiers & HOTKEYF_SHIFT) if(modifiers & HOTKEYF_SHIFT)
{ {
if(bAdd) strText << TEXT(" + ");
GetKeyNameText((LONG)MapVirtualKey(VK_SHIFT, 0) << 16, lpName, 127); GetKeyNameText((LONG)MapVirtualKey(VK_SHIFT, 0) << 16, lpName, 127);
strText << lpName << TEXT(" + "); strText << lpName;
bAdd = true;
} }
if(modifiers & HOTKEYF_ALT) if(modifiers & HOTKEYF_ALT)
{ {
if(bAdd) strText << TEXT(" + ");
GetKeyNameText((LONG)MapVirtualKey(VK_MENU, 0) << 16, lpName, 127); GetKeyNameText((LONG)MapVirtualKey(VK_MENU, 0) << 16, lpName, 127);
strText << lpName << TEXT(" + "); strText << lpName;
bAdd = true;
} }
if(hotkeyVK) if(hotkeyVK)
{ {
if(bAdd) strText << TEXT(" + ");
if(hotkeyVK <= VK_RBUTTON) if(hotkeyVK <= VK_RBUTTON)
strText << TEXT("Mouse ") << UIntString(hotkeyVK); strText << TEXT("Mouse ") << UIntString(hotkeyVK);
else if(hotkeyVK > VK_CANCEL && hotkeyVK <= VK_XBUTTON2) else if(hotkeyVK > VK_CANCEL && hotkeyVK <= VK_XBUTTON2)

View File

@ -44,7 +44,7 @@ BASE_EXPORT String GetCBText(HWND hwndCombo, UINT id=CB_ERR);
BASE_EXPORT String GetEditText(HWND hwndEdit); BASE_EXPORT String GetEditText(HWND hwndEdit);
//#define SafeRelease(var) if(var) {ULONG chi = var->Release(); OSDebugOut(TEXT("releasing %s, %d refs were left\r\n"), L#var, chi); var = NULL;} #define SafeReleaseLogRef(var) if(var) {ULONG chi = var->Release(); OSDebugOut(TEXT("releasing %s, %d refs were left\r\n"), L#var, chi); var = NULL;}
#define SafeRelease(var) if(var) {var->Release(); var = NULL;} #define SafeRelease(var) if(var) {var->Release(); var = NULL;}
inline void SSECopy(void *lpDest, void *lpSource, UINT size) inline void SSECopy(void *lpDest, void *lpSource, UINT size)

View File

@ -124,6 +124,14 @@ D3D10System::D3D10System()
//------------------------------------------------------------------ //------------------------------------------------------------------
rasterizerDesc.ScissorEnable = TRUE;
err = d3d->CreateRasterizerState(&rasterizerDesc, &scissorState);
if(FAILED(err))
CrashError(TEXT("Unable to create scissor state"));
//------------------------------------------------------------------
ID3D10Texture2D *backBuffer = NULL; ID3D10Texture2D *backBuffer = NULL;
err = swap->GetBuffer(0, IID_ID3D10Texture2D, (void**)&backBuffer); err = swap->GetBuffer(0, IID_ID3D10Texture2D, (void**)&backBuffer);
if(FAILED(err)) if(FAILED(err))
@ -169,6 +177,7 @@ D3D10System::~D3D10System()
for(UINT i=0; i<blends.Num(); i++) for(UINT i=0; i<blends.Num(); i++)
SafeRelease(blends[i].blendState); SafeRelease(blends[i].blendState);
SafeRelease(scissorState);
SafeRelease(rasterizerState); SafeRelease(rasterizerState);
SafeRelease(depthState); SafeRelease(depthState);
SafeRelease(disabledBlend); SafeRelease(disabledBlend);
@ -206,6 +215,7 @@ void D3D10System::UnloadAllData()
d3d->PSSetShader(NULL); d3d->PSSetShader(NULL);
d3d->VSSetShader(NULL); d3d->VSSetShader(NULL);
d3d->RSSetState(NULL); d3d->RSSetState(NULL);
d3d->RSSetScissorRects(0, NULL);
} }
LPVOID D3D10System::GetDevice() LPVOID D3D10System::GetDevice()
@ -630,6 +640,21 @@ void D3D10System::SetViewport(float x, float y, float width, float height)
d3d->RSSetViewports(1, &vp); d3d->RSSetViewports(1, &vp);
} }
void D3D10System::SetScissorRect(XRect *pRect)
{
if(pRect)
{
d3d->RSSetState(scissorState);
D3D10_RECT rc = {pRect->x, pRect->y, pRect->x+pRect->cx, pRect->y+pRect->cy};
d3d->RSSetScissorRects(1, &rc);
}
else
{
d3d->RSSetState(rasterizerState);
d3d->RSSetScissorRects(0, NULL);
}
}
void D3D10System::DrawSpriteEx(Texture *texture, DWORD color, float x, float y, float x2, float y2, float u, float v, float u2, float v2) void D3D10System::DrawSpriteEx(Texture *texture, DWORD color, float x, float y, float x2, float y2, float u, float v, float u2, float v2)
{ {

View File

@ -304,6 +304,7 @@ class D3D10System : public GraphicsSystem
ID3D10DepthStencilState *depthState; ID3D10DepthStencilState *depthState;
ID3D10RasterizerState *rasterizerState; ID3D10RasterizerState *rasterizerState;
ID3D10RasterizerState *scissorState;
bool bDisableCompatibilityMode; bool bDisableCompatibilityMode;
@ -403,6 +404,9 @@ public:
virtual void SetViewport(float x, float y, float width, float height); virtual void SetViewport(float x, float y, float width, float height);
virtual void SetScissorRect(XRect *pRect=NULL);
virtual void DrawSpriteEx(Texture *texture, DWORD color, float x, float y, float x2 = -1.0f, float y2 = -1.0f, float u = -1.0f, float v = -1.0f, float u2 = -1.0f, float v2 = -1.0f); virtual void DrawSpriteEx(Texture *texture, DWORD color, float x, float y, float x2 = -1.0f, float y2 = -1.0f, float u = -1.0f, float v = -1.0f, float u2 = -1.0f, float v2 = -1.0f);
virtual void DrawBox(const Vect2 &upperLeft, const Vect2 &size); virtual void DrawBox(const Vect2 &upperLeft, const Vect2 &size);
}; };

View File

@ -32,6 +32,8 @@ class DesktopImageSource : public ImageSource
BOOL bClientCapture, bCaptureMouse; BOOL bClientCapture, bCaptureMouse;
HWND hwndFoundWindow; HWND hwndFoundWindow;
Shader *colorKeyShader;
int width, height; int width, height;
RECT captureRect; RECT captureRect;
UINT frameTime; UINT frameTime;
@ -40,10 +42,14 @@ class DesktopImageSource : public ImageSource
UINT warningID; UINT warningID;
bool bUseColorKey;
DWORD keyColor;
UINT keySimilarity, keyBlend;
public: public:
DesktopImageSource(UINT frameTime, XElement *data) DesktopImageSource(UINT frameTime, XElement *data)
{ {
traceIn(DesktopImageSource::DesktopImageSource); //traceIn(DesktopImageSource::DesktopImageSource);
this->data = data; this->data = data;
UpdateSettings(); UpdateSettings();
@ -53,12 +59,12 @@ public:
//------------------------------------------------------- //-------------------------------------------------------
traceOut; //traceOut;
} }
~DesktopImageSource() ~DesktopImageSource()
{ {
traceIn(DesktopImageSource::~DesktopImageSource); //traceIn(DesktopImageSource::~DesktopImageSource);
for(int i=0; i<NUM_CAPTURE_TEXTURES; i++) for(int i=0; i<NUM_CAPTURE_TEXTURES; i++)
delete renderTextures[i]; delete renderTextures[i];
@ -66,12 +72,15 @@ public:
if(warningID) if(warningID)
App->RemoveStreamInfo(warningID); App->RemoveStreamInfo(warningID);
traceOut; if(colorKeyShader)
delete colorKeyShader;
//traceOut;
} }
void Preprocess() void Preprocess()
{ {
traceIn(DesktopImageSource::Preprocess); //traceIn(DesktopImageSource::Preprocess);
Texture *captureTexture = renderTextures[curCaptureTexture]; Texture *captureTexture = renderTextures[curCaptureTexture];
@ -221,21 +230,41 @@ public:
if(++curCaptureTexture == NUM_CAPTURE_TEXTURES) if(++curCaptureTexture == NUM_CAPTURE_TEXTURES)
curCaptureTexture = 0; curCaptureTexture = 0;
traceOut; //traceOut;
} }
void Render(const Vect2 &pos, const Vect2 &size) void Render(const Vect2 &pos, const Vect2 &size)
{ {
traceIn(DesktopImageSource::Render); //traceIn(DesktopImageSource::Render);
if(lastRendered) if(lastRendered)
{ {
EnableBlending(FALSE); Shader *lastPixelShader;
if(bUseColorKey)
{
lastPixelShader = GetCurrentPixelShader();
LoadPixelShader(colorKeyShader);
float fSimilarity = float(keySimilarity)*0.01f;
float fBlend = float(keyBlend)*0.01f;
colorKeyShader->SetColor(colorKeyShader->GetParameter(2), keyColor);
colorKeyShader->SetFloat(colorKeyShader->GetParameter(3), fSimilarity);
colorKeyShader->SetFloat(colorKeyShader->GetParameter(4), fBlend);
}
else
EnableBlending(FALSE);
DrawSprite(lastRendered, 0xFFFFFFFF, pos.x, pos.y, pos.x+size.x, pos.y+size.y); DrawSprite(lastRendered, 0xFFFFFFFF, pos.x, pos.y, pos.x+size.x, pos.y+size.y);
EnableBlending(TRUE);
if(bUseColorKey)
LoadPixelShader(lastPixelShader);
else
EnableBlending(TRUE);
} }
traceOut; //traceOut;
} }
Vect2 GetSize() const Vect2 GetSize() const
@ -247,13 +276,11 @@ public:
{ {
App->EnterSceneMutex(); App->EnterSceneMutex();
for(int i=0; i<NUM_CAPTURE_TEXTURES; i++) UINT newCaptureType = data->GetInt(TEXT("captureType"));
delete renderTextures[i]; String strNewWindow = data->GetString(TEXT("window"));
String strNewWindowClass= data->GetString(TEXT("windowClass"));
BOOL bNewClientCapture = data->GetInt(TEXT("innerWindow"), 1);
captureType = data->GetInt(TEXT("captureType"));
strWindow = data->GetString(TEXT("window"));
strWindowClass = data->GetString(TEXT("windowClass"));
bClientCapture = data->GetInt(TEXT("innerWindow"), 1);
bCaptureMouse = data->GetInt(TEXT("captureMouse"), 1); bCaptureMouse = data->GetInt(TEXT("captureMouse"), 1);
int x = data->GetInt(TEXT("captureX")); int x = data->GetInt(TEXT("captureX"));
@ -261,21 +288,85 @@ public:
int cx = data->GetInt(TEXT("captureCX"), 32); int cx = data->GetInt(TEXT("captureCX"), 32);
int cy = data->GetInt(TEXT("captureCY"), 32); int cy = data->GetInt(TEXT("captureCY"), 32);
captureRect.left = x; if( captureRect.left != x || captureRect.right != (x+cx) || captureRect.top != cy || captureRect.bottom != (y+cy) ||
captureRect.top = y; newCaptureType != captureType || !strNewWindowClass.CompareI(strWindowClass) || !strNewWindow.CompareI(strWindow) ||
captureRect.right = x+cx; bNewClientCapture != bClientCapture)
captureRect.bottom = y+cy; {
for(int i=0; i<NUM_CAPTURE_TEXTURES; i++)
delete renderTextures[i];
width = cx; captureType = newCaptureType;
height = cy; strWindow = strNewWindow;
strWindowClass = strNewWindowClass;
bClientCapture = bNewClientCapture;
for(UINT i=0; i<NUM_CAPTURE_TEXTURES; i++) captureRect.left = x;
renderTextures[i] = CreateGDITexture(width, height); captureRect.top = y;
captureRect.right = x+cx;
captureRect.bottom = y+cy;
lastRendered = NULL; width = cx;
height = cy;
for(UINT i=0; i<NUM_CAPTURE_TEXTURES; i++)
renderTextures[i] = CreateGDITexture(width, height);
lastRendered = NULL;
}
bool bNewUseColorKey = data->GetInt(TEXT("useColorKey"), 0) != 0;
keyColor = data->GetInt(TEXT("keyColor"), 0xFFFFFFFF);
keySimilarity = data->GetInt(TEXT("keySimilarity"), 10);
keyBlend = data->GetInt(TEXT("keyBlend"), 0);
if(bNewUseColorKey != bUseColorKey)
{
if(colorKeyShader)
{
delete colorKeyShader;
colorKeyShader = NULL;
}
if(bUseColorKey = bNewUseColorKey)
colorKeyShader = CreatePixelShaderFromFile(TEXT("shaders\\ColorKey_RGB.pShader"));
}
App->LeaveSceneMutex(); App->LeaveSceneMutex();
} }
void SetInt(CTSTR lpName, int iVal)
{
if(scmpi(lpName, TEXT("useColorKey")) == 0)
{
bool bNewVal = iVal != 0;
if(bUseColorKey != bNewVal)
{
API->EnterSceneMutex();
if(colorKeyShader)
{
delete colorKeyShader;
colorKeyShader = NULL;
}
if(bUseColorKey = bNewVal)
colorKeyShader = CreatePixelShaderFromFile(TEXT("shaders\\ColorKey_RGB.pShader"));
API->LeaveSceneMutex();
}
}
else if(scmpi(lpName, TEXT("keyColor")) == 0)
{
keyColor = (DWORD)iVal;
}
else if(scmpi(lpName, TEXT("keySimilarity")) == 0)
{
keySimilarity = iVal;
}
else if(scmpi(lpName, TEXT("keyBlend")) == 0)
{
keyBlend = iVal;
}
}
}; };
ImageSource* STDCALL CreateDesktopSource(XElement *data) ImageSource* STDCALL CreateDesktopSource(XElement *data)
@ -353,6 +444,7 @@ void RefreshWindowList(HWND hwndCombobox, StringList &classList)
struct ConfigDesktopSourceInfo struct ConfigDesktopSourceInfo
{ {
CTSTR lpName;
XElement *data; XElement *data;
StringList strClasses; StringList strClasses;
}; };
@ -701,8 +793,98 @@ LRESULT WINAPI RegionWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM l
return DefWindowProc(hwnd, message, wParam, lParam); return DefWindowProc(hwnd, message, wParam, lParam);
} }
struct ColorSelectionData
{
HDC hdcDesktop;
HDC hdcDestination;
HBITMAP hBitmap;
bool bValid;
inline ColorSelectionData() : hdcDesktop(NULL), hdcDestination(NULL), hBitmap(NULL), bValid(false) {}
inline ~ColorSelectionData() {Clear();}
inline bool Init()
{
hdcDesktop = GetDC(NULL);
if(!hdcDesktop)
return false;
hdcDestination = CreateCompatibleDC(hdcDesktop);
if(!hdcDestination)
return false;
hBitmap = CreateCompatibleBitmap(hdcDesktop, 1, 1);
if(!hBitmap)
return false;
SelectObject(hdcDestination, hBitmap);
bValid = true;
return true;
}
inline void Clear()
{
if(hdcDesktop)
{
ReleaseDC(NULL, hdcDesktop);
hdcDesktop = NULL;
}
if(hdcDestination)
{
DeleteDC(hdcDestination);
hdcDestination = NULL;
}
if(hBitmap)
{
DeleteObject(hBitmap);
hBitmap = NULL;
}
bValid = false;
}
inline DWORD GetColor()
{
POINT p;
if(GetCursorPos(&p))
{
BITMAPINFO data;
zero(&data, sizeof(data));
data.bmiHeader.biSize = sizeof(data.bmiHeader);
data.bmiHeader.biWidth = 1;
data.bmiHeader.biHeight = 1;
data.bmiHeader.biPlanes = 1;
data.bmiHeader.biBitCount = 24;
data.bmiHeader.biCompression = BI_RGB;
data.bmiHeader.biSizeImage = 4;
if(BitBlt(hdcDestination, 0, 0, 1, 1, hdcDesktop, p.x, p.y, SRCCOPY|CAPTUREBLT))
{
DWORD buffer;
if(GetDIBits(hdcDestination, hBitmap, 0, 1, &buffer, &data, DIB_RGB_COLORS))
return 0xFF000000|buffer;
}
else
{
int err = GetLastError();
nop();
}
}
return 0xFF000000;
}
};
INT_PTR CALLBACK ConfigDesktopSourceProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) INT_PTR CALLBACK ConfigDesktopSourceProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{ {
static bool bSelectingColor = false;
static bool bMouseDown = false;
static ColorSelectionData colorData;
switch(message) switch(message)
{ {
case WM_INITDIALOG: case WM_INITDIALOG:
@ -825,9 +1007,93 @@ INT_PTR CALLBACK ConfigDesktopSourceProc(HWND hwnd, UINT message, WPARAM wParam,
ti.uId = (UINT_PTR)GetDlgItem(hwnd, IDC_SELECTREGION); ti.uId = (UINT_PTR)GetDlgItem(hwnd, IDC_SELECTREGION);
SendMessage(hwndToolTip, TTM_ADDTOOL, 0, (LPARAM)&ti); SendMessage(hwndToolTip, TTM_ADDTOOL, 0, (LPARAM)&ti);
//------------------------------------------
BOOL bUseColorKey = data->GetInt(TEXT("useColorKey"), 0);
DWORD keyColor = data->GetInt(TEXT("keyColor"), 0xFFFFFFFF);
UINT similarity = data->GetInt(TEXT("keySimilarity"), 10);
UINT blend = data->GetInt(TEXT("keyBlend"), 0);
SendMessage(GetDlgItem(hwnd, IDC_USECOLORKEY), BM_SETCHECK, bUseColorKey ? BST_CHECKED : BST_UNCHECKED, 0);
CCSetColor(GetDlgItem(hwnd, IDC_COLOR), keyColor);
SendMessage(GetDlgItem(hwnd, IDC_BASETHRESHOLD), UDM_SETRANGE32, 0, 100);
SendMessage(GetDlgItem(hwnd, IDC_BASETHRESHOLD), UDM_SETPOS32, 0, similarity);
SendMessage(GetDlgItem(hwnd, IDC_BLEND), UDM_SETRANGE32, 0, 100);
SendMessage(GetDlgItem(hwnd, IDC_BLEND), UDM_SETPOS32, 0, blend);
EnableWindow(GetDlgItem(hwnd, IDC_COLOR), bUseColorKey);
EnableWindow(GetDlgItem(hwnd, IDC_SELECT), bUseColorKey);
EnableWindow(GetDlgItem(hwnd, IDC_BASETHRESHOLD_EDIT), bUseColorKey);
EnableWindow(GetDlgItem(hwnd, IDC_BASETHRESHOLD), bUseColorKey);
EnableWindow(GetDlgItem(hwnd, IDC_BLEND_EDIT), bUseColorKey);
EnableWindow(GetDlgItem(hwnd, IDC_BLEND), bUseColorKey);
return TRUE; return TRUE;
} }
case WM_DESTROY:
if(colorData.bValid)
{
CCSetColor(GetDlgItem(hwnd, IDC_COLOR), colorData.GetColor());
colorData.Clear();
}
break;
case WM_LBUTTONDOWN:
if(bSelectingColor)
{
bMouseDown = true;
CCSetColor(GetDlgItem(hwnd, IDC_COLOR), colorData.GetColor());
ConfigDesktopSourceProc(hwnd, WM_COMMAND, MAKEWPARAM(IDC_COLOR, CCN_CHANGED), (LPARAM)GetDlgItem(hwnd, IDC_COLOR));
}
break;
case WM_MOUSEMOVE:
if(bSelectingColor && bMouseDown)
{
CCSetColor(GetDlgItem(hwnd, IDC_COLOR), colorData.GetColor());
ConfigDesktopSourceProc(hwnd, WM_COMMAND, MAKEWPARAM(IDC_COLOR, CCN_CHANGED), (LPARAM)GetDlgItem(hwnd, IDC_COLOR));
}
break;
case WM_LBUTTONUP:
if(bSelectingColor)
{
colorData.Clear();
ReleaseCapture();
bMouseDown = false;
bSelectingColor = false;
ConfigDesktopSourceInfo *configData = (ConfigDesktopSourceInfo*)GetWindowLongPtr(hwnd, DWLP_USER);
ImageSource *source = API->GetSceneImageSource(configData->lpName);
if(source)
source->SetInt(TEXT("useColorKey"), true);
}
break;
case WM_CAPTURECHANGED:
if(bSelectingColor)
{
if(colorData.bValid)
{
CCSetColor(GetDlgItem(hwnd, IDC_COLOR), colorData.GetColor());
ConfigDesktopSourceProc(hwnd, WM_COMMAND, MAKEWPARAM(IDC_COLOR, CCN_CHANGED), (LPARAM)GetDlgItem(hwnd, IDC_COLOR));
colorData.Clear();
}
ReleaseCapture();
bMouseDown = false;
bSelectingColor = false;
ConfigDesktopSourceInfo *configData = (ConfigDesktopSourceInfo*)GetWindowLongPtr(hwnd, DWLP_USER);
ImageSource *source = API->GetSceneImageSource(configData->lpName);
if(source)
source->SetInt(TEXT("useColorKey"), true);
}
break;
case WM_COMMAND: case WM_COMMAND:
switch(LOWORD(wParam)) switch(LOWORD(wParam))
{ {
@ -988,6 +1254,90 @@ INT_PTR CALLBACK ConfigDesktopSourceProc(HWND hwnd, UINT message, WPARAM wParam,
break; break;
} }
case IDC_USECOLORKEY:
{
HWND hwndUseColorKey = (HWND)lParam;
BOOL bUseColorKey = SendMessage(hwndUseColorKey, BM_GETCHECK, 0, 0) == BST_CHECKED;
ConfigDesktopSourceInfo *configData = (ConfigDesktopSourceInfo*)GetWindowLongPtr(hwnd, DWLP_USER);
ImageSource *source = API->GetSceneImageSource(configData->lpName);
if(source)
source->SetInt(TEXT("useColorKey"), bUseColorKey);
EnableWindow(GetDlgItem(hwnd, IDC_COLOR), bUseColorKey);
EnableWindow(GetDlgItem(hwnd, IDC_SELECT), bUseColorKey);
EnableWindow(GetDlgItem(hwnd, IDC_BASETHRESHOLD_EDIT), bUseColorKey);
EnableWindow(GetDlgItem(hwnd, IDC_BASETHRESHOLD), bUseColorKey);
EnableWindow(GetDlgItem(hwnd, IDC_BLEND_EDIT), bUseColorKey);
EnableWindow(GetDlgItem(hwnd, IDC_BLEND), bUseColorKey);
break;
}
case IDC_COLOR:
{
ConfigDesktopSourceInfo *configData = (ConfigDesktopSourceInfo*)GetWindowLongPtr(hwnd, DWLP_USER);
ImageSource *source = API->GetSceneImageSource(configData->lpName);
if(source)
{
DWORD color = CCGetColor((HWND)lParam);
source->SetInt(TEXT("keyColor"), color);
}
break;
}
case IDC_SELECT:
{
if(!bSelectingColor)
{
if(colorData.Init())
{
bMouseDown = false;
bSelectingColor = true;
SetCapture(hwnd);
HCURSOR hCursor = (HCURSOR)LoadImage(hinstMain, MAKEINTRESOURCE(IDC_COLORPICKER), IMAGE_CURSOR, 32, 32, 0);
SetCursor(hCursor);
ConfigDesktopSourceInfo *configData = (ConfigDesktopSourceInfo*)GetWindowLongPtr(hwnd, DWLP_USER);
ImageSource *source = API->GetSceneImageSource(configData->lpName);
if(source)
source->SetInt(TEXT("useColorKey"), false);
}
else
colorData.Clear();
}
break;
}
case IDC_BASETHRESHOLD_EDIT:
case IDC_BLEND_EDIT:
if(HIWORD(wParam) == EN_CHANGE)
{
ConfigDesktopSourceInfo *configData = (ConfigDesktopSourceInfo*)GetWindowLongPtr(hwnd, DWLP_USER);
if(configData)
{
ImageSource *source = API->GetSceneImageSource(configData->lpName);
if(source)
{
HWND hwndVal = NULL;
switch(LOWORD(wParam))
{
case IDC_BASETHRESHOLD_EDIT: hwndVal = GetDlgItem(hwnd, IDC_BASETHRESHOLD); break;
case IDC_BLEND_EDIT: hwndVal = GetDlgItem(hwnd, IDC_BLEND); break;
}
int val = (int)SendMessage(hwndVal, UDM_GETPOS32, 0, 0);
switch(LOWORD(wParam))
{
case IDC_BASETHRESHOLD_EDIT: source->SetInt(TEXT("keySimilarity"), val); break;
case IDC_BLEND_EDIT: source->SetInt(TEXT("keyBlend"), val); break;
}
}
}
}
break;
case IDOK: case IDOK:
{ {
UINT captureType = 0; UINT captureType = 0;
@ -1046,9 +1396,35 @@ INT_PTR CALLBACK ConfigDesktopSourceProc(HWND hwnd, UINT message, WPARAM wParam,
data->SetInt(TEXT("captureY"), posY); data->SetInt(TEXT("captureY"), posY);
data->SetInt(TEXT("captureCX"), sizeX); data->SetInt(TEXT("captureCX"), sizeX);
data->SetInt(TEXT("captureCY"), sizeY); data->SetInt(TEXT("captureCY"), sizeY);
//---------------------------------
BOOL bUseColorKey = SendMessage(GetDlgItem(hwnd, IDC_USECOLORKEY), BM_GETCHECK, 0, 0) == BST_CHECKED;
DWORD keyColor = CCGetColor(GetDlgItem(hwnd, IDC_COLOR));
UINT keySimilarity = (UINT)SendMessage(GetDlgItem(hwnd, IDC_BASETHRESHOLD), UDM_GETPOS32, 0, 0);
UINT keyBlend = (UINT)SendMessage(GetDlgItem(hwnd, IDC_BLEND), UDM_GETPOS32, 0, 0);
data->SetInt(TEXT("useColorKey"), bUseColorKey);
data->SetInt(TEXT("keyColor"), keyColor);
data->SetInt(TEXT("keySimilarity"), keySimilarity);
data->SetInt(TEXT("keyBlend"), keyBlend);
} }
case IDCANCEL: case IDCANCEL:
if(LOWORD(wParam) == IDCANCEL)
{
ConfigDesktopSourceInfo *info = (ConfigDesktopSourceInfo*)GetWindowLongPtr(hwnd, DWLP_USER);
ImageSource *source = API->GetSceneImageSource(info->lpName);
if(source)
{
XElement *data = info->data;
source->SetInt(TEXT("useColorKey"), data->GetInt(TEXT("useColorKey"), 0));
source->SetInt(TEXT("keyColor"), data->GetInt(TEXT("keyColor"), 0xFFFFFFFF));
source->SetInt(TEXT("keySimilarity"), data->GetInt(TEXT("keySimilarity"), 10));
source->SetInt(TEXT("keyBlend"), data->GetInt(TEXT("keyBlend"), 0));
}
}
EndDialog(hwnd, LOWORD(wParam)); EndDialog(hwnd, LOWORD(wParam));
break; break;
} }
@ -1087,6 +1463,7 @@ bool STDCALL ConfigureDesktopSource(XElement *element, bool bInitialize)
ConfigDesktopSourceInfo info; ConfigDesktopSourceInfo info;
info.data = data; info.data = data;
info.lpName = element->GetName();
if(DialogBoxParam(hinstMain, MAKEINTRESOURCE(IDD_CONFIGUREDESKTOPSOURCE), hwndMain, ConfigDesktopSourceProc, (LPARAM)&info) == IDOK) if(DialogBoxParam(hinstMain, MAKEINTRESOURCE(IDD_CONFIGUREDESKTOPSOURCE), hwndMain, ConfigDesktopSourceProc, (LPARAM)&info) == IDOK)
{ {

View File

@ -113,7 +113,10 @@ bool STDCALL OBS::ConfigGlobalSource(XElement *element, bool bCreating)
{ {
GlobalSourceInfo &info = App->globalSources[i]; GlobalSourceInfo &info = App->globalSources[i];
if(info.strName.CompareI(lpGlobalSourceName) && info.source) if(info.strName.CompareI(lpGlobalSourceName) && info.source)
{
info.source->UpdateSettings(); info.source->UpdateSettings();
break;
}
} }
} }
} }

View File

@ -61,8 +61,8 @@ extern ConfigFile *AppConfig;
extern OBS *App; extern OBS *App;
extern TCHAR lpAppDataPath[MAX_PATH]; extern TCHAR lpAppDataPath[MAX_PATH];
#define OBS_VERSION 0x000430 #define OBS_VERSION 0x000432
#define OBS_VERSION_STRING_ANSI "Open Broadcaster Software v0.43a" #define OBS_VERSION_STRING_ANSI "Open Broadcaster Software v0.432a"
#define OBS_VERSION_STRING TEXT(OBS_VERSION_STRING_ANSI) #define OBS_VERSION_STRING TEXT(OBS_VERSION_STRING_ANSI)
#define OBS_WINDOW_CLASS TEXT("OBSWindowClass") #define OBS_WINDOW_CLASS TEXT("OBSWindowClass")

View File

@ -2034,13 +2034,13 @@ void OBS::MainCaptureLoop()
Ortho(0.0f, renderFrameSize.x, renderFrameSize.y, 0.0f, -100.0f, 100.0f); Ortho(0.0f, renderFrameSize.x, renderFrameSize.y, 0.0f, -100.0f, 100.0f);
LoadVertexShader(solidVertexShader);
LoadPixelShader(solidPixelShader);
solidPixelShader->SetColor(solidPixelShader->GetParameter(0), 0xFFFF0000);
//draw selections if in edit mode //draw selections if in edit mode
if(bEditMode && !bSizeChanging) if(bEditMode && !bSizeChanging)
{ {
LoadVertexShader(solidVertexShader);
LoadPixelShader(solidPixelShader);
solidPixelShader->SetColor(solidPixelShader->GetParameter(0), 0xFFFF0000);
Ortho(0.0f, baseSize.x, baseSize.y, 0.0f, -100.0f, 100.0f); Ortho(0.0f, baseSize.x, baseSize.y, 0.0f, -100.0f, 100.0f);
if(scene) if(scene)
@ -2726,23 +2726,41 @@ void OBSAPIInterface::HandleHotkeys()
DWORD hotkeyModifiers = HIBYTE(info.hotkey); DWORD hotkeyModifiers = HIBYTE(info.hotkey);
bool bModifiersMatch = (hotkeyModifiers == modifiers); bool bModifiersMatch = (hotkeyModifiers == modifiers);
if(bModifiersMatch)
{
short keyState = GetAsyncKeyState(hotkeyVK);
bool bDown = (keyState & 0x8000) != 0;
bool bWasPressed = (keyState & 0x1) != 0;
if(bDown || bWasPressed) if(hotkeyModifiers && !hotkeyVK) //modifier-only hotkey
{
if((hotkeyModifiers & modifiers) == hotkeyModifiers)
{ {
if(!info.bHotkeyDown && info.bModifiersDown) //only triggers the hotkey if the actual main key was pressed second if(!info.bHotkeyDown)
{ {
PostMessage(hwndMain, OBS_CALLHOTKEY, TRUE, info.hotkeyID); PostMessage(hwndMain, OBS_CALLHOTKEY, TRUE, info.hotkeyID);
info.bDownSent = true; info.bDownSent = true;
info.bHotkeyDown = true;
} }
info.bHotkeyDown = true; continue;
if(bDown) }
continue; }
else
{
if(bModifiersMatch)
{
short keyState = GetAsyncKeyState(hotkeyVK);
bool bDown = (keyState & 0x8000) != 0;
bool bWasPressed = (keyState & 0x1) != 0;
if(bDown || bWasPressed)
{
if(!info.bHotkeyDown && info.bModifiersDown) //only triggers the hotkey if the actual main key was pressed second
{
PostMessage(hwndMain, OBS_CALLHOTKEY, TRUE, info.hotkeyID);
info.bDownSent = true;
}
info.bHotkeyDown = true;
if(bDown)
continue;
}
} }
} }

View File

@ -325,6 +325,7 @@ class OBS
friend class D3D10System; friend class D3D10System;
friend class OBSAPIInterface; friend class OBSAPIInterface;
friend class GlobalSource; friend class GlobalSource;
friend class TextOutputSource;
//--------------------------------------------------- //---------------------------------------------------
// graphics stuff // graphics stuff

View File

@ -65,6 +65,8 @@ class TextOutputSource : public ImageSource
void UpdateTexture() void UpdateTexture()
{ {
Gdiplus::Status stat;
if(bMonitoringFileChanges) if(bMonitoringFileChanges)
{ {
CancelIoEx(hDirectory, &directoryChange); CancelIoEx(hDirectory, &directoryChange);
@ -138,7 +140,7 @@ class TextOutputSource : public ImageSource
return; return;
SIZE textSize; SIZE textSize;
if(bUseExtents) if(bUseExtents && bWrap)
{ {
textSize.cx = extentWidth; textSize.cx = extentWidth;
textSize.cy = extentHeight; textSize.cy = extentHeight;
@ -155,13 +157,16 @@ class TextOutputSource : public ImageSource
format.SetFormatFlags(Gdiplus::StringFormatFlagsDirectionVertical|Gdiplus::StringFormatFlagsDirectionRightToLeft); format.SetFormatFlags(Gdiplus::StringFormatFlagsDirectionVertical|Gdiplus::StringFormatFlagsDirectionRightToLeft);
Gdiplus::RectF rcf; Gdiplus::RectF rcf;
graphics.MeasureString(strCurrentText, -1, &font, Gdiplus::PointF(0.0f, 0.0f), &format, &rcf); stat = graphics.MeasureString(strCurrentText, -1, &font, Gdiplus::PointF(0.0f, 0.0f), &format, &rcf);
if(stat != Gdiplus::Ok)
AppWarning(TEXT("graphics.MeasureString failed: %u"), (int)stat);
textSize.cx = long(rcf.Width+EPSILON); textSize.cx = long(rcf.Width+EPSILON);
textSize.cy = long(rcf.Height+EPSILON); textSize.cy = long(rcf.Height+EPSILON);
if(!textSize.cx || !textSize.cy) if(!textSize.cx || !textSize.cy)
{ {
AppWarning(TEXT("TextSource::UpdateTexture: bad texture sizes apparently, very strange"));
DeleteObject(hFont); DeleteObject(hFont);
return; return;
} }
@ -174,8 +179,8 @@ class TextOutputSource : public ImageSource
textSize.cx &= 0xFFFFFFFE; textSize.cx &= 0xFFFFFFFE;
textSize.cy &= 0xFFFFFFFE; textSize.cy &= 0xFFFFFFFE;
ClampInt(textSize.cx, 32, 2048); ClampInt(textSize.cx, 32, 4096);
ClampInt(textSize.cy, 32, 2048); ClampInt(textSize.cy, 32, 4096);
if(textureSize.cx != textSize.cx || textureSize.cy != textSize.cy) if(textureSize.cx != textSize.cx || textureSize.cy != textSize.cy)
{ {
@ -191,6 +196,7 @@ class TextOutputSource : public ImageSource
if(!texture) if(!texture)
{ {
AppWarning(TEXT("TextSource::UpdateTexture: could not create texture"));
DeleteObject(hFont); DeleteObject(hFont);
return; return;
} }
@ -198,15 +204,36 @@ class TextOutputSource : public ImageSource
HDC hDC; HDC hDC;
if(texture->GetDC(hDC)) if(texture->GetDC(hDC))
{ {
HDC hTempDC = CreateCompatibleDC(NULL);
BITMAPINFO bi;
zero(&bi, sizeof(bi));
void* lpBits;
BITMAPINFOHEADER &bih = bi.bmiHeader;
bih.biSize = sizeof(bih);
bih.biBitCount = 32;
bih.biWidth = textureSize.cx;
bih.biHeight = textureSize.cy;
bih.biPlanes = 1;
HBITMAP hBitmap = CreateDIBSection(hTempDC, &bi, DIB_RGB_COLORS, &lpBits, NULL, 0);
{ {
Gdiplus::Graphics graphics(hDC); Gdiplus::Bitmap bmp(textureSize.cx, textureSize.cy, 4*textureSize.cx, PixelFormat32bppARGB, (BYTE*)lpBits);
Gdiplus::Graphics graphics(&bmp);
Gdiplus::SolidBrush *brush = new Gdiplus::SolidBrush(Gdiplus::Color(0xFF000000|color)); Gdiplus::SolidBrush *brush = new Gdiplus::SolidBrush(Gdiplus::Color(0xFF000000|color));
Gdiplus::Font font(hDC, hFont); Gdiplus::Font font(hTempDC, hFont);
graphics.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAliasGridFit); graphics.FillRectangle(brush, 0, 0, 50, 50);
graphics.Clear(Gdiplus::Color(0));
if(bUseExtents) stat = graphics.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias);
if(stat != Gdiplus::Ok) AppWarning(TEXT("graphics.SetTextRenderingHint failed: %u"), (int)stat);
stat = graphics.Clear(Gdiplus::Color(0));
if(stat != Gdiplus::Ok) AppWarning(TEXT("graphics.Clear failed: %u"), (int)stat);
if(bUseExtents && bWrap)
{ {
Gdiplus::StringFormat format; Gdiplus::StringFormat format;
Gdiplus::PointF pos(0.0f, 0.0f); Gdiplus::PointF pos(0.0f, 0.0f);
@ -238,13 +265,13 @@ class TextOutputSource : public ImageSource
if(bVertical) if(bVertical)
format.SetFormatFlags(Gdiplus::StringFormatFlagsDirectionVertical|Gdiplus::StringFormatFlagsDirectionRightToLeft); format.SetFormatFlags(Gdiplus::StringFormatFlagsDirectionVertical|Gdiplus::StringFormatFlagsDirectionRightToLeft);
if(bWrap) /*if(bWrap)
{ {*/
Gdiplus::RectF rcf(0.0f, 0.0f, float(textSize.cx), float(textSize.cy)); Gdiplus::RectF rcf(0.0f, 0.0f, float(textSize.cx), float(textSize.cy));
graphics.DrawString(strCurrentText, -1, &font, rcf, &format, brush); graphics.DrawString(strCurrentText, -1, &font, rcf, &format, brush);
} /*}
else else
graphics.DrawString(strCurrentText, -1, &font, pos, &format, brush); graphics.DrawString(strCurrentText, -1, &font, pos, &format, brush);*/
} }
else else
{ {
@ -253,12 +280,20 @@ class TextOutputSource : public ImageSource
if(bVertical) if(bVertical)
format.SetFormatFlags(Gdiplus::StringFormatFlagsDirectionVertical|Gdiplus::StringFormatFlagsDirectionRightToLeft); format.SetFormatFlags(Gdiplus::StringFormatFlagsDirectionVertical|Gdiplus::StringFormatFlagsDirectionRightToLeft);
graphics.DrawString(strCurrentText, -1, &font, Gdiplus::PointF(bVertical ? float(textSize.cx) : 0.0f, 0.0f), &format, brush); stat = graphics.DrawString(strCurrentText, -1, &font, Gdiplus::PointF(bVertical ? float(textSize.cx) : 0.0f, -4.0f), &format, brush);
if(stat != Gdiplus::Ok) AppWarning(TEXT("Hmm, DrawString failed: %u"), (int)stat);
} }
delete brush; delete brush;
} }
HBITMAP hbmpOld = (HBITMAP)SelectObject(hTempDC, hBitmap);
BitBlt(hDC, 0, 0, textureSize.cx, textureSize.cy, hTempDC, 0, 0, SRCCOPY);
SelectObject(hTempDC, hbmpOld);
DeleteDC(hTempDC);
DeleteObject(hBitmap);
texture->ReleaseDC(); texture->ReleaseDC();
} }
@ -351,15 +386,49 @@ public:
while(scrollValue < -1.0f) while(scrollValue < -1.0f)
scrollValue += 1.0f; scrollValue += 1.0f;
} }
if(showExtentTime > 0.0f)
showExtentTime -= fSeconds;
} }
void Render(const Vect2 &pos, const Vect2 &size) void Render(const Vect2 &pos, const Vect2 &size)
{ {
if(texture) if(texture)
{ {
//EnableBlending(FALSE);
Vect2 sizeMultiplier = size/baseSize; Vect2 sizeMultiplier = size/baseSize;
Vect2 newSize = Vect2(float(textureSize.cx), float(textureSize.cy))*sizeMultiplier; Vect2 newSize = Vect2(float(textureSize.cx), float(textureSize.cy))*sizeMultiplier;
if(bUseExtents)
{
Vect2 extentVal = Vect2(float(extentWidth), float(extentHeight))*sizeMultiplier;
if(showExtentTime > 0.0f)
{
Shader *pShader = GS->GetCurrentPixelShader();
Shader *vShader = GS->GetCurrentVertexShader();
Color4 rectangleColor = Color4(0.0f, 1.0f, 0.0f, 1.0f);
if(showExtentTime < 1.0f)
rectangleColor.w = showExtentTime;
App->solidPixelShader->SetColor(App->solidPixelShader->GetParameter(0), rectangleColor);
LoadVertexShader(App->solidVertexShader);
LoadPixelShader(App->solidPixelShader);
DrawBox(pos, extentVal);
LoadVertexShader(vShader);
LoadPixelShader(pShader);
}
if(!bWrap)
{
XRect rect = {int(pos.x), int(pos.y), int(extentVal.x), int(extentVal.y)};
SetScissorRect(&rect);
}
}
DWORD alpha = DWORD(double(opacity)*2.55); DWORD alpha = DWORD(double(opacity)*2.55);
DWORD outputColor = (alpha << 24) | 0xFFFFFF; DWORD outputColor = (alpha << 24) | 0xFFFFFF;
@ -384,10 +453,14 @@ public:
} }
LoadSamplerState(ss); LoadSamplerState(ss);
DrawSpriteEx(texture, outputColor, pos.x, pos.y, pos.x+newSize.x, pos.y+newSize.y, ul.x, ul.y, lr.x, lr.y); DrawSpriteEx(texture, outputColor, pos.x, pos.y+newSize.y, pos.x+newSize.x, pos.y, ul.x, ul.y, lr.x, lr.y);
} }
else else
DrawSprite(texture, outputColor, pos.x, pos.y, pos.x+newSize.x, pos.y+newSize.y); DrawSprite(texture, outputColor, pos.x, pos.y+newSize.y, pos.x+newSize.x, pos.y);
if(bUseExtents && !bWrap)
SetScissorRect(NULL);
//EnableBlending(TRUE);
} }
} }
@ -461,9 +534,15 @@ public:
else if(scmpi(lpName, TEXT("useTextExtents")) == 0) else if(scmpi(lpName, TEXT("useTextExtents")) == 0)
bUseExtents = iValue != 0; bUseExtents = iValue != 0;
else if(scmpi(lpName, TEXT("extentWidth")) == 0) else if(scmpi(lpName, TEXT("extentWidth")) == 0)
{
showExtentTime = 2.0f;
extentWidth = iValue; extentWidth = iValue;
}
else if(scmpi(lpName, TEXT("extentHeight")) == 0) else if(scmpi(lpName, TEXT("extentHeight")) == 0)
{
showExtentTime = 2.0f;
extentHeight = iValue; extentHeight = iValue;
}
else if(scmpi(lpName, TEXT("align")) == 0) else if(scmpi(lpName, TEXT("align")) == 0)
align = iValue; align = iValue;
else if(scmpi(lpName, TEXT("mode")) == 0) else if(scmpi(lpName, TEXT("mode")) == 0)
@ -471,6 +550,8 @@ public:
bUpdateTexture = true; bUpdateTexture = true;
} }
inline void ResetExtentRect() {showExtentTime = 0.0f;}
}; };
struct ConfigTextSourceInfo struct ConfigTextSourceInfo
@ -544,6 +625,8 @@ CTSTR GetFontFace(ConfigTextSourceInfo *configInfo, HWND hwndFontList)
INT_PTR CALLBACK ConfigureTextProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) INT_PTR CALLBACK ConfigureTextProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{ {
static bool bInitializedDialog = false;
switch(message) switch(message)
{ {
case WM_INITDIALOG: case WM_INITDIALOG:
@ -631,13 +714,20 @@ INT_PTR CALLBACK ConfigureTextProc(HWND hwnd, UINT message, WPARAM wParam, LPARA
EnableWindow(GetDlgItem(hwnd, IDC_FILE), bUseFile); EnableWindow(GetDlgItem(hwnd, IDC_FILE), bUseFile);
EnableWindow(GetDlgItem(hwnd, IDC_BROWSE), bUseFile); EnableWindow(GetDlgItem(hwnd, IDC_BROWSE), bUseFile);
bInitializedDialog = true;
return TRUE; return TRUE;
} }
case WM_DESTROY:
bInitializedDialog = false;
break;
case WM_COMMAND: case WM_COMMAND:
switch(LOWORD(wParam)) switch(LOWORD(wParam))
{ {
case IDC_FONT: case IDC_FONT:
if(bInitializedDialog)
{ {
if(HIWORD(wParam) == CBN_SELCHANGE || HIWORD(wParam) == CBN_EDITCHANGE) if(HIWORD(wParam) == CBN_SELCHANGE || HIWORD(wParam) == CBN_EDITCHANGE)
{ {
@ -662,6 +752,7 @@ INT_PTR CALLBACK ConfigureTextProc(HWND hwnd, UINT message, WPARAM wParam, LPARA
break; break;
case IDC_COLOR: case IDC_COLOR:
if(bInitializedDialog)
{ {
DWORD color = CCGetColor((HWND)lParam); DWORD color = CCGetColor((HWND)lParam);
@ -678,7 +769,7 @@ INT_PTR CALLBACK ConfigureTextProc(HWND hwnd, UINT message, WPARAM wParam, LPARA
case IDC_EXTENTHEIGHT_EDIT: case IDC_EXTENTHEIGHT_EDIT:
case IDC_TEXTOPACITY_EDIT: case IDC_TEXTOPACITY_EDIT:
case IDC_SCROLLSPEED_EDIT: case IDC_SCROLLSPEED_EDIT:
if(HIWORD(wParam) == EN_CHANGE) if(HIWORD(wParam) == EN_CHANGE && bInitializedDialog)
{ {
int val = (int)SendMessage(GetWindow((HWND)lParam, GW_HWNDNEXT), UDM_GETPOS32, 0, 0); int val = (int)SendMessage(GetWindow((HWND)lParam, GW_HWNDNEXT), UDM_GETPOS32, 0, 0);
@ -706,7 +797,7 @@ INT_PTR CALLBACK ConfigureTextProc(HWND hwnd, UINT message, WPARAM wParam, LPARA
case IDC_VERTICALSCRIPT: case IDC_VERTICALSCRIPT:
case IDC_WRAP: case IDC_WRAP:
case IDC_USETEXTEXTENTS: case IDC_USETEXTEXTENTS:
if(HIWORD(wParam) == BN_CLICKED) if(HIWORD(wParam) == BN_CLICKED && bInitializedDialog)
{ {
BOOL bChecked = SendMessage((HWND)lParam, BM_GETCHECK, 0, 0) == BST_CHECKED; BOOL bChecked = SendMessage((HWND)lParam, BM_GETCHECK, 0, 0) == BST_CHECKED;
@ -739,7 +830,7 @@ INT_PTR CALLBACK ConfigureTextProc(HWND hwnd, UINT message, WPARAM wParam, LPARA
break; break;
case IDC_ALIGN: case IDC_ALIGN:
if(HIWORD(wParam) == CBN_SELCHANGE) if(HIWORD(wParam) == CBN_SELCHANGE && bInitializedDialog)
{ {
int align = (int)SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0); int align = (int)SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0);
if(align == CB_ERR) if(align == CB_ERR)
@ -755,7 +846,7 @@ INT_PTR CALLBACK ConfigureTextProc(HWND hwnd, UINT message, WPARAM wParam, LPARA
case IDC_FILE: case IDC_FILE:
case IDC_TEXT: case IDC_TEXT:
if(HIWORD(wParam) == EN_CHANGE) if(HIWORD(wParam) == EN_CHANGE && bInitializedDialog)
{ {
String strText = GetEditText((HWND)lParam); String strText = GetEditText((HWND)lParam);
@ -774,7 +865,7 @@ INT_PTR CALLBACK ConfigureTextProc(HWND hwnd, UINT message, WPARAM wParam, LPARA
break; break;
case IDC_USEFILE: case IDC_USEFILE:
if(HIWORD(wParam) == BN_CLICKED) if(HIWORD(wParam) == BN_CLICKED && bInitializedDialog)
{ {
EnableWindow(GetDlgItem(hwnd, IDC_TEXT), FALSE); EnableWindow(GetDlgItem(hwnd, IDC_TEXT), FALSE);
EnableWindow(GetDlgItem(hwnd, IDC_FILE), TRUE); EnableWindow(GetDlgItem(hwnd, IDC_FILE), TRUE);
@ -788,7 +879,7 @@ INT_PTR CALLBACK ConfigureTextProc(HWND hwnd, UINT message, WPARAM wParam, LPARA
break; break;
case IDC_USETEXT: case IDC_USETEXT:
if(HIWORD(wParam) == BN_CLICKED) if(HIWORD(wParam) == BN_CLICKED && bInitializedDialog)
{ {
EnableWindow(GetDlgItem(hwnd, IDC_TEXT), TRUE); EnableWindow(GetDlgItem(hwnd, IDC_TEXT), TRUE);
EnableWindow(GetDlgItem(hwnd, IDC_FILE), FALSE); EnableWindow(GetDlgItem(hwnd, IDC_FILE), FALSE);

BIN
cursor1.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

View File

@ -44,11 +44,17 @@
#define IDC_SERVICE 1014 #define IDC_SERVICE 1014
#define IDC_DOWNSCALE 1014 #define IDC_DOWNSCALE 1014
#define IDC_MAXBITRATE 1015 #define IDC_MAXBITRATE 1015
#define IDC_COLORPICKER 1015
#define IDC_BUFFERSIZE 1016 #define IDC_BUFFERSIZE 1016
#define IDC_AUDIOCODEC 1017 #define IDC_AUDIOCODEC 1017
#define IDC_USECOLORKEY 1017
#define IDC_AUDIOFORMAT 1018 #define IDC_AUDIOFORMAT 1018
#define IDC_AUDIOBITRATE 1019 #define IDC_AUDIOBITRATE 1019
#define IDC_MONITOR 1019 #define IDC_MONITOR 1019
#define IDC_BASETHRESHOLD_EDIT 1020
#define IDC_BASETHRESHOLD 1021
#define IDC_BLEND_EDIT 1022
#define IDC_BLEND 1023
#define IDC_LANGUAGE 1028 #define IDC_LANGUAGE 1028
#define IDC_INFO 1029 #define IDC_INFO 1029
#define IDC_FPS 1030 #define IDC_FPS 1030
@ -174,6 +180,7 @@
#define IDC_VERTICALSCRIPT 1122 #define IDC_VERTICALSCRIPT 1122
#define IDC_UNDERLINE 1123 #define IDC_UNDERLINE 1123
#define IDC_ALIGN 1124 #define IDC_ALIGN 1124
#define IDC_SELECT 1125
#define IDC_BOLD 1126 #define IDC_BOLD 1126
#define IDC_ITALIC 1127 #define IDC_ITALIC 1127
#define IDA_SOURCE_MOVEUP 40018 #define IDA_SOURCE_MOVEUP 40018
@ -206,7 +213,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS #ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 140 #define _APS_NEXT_RESOURCE_VALUE 140
#define _APS_NEXT_COMMAND_VALUE 40044 #define _APS_NEXT_COMMAND_VALUE 40044
#define _APS_NEXT_CONTROL_VALUE 1125 #define _APS_NEXT_CONTROL_VALUE 1126
#define _APS_NEXT_SYMED_VALUE 101 #define _APS_NEXT_SYMED_VALUE 101
#endif #endif
#endif #endif

View File

@ -178,7 +178,7 @@ Sources.GameCaptureSource.PluginDescription "Captures frames directly from games
Sources.GameCaptureSource.PluginName "Game Capture Plugin" Sources.GameCaptureSource.PluginName "Game Capture Plugin"
Sources.GameCaptureSource.StretchToScreen "Strech image to screen" Sources.GameCaptureSource.StretchToScreen "Strech image to screen"
Sources.SoftwareCaptureSource.Blend "Blend:" Sources.SoftwareCaptureSource.Blend "Blend (1-100):"
Sources.SoftwareCaptureSource.ColorKey "Color Key" Sources.SoftwareCaptureSource.ColorKey "Color Key"
Sources.SoftwareCaptureSource.EntireWindow "Entire Window" Sources.SoftwareCaptureSource.EntireWindow "Entire Window"
Sources.SoftwareCaptureSource.InnerWindow "Inner Window" Sources.SoftwareCaptureSource.InnerWindow "Inner Window"
@ -193,7 +193,7 @@ Sources.SoftwareCaptureSource.RegionWindowText "Press Enter, Esc, or click
Sources.SoftwareCaptureSource.Select "Select" Sources.SoftwareCaptureSource.Select "Select"
Sources.SoftwareCaptureSource.SelectRegion "Select Region" Sources.SoftwareCaptureSource.SelectRegion "Select Region"
Sources.SoftwareCaptureSource.SelectRegionTooltip "When selecting a region, move by clicking and dragging, or resize the rectangle by clicking the edges." Sources.SoftwareCaptureSource.SelectRegionTooltip "When selecting a region, move by clicking and dragging, or resize the rectangle by clicking the edges."
Sources.SoftwareCaptureSource.Similarity "Similarity:" Sources.SoftwareCaptureSource.Similarity "Similarity (1-100):"
Sources.SoftwareCaptureSource.Size "Size:" Sources.SoftwareCaptureSource.Size "Size:"
Sources.SoftwareCaptureSource.SpillReduction "Spill Reduction:" Sources.SoftwareCaptureSource.SpillReduction "Spill Reduction:"
Sources.SoftwareCaptureSource.UseColorKey "Use Color Key:" Sources.SoftwareCaptureSource.UseColorKey "Use Color Key:"

View File

@ -0,0 +1,48 @@
/********************************************************************************
Copyright (C) 2012 Hugh Bailey <obs.jim@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
********************************************************************************/
uniform Texture2D diffuseTexture;
uniform float4 outputColor;
uniform float4 colorKey;
uniform float similarity;
uniform float blend;
SamplerState textureSampler
{
AddressU = Clamp;
AddressV = Clamp;
Filter = Linear;
};
struct VertData
{
float4 pos : SV_Position;
float2 texCoord : TexCoord0;
};
float4 main(VertData input) : SV_Target
{
float4 rgbx = diffuseTexture.Sample(textureSampler, input.texCoord);
rgbx = saturate(rgbx);
float colorDiff = length(rgbx.rgb - colorKey.rgb);
rgbx.a = saturate(max(colorDiff-similarity, 0.0)/blend);
return rgbx * outputColor;
}