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

Aktuelle Zeit: Sa Jun 08, 2024 21:06

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



Ein neues Thema erstellen Auf das Thema antworten  [ 3 Beiträge ] 
Autor Nachricht
BeitragVerfasst: So Aug 19, 2007 13:44 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 24, 2007 00:44
Beiträge: 144
Hello,

I had the idea that certain UI components of my project could 'fly away' when I decided to move to another screen. Sure, I could just send them along a straight +X or +Y line until they disappeared from the screen, but I thought that it would be very nice looking to have them follow a flight plan that was described by a curve - maybe even a random curve - but a curve anyway.

So, I've started educating myself about OpenGL and calculating and drawing Bezier curves. Here is the entirety of my code - it is pretty straightforward and will run easily (just a TForm, with a client-aligned TPanel and a TTimer). This code calculates a curve via four control points and is able to display it on the screen - as well as displaying each point on the curve and the control points connected via a thin red line.

What I'm curious about is the code at lines 137 and 148 - the lines that use glEvalCoord1f to apparently draw out a GL_POINT (or a part of a LINE_LOOP) by referencing some values it seems to have pre-calculated with the call to glMap1f earlier - or is calculating on the fly.

While calculating my curve, I would prefer to be able pre-calculate and store the X, Y and Z of each point on the curve in an array - so I can look them up later - glEvalCoord1f is obviously pulling out the correct details - but 1) I don't really know where it is getting them from and 2) I don't know if I can access them in code so I can use glVertex3f to display things.

Is there a way of 1) setting up my control points, 2) setting a number of segments (level of detail), 3) calculating the curve according to the control points and number of segments (level of detail) I want and 4) storing the values of each point on the curve in X, Y and Z format in an array, so that I can then 5) reference them so my moving objects can follow some kind of flight plan?

glEvalCoord1f is great in that it obviously returns or uses some form of X, Y and Z values for the LINE_LOOP and GL_POINTs loop it is being used in - but it is not a function, so I don't know how to get my X, Y and Z values from it... does that make sense?

Code:
  1. unit Main;
  2.  
  3. interface
  4.  
  5. uses
  6.   OpenGL, Windows, SysUtils, Classes, Controls, Forms, StdCtrls, ComCtrls, ExtCtrls;
  7.  
  8. const
  9.   LevelOfDetail = 20;
  10.   NumberOfControlPoints = 4;
  11.  
  12. type
  13.   TPoint = record
  14.     X, Y, Z : GLFloat;
  15.   end;
  16.  
  17.   TfrmMain = class(TForm)
  18.     Timer1 : TTimer;
  19.     pOGL : TPanel;
  20.     procedure FormCreate (Sender : TObject);
  21.     procedure Timer1Timer (Sender : TObject);
  22.   private
  23.     procedure Draw;
  24.   public
  25.   end;
  26.  
  27. var
  28.   frmMain : TfrmMain;
  29.   ControlPoints : array[0..NumberOfControlPoints - 1] of TPoint;
  30.   Colours : array[0..LevelOfDetail] of array[0..2] of GLFloat;
  31.   Rotation : GLFloat = 0;
  32.  
  33.  
  34. implementation
  35.  
  36.  
  37. {$R *.DFM}
  38.  
  39.  
  40. procedure SetupPixelFormat ( DC : HDC
  41.                            );
  42. const
  43.    PFD : TPIXELFORMATDESCRIPTOR = (
  44.          nSize : SizeOf (TPIXELFORMATDESCRIPTOR); nVersion : 1;
  45.          dwFlags : PFD_SUPPORT_OPENGL or PFD_DRAW_TO_WINDOW or PFD_DOUBLEBUFFER;
  46.          iPixelType : PFD_TYPE_RGBA;
  47.          cColorBits : 24; cRedBits : 0; cRedShift : 0; cGreenBits : 0; cGreenShift : 0;
  48.          cBlueBits : 0; cBlueShift : 0; cAlphaBits : 0; cAlphaShift : 0; cAccumBits : 0;
  49.          cAccumRedBits : 0; cAccumGreenBits : 0; cAccumBlueBits : 0; cAccumAlphaBits : 0;
  50.          cDepthBits : 16; cStencilBits : 0; cAuxBuffers : 0; iLayerType : PFD_MAIN_PLANE;
  51.          bReserved : 0; dwLayerMask : 0; dwVisibleMask : 0; dwDamageMask : 0);
  52. var
  53.   PixelFormat : Integer;
  54. begin
  55.    PixelFormat := ChoosePixelFormat (DC,@PFD);
  56.    if (PixelFormat = 0) then
  57.    begin
  58.      Exit;
  59.    end;
  60.  
  61.    if (SetPixelFormat (DC,PixelFormat,@PFD) <> True) then
  62.    begin
  63.      Exit;
  64.    end;
  65. end;
  66.  
  67.  
  68. procedure TfrmMain.FormCreate ( Sender : TObject
  69.                               );
  70. var
  71.   DC : HDC;
  72.   RC : HGLRC;
  73.   Loop : Integer;
  74. begin
  75.   DC := GetDC (pOGL.Handle);
  76.   SetupPixelFormat (DC);
  77.   RC := wglCreateContext (DC);
  78.   wglMakeCurrent (DC,RC);
  79.  
  80.   { Set up the control points for the Bezier curve... }
  81.   ControlPoints[0].X := -4;
  82.   ControlPoints[0].Y := -4;
  83.   ControlPoints[0].Z := -2;
  84.  
  85.   ControlPoints[1].X := -2;
  86.   ControlPoints[1].Y := 6;
  87.   ControlPoints[1].Z := 0;
  88.  
  89.   ControlPoints[2].X := 0;
  90.   ControlPoints[2].Y := -2;
  91.   ControlPoints[2].Z := 0;
  92.  
  93.   ControlPoints[3].X := 4;
  94.   ControlPoints[3].Y := 4;
  95.   ControlPoints[3].Z := -3;
  96.  
  97.   Randomize;
  98.   { Calculate colours for each segment of the created curve. }
  99.   for Loop := 0 to LevelOfDetail do
  100.   begin
  101.     Colours[Loop][0] := Random (100) / 100;
  102.     Colours[Loop][1] := Random (100) / 100;
  103.     Colours[Loop][2] := Random (100) / 100;
  104.   end;
  105.   glClearColor (0,0,0,1);
  106.  
  107.   glMap1f (GL_MAP1_VERTEX_3,0,1,3,4,@ControlPoints[0]);
  108.   glEnable (GL_MAP1_VERTEX_3);
  109.   glShadeModel (GL_FLAT);
  110.  
  111.   glMatrixMode (GL_PROJECTION);
  112.   glLoadIdentity;
  113.   gluPerspective (45,frmMain.Width / frmMain.Height,1,100);
  114.   glMatrixMode (GL_MODELVIEW);
  115. end;
  116.  
  117.  
  118. procedure TfrmMain.Draw;
  119. var
  120.   Loop : Integer;
  121. begin
  122.   glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  123.   glLoadIdentity;
  124.   glTranslatef (0,0,-15);
  125.  
  126.   glRotatef (Sin (GetTickCount / 500) * 60,1,0,0);
  127.   glRotatef (Sin (GetTickCount / 600) * 30,0,1,0);
  128.   glRotatef (Sin (GetTickCount / 2000) * 140,0,0,1);
  129.  
  130.   { Draw the actual segements of the Bezier curve. }
  131.   glLineWidth (4);
  132.   glBegin (GL_LINE_STRIP);
  133.     for Loop := 0 to LevelOfDetail do
  134.     begin
  135.       glColor3f (Colours[Loop][0],Colours[Loop][1],Colours[Loop][2]);
  136.       { How do I really know what X, Y and Z this is? }
  137.       glEvalCoord1f (Loop / LevelOfDetail);
  138.     end;
  139.   glEnd;
  140.  
  141.   { Draw each point along the Bezier curve... }
  142.   glColor3f (1,1,0);
  143.   glPointSize (5);
  144.   glBegin (GL_POINTS);
  145.     for Loop := 0 to LevelOfDetail do
  146.     begin
  147.       { Again - how can my X, Y and Z be obtained? }
  148.       glEvalCoord1f (Loop / LevelOfDetail);
  149.     end;
  150.   glEnd;
  151.  
  152.   { Draw the control points of the Bezier curve... }
  153.   glColor3f (1,0,0);
  154.   glLineWidth (1);
  155.   glBegin (GL_LINE_STRIP);
  156.     for Loop := 0 to 3 do
  157.     begin
  158.       { Obviously I know what my X, Y and Z are for these... }
  159.       glVertex3f (ControlPoints[Loop].X,ControlPoints[Loop].Y,ControlPoints[Loop].Z);
  160.     end;
  161.   glEnd;
  162.  
  163.   SwapBuffers (wglGetCurrentDC);
  164. end;
  165.  
  166.  
  167. procedure TfrmMain.Timer1Timer ( Sender : TObject
  168.                                );
  169. begin
  170.   Draw;
  171. end;
  172.  
  173.  
  174. end.

_________________
Cheers, DpM
http://www.hmusiccentre.org.uk


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Aug 19, 2007 14:26 
Offline
Ernährungsberater
Benutzeravatar

Registriert: Sa Jan 01, 2005 17:11
Beiträge: 2067
Programmiersprache: C++
Casteljau:
b_k^n (x) := x_k, k = 0,..., n;
b_k^(j+1) (x) := u_o(x|I) b_k^j (x) + u_1(x|I) b_(k+1)^j (x), k = 0,..., n - j - 1;

where u_0 and u_1 are "baryzentrische Koordinaten" which meens:
u_0(x|I) := (t_1 - x) / (t_1 - t_0)
and
u_1(x|I) := (x - t_0) / (t_1 - t_0)
where t_0 and t_1 are the points at the border of the interval I.

b_0^n(x) is the value of the bezier curve at point x.

_________________
Steppity,steppity,step,step,step! :twisted:
❆ ❄ ❄ ❄ ❅ ❄ ❆ ❄ ❅ ❄ ❅ ❄ ❅ ❄ ❄
❄ ❄ ❄ ❅ ❄ ❄ ❄ ❅ ❄ ❄ ❆ ❄ ❄


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Success!
BeitragVerfasst: So Aug 19, 2007 14:27 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 24, 2007 00:44
Beiträge: 144
S'OK... got it. Not exactly got it figured out - but got it working anyway with:

Code:
  1. function TfrmMain.GetPointOnCurve ( ControlPoint1, ControlPoint2, ControlPoint3, ControlPoint4 : TPoint;
  2.                                     CurvePoint : GLFloat
  3.                                   ) : TPoint;
  4. var
  5.   V1, V2, V3 : GLFloat;
  6.   Returning : TPoint;
  7. begin
  8.   V1 := 1 - CurvePoint;
  9.   V2 := V1 * V1 * V1;
  10.   V3 := CurvePoint * CurvePoint * CurvePoint;
  11.  
  12.   Returning.X := V2 * ControlPoint1.X + 3 * CurvePoint * V1 * V1 * ControlPoint2.X + 3 * CurvePoint * CurvePoint * V1 * ControlPoint3.X + V3 * ControlPoint4.X;
  13.   Returning.Y := V2 * ControlPoint1.Y + 3 * CurvePoint * V1 * V1 * ControlPoint2.Y + 3 * CurvePoint * CurvePoint * V1 * ControlPoint3.Y + V3 * ControlPoint4.Y;
  14.   Returning.Z := V2 * ControlPoint1.Z + 3 * CurvePoint * V1 * V1 * ControlPoint2.Z + 3 * CurvePoint * CurvePoint * V1 * ControlPoint3.Z + V3 * ControlPoint4.Z;
  15.  
  16.   GetPointOnCurve := Returning;
  17. end;
  18.  

...and:

Code:
  1.   glColor3f (1,1,0);
  2.   glPointSize (5);
  3.   glBegin (GL_POINTS);
  4.     T := 0;
  5.     for Loop := 0 to LevelOfDetail do
  6.     begin
  7.       ThisPoint := GetPointOnCurve (ControlPoints[0],ControlPoints[1],ControlPoints[2],ControlPoints[3],T);
  8.       glVertex3f (ThisPoint.X,ThisPoint.Y,ThisPoint.Z);
  9.       T := T + 1 / LevelOfDetail;
  10.     end;
  11.   glEnd;
  12.  
  13.  

Do I fully understand it? No. Do I understand that it does what I want? Yes. Am I happy with it? Yes.

_________________
Cheers, DpM
http://www.hmusiccentre.org.uk


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 13 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.010s | 14 Queries | GZIP : On ]