NEHE OpenGL Tutorial Delphi Edition (1) ---- Basic Framework

zhaozj2021-02-16  45

The OpenGL framework of Nehe's VC translated by cker into the delphi version, I hope to help the brothers who use Delphi OpenGL, I don't know why, I can't run directly in my Delphi environment, but don't seem to have no problem in other machines. The machine can only compile the EXE file. Thanks to Nehe's so good frame, thank you cker translation VC information

PROGRAM Project1;

Uses OpenGL, Windows, Messages;

Const wnd_title = 'OpenGL Basic Frame'; // Title VAR / / =================================== ================================================== each OpenGL is connected to one Coloring a description table. Color Description Table Connect all OpenGL calls commands to the Device Context, define the OpenGL's coloring description table as HRC, let the program can / / enough to draw the window, you also need to create a device description Table, Windows Device Description Table is defined as HDC, // DC connects the window to the GDI (Graphics Device Interface graphics). RC connects OpenGL to DC. / / =========================================================================================================================================================================================== ==================================== Hglrc; // rendering context (Color Description Table). H_dc: hdc; // device context h_wnd: hwnd; // window handle h_instance: hinst; // program instance (instance). Keys: array [0..255] of boolean; // The array of keyboard routines {$ r * .res}

/ / =========================================================================================================================================================================================== ================================= Reset the size of the OpenGL scene, regardless of whether the size of the window has changed (assuming no Use full screen mode). // Even the size of the window is not changed (for example, in full screen mode), it will still run once -------- // Set a perspective at the beginning of the program. The size of the OpenGL scene will be set to the size of the window in which it is displayed. / / =========================================================================================================================================================================================== ======================================== Procedure GlResizeWnd (width, height: integer); // Reset and initialize the GL window size Begin If (height = 0) THEN / / Prevent height 0, resulting in 0 abnormal height: = 1; GLVIEWPORT (0, 0, width, height); // Reset the current viewport (Viewport)

// The following behavior perspective settings screen. It means that the farther things look smaller. Do this created a scene of a real // appearance. Here, perspective is calculated according to the 45 degree view of the window width and height. 0.1f, 100.0f is // We can draw the starting point and end of the depth in the scene. // GlmatrixMode (GL_PROJECTION) indicates that the next two lines of code will affect the Projection Matrix (Projection Matrix). // The projection matrix is ​​responsible for increasing perspective for our scene. // GLLoadIdentity () approximates reset. It restores the selected matrix state into its original state. // We will set up a perspective for the scene after calling GLLoadIdentity ().

GLmatrixMode (GL_PROJECTION); // Select Projection Matrix GLLoadIdentity (); // Reset Projection Matrix

Gluperspective (45.0, Width / Height, 0.1, 100.0); // Calculate the appearance ratio of the window

// GlmatrixMode (GL_ModelView) indicates that any new transformation will affect ModelView Matrix. // Model observation matrix stores our object information.

Glmatrixmode (GL_MODELVIEW); // Select model observation matrix GLLoadIdentity (); // Reset model observation matrix // If you still can't understand the meaning of these terms, please don't worry. // Just know if you want to get a wonderful perspective scene, you must do this. END;

/ / =========================================================================================================================================================================================== ================================= All settings for OpenGL. Set the color used by the Clear screen, open the depth cache, // Enable smooth shading, and so on. This routine will be called until the OpenGL window is created. // This process will have a return value. But the initialization here is not so complicated, and it is still not worried about this return value. / / =========================================================================================================================================================================================== ===============================

Procedure glinit (); begin

/ / Set the color used when the screen is cleared. If you don't know how to work with the color of the color, you will quickly explain it. // The range of color values ​​range from 0.0F to 1.0f. 0.0F represents the most dark situation, 1.0f is the brightest situation. // The first parameter after GlclearColor is Red INTENSITY (red component), the second is green, the third is blue. // The maximum value is also 1.0F, represents the brightest situation of a particular color component. The last parameter is an alpha value. // When it is used to clear the screen, you don't have to care about the fourth number. Now let it be 0.0F. // By mixing three primary colors (red, green, blue), you can get different colors //, therefore, using GlclearColor (0.0F, 0.0F, 1.0F, 0.0F), you can clear the screen. // If you use GlclearColor (0.5F, 0.0F, 0.0F, 0.0F), it will be used to clear the screen. / / Is not the brightest (1.0F), nor is the darkest (0.0F). To get a white background, you should set all the colors to the brightest (1.0F). // If you want a black background, you will set all the colors to the darker (0.0F).

GlclearColor (0.0, 0.0, 0.0, 0.0); // black background

/ / The shadow is smooth through the fine mixed colors of polygons, and the external light is smooth. Glshademodel (GL_SMOOTH); // Enable shadow smooth

// The next must be done is about Depth Buffer. Depending on the depth cache as the layer behind the screen. // Depth cache continues to track the object into the screen. This program does not actually use depth cache, //, but almost all on the screen display 3D scene OpenGL programs use depth cache. Its sort determines the object to draw first. // This does not give a square on a circular shape to a circular shape. The depth cache is an important part of OpenGL.

GLCLEARDEPTH (1.0); // Set depth cache Glenable (GL_Depth_test); // Enable depth test GLDEPTHFUNC (GL_SS); // The type of depth test

/ / Then tell OpenGL we want to make the best perspective correction. // This will be very slightly influenced. But make perspective look good.

GLHINT (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); / / True fine perspective correction

END;

/ / =========================================================================================================================================================================================== ====================================== // All draw code. Any Dongdong that you want to display on the screen will appear in this code. // Each program will add new code here. / / =========================================================================================================================================================================================== ===============================

Procedure gldraw (); begin glclear (gl_color_buffer_bit or gl_depth_buffer_bit); // Clear the screen and depth cache GLLoadIdentity (); // Reset the current model observation matrix END;

Function WndProc (HWND: HWND; // Handle MSG: UINT; // Window Message WPARAM: WPARAM; // Additional Message Content LParam: lparam // Additional Message Content): LRESULT; STDCALL; Begin Result: = 0; Case (MSG) OF / / Check Windows Message WM_ACTIVATE: // Monitor window Activate message begin end; wm_create: // Create Begin End; WM_Close: // Close Begin PostquitMessage (0); // Send Exit Message Result: = 0 end; wm_keydown: // Press Begin Keys [wparam]: = true; // If yes, set to true result: = 0; end; wm_keyup: // Press to loose Begin Keys [wparam]: = false; // If yes, set to false results: = 0; end; wm_size: // Adjust the OpenGL window size Begin GlResizeWnd (Loword (LPARAM), HI Word (LPARAM)); // loword = width, HiWord = Height Result: = 0; END; WM_TIMER: / / TIMERS BEGIN END; ELSE / / The rest of the Windows self-handling. Result: = DEFWINDOWPROC (HWND, MSG, WPARAM, LPARAM); // Pass all unprocessed messages to DEFWINDOWPROC.

End; end; // ============================================ ======================================== // only calls before the program exits. The role is to release coloring description tables, device descriptive tables and window handles. // Add a lot of error checks. If the program does not destroy any part of the window, the // message window with the corresponding error message will pop up, // =========================== ============================================================================================================================================================================================================= = Procedure GlkillWnd (Fullscreen: Boolean); Begin

// The first thing to killglwindow () is to check if it is full screen mode. // If it is, you want to switch back to the desktop. This should be destroyed before disabling full-screen mode, // But doing this on some graphics causing the desktop. So before you first disable full screen mode. // This will prevent the desktop from crashing and work very well on NVIDIA and 3DFX graphics cards!

If fullscreen dam? Is it in full screen mode? Begin // returns to the original desktop using ChangeDisplaySettings (NULL, 0). // Take NULL as the first parameter, // 0 As the second parameter, force Windows uses the value of the current stored in the registry // (default resolution, color depth, refresh frequency, etc.) to be effective Restore my original desktop. / / After retrofitting the desktop, the mouse pointer is also re-visible.

ChangeDisplaySettings (devmode (nil ^), 0); // is, switch back to desktop showcursor (TRUE); // Displays the mouse END;

// Is there a coloring description table (HRC). If H_RC> 0 THEN / / We can release it (separated from HRC from HDC). IF (NOT WGLMAKECURRENT (H_DC, 0)) The MessageBox (0, 'DC and RC cannot be released!', 'Error', MB_OK or MB_ICONERROR);

/ / Can delete a colored description table if (NOT WGLDELETECONTEXT (H_RC)) THEN Begin MessageBox (0, 'Deleting Color Description Table Failed!', 'Error', MB_OK or Mb_ICONERROR); H_RC: = 0; End; // Whether There is a device descriptor table if there is an attempt to release it. IF ((H_DC> 0) and (ReleaseDC (H_Wnd, H_DC) = 0)) The begin MessageBox (0, 'Release Device Description Table Failed!', 'Error', MB_OK or MB_ICONERROR); H_DC: = 0; End;

/ / Whether there is a window handle, call DESTROYWINDOW (HWND) to try to destroy the window IF ((h_wnd <> 0) and (Not DestroyWindow (H_Wnd))) The begin MessageBox (0, 'Unable to destroy the form!', 'Error' , MB_OK or MB_ICONERROR); h_wnd: = 0;

// Logout window class // This allows us to destroy the window normally, then when you open another window, // does not receive an error message such as "Windows Class Already Registered" (window classes). IF (NOT UnregisterClass ('OpenGL', Hinstance)) THEN BEGIN MessageBox (0, 'Unable to log out window class!', 'Error', MB_OK or MB_ICONERROR); Hinstance: = 0; end; End;

/ / =========================================================================================================================================================================================== =============================== // Create an OpenGL window, // With 5 parameters: Window's title bar, window The width, the height of the window (16/24/32), // full screen sign (True - full screen mode, FALSE - window mode). // The returned Boolean window is successfully created. / / =========================================================================================================================================================================================== ================================================================================================================================================ Var Wndclass: Twndclass; // Window DWStyle: DWORD; // Window Style DWEXStyle: DWORD; / / Extension Window Style Pixelformat: Gluint; // Pixel Format H_InStance: Hinst; // Current Instance DMSCREENSETTINGS: DEVMODE; / / Equipment Mode PFD: TpixelformATDEScriptor; // Format Descriptor

Begin h_instance: = getModuleHandle (NIL); // Get the example of the window ZeromeMory (@wndclass, sizeof (wndclass))); // Initialize the memory with With WndClass do // Settings window class begin style: = cs_hredraw or/ If the length changes, CS_VREDREDRAW OR // If the height change is as long as the change will force the CS_OWNDC; // CS_OWNDC to create a private DC for the window. This means that the DC cannot share between the program. LpfnWndproc: = @wndproc; // wndproc processing message // cbclsextra: = 0; // No additional window data // CbWndextra: = 0; // No additional window data Hinstance: = h_instance; // Setting instance // Hicon: = LOADICON (0, IDi_winlogo); // Load the default icon hcursor: = loadingcursor (0, IDC_ARROW); // Load mouse pointer // hbrbackground: = 0; // GL does not need background // lpszMenuname: = ' '; // Don't need menu lpszclassname: =' OpenGL '; // Settings the class end; if (RegisterClass (WNDCLASS) = 0) THEN // Register Form Begin MessageBox (0,' Registration Forms failed! ',' error ', MB_OK Or MB_ICONERROR); Result: = False; Exit End; // if desired it fullscreen If fullscreen then Begin ZeroMemory (@dmScreenSettings, SizeOf (dmScreenSettings)); // ensure that the memory allocation With dmScreenSettings Do Begin / / Set the parameter: = sizeOf (dmscreensettings); // devmode structure size DMPELSWIDTH: = width; // selected screen width DMPELSHEI ght: = Height; // selected screen height dmBitsPerPel: = PixelDepth; // color depth per pixel selected dmFields: = DM_PELSWIDTH // set the initial flag and dmPelsWidth Or DM_PELSHEIGHT // dmPelsHeight Or DM_BITSPERPEL; // dmBitsPerPel End ;

// Convert to full screen mode, // Switch to match the DMSCREENSETTINGS. // CDS_FULLSCREEN removes the status bar. // and ensure that you don't move or change your window on your desktop when you swithel. // converted to full-screen mode If (ChangeDisplaySettings (dmScreenSettings, CDS_FULLSCREEN) = DISP_CHANGE_FAILED) Then // conversion failure Begin MessageBox (0, 'can not be converted to full-screen mode!', 'Error', MB_OK Or MB_ICONERROR); Fullscreen: = False; End; End; if (fullscreen) THEN / / is still in full screen mode Begin DWStyle: = WS_POPUP OR / / No Border WS_CLIPCHILDREN / / Let OpenGL run normally, these two attributes are necessary. Or ws_clipsiblings; // They prevent other forms from drawing in our form / draw. DWEXSTYLE: = WS_EX_APPWINDOW; // The form is visible to the front showcursor (false); // Does not display the mouse end else // Otherwise, begin dWStyle: = WS_OVERLAPPEDWINDOW OR / / with title bar, variable size border, menu and maximum / Minifine button WS_CLIPCHILDEN OR / / To make OpenGL run normally, these two attributes are necessary. WS_CLIPSIBLINGS; // They prevent other forms from drawing in our form. DWEXStyle: = WS_EX_APPWINDOW OR // Enhances the 3D Movement WS_EX_WINDOWEDGE; / / Border as raised showcursor (false); // does not display the mouse end;

// Create a form h_wnd: = CREATEWINDOWEX (DWEXSTYLE, / / ​​Extension Form "OpenGL ', // Class Name WND_TITLE, / / ​​Title DWStyle, // Form Properties 0, 0, // Form Location Width, Height, // Form size 0, // There is no parent window 0, // no menu h_instance, // instance handle nil); // Do not pass any stuff to WM_CREATE

If h_wnd = 0 THEN / / Creation Failure, Destroy Form Begin GlkillWnd (Fullscreen); MessageBox (0, 'Can't create a form!', 'Error', MB_OK or MB_ICONERROR); result: = false; exit; / Describe the pixel format // Select the format of OpenGL and dual cache through RGBA (red, green, blue, alpha channel). // Try to find a pixel format that matches the selected color depth (16-bit, 24-bit, 32-bit). // Finally set up 16-bit Z-cache. // The rest of the parameters either do not use or not important // (Stencil Buffer Template Cache, and Accumulation Buffer Aggregation Cache).

With pfd Do Begin nSize: = SizeOf (TPIXELFORMATDESCRIPTOR); // Format Descriptor Size nVersion: = 1; // version dwFlags: = PFD_DRAW_TO_WINDOW // format must support window Or PFD_SUPPORT_OPENGL // format must support OpenGL Or PFD_DOUBLEBUFFER; // Double buffer ipixeltype: = pfd_type_rgba; // Apply RGBA format ccolorbits: = pixeldepth; // Select Color Depth Credbits: = 0; // ignored color bit Credshift: = 0; // ignore color bit cgreenbits: = 0; // ignored color bit cgreenshift: = 0; // ignored color bit cbluebits: = 0; // ignored color bit CBLUESHIFT: = 0; // ignored color bit Calphabits: = 0; // No alpha Cache Calphashift: = 0; // ignore Shift Bit Caccumbits: = 0; // No aggregation CaccumRedbits: = 0; // ignore the gathering position caccumgreenbits: = 0; // ignore the aggregate position caccumbluebits: = 0; // ignore the gathering Caccumalphabit S: = 0; // ignore the gathered position cdepthbits: = 16; // 16-bit Z-cache (depth cache) cstencilbits: = 0; // No template cache CAUXBUFFERS: = 0; // No auxiliary cache ILAYERTYPE: = PFD_MAIN_PLANE ; // Mainly drawing the layer BRESERVED: = 0; // Keep dwlayermask: = 0; // ignore the layer mask dwvisiblemask: = 0; // ignore the layer mask dwdamagemask: = 0; // ignore the layer mask END; / / Get the device scene description h_dc: = getdc (h_wnd); if (h_dc = 0) Then Begin GlkillWnd (Fullscreen); // Creating Fail, Destroy Form MessageBox (0, 'Can't get the device scene!', 'Error'

, MB_OK or MB_ICONERROR); Result: = false; exit; end; // Find the corresponding pixel format Pixelformat: = choosepixelformat (h_dc, @pfd); if (Pixelformat = 0) Then Begin Glkillwnd (Fullscreen); MessageBox (0 , 'Find the right format', 'error', MB_OK or MB_ICONERROR); result: = false; exit;

// Set pixel format. If setpixelformat (h_dc, pixelformat, @PFD)) The begin Glkillwnd (Fullscreen); MessageBox (0, 'Unable to create rendering format ",' error ', MB_OK or MB_ICONERROR); Result: = false ;

// Get coloring description table h_rc: = wglcreateContext (h_dc); if (h_rc = 0) THEN BEGIN GLKILLLWND (FULLSCREEN); MessageBox (0, 'Unable to create OpenGL Draw Description Table', 'Error', MB_OK or Mb_ICONERROR); Result : = FALSE; EXIT;

// The device description table and coloring description have been obtained. // Activate coloring description If (Not wglMakeCurrent (h_DC, h_RC)) Then Begin glKillWnd (Fullscreen); MessageBox (0, 'Unable to activate OpenGL rendering context', 'Error', MB_OK Or MB_ICONERROR); Result: = False; EXIT; END; // OpenGL window has been created

// Display the form, placed in the top showwindow (h_wnd, sw_show); // Display window setForegroundWindow (h_wnd); // 提 提 优 s sc oCus (h_wnd); // Set the focus of the keyboard to this window

GlResizeWnd (width, height); // Set Poscope GL screen glinit (); // Initialize the new GL window

RESULT: = True; End;

Function WinMain (Hinstance: hinst; // instance hinst; // Previous instance lpcmdline: pchar; // command line parameter ncmdshow: integer // window display status): Integer; stdcall; var msg: TMSG; // WindowsXXX Message structure finished: boolean; // Used to exit the BOOL variable becom finished: = false; // application initialization // GLCREATEWND, create a form 800 * 600 if not GlcreateWnd (800, 600, false, 32) THEN Begin Result: = 0; exit;

While Not Finished Do Begin // Check a thread message queue, saving the selected range to the message record // Bool PeekMessage (// lpmsg lpmsg, // message record pointer // hwnd hwnd, // window handle // UINT WMSGFILTERMIN, / / ​​First message // uint WMSGFILTERMAX, / / ​​Last message // uint wremovemsg // flag value meaning //); after the PM_NOREMOVE is processed, retain it from the message queue in the message queue after // PM_Remove processing // The first thing to do is to check if there is a message waiting. // Use peekMessage () to check the message without locking our programs. // Many programs use getMessage () or work well. / / But use getMessage (), the program will not do anything before receiving a PAINT message or other window message. IF (PeekMessage) then // Check if there is message // WMSGFILTERMIN, WMSGFiltermax These two parameters are 0, return all available messages Begin if (msg.Message = WM_QUIT) THEN // If you are an exit message Finished: = true // change the loop condition, exit the ELSE begin // Otherwise, the message // translate message, then send the message so that WndProc () or Windows can handle them. TranslateMessage (MSG); // Translation Message DispatchMessage (MSG); // Send Message End; END ELSE // If there is no message, we draw our OpenGL scene. Begin gldraw (); // Heavy painting screen swapbuffrs (h_dc); // switched cache (dual cache)

IF (Keys [vk_escape]) then // If the ESC key Finished: = true end; end; glkillwnd (false); // Release form result: = msg.wpaaM; // exits the program END;

Begin Winmain (Hinstance, Hprevinst, cmdline, cmdshow); END.

转载请注明原文地址:https://www.9cbs.com/read-25044.html

New Post(0)