Open GL Super Bible:Quadrics: Spheres, Cylinders, and Disks
To access the contents, click the chapter and section titles.
Open GL Super Bible
(Publisher: Macmillan Computer Publishing)
Author(s): Waite group Press
ISBN: 1571690735
Publication Date: 08/01/96
Previous
Table of Contents
Next
Summary
In this chapter wełve covered the quadric drawing functions. OpenGL quadrics are geometric shapes that form the basic building blocks" of many objects, both manufactured and natural. Using the quadric drawing functions is a convenient and fast way to avoid writing a lot of extra code for drawing these shapes.
Now herełs Listing 13-1, the pencil program.
Listing 13-1 The pencil drawing program
/*
* Include necessary headers.
*/
#include "texture.h"
#include "pencil.h"
#include <stdarg.h>
/*
* Globals
*/
HWND PencilWindow; /* Scene window */
HPALETTE PencilPalette; /* Color palette (if necessary) */
HDC PencilDC; /* Drawing context */
HGLRC PencilRC; /* OpenGL rendering context */
GLuint PencilTexture, /* Pencil texture image */
LeadTexture; /* Lead */
GLfloat PencilRoll = 0.0, /* Pencil orientation */
PencilPitch = 90.0,
PencilHeading = 0.0;
GLUquadricObj *PencilObj;
/*
* Local functions
*/
void DisplayErrorMessage(char *, );
void MakePalette(int);
LRESULT CALLBACK PencilProc(HWND, UINT, WPARAM, LPARAM);
void LoadAllTextures(void);
void RepaintWindow(RECT *);
void PrintBitmap(void);
/*
* 'WinMain()' - Main entry
*/
int APIENTRY
WinMain(HINSTANCE hInst, /* I - Current process instance */
HINSTANCE hPrevInstance, /* I - Parent process instance */
LPSTR lpCmdLine, /* I - Command-line arguments */
int nCmdShow) /* I - Show window at startup? */
{
MSG msg; /* Window UI event */
WNDCLASS wc; /* Window class */
RECT rect; /* Current client area rectangle */
/*
* Register main window
*/
wc.style = 0;
wc.lpfnWndProc = (WNDPROC)PencilProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = 0;
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
wc.lpszClassName = "Textured Quadric Pencil";
if (RegisterClass(&wc) == 0)
{
DisplayErrorMessage("Unable to register window class!");
return (FALSE);
};
/*
* Then create it
*/
PencilWindow = CreateWindow("Textured Quadric Pencil", "Textured
Quadric Pencil", WS_OVERLAPPEDWINDOW
| WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
32, 32, 400, 300,
NULL, NULL, hInst, NULL);
if (PencilWindow == NULL)
{
DisplayErrorMessage("Unable to create window!");
return (FALSE);
};
ShowWindow(PencilWindow, nCmdShow);
UpdateWindow(PencilWindow);
/*
* Loop on events until the user quits this application
*/
while (TRUE)
{
/*
* Process all messages in the queue
*/
while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) == TRUE)
if (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
return (1);
/*
* Spin the pencil
*/
PencilRoll += 1.0;
PencilPitch += 2.0;
PencilHeading += 3.0;
GetClientRect(PencilWindow, &rect);
RepaintWindow(&rect);
};
return (msg.wParam);
}
/*
* 'DisplayErrorMessage()' - Display an error message dialog.
*/
void
DisplayErrorMessage(char *format, /* I - printf() style format string */
) /* I - Other arguments as necessary */
{
va_list ap; /* Argument pointer */
char s[1024]; /* Output string */
if (format == NULL)
return;
va_start(ap, format);
vsprintf(s, format, ap);
va_end(ap);
MessageBeep(MB_ICONEXCLAMATION);
MessageBox(NULL, s, "Error", MB_OK | MB_ICONEXCLAMATION);
}
/*
* 'MakePalette()' - Make a color palette for RGB colors if necessary.
*/
void
MakePalette(int pf) /* I - Pixel format ID */
{
PIXELFORMATDESCRIPTOR pfd; /* Pixel format information */
LOGPALETTE *pPal; /* Pointer to logical palette */
int nColors; /* Number of entries in palette */
int i, /* Color index */
rmax, /* Maximum red value */
gmax, /* Maximum green value */
bmax; /* Maximum blue value */
/*
* Find out if we need to define a color palette
*/
DescribePixelFormat(PencilDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
if (!(pfd.dwFlags & PFD_NEED_PALETTE))
{
PencilPalette = NULL;
return;
};
/*
* Allocate memory for a color palette
*/
nColors = 1 << pfd.cColorBits;
pPal = (LOGPALETTE *)malloc(sizeof(LOGPALETTE) +
nColors * sizeof(PALETTEENTRY));
pPal->palVersion = 0x300;
pPal->palNumEntries = nColors;
/*
* Get the maximum values for red, green, and blue. Then build 'nColors'
* colors
*/
rmax = (1 << pfd.cRedBits) - 1;
gmax = (1 << pfd.cGreenBits) - 1;
bmax = (1 << pfd.cBlueBits) - 1;
for (i = 0; i < nColors; i ++)
{
pPal->palPalEntry[i].peRed = 255 *
((i >> pfd.cRedShift) & rmax) /
rmax;
pPal->palPalEntry[i].peGreen = 255 *
((i >> pfd.cGreenShift) & gmax) /
gmax;
pPal->palPalEntry[i].peBlue = 255 *
((i >> pfd.cBlueShift) & bmax) /
bmax;
pPal->palPalEntry[i].peFlags = 0;
};
/*
* Create, select, and realize the palette
*/
PencilPalette = CreatePalette(pPal);
SelectPalette(PencilDC, PencilPalette, FALSE);
RealizePalette(PencilDC);
free(pPal);
}
/*
* 'PencilProc()' - Handle window events in the viewing window.
*/
LRESULT CALLBACK
PencilProc(CHWND hWnd, /* I - Window triggering this event */
UINT uMsg, /* I - Message type */
WPARAM wParam, /* I - 'word' parameter value */
LPARAM lParam) /* I - 'long' parameter value */
{
int pf; /* Pixel format ID */
PIXELFORMATDESCRIPTOR pfd; /* Pixel format information */
PAINTSTRUCT ps; /* WM_PAINT message info */
RECT rect; /* Current client area rectangle */
switch (uMsg)
{
case WM_CREATE :
/*
* 'Create' message. Get device and rendering contexts, and
* setup the client area for OpenGL drawing
*/
PencilDC = GetDC(hWnd);
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL
| PFD_DOUBLEBUFFER;
/* Do OpenGL drawing */
pfd.dwLayerMask = PFD_MAIN_PLANE; /* Main drawing plane */
pfd.iPixelType = PFD_TYPE_RGBA; /* RGB color buffer */
pfd.cColorBits = 0; /* Best color buffer
please*/
pfd.cDepthBits = 32; /* Need a depth buffer */
pfd.cStencilBits = 0; /* No stencil buffer */
pfd.cAccumBits = 0; /* No accumulation buffer
*/
pf = ChoosePixelFormat(PencilDC, &pfd);
if (pf == 0)
DisplayErrorMessage("texscene was unable to choose a suitable
pixel format!");
else if (!SetPixelFormat(PencilDC, pf, &pfd))
DisplayErrorMessage("texscene was unable to set the pixel
format!");
MakePalette(pf);
PencilRC = wglCreateContext(PencilDC);
wglMakeCurrent(PencilDC, PencilRC);
/*
* Load all the texture images into display lists
*/
LoadAllTextures();
PencilObj = gluNewQuadric();
gluQuadricTexture(PencilObj, GL_TRUE);
break;
case WM_SIZE :
case WM_PAINT :
/*
* Repaint the client area with our bitmap
*/
BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rect);
RepaintWindow(&rect);
EndPaint(hWnd, &ps);
break;
case WM_COMMAND :
/*
* Handle menu selections
*/
switch (LOWORD(wParam))
{
case IDM_FILE_PRINT :
PrintBitmap();
break;
case IDM_FILE_EXIT :
DestroyWindow(PencilWindow);
break;
};
break;
case WM_QUIT :
case WM_CLOSE :
/*
* Destroy the windows and bitmaps and exit
*/
DestroyWindow(PencilWindow);
exit(0);
break;
case WM_DESTROY :
/*
* Release and free the device context, rendering
* context, and color palette
*/
if (PencilRC)
wglDeleteContext(PencilRC);
if (PencilDC)
ReleaseDC(PencilWindow, PencilDC);
if (PencilPalette)
DeleteObject(PencilPalette);
PostQuitMessage(0);
break;
case WM_QUERYNEWPALETTE :
/*
* Realize the color palette if necessary
*/
if (PencilPalette)
{
SelectPalette(PencilDC, PencilPalette, FALSE);
RealizePalette(PencilDC);
InvalidateRect(hWnd, NULL, FALSE);
return (TRUE);
};
break;
case WM_PALETTECHANGED:
/*
* Reselect our color palette if necessary
*/
if (PencilPalette && (HWND)wParam != hWnd)
{
SelectPalette(PencilDC, PencilPalette, FALSE);
RealizePalette(PencilDC);
UpdateColors(PencilDC);
};
break;
default :
/*
* Pass all other messages through the default window
* procedure
*/
return (DefWindowProc(hWnd, uMsg, wParam, lParam));
};
return (FALSE);
}
/*
* 'LoadAllTextures()' - Load texture images for the scene.
*/
void
LoadAllTextures(void)
{
glNewList(PencilTexture = glGenLists(1), GL_COMPILE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
TextureLoadBitmap("textures/pencil.bmp");
glEndList();
glNewList(LeadTexture = glGenLists(1), GL_COMPILE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
TextureLoadBitmap("textures/lead.bmp");
glEndList();
}
/*
* 'RepaintWindow()' - Redraw the client area with our pencil.
*/
void
RepaintWindow(RECT *rect) /* I - Client area rectangle */
{
/*
* Reset the viewport and clear the window to light blue
*/
glViewport(0, 0, rect->right, rect->bottom);
glClearColor(0.7, 0.7, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/*
* Setup viewing transformations for the current position and
* orientation
*/
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (float)rect->right / (float)rect->bottom,
0.1, 1000.0);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef(0.0, 0.0, -80.0);
glRotatef(PencilHeading, 0.0, -1.0, 0.0);
glRotatef(PencilPitch, 1.0, 0.0, 0.0);
glRotatef(PencilRoll, 0.0, 0.0, -1.0);
/*
* First the pencil body - this uses a 6-sided cylinder
*/
gluQuadricNormals(PencilObj, GLU_FLAT);
glCallList(PencilTexture);
glPushMatrix();
glTranslatef(0.0, 0.0, -20.0);
gluCylinder(PencilObj, 5.0, 5.0, 40.0, 6, 2);
glPopMatrix();
/*
* Then the ends - a cone at the tip and a flat cone at the base
*/
gluQuadricNormals(PencilObj, GLU_SMOOTH);
glCallList(LeadTexture);
glPushMatrix();
glTranslatef(0.0, 0.0, 20.0);
gluCylinder(PencilObj, 5.0, 0.0, 7.5, 6, 2);
glPopMatrix();
glPushMatrix();
glTranslatef(0.0, 0.0, -20.0);
/*
* Normally we might use a disk shape for this, but unfortunately the
texture
* coordinates don't match up
*/
gluCylinder(PencilObj, 5.0, 0.0, 0.0, 6, 2);
glPopMatrix();
glPopMatrix();
/*
* Swap buffers and return
*/
glFinish();
SwapBuffers(PencilDC);
}
/*
* 'PrintBitmap()' - Print the currently displayed scene.
*/
void
PrintBitmap(void)
{
void *bits; /* Screen bitmap bits */
BITMAPINFO *info; /* Screen bitmap info */
/*
* Grab the screen bitmap
*/
bits = ReadDIBitmap(&info);
if (bits == NULL)
{
DisplayErrorMessage("Unable to get OpenGL bitmap from screen!");
return;
};
/*
* Print the bitmap
*/
PrintDIBitmap(PencilWindow, info, bits);
/*
* Free memory and return
*/
free(info);
free(bits);
}
Previous
Table of Contents
Next
Use of this site is subject to certain Terms & Conditions, Copyright 1996-2000 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.
Wyszukiwarka
Podobne podstrony:
02 (449)Skaldowie Z kopyta kulig rwie (440)VOLVO 440 1 9D turbo (90 konie)447 449449 Przychody i koszty z tytułu wniesienia aportu do sp z o oVOLVO 440 2 0 (110 konie)446 449440 acMAGNUM DINAMIK INSTRUKCJA OBSŁUGI PROSTOWNIKÓW DO ŁADOWANIA I ROZRUCHU 440 PLwięcej podobnych podstron