glPerspective 和glLookAt

本文介绍了OpenGL中两个重要的函数gluLookAt和gluPerspective。gluLookAt用于设置观察者的位置和朝向,而gluPerspective则用于设置透视投影的视角、纵横比和裁剪平面。fovy参数表示视角大小,aspect是窗口纵横比,zNear和zFar定义了裁剪平面的位置,展示了透视原理的应用。

函数原型
gluLookAt(GLdoble eyex,GLdouble eyey,GLdouble eyez,GLdouble centerx,GLdouble centery,GLdouble centerz,GLdouble upx,GLdouble upy,GLdouble upz);

gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear,GLdouble zFar)

一个一个来,首先得设置gluPerspective,来看看它的参数都表示什么意思
fovy,这个最难理解,我的理解是,眼睛睁开的角度,即,视角的大小,如果设置为0,相当你闭上眼睛了,所以什么也看不到,如果为180,那么可以认为你的视界很广阔,
aspect,这个好理解,就是实际窗口的纵横比,即x/y
zNear,这个呢,表示你近处,的裁面,
zFar表示远处的裁面,

如果还没有理解就继续看,
我们知道,远处的东西看起来要小一些,近处的东西看起来会大一些,这就是透视原理
如下图所示




假设那两条线表示公路,理论上讲,它们的两条边是平行的,
但现实情况中,它们在远方(可以无限远)总要相交于一点,
实际线段AB的长度=CD的长度,只是在此例中使用了透视角,故会有如上的效果,是不是很接近现实的情况?

结合我们刚才这两个函数
zNear,眼睛距离近处的距离,假设为10米远,请不要设置为负值,OpenGl就傻
在Dev - C++中,出现`'glPerspective' was not declared in this scope`错误,通常是因为缺少必要的头文件或库链接问题。针对仅使用原生OpenGL库开发的情况,可以按以下方法解决: ### 1. 包含必要头文件 `glPerspective` 函数来自 OpenGL Utility Library(GLU),需要包含 `<GL/glu.h>` 头文件。在代码开头添加: ```cpp #include <windows.h> #include <GL/gl.h> #include <GL/glu.h> ``` ### 2. 链接 GLU 库 如果头文件包含正确,但仍然出现未声明错误,可能是没有链接 GLU 库。在 Dev - C++ 中链接库的步骤如下: - 打开项目属性(通常在“项目”菜单中选择“项目属性”)。 - 在“参数”选项卡中,找到“链接器”一栏,添加 `-lglu32` 到链接器命令行中。这样可以确保在编译时链接 GLU 库。 ### 示例代码 以下是一个完整的示例代码,展示了如何使用 `glPerspective` 函数: ```cpp #include <windows.h> #include <GL/gl.h> #include <GL/glu.h> LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; } BOOL SetupPixelFormat(HDC hdc) { PIXELFORMATDESCRIPTOR pfd; int pixelformat; ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR)); pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 32; pfd.cDepthBits = 32; pfd.iLayerType = PFD_MAIN_PLANE; pixelformat = ChoosePixelFormat(hdc, &pfd); if (pixelformat == 0) return FALSE; if (SetPixelFormat(hdc, pixelformat, &pfd) == FALSE) return FALSE; return TRUE; } void InitOpenGL(HDC hdc) { HGLRC hrc = wglCreateContext(hdc); wglMakeCurrent(hdc, hrc); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, 800.0f / 600.0f, 0.1f, 100.0f); glMatrixMode(GL_MODELVIEW); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASS wc; HWND hwnd; MSG msg; ZeroMemory(&wc, sizeof(WNDCLASS)); wc.lpfnWndProc = WndProc; wc.hInstance = hInstance; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.lpszClassName = "OpenGLWindow"; RegisterClass(&wc); hwnd = CreateWindow("OpenGLWindow", "OpenGL 3D Window", WS_OVERLAPPEDWINDOW, 100, 100, 800, 600, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, nCmdShow); HDC hdc = GetDC(hwnd); SetupPixelFormat(hdc); InitOpenGL(hdc); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslatef(0.0f, 0.0f, -5.0f); glBegin(GL_TRIANGLES); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(-0.5f, -0.5f, 0.0f); glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(0.5f, -0.5f, 0.0f); glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(0.0f, 0.5f, 0.0f); glEnd(); SwapBuffers(hdc); } wglMakeCurrent(NULL, NULL); wglDeleteContext(wglGetCurrentContext()); ReleaseDC(hwnd, hdc); DestroyWindow(hwnd); UnregisterClass("OpenGLWindow", hInstance); return msg.wParam; } ``` ###
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值