4

私がやろうとしていること

複数のグラフィックスを Timage に描画しようとしています。描画するこれらのグラフィックスは、フードフィルと線を含む順序付けられたレイヤーで構成されています。順序付けとダブル バッファリングを確実にするために、複数のバッファを使用します。

私がしていること

    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;

私が期待すること

各画像オブジェクトが互いの上にレイヤー化され、各画像レイヤーがそのレイヤーの完全な画像になることを期待しています。私の例では、後ろに旗が付いたロボットです。最初に旗が描かれ、次にロボットが描かれます。

私が得るもの(PC上)

PC では、期待どおりの結果が得られ、すべてが正しいように見えます。

私が得るもの(ラップトップ上)

ほぼすべてのラップトップと一部の PC では、ロボットしか表示されません。フラグを描いているかどうかを確認するためにいくつかのステートメントを入れました。ゲームは正しい方法でフラグとやり取りすることさえできます。さらに調査したところ、「描画シーン」で描画された最後の画像のみが表示され、画像がキャンバス全体に直接描画されたときにすべてが表示されたことがわかりました(これは、塗りつぶしレイヤーが重なっている理由で実行できません)

私が考えていることは起こっている

だから私が推測したのは、TimageのTimage.transparentプロパティが機能していないか、一部のマシンで異なる方法で計算されているということです..

これを証明するためにテストを行い、キャンバスを赤くしました。次に、そのキャンバスに 0,0 i Timage でプロパティ transparent=true を描画し、赤いキャンバスの真ん中にドットを 1 つだけ配置しました。その結果、真ん中に点のある白いキャンバスができました。

非常に基本的なグラフィックス ドライバーを搭載したマシンは null または透明を白として扱い、より強力なマシンは null または透明を透明として扱うようであると推測しています。

Timage.Transparent プロパティが true であったため、これは少し失敗したようです。

編集:更新!!! ATI グラフィックス カードでは、色が「null」の場合、PF24bit の形式で解釈されるため、アルファ チャネルも透明度もありません。

Nvidia カードでは、PF32bit として取り、null を透明として扱います。

この問題を回避する明白な方法は、bitmaptype を PF32bit に設定することですが、それでもうまくいきません。次に、おそらくそれでは不十分であり、背景がnullのままではなく透明に設定されていることを確認する必要があると想定しました..しかし、Timage内にアルファで色を設定するためのツール(私が見ることができる)はありません. すべてのキャンバス描画関数は、RGB 24 ビットの Tcolor を必要とし、RGBA 32 ビットの TcolorRef のみが必要です....アルファ 0 で描画する方法はありますか?

私が知る必要があると思うこと

透明なプロパティをすべてのマシンで強制的に機能させる方法、またはラップトップを白として透明に貼り付けないようにする方法、または同じ結果を達成する方法。

誰にも解決策やアイデアはありますか?

4

3 に答える 3

2

過去(数年前)に、さまざまなマシンで同様の動作を見てきました。

これらは、異なるビデオ カードとドライバーが原因でした。NVideo か ATI のどちらかで間違った結果が得られましたが、どれか忘れてしまいました。

ラップトップと通常の PC の両方で再生できます。

では、どのビデオカードとドライバーを使用していますか?

--jeroen

于 2010-07-16T12:01:18.700 に答える
2

グラフィックスの描画を支援するためにグラフィックス ライブラリ (AggPas) を使用してきましたが、気づいたことの 1 つは、Bitmap.PixelFormat = pf32bit透明度を描画するために常に線が必要だということです。

AggPas ライブラリの TransformImage を使用して、背景が透明な画像を別の画像にコピーすると言いましたが、AggPas はピクセル形式として pf24bit または pf32bits のみを受け入れます (それ以外の場合はビットマップに添付されません)。

于 2010-07-16T12:32:10.323 に答える
1

作成するビットマップごとにビットマップ形式を明示的に pf32bit に設定して、問題が 32 ビットから 16 ビットに色を変換しないようにします (それが作成されるビットマップのネイティブ ビデオ解像度である場合)。また、過去に透明色を具体的に設定した方が幸運でした。

別のオプション - おそらく長期的にはより良い方法は、代わりに画像にアルファ チャネルを設定 (つまり、PNG ファイルを使用) し、GDI 関数 AlphaBlend() を使用してグラフィックを描画することです。

于 2010-07-16T20:31:36.807 に答える