views:

97

answers:

3

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. 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)

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..

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. 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.

this seems to be a bit of a failure due to the fact that the Timage.Transparent property was 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.

on Nvidia cards it takes it as PF32bit and treats null as transparent.

the obvious way to get around that woulf be to set the bitmaptype to PF32bit, but that does still not work. 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. all canvas drawing fuctions 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?

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.

Anyone have any solutions or ideas?

Thanks in Advance

Arthur Gibbs

+2  A: 

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.

It could be reproduced on both laptops and regular PC's.

So: what video cards and drivers do you use?

--jeroen

Jeroen Pluimers
This seems to be the issue, Upon investigation, some machines with same colour depth as working bachines dont work, and the colours it fails to display include black on white. but when i looked at video drivers i found all machines that worked had Nvidia drivers/cards and all machines that didnt had ATI. is there any way i can make stuff worK?
Arthur
@Arthur: back then, I didn't find a solution to make it work. But then the client moved away from the ATI based machines, so the problem solved itself.
Jeroen Pluimers
+1  A: 

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.

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)

JamesB
+1  A: 

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. 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.

GrandmasterB