Graphic Delphi

Title: Introducing OpenGL to Delphi (advanced programmers)
Question: OpenGL is a powerful API generally used with games (Quake, Unreal, Counter-Strike, etc.). This API let us work with 3D figures of any kind (cubes, or much more complex objects) in a very easy way. It also permits transformation (size, zoom, etc.) light effects, shadows, materials, aliasing, and a lot of inimaginable features.
Answer:
//---------------------------------------------------------------------------
// Author : Digital Survivor [Esteban Rodrguez Nieto | Jos Plano]
// Email : plmad666@gmail.com | jose.plano@gmail.com
// Web site : www.ds-studios.com.ar
//---------------------------------------------------------------------------
Unit UPrinc;
// This example uses teh default Delphi's OpenGL unit. This unit have many bugs.
// For get a more complete unit and some utilities go to http://www.mad666.net
Interface
Uses
// You must include the unit "OpenGL.pas"
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
OpenGL, ExtCtrls;
Type
TPrincipal = Class (TForm)
Procedure FormCreate (Sender : TObject);
Procedure FormResize (Sender : TObject);
Procedure FormDestroy (Sender : TObject);
Protected { Protected declarations }
Procedure WMPaint (Var Msg : TWMPaint); Message WM_PAINT;
Private { Private declarations }
// Here are a couple of variables: DC is our "Device context". This is
// where we want to draw. HRC is our "Rendering context". This is the
// context where OpenGL will draw all the figures and so...
DC : HDC;
HRC : HGLRC;
Procedure SetDCPixelFormat;
Public { Public declarations }
End;
Var
// Note: OpenGL has your own variables (for example: GLFloat, GLInt, etc.)
// They was similar to Delphi's variables, but for compatibility between
// languajes it is recomended that we use OpenGL's variable declaration.
Principal : TPrincipal;
FPS,
Angle : GLFloat;
NewCount,
LastCount,
FrameCount : Integer;
Implementation
{$R *.DFM}
Procedure TPrincipal.SetDCPixelFormat;
// In any OpenGL Based application we need to choose a "Pixel Format". This
// is needed because not all machines supports all video or hicolor modes.
// But here is a procedure that make all the work for us. It's need a lot
// of parameters. For more especifications consult Delphi's help.
Const
Pfd : PIXELFORMATDESCRIPTOR = (
nSize : SizeOf (PIXELFORMATDESCRIPTOR);
nVersion : 1;
dwFlags : PFD_DRAW_TO_WINDOW Or PFD_SUPPORT_OPENGL Or PFD_DOUBLEBUFFER;
iPixelType : PFD_TYPE_RGBA;
cColorBits : 32;
cRedBits : 0;
cRedShift : 0;
cGreenBits : 0;
cBlueBits : 0;
cBlueShift : 0;
cAlphaBits : 0;
cAlphaShift : 0;
cAccumBits : 0;
cAccumRedBits : 0;
cAccumGreenBits : 0;
cAccumBlueBits : 0;
cAccumAlphaBits : 0;
cDepthBits : 32;
cStencilBits : 0;
cAuxBuffers : 0;
iLayerType : PFD_MAIN_PLANE;
bReserved : 0;
dwLayerMask : 0;
dwVisibleMask : 0;
dwDamageMask : 0);
Var
PixelFormat : Integer;
Begin
PixelFormat := ChoosePixelFormat (DC, @Pfd);
SetPixelFormat (DC, PixelFormat, @Pfd);
End;
Procedure TPrincipal.FormCreate (Sender : TObject);
Const
// Parameters for ligthning and material
LightAmbient : Array [0..3] Of GLfloat = (0.1, 0.1, 0.1, 1.0);
LightDiffuse : Array [0..3] Of GLfloat = (0.7, 0.7, 0.7, 1.0);
LightSpecular : Array [0..3] Of GLfloat = (0.0, 0.0, 0.0, 1.0);
LightPosition : Array [0..3] Of GLfloat = (0.0, 0.0, 2.0, 1.0);
MaterialColor : Array [0..3] Of GLfloat = (1.0, 0.0, 0.0, 1.0);
Begin
DC := GetDC (Handle); // Initialize the rendering context
SetDCPixelFormat; // Sets the pixel format
HRC := wglCreateContext (DC); // Make a GL Context
wglMakeCurrent (DC, HRC);
glClearColor(0.0, 0.0, 0.0, 0.0); // Clear background color to black
glClearDepth(1.0); // Clear the depth buffer
glDepthFunc(GL_LESS); // Type of depth test
glShadeModel (GL_SMOOTH); // Smooth color shading
glEnable (GL_DEPTH_TEST); // Enables depth test
glMatrixMode (GL_PROJECTION);
glLoadIdentity; // Reset projection matrix
gluPerspective (45.0, Width / Height, 0.1, 100.0); // Aspect ratio of the viewport
glMatrixMode (GL_MODELVIEW);
glLightfv (GL_LIGHT0, GL_AMBIENT, @LightAmbient); // Create light
glLightfv (GL_LIGHT0, GL_DIFFUSE, @LightDiffuse);
glLightfv (GL_LIGHT0, GL_SPECULAR, @LightSpecular);
glLightfv (GL_LIGHT0, GL_POSITION, @LightPosition); // Light position
glEnable (GL_LIGHTING);
glEnable (GL_LIGHT0);
glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, @MaterialColor); // Reflective properties
Angle := 0;
End;
Procedure TPrincipal.FormResize (Sender : TObject);
Begin
glViewport (0, 0, Width, Height); // Reset The Current Viewport And Perspective Transformation
glMatrixMode (GL_PROJECTION);
glLoadIdentity;
gluPerspective (30.0, Width / Height, 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
InvalidateRect (Handle, Nil, False); // Force window repaint
End;
Procedure TPrincipal.WMPaint (Var Msg : TWMPaint);
Var
Ps : TPaintStruct;
Begin
BeginPaint (Handle, Ps);
NewCount := GetTickCount;
Inc (FrameCount);
If (NewCount - LastCount) 1000 Then
Begin
Caption := Format ('MAD GLcube - %f fps', [FrameCount * 1000 / (NewCount - LastCount)]);
LastCount := NewCount;
FrameCount := 0;
End;
glClear (GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT); // Clear color & depth buffers
glLoadIdentity;
glTranslatef (0.0, 0.0, -8.0); // Polygon depth
glRotatef (30.0, 1.0, 0.0, 0.0);
glRotatef (Angle, 0.0, 1.0, 0.0);
glBegin (GL_POLYGON);
glNormal3f (0.0, 0.0, 1.0);
glVertex3f (1.0, 1.0, 1.0);
glVertex3f (-1.0, 1.0, 1.0);
glVertex3f (-1.0, -1.0, 1.0);
glVertex3f (1.0, -1.0, 1.0);
glEnd;
glBegin (GL_POLYGON);
glNormal3f (0.0, 0.0, -1.0);
glVertex3f (1.0, 1.0, -1.0);
glVertex3f (1.0, -1.0, -1.0);
glVertex3f (-1.0, -1.0, -1.0);
glVertex3f (-1.0, 1.0, -1.0);
glEnd;
glBegin (GL_POLYGON);
glNormal3f (-1.0, 0.0, 0.0);
glVertex3f (-1.0, 1.0, 1.0);
glVertex3f (-1.0, 1.0, -1.0);
glVertex3f (-1.0, -1.0, -1.0);
glVertex3f (-1.0, -1.0, 1.0);
glEnd;
glBegin (GL_POLYGON);
glNormal3f (1.0, 0.0, 0.0);
glVertex3f (1.0, 1.0, 1.0);
glVertex3f (1.0, -1.0, 1.0);
glVertex3f (1.0, -1.0, -1.0);
glVertex3f (1.0, 1.0, -1.0);
glEnd;
glBegin (GL_POLYGON);
glNormal3f (0.0, 1.0, 0.0);
glVertex3f (-1.0, 1.0, -1.0);
glVertex3f (-1.0, 1.0, 1.0);
glVertex3f (1.0, 1.0, 1.0);
glVertex3f (1.0, 1.0, -1.0);
glEnd;
glBegin (GL_POLYGON);
glNormal3f (0.0, -1.0, 0.0);
glVertex3f (-1.0, -1.0, -1.0);
glVertex3f (1.0, -1.0, -1.0);
glVertex3f (1.0, -1.0, 1.0);
glVertex3f (-1.0, -1.0, 1.0);
glEnd;
SwapBuffers (DC);
If Angle = 360.0 Then Angle := 0.0;
Angle := Angle + 0.5;
EndPaint (Handle, Ps);
InvalidateRect (Handle, Nil, False); // Force window repaint
End;
Procedure TPrincipal.FormDestroy (Sender : TObject);
Begin
wglMakeCurrent (0, 0);
wglDeleteContext (HRC);
ReleaseDC (Handle, DC);
End;
End.