From a4fbd6f19b05076af7bb19b6364cd0adc785d8c1 Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Wed, 21 Mar 2007 04:38:17 +0000 Subject: [PATCH] implement EffectMode_YUYV422 --- stepmania/Data/Shaders/GLSL/YUYV422.frag | 94 ++++++++++++++++++++++++ stepmania/src/RageDisplay_OGL.cpp | 13 ++++ 2 files changed, 107 insertions(+) create mode 100644 stepmania/Data/Shaders/GLSL/YUYV422.frag diff --git a/stepmania/Data/Shaders/GLSL/YUYV422.frag b/stepmania/Data/Shaders/GLSL/YUYV422.frag new file mode 100644 index 0000000000..f48e325d71 --- /dev/null +++ b/stepmania/Data/Shaders/GLSL/YUYV422.frag @@ -0,0 +1,94 @@ +uniform sampler2D Texture1; +uniform sampler2D Texture2; +uniform int TextureWidth; + +/* + * Convert from YUYV422 to RGB. + * + * This is used by MovieTexture_Generic. The input texture is TextureWidth + * texels wide, the output texture is TextureWidth*2 texels wide, and texels + * are aligned. We can use this to determine if the fragment we're generating + * is even or odd. + */ +void main(void) +{ + vec4 tex = gl_TexCoord[0]; + + float fRealWidth = float(TextureWidth); + float fU = tex.x; + + /* Scale U to [0.25,fRealWidth+0.25]. */ + fU *= fRealWidth; + + /* Scale the U texture coordinate to the size of the destination texture, + * [0.5,fDestWidth+0.5]. */ + fU *= 2.0; + + /* Texture coordinates are center-aligned; an exact sample lies at 0.5, + * not 0. Shift U from [0.5,fDestWidth+0.5] to [0,fDestWidth]. */ + fU -= 0.5; + + /* If this is an odd fragment, fOdd is 1. */ + float fOdd = mod(fU+0.0001, 2.0); + + /* Align fU to an even coordinate. */ + fU -= fOdd; + + /* Scale U back. Because fU is aligned to an even coordinate, this + * will always be an exact sample. */ + fU += 0.5; + fU /= 2.0; + fU /= fRealWidth; + + tex.x = fU; + + vec4 yuyv = texture2D( Texture1, tex.xy ); + + vec3 yuv; + if( fOdd <= 0.5 ) + yuv = yuyv.rga; + else + yuv = yuyv.bga; + yuv -= vec3(16.0/255.0, 128.0/255.0, 128.0/255.0); + + mat3 conv = mat3( + // Y U (Cb) V (Cr) + 1.1643, 0.000, 1.5958, // R + 1.1643, -0.39173, -0.81290, // G + 1.1643, 2.017, 0.000); // B + + gl_FragColor.r=dot(yuv,conv[0]); + gl_FragColor.g=dot(yuv,conv[1]); + gl_FragColor.b=dot(yuv,conv[2]); + gl_FragColor.a = 1.0; + + /* Why doesn't this work? */ +// gl_FragColor.rgb = yuv * conv; +// gl_FragColor.a = 1.0; +} + +/* + * Copyright (c) 2007 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + diff --git a/stepmania/src/RageDisplay_OGL.cpp b/stepmania/src/RageDisplay_OGL.cpp index 2c34cfb702..3de9005874 100644 --- a/stepmania/src/RageDisplay_OGL.cpp +++ b/stepmania/src/RageDisplay_OGL.cpp @@ -367,6 +367,7 @@ static GLhandleARB g_bColorBurnShader = 0; static GLhandleARB g_bColorDodgeShader = 0; static GLhandleARB g_bVividLightShader = 0; static GLhandleARB g_hHardMixShader = 0; +static GLhandleARB g_hYUYV422Shader = 0; void InitShaders() { @@ -377,6 +378,7 @@ void InitShaders() g_bColorDodgeShader = LoadShader( GL_FRAGMENT_SHADER_ARB, "Data/Shaders/GLSL/Color dodge.frag", asDefines ); g_bVividLightShader = LoadShader( GL_FRAGMENT_SHADER_ARB, "Data/Shaders/GLSL/Vivid light.frag", asDefines ); g_hHardMixShader = LoadShader( GL_FRAGMENT_SHADER_ARB, "Data/Shaders/GLSL/Hard mix.frag", asDefines ); + g_hYUYV422Shader = LoadShader( GL_FRAGMENT_SHADER_ARB, "Data/Shaders/GLSL/YUYV422.frag", asDefines ); // Bind attributes. if( g_bTextureMatrixShader ) @@ -1596,6 +1598,7 @@ void RageDisplay_OGL::SetEffectMode( EffectMode effect ) case EffectMode_ColorDodge: hShader = g_bColorDodgeShader; break; case EffectMode_VividLight: hShader = g_bVividLightShader; break; case EffectMode_HardMix: hShader = g_hHardMixShader; break; + case EffectMode_YUYV422: hShader = g_hYUYV422Shader; break; } FlushGLErrors(); @@ -1606,6 +1609,15 @@ void RageDisplay_OGL::SetEffectMode( EffectMode effect ) GLint iTexture2 = GLExt.glGetUniformLocationARB( hShader, "Texture2" ); GLExt.glUniform1iARB( iTexture1, 0 ); GLExt.glUniform1iARB( iTexture2, 1 ); + + if( effect == EffectMode_YUYV422 ) + { + GLint iTextureWidthUniform = GLExt.glGetUniformLocationARB( hShader, "TextureWidth" ); + GLint iWidth; + glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &iWidth ); + GLExt.glUniform1iARB( iTextureWidthUniform, iWidth ); + } + AssertNoGLError(); } @@ -1619,6 +1631,7 @@ bool RageDisplay_OGL::IsEffectModeSupported( EffectMode effect ) case EffectMode_ColorDodge: return g_bColorDodgeShader != 0; case EffectMode_VividLight: return g_bVividLightShader != 0; case EffectMode_HardMix: return g_hHardMixShader != 0; + case EffectMode_YUYV422: return g_hYUYV422Shader != 0; } return false;