Search code examples
delphiopengldelphi-7

Delphi OpenGL traiangle does not rotate


I am trying to animate this triangle I made through rotation and haven't been able to figure out how to do it. There's something more than just using glRotateF before the FormPaint function.

unit tri;    
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, OpenGL;

const
  GL_NO_ERROR = 0;

type
  HGLRC = THandle;
  GLenum = Cardinal;
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormPaint(Sender: TObject);
    procedure FormResize(Sender: TObject);
  private
    GLContext : HGLRC;
    glDC: HDC;
    errorCode: GLenum;
    openGLReady: Boolean;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  pfd: TPixelFormatDescriptor;
  FormatIndex: Integer;
begin
  FillChar(pfd,SizeOf(pfd),0);
  with pfd do
  begin
    nSize := SizeOf(pfd);
    nVersion := 1; {The current version of the desccriptor is 1}
    dwFlags := PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL;
    iPixelType := PFD_TYPE_RGBA;
    cColorBits := 24; {support 24-bit color}
    cDepthBits := 32; {depth of z-axis}
    iLayerType := PFD_MAIN_PLANE;
  end;
  glDC := getDC(handle);
  FormatIndex := ChoosePixelFormat(glDC,@pfd);
  SetPixelFormat(glDC,FormatIndex,@pfd);
  GLContext := wglCreateContext(glDC);
  wglMakeCurrent(glDC,GLContext);
  OpenGLReady := true;
end;


procedure TForm1.FormPaint(Sender: TObject);
begin
  if not openGLReady then
    exit;
  {background}
  glClearColor(0.1,0.0,0.1,0.0);
  glClear(GL_COLOR_BUFFER_BIT);
  glLoadIdentity; // Reset The View
  glTranslatef(0.0, 0, 0.0);
  glRotateF (360, 0.0, 0.0, 1.0);
  glBegin( GL_POLYGON ); // start drawing a polygon
    glColor3f( 1.0, 0.0, 0.0);
    glVertex3f( 0.0, 0.5, 0.0 ); // Top
    glColor3f(0.0, 1.0, 0.0);
    glVertex3f( 0.5, -0.5, 0.0 ); // Bottom Right
    glColor3f(0.0, 0.0, 1.0);
    glVertex3f( -0.5, -0.5, 0.0 ); // Bottom Left
  glEnd;
  glFlush;
  {error checking}
  errorCode:=glGetError;
   if errorCode<>GL_NO_ERROR then
      raise Exception.Create('Error in Paint'#13+gluErrorString(errorCode));
  SwapBuffers(wglGetCurrentDC);
  glFlush();
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  wglMakeCurrent(Canvas.Handle,0);
  wglDeleteContext(GLContext);
end;

procedure TForm1.FormResize(Sender: TObject);
begin
  if not openGLReady then
  exit;
  glViewPort(0,0,ClientWidth,ClientHeight);
  glOrtho(-1.0,1.0,-1.0,1.0,-1.0,1.0);
  errorCode := glGetError;
  if errorCode<>GL_NO_ERROR then
  raise Exception.Create('FormResize:'+gluErrorString(errorCode));
end;

procedure GLInit;
begin
  // set viewing projection
  glMatrixMode(GL_PROJECTION);
  glFrustum(-0.1, 0.1, -0.1, 0.1, 0.3, 15.0);
  // position viewer
  glMatrixMode(GL_MODELVIEW);
  glEnable(GL_DEPTH_TEST);
end;

end.

since I'm using the VCL component of delphi 7, what would I need? and how would I set it up so my triangle rotates on the z axis?


Solution

  • Replace

    glRotateF (360, 0.0, 0.0, 1.0);
    

    by

    glRotateF (alpha, 0.0, 0.0, 1.0);
    

    where alpha: GLfloat; is a private member of your form class which you set to 0 in FormCreate. Now, simply add a TTimer to your form, set its Interval to 30 and add the following code on its OnTimer event:

    procedure TForm1.Timer1Timer(Sender: TObject);
    begin
      alpha := alpha + 0.1;
      Invalidate;
    end;
    

    (To remove the flickering, you can add

    procedure TForm1.WMEraseBkgnd(var Message: TWMEraseBkgnd);
    begin
      Message.Result := 0;
    end;
    

    to your class, as well.)