📄 unit1.pas
字号:
vPoint.X := 0.0; vPoint.Y := 0.0; vPoint.Z := 0.0; // Initialize a CVector3 to hold points.
// Just so we can see the curve better, I rotate the curve and sphere
if chkRotate.Checked then
begin
glRotatef(rotateY, 0.0, 1.0, 0.0); // Rotate the curve around the Y-Axis
//rotateY := rotateY + 0.1; // Increase the current rotation
end;
// Here we tell OpenGL to render lines with a greater thickness (default is 1.0)
glLineWidth(1.5); // Increase the size of a line for visibility
{-----------------------------------------------------------------------------}
{ We haven't used GL_LINE_STRIP before so let me explain. }
{ Instead of passing in the first point of the line, }
{ then the next point of the line, then passing in that same point again }
{ for the first point of the next line, etc... we can do a line strip. }
{ That means we just pass in ONE point and it connects them for us. }
{ If we just did GL_LINES it would render the curve is broken segments. }
{ Strips are very usefull, as well as fast. }
{ You can do quad and triangle strips too. }
{-----------------------------------------------------------------------------}
if chkAllBeziers.Checked then
begin
glColor3ub(0, 0, 255); // Set the color to Blue
for I := 0 to high(g_arrvStartPoint) do
begin
glBegin(GL_LINE_STRIP); // Start drawing lines
if I <> g_arrIndex then
begin
t := 0;
while t <= (1 + (1.0 / MAX_STEPS)) do
begin
vPoint := PointOnCurve(g_arrvStartPoint[I], g_arrvControlPoint1[I], g_arrvControlPoint2[I], g_arrvEndPoint[I], t);
glVertex3f(vPoint.x, vPoint.y, vPoint.z);
t := t + 1.0 / MAX_STEPS;
end;
end;
glEnd();
end;
end;
glColor3ub(0, 255, 0); // Set the color to Green
glBegin(GL_LINE_STRIP); // Start drawing lines
{-----------------------------------------------------------------------------}
{ Here we actually go through the curve and get the points }
{ that make up the curve. Since our PointOnCurve() function }
{ Take 4 points and a time value, we use a for loop starting }
{ "t" at 0 (the starting point of the curve) and then increase }
{ "t" by constant value of time. Because time is measured from }
{ 0 being the beginning of the curve, and 1 being the end, we divide }
{ 1 by the amount of steps we want to draw the curve. Basically the }
{ amount steps defines the detail of the curve. If we just had 4 }
{ steps, the curve would be created out of 4 lines. The lowest the }
{ the amount of steps to make the curve is 3. Otherwise it is just }
{ a straight line. The more steps, the more rounded the curve is. }
{ }
{ Go through the curve starting at 0, ending at 1 + another step. }
{ Since we are using line strips, we need to go past the end point by 1 step. }
{-----------------------------------------------------------------------------}
t := 0;
while t <= (1 + (1.0 / MAX_STEPS)) do
begin
{-----------------------------------------------------------------------------}
{ Here we pass in our 4 points that make up the curve to PointOnCurve(). }
{ We also pass in "t", which is the current time from 0 to 1. If we pass }
{ in 0 for t, we should get the starting point of the curve, if we pass in }
{ 1 for t, we should get the end point of the curve. }
{ So anything in between 0 and 1 will be another point along the curve }
{ (IE, .5 would be a point halfway along the curve). }
{-----------------------------------------------------------------------------}
// Get the current point on the curve, depending on the time.
vPoint := PointOnCurve(g_arrvStartPoint[g_arrIndex], g_arrvControlPoint1[g_arrIndex], g_arrvControlPoint2[g_arrIndex], g_arrvEndPoint[g_arrIndex], t);
// Draw the current point at distance "t" of the curve.
glVertex3f(vPoint.x, vPoint.y, vPoint.z);
t := t + 1.0 / MAX_STEPS;
end;
glEnd();
{-----------------------------------------------------------------------------}
{ Now that we drew the curve, we can turn lighting back on so the sphere }
{ has some more realistic properties (shading). }
{-----------------------------------------------------------------------------}
glEnable(GL_LIGHTING); // Turn lighting back on
{-----------------------------------------------------------------------------}
{ In order to move the sphere along the curve, }
{ we use the same function do draw the curve, }
{ except that we pass in the current time from 0 to 1 that the sphere is at. }
{ In the beginning the sphere's time is 0, }
{ so it's at the beginning of the curve. }
{ As we hit the RIGHT arrow key, g_CurrentTime will increase }
{ and will move the sphere along the curve }
{ with a certain fixed speed (BALL_SPEED). }
{ When g_CurrentTime gets to 1, we stop. }
{ If the time gets below 0, we stop again. }
{-----------------------------------------------------------------------------}
if ShowStart1.Checked then
begin
// Get the current point on the curve, depending on the time.
vPoint := PointOnCurve(g_arrvStartPoint[g_arrIndex], g_arrvControlPoint1[g_arrIndex],
g_arrvControlPoint2[g_arrIndex], g_arrvEndPoint[g_arrIndex], g_CurrentTime);
glColor3ub(255, 0, 0); // Set the color to red
// Draw the sphere at the current point along of the curve. Give it a radius of 0.2f
DrawSphere(vPoint.x, vPoint.y, vPoint.z, 0.2);
end;
//glColor3ub(255, 255, 0); // Set the color to yellow
// Now, we should display the control points so you can better visualize what they do.
// We represent them as small yellow spheres.
glColor3f(0.0,g_ControlPoint1Color,g_ControlPoint2Color);
// Draw the first control point as a small yellow sphere
DrawSphere(g_arrvControlPoint1[g_arrIndex].x, g_arrvControlPoint1[g_arrIndex].y, g_arrvControlPoint1[g_arrIndex].z, 0.1);
glColor3f(g_ControlPoint1Color,g_ControlPoint2Color,0.0);
// Draw the second control point as a small yellow sphere
DrawSphere(g_arrvControlPoint2[g_arrIndex].x, g_arrvControlPoint2[g_arrIndex].y, g_arrvControlPoint2[g_arrIndex].z, 0.1);
glEnd();
glDisable(GL_LIGHTING);
glEnable(GL_BLEND);
glColor4f(0.0,0.0,0.6,0.5);
glBegin(GL_QUADS);
glVertex3f(-6.0,0.0,-6.0);
glVertex3f( 6.0,0.0,-6.0);
glVertex3f( 6.0,0.0, 6.0);
glVertex3f(-6.0,0.0, 6.0);
glEnd;
glDisable(GL_BLEND);
glBegin(GL_LINES);
glColor3f(1.0,1.0,0.0);
glVertex3f(0.0,0.0,0.0);
glVertex3f(1.0,0.0,0.0);
glColor3f(0.0,1.0,1.0);
glVertex3f(0.0,0.0,0.0);
glVertex3f(0.0,1.0,0.0);
glColor3f(1.0,0.0,1.0);
glVertex3f(0.0,0.0,0.0);
glVertex3f(0.0,0.0,1.0);
glEnd;
end;
{------------------------------------------------------------------}
{ Initialise OpenGL }
{------------------------------------------------------------------}
procedure TForm1.glInit();
begin
glClearColor(0.0, 0.0, 0.0, 0.0); // Black Background
glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
glClearDepth(1.0); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enable Depth Buffer
glDepthFunc(GL_LESS); // The Type Of Depth Test To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //Realy Nice perspective calculations
//////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** ////////////////////
// Just to give the sphere more realism, we enable the default
// lights for shading. First we turn on a light, turn lighting on,
// then enable coloring. We need to enable color functions like glColor3f()
// since lighting is on. If we don't all objects will be white.
glEnable(GL_LIGHT0); // Turn on this light
glEnable(GL_LIGHTING); // Turn lighting on
glEnable(GL_COLOR_MATERIAL); // Since lighting is on, allow glColor*() functions
//////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** ////////////////////
// soft edge, antialiasing when blending is enabled
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
g_CurrentTime := 0.0; // This is the current position of the sphere along the curve (0 to 1)
New1Click(nil);
zView := 10.0;
g_ControlPoint1Color := 1.0;
g_ControlPoint2Color := 1.0;
end;
{------------------------------------------------------------------}
{ Create the form and initialist openGL }
{------------------------------------------------------------------}
procedure TForm1.FormCreate(Sender: TObject);
var pfd : TPIXELFORMATDESCRIPTOR;
pf : Integer;
begin
// OpenGL initialisieren
dc:=GetDC(Panel1.Handle);
// PixelFormat
pfd.nSize:=sizeof(pfd);
pfd.nVersion:=1;
pfd.dwFlags:=PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER or 0;
pfd.iPixelType:=PFD_TYPE_RGBA; // PFD_TYPE_RGBA or PFD_TYPEINDEX
pfd.cColorBits:=32;
pf :=ChoosePixelFormat(dc, @pfd); // Returns format that most closely matches above pixel format
SetPixelFormat(dc, pf, @pfd);
rc :=wglCreateContext(dc); // Rendering Context = window-glCreateContext
wglMakeCurrent(dc,rc); // Make the DC (Form1) the rendering Context
// Initialist GL environment variables
glInit;
Panel1Resize(sender); // sets up the perspective
AppStart :=GetTickCount();
// when the app has spare time, render the GL scene
Application.OnIdle := Idle;
end;
{------------------------------------------------------------------}
{ Release rendering context when form gets detroyed }
{------------------------------------------------------------------}
procedure TForm1.FormDestroy(Sender: TObject);
begin
wglMakeCurrent(0,0);
wglDeleteContext(rc);
end;
{------------------------------------------------------------------}
{ Application onIdle event }
{------------------------------------------------------------------}
procedure TForm1.Idle(Sender: TObject; var Done: Boolean);
begin
Done := FALSE;
LastTime :=ElapsedTime;
ElapsedTime :=GetTickCount() - AppStart; // Calculate Elapsed Time
ElapsedTime :=(LastTime + ElapsedTime) DIV 2; // Average it out for smoother movement
glDraw(); // Draw the scene
SwapBuffers(DC); // Display the scene
end;
{------------------------------------------------------------------}
{ If the panel resizes, reset the GL scene }
{------------------------------------------------------------------}
procedure TForm1.Panel1Resize(Sender: TObject);
begin
glViewport(0, 0, Panel1.Width, Panel1.Height); // Set the viewport for the OpenGL window
glMatrixMode(GL_PROJECTION); // Change Matrix Mode to Projection
glLoadIdentity(); // Reset View
gluPerspective(45.0, Panel1.Width/Panel1.Height, 1.0, 500.0); // Do the perspective calculations. Last value = max clipping depth
glMatrixMode(GL_MODELVIEW); // Return to the modelview matrix
end;
{------------------------------------------------------------------}
{ Monitors all keypress events for the app }
{------------------------------------------------------------------}
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
if Key = char(VK_LEFT) then // If we hit the LEFT arrow
begin
g_CurrentTime := g_CurrentTime - BALL_SPEED; // Increase the position of the ball along the curve
if g_CurrentTime < 0 then // If we go below 0
begin
g_CurrentTime := 0; // Set it back to 0
end;
end;
if Key = char(VK_RIGHT) then // If we hit the Right arrow
begin
g_CurrentTime := g_CurrentTime + BALL_SPEED; // Increase the position of the ball along the curve
if g_CurrentTime > 1 then // If we go below 0
begin
g_CurrentTime := 1; // Set it back to 0
end;
end;
if Key = #27 then
Close;
end;
{------------------------------------------------------------------------}
{ Close the application }
{------------------------------------------------------------------------}
procedure TForm1.Button1Click(Sender: TObject);
begin
Close;
end;
{------------------------------------------------------------------------}
{ Apply button }
{------------------------------------------------------------------------}
procedure TForm1.Button2Click(Sender: TObject);
begin
UpdatePointValues();
end;
{------------------------------------------------------------------------}
{ Set the value of the target textBox higher or lower }
{------------------------------------------------------------------------}
procedure TForm1.DoUpDown(txtBox : TEdit;Button: TUDBtnType);
begin
if Button = btPrev then
begin
txtBox.Text := FloatToStr(StrToFloat(txtBox.Text) - 0.01);
end
else
begin
txtBox.Text := FloatToStr(StrToFloat(txtBox.Text) + 0.01);
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -