Since Delphi comes with OpenGL.PAS is 1.0, now the actual use is at least 1.1 version, Windows pure software simulation method is also 1.1, so you have to import some necessary functions. You can also use some open source free units such as OpenGL12.PAS of Mike Lischke. Of course, you can write a more concise code yourself, and you don't have to find errors in the huge code that is too advanced.
First introduce the necessary units Windows, Messages, OpenGL
To add some necessary extensions.
Const // GL_EXT_BGRA GL_BGR_EXT = $ 80E0; GL_BGRA_EXT = $ 80E1;
// polygon offset GL_POLYGON_OFFSET_UNITS = $ 2A00; GL_POLYGON_OFFSET_POINT = $ 2A01; GL_POLYGON_OFFSET_LINE = $ 2A02; GL_POLYGON_OFFSET_FILL = $ 8037; GL_POLYGON_OFFSET_FACTOR = $ 8038;
procedure glBindTexture (target: GLEnum; texture: GLuint); stdcall; external opengl32; procedure glDeleteTextures (n: GLsizei; textures: PGLuint); stdcall; external opengl32; procedure glGenTextures (n: GLsizei; textures: PGLuint); stdcall; external opengl32 Function Glistext: glboolean; stdcall; external opengl32; procedure glpolygonoffset (factory, units: glfloat); stdcall; External OpenGL32;
// This declaration is used to correct an bugfunction glubuild2dmipmaps of OpenGL.PAS (Target: Glenum; Components, Width, Height: Glint; Format, Atype: Glenum; Data: Pointer: Glint; stdcall; external opengl32;
The interface is now basically upgraded to version 1.1. If other extensions are needed, you can also increase.
Next, you want to create OpenGL's drawing context RC, and you need the GDI window to the device context DC. TForm.Handle Attributes or other TwinControl's Handle properties are DC. The following functions can be used by DC, and the return value is the handle of the RC. OpenGL drawing can be used later. Generally can be used within the Form's oncreate event. The options of this function are depth buffers, template buffers, accumulated buffers, and generate the value of the Alpha channel.
type TRCOptions = set of (roDepth, roStencil, roAccum, roAlpha); function CreateRC (dc: HDC; opt: TRCOptions): HGLRC; var PFDescriptor: TPixelFormatDescriptor; PixelFormat: Integer; begin FillChar (PFDescriptor, SizeOf (PFDescriptor), 0) ; with PFDescriptor do begin nSize: = SizeOf (PFDescriptor); nVersion: = 1; dwFlags: = PFD_SUPPORT_OPENGL or PFD_DRAW_TO_WINDOW or PFD_DOUBLEBUFFER; iPixelType: = PFD_TYPE_RGBA; cColorBits: = GetDeviceCaps (DC, BITSPIXEL) * GetDeviceCaps (DC, PLANES); if roDepth in opt then cDepthBits: = 24; if roStencil in opt then cStencilBits: = 8; if roAccum in opt then cAccumBits: = 64; iLayerType: = PFD_MAIN_PLANE; end; PixelFormat: = ChoosePixelFormat (DC, @PFDescriptor); Assert (PixelFormat <> 0); assert (setpixelformat (@pfdescriptor)); Result: = WGLCReateContext (DC); assert (Result <> 0); WGLmakecurrent (DC, Result);
Draw in the ONPAINT event in Form. Remember, after the drawing is completed, use SwapBuffers (DC: HDC) to exchange the drawing buffer and display buffering, so that the image will appear. Also remember to call GLVIEWPORT (0, 0, ClientWidth, ClientHeight) in the onResize event in Form; so that RC and DC are synchronized.
Destroy the RC in the ONDESTROY event of the Form.
Procedure destroyrc (rc: hglrc); begin if rc = 0 dam; wglmakecurrent (0, 0); WGLDeleteContext (rc);
At this point, the framework of an OpenGL program is generally formed. But there is a problem to be solved.
First, to prevent the Windows erase background and affect speed. Add member functions in Form
Private Procedure W MeraseBkgnd (Var Message: TwmeseBkgnd); Message WM_ERASEBKGND; Procedure TGLWindow.wmeraseBkgnd (Var Message: TwmeseBkgnd); begin message.result: = 1;
Second, in order to be more insurance. Add the following member functions.
protected procedure CreateParams (var Params: TCreateParams); override; procedure TGLWindow.CreateParams (var Params: TCreateParams); begin inherited; with Params do begin Style: = Style or WS_CLIPCHILDREN or WS_CLIPSIBLINGS; WindowClass.Style: = CS_VREDRAW or CS_HREDRAW or CS_OWNDC; End; end; good, now you can forget these troubles, write your wonderful 3D display :)
I have a few words, don't create multiple RCs in a thread, which will seriously affect performance. Some personal OpenGL window control demonstrates multiple controls on an Form, which is not good. You should display multiple views with an OpenGL window. Also, don't access the OpenGL function across threads.
There is also Windows automatically install the graphics card driver, it is not installed in OpenGL hardware, and must install the driver of the graphics manufacturer!
In addition, the sub-gift full screen display function :)
function FullScreen (win: TWinControl; width, height, bitdepth: integer): boolean; var displaymode: DEVMODE; begin FillChar (displaymode, sizeof (displaymode), 0); with displaymode do begin dmSize: = sizeof (displaymode); dmPelsWidth: = width; dmPelsHeight: = height; dmBitsPerPel: = bitdepth; dmFields: = DM_BITSPERPEL or DM_PELSWIDTH or DM_PELSHEIGHT; end; if ChangeDisplaySettings (displaymode, CDS_FULLSCREEN) = DISP_CHANGE_SUCCESSFUL then begin ShowWindow (win.Handle, WS_MAXIMIZE); result: = true; end Else Result: = false;
Procedure Restoredisplay; Begin ChangeDisplaySettings (PDEVMODE (0) ^, 0); ShowWindow (Win.Handle, Sw_Restore); END;
=========================================
Li QingruiHttp: //wrighteagle.org/Appdev