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

Aktuelle Zeit: Sa Aug 13, 2022 16:22

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



Ein neues Thema erstellen Auf das Thema antworten  [ 1 Beitrag ] 
Autor Nachricht
BeitragVerfasst: Di Apr 26, 2022 19:07 
Offline
DGL Member

Registriert: Di Apr 26, 2022 15:52
Beiträge: 1
Programmiersprache: Delphi 11.1
Hallo OpenGL-Profis,

ich hoffe, jemand hier im Forum hat eine Idee zu diesem Problem... Ich habe das Problem auch bei delphipraxis.net eingestellt (https://www.delphipraxis.net/210444-windows-energieoptionen-monitor-aus-opengl-friert-ein.html#post1505122) , aber hier ist es wahrscheinlich auch gut aufgehoben :-)

Nachdem Windows aufgrund der Energieoptionen den Monitor ausgeschaltet hat, und ich ihn mit Mausbewegung wieder wecke, kommt es auf der Hälfte der Rechner, mit denen ich es probiert habe, vor, das die OpenGL-Ausgabe hängt, während Ausgaben in z.B. die Titelzeile des Fensters weiterhin stattfinden. Nach einigen Sekunden bis Minuten läuft die Grafikausgabe dann einfach so weiter.

Habe das Problem auf ein kleines Testprogramm reduziert, daß lediglich ein Dreieck dreht und bei den Testrechnern die "Monitor ausschalten nach"-zeit auf 1 Minute gesetzt.

UHD530 Win10 hängt
UHD630 Win11 läuft
AMD 6900M Win10 hängt
Nvidia GTX980M Win 10 läuft

Das ganze ist absolut reproduzierbar.

Hat jemand hier im Forum das auch schon erlebt und eine Idee, was man da tun kann?

Das folgende einfach auf ein leeres Form1 werfen reicht, keine weiteren Komponenten erforderlich:

Code:
  1. unit Unit1;
  2.  
  3. interface
  4.  
  5. {$DEFINE DGLOGL}
  6.  
  7. uses
  8.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, System.UITypes,
  9.   Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls,
  10.   {$IFDEF DGLOGL}dglOpenGL{$ELSE}Winapi.OpenGL, Winapi.OpenGLext{$ENDIF};
  11.  
  12. type
  13.   TOpenGLContext = class
  14.   public
  15.     Control: TControl;
  16.     DevCon: HDC;
  17.     RenderCon: HGLRC;
  18.     class procedure SetViewport(ClientWidth, ClientHeight: Integer);
  19.     procedure MakeCurrent;
  20.   end;
  21.  
  22.   TglPanel = class(TPanel)
  23.   public
  24.     OnPaint: TNotifyEvent;
  25.     procedure CreateRenderContext(oglc: TOpenGLContext); //var DeviceContext: HDC; var RenderingContext: HGLRC);
  26.   protected
  27.     procedure WMEraseBkgnd(var msg: TWmEraseBkgnd); message WM_ERASEBKGND;
  28.     procedure WMPaint(var msg: TWMPaint); message WM_PAINT;
  29.   end;
  30.  
  31.   TForm1 = class(TForm)
  32.     Panel1: TPanel;
  33.     procedure FormCreate(Sender: TObject);
  34.     procedure FormResize(Sender: TObject);
  35.   private
  36.     HoldError: Boolean;
  37.     procedure DreieckMalen(Sender: TObject);
  38.     procedure glPanelMouseMove(Sender: TObject; Shift: TShiftState; X,
  39.       Y: Integer);
  40.   public
  41.     fglPanel: TglPanel;
  42.     procedure IdleHandler(Sender: TObject; var Done: Boolean); // GL zeichnen
  43.   end;
  44.  
  45. var
  46.   Form1: TForm1;
  47.   OpenGLContextMain: TOpenGLContext;
  48.  
  49. {$IFNDEF DGLOGL}
  50. type
  51.   TRCOptions = set of (opDoubleBuffered, opGDI, opStereo);
  52. function CreateRenderingContext(DC: HDC; Options: TRCOptions; ColorBits, ZBits, StencilBits, AccumBits, AuxBuffers: Integer; Layer: Integer): HGLRC;
  53. {$ENDIF}
  54.  
  55. implementation
  56.  
  57. {$R *.dfm}
  58.  
  59. {$IFNDEF DGLOGL}
  60. function CreateRenderingContext(DC: HDC; Options: TRCOptions; ColorBits, ZBits, StencilBits, AccumBits, AuxBuffers: Integer; Layer: Integer): HGLRC;
  61. const
  62.   MemoryDCs = [OBJ_MEMDC, OBJ_METADC, OBJ_ENHMETADC];
  63. var
  64.   pfd: TPixelFormatDescriptor;
  65.   PixelFormat: Integer;
  66.   AType: DWORD;
  67. begin
  68.   System.FillChar(pfd, SizeOf(pfd), 0);
  69.  
  70.   pfd.nSize := SizeOf(pfd);
  71.   pfd.nVersion := 1;
  72.   pfd.dwFlags := PFD_SUPPORT_OPENGL;
  73.  
  74.   AType := GetObjectType(DC);
  75.  
  76.   if (AType = 0) then
  77.     RaiseLastOSError;
  78.  
  79.   if (AType in MemoryDCs) then
  80.     pfd.dwFlags := pfd.dwFlags or PFD_DRAW_TO_BITMAP
  81.   else
  82.     pfd.dwFlags := pfd.dwFlags or PFD_DRAW_TO_WINDOW;
  83.  
  84.   if opDoubleBuffered in Options then pfd.dwFlags := pfd.dwFlags or PFD_DOUBLEBUFFER;
  85.   if opGDI in Options then pfd.dwFlags := pfd.dwFlags or PFD_SUPPORT_GDI;
  86.   if opStereo in Options then pfd.dwFlags := pfd.dwFlags or PFD_STEREO;
  87.  
  88.   pfd.iPixelType := PFD_TYPE_RGBA;
  89.   pfd.cColorBits := ColorBits;
  90.   pfd.cDepthBits := zBits;
  91.   pfd.cStencilBits := StencilBits;
  92.   pfd.cAccumBits := AccumBits;
  93.   pfd.cAuxBuffers := AuxBuffers;
  94.  
  95.   if (Layer = 0) then
  96.     pfd.iLayerType := PFD_MAIN_PLANE
  97.   else
  98.     if (Layer > 0) then
  99.       pfd.iLayerType := PFD_OVERLAY_PLANE
  100.     else
  101.       pfd.iLayerType := Byte(PFD_UNDERLAY_PLANE);
  102.  
  103.   PixelFormat := ChoosePixelFormat(DC, @pfd);
  104.  
  105.   if PixelFormat = 0 then
  106.     RaiseLastOSError;
  107.  
  108.   if GetPixelFormat(DC) <> PixelFormat then
  109.     if not SetPixelFormat(DC, PixelFormat, @pfd) then
  110.       RaiseLastOSError;
  111.  
  112.   DescribePixelFormat(DC, PixelFormat, SizeOf(pfd), pfd);
  113.  
  114.   Result := wglCreateContext(DC);
  115.  
  116.   if Result = 0 then
  117.     RaiseLastOSError;
  118. end;
  119. {$ENDIF}
  120.  
  121. { TglPanel }
  122. procedure TglPanel.WMEraseBkgnd(var msg: TWMEraseBkgnd);
  123. begin
  124.   msg.Result := 1;
  125. end;
  126.  
  127. procedure TglPanel.WMPaint(var msg: TWMPaint);
  128. var
  129.   PS: TPaintStruct;
  130. begin
  131.   BeginPaint(Handle, PS);
  132.  
  133.   if Assigned(OnPaint) then
  134.     OnPaint(Self);
  135.  
  136.   EndPaint(Handle, PS);
  137.  
  138.   msg.Result := 0;
  139. end;
  140.  
  141. procedure TglPanel.CreateRenderContext(oglc: TOpenGLContext); //var DeviceContext: HDC; var RenderingContext: HGLRC);
  142. begin
  143.   try
  144.     oglc.DevCon := GetDC(Self.Handle);
  145.     oglc.RenderCon := CreateRenderingContext(oglc.DevCon, [opDoubleBuffered], 32, 24, 8, 0, 0, 0);
  146.  
  147.     wglMakeCurrent(oglc.DevCon, oglc.RenderCon);
  148.  
  149.     {$IFNDEF DGLOGL}
  150.     Winapi.OpenGLExt.InitOpenGLext; // Darf erst hier, nach wglMakeCurrent(), aufgerufen werden... Für z.B. MultiTexturing erforderlich...
  151.     {$ELSE}
  152.     ActivateRenderingContext(oglc.DevCon, oglc.RenderCon);
  153.     {$ENDIF}
  154.  
  155.     glEnable(GL_DEPTH_TEST);
  156.     glDepthFunc(GL_LESS);
  157.     glEnable(GL_TEXTURE_2D);
  158.   except
  159.     MessageDlg('Can''t create OpenGL Rendering Context!', mtError, [mbOK], 0);
  160.   end;
  161. end;
  162.  
  163. class procedure TOpenGLContext.SetViewport(ClientWidth, ClientHeight: Integer);
  164. begin
  165.   glViewport(0, 0, ClientWidth, ClientHeight);
  166.  
  167.   glMatrixMode(GL_PROJECTION);
  168.   glLoadIdentity;
  169.  
  170.   glOrtho(-ClientWidth / 2, ClientWidth / 2,
  171.           -ClientHeight / 2, ClientHeight / 2,
  172.           0, 100);
  173.  
  174.   glMatrixMode(GL_MODELVIEW);
  175.   glLoadIdentity;
  176. end;
  177.  
  178. procedure TOpenGLContext.MakeCurrent;
  179. begin
  180.   wglMakeCurrent(DevCon, RenderCon);
  181.  
  182.   TOpenGLContext.SetViewport(Control.Width, Control.Height);
  183.  
  184.   glDisable(GL_BLEND);
  185.   glClearColor(0, 0, 0, 0);
  186.   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);// or GL_STENCIL_BUFFER_BIT);
  187. end;
  188.  
  189. procedure TForm1.FormCreate(Sender: TObject);
  190. begin
  191.   OpenGLContextMain := TOpenGLContext.Create;
  192.  
  193.   fglPanel := TglPanel.Create(Self);
  194.   fglPanel.Parent := Self;
  195.   fglPanel.Name := 'glPanel';
  196.   fglPanel.Color := clBlack;
  197.   fglPanel.ParentColor := FALSE;
  198.   fglPanel.ParentBackground := FALSE;
  199.   fglPanel.Align := alClient;
  200.   fglPanel.CreateRenderContext(OpenGLContextMain);
  201.   fglPanel.OnPaint := DreieckMalen;
  202.   fglPanel.OnMouseMove := glPanelMouseMove;
  203.  
  204.   OpenGLContextMain.Control := fglPanel;
  205.  
  206.   Application.OnIdle := IdleHandler;
  207. end;
  208.  
  209. procedure TForm1.FormResize(Sender: TObject);
  210. var
  211.   Done: Boolean;
  212. begin
  213.   IdleHandler(Sender, Done);
  214. end;
  215.  
  216. procedure TForm1.IdleHandler(Sender: TObject; var Done: Boolean);
  217. begin
  218.   fglPanel.Invalidate; // fglPanel.onPaint = DreieckMalen zeichnet für uns...
  219.   sleep(1);
  220.   Done := FALSE;
  221. end;
  222.  
  223. procedure TForm1.glPanelMouseMove(Sender: TObject; Shift: TShiftState; X,
  224.   Y: Integer);
  225. begin
  226. (*
  227.   sinnlos, bringt auch nix.
  228.   PostMessage(Self.Handle, WM_MOVE, 0, $00010001);
  229.   PostMessage(Self.Handle, WM_MOVE, 0, NativeInt($FFFFFFFF));
  230. *)
  231. end;
  232.  
  233. procedure TForm1.DreieckMalen(Sender: TObject);
  234. var
  235.   i: Cardinal;
  236.   x: Array [0..2] of Double;
  237.   y: Array [0..2] of Double;
  238.   e: GLenum;
  239. begin
  240.  // OpenGLContextMain.MakeCurrent;
  241.  
  242.   // Mal nur so probieren:
  243.   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);// or GL_STENCIL_BUFFER_BIT);
  244.   glMatrixMode(GL_PROJECTION);
  245.   glLoadIdentity;
  246.  
  247.   glOrtho(-ClientWidth / 2, ClientWidth / 2,
  248.           -ClientHeight / 2, ClientHeight / 2,
  249.           0, 100);
  250.  
  251.   glMatrixMode(GL_MODELVIEW);
  252.   glLoadIdentity;
  253.  
  254.   // Drei Punkte rumwirbeln
  255.   for i := 0 to 2 do
  256.   begin
  257.     x[i] := 400 * sin((GetTickCount+(i*1000)) / 500);
  258.     y[i] := 300 * cos((GetTickCount+(i*1000)) / 700);
  259.   end;
  260.  
  261.   glTranslated(0, 0, -10);
  262.  
  263.   // und Dreieck füllen
  264.   glDisable(GL_TEXTURE_2D);
  265.   glBegin(GL_TRIANGLES);
  266.     glColor4f(1.0, 0.0, 0.0, 1.0);
  267.     glVertex2f(x[0], y[0]);
  268.     glColor4f(0.0, 1.0, 0.0, 1.0);
  269.     glVertex2f(x[1], y[1]);
  270.     glColor4f(0.0, 0.0, 1.0, 1.0);
  271.     glVertex2f(x[2], y[2]);
  272.   glEnd();
  273.  
  274.   if not SwapBuffers(OpenGLContextMain.DevCon) then
  275.   begin
  276.     Caption := 'SwapBuffers fehlgeschlagen: ' + GetLastError().ToString;
  277.     HoldError := TRUE; // einmal Error, immer Error anzeigen.
  278.   end;
  279.  
  280.   if not HoldError then
  281.   begin
  282.     e := glGetError();
  283.     if e <> GL_NO_ERROR then
  284.     begin
  285.       Caption := gluErrorString(e);
  286.       HoldError := TRUE; // einmal Error, immer Error anzeigen.
  287.     end;
  288.   end;
  289.  
  290.   if not HoldError then
  291.     Form1.Caption := TimeToStr(Now); // Uhrzeit als WindowTitle läuft weiter
  292. end;
  293.  
  294. end.


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 11 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.016s | 17 Queries | GZIP : On ]