发信人: mendy.bbs@bbs.nju.edu.cn (孟迪), 信区: cnprogram
标  题: VC 4.0中使用OpenGL(3)
发信站: nju_bbs (Sun Apr 19 13:53:19 1998)
转信站: Lilac!ustcnews!nju_bbs

The Window Procedure 

The application's simple window procedure processes only two messages: 
WM_PAINT and WM_DESTROY. When a WM_PAINT message is received, the window 
procedure calls the DrawHello function; it is in this function where OpenGL

drawing operations take place. 

The first step in DrawHello is to select the rendering context as the 
current context and set the viewport size by calling glViewport. The 
viewport size was obtained by a call to the Win32 GetClientRect function. 
Next, the frame buffer is erased, and an identity transformation matrix is 
loaded. 

The transformation matrix is changed by two subsequent rotations, specified

by calls to glRotated. The first call rotates the view around the vertical 
axis. The second call tips the view forward by rotating it around the 
horizontal axis. As a result, we will see the cube from a viewpoint 
somewhat above and to the left of the cube. 

The rotations are followed by calls that enable lighting mode and specify a

light source. The code specifies a single light source that illuminates the

cube from the left and above. 

With all this initialization work complete, actual drawing can begin. A 
series of six quadrilaterals is drawn, representing the six sides of the 
cube. For each of the quadrilaterals, the normal vector is defined by a 
separate call to glNormal3d. When the construction of the six primitives is

complete, a call to glFlush is used to ensure that all OpenGL operations 
are complete, and then the device context is released and the function 
returns. 

                   Compiling and Running the Application 

This application can be compiled simply from the command line. I called the

source file cube.c; to compile this file, type the following: 

cl cube.c user32.lib gdi32.lib opengl32.lib 

Note that applications that use the GLU Library or the GLAUX Library must 
also specify glaux.lib or glu32.lib on the command line. And because OpenGL

is computation-intensive, it might be a useful idea to compile with the 
appropriate optimization flags set. 

The application should display a window with a three-dimensional image of a

cube rendered in it, similar to that shown in Figure 41.2. 

Figure 41.2. Running the cube.exe Windows application. 

                        OpenGL in MFC Applications 

The OpenGL Library can easily be utilized from MFC applications as well. To

enable the OpenGL libraries, add the appropriate library names to your 
project settings (Figure 41.3). 

Figure 41.3. Adding the OpenGL libraries to MFC project settings. 

When initializing the OpenGL Library in an MFC application, it is important

to remember which window you wish to use for a rendering context. For 
example, if it is a view window that will serve as the rendering context, 
it is this window that should be used when the OpenGL rendering context is 
created. 

                           OpenGL initialization 

The MFC OpenGL application I created is based on an AppWizard-generated 
single document interface application skeleton. 

In this application, we draw a cube identical to the cube drawn in the C 
application discussed earlier. The cube is drawn into the application's 
view window. Accordingly, the first task after creating the application's 
skeleton is to modify the view class's PreCreateWindow member function, to 
ensure that the view window is created with the appropriate flags. 

The modified version of this function is shown in Listing 41.2. 

     Listing 41.2. Modified version of CCubeView::PreCreateWindow. 

BOOL CCUBEView::PreCreateWindow(CREATESTRUCT& cs) 

    // TODO: Modify the Window class or styles here by modifying 
    //  the CREATESTRUCT cs 
    cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN; 
    return CView::PreCreateWindow(cs); 


As you can see, the change to this function is simple; it consists only of 
adding the WS_CLIPSIBLINGS and WS_CLIPCHILDREN flags to the window style to

ensure proper operation of the OpenGL libraries. 

Much more extensive initialization work is performed in the view class's 
OnCreate member function. This member function must be added using 
ClassWizard or the WizardBar, as a handler function for WM_CREATE messages.

The implementation of this function, shown in Listing 41.3, creates a 
rendering context after setting a pixel format for the view window's device

context. 

     Listing 41.3. Implementation of CCubeView::OnCreate. 

int CCUBEView::OnCreate(LPCREATESTRUCT lpCreateStruct) 

    PIXELFORMATDESCRIPTOR pfd; 
    int iPixelFormat; 
    CDC *pDC; 
    if (CView::OnCreate(lpCreateStruct) == -1) 
        return -1; 
    // TODO: Add your specialized creation code here 
    pDC = GetDC(); 
    memset(&pfd, 0, sizeof(pfd)); 
    pfd.nSize = sizeof(pfd); 
    pfd.nVersion = 1; 
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; 
    pfd.iPixelType = PFD_TYPE_RGBA; 
    pfd.iLayerType = PFD_MAIN_PLANE; 
    pfd.cDepthBits = 16; 
    iPixelFormat = ChoosePixelFormat(pDC->m_hDC, &pfd); 
    SetPixelFormat(pDC->m_hDC, iPixelFormat, &pfd); 
    m_hglrc = wglCreateContext(pDC->m_hDC); 
    ReleaseDC(pDC); 
    return 0; 


The rendering context handle is stored in the member variable m_hglrc. This

member variable should be added to the declaration of the view class in the

Attributes section, as follows: 

class CCUBEView : public CView 

    ... 
// Attributes 
public: 
    CCUBEDoc* GetDocument(); 
HGLRC m_hglrc; 
... 

                             Drawing the Cube 

The actual drawing of the cube is performed in the OnDraw member function 
of the view class. This member function, shown in Listing 41.4, is very 
similar to the DrawHello function of the C application presented earlier in

this chapter. After making the rendering context current, the function 
performs a series of initializations, including setting the size of the 
viewport, applying coordinate transformations, and setting up lighting. 
Afterwards, four quadrilaterals that together comprise the cube are drawn. 

     Listing 41.4. Implementation of CCubeView::OnDraw. 

void CCUBEView::OnDraw(CDC* pDC) 

    CRect clientRect; 
    GLfloat lightPos[4] = {-1.0F, 2.0F, 0.2F, 0.0F}; 
    CCUBEDoc* pDoc = GetDocument(); 
    ASSERT_VALID(pDoc); 
    // TODO: add draw code for native data here 
    GetClientRect(&clientRect); 
    wglMakeCurrent(pDC->m_hDC, m_hglrc); 
    glViewport(0, 0, clientRect.right, clientRect.bottom); 
    glLoadIdentity(); 
    glClear(GL_COLOR_BUFFER_BIT); 
    glColor4d(1.0, 1.0, 1.0, 1.0); 
    glRotated(30.0, 0.0, 1.0, 0.0); 
    glRotated(15.0, 1.0, 0.0, 0.0); 
    glEnable(GL_LIGHTING); 
    glEnable(GL_LIGHT0); 
    glLightfv(GL_LIGHT0, GL_POSITION, lightPos); 
    glBegin(GL_QUADS); 
    glNormal3d(0.0, -1.0, 0.0); 
    glVertex3d(0.5, -0.5, 0.5); 
    glVertex3d(-0.5, -0.5, 0.5); 
    glVertex3d(-0.5, -0.5, -0.5); 
    glVertex3d(0.5, -0.5, -0.5); 
    glNormal3d(0.0, 0.0, -1.0); 
    glVertex3d(-0.5, -0.5, -0.5); 
    glVertex3d(-0.5, 0.5, -0.5); 
    glVertex3d(0.5, 0.5, -0.5); 
    glVertex3d(0.5, -0.5, -0.5); 
    glNormal3d(1.0, 0.0, 0.0); 
    glVertex3d(0.5, -0.5, -0.5); 
    glVertex3d(0.5, 0.5, -0.5); 
    glVertex3d(0.5, 0.5, 0.5); 
    glVertex3d(0.5, -0.5, 0.5); 
    glNormal3d(0.0, 0.0, 1.0); 
    glVertex3d(-0.5, -0.5, 0.5); 
    glVertex3d(-0.5, 0.5, 0.5); 
    glVertex3d(0.5, 0.5, 0.5); 
    glVertex3d(0.5, -0.5, 0.5); 
    glNormal3d(-1.0, 0.0, 0.0); 
    glVertex3d(-0.5, -0.5, 0.5); 
    glVertex3d(-0.5, 0.5, 0.5); 
    glVertex3d(-0.5, 0.5, -0.5); 
    glVertex3d(-0.5, -0.5, -0.5); 
    glNormal3d(0.0, 1.0, 0.0); 
    glVertex3d(-0.5, 0.5, 0.5); 
    glVertex3d(0.5, 0.5, 0.5); 
    glVertex3d(0.5, 0.5, -0.5); 
    glVertex3d(-0.5, 0.5, -0.5); 
    glEnd(); 
    glFlush(); 
    wglMakeCurrent(NULL, NULL); 


Note that this implementation does not take into account the fact that the 
MFC framework also calls the view class's OnDraw function when drawing into

a printer-device context. In its present state, attempts to use this 
application for printing will fail. 

                          Running the Application 

To run the application, compile and execute it from the Build menu. The 
application's window should appear similar to that shown in Figure 41.4. 

Figure 41.4. Running the cube.exe MFC application. 

Note that this application, as its non-MFC counterpart, includes no palette

initialization and may not work properly on systems configured with 16 or 
256 colors. 

                                  Summary 

OpenGL is a library of high-quality three-dimensional graphics and 
rendering functions. The library's device- and platform-independence make 
it a library of choice for developing portable graphical applications. 

OpenGL drawings are constructed from primitives; primitives are simple 
items such as lines or polygons, which in turn are composed of vertices. 

The OpenGL Library assembles primitives from vertices while taking into 
account a variety of settings, such as color, lighting, and texture. 
Primitives are then processed in accordance with transformations, clipping 
settings, and other parameters; at the end of the rasterization process is 
pixel data deposited into a frame buffer. 

The Windows implementation of the OpenGL Library consists of the core 
library, utility functions (GLU), and auxiliary functions (GLAUX). The 
auxiliary library can be used to easily create simple stand-alone OpenGL 
applications, as it implements a message loop and a window procedure 
internally. However, due to the simplicity of implementation, this library 
should not be used in production applications. 

Windows also provides a set of extension functions (WGL) that facilitate 
the use of OpenGL functions in the context of the Windows GDI. Furthermore,

a set of new functions has been added to the Win32 API to support pixel 
formats and OpenGL double buffering. 

The main steps of creating a Windows OpenGL application are as follows: 

  1. Ensure that your window class is not created with the CS_PARENTDC 
     style. Ensure that your window is created with the styles 
     WM_CLIPCHILDREN and WM_CLIPSIBLINGS set. 

  2. Create an OpenGL rendering context; a good spot for doing so is in the

     WM_CREATE handler function for the window that you intend to use with 
     OpenGL. 

  3. Add appropriate calls in your handler for WM_PAINT messages to draw 
     the OpenGL image. 

  4. Optionally, add a handler for WM_SIZE messages to reflect changes in 
     the viewport size. Use glViewport to set the viewport size. 

If you plan to run your application on 256-color devices, add handling for 
custom palettes. 


--
m;31m※ 来源:·紫金飞鸿 bbs.njupt.edu.cn·[FROM: pc05.info.njupt]m

--
※ 来源:.南大小百合信息交换站 bbs.nju.edu.cn.[FROM: a507yjh.nju.edu]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:210.677毫秒