简体   繁体   English

Delphi 7中笔记本电脑上的Timage透明胶片

[英]Timage Transparencies on laptops in Delphi 7

WHAT I AM TRYING TO DO 我在做什么

I am trying to draw multiple graphics to a Timage, These graphics that i Draw consist of ordered layers with Foodfills and lines. 我正在尝试将多个图形绘制到Timage中,这些我绘制的图形由带有Foodfills和线条的有序图层组成。 I use multiple buffers to ensure ordering and double buffering. 我使用多个缓冲区来确保排序和双缓冲。

WHAT I AM DOING 我在做什么

    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;

WHAT I EXPECT 我期待什么

I expect to see each image object layered on top of one another with each image layer being the complete image for that layer. 我希望看到每个图像对象彼此叠加,每个图像层都是该图层的完整图像。 im my example it is a robot with a flag behind it. 我的例子是它背后有一面旗帜的机器人。 the flag is drawn first and then the robot. 首先绘制标志然后绘制机器人。

WHAT I GET(on a pc) 我得到什么(在电脑上)

on a pc i get what i expect and all appears to be correct. 在电脑上,我得到了我所期待的,似乎都是正确的。

WHAT I GET(on a laptop) 我得到了什么(在笔记本电脑上)

On a nearly every laptop and some pc's i only see the robot. 在几乎每台笔记本电脑和一些电脑上我只能看到机器人。 i put in some statments to see if it is drawing the flag and it does. 我提出了一些判断,看它是否正在绘制旗帜,它确实如此。 the game can even interact with the flag in the correct manner. 游戏甚至可以以正确的方式与旗帜互动。 further investigation showed me that it was only showing the last image drawn my "drawscene", and when images were drawn directly to the wholecanvas everthing apeared(this cannot be done for overlapping fill layers reasons) 进一步的调查显示,它只是显示最后一个图像绘制了我的“drawcene”,并且当图像被直接绘制到wholecanvas everthing apeared时(这不能用于重叠填充层的原因)

WHAT I THINK IS HAPPENING 我认为是什么发生了

so what i deduced is that the Timage.transparent property of the Timage is not working or is being computed differently on some machines.. 所以我推断出Timage的Timage.transparent属性不起作用或在某些机器上的计算方式不同。

i did a test to prove this and made a canvas red. 我做了一个测试,以证明这一点,并使帆布红色。 then to that canvas i drew at 0,0 i Timage with property transparent=true with just one dot in the middle to the red canvas. 然后到画布我画了0,0 i Timage,属性transparent = true,红色画布中间只有一个点。 the resuly was a white canvas with a dot in the middle. 那件商品是一块白色的帆布,中间有一个圆点。

I am assuming and findings indicate that machines with very basic graphics drivers seem to treat null or transparent as white where as more powerful machines seem to treat null or transparent as transparent. 我假设并且调查结果表明,具有非常基本图形驱动程序的计算机似乎将null或透明视为白色,而更强大的计算机似乎将null或透明视为透明。

this seems to be a bit of a failure due to the fact that the Timage.Transparent property was true. 由于Timage.Transparent属性为true,这似乎有点失败。

EDIT: UPDATE!!! 编辑:更新!!! It would appear to be that on ATI graphics cards if a colour is "null" then it is interpreted in the format of PF24bit and therefore no alpha channel and no transparency. 看起来在ATI显卡上,如果颜色为“空”,那么它将以PF24bit的格式进行解释,因此没有alpha通道,也没有透明度。

on Nvidia cards it takes it as PF32bit and treats null as transparent. 在Nvidia卡上它将它作为PF32bit并将null视为透明。

the obvious way to get around that woulf be to set the bitmaptype to PF32bit, but that does still not work. 解决这个问题的明显方法是将位图类型设置为PF32bit,但这仍然不起作用。 I then assumed that maybe that is not enough and I should make sure that the background is SET to transparent rather than being left as null.. but there are no tools ( that I can see) inside the Timage to set colour with alpha. 我假设可能这还不够,我应该确保背景设置为透明而不是保留为空...但是在Timage中没有工具(我可以看到)用alpha设置颜色。 all canvas drawing functions require a Tcolor that is RGB 24 bit and ony a TcolorRef with RGBA 32 bit would do.... is there a way of drawing with alpha 0? 所有的画布绘图功能都需要一个RGB 24位的Tcolor和一个带有RGBA 32位的TcolorRef ....有没有一种用alpha 0绘制的方法?

WHAT I THINK I NEED TO KNOW 我认为我需要知道什么

How to force the Transparent property to work on all machines or a way to make laptops not paste in transparent as white Or a way to achieve the same result. 如何强制Transparent属性在所有机器上工作或者使笔记本电脑不以透明方式粘贴为白色或者达到相同结果的方法。

Anyone have any solutions or ideas? 有人有任何解决方案或想法吗?

I've seen similar behaviour on different machines in the past (a few years back). 我在过去(几​​年前)在不同的机器上看到了类似的行为。

They were caused by different video cards and drivers. 它们是由不同的视频卡和驱动程序引起的。 Either the NVideo or the ATI ones were getting the wrong results, but I forgot which ones. 无论是NVideo还是ATI都得到了错误的结果,但我忘记了哪些。

It could be reproduced on both laptops and regular PC's. 它可以在笔记本电脑和普通PC上重现。

So: what video cards and drivers do you use? 那么:你使用什么视频卡和驱动程序?

--jeroen --jeroen

I have been using an Graphics library (AggPas) to help with drawing graphics and one of the things I've noticed is that I always need a line Bitmap.PixelFormat = pf32bit to get it to draw transparancies. 我一直在使用图形库(AggPas)来帮助绘制图形,我注意到的一件事是我总是需要一行Bitmap.PixelFormat = pf32bit来让它绘制透明度。

Having said that I use TransformImage from the AggPas library to copy the Image with a transparent background to another one and AggPas only accepts pf24bit or pf32bits as Pixel formats (otherwise it doesn't attach to the bitmap) 话虽如此,我使用AggPas库中的TransformImage将具有透明背景的Image复制到另一个,而AggPas仅接受pf24bit或pf32bits作为Pixel格式(否则它不会附加到位图)

I would explicitly set the bitmap format to pf32bit for each bitmap you create to ensure the problem isnt converting colors from 32 to 16 bit (if thats the native video resolution of the bitmaps getting created), which might interfere with how the transparency works. 我会为您创建的每个位图显式设置位图格式为pf32bit,以确保问题不会将颜色从32位转换为16位(如果这是位图的本机视频分辨率被创建),这可能会干扰透明度的工作方式。 Also, I've had better luck specifically setting the transparency color in the past. 另外,我有更好的运气,专门设置过去的透明度颜色。

Another option - perhaps a better one in the long run, is to instead set the Alpha Channel on the images (ie, use PNG files), and use the GDI function AlphaBlend() to draw the graphics. 另一种选择 - 从长远来看可能是更好的选择 - 是在图像上设置Alpha通道(即使用PNG文件),并使用GDI函数AlphaBlend()绘制图形。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM