Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Di Jul 15, 2025 13:03

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 6 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Komponente: OpenGL Instabil
BeitragVerfasst: So Nov 21, 2010 16:34 
Offline
DGL Member

Registriert: Fr Mai 14, 2010 08:34
Beiträge: 54
Guten Tag!

Ich habe bereits für ein Projekt einen OpenGL rendering context auf ein TPanel gesetzt. Jetzt will ich eine eigene Komponente schreiben. Hier das Grundgerüst (sollte mit dem Delphi-OpenGL-Header gecopypastet laufen):
Code:
unit PanelOpenGL;

interface

uses
  SysUtils, Classes, Controls, ExtCtrls, dglOpenGL, Windows, Graphics, Forms;

type
  TPanelOpenGL = class(TPanel)
  private
    { Private declarations }
    HandleTemp : HWND;
    procedure IdleHandler(Sender: TObject; var Done: Boolean);
  protected
    { Protected declarations }
    procedure Loaded; override;
    procedure Resize; override;
  public
    { Public declarations }
    DC : HDC;
    RC : HGLRC;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    { Published declarations }
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Samples', [TPanelOpenGL]);
end;

constructor TPanelOpenGL.Create(AOwner: TComponent);
begin
  Inherited;
  DoubleBuffered := true;
  Color:=clWhite;
  ShowCaption:=false;
end;

destructor TPanelOpenGL.Destroy;
begin
  if DC<>0 then begin
    DeactivateRenderingContext;
    DestroyRenderingContext(RC);
    ReleaseDC(HandleTemp, DC);
  end;
  Inherited;
end;

procedure TPanelOpenGL.IdleHandler(Sender: TObject; var Done: Boolean);
begin
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity;
  //Todo: Render
  SwapBuffers(DC);
  Done:=false;
end;

procedure TPanelOpenGL.Loaded;
begin
  inherited;
  HandleTemp:=Handle;
  DC:= GetDC(Handle);
  if not InitOpenGL then raise Exception.Create('Fehler beim Laden von OpenGL');;
  RC:= CreateRenderingContext(DC,[opDoubleBuffered],32,24,0,0,0,0);
  ActivateRenderingContext(DC, RC);
  Application.OnIdle := IdleHandler;
  glClearColor(0,0,0,0);
  Resize;
end;

procedure TPanelOpenGL.Resize;
begin
 inherited;
 if DC<>0 then begin
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity;
    glViewport(0, 0, Width, Height);
    glOrtho(0,Width,0,Height,0,1);
 end;
end;

end.


Soweit funktioniert auch alles (sollte im obigen Fall das Panel schwarz zeichnen). Nun schmiert Delphi selber aber total häufig ab, wenn ich die Komponente zum testen auf ein Form setze und das Programm ausführe. Und das in Delphi 2010 und Delphi XE. Bitte helft mir ;)

Grüße

EDIT:
Fehlermeldungen gibt es verschiedene. Ich kann den Fehler leider nicht reproduzieren. Ein Meldung ist z.B.:
Code:
(00001A6F){            } [0F4B2A6F]
[2102FD16]{designide150.bpl} DeskUtil.SetFocusHook (Line 454, "DeskUtil.pas" + 4) + $C
[50282838]{vcl150.bpl  } Controls.TWinControl.WndProc (Line 9831, "Controls.pas" + 144) + $6
[50359871]{vcl150.bpl  } Forms.TApplication.Idle (Line 10341, "Forms.pas" + 7) + $1C
[5035993C]{vcl150.bpl  } Forms.TApplication.Idle (Line 10374, "Forms.pas" + 40) + $16
[50358B4F]{vcl150.bpl  } Forms.TApplication.HandleMessage (Line 9790, "Forms.pas" + 1) + $11
[50358E6D]{vcl150.bpl  } Forms.TApplication.Run (Line 9927, "Forms.pas" + 26) + $3
[004ACCE2]{bds.exe     } bds.bds (Line 201, "" + 8) + $FFFB


Zuletzt geändert von j0hnnie am So Nov 21, 2010 16:47, insgesamt 2-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Komponente: OpenGL Instabil
BeitragVerfasst: So Nov 21, 2010 16:44 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Wenn du erreignisse nutzt wie z.b. OnResize dann musst du immer darauf achten,
das kein GL code verwendet wird, wenn die Komponente im Design oder Zerstörungsmodus ist.
Genaugenommen darfst du keinen Code verwenden der zur Laufzeit benutzt wird, z.b. laden von Resourcen oder son kram.

ComponentState ist das zauberwort hier.
Einfach mal googlen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Komponente: OpenGL Instabil
BeitragVerfasst: So Nov 21, 2010 16:50 
Offline
DGL Member

Registriert: Fr Mai 14, 2010 08:34
Beiträge: 54
Cool. Danke für die fixe Antwort. Aber überprüfe ich nicht mit DC<>0, ob ein OpenGL-DC besteht. Das DC erzeuge ich ja in Loaded, was ja erst zur runtime läuft, oder lieg ich da falsch?

Mit dem ComponentState klingt interessant. Ab welchem ComponentState darf denn erst OpenGL-Code folgen?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Komponente: OpenGL Instabil
BeitragVerfasst: So Nov 21, 2010 17:02 
Offline
DGL Member

Registriert: Fr Mai 14, 2010 08:34
Beiträge: 54
Ok ich habe jetzt mal zum testen den Code von Resize auskommentiert. Mit FPS ausgabe sieht das Ganze jetzt so aus:

Code:
unit PanelOpenGL;

interface

uses
  SysUtils, Classes, Controls, ExtCtrls, dglOpenGL, Windows, Graphics, Forms;

type
  TPanelOpenGL = class(TPanel)
  private
    { Private declarations }
    StartTime, TimeCount, FrameCount, DrawTime : Cardinal;
    HandleTemp : HWND;
    procedure IdleHandler(Sender: TObject; var Done: Boolean);
  protected
    { Protected declarations }
    procedure Loaded; override;
    procedure Resize; override;
  public
    { Public declarations }
    DC : HDC;
    RC : HGLRC;
    FPS : Cardinal;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    { Published declarations }
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Samples', [TPanelOpenGL]);
end;

constructor TPanelOpenGL.Create(AOwner: TComponent);
begin
  Inherited;
  DoubleBuffered := true;
  Color:=clWhite;
  ShowCaption:=false;
end;

destructor TPanelOpenGL.Destroy;
begin
  if DC<>0 then begin
    DeactivateRenderingContext;
    DestroyRenderingContext(RC);
    ReleaseDC(HandleTemp, DC);
  end;
  Inherited;
end;

procedure TPanelOpenGL.IdleHandler(Sender: TObject; var Done: Boolean);
begin
  StartTime:= GetTickCount;
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity;
  //Todo: Render
  SwapBuffers(DC);
  DrawTime:= GetTickCount - StartTime;
  Inc(TimeCount, DrawTime);
  Inc(FrameCount);
  if TimeCount >= 1000 then begin
    FPS:= FrameCount;
    TimeCount:= TimeCount - 1000;
    FrameCount:= 0;
  end;
  Done:=false;
end;

procedure TPanelOpenGL.Loaded;
var
  r, g, b: Single;
begin
  inherited;
  HandleTemp:=Handle;
  DC:= GetDC(Handle);
  if not InitOpenGL then raise Exception.Create('Fehler beim Laden von OpenGL');;
  RC:= CreateRenderingContext(DC,[opDoubleBuffered],32,24,0,0,0,0);
  ActivateRenderingContext(DC, RC);
  Application.OnIdle := IdleHandler;
  glClearColor(0,0,0,0);
  Resize;
end;

procedure TPanelOpenGL.Resize;
begin
 inherited;
 {if DC<>0 then begin
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity;
    glViewport(0, 0, Width, Height);
    glOrtho(0,Width,0,Height,0,1);
 end;}
end;

end.


Leider ist Delphi immer noch am abstürzen. Jetzt kam wieder eine Fehlermeldung, die auch schon vorher kam:

Code:
(0F6D1A58){bds.exe     } [0F6D2A58]
[2121E3CA]{vclide150.bpl} IDEVirtualTrees.TBaseVirtualTree.WMNCHitTest (Line 16688, "IDEVirtualTrees.pas" + 2) + $44
[5027DF74]{vcl150.bpl  } Controls.TControl.WndProc (Line 7074, "Controls.pas" + 91) + $6
[50359871]{vcl150.bpl  } Forms.TApplication.Idle (Line 10341, "Forms.pas" + 7) + $1C
[5035993C]{vcl150.bpl  } Forms.TApplication.Idle (Line 10374, "Forms.pas" + 40) + $16
[50358B4F]{vcl150.bpl  } Forms.TApplication.HandleMessage (Line 9790, "Forms.pas" + 1) + $11
[50358E6D]{vcl150.bpl  } Forms.TApplication.Run (Line 9927, "Forms.pas" + 26) + $3
[004ACCE2]{bds.exe     } bds.bds (Line 201, "" + 8) + $FFFB


EDIT: Ach ja. Nach erscheinen des Fehlers, kommt ein Dialog mit der Fehlermeldung (mit "Details" und "Senden"). Die Buttons lassen sich dort nicht mehr der Maus anklicken, sondern nur mit der Tastatur aktivieren.

Wenn ich nach auftreten des Fehlers Delphi neustarte und die Komponente deinstalliere kommt eine "Delphi privileged instruction"
Code:
(00001A33){            } [0F4B2A33]
[5027DF74]{vcl150.bpl  } Controls.TControl.WndProc (Line 7074, "Controls.pas" + 91) + $6
[50359871]{vcl150.bpl  } Forms.TApplication.Idle (Line 10341, "Forms.pas" + 7) + $1C
[5035993C]{vcl150.bpl  } Forms.TApplication.Idle (Line 10374, "Forms.pas" + 40) + $16
[50358B4F]{vcl150.bpl  } Forms.TApplication.HandleMessage (Line 9790, "Forms.pas" + 1) + $11
[50358E6D]{vcl150.bpl  } Forms.TApplication.Run (Line 9927, "Forms.pas" + 26) + $3
[004ACCE2]{bds.exe     } bds.bds (Line 201, "" + 8) + $FFFB

Erst wenn ich Delphi dann nochmal neustarte und die Komponente neu auf ein Form setze, dann tritt der Fehler vorübergehend nicht mehr auf.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Komponente: OpenGL Instabil
BeitragVerfasst: So Nov 21, 2010 18:10 
Offline
DGL Member

Registriert: Fr Mai 14, 2010 08:34
Beiträge: 54
Ok, ich habe jetzt nach und nach versucht die Fehlerquelle einzugrenzen. Also wenn ich das OnIdle event weglasse, läuft alles stabil. Aber wie kriege ich jetzt aus der Komponente heraus das OnIdle Event der Anwendung, ohne das Delphi daurend abstürzt?

Also schon mit
Code:
procedure TPanelOpenGL.IdleHandler(Sender: TObject; var Done: Boolean);
begin
  Done:=false;
end;


scheint er nicht klar zu kommen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Komponente: OpenGL Instabil
BeitragVerfasst: So Nov 21, 2010 18:30 
Offline
DGL Member

Registriert: Fr Mai 14, 2010 08:34
Beiträge: 54
Ich glaube ich habs hinbekommen.

Habe ein TApplicationEvents erzeugt und das OnIdle-Event davon benutzt. Seltsamerweise ging es über Appilcation.OnIdle nicht.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 6 Beiträge ] 
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.009s | 14 Queries | GZIP : On ]