荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: Peter (小飞侠), 信区: Program
标  题: VC 4.0中使用OpenGL(3)
发信站: BBS 荔园晨风站 (Tue Jan 26 22:55:53 1999), 转信

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.

--
※ 来源:.BBS 荔园晨风站 bbs.szu.edu.cn.[FROM: 192.168.1.3]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店