Convert NeHe's VC OPENGL framework translated by CKER into the Delphi version.
I hope it will be helpful to brothers who use Delphi to learn OPENGL.
I don’t know why, but it can’t run directly in my Delphi environment, but it seems to be fine on other machines.
My machine can only compile and run EXE files.
Thanks to NeHe for providing such a good framework, and thanks to CKER for translating VC information.
PROgram Project1;
Uses
opengl,
windows,
Messages;
Const
WND_TITLE = 'OPenGl basic framework'; //Title
Var
//================================================ ===========================
// Each OpenGL is connected to a shading context table. The shading context connects all OpenGL calls to
// Receive the Device Context (device description table) and define the OpenGL shading description table as hRC, so that the program can
// If it is enough to draw the window, you also need to create a device description table. The Windows device description table is defined as hDC,
// DC connects the window to GDI (Graphics Device Interface). And RC connects OpenGL
// to DC.
//================================================ ===========================
h_RC: HGLRC; // Rendering Context (shading description table).
h_DC: HDC; // Device Context (device description table)
h_Wnd: HWND; // window handle
h_Instance: HINST; // Program Instance (instance).
keys : Array[0..255] Of Boolean; // Array for keyboard routines
{$R *.res}
//================================================ ==============================
//Reset the size of the OpenGL scene regardless of whether the window size has changed (assuming full screen mode is not used).
//Even when the window cannot be resized (e.g. in full screen mode), it will still run at least once————————
//Set the 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 the height from being 0 and causing a divide-by-0 exception.
Height := 1;
glViewport(0, 0, Width, Height); //Reset the current viewport (Viewport)
//The following lines set up the perspective screen. This means that things that are further away appear smaller. Doing so creates a reality
//Appearance scene. Perspective here is calculated as a 45 degree viewing angle based on the width and height of the window. 0.1f, 100.0f are
//The starting point and end point of the depth we can draw in the scene.
//glMatrixMode(GL_PROJECTION) specifies that the next two lines of code will affect the projection matrix.
//The projection matrix is responsible for adding perspective to our scene.
//glLoadIdentity() is similar to reset. It restores the selected matrix state to its original state.
//After calling glLoadIdentity() we set the perspective for the scene.
glMatrixMode(GL_PROJECTION); //Select the projection matrix
glLoadIdentity(); // Reset the projection matrix
gluPerspective(45.0, Width / Height, 0.1, 100.0); // Calculate the appearance proportion of the window
//glMatrixMode(GL_MODELVIEW) specifies that any new transformation will affect the modelview matrix (model observation matrix).
//Our object information is stored in the model observation matrix.
glMatrixMode(GL_MODELVIEW); //Select model observation matrix
glLoadIdentity(); //Reset model observation matrix
//If you don’t understand what these terms mean just yet, don’t worry.
//Just know that you have to do this if you want to get a great perspective scene.
End;
//================================================ ==============================
// Make all settings for OpenGL. Set the color to clear the screen, turn on the depth cache,
// Enable smooth shading (shadow smoothing), etc. This routine is not called until the OpenGL window is created.
// This process will have a return value. But the initialization here is not that complicated, and there is no need to worry about the return value yet.
//================================================ ==============================
Procedure glInit();
Begin
//Set the color used when clearing the screen. If you're not sure how color works, here's a quick explanation.
//Color values range from 0.0f to 1.0f. 0.0f represents the darkest situation, and 1.0f is the brightest situation.
//The first parameter after glClearColor is Red Intensity (red component), the second is green, and the third is blue.
//The maximum value is also 1.0f, which represents the brightest case of a specific color component. The last parameter is the Alpha value.
//When it is used to clear the screen, don't care about the fourth number. Now let it be 0.0f.
//By mixing three primary colors (red, green, blue), you can get different colors
//So, use glClearColor(0.0f,0.0f,1.0f,0.0f), your blue to clear the screen.
//If you use glClearColor(0.5f,0.0f,0.0f,0.0f), medium red will be used to clear the screen.
//Not the brightest (1.0f), nor the darkest (0.0f). To get a white background, all colors should be set to their brightest (1.0f).
//If you want a black background, set all colors to the darkest (0.0f).
glClearColor(0.0, 0.0, 0.0, 0.0); // black background
//Shadow smoothing finely blends colors through polygons and smoothes external light.
glShadeModel(GL_SMOOTH); // Enable shadow smoothing
//The next thing that must be done is about the depth buffer. Think of the depth buffer as a layer behind the screen.
//The depth buffer continuously keeps track of how deep the object enters the screen. This program actually does not actually use the depth cache.
//But almost all OpenGL programs that display 3D scenes on the screen use depth buffers. Its ordering determines which object is drawn first.
//This way you don't draw a square behind a circle onto the circle. The depth buffer is a very important part of OpenGL.
glClearDepth(1.0); //Set the depth buffer
glEnable(GL_DEPTH_TEST); // Enable depth testing
glDepthFunc(GL_LESS); // Type of depth test done
//Then tell OpenGL that we want the best perspective correction possible.
//This will affect performance very slightly. But makes the perspective look a little better.
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really fine perspective correction
End;
//================================================ ==============================
//All drawing code. Anything you want to display on the screen will appear in this code.
//Every future program will add new code here.
//================================================ ==============================
Procedure glDraw();
Begin
glClear(GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT); // Clear the screen and depth buffer
glLoadIdentity(); //Reset the current model observation matrix
End;
Function WndProc(hWnd: HWND; // handle of window
Msg: UINT; // Window message
wParam: WPARAM; // Additional message content
lParam: LPARAM // Additional message content
): LRESULT; stdcall;
Begin
Result := 0;
Case (Msg) Of // Check Windows messages
WM_ACTIVATE: // Monitor window activation message
Begin
End;
WM_CREATE: // Create
Begin
End;
WM_CLOSE: // close
Begin
PostQuitMessage(0); //Send exit message
Result := 0
End;
WM_KEYDOWN: // key pressed
Begin
keys[wParam] := True; // If yes, set to TRUE
Result := 0;
End;
WM_KEYUP: // Release the key
Begin
keys[wParam] := False; // If yes, set to FALSE
Result := 0;
End;
WM_SIZE: //Adjust OpenGL window size
Begin
glResizeWnd(LOWord(lParam), HIWORD(lParam)); //LoWord=Width,HiWord=Height
Result := 0;
End;
WM_TIMER: //timers
Begin
End;
Else //Let Windows handle the rest.
Result := DefWindowProc(hWnd, Msg, wParam, lParam); // Pass all unprocessed messages to DefWindowProc.
End;
End;
//================================================ ==============================
// Only called before the program exits. The function is to release the coloring context table, device context table and window handle in sequence.
// Added a lot of error checking. If the program is unable to destroy any part of the window, an appropriate error message will pop up.
// message window,
//================================================ ==============================
Procedure glKillWnd(Fullscreen: Boolean);
Begin
//The first thing done in KillGLWindow() is to check whether it is in full screen mode.
//If yes, switch back to the desktop. The window should have been destroyed before disabling full screen mode,
//But doing this on some graphics cards may crash the desktop. So it’s better to disable full screen mode first.
//This will prevent desktop crashes and works great on both Nvidia and 3dfx graphics cards!
If Fullscreen Then // In full screen mode?
Begin
// Use ChangeDisplaySettings(NULL,0) to return to the original desktop.
// Take NULL as the first parameter,
// Passing 0 as the second parameter forces Windows to use the value currently stored in the registry
// (default resolution, color depth, refresh rate, etc.) to effectively restore my original desktop.
// After switching back to the desktop, the mouse pointer must be made visible again.
ChangeDisplaySettings(devmode(Nil^), 0); // If yes, switch back to the desktop
ShowCursor(True); //Show mouse
End;
//Whether it has a coloring description table (hRC).
If h_RC > 0 Then
//See if we can free it (separate hRC from hDC).
If (Not wglMakeCurrent(h_DC, 0)) Then
MessageBox(0, 'DC and RC cannot be released!', 'Error', MB_OK Or
MB_ICONERROR);
// Can the shading description table be deleted?
If (Not wglDeleteContext(h_RC)) Then
Begin
MessageBox(0, 'Failed to delete shading context table!', 'Error', MB_OK Or
MB_ICONERROR);
h_RC := 0;
End;
//Whether the device context table exists, and if so, try to release it.
If ((h_DC > 0) And (ReleaseDC(h_Wnd, h_DC) = 0)) Then
Begin
MessageBox(0, 'Failed to release device context!', '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))) Then
Begin
MessageBox(0, 'Cannot destroy form!', 'Error', MB_OK Or
MB_ICONERROR);
h_Wnd := 0;
End;
//Log out window class
//This allows us to destroy the window normally and then when other windows are opened,
//You will not receive error messages such as "Windows Class already registered" (window class already registered).
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;