📄 sphereworld32.c
字号:
glStencilOp(GL_INCR, GL_INCR, GL_INCR);
glClearStencil(0);
glStencilFunc(GL_EQUAL, 0x0, 0x01);
// Cull backs of polygons
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
// Setup light parameters
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, fNoLight);
glLightfv(GL_LIGHT0, GL_AMBIENT, fLowLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, fBrightLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, fBrightLight);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
// Calculate shadow matrix
gltMakeShadowMatrix(vPoints, fLightPos, mShadowMatrix);
// Mostly use material tracking
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glMateriali(GL_FRONT, GL_SHININESS, 128);
gltInitFrame(&frameCamera); // Initialize the camera
// Randomly place the sphere inhabitants
for(iSphere = 0; iSphere < NUM_SPHERES; iSphere++)
{
gltInitFrame(&spheres[iSphere]); // Initialize the frame
// Pick a random location between -20 and 20 at .1 increments
spheres[iSphere].vLocation[0] = (float)((rand() % 400) - 200) * 0.1f;
spheres[iSphere].vLocation[1] = 0.0f;
spheres[iSphere].vLocation[2] = (float)((rand() % 400) - 200) * 0.1f;
}
// Set up texture maps
glEnable(GL_TEXTURE_2D);
glGenTextures(NUM_TEXTURES, textureObjects);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
// Load teach texture
for(i = 0; i < NUM_TEXTURES; i++)
{
GLubyte *pBytes;
GLint iWidth, iHeight, iComponents;
GLenum eFormat;
glBindTexture(GL_TEXTURE_2D, textureObjects[i]);
// Load this texture map
pBytes = gltLoadTGA(szTextureFiles[i], &iWidth, &iHeight, &iComponents, &eFormat);
gluBuild2DMipmaps(GL_TEXTURE_2D, iComponents, iWidth, iHeight, eFormat, GL_UNSIGNED_BYTE, pBytes);
free(pBytes);
// Trilinear mipmapping
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
// Get window position function pointer if it exists
glWindowPos2i = (PFNGLWINDOWPOS2IPROC)wglGetProcAddress("glWindowPos2i");
// Get swap interval function pointer if it exists
wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
if(wglSwapIntervalEXT != NULL && startupOptions.bVerticalSync == TRUE)
wglSwapIntervalEXT(1);
// If multisampling was available and was selected, enable
if(startupOptions.bFSAA == TRUE && startupOptions.nPixelFormatMS != 0)
glEnable(GL_MULTISAMPLE_ARB);
// If sepearate specular color is available, make torus shiney
if(gltIsExtSupported("GL_EXT_separate_specular_color"))
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
// Initialize the timers
QueryPerformanceFrequency(&CounterFrequency);
QueryPerformanceCounter(&FPSCount);
CameraTimer = FPSCount;
// Build display lists for the torus and spheres
// (You could do one for the ground as well)
lTorusList = glGenLists(2);
lSphereList = lTorusList + 1;
glNewList(lTorusList, GL_COMPILE);
gltDrawTorus(0.35f, 0.15f, 61, 37);
glEndList();
glNewList(lSphereList, GL_COMPILE);
gltDrawSphere(0.3f, 31, 16);
glEndList();
}
///////////////////////////////////////////////////////////////////////////////
// Shutdown the rendering context
void ShutdownRC(void)
{
glDeleteLists(nFontList, 128); // Delete font display list
glDeleteLists(lTorusList, 2); // Delete object display lists
glDeleteTextures(NUM_TEXTURES, textureObjects); // Release textures
}
///////////////////////////////////////////////////////////////////////
// If necessary, creates a 3-3-2 palette for the device context listed.
HPALETTE GetOpenGLPalette(HDC hDC)
{
HPALETTE hRetPal = NULL; // Handle to palette to be created
PIXELFORMATDESCRIPTOR pfd; // Pixel Format Descriptor
LOGPALETTE *pPal; // Pointer to memory for logical palette
int nPixelFormat; // Pixel format index
int nColors; // Number of entries in palette
int i; // Counting variable
BYTE RedRange,GreenRange,BlueRange;
// Range for each color entry (7,7,and 3)
// Get the pixel format index and retrieve the pixel format description
nPixelFormat = GetPixelFormat(hDC);
DescribePixelFormat(hDC, nPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
// Does this pixel format require a palette? If not, do not create a
// palette and just return NULL
if(!(pfd.dwFlags & PFD_NEED_PALETTE))
return NULL;
// Number of entries in palette. 8 bits yeilds 256 entries
nColors = 1 << pfd.cColorBits;
// Allocate space for a logical palette structure plus all the palette entries
pPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) +nColors*sizeof(PALETTEENTRY));
// Fill in palette header
pPal->palVersion = 0x300; // Windows 3.0
pPal->palNumEntries = nColors; // table size
// Build mask of all 1's. This creates a number represented by having
// the low order x bits set, where x = pfd.cRedBits, pfd.cGreenBits, and
// pfd.cBlueBits.
RedRange = (1 << pfd.cRedBits) -1;
GreenRange = (1 << pfd.cGreenBits) - 1;
BlueRange = (1 << pfd.cBlueBits) -1;
// Loop through all the palette entries
for(i = 0; i < nColors; i++)
{
// Fill in the 8-bit equivalents for each component
pPal->palPalEntry[i].peRed = (i >> pfd.cRedShift) & RedRange;
pPal->palPalEntry[i].peRed = (unsigned char)(
(double) pPal->palPalEntry[i].peRed * 255.0 / RedRange);
pPal->palPalEntry[i].peGreen = (i >> pfd.cGreenShift) & GreenRange;
pPal->palPalEntry[i].peGreen = (unsigned char)(
(double)pPal->palPalEntry[i].peGreen * 255.0 / GreenRange);
pPal->palPalEntry[i].peBlue = (i >> pfd.cBlueShift) & BlueRange;
pPal->palPalEntry[i].peBlue = (unsigned char)(
(double)pPal->palPalEntry[i].peBlue * 255.0 / BlueRange);
pPal->palPalEntry[i].peFlags = (unsigned char) NULL;
}
// Create the palette
hRetPal = CreatePalette(pPal);
// Go ahead and select and realize the palette for this device context
SelectPalette(hDC,hRetPal,FALSE);
RealizePalette(hDC);
// Free the memory used for the logical palette structure
free(pPal);
// Return the handle to the new palette
return hRetPal;
}
///////////////////////////////////////////////////////////////////
// Entry point of all Windows programs
int APIENTRY WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg; // Windows message structure
WNDCLASS wc; // Windows class structure
HWND hWnd; // Storeage for window handle
UINT uiStyle,uiStyleX;
ghInstance = hInstance; // Save instance handle
// Get startup options, or shutdown
if(ShowStartupOptions() == FALSE)
return 0;
if(startupOptions.bFullScreen == TRUE)
if(ChangeDisplaySettings(&startupOptions.devMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
{
// Replace with string resource, and actual width and height
MessageBox(NULL, TEXT("Cannot change to selected desktop resolution."),
NULL, MB_OK | MB_ICONSTOP);
return -1;
}
// Register Window style
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
// No need for background brush for OpenGL window
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = lpszAppName;
// Register the window class
if(RegisterClass(&wc) == 0)
return FALSE;
// Select window styles
if(startupOptions.bFullScreen == TRUE)
{
uiStyle = WS_POPUP;
uiStyleX = WS_EX_TOPMOST;
}
else
{
uiStyle = WS_OVERLAPPEDWINDOW;
uiStyleX = 0;
}
// Create the main 3D window
hWnd = CreateWindowEx(uiStyleX, wc.lpszClassName, lpszAppName, uiStyle,
0, 0, startupOptions.devMode.dmPelsWidth, startupOptions.devMode.dmPelsHeight, NULL, NULL, hInstance, NULL);
// If window was not created, quit
if(hWnd == NULL)
return FALSE;
// Make sure window manager stays hidden
ShowWindow(hWnd,SW_SHOW);
UpdateWindow(hWnd);
// Process application messages until the application closes
while( GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// Restore Display Settings
if(startupOptions.bFullScreen == TRUE)
ChangeDisplaySettings(NULL, 0);
return msg.wParam;
}
/////////////////////////////////////////////////////////////////
// Window procedure, handles all messages for this program
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HGLRC hRC; // Permenant Rendering context
static HDC hDC; // Private GDI Device context
switch (message)
{
// Window creation, setup for OpenGL
case WM_CREATE:
// Store the device context
hDC = GetDC(hWnd);
// The screen and desktop may have changed, so do this again
FindBestPF(hDC, &startupOptions.nPixelFormat, &startupOptions.nPixelFormatMS);
// Set pixelformat
if(startupOptions.bFSAA == TRUE && (startupOptions.nPixelFormatMS != 0))
SetPixelFormat(hDC, startupOptions.nPixelFormatMS, NULL);
else
SetPixelFormat(hDC, startupOptions.nPixelFormat, NULL);
// Create the rendering context and make it current
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);
// Create the palette
hPalette = GetOpenGLPalette(hDC);
SetupRC(hDC);
break;
// Check for ESC key
case WM_CHAR:
if(wParam == 27)
DestroyWindow(hWnd);
break;
// Window is either full screen, or not visible
case WM_ACTIVATE:
{
// Ignore this altogether unless we are in full screen mode
if(startupOptions.bFullScreen == TRUE)
{
// Construct windowplacement structure
WINDOWPLACEMENT wndPlacement;
wndPlacement.length = sizeof(WINDOWPLACEMENT);
wndPlacement.flags = WPF_RESTORETOMAXIMIZED;
wndPlacement.ptMaxPosition.x = 0;
wndPlacement.ptMaxPosition.y = 0;
wndPlacement.ptMinPosition.x = 0;
wndPlacement.ptMinPosition.y = 0;
wndPlacement.rcNormalPosition.bottom = startupOptions.devMode.dmPelsHeight;
wndPlacement.rcNormalPosition.left = 0;
wndPlacement.rcNormalPosition.top = 0;
wndPlacement.rcNormalPosition.right = startupOptions.devMode.dmPelsWidth;
// Switching away from window
if(LOWORD(wParam) == WA_INACTIVE)
{
wndPlacement.showCmd = SW_SHOWMINNOACTIVE;
SetWindowPlacement(hWnd, &wndPlacement);
ShowCursor(TRUE);
}
else // Switching back to window
{
wndPlacement.showCmd = SW_RESTORE;
SetWindowPlacement(hWnd, &wndPlacement);
ShowCursor(FALSE);
}
}
}
break;
// Window is being destroyed, cleanup
case WM_DESTROY:
// Kill the timer that we created
KillTimer(hWnd,101);
ShutdownRC();
// Deselect the current rendering context and delete it
wglMakeCurrent(hDC,NULL);
wglDeleteContext(hRC);
// Delete the palette
if(hPalette != NULL)
DeleteObject(hPalette);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -