//这个是一个效果图,仅仅是演示一下。
///本文档基于NeHe的教程,在此感谢他的无私奉献,让大家学会了怎样使用OpenGL。
//这段生成sin数据
int main(int argc, char** argv)
{
for (int i = -360; i <= 360; i += 10) {
cout<<" { "<
}
}
//生成的数据放在这里
typedef struct tagVector {
float X, Y, Z;
} VECTOR, *PVECTOR;
VECTOR vec[] = {
{ -18 , -0.000220392 , 0 },
{ -17 , 2.60451 , 0 },
{ -17 , 5.13011 , 0 },
{ -16 , 9.64166 , 0 }, { -15 , 11.4905 , 0 }, { -15 , 12.9903 , 0 }, { -14 , 14.0953 , 0 }, { -14 , 14.7721 , 0 }, { -13 , 15 , 0 },
{ -13 , 14.7721 , 0 }, { -12 , 14.0954 , 0 }, { -12 , 12.9905 , 0 }, { -11 , 11.4908 , 0 }, { -11 , 9.64192 , 0 }, { -10 , 7.50011 , 0 }, { -10 , 5.13042 , 0 }, { -9 , 2.60484 , 0 }, { -9 , 0.000110196 , 0 }, { -8 , -2.60462 , 0 }, { -8 , -5.13021 , 0 }, { -7 , -7.49992 , 0 }, { -7 , -9.64175 , 0 }, { -6 , -11.4906 , 0 }, { -6 , -12.9903 , 0 }, { -5 , -14.0954 , 0 }, { -5 , -14.7721 , 0 }, { -4 , -15 , 0 },
{ -4 , -14.7721 , 0 }, { -3 , -14.0954 , 0 }, { -3 , -12.9904 , 0 }, { -2 , -11.4907 , 0 }, { -2 , -9.64183 , 0 }, { -1 , -7.50002 , 0 }, { -1 , -5.13031 , 0 }, { 0 , -2.60473 , 0 }, { 0 , 0 , 0 },
{ 0 , 2.60473 , 0 }, { 1 , 5.13031 , 0 }, { 1 , 7.50002 , 0 }, { 2 , 9.64183 , 0 }, { 2 , 11.4907 , 0 },
{ 3 , 12.9904 , 0 }, { 3 , 14.0954 , 0 }, { 4 , 14.7721 , 0 }, { 4 , 15 , 0 },
{ 5 , 14.7721 , 0 },
{ 6 , 12.9903 , 0 },
{ 6 , 11.4906 , 0 },
{ 7 , 9.64175 , 0 },
{ 7 , 7.49992 , 0 },
{ 8 , 5.13021 , 0 },
{ 8 , 2.60462 , 0 },
{ 9 , -0.000110196 , 0 },
{ 9 , -2.60484 , 0 },
{ 10 , -5.13042 , 0 },
{ 10 , -7.50011 , 0 },
{ 11 , -9.64192 , 0 },
{ 11 , -11.4908 , 0 },
{ 12 , -12.9905 , 0 },
{ 12 , -14.0954 , 0 },
{ 13 , -14.7721 , 0 },
{ 13 , -15 , 0 },
{ 14 , -14.7721 , 0 },
{ 14 , -14.0953 , 0 },
{ 15 , -12.9903 , 0 },
{ 15 , -11.4905 , 0 },
{ 16 , -9.64166 , 0 },
{ 16 , -7.49983 , 0 },
{ 17 , -5.13011 , 0 },
{ 17 , -2.60451 , 0 },
{ 18 , 0.000220392 , 0 }
};
//在这里进行调用绘制
#include
#include
#include
#include
#include
#include "NeHeGL.h"// Header File For NeHeGL
#include "Data.h"//让数据单独在一个文件里
#pragma comment( lib, "opengl32.lib" )// Search For OpenGL32.lib While Linking #pragma comment( lib, "glu32.lib" )// Search For GLu32.lib While Linking
using namespace std;
#ifndef CDS_FULLSCREEN// CDS_FULLSCREEN Is Not Defined By Some
#define CDS_FULLSCREEN 4// Compilers. By Defining It This Way,
#endif// We Can Avoid Errors
GL_Window* g_window;
Keys* g_keys;
float timeElapsed = 0;// Elapsed Time In The
GLuint base;// Base Display List For The Font Set
GL YPHMETRICSFLOAT gmf[256];// Storage For Information About Our Outline Font Characters
GLvoid BuildFont(GL_Window* window)// Build Our Bitmap Font
{
HFONT font;// Windows Font ID
base = glGenLists(256);// Storage For 256 Characters
font = CreateFont( -12,// Height Of Font
0,// Width Of Font
0,// Angle Of Escapement
0,// Orientation Angle
FW_BOLD,// Font Weight
FALSE,// Italic
FALSE,// Underline
FALSE,// Strikeout
ANSI_CHARSET,// Character Set Identifier
OUT_TT_PRECIS,// Output Precision
CLIP_DEFAULT_PRECIS,// Clipping Precision
ANTIALIASED_QUALITY,// Output Quality
FF_DONTCARE|DEFAULT_PITCH,// Family And Pitch
NULL);// Font Name
HDC hDC = window->hDC;
SelectObject(hDC, font);// Selects The Font We Created
wglUseFontOutlines( hDC,// Select The Current DC
0,// Starting Character
255,// Number Of Display Lists To Build
base,// Starting Display Lists
0.0f,// Deviation From The True Outlines
0.0f,// Font Thickness In The Z Direction
WGL_FONT_POL YGONS,// Use Polygons, Not Lines
gmf);// Address Of Buffer To Recieve Data
}
GLvoid KillFont(GLvoid)// Delete The Font
{
glDeleteLists(base, 256);// Delete All 256 Characters
}
GLvoid glPrint(float x, float y, float z, const char *fmt, ...) // Custom GL "Print" Routine
{
float length=0;// Used To Find The Length Of The Text
char text[256];// Holds Our String
va_list ap;// Pointer To List Of Arguments
if (fmt == NULL)// If There's No Text
return;// Do Nothing
va_start(ap, fmt);// Parses The String For Variables
vsprintf(text, fmt, ap);// And Converts Symbols To Actual Numbers
va_end(ap);// Results Are Stored In Text
for (unsigned int loop=0;loop<(strlen(text));loop++)// Loop To Find Text Length
{
length+=gmf[text[loop]].gmfCellIncX;// Increase Length By Each Characters Width }
glTranslatef(x - length, y, z);// Position Text On The Screen
glPushAttrib(GL_LIST_BIT);// Pushes The Display List Bits
glListBase(base);// Sets The Base Character to 0
glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);// Draws The Display List Text
glPopAttrib();// Pops The Display List Bits
glTranslatef(-x, -y, -z);// Position Text On The Screen
}
BOOL Initialize (GL_Window* window, Keys* keys)// Any GL Init Code & User Initialiazation Goes Here
{
g_window = window;
g_keys = keys;
glClearColor (0.0f, 0.0f, 0.0f, 0.5f);// Black Background
glShadeModel (GL_SMOOTH);// Select Smooth Shading
glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);// Set Perspective
Calculations To Most Accurate
BuildFont(window);// Build The Font
return TRUE;// Return TRUE (Initialization Successful)
}
void Deinitialize (void)// Any User DeInitialization Goes Here
{
KillFont();
}
void Update (DWORD milliseconds)// Perform Motion Updates Here
{
if (g_keys->keyDown [VK_ESCAPE] == TRUE)// Is ESC Being Pressed?
TerminateApplication (g_window);// Terminate The Program
if (g_keys->keyDown [VK_F1] == TRUE)// Is F1 Being Pressed?
ToggleFullscreen (g_window);// Toggle Fullscreen Mode
// dt Is The Time Interval (As Seconds) From The Previous Frame To The Current Frame.
// dt Will Be Used To Iterate Simulation Values Such As Velocity And Position Of Masses.
float dt = milliseconds / 1000.0f;// Let's Convert Milliseconds To Seconds
timeElapsed += dt;// Iterate Elapsed Time
float maxPossible_dt = 0.1f;// Say That The Maximum Possible dt Is 0.1 Seconds
// This Is Needed So We Do Not Pass Over A Non Precise dt Value
int numOfIterations = (int)(dt / maxPossible_dt) + 1;// Calculate Number Of Iterations To Be Made At This Update Depending On maxPossible_dt And dt
if (numOfIterations != 0)// Avoid Division By Zero
dt = dt / numOfIterations;// dt Should Be Updated According To numOfIterations
for (int a = 0; a < numOfIterations; ++a)// We Need To Iterate Simulations "numOfIterations" Times
{
//Add iteration action...
}
void Draw (void)
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity ();// Reset The Modelview Matrix
// Position Camera 40 Meters Up In Z-Direction.
// Set The Up Vector In Y-Direction So That +X Directs To Right And +Y Directs To Up On The Window.
gluLookAt(0, 0, 40, 0, 0, 0, 0, 1, 0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// Clear Screen And Depth Buffer
// Drawing The Coordinate Plane Starts Here.
// We Will Draw Horizontal And V ertical Lines With A Space Of 1 Meter Between Them.
glColor3ub(0, 255, 255);// Draw In Blue
glBegin(GL_LINES);
//Add lines...
int i;
for ( i = 0; i < sizeof(vec) / sizeof(vec[0]) - 1; i++) {
glVertex3f(vec[i].X, vec[i].Y, vec[i].Z);
glVertex3f(vec[i+1].X, vec[i+1].Y, vec[i+1].Z);
}
glVertex3f(-20, 0, 0);
glVertex3f(20, 0, 0);
glEnd();
glColor3ub(255, 0, 0);
glPointSize(4);
glBegin(GL_POINTS);
//Add points...
for (int i = 0; i < sizeof(vec) / sizeof(vec[0]); i++) {
glVertex3f(vec[i].X, vec[i].Y, vec[i].Z);
}
glEnd();
glColor3ub(255, 255, 255);// Draw In White
glPrint(-5.0f, 14, 0, "Time elapsed (seconds): %.2f", timeElapsed); // Print timeElapsed
glPrint(-5.0f, 13, 0, "Add What You WANT To Say HERE"); // Print
glFlush ();// Flush The GL Rendering Pipeline
}
//这边是框架
#include
#include
#include
#include "NeHeGL.h"// Header File For The NeHeGL Basecode
#define WM_TOGGLEFULLSCREEN (WM_USER+1)// Application Define Message For Toggling
static BOOL g_isProgramLooping;// Window Creation Loop, For FullScreen/Windowed Toggle// Between Fullscreen / Windowed Mode
static BOOL g_createFullScreen;// If TRUE, Then Create Fullscreen
void TerminateApplication (GL_Window* window)// Terminate The Application
{
PostMessage (window->hWnd, WM_QUIT, 0, 0);// Send A WM_QUIT Message
g_isProgramLooping = FALSE;// Stop Looping Of The Program
}
void ToggleFullscreen (GL_Window* window)// Toggle Fullscreen/Windowed
{
PostMessage (window->hWnd, WM_TOGGLEFULLSCREEN, 0, 0);// Send A WM_TOGGLEFULLSCREEN Message
}
void ReshapeGL (int width, int height)// Reshape The Window When It's Moved Or Resized
{
glViewport (0, 0, (GLsizei)(width), (GLsizei)(height));// Reset The Current Viewport
glMatrixMode (GL_PROJECTION);// Select The Projection Matrix
glLoadIdentity ();// Reset The Projection Matrix
gluPerspective (45.0f, (GLfloat)(width)/(GLfloat)(height),// Calculate The Aspect Ratio Of The Window
1.0f, 100.0f);
glMatrixMode (GL_MODELVIEW);// Select The Modelview Matrix
glLoadIdentity ();// Reset The Modelview Matrix
}
BOOL ChangeScreenResolution (int width, int height, int bitsPerPixel) // Change The Screen Resolution
DEVMODE dmScreenSettings;// Device Mode
ZeroMemory (&dmScreenSettings, sizeof (DEVMODE));// Make Sure Memory Is Cleared dmScreenSettings.dmSize = sizeof (DEVMODE);// Size Of The Devmode Structure
dmScreenSettings.dmPelsWidth = width;// Select Screen Width
dmScreenSettings.dmPelsHeight = height;// Select Screen Height
dmScreenSettings.dmBitsPerPel = bitsPerPixel;// Select Bits Per Pixel
dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
if (ChangeDisplaySettings (&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
{
return FALSE;// Display Change Failed, Return False
}
return TRUE;// Display Change Was Successful, Return True
}
BOOL CreateWindowGL (GL_Window* window)// This Code Creates Our OpenGL Window {
DWORD windowStyle = WS_OVERLAPPEDWINDOW;// Define Our Window Style
DWORD windowExtendedStyle = WS_EX_APPWINDOW;// Define The Window's Extended Style
PIXELFORMATDESCRIPTOR pfd =// pfd Tells Windows How We Want Things To Be
{
sizeof (PIXELFORMATDESCRIPTOR),// Size Of This Pixel Format Descriptor
1,// Version Number
PFD_DRAW_TO_WINDOW |// Format Must Support Window
PFD_SUPPORT_OPENGL |// Format Must Support OpenGL
PFD_DOUBLEBUFFER,// Must Support Double Buffering
PFD_TYPE_RGBA,// Request An RGBA Format
window->init.bitsPerPixel,// Select Our Color Depth
0, 0, 0, 0, 0, 0,// Color Bits Ignored
0,// No Alpha Buffer
0,// Shift Bit Ignored
0,// No Accumulation Buffer
0, 0, 0, 0,// Accumulation Bits Ignored
16,// 16Bit Z-Buffer (Depth Buffer)
0,// No Stencil Buffer
0,// No Auxiliary Buffer
PFD_MAIN_PLANE,// Main Drawing Layer
0,// Reserved
0, 0, 0// Layer Masks Ignored
};
RECT windowRect = {0, 0, window->init.width, window->init.height}; // Define Our Window Coordinates
GLuint PixelFormat;// Will Hold The Selected Pixel Format
if (window->init.isFullScreen == TRUE)// Fullscreen Requested, Try Changing Video Modes {
if (ChangeScreenResolution (window->init.width, window->init.height, window->init.bitsPerPixel) == FALSE)
{
// Fullscreen Mode Failed. Run In Windowed Mode Instead
MessageBox (HWND_DESKTOP, "Mode Switch Failed.\nRunning In Windowed Mode.", "Error", MB_OK | MB_ICONEXCLAMA TION);
window->init.isFullScreen = FALSE;// Set isFullscreen To False (Windowed Mode)
}
else// Otherwise (If Fullscreen Mode Was Successful)
{
ShowCursor (FALSE);// Turn Off The Cursor
windowStyle = WS_POPUP;// Set The WindowStyle To WS_POPUP (Popup Window)
windowExtendedStyle |= WS_EX_TOPMOST;// Set The Extended Window Style To WS_EX_TOPMOST
}// (Top Window Covering Everything Else)
}
else// If Fullscreen Was Not Selected
{
// Adjust Window, Account For Window Borders
AdjustWindowRectEx (&windowRect, windowStyle, 0, windowExtendedStyle);
}
// Create The OpenGL Window
window->hWnd = CreateWindowEx (windowExtendedStyle,// Extended Style
window->init.application->className, // Class Name
window->init.title,// Window Title
windowStyle,// Window Style
0, 0,// Window X,Y Position
windowRect.right - windowRect.left, // Window Width
windowRect.bottom - windowRect.top, // Window Height
HWND_DESKTOP,// Desktop Is Window's Parent
0,// No Menu
window->init.application->hInstance, // Pass The Window Instance
window);
if (window->hWnd == 0)// Was Window Creation A Success?
{
return FALSE;// If Not Return False
}
window->hDC = GetDC (window->hWnd);// Grab A Device Context For This Window
if (window->hDC == 0)// Did We Get A Device Context?
{
// Failed
DestroyWindow (window->hWnd);// Destroy The Window
window->hWnd = 0;// Zero The Window Handle
return FALSE;// Return False
}
PixelFormat = ChoosePixelFormat (window->hDC, &pfd);// Find A Compatible Pixel Format
if (PixelFormat == 0)// Did We Find A Compatible Format?
{
// Failed
ReleaseDC (window->hWnd, window->hDC);// Release Our Device Context
window->hDC = 0;// Zero The Device Context
DestroyWindow (window->hWnd);// Destroy The Window
window->hWnd = 0;// Zero The Window Handle
return FALSE;// Return False
}
if (SetPixelFormat (window->hDC, PixelFormat, &pfd) == FALSE)// Try To Set The Pixel Format
{
// Failed
ReleaseDC (window->hWnd, window->hDC);// Release Our Device Context
window->hDC = 0;// Zero The Device Context
DestroyWindow (window->hWnd);// Destroy The Window
window->hWnd = 0;// Zero The Window Handle
return FALSE;// Return False
}
window->hRC = wglCreateContext (window->hDC);// Try To Get A Rendering Context
if (window->hRC == 0)// Did We Get A Rendering Context?
{
// Failed
ReleaseDC (window->hWnd, window->hDC);// Release Our Device Context
window->hDC = 0;// Zero The Device Context
DestroyWindow (window->hWnd);// Destroy The Window
window->hWnd = 0;// Zero The Window Handle
return FALSE;// Return False
}
// Make The Rendering Context Our Current Rendering Context
if (wglMakeCurrent (window->hDC, window->hRC) == FALSE)
{
// Failed
wglDeleteContext (window->hRC);// Delete The Rendering Context
window->hRC = 0;// Zero The Rendering Context
ReleaseDC (window->hWnd, window->hDC);// Release Our Device Context
window->hDC = 0;// Zero The Device Context
DestroyWindow (window->hWnd);// Destroy The Window
window->hWnd = 0;// Zero The Window Handle
return FALSE;// Return False
}
ShowWindow (window->hWnd, SW_NORMAL);// Make The Window Visible
window->isVisible = TRUE;// Set isVisible To True
ReshapeGL (window->init.width, window->init.height);// Reshape Our GL Window
ZeroMemory (window->keys, sizeof (Keys));// Clear All Keys
window->lastTickCount = GetTickCount ();// Get Tick Count
return TRUE;// Window Creating Was A Success
// Initialization Will Be Done In WM_CREATE
}
BOOL DestroyWindowGL (GL_Window* window)// Destroy The OpenGL Window & Release Resources
{
if (window->hWnd != 0)// Does The Window Have A Handle?
{
if (window->hDC != 0)// Does The Window Have A Device Context?
{
wglMakeCurrent (window->hDC, 0);// Set The Current Active Rendering Context To Zero
if (window->hRC != 0)// Does The Window Have A Rendering Context?
{
wglDeleteContext (window->hRC);// Release The Rendering Context
window->hRC = 0;// Zero The Rendering Context
}
ReleaseDC (window->hWnd, window->hDC);// Release The Device Context
window->hDC = 0;// Zero The Device Context
}
DestroyWindow (window->hWnd);// Destroy The Window
window->hWnd = 0;// Zero The Window Handle
}
if (window->init.isFullScreen)// Is Window In Fullscreen Mode
{
ChangeDisplaySettings (NULL,0);// Switch Back To Desktop Resolution
ShowCursor (TRUE);// Show The Cursor
}
return TRUE;// Return True
}
// Process Window Message Callbacks
LRESULT CALLBACK WindowProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// Get The Window Context
GL_Window* window = (GL_Window*)(GetWindowLong (hWnd, GWL_USERDA TA));
switch (uMsg)// Evaluate Window Message
{
case WM_SYSCOMMAND:// Intercept System Commands
{
switch (wParam)// Check System Calls
{
case SC_SCREENSA VE:// Screensaver Trying To Start?
case SC_MONITORPOWER:// Monitor Trying To Enter Powersave?
return 0;// Prevent From Happening
}
break;// Exit
}
return 0;// Return
case WM_CREATE:// Window Creation
{
CREATESTRUCT* creation = (CREATESTRUCT*)(lParam);// Store Window
Structure Pointer
window = (GL_Window*)(creation->lpCreateParams);
SetWindowLong (hWnd, GWL_USERDATA, (LONG)(window));
}
return 0;// Return
case WM_CLOSE:// Closing The Window
TerminateApplication(window);// Terminate The Application
return 0;// Return
case WM_SIZE:// Size Action Has Taken Place
switch (wParam)// Evaluate Size Action
{
case SIZE_MINIMIZED:// Was Window Minimized?
window->isVisible = FALSE;// Set isVisible To False
return 0;// Return
case SIZE_MAXIMIZED:// Was Window Maximized?
window->isVisible = TRUE;// Set isVisible To True
ReshapeGL (LOWORD (lParam), HIWORD (lParam));// Reshape Window - LoWord=Width, HiWord=Height
return 0;// Return
case SIZE_RESTORED:// Was Window Restored?
window->isVisible = TRUE;// Set isVisible To True
ReshapeGL (LOWORD (lParam), HIWORD (lParam));// Reshape Window - LoWord=Width, HiWord=Height
return 0;// Return
}
break;// Break
case WM_KEYDOWN:// Update Keyboard Buffers For Keys Pressed
if ((wParam >= 0) && (wParam <= 255))// Is Key (wParam) In A Valid Range?
{
window->keys->keyDown [wParam] = TRUE;// Set The Selected Key (wParam) To True
return 0;// Return
}
break;// Break
case WM_KEYUP:// Update Keyboard Buffers For Keys Released
if ((wParam >= 0) && (wParam <= 255))// Is Key (wParam) In A Valid Range?
{
window->keys->keyDown [wParam] = FALSE;// Set The Selected Key
(wParam) To False
return 0;// Return
}
break;// Break
case WM_TOGGLEFULLSCREEN:// Toggle FullScreen Mode On/Off
g_createFullScreen = (g_createFullScreen == TRUE) ? FALSE : TRUE;
PostMessage (hWnd, WM_QUIT, 0, 0);
break;// Break
}
return DefWindowProc (hWnd, uMsg, wParam, lParam);// Pass Unhandled Messages To DefWindowProc
}
BOOL RegisterWindowClass (Application* application)// Register A Window Class For This Application.
{// TRUE If Successful
// Register A Window Class
WNDCLASSEX windowClass;// Window Class
ZeroMemory (&windowClass, sizeof (WNDCLASSEX));// Make Sure Memory Is Cleared windowClass.cbSize = sizeof (WNDCLASSEX);// Size Of The windowClass Structure
windowClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraws The Window For Any Movement / Resizing
windowClass.lpfnWndProc = (WNDPROC)(WindowProc);// WindowProc Handles Messages
windowClass.hInstance = application->hInstance;// Set The Instance
windowClass.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE);// Class Background Brush Color
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);// Load The Arrow Pointer
windowClass.lpszClassName = application->className;// Sets The Applications Classname if (RegisterClassEx (&windowClass) == 0)// Did Registering The Class Fail?
{
// NOTE: Failure, Should Never Happen
MessageBox (HWND_DESKTOP, "RegisterClassEx Failed!", "Error", MB_OK | MB_ICONEXCLAMA TION);
return FALSE;// Return False (Failure)
}
return TRUE;// Return True (Success)
}
// Program Entry (WinMain)
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
Application application;// Application Structure
GL_Window window;// Window Structure
Keys keys;// Key Structure
BOOL isMessagePumpActive;// Message Pump Active?
MSG msg;// Window Message Structure
DWORD tickCount;// Used For The Tick Counter
// Fill Out Application Data
application.className = "OpenGL";// Application Class Name
application.hInstance = hInstance;// Application Instance
// Fill Out Window
ZeroMemory (&window, sizeof (GL_Window));// Make Sure Memory Is Zeroed
window.keys = &keys;// Window Key Structure
window.init.application = &application;// Window Application
window.init.title = "OPENGL FRAME DEMOS"; // Window Title
window.init.width = 640;// Window Width
window.init.height = 480;// Window Height
window.init.bitsPerPixel = 16;// Bits Per Pixel
window.init.isFullScreen = TRUE;// Fullscreen? (Set To TRUE)
ZeroMemory (&keys, sizeof (Keys));// Zero keys Structure
// Ask The User If They Want To Start In FullScreen Mode?
if (MessageBox (HWND_DESKTOP, "Would You Like To Run In Fullscreen Mode?", "Start FullScreen?", MB_YESNO | MB_ICONQUESTION) == IDNO)
{
window.init.isFullScreen = FALSE;// If Not, Run In Windowed Mode }
// Register A Class For Our Window To Use
if (RegisterWindowClass (&application) == FALSE)// Did Registering A Class Fail?
{
// Failure
MessageBox (HWND_DESKTOP, "Error Registering Window Class!", "Error", MB_OK | MB_ICONEXCLAMATION);
return -1;// Terminate Application
}
g_isProgramLooping = TRUE;// Program Looping Is Set To TRUE
g_createFullScreen = window.init.isFullScreen;// g_createFullScreen Is Set To User Default
while (g_isProgramLooping)// Loop Until WM_QUIT Is Received
{
// Create A Window
window.init.isFullScreen = g_createFullScreen;// Set Init Param Of Window Creation To Fullscreen?
if (CreateWindowGL (&window) == TRUE)// Was Window Creation Successful?
{
// At This Point We Should Have A Window That Is Setup To Render OpenGL
if (Initialize (&window, &keys) == FALSE)// Call User Intialization
{
// Failure
TerminateApplication (&window);// Close Window, This Will Handle The Shutdown
}
else// Otherwise (Start The Message Pump)
{ // Initialize was a success
isMessagePumpActive = TRUE;// Set isMessagePumpActive To TRUE
while (isMessagePumpActive == TRUE)// While The Message Pump Is Active
{
// Success Creating Window. Check For Window Messages
if (PeekMessage (&msg, window.hWnd, 0, 0, PM_REMOVE) != 0)
{
// Check For WM_QUIT Message
if (msg.message != WM_QUIT)// Is The Message A WM_QUIT Message?
{
DispatchMessage (&msg);// If Not, Dispatch The Message
}
else// Otherwise (If Message Is WM_QUIT)
{
isMessagePumpActive = FALSE;// Terminate The Message Pump
}
}
else// If There Are No Messages
{
if (window.isVisible == FALSE)// If Window Is Not Visible
{
WaitMessage ();// Application Is Minimized Wait For A Message
}
else// If Window Is Visible
{
// Process Application Loop
tickCount = GetTickCount ();// Get The Tick Count
Update (tickCount - https://www.sodocs.net/doc/8c6185939.html,stTickCount); // Update The Counter
https://www.sodocs.net/doc/8c6185939.html,stTickCount = tickCount;// Set Last Count To Current Count
Draw ();// Draw Our Scene
SwapBuffers (window.hDC);// Swap Buffers (Double Buffering)
}
}
}// Loop While isMessagePumpActive == TRUE
}// If (Initialize (...
// Application Is Finished
Deinitialize ();// User Defined DeInitialization
DestroyWindowGL (&window);// Destroy The Active Window
}
else// If Window Creation Failed
{
// Error Creating Window
MessageBox (HWND_DESKTOP, "Error Creating OpenGL Window", "Error", MB_OK | MB_ICONEXCLAMATION);
g_isProgramLooping = FALSE;// Terminate The Loop
}
}// While (isProgramLooping)
UnregisterClass (application.className, application.hInstance);// UnRegister Window Class return 0;
}// End Of WinMain()
///这个是框架的头文件
#ifndef GL_FRAMEWORK__INCLUDED
#define GL_FRAMEWORK__INCLUDED
#include
typedef struct {// Structure For Keyboard Stuff
BOOL keyDown [256];// Holds TRUE / FALSE For Each Key
} Keys;// Keys
typedef struct {// Contains Information Vital To Applications
HINSTANCE hInstance;// Application Instance
const char* className;// Application ClassName
} Application;// Application
typedef struct {// Window Creation Info
Application* application;// Application Structure
char* title;// Window Title
int width;// Width
int height;// Height
int bitsPerPixel;// Bits Per Pixel
BOOL isFullScreen;// FullScreen?
} GL_WindowInit;// GL_WindowInit
typedef struct {// Contains Information Vital To A Window
Keys* keys;// Key Structure
HWND hWnd;// Window Handle
HDC hDC;// Device Context
HGLRC hRC;// Rendering Context
GL_WindowInit init;// Window Init
BOOL isVisible;// Window Visible?
DWORD lastTickCount;// Tick Counter
} GL_Window;// GL_Window
void TerminateApplication (GL_Window* window);// Terminate The Application
void ToggleFullscreen (GL_Window* window);// Toggle Fullscreen / Windowed Mode
// These Are The Function You Must Provide
BOOL Initialize (GL_Window* window, Keys* keys); // Performs All Your Initialization void Deinitialize (void);// Performs All Your DeInitialization
void Update (DWORD milliseconds);// Perform Motion Updates
void Draw (void);// Perform All Your Scene Drawing
#endif// GL_FRAMEWORK__INCLUDED
////////////////////////////////////////////////////////////////////////////////