如何进行快速位图拉伸? [英] How to do fast bitmap stretching?
本文介绍了如何进行快速位图拉伸?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在尝试尽可能快地拉伸位图.
我需要每秒拉伸60个位图.
我正在使用StretchBltBits,但是当我使用HALFTONE BltMode时,我每秒只能得到24-25帧.
位图可以是16bpp,24bppor和32bpp 1024x576.
如果真的想改善图像的显示效果,那么可以考虑使用硬件加速功能.使用DirectX或OpenGL库.
一次,我使用DirectX和Sprite来显示2D图像(还有其他一些东西).我将复制对我有用的代码,但是请注意我不是Direct3D专家,并且我使用了 DirectX9 ,因此您可能会找到更好,最新的代码.
初始化代码:
// 创建Direct3D对象(类型:IDirect3D9 *) m_pDirect3D9 = Direct3DCreate9(D3D_SDK_VERSION); 如果(!m_pDirect3D9) 返回为假; // 设置显示模式(根据需要更改所需的内容) D3DDISPLAYMODE displayMode; m_pDirect3D9-> GetAdapterDisplayMode(D3DADAPTER_DEFAULT,& displayMode); displayMode.Format = D3DFMT_A8R8G8B8; D3DPRESENT_PARAMETERS presentParameters; ZeroMemory(& presentParameters, sizeof (D3DPRESENT_PARAMETERS)); presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // 别忘了这个 presentParameters.Windowed = TRUE; presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD; presentParameters.EnableAutoDepthStencil = TRUE; presentParameters.AutoDepthStencilFormat = D3DFMT_D24X8; presentParameters.BackBufferCount = 1 ; // 格式=每像素32位(ARGB) presentParameters.BackBufferFormat = D3DFMT_A8R8G8B8; presentParameters.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL; // 在此处放置图片大小 presentParameters.BackBufferWidth = imageWidth; presentParameters.BackBufferHeight = imageHeight; // 创建设备(类型:IDirect3DDevice9 *) HRESULT res = m_pDirect3D9-> CreateDevice( D3DADAPTER_DEFAULT, // 使用视频卡 D3DDEVTYPE_HAL, // 窗口句柄(您将在其中显示图像的窗口句柄) hWnd, // 这对我来说很重要 // 尤其是第二个:浮点运算可能会给出 如果不使用FPU_PRESERVE,则// 不同的结果将导致另一个线程! // ,但在大多数情况下,我认为您可以删除此 D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, & presentParameters, & m_pDirect3DDevice9 ); 如果(m_pDirect3DDevice9 == NULL) 返回为假; // 创建用于显示图像的精灵(m_pSprite的ID3DXSprite *类型) D3DXCreateSprite(m_pDirect3DDevice9,& m_pSprite); 如果(m_pSprite == NULL) 返回为假; // 创建将由精灵使用的纹理 // m_pTexture的类型为IDirect3DTexture9 * m_pDirect3DDevice9-> CreateTexture( imageWidth,imageHeight, 1 , 0 , // 像素格式:在我的情况下,我想显示8位/像素的图像 D3DFMT_L8, D3DPOOL_MANAGED, & m_pTexture, 无效的 ); 如果(!m_pTexture) 返回为假;
更新纹理:
// 在我的情况下,图像为8位/像素 无效 YourClass :: UpdateTexture( const BYTE *图片) { 如果(m_pTexture == NULL) 返回; D3DLOCKED_RECT已锁定; m_pTexture-> LockRect( 0 , & lockedRect, 无效的, D3DLOCK_DISCARD ); for ( int y = 0 ; y < m_imageHeight; y ++) { 复制内存( (BYTE *)lockedRect.pBits + y * lockedRect.Pitch, 图片+ y * m_imageWidth, m_imageWidth ); } m_pTexture-> UnlockRect( 0 ); }
绘图代码(从OnPaint
调用):
void YourClass :: Draw() { 如果(!m_pDirect3DDevice9) 返回; m_pDirect3DDevice9-> BeginScene(); m_pDirect3DDevice9-> Clear( 0 ,NULL,D3DCLEAR_TARGET,D3DCOLOR_ARGB( 255 , 0 , 1 .0f,// 绘制纹理 m_pSprite-> Begin( 0 ); m_pSprite-> Draw( m_pTexture,// 纹理 NULL,NULL,NULL, D3DCOLOR_ARGB( 255 , 255 , 255 , 255 )// 使用alpha +颜色 ); m_pSprite-> End(); m_pDirect3DDevice9-> EndScene(); m_pDirect3DDevice9-> Present(NULL,NULL,NULL,NULL); }
您可以在OpenGL中执行类似的操作.不幸的是,我无法在本机OpenGL中提供代码.
Hi I am trying to stretch a bitmapas fast as possible.
I need to stretch 60 bitmaps per second.
I am using StretchBltBits but when I use HALFTONE BltMode I only get 24-25 frames per second.
The bitmap can be 16bpp, 24bppor and 32bpp 1024x576.
is ther a faster way to strech the bitmap then StretchBltBits?
解决方案
If you want to really improve your image display, then consider using hardware accelerated functions. Use DirectX or OpenGL libraries.
Once, I used DirectX and sprites to display a 2D image (and a few more things). I will copy the code that worked for me, but please note I am not a Direct3D expert and I used DirectX9 so you can probably find better and more up to date code.
Initialization code:
//creates the Direct3D object (type: IDirect3D9*) m_pDirect3D9 = Direct3DCreate9(D3D_SDK_VERSION); if (!m_pDirect3D9) return FALSE; //setup the display mode (change whatever you want depending on your requirements) D3DDISPLAYMODE displayMode; m_pDirect3D9->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode); displayMode.Format = D3DFMT_A8R8G8B8; D3DPRESENT_PARAMETERS presentParameters; ZeroMemory(&presentParameters, sizeof(D3DPRESENT_PARAMETERS)); presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; //don't forget this presentParameters.Windowed = TRUE; presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD; presentParameters.EnableAutoDepthStencil = TRUE; presentParameters.AutoDepthStencilFormat = D3DFMT_D24X8; presentParameters.BackBufferCount = 1; //format = 32 bits per pixel (ARGB) presentParameters.BackBufferFormat = D3DFMT_A8R8G8B8; presentParameters.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL; //put the size of your image here presentParameters.BackBufferWidth = imageWidth; presentParameters.BackBufferHeight = imageHeight; //create the device (type: IDirect3DDevice9*) HRESULT res = m_pDirect3D9->CreateDevice( D3DADAPTER_DEFAULT, // use video card D3DDEVTYPE_HAL, // window handle (the one into which you will display the image) hWnd, //this was important in my case //especially the second one: floating point operations may give //different results in another thread if you don't use FPU_PRESERVE!! //but in most case I think you can remove this D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &presentParameters, &m_pDirect3DDevice9 ); if (m_pDirect3DDevice9 == NULL) return FALSE; //create the sprite used to display the image (m_pSprite is of type ID3DXSprite*) D3DXCreateSprite(m_pDirect3DDevice9, &m_pSprite); if (m_pSprite == NULL) return FALSE; //create the texture that will be used by the sprite //m_pTexture is of type IDirect3DTexture9* m_pDirect3DDevice9->CreateTexture( imageWidth, imageHeight, 1, 0, //pixel format: in my case I wanted to display a 8 bits/pixel image D3DFMT_L8, D3DPOOL_MANAGED, &m_pTexture, NULL ); if (!m_pTexture) return FALSE;
Updating the texture:
//in my case, the image is 8 bits/pixel void YourClass::UpdateTexture(const BYTE* image) { if (m_pTexture == NULL) return; D3DLOCKED_RECT lockedRect; m_pTexture->LockRect( 0, &lockedRect, NULL, D3DLOCK_DISCARD ); for (int y = 0; y < m_imageHeight; y++) { CopyMemory( (BYTE*)lockedRect.pBits + y * lockedRect.Pitch, image + y * m_imageWidth, m_imageWidth ); } m_pTexture->UnlockRect(0); }
Drawing code (to be called fromOnPaint
):
void YourClass::Draw() { if (!m_pDirect3DDevice9) return; m_pDirect3DDevice9->BeginScene(); m_pDirect3DDevice9->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(255, 0, 0, 0), 1.0f, 0); // draw the texture m_pSprite->Begin(0); m_pSprite->Draw( m_pTexture, // texture NULL, NULL, NULL, D3DCOLOR_ARGB(255, 255, 255, 255) // use alpha + colors ); m_pSprite->End(); m_pDirect3DDevice9->EndScene(); m_pDirect3DDevice9->Present(NULL, NULL, NULL, NULL); }
You can do something similar in OpenGL. Unfortunately, I can''t provide code in native OpenGL.
这篇关于如何进行快速位图拉伸?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文