📄 lesson34.cpp
字号:
/*
* This Code Was Created By Ben Humphrey 2001
* If You've Found This Code Useful, Please Let Me Know.
* Visit NeHe Productions At http://nehe.gamedev.net
*/
#include <windows.h> // Header File For Windows
#include <stdio.h> // Header file for standard input output (IE, "FILE") (NEW)
#include <gl\gl.h> // Header File For The OpenGL32 Library
#include <gl\glu.h> // Header File For The GLu32 Library
#include <gl\glaux.h> // Header File For The Glaux Library
#pragma comment(lib, "opengl32.lib") // Link OpenGL32.lib
#pragma comment(lib, "glu32.lib") // Link Glu32.lib
#define MAP_SIZE 1024 // Size Of Our .RAW Height Map (NEW)
#define STEP_SIZE 16 // Width And Height Of Each Quad (NEW)
#define HEIGHT_RATIO 1.5f // Ratio That The Y Is Scaled According To The X And Z (NEW)
HDC hDC=NULL; // Private GDI Device Context
HGLRC hRC=NULL; // Permanent Rendering Context
HWND hWnd=NULL; // Holds Our Window Handle
HINSTANCE hInstance; // Holds The Instance Of The Application
bool keys[256]; // Array Used For The Keyboard Routine
bool active=TRUE; // Window Active Flag Set To TRUE By Default
bool fullscreen=TRUE; // Fullscreen Flag Set To TRUE By Default
bool bRender = TRUE; // Polygon Flag Set To TRUE By Default (NEW)
BYTE g_HeightMap[MAP_SIZE*MAP_SIZE]; // Holds The Height Map Data (NEW)
float scaleValue = 0.15f; // Scale Value For The Terrain (NEW)
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc
GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize And Initialize The GL Window
{
if (height==0) // Prevent A Divide By Zero By
height=1; // Making Height Equal One
glViewport(0,0,width,height); // Reset The Current Viewport
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window. Farthest Distance Changed To 500.0f (NEW)
gluPerspective(45.0f, (GLfloat)width/(GLfloat)height, 0.1f, 500.0f);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
}
// Loads The .RAW File And Stores It In pHeightMap
void LoadRawFile(LPSTR strName, int nSize, BYTE *pHeightMap)
{
FILE *pFile = NULL;
// Open The File In Read / Binary Mode.
pFile = fopen( strName, "rb" );
// Check To See If We Found The File And Could Open It
if ( pFile == NULL )
{
// Display Error Message And Stop The Function
MessageBox(NULL, "Can't Find The Height Map!", "Error", MB_OK);
return;
}
fread( pHeightMap, 1, nSize, pFile );
// After We Read The Data, It's A Good Idea To Check If Everything Read Fine
int result = ferror( pFile );
// Check If We Received An Error
if (result)
{
MessageBox(NULL, "Failed To Get Data!", "Error", MB_OK);
}
// Close The File.
fclose(pFile);
}
int InitGL(GLvoid) // All Setup For OpenGL Goes Here
{
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
LoadRawFile("Data/Terrain.raw", MAP_SIZE * MAP_SIZE, g_HeightMap); // (NEW)
return TRUE; // Initialization Went OK
}
int Height(BYTE *pHeightMap, int X, int Y) // This Returns The Height From A Height Map Index
{
int x = X % MAP_SIZE; // Error Check Our x Value
int y = Y % MAP_SIZE; // Error Check Our y Value
if(!pHeightMap) return 0; // Make Sure Our Data Is Valid
return pHeightMap[x + (y * MAP_SIZE)]; // Index Into Our Height Array And Return The Height
}
void SetVertexColor(BYTE *pHeightMap, int x, int y) // Sets The Color Value For A Particular Index, Depending On The Height Index
{
if(!pHeightMap) return; // Make Sure Our Height Data Is Valid
float fColor = -0.15f + (Height(pHeightMap, x, y ) / 256.0f);
// Assign This Blue Shade To The Current Vertex
glColor3f(0, 0, fColor );
}
void RenderHeightMap(BYTE pHeightMap[]) // This Renders The Height Map As Quads
{
int X = 0, Y = 0; // Create Some Variables To Walk The Array With.
int x, y, z; // Create Some Variables For Readability
if(!pHeightMap) return; // Make Sure Our Height Data Is Valid
if(bRender) // What We Want To Render
glBegin( GL_QUADS ); // Render Polygons
else
glBegin( GL_LINES ); // Render Lines Instead
for ( X = 0; X < (MAP_SIZE-STEP_SIZE); X += STEP_SIZE )
for ( Y = 0; Y < (MAP_SIZE-STEP_SIZE); Y += STEP_SIZE )
{
// Get The (X, Y, Z) Value For The Bottom Left Vertex
x = X;
y = Height(pHeightMap, X, Y );
z = Y;
// Set The Color Value Of The Current Vertex
SetVertexColor(pHeightMap, x, z);
glVertex3i(x, y, z); // Send This Vertex To OpenGL To Be Rendered (Integer Points Are Faster)
// Get The (X, Y, Z) Value For The Top Left Vertex
x = X;
y = Height(pHeightMap, X, Y + STEP_SIZE );
z = Y + STEP_SIZE ;
// Set The Color Value Of The Current Vertex
SetVertexColor(pHeightMap, x, z);
glVertex3i(x, y, z); // Send This Vertex To OpenGL To Be Rendered
// Get The (X, Y, Z) Value For The Top Right Vertex
x = X + STEP_SIZE;
y = Height(pHeightMap, X + STEP_SIZE, Y + STEP_SIZE );
z = Y + STEP_SIZE ;
// Set The Color Value Of The Current Vertex
SetVertexColor(pHeightMap, x, z);
glVertex3i(x, y, z); // Send This Vertex To OpenGL To Be Rendered
// Get The (X, Y, Z) Value For The Bottom Right Vertex
x = X + STEP_SIZE;
y = Height(pHeightMap, X + STEP_SIZE, Y );
z = Y;
// Set The Color Value Of The Current Vertex
SetVertexColor(pHeightMap, x, z);
glVertex3i(x, y, z); // Send This Vertex To OpenGL To Be Rendered
}
glEnd();
glColor4f(1.0f, 1.0f, 1.0f, 1.0f); // Reset The Color
}
int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The Matrix
// Position View Up Vector
gluLookAt(212, 60, 194, 186, 55, 171, 0, 1, 0); // This Determines Where The Camera's Position And View Is
glScalef(scaleValue, scaleValue * HEIGHT_RATIO, scaleValue);
RenderHeightMap(g_HeightMap); // Render The Height Map
return TRUE; // Keep Going
}
GLvoid KillGLWindow(GLvoid) // Properly Kill The Window
{
if (fullscreen) // Are We In Fullscreen Mode?
{
ChangeDisplaySettings(NULL,0); // If So Switch Back To The Desktop
ShowCursor(TRUE); // Show Mouse Pointer
}
if (hRC) // Do We Have A Rendering Context?
{
if (!wglMakeCurrent(NULL,NULL)) // Are We Able To Release The DC And RC Contexts?
{
MessageBox(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
}
if (!wglDeleteContext(hRC)) // Are We Able To Delete The RC?
{
MessageBox(NULL,"Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
}
hRC=NULL; // Set RC To NULL
}
if (hDC && !ReleaseDC(hWnd,hDC)) // Are We Able To Release The DC
{
MessageBox(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hDC=NULL; // Set DC To NULL
}
if (hWnd && !DestroyWindow(hWnd)) // Are We Able To Destroy The Window?
{
MessageBox(NULL,"Could Not Release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hWnd=NULL; // Set hWnd To NULL
}
if (!UnregisterClass("OpenGL",hInstance)) // Are We Able To Unregister Class
{
MessageBox(NULL,"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hInstance=NULL; // Set hInstance To NULL
}
}
/* This Code Creates Our OpenGL Window. Parameters Are: *
* title - Title To Appear At The Top Of The Window *
* width - Width Of The GL Window Or Fullscreen Mode *
* height - Height Of The GL Window Or Fullscreen Mode *
* bits - Number Of Bits To Use For Color (8/16/24/32) *
* fullscreenflag - Use Fullscreen Mode (TRUE) Or Windowed Mode (FALSE) */
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
{
GLuint PixelFormat; // Holds The Results After Searching For A Match
WNDCLASS wc; // Windows Class Structure
DWORD dwExStyle; // Window Extended Style
DWORD dwStyle; // Window Style
RECT WindowRect; // Grabs Rectangle Upper Left / Lower Right Values
WindowRect.left=(long)0; // Set Left Value To 0
WindowRect.right=(long)width; // Set Right Value To Requested Width
WindowRect.top=(long)0; // Set Top Value To 0
WindowRect.bottom=(long)height; // Set Bottom Value To Requested Height
fullscreen=fullscreenflag; // Set The Global Fullscreen Flag
hInstance = GetModuleHandle(NULL); // Grab An Instance For Our Window
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Size, And Own DC For Window.
wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc Handles Messages
wc.cbClsExtra = 0; // No Extra Window Data
wc.cbWndExtra = 0; // No Extra Window Data
wc.hInstance = hInstance; // Set The Instance
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load The Default Icon
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load The Arrow Pointer
wc.hbrBackground = NULL; // No Background Required For GL
wc.lpszMenuName = NULL; // We Don't Want A Menu
wc.lpszClassName = "OpenGL"; // Set The Class Name
if (!RegisterClass(&wc)) // Attempt To Register The Window Class
{
MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -