Skip to content

Commit

Permalink
Use a separate texture when scene transitioning.
Browse files Browse the repository at this point in the history
Get rid of 1+ DrawSprite call(s) during scene transition.
  • Loading branch information
hwdro committed Oct 3, 2014
1 parent 0ef092a commit 872ed6f
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 25 deletions.
1 change: 1 addition & 0 deletions OBS.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@
</ItemGroup>
<ItemGroup>
<None Include="cursor1.cur" />
<None Include="rundir\shaders\SceneTransition.pShader" />
<None Include="ui\mic2-muted.ico" />
<None Include="ui\mic2.ico" />
<None Include="ui\speaker-muted.ico" />
Expand Down
3 changes: 3 additions & 0 deletions OBS.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,9 @@
<None Include="ui\test2\recording.ico">
<Filter>Resources</Filter>
</None>
<None Include="rundir\shaders\SceneTransition.pShader">
<Filter>Shaders</Filter>
</None>
</ItemGroup>
<ItemGroup>
<Filter Include="Headers">
Expand Down
4 changes: 3 additions & 1 deletion Source/OBS.h
Original file line number Diff line number Diff line change
Expand Up @@ -628,11 +628,13 @@ class OBS
Texture *mainRenderTextures[NUM_RENDER_BUFFERS];
Texture *yuvRenderTextures[NUM_RENDER_BUFFERS];

Texture *lastRenderTexture;
Texture *transitionTexture;

bool bTransitioning;
float transitionAlpha;

Shader *mainVertexShader, *mainPixelShader, *yuvScalePixelShader;
Shader *mainVertexShader, *mainPixelShader, *yuvScalePixelShader, *transitionPixelShader;
Shader *solidVertexShader, *solidPixelShader;

//---------------------------------------------------
Expand Down
12 changes: 12 additions & 0 deletions Source/OBSCapture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -571,12 +571,17 @@ void OBS::Start(bool recordingOnly, bool replayBufferOnly)
solidVertexShader = CreateVertexShaderFromFile(TEXT("shaders/DrawSolid.vShader"));
solidPixelShader = CreatePixelShaderFromFile(TEXT("shaders/DrawSolid.pShader"));

transitionPixelShader = CreatePixelShaderFromFile(TEXT("shaders/SceneTransition.pShader"));

if(!mainVertexShader || !mainPixelShader)
CrashError(TEXT("Unable to load DrawTexture shaders"));

if(!solidVertexShader || !solidPixelShader)
CrashError(TEXT("Unable to load DrawSolid shaders"));

if (!transitionPixelShader)
CrashError(TEXT("Unable to load SceneTransition shader"));

//------------------------------------------------------------------

CTSTR lpShader;
Expand Down Expand Up @@ -608,6 +613,8 @@ void OBS::Start(bool recordingOnly, bool replayBufferOnly)
yuvRenderTextures[i] = CreateRenderTarget(outputCX, outputCY, GS_BGRA, FALSE);
}

transitionTexture = CreateRenderTarget(baseCX, baseCY, GS_BGRA, FALSE);

//-------------------------------------------------------------

D3D10_TEXTURE2D_DESC td;
Expand Down Expand Up @@ -1092,18 +1099,23 @@ void OBS::Stop(bool overrideKeepRecording, bool stopReplayBuffer)
delete transitionTexture;
transitionTexture = NULL;

delete lastRenderTexture;
lastRenderTexture = NULL;

//-------------------------------------------------------------

delete mainVertexShader;
delete mainPixelShader;
delete yuvScalePixelShader;
delete transitionPixelShader;

delete solidVertexShader;
delete solidPixelShader;

mainVertexShader = NULL;
mainPixelShader = NULL;
yuvScalePixelShader = NULL;
transitionPixelShader = NULL;

solidVertexShader = NULL;
solidPixelShader = NULL;
Expand Down
56 changes: 32 additions & 24 deletions Source/OBSVideoCapture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -525,17 +525,13 @@ void OBS::DrawPreview(const Vect2 &renderFrameSize, const Vect2 &renderFrameOffs
ClearColorBuffer(GetSysColor(COLOR_BTNFACE));

if(bTransitioning)
{
BlendFunction(GS_BLEND_ONE, GS_BLEND_ZERO);
DrawSprite(transitionTexture, 0xFFFFFFFF,
renderFrameOffset.x, renderFrameOffset.y,
renderFrameOffset.x + renderFrameSize.x, renderFrameOffset.y + renderFrameSize.y);
BlendFunction(GS_BLEND_FACTOR, GS_BLEND_INVFACTOR, transitionAlpha);
}

DrawSprite(mainRenderTextures[curRenderTarget], 0xFFFFFFFF,
renderFrameOffset.x, renderFrameOffset.y,
renderFrameOffset.x + renderFrameSize.x, renderFrameOffset.y + renderFrameSize.y);
else
DrawSprite(mainRenderTextures[curRenderTarget], 0xFFFFFFFF,
renderFrameOffset.x, renderFrameOffset.y,
renderFrameOffset.x + renderFrameSize.x, renderFrameOffset.y + renderFrameSize.y);
}

const float yuvFullMat[][16] = {
Expand Down Expand Up @@ -622,6 +618,8 @@ void OBS::MainCaptureLoop()
HANDLE hMatrix = yuvScalePixelShader->GetParameterByName(TEXT("yuvMat"));
HANDLE hScaleVal = yuvScalePixelShader->GetParameterByName(TEXT("baseDimensionI"));

HANDLE hTransitionTime = transitionPixelShader->GetParameterByName(TEXT("transitionTime"));

//----------------------------------------
// x264 input buffers

Expand Down Expand Up @@ -918,12 +916,12 @@ void OBS::MainCaptureLoop()

if(bTransitioning)
{
if(!transitionTexture)
if(!lastRenderTexture)
{
transitionTexture = CreateTexture(baseCX, baseCY, GS_BGRA, NULL, FALSE, TRUE);
if(transitionTexture)
lastRenderTexture = CreateTexture(baseCX, baseCY, GS_BGRA, NULL, FALSE, TRUE);
if(lastRenderTexture)
{
D3D10Texture *d3dTransitionTex = static_cast<D3D10Texture*>(transitionTexture);
D3D10Texture *d3dTransitionTex = static_cast<D3D10Texture*>(lastRenderTexture);
D3D10Texture *d3dSceneTex = static_cast<D3D10Texture*>(mainRenderTextures[lastRenderTarget]);
GetD3D()->CopyResource(d3dTransitionTex->texture, d3dSceneTex->texture);
}
Expand All @@ -932,22 +930,36 @@ void OBS::MainCaptureLoop()
}
else if(transitionAlpha >= 1.0f)
{
delete transitionTexture;
transitionTexture = NULL;
delete lastRenderTexture;
lastRenderTexture = NULL;

bTransitioning = false;
}
}

if(bTransitioning)
{
EnableBlending(TRUE);
transitionAlpha += float(fSeconds)*5.0f;
transitionAlpha += float(fSeconds) * 5.0f;
if(transitionAlpha > 1.0f)
transitionAlpha = 1.0f;

SetRenderTarget(transitionTexture);

Shader *oldPixelShader = GetCurrentPixelShader();
LoadPixelShader(transitionPixelShader);

transitionPixelShader->SetFloat(hTransitionTime, transitionAlpha);
LoadTexture(mainRenderTextures[curRenderTarget], 1U);

DrawSpriteEx(lastRenderTexture, 0xFFFFFFFF,
0, 0, baseSize.x, baseSize.y, 0.0f, 0.0f, 1.0f, 1.0f);

LoadTexture(nullptr, 1U);
LoadPixelShader(oldPixelShader);
}
else
EnableBlending(FALSE);

EnableBlending(FALSE);


//------------------------------------
// render the mini view thingy
Expand Down Expand Up @@ -1049,13 +1061,9 @@ void OBS::MainCaptureLoop()
//because outputSize can be trimmed by up to three pixels due to 128-bit alignment.
//using the scale function with outputSize can cause slightly inaccurate scaled images
if(bTransitioning)
{
BlendFunction(GS_BLEND_ONE, GS_BLEND_ZERO);
DrawSpriteEx(transitionTexture, 0xFFFFFFFF, 0.0f, 0.0f, scaleSize.x, scaleSize.y, 0.0f, 0.0f, 1.0f, 1.0f);
BlendFunction(GS_BLEND_FACTOR, GS_BLEND_INVFACTOR, transitionAlpha);
}

DrawSpriteEx(mainRenderTextures[curRenderTarget], 0xFFFFFFFF, 0.0f, 0.0f, outputSize.x, outputSize.y, 0.0f, 0.0f, 1.0f, 1.0f);
else
DrawSpriteEx(mainRenderTextures[curRenderTarget], 0xFFFFFFFF, 0.0f, 0.0f, outputSize.x, outputSize.y, 0.0f, 0.0f, 1.0f, 1.0f);

//------------------------------------

Expand Down
43 changes: 43 additions & 0 deletions rundir/shaders/SceneTransition.pShader
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/********************************************************************************
Copyright (C) 2014 Hugh Bailey <[email protected]>

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 prevTexture;
uniform Texture2D currTexture;

uniform float4 outputColor;
uniform float transitionTime;

SamplerState textureSampler
{
AddressU = Clamp;
AddressV = Clamp;
Filter = Linear;
};

struct VertData
{
float4 pos : SV_Position;
float2 texCoord : TexCoord0;
};

float4 main(VertData input) : SV_Target
{
float3 color = lerp(prevTexture.Sample(textureSampler, input.texCoord).rgb, currTexture.Sample(textureSampler, input.texCoord).rgb, transitionTime);
return float4(color, 1.0f) * outputColor;
}

0 comments on commit 872ed6f

Please sign in to comment.