OpenGL programming principle under Windows95NT

xiaoxiao2021-03-06  41

WINDOWS95 / NT OpenGL programming principle Xi'an Jiaotong University 9693 Mailbox Cai Mao - Scientific Calculation Visualization, computer animation and virtual reality are three hotspots in computer graphics. The core of these three hotspots is drawn by three-dimensional realistic graphics. Since OpenGRAPHICSLIBRAR has a cross-platform, simple, efficient, and functional perfect, it has now become a three-dimensional graphics production method in fact industrial standards. Since WindowsNT3.51 supports OpenGL on the microcomputer platform, Microsoft provides an OpenGL development environment in Windows95OSR2, WindowsNT4.0. Visualc has fully supported OpenGL API after version 4.2, so that "civilianization" in the three-dimensional world has become inevitable.

---- WINDOWS operating system supports OpenGL support

---- People with Windows programming experience know that in Windows, use the GDI mapping must call the corresponding function through the DeviceContext Shop DC); the OpenGL mapping is similar, the OpenGL function is through "rendering context" ( RenderingContext Shop RC) Draw a drawing of 3D graphics. Windows and device contexts support "Pixelformat" attributes, and RC has the same as the bitmap structure. Just establish contact with a DC when creating RC (RC can only be created by DC that has established bitmap format), OpenGL's function can be drawn to the corresponding display device via DC corresponding to the RC. There is also the following aspects:

---- 1. A thread can only have a rendering context (RC), that is, if the user is made to different devices within a thread, only the DC corresponding to the RC is completed, while the RC is threaded Remain unchanged. (Of course, after deleting the old RC, create a new one), corresponding to this, one RC can only belong to a thread and cannot be shared simultaneously by different threads.

---- 2. Set the DC bitmap format is equal to the bitmap format of the corresponding window, and the DC and the window's bitmap format can no longer change again. This can only be improved in the future Windows version.

---- 3. Although the DC can be replaced, only one DC can be utilized at any time (this DC called RC's current DC), but because a window can make multiple DC mapping so that multiple threads can be utilized Multiple RC performs OpenGL operations on this window.

---- 4. The OpenGL version under Windows has a certain limit on OpenGL and GDI on the same DC. When using the double cache OpenGL generates an animation, the GDI function cannot be used to map the DC.

---- 5. Not recommended with ASIC to write OpenGL programs under Windows. Such programs have a cross-platform portability (such as many SGI examples), but they cannot use a lot of features of the Windows operating system, and the practical value is not large.

---- Use VC to write OpenGL programs ---- After the above analysis, the method of calling the OpenGL mapping with VC is obvious. Proceed as follows:

---- 1. First set the bitmap format (Pixelformat property of the display device DC. This is done by filling a structure of a PixelformatDescriptor (see the help information of the data in PixelformATDescriptor), which determines the properties of the physical device of the OpenGL mapping, such as the data item dwflags in this structure DWFLAGS PFD_Doublebuffer If there is no setting (set 1), the OpenGL commands made by the DC of the device cannot be animated using a double buffer. There are some bitmap formats (Pixelformat) is supported by DC, and some DCs are not supported. So the program must first use ChoosepixElFormat to select the bitmap format that the DC supported with the nature bitmap format, and then set the DC bitmap format with SetpixElFormat.

---- 2. Establish a rendering context RC (WGLCReateContext) using the original device DC, so that the RC is connected to the DC (WGLmakecurrent).

---- 3. Call the OpenGL function mapping. Because the thread is corresponding to the RC one-to-one, the handle of this thread RC is not referred to in the parameters of the OpenGL function.

---- 4. After the drawings, first click the RC of the current thread to null (:: wglmakecurrent (null);), disconnect the current thread and the rendering context, thereby disconnects to DC contact. At this point, the effectiveness of the RC handle is not clear in Microsoft's own document, so when it deletes the RC later, it is necessary to judge the validity of the following RC handle (if (m_hrc) :: wgldeleteContext (m_hrc);). Release the situation (ReleaseDC) or deletedc DC

---- The apartment is explained

---- The attached program has completed a simple OpenGL mapping with MFC, and draws a solid sphere with OpenGL's auxiliary library. The function of OpenGL itself is not explained here, only a brief description of the content you need to pay attention only when using the MFC OpenGL:

---- 1. Once a DC bitmap format is set, the bitmap format of the window contacted by the DC is set. If the window contains a sub-window or has a brother window, the bitmap format of these brothers / sub-windows is not set to format that correspond to the corresponding RC, and OpenGL is easier to make an error above them. OpenGL window must therefore have plotted WS_CLIPSIBLINGS WS_CLIPCHILDREN and style, with the program in the window main frame constructor LoadFrame (IDR_MAINFRAME, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, NULL, NULL); specifies the style of the main window.

---- 2. In the ANSIC OpenGL program, set the OpenGL viewport size and the callback function of the OpenGL viewport size and the status size of the AuxreshapeFunc. The processing function of the WM_SIZ message should be completed in the MFC. In the OpenGL programming of ASIC, the callback function of the mapping is defined by EAUXMAINLOOP. The processing function of the WM_PAINT message should be processed in the MFC. Correspondingly, the keyboard defined by OpenGL, the mouse processing function should be responded by the corresponding Windows handler. ---- 3. OpenGL ourselves have a function GLCLEAR that refreshes the background, so it should be prohibited from refreshing Windows refresh window background. Otherwise, when the window needs to redraw, Windows will automatically send WM_RASEBKGND, and the default handler uses a white background brush. When the background color used by OpenGL is not white, there is a frame of blinking when the figure is made. This phenomenon is particularly obvious when making animations. Only the message processing of the parent window class is forbidden in the message processing function of WM_ERASEBKGND, and simply returns a TRUE.

---- 4. Due to OpenGL's cross-platform, it must use the palette of the operating system. So if the GL_INDEX_MODE is mapping, you must define the palette by VC yourself. However, in general, it is more convenient to use GL_RGBA_MODE mode and rarely used GL_INDEX_MODE mode.

---- 5. During the OpenGL mapping, the DC corresponding to the RC cannot be deleted or released.

---- 6. Due to the OpenGL mapping, it takes a long time to occupy DC, so it is best to set the dynamic window class into a cs_owndc. This property does not have this property in the MFC default window style. In the Program, you registered a window class in the PrcReateWindow method of the main window C class. In addition to setting the cs_owndc property, CS_HREDRAW, CS_VREDRAW, and CS_SAVEBITS are set. Set CS_HREDRAW, CS_VREDRAW is to generate a WM_Paint message when the window is zoomed, correct OpenGL viewport, and mapping size; because the OpenGL mapping requires a lot of calculations, set CS_SAVEBITS is to display when the OpenGL window is covered, do not generate WM_PAINT The message is filled with an image stored in memory, so that the calculation time is used in spatial consumption.

---- 7. There is no handling of the OpenGL function in this program. After OpenGL error, return an error code, not throwing an exception; and after a function error, the subsequent function generally does not appear an exception, just returns an error code, and some errors may be ignored. The judgment of each OpenGL function is more troublesome, so the function of OpenGL should be very careful when programming.

---- Reference book: ---- "OpenGLPROGRAMMER'SGUIDE" SGIINC .---- "OpenGL 3D graphics programming" Liao Duo, Zhang Huajun, Planet Map Publishing House ---- "Visualc 5.0 Online help "

---- The attachment procedures:

---- The program must determine when OpenGL32.DLL, GLU.DLL, GLAUX.DLL in Windows, must be determined. If you can't find these files, you can copy these files from the Windows95OSR2 machine. OpenGL does not require registration library information. When running the program in the VC's Studio, OpenGL.H, Glu.h, Glaux.h, OpenGL.LIB, Glu.Lib, Glaux.lib, GLAUX.LIB must be added to the project file, which comes with the VC.

---- main window class definitions (OpenGLWnd.h):! # If defined (AFX_OPENGLWND_H__3FB1AB28_0E70_11D2_9ACA_48543300E17D__INCLUDED _) # define AFX_OPENGLWND_H__3FB1AB28_0E70_11D2_9ACA_48543300E17D__INCLUDED_ # if _MSC_VER> = 1000 # pragma once # endif // _MSC_VER> = 1000

#include #include "simpleglapp.h" #include "resource.h" // OpenGLWnd.h: Header file //////// CopengLWnd Frame

class COpenGLWnd: public CFrameWnd {DECLARE_DYNCREATE (COpenGLWnd) public: COpenGLWnd (); // protected constructor used by dynamic creationprotected: HGLRC m_hrc; CClientDC * m_pDC; // Attributespublic:

// OperationsPublic:

// Overrides // classwizard generated virtual function overrides // {{AFX_VIRTUAL (COPENGLWND) Protected: Virtual Bool PrecreateWindow (Createstruct & Cs); //}} AFX_VIRTUAL

// ImplementationPublic: Virtual ~ CopenglWnd ();

// Generated message map functions // {{AFX_MSG (COpenGLWnd) afx_msg int OnCreate (LPCREATESTRUCT lpCreateStruct); afx_msg void OnSize (UINT nType, int cx, int cy); afx_msg void OnDestroy (); afx_msg BOOL OnEraseBkgnd (CDC * pDC) AFX_MSG void onpaint (); //}} AFX_MSG DECLARE_MESSAGE_MAP ()};

/////

// {{AFX_INSERT_LOCATION}} // Microsoft Developer Studio Will Insert Additional Declarations Immedierately Before The Previous Line.

#endif //! defined (AFX_OPENGLWND_H__3FB1AB28_0E70_11D2_9ACA_48543300E17D__INCLUDED_) The implementation of the main window class (OpenGLWND.CPP): // OpenGLWnd.cpp: Implementation File //

#include "stdafx.h" #include "opengwnd.h" #include "simpleglapp.h" #include "gl / glu.h" #include "gl / gl.h" #include "gl / glaux.h"

#ifdef _debug # define new debug_new # undef this_filestatic char this_file [] = __file __; # ENDIF

////// CopengLWnd

IMPLEMENT_DYNCREATE (COpenGLWnd, CFrameWnd) COpenGLWnd :: COpenGLWnd () {m_pDC = NULL; m_hrc = 0; LoadFrame (IDR_MAINFRAME, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, NULL, NULL);}

CopENGLWND :: ~ CopengLWnd () {}

BEGIN_MESSAGE_MAP (COpenGLWnd, CFrameWnd) // {{AFX_MSG_MAP (COpenGLWnd) ON_WM_CREATE () ON_WM_SIZE () ON_WM_DESTROY () ON_WM_ERASEBKGND () ON_WM_PAINT () //}} AFX_MSG_MAPEND_MESSAGE_MAP ()

BOOL COpenGLWnd :: PreCreateWindow (CREATESTRUCT & cs) {// TODO: Add your specialized code here and / or call the base classcs.lpszClass = AfxRegisterWndClass (CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_SAVEBITS | CS_NOCLOSE | CS_OWNDC, AfxGetApp () -> LoadStandardCursor ( IDC_ARROW), 0, AFXGetApp () -> LoadStandardIn (IDi_Application)); Return CFrameWnd :: PrecreateWindow (CS);

INT COPENGLWND :: OnCreate (lpcreatestruct lpcreatestruct) {if (cframeWnd :: oncreate (lpcreateStruct) == -1) Return -1; int Pixelformat;

M_PDC = New CclientDC (this); // Make a map assert in the customer area (m_pdc! = null);

static PIXELFORMATDESCRIPTOR pfd = {sizeof (PIXELFORMATDESCRIPTOR), // a fixed value, the fixed value // PFD_DRAW_TO_WINDOW | // support window PFD_SUPPORT_OPENGL | // support OpenGL PFD_TYPE_RGBA, // RGBA mode, no color palette 16, 16 // program Bit colors running 0, 0, 0, 0, 0, 0, // color bits ignored 0, // no alpha buffer 0, // shift bit ignored 0, // no Accumulation buffer 0, 0, 0, 0, // Accum bits ignored 32, // 32-bit z-buffer 0, // no stencil buffer 0, // no auxiliary buffer pfd_main_plane, // main layer 0, // reserved 0, 0, 0 // Layer Masks ignored}; If ((pixelformat = choosepixelformat (m_pdc-> getsafehdc (), & pfd)) == 0) {MessageBox ("bitmap structure close to PFD on this DC"); Return -1;}

IF (setpixelformat (m_pdc-> getsafehdc (), pixelformat, & pfd) == false) {MessageBox ("Unable to set bitmap structure on this DC"); return -1;} m_hrc = wglcreatecontext (m_pdc-> getsafehdc () ); Wglmakecurrent (m_pdc-> getsafehdc (), m_hrc); GLCLEARDEPTH; GLENABLE (GL_DEPTH_TEST);

Glmatrixmode (GL_Projection); GLLoadIdentity (); GLmatrixmode (GL_MODELVIEW); return 0; // OpenGL window construction success}

Void CopENGLWND :: OnSize (uint ntype, int cx, int CY) {cframeWnd :: Onse (NTYPE, CX, CY); // Todo: add your message handler code hereiff (cy> 0) {GLVIEWPORT (0, 0 , CX, CY); GLMATRIXMODE (GL_Projection); GLLoadIdentity (); IF (CX <= cy) glortho (-3.0, 3.0, -3.0 * (GLFLOAT) CX / (GLFLOAT) CY, 3.0 * (GLFLOAT) CX / GLFLOAT) CY, -3.0, 3.0); Else Glortho (-3.0, 3.0, -3.0 * (GLFLOAT) CX, 3.0 * (GLFLOAT) CY / (GLFLOAT) CX, -3.0, 3.0); GLmatrixMode (GL_MODELVIEW);}} void CopenglWnd :: ONDESTROY () {

CframeWnd :: Ondestroy (); :: Wglmakecurrent (NULL, NULL); if (m_hrc) :: WGLDeleteContext (m_hrc); if (m_pdc) delete m_pdc; // Todo: add your message handler code here}

Bool CopenGLWnd :: OneRaseBkgnd (CDC * PDC) {// Todo: add your message hand default return true and / or call default return true; // return cframewnd :: OneRaseBkGnd (PDC);

Void CopENGLWND :: OnPaint () {CPAINTDC DC (this); // Device Context for Painting

GLFLOAT LIGHT_POSITION [] = {2.0F, 0.0F, 4.0F, 0.0F}; // Todo: Add your message Handler Code Here

GlclearColor (0.0F, 0.0F, 0.0F, 1.0F); GLCLEAR (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

GLPUSHMATRIX ();

glTranslatef (0.0f, 0.0f, -2.0f); glLightfv (GL_LIGHT0, GL_POSITION, light_position); glEnable (GL_LIGHTING); glEnable (GL_LIGHT0); glDepthFunc (GL_LESS); glEnable (GL_DEPTH_TEST); auxSolidSphere (1.0);

GLPopmatrix (); GLFINISH ();

// Do not call CFrameWnd :: OnPaint () for painting messages} custom application class (SimpleGLApp.h):! # If defined (AFX_SIMPLEGLAPP_H__3FB1AB29_0E70_11D2_9ACA_48543300E17D__INCLUDED _) # define AFX_SIMPLEGLAPP_H__3FB1AB29_0E70_11D2_9ACA_48543300E17D__INCLUDED_

#iF _MSC_VER> = 1000 # pragma overce # endif //_msc_ver> = 1000 // simpleglapp.h: header file // # include "outwin.h" #include "rentce.h" // /// / CSIMPLEGLAPP THREAD

Class csimpleglapp: public cwinapp {declare_dyncreate (csimpleglapp) public: csimpleglapp (); // protected constructor used by Dynamic Creation

// attributespublic:

// OperationsPublic:

// Overrides // ClassWizard Generated Virtual Function Overrides // {AFX_VIRTUAL (CSIMPLEGLAPP) Public: Virtual Bool InitInstance (); Virtual Int ExitInstance (); ///}} AFX_VIRTUAL

// ImplementationPublic: Virtual ~ csimplegLAPP ();

// generated message map functions // {{AFX_MSG (CSIMPLEGLAPP) AFX_MSG Void onappeXit (); //}} AFX_MSG

DECLARE_MESSAGE_MAP ()};

/////

// {{AFX_INSERT_LOCATION}} // Microsoft Developer Studio Will Insert Additional Declarations Immedierately Before The Previous Line.

#ndif //! defined (AFX_SIMPLEGLAPP_H__3FB1AB29_0E70_11D2_9ACA_4854300E17D__INCLUDED_) Implementation (SimpleGlapp.cpp): // SimpleGlapp.cpp: Implementation File //

#include "stdafx.h" #include "simpleglapp.h" #include "OpenGLWnd.h"

#ifdef _debug # define new debug_new # undef this_filestatic char this_file [] = __file __; # ENDIF

/// / / / CSIMPLEGLAPP

Implement_dyncreate (CSIMplegLAPP, CWINAP)

CSIMPLEGLAPP :: CSIMPLEGLAPP () {}

CSIMPLEGLAPP :: ~ csimpleglapp () {}

BOOL CSimpleGLApp :: InitInstance () {// TODO: perform and per-thread initialization here m_pMainWnd = new COpenGLWnd (); m_pMainWnd-> ShowWindow (m_nCmdShow); m_pMainWnd-> UpdateWindow (); return TRUE;}

INT csimpleglapp :: exitInstance () {Return CWINApp :: exitInstance ();

BEGIN_MESSAGE_MAP (CSimpleGLApp, CWinApp) // {{AFX_MSG_MAP (CSimpleGLApp) ON_COMMAND (ID_APP_EXIT, OnAppExit) //}} AFX_MSG_MAPEND_MESSAGE_MAP () /////// CSimpleGLApp message handlersvoid CSimpleGLApp :: OnAppExit () {// TODO: Add your Command Handler Code Here CWINApp :: onappexit ();

CSIMPLEGLAPP SIMPLEGLAPP;

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

New Post(0)