没有合适的资源?快使用搜索试试~ 我知道了~
首页NeHe教程:OpenGL进阶指南
NeHeTutorials是一套由Andreas Lagotzki编译自英文原版的OpenGL教程,该系列教程发布于2004年12月。这些教程是将NeHe网站上的在线OpenGL教程转换成了RTF和PDF格式,适合双面打印在A4纸张上,旨在帮助学习者系统地掌握OpenGL编程。以下是部分内容概览:
1. **设置OpenGL环境**:教程首先指导读者如何在不同的操作系统上配置OpenGL,包括MacOS、Solaris以及MacOS X上使用GLUT库进行窗口设置。
2. **基本操作**:从"Your First Polygon"开始,介绍了如何绘制二维和三维图形的基本元素,如创建第一个多边形,并逐步添加颜色和变换功能。
3. **高级特性**:随后章节涉及更复杂的技术,如纹理映射,通过纹理过滤、光照效果和键盘控制实现三维物体的动态表现。接着探讨了混合模式(blending)、3D空间中的位图移动以及3D世界导航。
4. **特殊效果**:如“Flag Effect”(动态波浪纹理)展示了高级渲染技术,而“Display Lists”则讲解了列表化绘制以提高性能。此外,还涵盖了字体处理,如位图字体、轮廓字体和纹理映射轮廓字体。
5. **视觉增强**:包括了酷炫的雾效果,以及2D纹理字体和四元体(quadrics)的应用,为渲染增添了更多维度。
6. **粒子系统与动画**:“Particle Engine Using Triangle Strips”展示了如何利用三角形链表实现粒子系统的动画效果。
7. **遮罩与增强功能**:学习者可以在这里了解到线条渲染、抗锯齿、计时、透视视图和简单的音频应用,以及多纹理贴图和扩展功能。
8. **高级技术**:包括球面映射、多纹理及硬件扩展,如介绍如何加载对象文件和使用剪裁测试与TGA加载。
9. **变形与交互**:"Morphing & Loading Objects From A File"教导如何实现形状的变形,以及从文件中加载对象以增强用户交互。
10. **复杂场景处理**:最后部分涵盖了剪辑与反射技术,以及如何结合tokens、扩展和Scissor Testing等技术,为更复杂的3D场景提供深度处理。
NeHeTutorials是一套详尽且实用的OpenGL教程,从基础入门到高级技术,覆盖了丰富的实践案例和理论知识,对学习OpenGL编程具有很高的参考价值。无论是对初学者还是进阶开发者,这套教程都是宝贵的学习资源。
16 Setting Up An OpenGL Window NeHe's OpenGL Tutorials
using fullscreen? How do I change the Window's title? How do I change the resolution or pixel format of the
Window? The following code does all of that! Therefore it's better learning material and will make writing
OpenGL programs of your own a lot easier!
As you can see the procedure returns BOOL (TRUE or FALSE), it also takes 5 parameters: title of the
Window, width of the Window, height of the Window, bits (16/24/32), and finally fullscreenflag TRUE for
fullscreen or FALSE for windowed. We return a boolean value that will tell us if the Window was created
successfully.
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
{
When we ask Windows to find us a pixel format that matches the one we want, the number of the mode that
Windows ends up finding for us will be stored in the variable PixelFormat.
GLuint PixelFormat; // Holds The Results After Searching For A Match
wc will be used to hold our Window Class structure. The Window Class structure holds information about
our window. By changing different fields in the Class we can change how the window looks and behaves.
Every window belongs to a Window Class. Before you create a window, you MUST register a Class for the
window.
WNDCLASS wc; // Windows Class Structure
dwExStyle and dwStyle will store the Extended and normal Window Style Information. I use variables to
store the styles so that I can change the styles depending on what type of window I need to create (A popup
window for fullscreen or a window with a border for windowed mode)
DWORD dwExStyle; // Window Extended Style
DWORD dwStyle; // Window Style
The following 5 lines of code grab the upper left, and lower right values of a rectangle. We'll use these
values to adjust our window so that the area we draw on is the exact resolution we want. Normally if we
create a 640x480 window, the borders of the window take up some of our resolution.
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
In the next line of code we make the global variable fullscreen equal fullscreenflag.
fullscreen=fullscreenflag; // Set The Global Fullscreen Flag
In the next section of code, we grab an instance for our Window, then we declare the Window Class.
The style CS_HREDRAW and CS_VREDRAW force the Window to redraw whenever it is resized.
CS_OWNDC creates a private DC for the Window. Meaning the DC is not shared across applications.
WndProc is the procedure that watches for messages in our program. No extra Window data is used so we
zero the two fields. Then we set the instance. Next we set hIcon to NULL meaning we don't want an ICON
in the Window, and for a mouse pointer we use the standard arrow. The background color doesn't matter
(we set that in GL). We don't want a menu in this Window so we set it to NULL, and the class name can be
any name you want. I'll use "OpenGL" for simplicity.
// Grab An Instance For Our Window
hInstance = GetModuleHandle(NULL);
// Redraw On Move, And Own DC For Window
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc Handles Messages
NeHe's OpenGL Tutorials Setting Up An OpenGL Window 17
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
Now we register the Class. If anything goes wrong, an error message will pop up. Clicking on OK in the
error box will exit the program.
if (!RegisterClass(&wc)) // Attempt To Register The Window Class
{
MessageBox(NULL,"Failed To Register The Window Class.","ERROR",
MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Exit And Return FALSE
}
Now we check to see if the program should run in fullscreen mode or windowed mode. If it should be
fullscreen mode, we'll attempt to set fullscreen mode.
if (fullscreen) // Attempt Fullscreen Mode?
{
The next section of code is something people seem to have a lot of problems with... switching to fullscreen
mode. There are a few very important things you should keep in mind when switching to full screen mode.
Make sure the width and height that you use in fullscreen mode is the same as the width and height you
plan to use for your window, and most importantly, set fullscreen mode BEFORE you create your window. In
this code, you don't have to worry about the width and height, the fullscreen and the window size are both
set to be the size requested.
DEVMODE dmScreenSettings; // Device Mode
// Makes Sure Memory's Cleared
memset(&dmScreenSettings,0,sizeof(dmScreenSettings));
// Size Of The Devmode Structure
dmScreenSettings.dmSize=sizeof(dmScreenSettings);
dmScreenSettings.dmPelsWidth = width; // Selected Screen Width
dmScreenSettings.dmPelsHeight = height; // Selected Screen Height
dmScreenSettings.dmBitsPerPel = bits; // Selected Bits Per Pixel
dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
In the code above we clear room to store our video settings. We set the width, height and bits that we want
the screen to switch to. In the code below we try to set the requested full screen mode. We stored all the
information about the width, height and bits in dmScreenSettings. In the line below ChangeDisplaySettings
tries to switch to a mode that matches what we stored in dmScreenSettings. I use the parameter
CDS_FULLSCREEN when switching modes, because it's supposed to remove the start bar at the bottom of
the screen, plus it doesn't move or resize the windows on your desktop when you switch to fullscreen mode
and back.
// Try To Set Selected Mode And Get Results.
// NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.
if ( ChangeDisplaySettings( &dmScreenSettings,CDS_FULLSCREEN)
!= DISP_CHANGE_SUCCESSFUL)
{
If the mode couldn't be set the code below will run. If a matching fullscreen mode doesn't exist, a message
box will pop up offering two options: The option to run in a window or the option to quit.
// If The Mode Fails, Offer Two Options. Quit Or Run In A Window.
if ( MessageBox( NULL, "The Requested Fullscreen Mode Is Not "
"Supported By\nYour Video Card. Use Windowed Mode Instead?",
18 Setting Up An OpenGL Window NeHe's OpenGL Tutorials
"NeHe GL", MB_YESNO|MB_ICONEXCLAMATION) == IDYES )
{
If the user decided to use windowed mode, the variable fullscreen becomes FALSE, and the program
continues running.
fullscreen=FALSE; // Select Windowed Mode (Fullscreen=FALSE)
}
else
{
If the user decided to quit, a message box will pop up telling the user that the program is about to close.
FALSE will be returned telling our program that the window was not created successfully. The program will
then quit.
// Pop Up A Message Box Letting User Know The Program Is Closing.
MessageBox(NULL,"Program Will Now Close.","ERROR",
MB_OK|MB_ICONSTOP);
return FALSE; // Exit And Return FALSE
}
}
}
Because the fullscreen code above may have failed and the user may have decided to run the program in a
window instead, we check once again to see if fullscreen is TRUE or FALSE before we set up the screen /
window type.
if (fullscreen) // Are We Still In Fullscreen Mode?
{
If we are still in fullscreen mode we'll set the extended style to WS_EX_APPWINDOW, which force a top
level window down to the taskbar once our window is visible. For the window style we'll create a
WS_POPUP window. This type of window has no border around it, making it perfect for fullscreen mode.
Finally, we disable the mouse pointer. If your program is not interactive, it's usually nice to disable the
mouse pointer when in fullscreen mode. It's up to you though.
dwExStyle=WS_EX_APPWINDOW; // Window Extended Style
dwStyle=WS_POPUP; // Windows Style
ShowCursor(FALSE); // Hide Mouse Pointer
}
else
{
If we're using a window instead of fullscreen mode, we'll add WS_EX_WINDOWEDGE to the extended
style. This gives the window a more 3D look. For style we'll use WS_OVERLAPPEDWINDOW instead of
WS_POPUP. WS_OVERLAPPEDWINDOW creates a window with a title bar, sizing border, window menu,
and minimize / maximize buttons.
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window Extended Style
dwStyle=WS_OVERLAPPEDWINDOW; // Windows Style
}
The line below adjust our window depending on what style of window we are creating. The adjustment will
make our window exactly the resolution we request. Normally the borders will overlap parts of our window.
By using the AdjustWindowRectEx command none of our OpenGL scene will be covered up by the borders,
instead, the window will be made larger to account for the pixels needed to draw the window border. In
fullscreen mode, this command has no effect.
// Adjust Window To True Requested Size
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);
NeHe's OpenGL Tutorials Setting Up An OpenGL Window 19
In the next section of code, we're going to create our window and check to see if it was created properly.
We pass CreateWindowEx() all the parameters it requires. The extended style we decided to use. The class
name (which has to be the same as the name you used when you registered the Window Class). The
window title. The window style. The top left position of your window (0,0 is a safe bet). The width and height
of the window. We don't want a parent window, and we don't want a menu so we set both these parameters
to NULL. We pass our window instance, and finally we NULL the last parameter.
Notice we include the styles WS_CLIPSIBLINGS and WS_CLIPCHILDREN along with the style of window
we've decided to use. WS_CLIPSIBLINGS and WS_CLIPCHILDREN are both REQUIRED for OpenGL to
work properly. These styles prevent other windows from drawing over or into our OpenGL Window.
if (!(hWnd=CreateWindowEx(
dwExStyle, // Extended Style For The Window
"OpenGL", // Class Name
title, // Window Title
WS_CLIPSIBLINGS | // Required Window Style
WS_CLIPCHILDREN | // Required Window Style
dwStyle, // Selected Window Style
0, 0, // Window Position
WindowRect.right-WindowRect.left, // Calculate Adjusted Window Width
WindowRect.bottom-WindowRect.top, // Calculate Adjusted Window Height
NULL, // No Parent Window
NULL, // No Menu
hInstance, // Instance
NULL // Don't Pass Anything To WM_CREATE
)))
Next we check to see if our window was created properly. If our window was created, hWnd will hold the
window handle. If the window wasn't created the code below will pop up an error message and the program
will quit.
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Window Creation Error.","ERROR", MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
The next section of code describes a Pixel Format. We choose a format that supports OpenGL and double
buffering, along with RGBA (red, green, blue, alpha channel). We try to find a pixel format that matches the
bits we decided on (16bit,24bit,32bit). Finally we set up a 16bit Z-Buffer. The remaining parameters are
either not used or are not important (aside from the stencil buffer and the (slow) accumulation buffer).
// pfd Tells Windows How We Want Things To Be
static PIXELFORMATDESCRIPTOR pfd =
{
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
bits, // 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
};
20 Setting Up An OpenGL Window NeHe's OpenGL Tutorials
If there were no errors while creating the window, we'll attempt to get an OpenGL Device Context. If we
can't get a DC an error message will pop onto the screen, and the program will quit (return FALSE).
if (!(hDC=GetDC(hWnd))) // Did We Get A Device Context?
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Can't Create A GL Device Context.","ERROR",
MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
If we managed to get a Device Context for our OpenGL window we'll try to find a pixel format that matches
the one we described above. If Windows can't find a matching pixel format, an error message will pop onto
the screen and the program will quit (return FALSE).
// Did Windows Find A Matching Pixel Format?
if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Can't Find A Suitable PixelFormat.","ERROR",
MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
If windows found a matching pixel format we'll try setting the pixel format. If the pixel format cannot be set,
an error message will pop up on the screen and the program will quit (return FALSE).
// Are We Able To Set The Pixel Format?
if(!SetPixelFormat(hDC,PixelFormat,&pfd))
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Can't Set The PixelFormat.","ERROR",
MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
If the pixel format was set properly we'll try to get a Rendering Context. If we can't get a Rendering Context
an error message will be displayed on the screen and the program will quit (return FALSE).
// Are We Able To Get A Rendering Context?
if (!(hRC=wglCreateContext(hDC)))
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",
MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
If there have been no errors so far, and we've managed to create both a Device Context and a Rendering
Context all we have to do now is make the Rendering Context active. If we can't make the Rendering
Context active an error message will pop up on the screen and the program will quit (return FALSE).
if(!wglMakeCurrent(hDC,hRC)) // Try To Activate The Rendering Context
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Can't Activate The GL Rendering Context.","ERROR",
MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
If everything went smoothly, and our OpenGL window was created we'll show the window, set it to be the
foreground window (giving it more priority) and then set the focus to that window. Then we'll call
ReSizeGLScene passing the screen width and height to set up our perspective OpenGL screen.
剩余481页未读,继续阅读
brennacccc
- 粉丝: 0
- 资源: 1
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- shiny-auth0-plus:具有用户身份验证和授权的Auth0 Shiny代理
- python tarpython tarpython tarpython tar
- musicGraph:这是一个图表。 它制作音乐。 嬷嬷?
- ZYNQ7100实现驱动OV5640摄像头采集图像LCD数字识别显示【FPGA Vivado实现】
- 行业资料-电子功用-光电跟踪气割机的纵向传动锁紧装置的说明分析.rar
- linkjuice:自动包装并创建锚链接标题
- matlabAPP-2048小游戏.zip
- Python库 | redrum-1.5.1.tar.gz
- King-Weatherbot:一个不和谐的机器人,它随机地焚化服务器成员
- Wepy-Redux:微信小程序wepy框架接入 Redux 状态管理
- 中国崛起之健身房管理系统@xxx@源码.zip
- Python豆瓣电影数据分析可视化系统-最新版.zip
- 行业资料-电子功用-光电转换输送组件的说明分析.rar
- java开发oa办公系统源码-jeecg:jeecg产品的源代码
- Excel模板-利润及利润分配表.rar
- Python库 | mycotools-0.1a2.tar.gz
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功