荔园在线

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

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


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

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.

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


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

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