MyTerrain1View.cpp
上传用户:sz25923981
上传日期:2022-06-28
资源大小:3615k
文件大小:10k
源码类别:

OpenGL

开发平台:

Visual C++

  1. // MyTerrain1View.cpp : implementation of the CMyTerrain1View class
  2. //
  3. #include "stdafx.h"
  4. #include "MyTerrain1.h"
  5. #include "MyTerrain1Doc.h"
  6. #include "MyTerrain1View.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12. /////////////////////////////////////////////////////////////////////////////
  13. // CMyTerrain1View
  14. IMPLEMENT_DYNCREATE(CMyTerrain1View, CView)
  15. BEGIN_MESSAGE_MAP(CMyTerrain1View, CView)
  16. //{{AFX_MSG_MAP(CMyTerrain1View)
  17. ON_WM_CREATE()
  18. ON_WM_DESTROY()
  19. ON_WM_SIZE()
  20. ON_WM_TIMER()
  21. ON_WM_KEYDOWN()
  22. //}}AFX_MSG_MAP
  23. // Standard printing commands
  24. ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
  25. ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
  26. ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
  27. END_MESSAGE_MAP()
  28. /////////////////////////////////////////////////////////////////////////////
  29. // CMyTerrain1View construction/destruction
  30. CMyTerrain1View::CMyTerrain1View()
  31. {
  32. // TODO: add construction code here
  33. }
  34. CMyTerrain1View::~CMyTerrain1View()
  35. {
  36. }
  37. BOOL CMyTerrain1View::PreCreateWindow(CREATESTRUCT& cs)
  38. {
  39. // TODO: Modify the Window class or styles here by modifying
  40. //  the CREATESTRUCT cs
  41. ////////////////////////////////////////////////////////////////
  42. //设置窗口类型
  43. cs.style |=WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
  44. ////////////////////////////////////////////////////////////////
  45. return CView::PreCreateWindow(cs);
  46. }
  47. /////////////////////////////////////////////////////////////////////////////
  48. // CMyTerrain1View drawing
  49. void CMyTerrain1View::OnDraw(CDC* pDC)
  50. {
  51. CMyTerrain1Doc* pDoc = GetDocument();
  52. ASSERT_VALID(pDoc);
  53. // TODO: add draw code for native data here
  54. //////////////////////////////////////////////////////////////////
  55. RenderScene(); //渲染场景
  56. //////////////////////////////////////////////////////////////////
  57. }
  58. /////////////////////////////////////////////////////////////////////////////
  59. // CMyTerrain1View printing
  60. BOOL CMyTerrain1View::OnPreparePrinting(CPrintInfo* pInfo)
  61. {
  62. // default preparation
  63. return DoPreparePrinting(pInfo);
  64. }
  65. void CMyTerrain1View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  66. {
  67. // TODO: add extra initialization before printing
  68. }
  69. void CMyTerrain1View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  70. {
  71. // TODO: add cleanup after printing
  72. }
  73. /////////////////////////////////////////////////////////////////////////////
  74. // CMyTerrain1View diagnostics
  75. #ifdef _DEBUG
  76. void CMyTerrain1View::AssertValid() const
  77. {
  78. CView::AssertValid();
  79. }
  80. void CMyTerrain1View::Dump(CDumpContext& dc) const
  81. {
  82. CView::Dump(dc);
  83. }
  84. CMyTerrain1Doc* CMyTerrain1View::GetDocument() // non-debug version is inline
  85. {
  86. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyTerrain1Doc)));
  87. return (CMyTerrain1Doc*)m_pDocument;
  88. }
  89. #endif //_DEBUG
  90. /////////////////////////////////////////////////////////////////////////////
  91. // CMyTerrain1View message handlers
  92. int CMyTerrain1View::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  93. {
  94. if (CView::OnCreate(lpCreateStruct) == -1)
  95. return -1;
  96. // TODO: Add your specialized creation code here
  97. //////////////////////////////////////////////////////////////////
  98. //初始化OpenGL和设置定时器
  99. m_pDC = new CClientDC(this);
  100. SetTimer(1, 20, NULL);
  101. InitializeOpenGL(m_pDC);
  102. //////////////////////////////////////////////////////////////////
  103. Init();
  104. return 0;
  105. }
  106. void CMyTerrain1View::OnDestroy() 
  107. {
  108. CView::OnDestroy();
  109. // TODO: Add your message handler code here
  110. /////////////////////////////////////////////////////////////////
  111. //删除调色板和渲染上下文、定时器
  112. ::wglMakeCurrent(0,0);
  113. ::wglDeleteContext( m_hRC);
  114. if (m_hPalette)
  115.     DeleteObject(m_hPalette);
  116. if ( m_pDC )
  117. {
  118. delete m_pDC;
  119. }
  120. KillTimer(1);
  121. /////////////////////////////////////////////////////////////////
  122. }
  123. void CMyTerrain1View::OnSize(UINT nType, int cx, int cy) 
  124. {
  125. CView::OnSize(nType, cx, cy);
  126. // TODO: Add your message handler code here
  127. /////////////////////////////////////////////////////////////////
  128. //添加窗口缩放时的图形变换函数
  129. glViewport(0,0,cx,cy);
  130. /////////////////////////////////////////////////////////////////
  131. glMatrixMode(GL_PROJECTION);
  132. glLoadIdentity();
  133. glFrustum(-10, 10, -10, 10, 10, 500);
  134. glMatrixMode(GL_MODELVIEW);
  135. }
  136. void CMyTerrain1View::OnTimer(UINT nIDEvent) 
  137. {
  138. // TODO: Add your message handler code here and/or call default
  139. /////////////////////////////////////////////////////////////////
  140. //添加定时器响应函数和场景更新函数
  141. Invalidate(FALSE);
  142. /////////////////////////////////////////////////////////////////
  143. CView::OnTimer(nIDEvent);
  144. }
  145. /////////////////////////////////////////////////////////////////////
  146. //                   设置逻辑调色板
  147. //////////////////////////////////////////////////////////////////////
  148. void CMyTerrain1View::SetLogicalPalette(void)
  149. {
  150.     struct
  151.     {
  152.         WORD Version;
  153.         WORD NumberOfEntries;
  154.         PALETTEENTRY aEntries[256];
  155.     } logicalPalette = { 0x300, 256 };
  156. BYTE reds[] = {0, 36, 72, 109, 145, 182, 218, 255};
  157. BYTE greens[] = {0, 36, 72, 109, 145, 182, 218, 255};
  158. BYTE blues[] = {0, 85, 170, 255};
  159.     for (int colorNum=0; colorNum<256; ++colorNum)
  160.     {
  161.         logicalPalette.aEntries[colorNum].peRed =
  162.             reds[colorNum & 0x07];
  163.         logicalPalette.aEntries[colorNum].peGreen =
  164.             greens[(colorNum >> 0x03) & 0x07];
  165.         logicalPalette.aEntries[colorNum].peBlue =
  166.             blues[(colorNum >> 0x06) & 0x03];
  167.         logicalPalette.aEntries[colorNum].peFlags = 0;
  168.     }
  169.     m_hPalette = CreatePalette ((LOGPALETTE*)&logicalPalette);
  170. }
  171. //////////////////////////////////////////////////////////
  172. // 初始化openGL场景
  173. //////////////////////////////////////////////////////////
  174. BOOL CMyTerrain1View::InitializeOpenGL(CDC* pDC)
  175. {
  176. m_pDC = pDC;
  177. SetupPixelFormat();
  178. //生成绘制描述表
  179. m_hRC = ::wglCreateContext(m_pDC->GetSafeHdc());
  180. //置当前绘制描述表
  181. ::wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC);
  182. return TRUE;
  183. }
  184. //////////////////////////////////////////////////////////
  185. // 设置像素格式
  186. //////////////////////////////////////////////////////////
  187. BOOL CMyTerrain1View::SetupPixelFormat()
  188. {
  189. PIXELFORMATDESCRIPTOR pfd = { 
  190.     sizeof(PIXELFORMATDESCRIPTOR),    // pfd结构的大小 
  191.     1,                                // 版本号 
  192.     PFD_DRAW_TO_WINDOW |              // 支持在窗口中绘图 
  193.     PFD_SUPPORT_OPENGL |              // 支持 OpenGL 
  194.     PFD_DOUBLEBUFFER,                 // 双缓存模式 
  195.     PFD_TYPE_RGBA,                    // RGBA 颜色模式 
  196.     24,                               // 24 位颜色深度 
  197.     0, 0, 0, 0, 0, 0,                 // 忽略颜色位 
  198.     0,                                // 没有非透明度缓存 
  199.     0,                                // 忽略移位位 
  200.     0,                                // 无累加缓存 
  201.     0, 0, 0, 0,                       // 忽略累加位 
  202.     32,                               // 32 位深度缓存     
  203.     0,                                // 无模板缓存 
  204.     0,                                // 无辅助缓存 
  205.     PFD_MAIN_PLANE,                   // 主层 
  206.     0,                                // 保留 
  207.     0, 0, 0                           // 忽略层,可见性和损毁掩模 
  208. }; 
  209. int pixelformat;
  210. pixelformat = ::ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd);//选择像素格式
  211. ::SetPixelFormat(m_pDC->GetSafeHdc(), pixelformat, &pfd); //设置像素格式
  212. if(pfd.dwFlags & PFD_NEED_PALETTE)
  213. SetLogicalPalette(); //设置逻辑调色板
  214. return TRUE;
  215. }
  216. //////////////////////////////////////////////////////////
  217. // 场景绘制与渲染
  218. //////////////////////////////////////////////////////////
  219. BOOL CMyTerrain1View::RenderScene() 
  220. {
  221. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  222.   
  223. glLoadIdentity();
  224. gluLookAt(100, 100, 100, 0, 0, 0, 0, 1, 0);
  225. glRotatef((float)angle, 0, 1, 0);
  226. glRotatef(90, 1, 0, 0);
  227. glTranslatef(-200, -200, 0);
  228. if (!stop) angle += 1;
  229. if (angle > 359) angle = 0;
  230. g.Draw(); // 绘制地形
  231. glFlush();  
  232. ::SwapBuffers(m_pDC->GetSafeHdc()); //交互缓冲区
  233. return TRUE;
  234. }
  235. void CMyTerrain1View::Init(void)
  236. {
  237. int angle=0;
  238. int stop=0;
  239. GLfloat light_ambient[] = {0.0, 0.0, 0.0, 1.0};
  240. GLfloat light_diffuse[] = {1.0, 1.0, 1.0, 1.0};
  241. GLfloat light_specular[] = {1.0, 1.0, 1.0, 1.0};
  242. GLfloat light_position[] = {0.0, -100.0, -100.0, 0.0};
  243. glClearColor(0, 0, 0, 0);
  244. glColor3f(1, 1, 1);
  245. g.SetCellLength(40); // 网格之间的长度
  246. g.SetHeight(0, 40); // 地形高程的最小和最大值
  247. g.GenerateNewGrid(); // 生成新的地形
  248. g.SetInterpolationLevel(6); // 曲线插值阶数
  249. g.Compile();
  250. glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
  251. glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
  252. glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
  253. glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
  254. glLightfv(GL_LIGHT0, GL_POSITION, light_position);
  255. glEnable(GL_LIGHT0);
  256. glDepthFunc(GL_LESS);
  257. glEnable(GL_DEPTH_TEST);
  258. glEnable(GL_LIGHTING); // 使用光照
  259. glEnable(GL_NORMALIZE);
  260. glShadeModel(GL_FLAT);
  261. glCullFace(GL_FRONT);
  262. glEnable(GL_CULL_FACE);
  263. glGenTextures(1, texture);
  264. LoadTexture("tr.rgb", 0);
  265. glEnable(GL_TEXTURE_2D);
  266. glBindTexture(GL_TEXTURE_2D, texture[0]);
  267. }
  268. /////////////////////////////////////////////////////////////////////////////////
  269. //装入纹理
  270. void CMyTerrain1View::LoadTexture(char *fn, int t_num)
  271. {
  272. int texwid, texht;
  273. int texcomps;
  274.  
  275. teximage = m_Tex->read_texture(fn, &texwid, &texht, &texcomps);
  276. if (!teximage)
  277. {
  278. MessageBox("没有找到图形文件tr.rgb","错误",MB_ICONQUESTION);
  279. exit(0);
  280. }
  281. glBindTexture(GL_TEXTURE_2D, texture[t_num]);
  282. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  283. glTexImage2D(GL_TEXTURE_2D, 0, 3, texwid, texht, 0, GL_RGBA, GL_UNSIGNED_BYTE, teximage);
  284. gluBuild2DMipmaps(GL_TEXTURE_2D, 3, texwid, texht, GL_RGBA, GL_UNSIGNED_BYTE, teximage);
  285. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 
  286. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR); 
  287. free(teximage);
  288. void CMyTerrain1View::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
  289. {
  290. // TODO: Add your message handler code here and/or call default
  291. switch (nChar)
  292. {
  293.     case VK_F12: g.GenerateNewGrid(); g.Compile(); // 生成新的地形
  294. break;
  295.     case VK_SPACE: stop = !stop; // 停止动画
  296. break;
  297.     case VK_ESCAPE: exit(0); //退出程序
  298. break;
  299. }
  300. CView::OnKeyDown(nChar, nRepCnt, nFlags);
  301. }