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

  Drawing with OpenGL 

Most OpenGL drawing consists of a series of vertex operations enclosed 
between a pair of glBegin and glEnd calls. The glBegin call identifies the 
type of primitive that subsequent vertex operations define; glEnd marks the

end of constructing the primitive. For example, the following series of 
calls constructs a pentagon: 

glBegin(GL_POLYGON); 
glVertex2d(0.0, 1.0); 
glVertex2d(-0.951057, 0.309017); 
glVertex2d(-0.587785, -0.809017); 
glVertex2d(0.587785, -0.809017); 
glVertex2d(0.951057, 0.309017); 
glEnd(); 

The glBegin function can be used to define a variety of primitives. Table 
41.1 lists the allowable parameters for this function. 

     Table 41.1. Primitives constructed through glBegin. 

glBegin ParameterDescription 

GL_POINTS        A series of points 

GL_LINES         A series of lines 

GL_LINE_STRIP    A connected group of line segments 

GL_LINE_LOOP     A connected, closed group of line segments 

GL_TRIANGLES     A set of triangles 

GL_TRIANGLE_STRIPA set of connected triangles 

GL_TRIANGLE_FAN  A set of connected triangles 

GL_QUADS         A set of quadrilaterals 

GL_QUAD_STRIP    A set of connected quadrilaterals 

GL_POLYGON       A polygon 

In the case when glBegin defines a set of connected primitives, specific 
rules govern how vertices of a primitive are reused as vertices of the 
subsequent primitive. For example, if GL_LINE_STRIP is specified, the 
vertex representing the end point of a line segment also becomes the 
starting point of the next line segment. 

                           Additional Libraries 

In addition to basic OpenGL functions, Microsoft's OpenGL implementation 
provides two additional OpenGL libraries. 

The OpenGL Utility Library (GLU) contains a series of functions that deal 
with texture support; coordinate transformation; rendering of spheres, 
disks, and cylinders; B-spline curves and surfaces; and error handling. 
Additionally, the GLU Library provides polygon tessellation functions; 
these functions can be used to break down complex or concave polygons into 
simple convex polygons (the only kind that OpenGL can handle). 

The OpenGL Programming Guide Auxiliary Library (GLAUX), in addition to 
providing functions for handling several three-dimensional objects, also 
provides functions to manage and run an OpenGL application. These functions

are most useful for quick porting OpenGL applications from other 
environments. In particular, these functions provide basic window 
management, implement a simple message loop, and provide a window procedure

for basic message handling. However, these library functions are not 
intended for use in production applications. 

                 Writing OpenGL Windows Applications in C 

Now for a look at a very simple OpenGL application. This application, shown

in Listing 41.1, displays a cube. The cube is slightly rotated to show a 
three-dimensional appearance, and is lit from the side. In its simplicity, 
this application is the OpenGL version of a Windows Hello, World 
application. 

     Listing 41.1. A simple OpenGL application. 

#include <windows.h> 
#include <GL/gl.h> 
#include <GL/glu.h> 
HGLRC hglrc; 
void DrawHello(HWND hwnd) 

    HDC hDC; 
    PAINTSTRUCT paintStruct; 
    RECT clientRect; 
    GLfloat lightPos[4] = {-1.0F, 2.0F, 0.2F, 0.0F}; 
    hDC = BeginPaint(hwnd, &paintStruct); 
    if (hDC != NULL) 
    { 
        GetClientRect(hwnd, &clientRect); 
        wglMakeCurrent(hDC, 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); 
        EndPaint(hwnd, &paintStruct); 
    } 

LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, 
                         WPARAM wParam, LPARAM lParam) 

    switch(uMsg) 
    { 
        case WM_PAINT: 
            DrawHello(hwnd); 
            break; 
        case WM_DESTROY: 
            PostQuitMessage(0); 
            break; 
        default: 
            return DefWindowProc(hwnd, uMsg, wParam, lParam); 
    } 
    return 0; 

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
                                        LPSTR d3, int nCmdShow) 

    MSG msg; 
    HWND hwnd; 
    WNDCLASS wndClass; 
    HDC hDC; 
    PIXELFORMATDESCRIPTOR pfd; 
    int iPixelFormat; 
    if (hPrevInstance == NULL) 
    { 
        memset(&wndClass, 0, sizeof(wndClass)); 
        wndClass.style = CS_HREDRAW | CS_VREDRAW; 
        wndClass.lpfnWndProc = WndProc; 
        wndClass.hInstance = hInstance; 
        wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); 
        wndClass.lpszClassName = "HELLO"; 
        if (!RegisterClass(&wndClass)) return FALSE; 
    } 
    hwnd = CreateWindow("HELLO", "HELLO", 
           WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 
                        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 
                        NULL, NULL, hInstance, NULL); 
    hDC = GetDC(hwnd); 
    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(hDC, &pfd); 
    SetPixelFormat(hDC, iPixelFormat, &pfd); 
    hglrc = wglCreateContext(hDC); 
    ReleaseDC(hwnd, hDC); 
    ShowWindow(hwnd, nCmdShow); 
    UpdateWindow(hwnd); 
    while (GetMessage(&msg, NULL, 0, 0)) 
        DispatchMessage(&msg); 
    wglMakeCurrent(NULL, NULL); 
    wglDeleteContext(hglrc); 
    return msg.wParam; 


The following sections explain this application's method of operation. 

Note that for the sake of simplicity, I did not include any palette 
initialization in this application. For this reason, the application may 
not behave properly on systems configured for 16 or 256 colors. 

                           OpenGL Initialization 

The first series of OpenGL calls in this application begins in WinMain, 
immediately after the application's window has been created. After 
obtaining a device-context handle for the client area of this window, the 
device context's pixel format is set to a pixel format obtained through 
ChoosePixelFormat. The ChoosePixelFormat function can be used to identify 
pixel formats for a specific device that best match a set of required 
characteristics. 

Note that although we are using the RGBA data mode, this application does 
not handle palette notification messages. This is done in order to keep the

application as simple as possible; in a production application, you would 
certainly not want to omit creating and managing a palette that is 
appropriate for your application. 

After the pixel format has been specified, a rendering context is created 
by a call to wglCreateContext. The rendering context handle is saved in a 
global variable that will be accessed from within other functions. 

When all initializations have been completed, the application enters its 
message loop. After the message loop terminates, cleanup is performed by 
calling wglMakeCurrent and wglDeleteContext before the application 
terminates. 

--
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.692毫秒