参考同事等的代码
这里的YUV文件的每一帧是Y,U,V分别单独存储的。
这里逻辑是对的,但代码不太完整
pBuf = new unsigned char[bytesPerFrame];
pBuf2 = new unsigned char[bytesPerFrame];
//fread(pBuf, 1, bytesPerFrame, f);
//yuv420_to_nv12(pBuf, pBuf2, nWidth, nHeight);
tex0 = TextureManager::getSingleton().createManual( "tex0",
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
TEX_TYPE_2D, nWidth, nHeight, 0,
Ogre::PF_L8,
Ogre::TU_DYNAMIC_WRITE_ONLY );
tex1 = TextureManager::getSingleton().createManual( "tex1",
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
TEX_TYPE_2D, nWidth >> 1, nHeight >> 1, 0,
Ogre::PF_BYTE_LA,
Ogre::TU_DYNAMIC_WRITE_ONLY );
File *f = fopen("E:\\ogre-1.10\\Samples\\Car\\akiyo_qcif.yuv","rb");
bytesPerFrame = ( nWidth * nHeight * 3 ) >> 1;
fseek(f, 0, SEEK_END);
frame_count = (int) ((int)ftell(f)/bytesPerFrame);
fseek(f, 0, SEEK_SET);
unsigned char *pBuf = new unsigned char[bytesPerFrame];
Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().getByName("YUV_test");
Pass *pass = material->getTechnique(0)->getPass(0);
pass->setDepthCheckEnabled(true);
pass->setDepthWriteEnabled(true);
pass->setLightingEnabled(false);
TextureUnitState* state = pass->createTextureUnitState("tex0"); //会累计,0,纹理坐标集 texture coordinate set
TextureUnitState* state1 = pass->createTextureUnitState("tex1");//会累计,1,纹理坐标集 texture coordinate set
GpuProgramParametersSharedPtr ptrFP = pass->getFragmentProgramParameters();
ptrFP->setNamedConstant("texTyp",1);
ptrFP->setNamedConstant("texture",0);//设置纹理坐标集
ptrFP->setNamedConstant("texture2",1);//设置纹理坐标集
ptrFP->setNamedConstant("gamVal",Ogre::Real(1.0));
ent->setMaterial(material);
每一帧更换纹理,这里pBuff2是用来做实验的,来验证另一种调整UV位置的方法
//设置当前帧的纹理数据,yoga test
void set_cur_frame_tex(int i)
{
if( i == frame_count )
return;
fseek(f, i * bytesPerFrame, SEEK_SET);
fread(pBuf2, 1, bytesPerFrame, f);
yuv420_to_nv12(pBuf, pBuf2, nWidth, nHeight);
// tex0
Ogre::HardwarePixelBufferSharedPtr pixelBuffer = tex0->getBuffer();
pixelBuffer->lock( Ogre::HardwareBuffer::HBL_DISCARD );
{
const Ogre::PixelBox &pixelBox = pixelBuffer->getCurrentLock();
Ogre::uint8 *dest = static_cast<Ogre::uint8*>( pixelBox.data );
PixelFormat format = pixelBox.format;
for( size_t j = 0; j < nWidth * nHeight; j++ )
{
dest[j] = pBuf[j];
}
}
pixelBuffer->unlock();
// tex1
//pixelBuffer = tex1->getBuffer();
Ogre::HardwarePixelBufferSharedPtr pixelBuffer1 = tex1->getBuffer();
pixelBuffer1->lock( Ogre::HardwareBuffer::HBL_DISCARD );
{
const Ogre::PixelBox &pixelBox = pixelBuffer1->getCurrentLock();
Ogre::uint8 *dest = static_cast<Ogre::uint8*>( pixelBox.data );
PixelFormat format = pixelBox.format;
/* for( size_t j = 0; j < ((nWidth * nHeight)>>1); j++ )
{
dest[j] = pBuf[ nWidth * nHeight + j];
}
for( size_t j = nWidth * nHeight, k = 0; j < nWidth * nHeight + ((nWidth * nHeight)>>2); j++, k++ )//nWidth * nHeight + (bytesPerFrame >> 1); j+=2, k+=2 )
{
dest[(k<<1)] = pBuf2[j];
//dest[k+1] = pBuf[k+1];
//break;//test
}
for( size_t j = nWidth * nHeight + ((nWidth * nHeight)>>2), k = 0; j < nWidth * nHeight + ((nWidth * nHeight)>>1); j++, k++ )//nWidth * nHeight + (bytesPerFrame >> 1); j+=2, k+=2 )
{
dest[(k<<1)+1] = pBuf2[j];
//dest[k+1] = pBuf[k+1];
//break;//test
}*/
//size_t sz0 = nWidth * nHeight;
//size_t sz1 = bytesPerFrame;
size_t pixelsPerFrame = nWidth * nHeight;
for( size_t j = pixelsPerFrame, k = 0; j < pixelsPerFrame + ((pixelsPerFrame)>>2); j++, k++ )//nWidth * nHeight + (bytesPerFrame >> 1); j+=2, k+=2 )
{
dest[(k<<1)] = pBuf2[j];
//dest[k+1] = pBuf[k+1];
//break;//test
}
for( size_t j = pixelsPerFrame + ((pixelsPerFrame)>>2), k = 0; j < pixelsPerFrame + ((pixelsPerFrame)>>1); j++, k++ )//nWidth * nHeight + (bytesPerFrame >> 1); j+=2, k+=2 )
{
dest[(k<<1)+1] = pBuf2[j];
//dest[k+1] = pBuf[k+1];
//break;//test
}
}
pixelBuffer1->unlock();
}
// Ogre glsles 要求一定要有 vert 和 frag shader
frag shader 如下,是把由420 YUV 的单帧文件数据记录到两个 纹理中,来进行计算,生产rgb颜色
precision mediump float;
uniform sampler2D texture;
uniform sampler2D texture2;
uniform float gamVal;
uniform int texTyp;
varying vec2 g_vVSTexCoord;
void main()
{
if( 0 == texTyp)
{
gl_FragColor = texture2D(texture,g_vVSTexCoord);
}
else if(1 == texTyp)
{
vec4 tmpColor;
vec4 yuv = vec4(1.0);
vec4 rgb = vec4(1.0);
mat4 conversion = mat4(1.0, 0.0, 1.596, -0.798,
1.0, -0.392, -0.813, 0.603,
1.0, 2.017, 0.0, -1.009,
0, 0, 0, 0);
tmpColor = texture2D(texture,g_vVSTexCoord);
yuv.r = tmpColor.r;
yuv.r = pow(yuv.r, gamVal);
tmpColor = texture2D(texture2,g_vVSTexCoord);
yuv.yz = tmpColor.ra;
rgb = yuv*conversion;
rgb.a = 1.0;
gl_FragColor = rgb;
}
}