我正在尝试做什么
我正在尝试将多个图形绘制到Timage,这些我绘制的图形由带有Foodfills和线条的有序图层组成。 我使用多个缓冲区来确保排序和双缓冲。
我在做什么
procedure DrawScene();
var
ObjLength,LineLength,Filllength,Obj,lin,angle,i:integer;
Npoints : array[0..1] of Tpoint;
Objmap:TBitmap;
wholemap:TBitmap;
begin
wholemap := TBitmap.Create;
wholemap.Width:=area;
wholemap.height:=area;
ObjLength:=length(Objects);
for Obj:=0 to (ObjLength-1) do
if objects[Obj].Visible then
begin
// create object bitmap
if Objects[obj].Tag='FBOX' then
begin
Objmap := TBitmap.Create;
Objmap.Width:=area;
Objmap.height:=area;
Objmap.Transparent:=true;
Objmap.Canvas.Rectangle((objects[obj].Boundleft-4)+objects[obj].Position.x,area-((objects[obj].boundtop+4)+objects[obj].Position.y),(objects[obj].boundright+4)+objects[obj].Position.x,area-((objects[obj].boundbottom-4)+objects[obj].Position.y));
end;
//draw object
LineLength:=length(objects[Obj].Lines)-1;
angle:=objects[Obj].Rotation;
for lin:=0 to (LineLength) do
begin
for i:=0 to 1 do
begin
Npoints[i] := PointAddition(RotatePoint(objects[obj].Lines[lin].Point[i],angle),objects[obj].Position,false);
end;
Objmap:=DrawLine(Npoints[0].x,Npoints[0].y,Npoints[1].x,Npoints[1].y,objects[obj].Lines[lin].Color,Objmap);
end;
Filllength:=length(objects[Obj].Fills)-1;
for i:=0 to Filllength do
begin
Npoints[0]:=PointAddition(RotatePoint(objects[Obj].Fills[i].Point,objects[Obj].Rotation),objects[Obj].Position,false);
Objmap:=fillpoint( Npoints[0].x, Npoints[0].y,objects[Obj].Fills[i].color,Objmap);
end;
//write object to step frame
wholemap.Canvas.Draw(0,0,Objmap);
Objmap.Free;
end;
// write step frame to Visible Canvas
mainwindow.bufferim.Canvas.Draw(0,0,wholemap);
mainwindow.RobotArea.Picture.Graphic:=mainwindow.bufferim.Picture.Graphic;
wholemap.Free;
end;
我的预期
我期望看到每个图像对象彼此叠加,每个图像层都是该图层的完整图像。 我的例子是它背后有一面旗帜的机器人。 首先绘制标志,然后绘制机器人。
我获取的内容(在电脑上)
在电脑上我得到了我所期待的,而且一切看起来都是正确的。
我获取的内容(在笔记本电脑上)
在几乎每台笔记本电脑和一些电脑上,我只能看到机器人。 我提出了一些判断,看它是否正在绘制旗帜,它确实如此。游戏甚至可以以正确的方式与旗帜互动。 进一步的调查显示,它只是显示最后一幅图像绘制了我的“drawcene”,并且当图像被直接绘制到wholecanvas everthing apeared时(这不能用于重叠填充图层的原因)
我认为发生了什么
所以我推断出Timage的Timage.transparent属性不起作用或在某些机器上的计算方式不同。
我做了一个测试来证明这一点并且画了一块红色。然后到画布我画了0,0 i Timage,属性transparent = true,红色画布中间只有一个点。那件商品是一块白色的帆布,中间有一个圆点。
我假设并且调查结果表明具有非常基本图形驱动程序的计算机似乎将null或透明视为白色,而更强大的计算机似乎将null或透明视为透明。
由于Timage.Transparent属性为真,这似乎有点失败。
编辑: UPDATE! 看起来在ATI显卡上,如果颜色为“空”,那么它将以PF24bit的格式进行解释,因此没有alpha通道,也没有透明度。
在Nvidia卡上它将它作为PF32bit并将null视为透明。
解决这个问题的明显方法是将位图类型设置为PF32bit,但这仍然不起作用。 我假设可能这还不够,我应该确保背景设置为透明而不是保留为空...但是在Timage中没有工具(我可以看到)用alpha设置颜色。所有画布绘图功能都需要一个RGB 24位的Tcolor和一个带有RGBA 32位的TcolorRef .... 有没有用alpha 0绘图的方法?
我认为我需要知道什么
如何强制Transparent属性在所有计算机上运行 或者让笔记本电脑不能透明地粘贴为白色的方法 或者是达到相同结果的方法。
任何人都有任何解决方案或想法吗?
答案 0 :(得分:2)
我在过去(几年前)在不同的机器上看到了类似的行为。
它们是由不同的视频卡和驱动程序引起的。 无论是NVideo还是ATI都得到了错误的结果,但我忘记了哪些。
它可以在笔记本电脑和普通电脑上重现。
那么:您使用的视频卡和驱动程序是什么?
- 的Jeroen
答案 1 :(得分:2)
我一直在使用图形库(AggPas)来帮助绘制图形,我注意到的一件事是我总是需要一行Bitmap.PixelFormat = pf32bit
来绘制透明度。
说过我使用AggPas库中的TransformImage将透明背景的Image复制到另一个,而AggPas只接受pf24bit或pf32bits作为Pixel格式(否则它不会附加到位图)
答案 2 :(得分:1)
我会为您创建的每个位图明确地将位图格式设置为pf32bit,以确保问题不会将颜色从32位转换为16位(如果这是位图的本机视频分辨率被创建),这可能会影响透明度作品。另外,我有更好的运气,专门设置过去的透明度颜色。
另一个选择 - 从长远来看可能是更好的选择 - 是在图像上设置Alpha通道(即使用PNG文件),并使用GDI函数AlphaBlend()绘制图形。