简而言之,我正在尝试绘制一个应该缩放/拖动的图像(2560x2048),但性能非常糟糕,因为每次移动它都会闪烁。我使用自定义控件能够将图像拖动到新位置并放大和缩小,这意味着它必须灵活且快速。
那么,使用显卡仅绘制单个图像的最简单和最好的方法是什么?无需为了一个简单的目的而初始化一千个 directX 对象。
总体而言,该应用程序是一种工具,而不是游戏。但是这个特别大的图像应该被有效地绘制。
简而言之,我正在尝试绘制一个应该缩放/拖动的图像(2560x2048),但性能非常糟糕,因为每次移动它都会闪烁。我使用自定义控件能够将图像拖动到新位置并放大和缩小,这意味着它必须灵活且快速。
那么,使用显卡仅绘制单个图像的最简单和最好的方法是什么?无需为了一个简单的目的而初始化一千个 directX 对象。
总体而言,该应用程序是一种工具,而不是游戏。但是这个特别大的图像应该被有效地绘制。
好吧,我对Borland C++很友好,所以我会使用简单的 Canvas(简单的 Windows GDI界面)。
无需GL、GLSL或DX
你需要2个位图。
一个作为源图像(即您的 2560x2048)接下来是屏幕的后缓冲区(您的视图区域的客户端大小)。两者都必须是DIB。我更喜欢pf32bit
像素格式(32 位 int 作为颜色,所以我可以使用int *p
...)
需要编写渲染函数(或使用 GDI 的 strech draw 或 CopyRect)
不要使用,或者Set
它们很慢(总是检查每个像素的大小和颜色格式以及许多其他内容)。而是使用位图扫描线(在VCL中)。Put
Pixels
bmp->ScanLine[y]
如果做得好,这通常会加快大约 1000 倍的速度
把它们放在一起
使用背景颜色清除后台缓冲区。使用您的渲染功能将查看区域复制到后台缓冲区(无需渲染整个图像)。完成所有渲染后,将后台缓冲区复制到屏幕。
当一切正常时,您可以进一步加快速度
使用扫描线指针数组而不是在渲染中调用它们。只有在调整位图大小后才会更改扫描线的地址,因此调整大小删除所有指针数组并创建并填充新的(int *pyx[ys];
)
这种位图渲染对于简单的软件 3D 渲染来说足够快,因此对于您的目的而言,必须具有足够高的帧速率(估计远高于70fps
普通台式机)
Borland C++ VCL的一些代码(只是为了让您知道在您的编程语言中寻找什么)
// init
int xs=0,ys=0,*pyx=NULL;
Graphics::TBitmap *bmp=new Graphics::TBitmap;
bmp->HandleType=bmDIB;
bmp->PixelFormat=pf32bit;
// exit
if (bmp) delete bmp; bmp=NULL;
if (pyx) delete pyx; pyx=NULL;
// resize(_xs,_ys)
if (pyx) delete pyx; pyx=NULL;
bmp->Width=_xs;
bmp->Height=_xs;
xs=bmp->Width;
ys=bmp->Height;
pyx=new int*[ys];
if (pyx==NULL) return; // not enough memory
for (int y=0;y<ys;y++) pyx[y]=(int*)bmp->ScanLine[y];
// now pyx[y][x]=0; means setpixel(x,y)=color(0) without any slowing down checks
// now c=pyx[y][x]; means colro(c)=getpixel(x,y) without any slowing down checks
// but beware of accessing x,y, outside <0;xs),<0;ys) !!!