1、作业名称:利用OpenGL实现有色立体茶壶旋转图形学 院:航海学院班 级:03021301学 号:2013300749姓 名:刘德柱团队组成:刘德柱主要负责茶壶形态构建函数模块、潘峰主要负责旋转实现函数,调试、完善、报告等共同完成。西北工业大学2024年7月23日请填写以下十项内容,将表格按页对齐(插入空行),勿删除任何部分。1、问题与背景(描述程序所要解决的问题或应用背景)图片,指的就是平面图片,二维图片。它所记录的,就是当前平面的内容。至于其它面有什么它是不会记录的,也是无法记录的。如你在拍一个人的正面图像,它的侧面或背后有什么,你知道?还是相机知道?是红的?黑的?没人知道!现在你让这张图
2、片进行立体旋转,旋转到人的背后之后,能看到什么?如果你要旋转,则就不能普通的平面图片,而应该是三维图像! 这就是c+中opengl的用处了。它可以实现立体旋转,旋转360地看这个物体,并且还能给三维物体添加颜色,更具真实感和视觉效果。2、开发工具(列出所使用的开发工具和第3方开发库)VC+6. 0,MFC,Windows API3、主要功能(详细说明程序的功能)本c+程序利用OpenGL实现旋转图形,可以使示例中有色立体茶壶实现360旋转,使观众全方位立体感知茶壶形态。4、设计内容(详细描述解决问题的原理和方法、算法、数据结构等)OpenGL: 的工作顺序就是一个从定义几何要素到把象素段写入帧
3、缓冲 区的过程。在屏幕上显示图象的主要步骤是以下3 步: 1)构造几何要素(点、线、多边形、图像、位图),创建对象的数学描 述。在三维空间放置对象,选择有利的观察点。 2)计算对象的颜色,这些颜色可能直接定义,或由光照条件及纹理间 接给出。 3)光栅化,把对象的数学描述和颜色信息转换到屏幕的象素。在本程序中。首先使用相关的WINDOWS API创建窗口,其次实现程序的相应功能: 1使用OPENGL相应库函数画出正方体。 2使之旋转起来。 3在窗体中响应鼠标事件,控制正方体的旋转。程序流程如图所示:至此,程序的大体内容以及机构已经构造成型OPENGL的主体绘制工作:首先使用glClear(GL_
4、COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 清除屏幕和深度缓存,然后使用glLoadIdentity();重置当前的模型观察矩阵,确定绘制好图形的位置glTranslatef(0.0f,0.0f,z); 移入屏幕 z 个单位。函数glTranslatef(x, y, z)作用为沿着 X, Y 和 Z 轴移动; 现在是本程序中最重要的语句:glRotatef(angle,0.0f,0.0f,0.0f),其中angle为每次旋转的角度,之后分别是XYZ三个轴的旋转分量,这三个旋转分量构成了三维坐标轴中的旋转法向量。绘制:void COPENGLActView:
5、OnDraw(CDC* pDC)COPENGLActDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);static GLfloat xangle = 10.0f;glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glPushMatrix ();glTranslatef(0.0f, 0.0f, -8.5);glRotatef(xangle, 1.0f, 0.0f, 0.0f);xangle+= 10.0f;auxSolidTeapot(1.5);glPopMatrix ();glFlush();if(FA
6、LSE=:SwapBuffers(m_pContextDC-GetSafeHdc()AfxMessageBox();重置模型观察矩阵 :glMatrixMode(GL_PROJECTION); / 选择投影矩阵 glLoadIdentity(); / 重置投影矩阵 / 设置视口的大小 gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); glMatrixMode(GL_MODELVIEW); / 选择模型观察矩阵 glLoadIdentity(); / 重置模型观察矩阵视图框的输出:BOOL COPENGLActVi
7、ew:OnPreparePrinting(CPrintInfo* pInfo) / 默认的准备return DoPreparePrinting(pInfo);void COPENGLActView:OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)/ TODO: 添加额外的初始化之前打印void COPENGLActView:OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)/ TODO: 添加打印后进行清理void COPENGLActView:OnTimer(UINT nIDEvent)
8、/ TODO: 在这里添加消息处理程序代码和/或调用默认旋转的定时操作和动画效果处理:this-OnDraw(this-GetDC();CView:OnTimer(nIDEvent);void COPENGLActView:OnAct()SetTimer(1,15,NULL);显示场景的设置:Void RenderSene(void) static float angle = 0.0;glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glPushMatrix ();glTranslatef(0.0f, 0.0f, -8.5);glRotate
9、f(xangle, 1.0f, 0.0f, 0.0f);xangle+= 10.0f;auxSolidTeapot(1.5);glPopMatrix ();glFlush();通过以上步骤,实现图形呈现,再通过旋转函数实现立体模型茶壶的旋转。5、程序文件与工程名称(标出程序中所有文件名、工程名称及其说明)OPENGLAct.dsw VC6工作区文件OPENGLAct.dsp VC6工程文件OPENGLAct.cpp 主程序OPENGLAct.h 主程序头文件MainFrm.cpp 框架类的实现文件OPENGLActDoc.cpp 文档OPENGLActView.cpp 视图框应用程序OPENG
10、LActView.h 视图框应用程序头文件StdAfx.cpp VC6预处理文件StdAfx.h VC6预处理头文件OPENGLAct.rc 资源文件resource.h 资源定义头文件res 图标存放文件夹OPENGLAct.ico 应用程序图标6、函数模块(程序中各个函数的原型声明及其说明)class COPENGLActApp : public CWinApp 应用程序类class COPENGLActDlg : public CDialog 应用程序对话框void COPENGLActView:OnDraw(CDC* pDC);立体模型绘制函数BOOL COPENGLActView:P
11、reCreateWindow(CREATESTRUCT& cs) ;窗口类或者样式的修改BOOL COPENGLActView:OnPreparePrinting(CPrintInfo* pInfo) ;函数的输出,实现立体茶壶的呈现void COPENGLActView:OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) ;打印之前的初始化void COPENGLActView:OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)打印之后的清理操作void COPENGLActView:On
12、Size(UINT nType, int cx, int cy) 尺寸控制void COPENGLActView:OnTimer(UINT nIDEvent)定时器void COPENGLActView:OnAct() 动画7、使用说明(运行程序的小型说明书)运行程序OPENGLAct.cpp后,进行调试,茶壶界面自动打开。此时有色茶壶呈静态。点击“查看”-“开始动画”后,茶壶自动翻转旋转,可全方位感知茶壶形态。8、程序开发总结(简要叙述编写本作业的收获与思考)收获:通过此次程序设计实验,我对OpenGL图形函数有了初步的了解,并且能够根据书本上的现有函数整合、编写出简单的图形处理函数。总结:
13、C+语言作用范围广,如果能够熟练掌握并且能够灵活运用,将会在工程运用方面起到很大的作用。例如本题中,通过VC+6.0实现了立体茶壶模型的旋转,这个可以用于茶壶生产制造前的产品预览。的功能十分强大,需要我们学习的地方还有很多。9、运行截图(附上程序运行的截图画面,至少有1幅,截图越翔实得分越高)Windows中抓取当前活动窗口:Alt + Print Screen,抓取全屏:Print Screen。或者使用HyperSnap等软件(百度搜索)。10、源程序(附上程序源代码,若是多个文件,标出文件名)/ 1.应用程序主窗框的源代码/ MainFrm.cpp : CMainFrame框架类的实现#
14、include stdafx.h#include OPENGLAct.h#include MainFrm.h#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE = _FILE_;#endif/ CMainFrameIMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)/AFX_MSG_MAP(CMainFrame)/ 注意,ClassWizard将添加和删除映射宏。/ 不编辑你所看到的这些生成的
15、代码块!ON_WM_CREATE()/AFX_MSG_MAPEND_MESSAGE_MAP()static UINT indicators =ID_SEPARATOR, / 状态行指标ID_INDICATOR_CAPS,ID_INDICATOR_NUM,ID_INDICATOR_SCRL,;/ CMainFrame建设/破坏CMainFrame:CMainFrame()/ 待办事项:添加成员初始化代码CMainFrame:CMainFrame()int CMainFrame:OnCreate(LPCREATESTRUCT lpCreateStruct)if (CFrameWnd:OnCreat
16、e(lpCreateStruct) = -1)return -1;if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) |!m_wndToolBar.LoadToolBar(IDR_MAINFRAME)TRACE0(Failed to create toolbarn);return -1; / 无法创建if (!m_wndStatusBar.Create(this
17、) |!m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT)TRACE0(Failed to create status barn);return -1; / 无法创建/ 待办事项:删除这三行如果你不想工具栏/ be dockablem_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);EnableDocking(CBRS_ALIGN_ANY);DockControlBar(&m_wndToolBar);return 0;BOOL CMainFrame:PreCreate
18、Window(CREATESTRUCT& cs)if( !CFrameWnd:PreCreateWindow(cs) )return FALSE;/ 待办事项:修改窗口类或样式来修改/ the CREATESTRUCT csreturn TRUE;/ CMainFrame诊断#ifdef _DEBUGvoid CMainFrame:AssertValid() constCFrameWnd:AssertValid();void CMainFrame:Dump(CDumpContext& dc) constCFrameWnd:Dump(dc);#endif /_DEBUG/ CMainFrame消
19、息处理程序/ 2. 主程序源代码/ OPENGLAct.cpp : 为应用程序定义了类的行为。/#include stdafx.h#include OPENGLAct.h#include MainFrm.h#include OPENGLActDoc.h#include OPENGLActView.h#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE = _FILE_;#endif/ COPENGLActAppBEGIN_MESSAGE_MAP(COPENGLActApp, CWinApp)/AFX_MS
20、G_MAP(COPENGLActApp)ON_MAND(ID_APP_ABOUT, OnAppAbout)/ 注意,ClassWizard将添加和删除映射宏。/ 不编辑你所看到的这些生成的代码块/AFX_MSG_MAP/ 基于标准的文件文档的命令ON_MAND(ID_FILE_NEW, CWinApp:OnFileNew)ON_MAND(ID_FILE_OPEN, CWinApp:OnFileOpen)/ 标准的打印设置命令ON_MAND(ID_FILE_PRINT_SETUP, CWinApp:OnFilePrintSetup)END_MESSAGE_MAP()/ COPENGLActApp
21、 constructionCOPENGLActApp:COPENGLActApp()/ 待办事项:建设代码添加在这里/ 把所有InitInstance的重要初始化/ 唯一的COPENGLActApp对象COPENGLActApp theApp;/ COPENGLActApp initializationBOOL COPENGLActApp:InitInstance()AfxEnableControlContainer();/ 标准的初始化/ 如果你不使用这些功能,希望减少规模/ 你的最终的可执行文件,你应该从以下删除/ 你不需要特定的初始化例程。#ifdef _AFXDLLEnable3dCo
22、ntrols();/ 称之为当使用MFC DLL共享#elseEnable3dControlsStatic();/ 当链接到MFC静态调用这个#endif/ 改变我们的注册表键设置存储。/ 待办事项:你应该修改这个字符串是合适的/ 如您的公司或组织的名称.SetRegistryKey(_T(Local AppWizard-Generated Applications);LoadStdProfileSettings(); / 加载标准INI文件选项(包括系统)/ 注册应用程序的文档模板。文档模板/ 作为文件之间的连接,框架窗口和视图。CSingleDocTemplate* pDocTemplat
23、e;pDocTemplate = new CSingleDocTemplate(IDR_MAINFRAME,RUNTIME_CLASS(COPENGLActDoc),RUNTIME_CLASS(CMainFrame), / 主要SDI框架窗口RUNTIME_CLASS(COPENGLActView);AddDocTemplate(pDocTemplate);/ 解析命令行标准shell命令,DDE,文件打开CmandLineInfo cmdInfo;ParsemandLine(cmdInfo);/ 调度命令在命令行上指定if (!ProcessShellmand(cmdInfo)return
24、FALSE;/ 唯一的窗口已经初始化,所以显示和更新m_pMainWnd-ShowWindow(SW_SHOW);m_pMainWnd-UpdateWindow();m_pMainWnd-SetWindowText(OpenGL);return TRUE;/ CAboutDlg对话框用于应用程序class CAboutDlg : public CDialogpublic:CAboutDlg();/ 对话框数据/AFX_DATA(CAboutDlg)enum IDD = IDD_ABOUTBOX ;/AFX_DATA/ ClassWizard生成的虚函数覆盖/AFX_VIRTUAL(CAbout
25、Dlg)protected:virtual void DoDataExchange(CDataExchange* pDX); / DDX/DDV support/AFX_VIRTUAL/ 实现protected:/AFX_MSG(CAboutDlg)/ 没有消息处理程序/AFX_MSGDECLARE_MESSAGE_MAP();CAboutDlg:CAboutDlg() : CDialog(CAboutDlg:IDD)/AFX_DATA_INIT(CAboutDlg)/AFX_DATA_INITvoid CAboutDlg:DoDataExchange(CDataExchange* pDX)C
26、Dialog:DoDataExchange(pDX);/AFX_DATA_MAP(CAboutDlg)/AFX_DATA_MAPBEGIN_MESSAGE_MAP(CAboutDlg, CDialog)/AFX_MSG_MAP(CAboutDlg)/ No message handlers/AFX_MSG_MAPEND_MESSAGE_MAP()/ 应用程序命令运行对话框void COPENGLActApp:OnAppAbout()CAboutDlg aboutDlg;aboutDlg.DoModal();/ COPENGLActApp消息处理程序/ 3. 文档框源代码/ OPENGLActD
27、oc.cpp : OPENGLActDoc类的实现#include stdafx.h#include OPENGLAct.h#include OPENGLActDoc.h#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE = _FILE_;#endif/ COPENGLActDocIMPLEMENT_DYNCREATE(COPENGLActDoc, CDocument)BEGIN_MESSAGE_MAP(COPENGLActDoc, CDocument)/AFX_MSG_MAP(COPENGLActDo
28、c)/ 注意,ClassWizard将添加和删除映射宏。/ 不编辑在这些你看到的生成的代码块/AFX_MSG_MAPEND_MESSAGE_MAP()/ COPENGLActDoc 创建/破坏COPENGLActDoc:COPENGLActDoc()/ TODO: 添加一次性建设代码在这里COPENGLActDoc:COPENGLActDoc()BOOL COPENGLActDoc:OnNewDocument()if (!CDocument:OnNewDocument()return FALSE;/ TODO: 仅代码添加在这里/ (SDI文档可以重用该文档)return TRUE;/ COP
29、ENGLActDoc 序列化void COPENGLActDoc:Serialize(CArchive& ar)if (ar.IsStoring()/ TODO: 在这里添加存储代码else/ TODO: 加载代码添加在这里/ COPENGLActDoc 诊断#ifdef _DEBUGvoid COPENGLActDoc:AssertValid() constCDocument:AssertValid();void COPENGLActDoc:Dump(CDumpContext& dc) constCDocument:Dump(dc);#endif /_DEBUG/ COPENGLActDoc
30、 命令/ 4. 视图框源代码/ OPENGLActView.cpp : COPENGLActView类的实现#include stdafx.h#include OPENGLAct.h#include OPENGLActDoc.h#include OPENGLActView.h#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE = _FILE_;#endifGLfloat sgenparams = 1.0, 1.0, 1.0, 0.0;GLubyte stripeImage3*64;/ COPENGLAc
31、tViewIMPLEMENT_DYNCREATE(COPENGLActView, CView)BEGIN_MESSAGE_MAP(COPENGLActView, CView)/AFX_MSG_MAP(COPENGLActView)ON_WM_CREATE()ON_WM_SIZE()ON_WM_TIMER()ON_MAND(ID_ACT, OnAct)/AFX_MSG_MAP/标准的打印命令ON_MAND(ID_FILE_PRINT, CView:OnFilePrint)ON_MAND(ID_FILE_PRINT_DIRECT, CView:OnFilePrint)ON_MAND(ID_FILE
32、_PRINT_PREVIEW, CView:OnFilePrintPreview)END_MESSAGE_MAP()/ COPENGLActView construction/destructionCOPENGLActView:COPENGLActView()/ TODO: 施工的代码在这里COPENGLActView:COPENGLActView()BOOL COPENGLActView:PreCreateWindow(CREATESTRUCT& cs)/ TODO: 在这里通过修改修改窗口类或样式/ the CREATESTRUCT cscs.style |= WS_CLIPSIBLING
33、S | WS_CLIPCHILDREN;return CView:PreCreateWindow(cs);/ COPENGLActView 绘制void COPENGLActView:OnDraw(CDC* pDC)COPENGLActDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);static GLfloat xangle = 10.0f;glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glPushMatrix ();glTranslatef(0.0f, 0.0f, -8.5);glRotatef
34、(xangle, 1.0f, 0.0f, 0.0f);xangle+= 10.0f;auxSolidTeapot(1.5);glPopMatrix ();glFlush();if(FALSE=:SwapBuffers(m_pContextDC-GetSafeHdc()AfxMessageBox();/ COPENGLActView 输出BOOL COPENGLActView:OnPreparePrinting(CPrintInfo* pInfo)/ 默认的准备return DoPreparePrinting(pInfo);void COPENGLActView:OnBeginPrinting(
35、CDC* /*pDC*/, CPrintInfo* /*pInfo*/)/ TODO: 添加额外的初始化之前打印void COPENGLActView:OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)/ TODO: 添加打印后进行清理/ COPENGLActView 诊断#ifdef _DEBUGvoid COPENGLActView:AssertValid() constCView:AssertValid();void COPENGLActView:Dump(CDumpContext& dc) constCView:Dump(dc);COP
36、ENGLActDoc* COPENGLActView:GetDocument() / 调试版本是内联ASSERT(m_pDocument-IsKindOf(RUNTIME_CLASS(COPENGLActDoc);return (COPENGLActDoc*)m_pDocument;#endif /_DEBUG/ COPENGLActView 消息处理程序int COPENGLActView:OnCreate(LPCREATESTRUCT lpCreateStruct)if (CView:OnCreate(lpCreateStruct) = -1)return -1;m_pContextDC=new CClientDC(this);ASSERT(m_pContextDC);static PIXELFORMATDESCRIPTOR pfd = sizeof(PIXELFORMATDESCRIPTOR), / 1, / PFD_DRAW_TO_WINDOW | / PFD_SUPPORT_OPENGL | / PFD_DOUBLEBUFFER, / PFD_TYPE_RGBA, / 24, / 0, 0, 0, 0, 0, 0, / 0, / 0, / 0, / 0,