您的位置:首页 > 运维架构

NeHe的OpenGl教程 - 前5课总结

2009-10-19 12:35 239 查看
NeHe 的 OpenGL 教程浅显易懂,每行都有注释,适合入门学习用。不过,要想让教程中的程序运行在我的电脑上,需要做一些小小的设置

我的电脑的软件配置:Windows XP Professional + Visual C++ 2008 Express

1. “项目属性”的 Configuration Properties 选项卡:Character Set

NeHe 教程用的全是 C-sytle null terminated string。所以我们要根据自己的项目的特点做相应设置。我的程序使用的都是UNICODE字符串,所以设置为 Use UNICODE Character Set

2. “Linker” -> “Input”选项卡:Additional Dependencies 需要添加两行

"$(WindowsSdkDir)Lib/glu32.lib"

"$(WindowsSdkDir)Lib/opengl32.lib"

3. 原教程中的代码:#include <glaux.h> 在网上很难找,于是去掉了。反正只要不用里面的代码就OK

然后就可以让下面的代码运行了:

#include <windows.h>
#include <math.h>
#include <gl/gl.h>
#include <gl/glu.h>
// global variable
HDC        g_hDC  = NULL;
HGLRC      g_hRC  = NULL;
HWND       g_hWnd = NULL;
HINSTANCE  g_hIns = NULL;
BOOL       g_pKeys[256]  = {0};
BOOL       g_bActive     = TRUE;
BOOL       g_bFullScreen = TRUE;
GLfloat    g_fAngle4Tri  = 0.0f;
GLfloat    g_fAngle4Quad = 0.0f;
LPCTSTR    g_lpszWndClass = TEXT("OpenGL");
const float kRotateSpeed = 0.001f;
const float kRadius = 3.0f;
const DWORD kStartTime = GetTickCount();
GLvoid ResizeGLWnd(GLsizei nWidth, GLsizei nHeight)
{
if(nHeight == 0)
{
nHeight = 1;
}
glViewport(0, 0, nWidth, nHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat)nWidth/(GLfloat)nHeight, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
GLvoid KillGLWnd()
{
if(g_bFullScreen)
{
ChangeDisplaySettings(NULL, 0);
ShowCursor(TRUE);
}
if(g_hRC)
{
if(!wglMakeCurrent(NULL, 0))
{
MessageBox(g_hWnd, TEXT("Desktop cannot be showed properly."), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
}
if(!wglDeleteContext(g_hRC))
{
MessageBox(g_hWnd, TEXT("OpenGL rendering context cannot be released"), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
}
g_hRC = NULL;
}
if(g_hDC && !ReleaseDC(g_hWnd, g_hDC))
{
MessageBox(g_hWnd, TEXT("Windows device context cannot be released"), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
g_hDC = NULL;
}
if(g_hWnd && !DestroyWindow(g_hWnd))
{
MessageBox(g_hWnd, TEXT("Windows cannot be destroyed"), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
g_hWnd = NULL;
}
if(!UnregisterClass(g_lpszWndClass, g_hIns))
{
MessageBox(g_hWnd, TEXT("Windows class unregistering failed"), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
g_hIns = NULL;
}
}
int InitOpenGL()
{
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL CreateGLWnd(PTSTR lpTitle, int nWidth, int nHeight, int nBits, bool bFullScreen)
{
GLuint nPixelFormat;
WNDCLASS wc;
DWORD dwStyle, dwExStyle;
RECT WndRect;
WndRect.left   = (long)0;
WndRect.right  = (long)nWidth;
WndRect.top    = (long)0;
WndRect.bottom = (long)nHeight;
g_bFullScreen = bFullScreen;
g_hIns = GetModuleHandle(NULL);
wc.style       = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.cbClsExtra  = 0;
wc.cbWndExtra  = 0;
wc.hInstance   = g_hIns;
wc.hIcon       = LoadIcon(NULL, IDI_WINLOGO);
wc.hCursor     = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName  = NULL;
wc.lpszClassName = g_lpszWndClass;
if(!RegisterClass(&wc))
{
MessageBox(NULL, TEXT("Register of window class failed"), TEXT("CREATE ERROR"), MB_OK | MB_ICONEXCLAMATION);
return FALSE;
}
if(g_bFullScreen)
{
DEVMODE dmScreenSettings;
memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
dmScreenSettings.dmSize = sizeof(dmScreenSettings);
dmScreenSettings.dmPelsWidth = nWidth;
dmScreenSettings.dmPelsHeight = nHeight;
dmScreenSettings.dmBitsPerPel = nBits;
dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
if(ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN))
{
if (MessageBox(NULL,
TEXT("The Requested Fullscreen Mode Is Not Supported By/nYour Video Card. Use Windowed Mode Instead?"),
TEXT("NeHe GL"),
MB_YESNO | MB_ICONEXCLAMATION)
== IDYES)
{
g_bFullScreen = FALSE;		// Windowed Mode Selected.  Fullscreen = FALSE
}
else
{
// Pop Up A Message Box Letting User Know The Program Is Closing.
MessageBox(NULL, TEXT("Program Will Now Close."),TEXT("ERROR"), MB_OK | MB_ICONSTOP);
return FALSE;									// Return FALSE
}
}
}
if(g_bFullScreen)
{
dwExStyle = WS_EX_APPWINDOW;
dwStyle   = WS_POPUP;
ShowCursor(FALSE);
}
else
{
dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
dwStyle   = WS_OVERLAPPEDWINDOW;
}
AdjustWindowRectEx(&WndRect, dwStyle, FALSE, dwExStyle);
if(!(g_hWnd = CreateWindowEx(dwExStyle,
g_lpszWndClass,
lpTitle,
dwStyle | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
0, 0,
WndRect.right - WndRect.left,
WndRect.bottom - WndRect.top,
NULL,
NULL,
g_hIns,
NULL)))
{
KillGLWnd();
MessageBox(NULL, TEXT("Window Creation Error."),TEXT("ERROR"), MB_OK | MB_ICONEXCLAMATION);
return FALSE;
}
static	PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
nBits,
0,0,0,0,0,0,
0,
0,
0,
0,0,0,0,
16,
0,
0,
PFD_MAIN_PLANE,
0,
0,0,0
};
if(!(g_hDC = GetDC(g_hWnd)))
{
KillGLWnd();
MessageBox(NULL, TEXT("Can't Create A GL Device Context."), TEXT("ERROR"), MB_OK | MB_ICONEXCLAMATION);
return FALSE;
}
if(!(nPixelFormat = ChoosePixelFormat(g_hDC, &pfd)))
{
KillGLWnd();
MessageBox(NULL, TEXT("Can't find proper pixel format."), TEXT("ERROR"), MB_OK | MB_ICONEXCLAMATION);
return FALSE;
}
if(!SetPixelFormat(g_hDC, nPixelFormat, &pfd))
{
KillGLWnd();
MessageBox(NULL, TEXT("Can't Set The PixelFormat."), TEXT("ERROR"),MB_OK | MB_ICONEXCLAMATION);
return FALSE;
}
if (!(g_hRC = wglCreateContext(g_hDC)))
{
KillGLWnd();
MessageBox(NULL, TEXT("Can't Create A GL Rendering Context."), TEXT("ERROR"),MB_OK | MB_ICONEXCLAMATION);
return FALSE;
}

if(!wglMakeCurrent(g_hDC, g_hRC))
{
KillGLWnd();
MessageBox(NULL, TEXT("Can't Activate The GL Rendering Context."), TEXT("ERROR"),MB_OK | MB_ICONEXCLAMATION);
return FALSE;
}
ShowWindow(g_hWnd, SW_SHOW);
SetForegroundWindow(g_hWnd);
SetFocus(g_hWnd);
ResizeGLWnd(nWidth, nHeight);
if(!InitOpenGL())
{
KillGLWnd();
MessageBox(NULL, TEXT("Initialization Failed."), TEXT("ERROR"),MB_OK | MB_ICONEXCLAMATION);
return FALSE;
}
}
int DrawScene()
{
const GLfloat kDistanceZ = -15.0f;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// triangle
glTranslatef(0.0f, -2.0f, kDistanceZ);
glRotatef(g_fAngle4Tri, 0.0f, 1.0f, 0.0f);
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);

glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glEnd();
glLoadIdentity();
// square
DWORD dwDeltaTime = GetTickCount() - kStartTime;
GLfloat fNewX = kRadius * cos(dwDeltaTime * kRotateSpeed);
GLfloat fNewZ = kRadius * sin(dwDeltaTime * kRotateSpeed);
glTranslatef(fNewX, -2.0f, fNewZ + kDistanceZ);
glRotatef(g_fAngle4Quad, 0.0f, 1.0f, 0.0f);
glBegin(GL_QUADS);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(1.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f);
glEnd();
g_fAngle4Tri  += 2.0f;
g_fAngle4Quad += 20.0f;
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_ACTIVATE:
g_bActive = !HIWORD(wParam) ? TRUE : FALSE;
return 0;
case WM_SYSCOMMAND:
switch (wParam)
{
case SC_SCREENSAVE:
case SC_MONITORPOWER:
return 0;
}
break;
case WM_CLOSE:
PostQuitMessage(0);
return 0;
case WM_KEYDOWN:
g_pKeys[wParam] = TRUE;
return 0;
case WM_KEYUP:
g_pKeys[wParam] = FALSE;
return 0;
case WM_SIZE:
ResizeGLWnd(LOWORD(lParam), HIWORD(lParam));
return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
BOOL bDone = FALSE;

// Ask The User Which Screen Mode They Prefer
if (MessageBox(NULL, TEXT("Would You Like To Run In Fullscreen Mode?"), TEXT("Start FullScreen?"), MB_YESNO | MB_ICONQUESTION) == IDNO)
{
g_bFullScreen = FALSE;
}
if (!CreateGLWnd(TEXT("NeHe's Rotation Tutorial"), 640, 480, 16, g_bFullScreen))
{
return 0;
}

while(!bDone)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
bDone = TRUE;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
if ((g_bActive && !DrawScene()) || g_pKeys[VK_ESCAPE])
{
bDone = TRUE;
}
else
{
SwapBuffers(g_hDC);
}
if (g_pKeys[VK_F1])
{
g_pKeys[VK_F1] = FALSE;
KillGLWnd();
g_bFullScreen = !g_bFullScreen;
if (!CreateGLWnd(TEXT("NeHe's Rotation Tutorial"), 640, 480, 16, g_bFullScreen))
{
return 0;
}
}
}
}
KillGLWnd();
return (msg.wParam);
}


显示效果如下图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: