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

Aktuelle Zeit: Di Mai 14, 2024 15:28

Foren-Übersicht » English » English Programming Forum
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 8 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Render From Thread
BeitragVerfasst: Fr Apr 04, 2008 18:18 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jul 01, 2003 18:59
Beiträge: 887
Wohnort: (The Netherlands)
Programmiersprache: fpc/delphi/java/c#
I am trying to do rendering from an thread. Unfortunately all i get is a black screen. I post my code below. Thank for your help in advance.

Code:
  1.  
  2. unit OpenGLTemplateForm;
  3.  
  4. interface
  5.  
  6. uses
  7.  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  8.   StdCtrls, ExtCtrls, ComCtrls, DglOpenGL;
  9.  
  10. type
  11.   TDGLForm = class(TForm)
  12.     procedure FormKeyPress(Sender: TObject; var Key: Char);
  13.     procedure FormCreate(Sender: TObject);
  14.     procedure FormDestroy(Sender: TObject);
  15.   private
  16.     { Private declarations }
  17.   public
  18.     { Public declarations }
  19.   end;
  20.  
  21.    TOpenGLRender = class(TThread)
  22.    public
  23.       destructor Destroy; override;
  24.       procedure Init(aHandle: cardinal);
  25.       procedure Draw;
  26.       procedure Stop;
  27.       procedure Execute; override;
  28.    end;
  29.  
  30. var
  31.   DGLForm: TDGLForm;
  32.   OpenGLRender: TOpenGLRender;
  33.   DC:HDC;
  34.   RC:HGLRC;
  35.   angle: integer;
  36.  
  37.  
  38. implementation
  39.  
  40. {$R *.DFM}
  41.  
  42. function getNormal(p1,p2,p3:TGLArrayf3):TGLArrayf3;
  43. var a,b:TGLArrayf3;
  44. begin
  45.  a[0]:=p2[0]-p1[0]; a[1]:=p2[1]-p1[1]; a[2]:=p2[2]-p1[2];
  46.  b[0]:=p3[0]-p1[0]; b[1]:=p3[1]-p1[1]; b[2]:=p3[2]-p1[2];
  47.  result[0]:=a[1]*b[2]-a[2]*b[1];
  48.  result[1]:=a[2]*b[0]-a[0]*b[2];
  49.  result[2]:=a[0]*b[1]-a[1]*b[0];
  50. end;
  51.  
  52. //TOpenGLRender
  53.  
  54. destructor TOpenGLRender.Destroy;
  55. begin
  56.   inherited;
  57. end;
  58.  
  59. procedure TOpenGLRender.Execute;
  60. begin
  61.   while not terminated do
  62.   begin
  63.     Draw;
  64.     sleep(1);
  65.   end;
  66. end;
  67.  
  68. procedure TOpenGLRender.Init(aHandle: cardinal);
  69. const
  70.   light0_position:TGLArrayf4=( -8.0, 8.0, -16.0, 0.0);
  71.   ambient:  TGLArrayf4=( 0.3, 0.3, 0.3, 0.3);
  72. begin
  73.  
  74.   InitOpenGL; // Initialize DglOpenGL
  75.  
  76.   DC := GetDC(aHandle);
  77.   // Create RenderContext (32 Bit Pixel, 24 Bit DepthBuffer, Doublebuffering)
  78.   RC := CreateRenderingContext(DC, [opDoubleBuffered], 32, 24, 0, 0, 0, 0);
  79.   // Activate RenderContext
  80.   ActivateRenderingContext(DC, RC);
  81.  
  82.   // set viewing projection
  83.   glMatrixMode(GL_PROJECTION);
  84.   glFrustum(-0.1, 0.1, -0.1, 0.1, 0.3, 25.0);
  85.  
  86.   // position viewer
  87.   glMatrixMode(GL_MODELVIEW);
  88.  
  89.   // Active DepthBuffer
  90.   glEnable(GL_DEPTH_TEST);
  91.   glDepthFunc(GL_LESS);
  92.  
  93.   // Set lighting
  94.   glEnable(GL_LIGHTING);
  95.   glLightfv(GL_LIGHT0, GL_POSITION, @light0_position);
  96.   glLightfv(GL_LIGHT0, GL_AMBIENT, @ambient);
  97.   glEnable(GL_LIGHT0);
  98.  
  99.   // Set clear background color
  100.   glClearColor(0,0,0,0);
  101. end;
  102.  
  103. procedure TOpenGLRender.Draw;
  104. const
  105.   D=1.5;
  106.   H1=D/1.732;
  107.   H2=D*1.732-H1; // D/H = tg(30) = 1/sqrt(3)
  108.   HY=3.0;
  109.   //vertexes
  110.   a1:TGLArrayf3=(-D, 0, -H1);
  111.   a2:TGLArrayf3=(D, 0, -H1);
  112.   a3:TGLArrayf3=(0, 0, H2);
  113.   a4:TGLArrayf3=(0, HY, 0);
  114. var
  115.   n1, n2, n3, n4: TGLArrayf3;   //normals
  116. begin
  117.   angle:=angle+1;
  118.   n1 := getNormal(a1,a3,a2);
  119.   n2 := getNormal(a1,a2,a4);
  120.   n3 := getNormal(a2,a3,a4);
  121.   n4 := getNormal(a3,a1,a4);
  122.   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  123.   glEnable(GL_NORMALIZE);
  124.   glShadeModel(GL_FLAT);
  125.   glCullFace(GL_BACK);
  126.   glLoadIdentity;
  127.   glTranslatef(0.0, 0.0, -12.0);
  128.   glRotatef(angle, 0.0, 1.0, 0.0);
  129.   glBegin(GL_TRIANGLES);
  130.     glNormal3fv(@n1);
  131.     glVertex3fv(@a1); glVertex3fv(@a2); glVertex3fv(@a3);
  132.     glNormal3fv(@n2);
  133.     glVertex3fv(@a1); glVertex3fv(@a2); glVertex3fv(@a4);
  134.     glNormal3fv(@n3);
  135.     glVertex3fv(@a2); glVertex3fv(@a3); glVertex3fv(@a4);
  136.     glNormal3fv(@n4);
  137.     glVertex3fv(@a3); glVertex3fv(@a1); glVertex3fv(@a4);
  138.   glEnd;
  139.   SwapBuffers(DC);
  140. end;
  141.  
  142. procedure TOpenGLRender.Stop;
  143. begin
  144. end;
  145.  
  146. //TDGLForm
  147.  
  148. procedure TDGLForm.FormCreate(Sender: TObject);
  149. begin
  150.   DecimalSeparator:='.'; //always use . as decimal seperator
  151.   OpenGLRender := TOpenGLRender.Create(true);
  152.   OpenGLRender.Init(Handle);
  153.   OpenGLRender.Resume;
  154. end;
  155.  
  156. procedure TDGLForm.FormDestroy(Sender: TObject);
  157. begin
  158.   OpenGLRender.Suspend;
  159.   OpenGLRender.Free;
  160.   DeactivateRenderingContext; // Deactivate RenderContext
  161.   wglDeleteContext(RC); //Delete RenderContext
  162.   ReleaseDC(Handle, DC);
  163. end;
  164.  
  165. procedure TDGLForm.FormKeyPress(Sender: TObject; var Key: Char);
  166. begin
  167.   case Key of
  168.     #27 : Close;
  169.   end;
  170. end;
  171.  
  172. end.
  173.  

_________________
http://3das.noeska.com - create adventure games without programming


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Apr 04, 2008 18:55 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jul 21, 2004 22:39
Beiträge: 360
Wohnort: UK, Scotland
don't you need to setup a viewport?

Code:
  1. if (Height = 0) then                // prevent divide by zero exception
  2.     Height := 1;
  3.   glViewport(0, 0, Width, Height);    // Set the viewport for the OpenGL window
  4.   glMatrixMode(GL_PROJECTION);        // Change Matrix Mode to Projection
  5.   glLoadIdentity();                   // Reset View
  6.   gluPerspective(FOV, Width/Height, 4.0, Depth_Of_View);  // Do the perspective calculations. Last value = max clipping depth
  7.  
  8.   glMatrixMode(GL_MODELVIEW);         // Return to the modelview matrix
  9.   glLoadIdentity();                   // Reset View

_________________
Free Map Editor - Game Requirements - Stucuk.Net
-Stu


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Apr 04, 2008 19:06 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jul 01, 2003 18:59
Beiträge: 887
Wohnort: (The Netherlands)
Programmiersprache: fpc/delphi/java/c#
The code worked before i implemented the threading part. But you are right a proper glviewport needs to be added. But adding it did not solve the problem.

_________________
http://3das.noeska.com - create adventure games without programming


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Apr 04, 2008 19:32 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Hmm... Interesting problem. Since you created the rendering context in your thread there should be no problem. I am quite sure that you can use a handle of another thread for drawing on it, since some applications draw even on windows of other processes.

What disturbes me is that you call the following in your FormDestroy:
Code:
  1.   DeactivateRenderingContext; // Deactivate RenderContext
  2.   wglDeleteContext(RC); //Delete RenderContext
  3.   ReleaseDC(Handle, DC);

You should call this at the end of your Execute method, since all this stuff has been created in the thread.

To check that all is working well, you could create a simple environment in the thread, with an glOrtho-Projection and a quad that should fill the whole viewport. If you see something then, there might be a slight difference in your code you didn't see yet.

greetings Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Apr 04, 2008 19:45 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jul 01, 2003 18:59
Beiträge: 887
Wohnort: (The Netherlands)
Programmiersprache: fpc/delphi/java/c#
Solved.

I should have called the init from within the procedure TOpenGLRender.Execute. Not from withing the form create. Now it works. Thans go to AthenaOfDelphi on the PascalGameDevelopment forum for pointing this out.

Here is the modified code. (needs a cleanup):
Code:
  1.  
  2. unit OpenGLTemplateForm;
  3.  
  4. interface
  5.  
  6. uses
  7.  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  8.   StdCtrls, ExtCtrls, ComCtrls, DglOpenGL;
  9.  
  10. type
  11.   TDGLForm = class(TForm)
  12.     procedure FormKeyPress(Sender: TObject; var Key: Char);
  13.     procedure FormCreate(Sender: TObject);
  14.     procedure FormDestroy(Sender: TObject);
  15.   private
  16.     { Private declarations }
  17.   public
  18.     { Public declarations }
  19.   end;
  20.  
  21.   TOpenGLRender = class(TThread)
  22.   private
  23.     DC:HDC;
  24.     RC:HGLRC;
  25.     angle: integer;
  26.     initialized: boolean;
  27.   public
  28.     destructor Destroy; override;
  29.     procedure Init(aHandle: cardinal);
  30.     procedure Draw;
  31.     procedure Stop;
  32.     procedure Execute; override;
  33.   end;
  34.  
  35. var
  36.   DGLForm: TDGLForm;
  37.   OpenGLRender: TOpenGLRender;
  38.  
  39. implementation
  40.  
  41. {$R *.DFM}
  42.  
  43. function getNormal(p1,p2,p3:TGLArrayf3):TGLArrayf3;
  44. var a,b:TGLArrayf3;
  45. begin
  46.  a[0]:=p2[0]-p1[0]; a[1]:=p2[1]-p1[1]; a[2]:=p2[2]-p1[2];
  47.  b[0]:=p3[0]-p1[0]; b[1]:=p3[1]-p1[1]; b[2]:=p3[2]-p1[2];
  48.  result[0]:=a[1]*b[2]-a[2]*b[1];
  49.  result[1]:=a[2]*b[0]-a[0]*b[2];
  50.  result[2]:=a[0]*b[1]-a[1]*b[0];
  51. end;
  52.  
  53. //TOpenGLRender
  54.  
  55. destructor TOpenGLRender.Destroy;
  56. begin
  57.   inherited;
  58. end;
  59.  
  60. procedure TOpenGLRender.Execute;
  61. begin
  62.   Init(0);
  63.   while not terminated do
  64.   begin
  65.     Draw;
  66.     sleep(1);
  67.   end;
  68. end;
  69.  
  70. procedure TOpenGLRender.Init(aHandle: cardinal);
  71. const
  72.   light0_position:TGLArrayf4=( -8.0, 8.0, -16.0, 0.0);
  73.   ambient:  TGLArrayf4=( 0.3, 0.3, 0.3, 0.3);
  74. begin
  75.  
  76. //  InitOpenGL;
  77.  
  78.   DC := GetDC(DGLForm.Handle);
  79.   // Create RenderContext (32 Bit Pixel, 24 Bit DepthBuffer, Doublebuffering)
  80.   RC := CreateRenderingContext(DC, [opDoubleBuffered], 32, 24, 0, 0, 0, 0);
  81.   // Activate RenderContext
  82.   ActivateRenderingContext(DC, RC);
  83.  
  84.   // set viewing projection
  85.   glMatrixMode(GL_PROJECTION);
  86.   glFrustum(-0.1, 0.1, -0.1, 0.1, 0.3, 25.0);
  87.  
  88.   // position viewer
  89.   glMatrixMode(GL_MODELVIEW);
  90.  
  91.   // Active DepthBuffer
  92.   glEnable(GL_DEPTH_TEST);
  93.   glDepthFunc(GL_LESS);
  94.  
  95.   // Set lighting
  96.   glEnable(GL_LIGHTING);
  97.   glLightfv(GL_LIGHT0, GL_POSITION, @light0_position);
  98.   glLightfv(GL_LIGHT0, GL_AMBIENT, @ambient);
  99.   glEnable(GL_LIGHT0);
  100.  
  101.   // Set clear background color
  102.   glClearColor(0,0,0,0);
  103. end;
  104.  
  105. procedure TOpenGLRender.Draw;
  106. const
  107.   D=1.5;
  108.   H1=D/1.732;
  109.   H2=D*1.732-H1; // D/H = tg(30) = 1/sqrt(3)
  110.   HY=3.0;
  111.   //vertexes
  112.   a1:TGLArrayf3=(-D, 0, -H1);
  113.   a2:TGLArrayf3=(D, 0, -H1);
  114.   a3:TGLArrayf3=(0, 0, H2);
  115.   a4:TGLArrayf3=(0, HY, 0);
  116. var
  117.   n1, n2, n3, n4: TGLArrayf3;   //normals
  118. begin
  119.   angle:=angle+1;
  120.   n1 := getNormal(a1,a3,a2);
  121.   n2 := getNormal(a1,a2,a4);
  122.   n3 := getNormal(a2,a3,a4);
  123.   n4 := getNormal(a3,a1,a4);
  124.   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  125.   glEnable(GL_NORMALIZE);
  126.   glShadeModel(GL_FLAT);
  127.   glCullFace(GL_BACK);
  128.   glLoadIdentity;
  129.   glTranslatef(0.0, 0.0, -12.0);
  130.   glRotatef(angle, 0.0, 1.0, 0.0);
  131.   glBegin(GL_TRIANGLES);
  132.     glNormal3fv(@n1);
  133.     glVertex3fv(@a1); glVertex3fv(@a2); glVertex3fv(@a3);
  134.     glNormal3fv(@n2);
  135.     glVertex3fv(@a1); glVertex3fv(@a2); glVertex3fv(@a4);
  136.     glNormal3fv(@n3);
  137.     glVertex3fv(@a2); glVertex3fv(@a3); glVertex3fv(@a4);
  138.     glNormal3fv(@n4);
  139.     glVertex3fv(@a3); glVertex3fv(@a1); glVertex3fv(@a4);
  140.   glEnd;
  141.   SwapBuffers(DC);
  142. end;
  143.  
  144. procedure TOpenGLRender.Stop;
  145. begin
  146.   OpenGLRender.Suspend;
  147.   DeactivateRenderingContext; // Deactivate RenderContext
  148.   wglDeleteContext(RC); //Delete RenderContext
  149.   ReleaseDC(Handle, DC);
  150. end;
  151.  
  152. //TDGLForm
  153.  
  154. procedure TDGLForm.FormCreate(Sender: TObject);
  155. begin
  156.   DecimalSeparator:='.'; //always use . as decimal seperator
  157.   //InitOpenGL; // Initialize DglOpenGL
  158.   OpenGLRender := TOpenGLRender.Create(true);
  159.   //OpenGLRender.Init(Handle);
  160.   OpenGLRender.Resume;
  161. end;
  162.  
  163. procedure TDGLForm.FormDestroy(Sender: TObject);
  164. begin
  165.   OpenGLRender.Stop;
  166.   OpenGLRender.Free;
  167. end;
  168.  
  169. procedure TDGLForm.FormKeyPress(Sender: TObject; var Key: Char);
  170. begin
  171.   case Key of
  172.     #27 : Close;
  173.   end;
  174. end;
  175.  
  176. end.
  177.  

_________________
http://3das.noeska.com - create adventure games without programming


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Apr 04, 2008 19:48 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
An Idea:
You could write a constructor to pass the handle on to the thread and save it in a local variable to avoid the access to the Form-Object from within the thread.

And you should also move the call to Stop from your FormDestroy to the end of the Execute method.

greetings Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Apr 04, 2008 20:22 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jul 01, 2003 18:59
Beiträge: 887
Wohnort: (The Netherlands)
Programmiersprache: fpc/delphi/java/c#
OK

I added an property to pass the handle.
I now call stop at the end of the execute method.

Now should i use
Code:
  1.  
  2.   OpenGLRender.Terminate;
  3.   OpenGLRender.WaitFor;
  4.   OpenGLRender.Free;
  5.  


Code:
  1.  
  2.  OpenGLRender.Suspend;
  3.  OpenGLRender.Free;
  4.  

in the formdestroy.

_________________
http://3das.noeska.com - create adventure games without programming


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Apr 04, 2008 20:41 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Suspend: Suspended the Thread but it's still alive an can resumed every time you want.
WaitFor: Blocks the calling thread until the running thread is terminated. WaitFor is also called in destructor of the threadclass.
Terminate: Sets an internal value of the thread. This value will be quered with terminated inside the thread. Terminate also will be called in the destuctor.

So to terminate the thread its enough if you only call Free. But i think you will generate an deadlock in your application if your thread dosn't quits the execute method.


PS: If you create an Thread suspended and free them before you have resumed it the destructor resume it for you. The Thread always getting called. Instead there will be some issues inside windows i think.


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


Wer ist online?

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