Use a separate texture when scene transitioning.

Get rid of 1+ DrawSprite call(s) during scene transition.
master
HomeWorld 2014-10-04 01:09:59 +03:00
parent 0ef092a33a
commit 872ed6f931
6 changed files with 94 additions and 25 deletions

View File

@ -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" />

View File

@ -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">

View File

@ -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;
//---------------------------------------------------

View File

@ -571,12 +571,17 @@ retryHookTestV2:
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;
@ -608,6 +613,8 @@ retryHookTestV2:
yuvRenderTextures[i] = CreateRenderTarget(outputCX, outputCY, GS_BGRA, FALSE);
}
transitionTexture = CreateRenderTarget(baseCX, baseCY, GS_BGRA, FALSE);
//-------------------------------------------------------------
D3D10_TEXTURE2D_DESC td;
@ -1092,11 +1099,15 @@ 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;
@ -1104,6 +1115,7 @@ void OBS::Stop(bool overrideKeepRecording, bool stopReplayBuffer)
mainVertexShader = NULL;
mainPixelShader = NULL;
yuvScalePixelShader = NULL;
transitionPixelShader = NULL;
solidVertexShader = NULL;
solidPixelShader = NULL;

View File

@ -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] = {
@ -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
@ -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);
}
@ -932,8 +930,8 @@ void OBS::MainCaptureLoop()
}
else if(transitionAlpha >= 1.0f)
{
delete transitionTexture;
transitionTexture = NULL;
delete lastRenderTexture;
lastRenderTexture = NULL;
bTransitioning = false;
}
@ -941,13 +939,27 @@ void OBS::MainCaptureLoop()
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
@ -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);
//------------------------------------

View File

@ -0,0 +1,43 @@
/********************************************************************************
Copyright (C) 2014 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 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;
}