由于时间仓促,翻译的不是很好,希望大家能够将就看看。
将 gifs, jpgs文件加载到表面
作者: w-buffer
相对而言,不是很难,我们并不需要解码器来得到jpg的每一个字节,或任何类似于次的,相反,我们将用一个图片框来打开一个图片,然后再将其传到表面,但首先我门需要声明api函数:
public declare function bitblt lib "gdi32" (byval hdestdc as long, byval x as long, byval y as long, byval nwidth as long, byval nheight as long, byval hsrcdc as long, byval xsrc as long, byval ysrc as long, byval dwrop as long) as long
public declare function createcompatibledc lib "gdi32" (byval hdc as long) as long
public declare function deletedc lib "gdi32" (byval hdc as long) as long
public declare function selectobject lib "gdi32" (byval hdc as long, byval hobject as long) as long
public declare function stretchblt lib "gdi32" (byval hdc as long, byval x as long, byval y as long, byval nwidth as long, byval nheight as long, byval hsrcdc as long, byval xsrc as long, byval ysrc as long, byval nsrcwidth as long, byval nsrcheight as long, byval dwrop as long) as long
现在我们要为加载图片作好准备
dim pict1 as stdpicture
set pict1 = loadpicture("mypict.jpg")
创造表面:
dim tdesc as ddsurfacedesc2
tdesc.lflags = ddsd_caps or ddsd_height or ddsd_width
tdesc.ddscaps.lcaps = ddscaps_offscreenplain
tdesc.lheight = clng((pict1.height * 0.001) * 567 / screen.twipsperpixely)
tdesc.lwidth = clng((tpict.width * 0.001) * 567 / screen.twipsperpixelx)
set surf = ddraw.createsurface(tdesc)
dim surfdc as long, pictdc as long
surfdc = surf.getdc
pictdc = createcompatibledc(0)
selectobject pict1.handle, pictdc
我们将使用dcs和bitblt或stretchblt来把pic1复制到表面
只复制成一样大小:
bitblt surfdc, 0, 0, tdesc.lwidth, tdesc.lheight, pictdc, 0, 0, vbsrccopy
现在复制并且改变图片大小
stretchblt surfdc, 0, 0, stretchwidth, stretchheight, pictdc, 0, 0, tdesc.lwidth, tdesc.lwidth, vbsrccopy
释放dc:
surf.releasedc surfdc
delectedc pictdc
set pict1 = nothing
下一步该怎么作呢?下载surfutil。bas,我将利用这一技巧来创造并加载图片
注意:有时stretchblt不能正常显示gif,那就是我添加了bitblt这个函数的原因
.
特殊效果
你会懒的不想利用c/c++或汇编来创造一个动态连接库,并用那个动态连接库来完成特殊效果吗?
就让blitter(我不认识,也查不出来,可能是glitter,闪光)光栅操作(rop)为你工作!
我的格言是让最小的努力为你带来最大的报酬!
在vb中有不少可使用的rop常数:
vbsrcpaint -逻辑或操作,源和目标图片,做一个模拟的alpha混合效果。
vbsrcand - 逻辑与操作,灰度效果。
vbsrcinvert - 逻辑异或操作。
vbsrcerase - 翻转目标图片,然后再和源图片进行逻辑与操作
vbsrccopy - 把原图片直接复制到目标图片上,在圆满的替换掉?(replacing it completely)
vbdstinvert -翻转目标图片,全部忽略原图片。
vbnotsrccopy -翻转源图片,然后在直接复制到目标上,又是圆满的替换掉?(replacing it completely)
vbnotsrcerase - 对源图片和目标图片进行逻辑或操作,在翻转。
现在我们利用这些rop有两个执行销毁的方法。我们能够使用apibitblt这个函数,,也可以使用directx的bltfx函数,只有用户的显卡能够使用硬件来支持rop而不是软件模拟rop,bltfx才能够工作,否则bltfx将会失败!无论怎样,bltfx失败时,api的bitblt还是能够调用,在软件中,一切就绪时,bitblt就决不会失败!
(深思熟虑:当使用bltfx时,它可以完美的将表面放到显存以使其借助显卡的blitter(和上面的一样,不认识也查不出来)来快速访问,而当另外使用api函数bitblt时,它却完美的将其置放到系统内存,否则数据将会被从显存中修改后带来,然后它将回到显存,没有效率啊!)
容易的知道确认用户的显卡是否硬件支持特殊的rop是件很好的事,我写了一个简单的函数来确认:
private function testrop(byref surfback as directdrawsurface7, lngrop as long) as boolean
dim objbltfx as ddbltfx
dim recttemp as rect
dim surftemp as directdrawsurface7
dim udtddsd as ddsurfacedesc2
'创造一个临时的表面
udtddsd.lflags = ddsd_height or ddsd_width
udtddsd.lheight = 1
udtddsd.lwidth = 1
set surftemp = mdd.createsurface(udtddsd)
'设置bltfx的rop操作代码
objbltfx.lrop = lngrop
'源和目标矩形
recttemp.right = 1
recttemp.bottom = 1
'测试bltfx 的能力
if surfback.bltfx(recttemp, surftemp, recttemp, ddblt_rop or ddblt_wait, objbltfx) <> 0 then
testrop = false
else
testrop = true
end if
end function
简单的传递这个函数 一个参考到你的当前后备缓存和你感兴趣的rop常数,它将把用户硬件是否支持特殊的rop告诉你给你,它执行一个bltfx 的blit例子并且测试错误然后返回错误。
(注:这一段如果你懂就可不必看我写的,有一些英文短语不容易翻译成中文)
simply pass this function a reference to your current backbuffer and the rop constant you're interested in and it will inform you of the user's hardware capabilities. it does this by performing a sample bltfx blit and examining the error code returned.
现在我门知道如果我们希望的rop已经被支持,我们就能往下继续并且执行我们的blit,如果rop以被支持,我们也能像这样使用bltfx:
objbltfx.lrop = lngrop
msurfback.bltfx rectdest, surfdisplay, rectsource, ddblt_rop or ddblt_wait, objbltfx
objbltfx的定义类型是ddbltfx,必须和我们希望执行(被储存在lngrop中)的rop一起被加载。一次,我们有我们的ddbltfx类型填充,我们就能使用后备缓存的bltfx方法,传递源和目标矩形、我们期望的表面、一点常数(ddblt_rop和ddblt_wait)和objbltfx,常数ddblt_rop是必须的,它将通知bltfx我们想使用ddbltfx结构的成员lrop。if we're forced to use the bitblt api, it can be handled in this fashion:
'锁主表面的dcs
lngdestdc = msurfback.getdc
lngsrcdc = surfdisplay.getdc
'do the fancy old-fashioned blit
bitblt lngdestdc, intx, inty, intwidth, intheight, lngsrcdc, 0, 0, lngrop
'释放dcs
surfdisplay.releasedc lngsrcdc
msurfback.releasedc lngdestdc
首先我们需要得到源(被blitte的表面,和上文的blitter有关,可能是directx的专有名词)和目标(后备缓存)的dc,一旦我们全部拥有,我们把它们作为bitblt的参数,再和妖怪定义(?sprite的确是妖怪)和我们期望的rop(lngrop)向前,然后必须释放dc,以免电脑当掉。