Mega Code Archive

 
Categories / Delphi / Graphic
 

Introducing OpenGL to Delphi (advanced programmers)

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.