Entwickler-Ecke

Multimedia / Grafik - Durchsichtiges Viereck in hohen Auflösungen flüssig zeichnen


Tony-S - Mi 23.03.11 22:28
Titel: Durchsichtiges Viereck in hohen Auflösungen flüssig zeichnen
Hallo Forum, der Titel sagt es ja schon fast,
ich zeichne ein durchsichtiges Viereck auf eine transparente Form.
Das klappt auf einem Bildschirm, mit einer nicht all zu großen Auflösung auch ganz gut,
in hohen Auflösungen stockt das aber ungemein. Gibt es zu der Art und Weise wie ich es gemacht hab eine Alternative?


Delphi-Quelltext
1:
2:
3:
4:
5:
// var global
Viereck, Temp:  TBitmap;
InMove:         Boolean;
MausPos:        TPoint;
X1, X2, Y1, Y2: Integer;



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
procedure TfrmDraw.FormCreate(Sender: TObject);
var
Breite, Hoehe: Integer;
begin
Breite            := Screen.DesktopWidth;
Hoehe             := Screen.DesktopHeight;

  with frmDraw do
  begin
  Left  := 0;
  Top   := 0;

  ClientWidth       := Breite;
  ClientHeight      := Hoehe;

  imgDisplay.Width  := Breite;
  imgDisplay.Height := Hoehe;
  end;

  Viereck         := TBitmap.Create;
  Viereck.Width   := Breite;
  Viereck.Height  := Hoehe;

  Temp            := TBitmap.Create;
  Temp.Width      := Breite;
  Temp.Width      := Hoehe;
end;


// Setzen der Startposition

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure TfrmDraw.imgDisplayMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if shift = [ssleft] then
  begin
  InMove := True;

  GetCursorPos(MausPos);
  X1  :=  MausPos.X;
  x2  :=  Mauspos.y;
  end;
end;


// Zeichnen des Vierecks
// imgDisplay ist die Image-Komponente
// TransparentColor der frmDraw-Form ist: Rot
// AlphaBlendValue ist: 150

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
procedure TfrmDraw.imgDisplayMouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer);
begin
  if InMove then
  begin
  GetCursorPos(MausPos);

  Y1  :=  MausPos.X;
  Y2  :=  Mauspos.y;

        with imgDisplay.Canvas do
        begin
        Draw(00, Temp);
        Pen.Color   := clBlack;
        Brush.color := clRed;
        Brush.style := bsSolid;

        fillrect (rect(x1, x2, y1, y2));
        Rectangle(rect(x1, x2, y1, y2));
        end;
  end;
end;


// Zeichnen beenden

Delphi-Quelltext
1:
2:
3:
4:
5:
procedure TfrmDraw.imgDisplayMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
InMove := False;
end;


Das ist eigentlich schon alles ... gibt es eine alternative zu der Variante das ich eine temporäre Bitmap zum überzeichnen nehme?
Denn so wird ja in jedem MouseMove der komplette Bildschirminhalt neugezeichnet.

Danke für eure Hilfe.

Mfg Tony-S


BenBE - Do 24.03.11 21:06

Die GDI nutzt unter alten Windows-Versionen keine Hardware-Beschleunigung.

Was du tun kannst ist (ab Vista IMHO möglich), die nen Desktop-Kontext mit OpenGL/DirectX holen und dann das Rechteck mit OpenGL/DirectX über den Desktop-Kontext drübermalen.


jaenicke - Do 24.03.11 22:19

Wichtig kann auch sein:
Speichere im Move die vorherige Position und zeichne nur neu, wenn sich die Position auch geändert hat. Leider scheint MouseMove ansonsten unnötig oft aufgerufen zu werden.

Hardwarebeschleunigung beim normalen Zeichnen in 2D funktioniert leider unter Vista nicht, erst unter Windows 7. Mit Windows 7 und Delphi 2010 oder XE funktioniert das auch direkt.

Mit Hilfe von DirectX oder OpenGL sollte es aber dennoch auch unter Vista schneller gehen, denn die Oberfläche wird ab Vista von der Grafikkarte gerendert, wenn man Aero aktiviert hat.