OpenGL 的初始化其实挺麻烦的,特别是那么多的大写字母,所以记在这以后用时直接抄
说明:以下参考书:向世明 编著的《OpenGL 编程与实例》,电子工业出版社 1999 年9月。
比较老的一本书,呵呵,借不到更新的了,不过里面讲的还不错,起码跟着走还能运行出想要的效果
(一)创建新的 VC++ 工程:
选择 MFC AppWizard(exe),这里我命名为 studyOpengl
第一步:Single document
第二步:None
第三步:None 并选择 ActiveX controls
第四步:Use 3D Controls
第五步和第六步:缺省设置
(二)添加头文件:共两个
在 studyOpenglView.h 里添加下面两个头文件
#include "gl\gl.h"
#include "gl\glu.h"
(三)添加 lib :共两个
打开菜单 Project(工程) -> Setting(设置),在弹出的对话框的右边选择 Link 标签,然后在下面的
Object\Libaray Modules(对象\库模块) 中添加 OpenGl32.lib 和 glu32.lib ,注意多个 lib 之间以空格分开,
这两个 lib 文件分别帮助程序利用链接器访问动态链接库函数 opengl32.dll 和 glu32.dll,这两个 动态链接库可以
在电脑里系统盘的 WINDOWS 系统文件夹下的 system32 文件夹下找到。
(四)编辑 MainFrm.cpp 文件:
打开 MainFrm.cpp 文件,编辑里面的 PreCreateWindow() 函数,如下:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
// 增加下面两行,设置窗口大小
cs.cx = 300;
cs.cy = 335;
return TRUE;
}
下面开始设置与 opengl 有关的环境
(五)设置像素格式:
在 Source Files 里打开 studyOpenglView.cpp 文件。然后在工具条中点击 WizardBar Action 方向朝下的三角形图标,选择 Add Windows Message Hander 选项,在弹出的对话框中增加 Windows 消息 WM_CREATE,选择 Add and Edit 按钮生成消息响应函数 OnCreate()。
再选择上面的三角形图标选择 Add Member Function 选项,编辑弹出的对话框,可如下:void protected Init(),在相应栏里写上即可。
按上述方法增加保护成员函数 bool bSetupPixelFormat() 用于设置像素格式。
再打开 studyOpenglView.h 头文件,声明两个公有成员如下:
CClientDC * m_pDC;
CRect m_oldRect;
再打开 studyOpenglView.cpp 文件,在构造函数里对上面声明的成员变量进行初始化,如下:
CStudyOpenGLView::CStudyOpenGLView()
{
// TODO: add construction code here
m_pDC = NULL;
}
再选择成员函数列表中的 bSetupPixelFormat(),编辑该函数如下:
bool CStudyOpenGLView::bSetupPixelFormat()
{
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL,
PFD_TYPE_RGBA,
24,
0,0,0,0,0,0,
0,
0,
0,
0,0,0,0,
32,
0,
0,
PFD_MAIN_PLANE,
0,
0,0,0
};
int pixelformat;
if((pixelformat = ChoosePixelFormat(m_pDC->GetSafeHdc(),&pfd)) == 0)
{
MessageBox("选择象素格式失败");
return false;
}
if((SetPixelFormat(m_pDC->GetSafeHdc(),pixelformat,&pfd)) == false)
{
MessageBox("设置象素格式失败");
return false;
}
return true;
}
再选择成员函数 Init() , 编辑如下:
void CStudyOpenGLView::Init()
{
PIXELFORMATDESCRIPTOR pfd;
int n;
HGLRC hrc;
m_pDC = new CClientDC(this);
ASSERT(m_pDC != NULL);
if(!bSetupPixelFormat()) return ;
}
到这里就完成了像素格式的设置,下面将创建着色描述表相关的
(六)创建着色描述表并设置:
在上面的 Init() 函数后面追加代码,最后 Init() 函数如下:
void CStudyOpenGLView::Init()
{
PIXELFORMATDESCRIPTOR pfd;
int n;
HGLRC hrc;
m_pDC = new CClientDC(this);
ASSERT(m_pDC != NULL);
if(!bSetupPixelFormat()) return ;
n =::GetPixelFormat(m_pDC->GetSafeHdc());
::DescribePixelFormat(m_pDC->GetSafeHdc(),n,sizeof(pfd),&pfd);
hrc = wglCreateContext(m_pDC->GetSafeHdc());
wglMakeCurrent(m_pDC->GetSafeHdc(),hrc);
}
(七)创建 结束时的删除着色描述表:
按前面的方法增加 Windows 消息 WM_DESTROY 选择 Add and Edit 生成响应函数 OnDestroy(),如下:
void CStudyOpenGLView::OnDestroy()
{
CView::OnDestroy();
// TODO: Add your message handler code here
HGLRC hrc;
hrc = ::wglGetCurrentContext();
::wglMakeCurrent(NULL,NULL);
if(hrc)
::wglDeleteContext(hrc);
if(m_pDC)
delete m_pDC;
CView::OnDestroy();
}
然后在前面生成的 OnCreate() 函数里添加代码,如下:
int CStudyOpenGLView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
Init();
return 0;
}
(八)设定OpenGL 风格:
选择成员函数 PreCreateWindow() ,编辑如下:
BOOL CStudyOpenGLView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
cs.style |= WS_CLIPCHILDREN|WS_CLIPSIBLINGS;
return CView::PreCreateWindow(cs);
}
(九)建立 OpenGL 视点:
1:再编辑 Init() 函数,编辑后的 Init() 如下:
void CStudyOpenGLView::Init()
{
PIXELFORMATDESCRIPTOR pfd;
int n;
HGLRC hrc;
m_pDC = new CClientDC(this);
ASSERT(m_pDC != NULL);
if(!bSetupPixelFormat()) return ;
n =::GetPixelFormat(m_pDC->GetSafeHdc());
::DescribePixelFormat(m_pDC->GetSafeHdc(),n,sizeof(pfd),&pfd);
hrc = wglCreateContext(m_pDC->GetSafeHdc());
wglMakeCurrent(m_pDC->GetSafeHdc(),hrc);
GetClientRect(&m_oldRect);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
2:添加 Windows 消息:
用前面的方法增加消息 WM_SIZE 并生成响应函数 OnSize(),编辑如下:
void CStudyOpenGLView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
if(cy > 0)
{
if((m_oldRect.right > cx) || (m_oldRect.bottom > cy))
{
RedrawWindow();
}
m_oldRect.right = cx;
m_oldRect.bottom = cy;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0,1.0,-1.0,1.0,0.0,7.0);
glViewport(0,0,cx,cy);
}
}
该函数用于当窗口尺寸大小改变时重新绘制
3:建立用户绘制函数 DrawScene():
增加保护成员函数 DrawScene(),该函数具体绘制 OpenGL 图形。
编辑 OnDraw() 函数如下:
void CStudyOpenGLView::OnDraw(CDC* pDC)
{
CStudyOpenGLDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
DrawScene();
}
到这里则所有工作都已经做完,只需要在 DrawScene() 函数里调用绘制图形的各种函数绘制图形即可,例如:
void CStudyOpenGLView::DrawScene()
{
// 设置背景颜色
glClearColor(0.0f , 0.0f , 0.0f , 1.0f);
// 清除颜色缓存和深度缓存
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
// 设置绘制物理的颜色,前景颜色
glColor3f(1.0f,0.0f,0.0f);
GLfloat fPointSize[2];
// 得到点的可表现的象素范围大小
glGetFloatv(GL_POINT_SIZE_RANGE , fPointSize);
// 设置点的象素尺寸
glPointSize(fPointSize[1]/2.0f);
// 绘制 5 个点
glBegin(GL_POINTS);
glVertex2f(0.0f,0.0f);
glVertex2f(0.5f , 0.5f);
glVertex2f(-0.5f , 0.5f);
glVertex2f(0.5f , -0.5f);
glVertex2f(-0.5f , -0.5f);
glEnd();
glFinish();
}
最后运行程序即可以看到效果图形,五个特别大的点。。。
需要注意下的是 最后的 glFinish() 函数,目前理解好象是输出缓冲图形,不加有时看不到该看到的效果,类似于一些语言里的 flush() 函数吧
分享到:
相关推荐
通常JavaWeb项目启动时我们需要做一些初始化工作,比如配置缓存、定时任务等等。举个例子:我在国内某公司曾经负责维护公司内部的全球通信系统的服务端,公司员工在10W人以上,需要初始化的内容就是将这10W多的用户...
TFT初始化是设置这些控制器的过程,通过向其内部的寄存器写入特定值来配置屏幕的工作状态。这个过程包括但不限于以下步骤: 1. **电源管理**:设置电源电压序列,以确保屏幕能正常启动并稳定工作。这包括VDD(主...
PCI设备BAR空间的初始化对于确保PCI设备能够在系统中正常工作至关重要。通过对BAR寄存器和其他相关寄存器的正确初始化,可以实现PCI设备与系统其他组件之间的有效通信。此外,理解存储器地址与PCI总线地址之间的转换...
在使用8251进行通信前,必须对其进行初始化,设置其工作模式和参数。 初始化过程主要涉及以下几个方面: 1. **配置控制寄存器**:8251有两个控制寄存器,即命令寄存器(Command Register, CR)和状态寄存器...
通过查看和分析这个文件的源代码,我们可以更深入地理解这两种初始化块的工作原理和应用场景。 总之,理解并有效地使用静态和对象初始化块是Java开发中的关键技能,它们可以帮助我们更好地控制类和对象的初始化过程...
载体初始化是为了确保打印机能够正常工作并维持打印质量的重要步骤之一。本文将详细介绍柯尼卡美能达7828打印机载体初始化的具体步骤和注意事项,帮助用户顺利完成操作。 #### 二、准备工作 在开始初始化操作之前...
1. 设置处理器状态:初始化文件首先会设置ARM处理器的工作模式,如复位模式、Thumb模式或ARM模式,以及相应的寄存器初始值。 2. 初始化内存系统:包括设置内存控制器参数,确保内存可以正常工作。 3. 配置中断控制器...
5. **响应式设计基础设置**:对于移动优先的设计策略,可以初始化一些媒体查询,如`@media screen and (max-width:XXXpx){...}`,以便在不同屏幕尺寸下应用不同样式。 6. **重置浏览器特定样式**:某些浏览器有特定...
这意味着,即使`InitCommonControls`函数本身不执行任何操作,但它会导致链接器将程序与comctl32.dll关联,从而在运行时自动完成必要的初始化工作。 相比之下,`InitCommonControlsEx`函数允许更精细的控制,因为它...
在本文中,我们将对 LPC2366 串口初始化代码进行分析,主要包括波特率计算、管脚配置、工作模式选择、中断寄存器配置等内容。 一、管脚配置 在串口初始化过程中,首先需要配置管脚。这里使用的微控制器是 LPC2366,...
本文将详细介绍FANUC机器人初始化系统的基本方法和步骤,包括必要的准备工作、具体操作流程及注意事项等内容。 #### 二、准备工作 在进行系统初始化之前,最重要的一步是做好系统的备份工作。备份可以确保在初始化...
DDR初始化流程是确保DDR内存正常运行的关键步骤之一,它涉及对DDR内存的各种设置和配置,以确保其在系统启动时能够正确地与系统其他组件协同工作。本文将深入探讨DDR初始化流程,特别是状态机形式下的标准流程。 ##...
正确的初始化对于保证LCD正常工作至关重要。 ### 单片机控制的LCD初始化程序结构 初始化程序通常包括以下几个关键步骤: 1. **配置LCD指令寄存器**:通过向LCD发送特定的指令码来配置其工作模式。如`0x38`指令...
初始化过程是DLL加载到进程地址空间时进行的一些关键操作,确保DLL可以正确地与调用程序交互。 在易语言中,DLL初始化涉及以下几个知识点: 1. **DLL源码编写**:易语言提供了一套易于理解和使用的语法结构,...
当程序启动时,ADS会自动调用一系列预定义的函数来完成初始化工作,包括内存管理、堆栈设置、中断向量表设置等。 这种初始化方式的优点是简单易用,适合于快速原型设计或简单的应用开发。但是,对于需要深入控制...
5. 故障诊断:在初始化前,工具可能会进行一些基本的硬件和软件检查,以确定问题所在。 在操作过程中,用户应按照工具提供的指南或帮助文档进行,避免误操作导致设备损坏。对于不熟悉这一过程的用户,建议在专业...
初始化工作的成功与否直接关系到后续业务流程的顺畅性以及用户体验。 ### 二、系统初始化完成确认书的作用 #### 1. 客户确认 系统初始化完成确认书是项目实施过程中的一项重要文档,它标志着系统初始化阶段的工作...
- **初始化头变量hdr**: hdr包含了一些重要的系统初始化参数。 - **准备实模式下C语言环境**: 实现C语言环境的基本设置,如栈和堆的初始化。 - **实模式代码main函数**: - **复制初始化头变量**: 将初始化信息...
- **执行初始化脚本**:运行`4初始基礎數據最終版.txt`中的脚本,导入最后确定的初始数据,这可能包括一些示例用户、角色分配等,以便快速体验和测试系统功能。 在进行数据初始化时,需要注意数据安全和权限控制,...
初始化刀库是确保数控机床正常工作的关键步骤,它涉及到机床的启动准备、刀具的定位以及系统的配置。该初始化方法使用特定的M代码来控制整个过程,并与PLC程序编写紧密相关,意味着这些方法可能并不适用于所有数控...