|
楼主 |
发表于 2005-8-8 23:12:31
|
显示全部楼层
里面的Blt之类的东西啦~,另外,由于我们的数据保留的是调色板的索引,所以,不能直接Blt到BackSurface上,自己分配一个缓冲区,大小和BackSurface一样大,不过用byte类型就够啦~
自己写几个Blt吧:
比如一个Alpha混合的操作:(代码取自我给出的Demo) void GBDI:rawToScreenAdditiveSrcColorKey(unsigned char*pBufDest,int nDestWidth,unsigned char*pBufSour,int nLine,int nRow) { unsigned char*pDestAddr = pBufDest; unsigned char*pSourAddr = pBufSour; for(register int i=0;i { for(register int j=0;j { if(*pSourAddr != m_byColorKeyIndex) { *pDestAddr = GBDI::BDI_AdditiveTable[*pSourAddr][*pDestAddr]; //这个地方极大的节省了大量的数学运算 } pDestAddr++; pSourAddr++; } pBufDest += nDestWidth; pBufSour += m_nWidth; pDestAddr = pBufDest; pSourAddr = pBufSour; } }上面的操作是经过裁减过后的显示,裁减代码如下:
RECT rtDest = {m_position.x,m_position.y,m_position.x+pScreen->GetWidth(),m_position.y+pScreen->GetHeight()}; RECT rtSour = m_rtShowArea; if(rtDest.top<0) { rtSour.top -= rtDest.top; rtDest.top = 0; } if(rtDest.left<0) { rtSour.left -= rtDest.left; rtDest.left = 0; } if(rtDest.left+rtSour.right-rtSour.left>pScreen->GetWidth()) { rtSour.right = rtSour.left+pScreen->GetWidth()-rtDest.left; } if(rtDest.top+rtSour.bottom-rtSour.top>pScreen->GetHeight()) { rtSour.bottom = rtSour.top+pScreen->GetHeight()-rtDest.top; }
unsigned char*pBufDest = pScreen->GetBuffer()+pScreen->GetWidth()*rtDest.top+rtDest.left;//目标地址 unsigned char*pBufSour = m_pData+m_nWidth*rtSour.top+rtSour.left;//源地址 int nLine = rtSour.right-rtSour.left; int nRow = rtSour.bottom-rtSour.top;
各种参数的含义都比较明显,了解E文的并且写过代码的应该都能看懂,看不懂的如果有兴趣的话,自己去看完整源代码,好了,如何才能在屏幕上正确的显示呢? 这个问题就很简单了,当然最最直接的方法就是:
for(缓冲区上的每一个点) BackSurface上的每一个点 = 缓冲区上的每一个点所代表的调色板的值
嘿嘿,别忘记了,上面说过用到的调色板是什么来的? 低8位和高8位相同! 如果了解mmx的话,就应该知道这一条指令:punpcklbw 哈哈!如何?知道优化的方法了吧?
下面是我的Demo中的代码: DDSURFACEDESC2 ddsd; ZeroMemory(&ddsd,sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); hr = m_pDSBack->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL); while(DD_OK!=hr) { if(DDERR_SURFACELOST==hr) RestoreSurface(); else return; hr=m_pDSBack->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL); } unsigned char*pSourBuf = (unsigned char*)m_pBuffer;
if(m_bDefaultPal)//如果是采用了默认的调色板(高8位==低8位) { //由于初学mmx,还不会作mmx指令的优化~代码见笑了~ unsigned long dwResPitch = ddsd.lPitch-(m_nWidth<<1); unsigned char*pBuf = (unsigned char*)ddsd.lpSurface; unsigned long dwHeight = m_nHeight; unsigned long loopTime = m_nWidth>>5; //一次处理32个索引点 { _asm { mov esi,pSourBuf; mov edi,pBuf; mov edx,dwHeight; rowLoop: cmp edx,0; je end; mov ecx,loopTime; mmxdraw: movq mm0,[esi]; //8个索引点 movq mm2,[esi+8]; //后8个索引点 movq mm4,[esi+16]; movq mm6,[esi+24]; movq mm1,mm0; movq mm3,mm2; movq mm5,mm4; movq mm7,mm6;
|
|