发信人: 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毫秒