main.cpp
上传用户:jinmajixie
上传日期:2022-07-12
资源大小:435k
文件大小:12k
源码类别:

OpenGL

开发平台:

Visual C++

  1. #include "main.h"
  2. CInputManager input;
  3. CVector cursor(50, 0, 50);
  4. CCamera cam;
  5. CVector cam_rot(0, -36, 0);
  6. CVector cam_pos(-58, 100, 58);
  7. CVector cam_lookat(20, 0, 20);
  8. // Function prototypes...
  9. bool InitializeGL();
  10. void RenderScene();
  11. void GetInput();
  12. void Shutdown();
  13. // Width and height of the screen.
  14. #define ScreenWidth 1024
  15. #define ScreenHeight 768
  16. // Device context.
  17. HDC g_HDC;
  18. float spd = 0.1f;
  19. CTerrain terrain;
  20. CTerrainData tdata;
  21. CTerrainEdit tedit;
  22. void SetupPixelFormat(HDC hDC)
  23. {
  24. int nPixelFormat;
  25. static PIXELFORMATDESCRIPTOR pfd = {
  26. sizeof(PIXELFORMATDESCRIPTOR), // size of structure.
  27. 1,  // always 1.
  28. PFD_DRAW_TO_WINDOW |  // support window
  29. PFD_SUPPORT_OPENGL |  // support OpenGl
  30. PFD_DOUBLEBUFFER,  // support double buffering
  31. PFD_TYPE_RGBA,  // support RGBA
  32. 16, // bit color mode
  33. 0, 0, 0, 0, 0, 0,  // ignore color bits
  34. 0,  // no alpha buffer
  35. 0,  // ignore shift bit
  36. 0,  // no accumulation buffer
  37. 0, 0, 0, 0,  // ignore accumulation bits.
  38. 16, // number of depth buffer bits.
  39. 0,  // number of stencil buffer bits.
  40. 0,  // 0 means no auxiliary buffer
  41. PFD_MAIN_PLANE, // The main drawing plane
  42. 0,  // this is reserved
  43. 0, 0, 0 };   // layer masks ignored.
  44. // This chooses the best pixel format and returns index.
  45. nPixelFormat = ChoosePixelFormat(hDC, &pfd);
  46. // This set pixel format to device context.
  47. SetPixelFormat(hDC, nPixelFormat, &pfd);
  48. }
  49. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  50. {
  51. static HGLRC hRC;  // Rendering context.
  52. static HDC hDC; // Device context.
  53. int width, height; // The window width and height.
  54. switch(message)
  55. {
  56. case WM_CREATE: // Windows creation.
  57. hDC = GetDC(hwnd); // This gets the device context for our window.
  58. g_HDC = hDC; // Assigns the global device context to this one.
  59. SetupPixelFormat(hDC);   // Call the pixel format function.
  60. hRC = wglCreateContext(hDC);   // Creates the rendering context.
  61. wglMakeCurrent(hDC, hRC);   // Makes the rendering context.
  62. return 0;
  63. break;
  64. case WM_CLOSE:  // Close message.
  65. case WM_DESTROY:
  66. wglMakeCurrent(hDC, NULL);
  67. wglDeleteContext(hRC);   // Deletes the rendering context.
  68. PostQuitMessage(0);   // Says close the program.
  69. return 0;
  70. break;
  71. case WM_SIZE:   // re-size message.
  72. height = HIWORD(lParam); // This gets the height of the window.
  73. width = LOWORD(lParam);  // This gets the width of the window.
  74. if(height==0)   // we don't want it to be possible for a
  75. {   // height of 0.  If it is 0 me make it 1.
  76. height = 1;
  77. }
  78. glViewport(0, 0, width, height); // resets the viewport to new dimensions.
  79. glMatrixMode(GL_PROJECTION);   // Sets the projection matrix.
  80. glLoadIdentity();  // Reset the modelview matrix.
  81. // Calculate the aspect ratio of the window.
  82. gluPerspective(45.0f, (GLfloat)width/(GLfloat)height, 0.1f, 2000.0f);
  83. glMatrixMode(GL_MODELVIEW); // Sets the projection matrix.
  84. glLoadIdentity();  // Reset the modelview matrix.
  85. return 0;
  86. break;
  87. case WM_MOUSEMOVE: input.MouseMove(); break;
  88. case WM_LBUTTONDOWN: input.KeyDown(VK_F15); break;
  89. case WM_LBUTTONUP: input.KeyUp(VK_F15); break;
  90. case WM_RBUTTONDOWN: input.KeyDown(VK_F16); break;
  91. case WM_RBUTTONUP: input.KeyUp(VK_F16); break;
  92. case WM_KEYUP: input.KeyUp(wParam); break;
  93. case WM_KEYDOWN: input.KeyDown(wParam); break;
  94. default:
  95. break;
  96. }
  97. // What this does is pass all of the unhandled messages to DefWindowProc.
  98. return (DefWindowProc(hwnd, message, wParam, lParam));
  99. }
  100. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
  101. {
  102. MSG msg;  // A message variable.
  103. WNDCLASSEX windowClass;  // Your Window class.
  104. HWND hwnd;   // The Window handle.
  105. bool isFinished;   // True then exit.
  106. // This is the Window class.
  107. windowClass.cbSize = sizeof(WNDCLASSEX);   // size of the WNDCLASSEX structure.
  108. windowClass.style = CS_HREDRAW | CS_VREDRAW;  // style of the window.
  109. windowClass.lpfnWndProc = WndProc;   // Address to the windows procedure.
  110. windowClass.cbClsExtra = 0; // Extra class information.
  111. windowClass.cbWndExtra = 0; // Extra window information.
  112. windowClass.hInstance = hInstance;   // Handle of application Instance.
  113. // Handle of application Icon.
  114. windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  115. windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);// mouse cursor
  116. windowClass.hbrBackground = NULL; // background color.
  117. windowClass.lpszMenuName = NULL;  // name of the main menu.
  118. windowClass.lpszClassName = "brm";// window class name.
  119. // icon when minimized.
  120. windowClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
  121. // You must register you class with Windows.
  122. if(!RegisterClassEx(&windowClass)) return 0;
  123. // Create window...
  124. hwnd = CreateWindowEx(0,// The extended window style.
  125. "brm",// window Class name.
  126. "roflmao",// window name.
  127. WS_OVERLAPPEDWINDOW | WS_VISIBLE |// The window style.
  128. WS_SYSMENU | WS_CLIPCHILDREN |// window style.
  129. WS_CLIPSIBLINGS,// window style.
  130. 0, 0,// window x, y coordinate.
  131. ScreenWidth, ScreenHeight,// window width and height.
  132. NULL,// handle to parent window.
  133. NULL,// menu.
  134. hInstance,// handle to app instance.
  135. 0); // pointer to window creation data.
  136. // If there was an error with creating the window, then close the program.
  137. if(!hwnd) return 0;
  138. ShowWindow(hwnd, SW_SHOW); // This shows the window.
  139. UpdateWindow(hwnd);   // This forces a paint message.
  140. isFinished = false;   // False = running, True = not running.
  141. // If initialize fail (return false), then we don't want the program to run.
  142. if(!InitializeGL()) isFinished = true;
  143. cam.AttachCameraRotation(&cam_rot);
  144. cam.AttachCameraPosition(&cam_pos);
  145. input.AttachFloatToMouseX(&cursor.z);
  146. input.AttachFloatToMouseY(&cursor.x);
  147. input.SetMousePointers(cam.position_p, cam.rotation_p, &cam.look_vector);
  148. // This is the messsage loop.
  149. while(!isFinished)
  150. {
  151. if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  152. {
  153. // If a quit message then quit the app.
  154. if(msg.message == WM_QUIT)
  155. {
  156. isFinished = true;
  157. }
  158. TranslateMessage(&msg);
  159. DispatchMessage(&msg);
  160. }
  161. else
  162. {
  163. input.ProcessInput();
  164. GetInput();
  165. RenderScene();
  166. }
  167. }
  168. // Shutdown (free) all resources we used up.
  169. Shutdown();
  170. return (int)msg.wParam;
  171. }
  172. bool InitializeGL()
  173. {
  174. glClearColor(0.6f, 0.6f, 1.0f, 1.0f);
  175. glShadeModel(GL_SMOOTH);
  176. glEnable(GL_DEPTH_TEST);
  177. glEnable(GL_TEXTURE_2D);
  178. glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  179. glFogi(GL_FOG_MODE, GL_LINEAR); // GL_EXP a GL_EXP2 mali rovnake fps
  180. float f[4];
  181. f[0] = 0.7f; f[1] = 0.7f; f[2] = 0.7f; f[3] = 0.7f;
  182. glFogfv(GL_FOG_COLOR, f);
  183. // glFogf(GL_FOG_DENSITY, fog.density); // useless for GL_LINEAR
  184. glHint(GL_FOG_HINT, GL_NICEST); // GL_FASTEST zmenilo zo 180 fps na 179 fps :]
  185. glFogf(GL_FOG_START, 0);
  186. glFogf(GL_FOG_END, 800);
  187. glEnable(GL_FOG);
  188. if (!tdata.Init(&terrain)) return false;
  189. tedit.Init(&terrain);
  190. if (!tdata.Generate("grass.bmp", 32, "lowest.tga", "low.tga", "high.tga", "highest.tga", "detail.tga")) return false;
  191. // if (!tdata.Generate("grass.bmp", 32, "lowest.tga", "low.tga", "high.tga", "highest.tga", "detail.tga")) return false;
  192. return true;
  193. }
  194. void RenderScene()
  195. {
  196. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clears the screen.
  197. glLoadIdentity();  //Reset modelview matrix for new frame.
  198. // Set the camera.
  199. cam.SetglLookAt();
  200. glAccum(GL_RETURN, 0.99f);
  201. tdata.RenderAll();
  202. glAccum(GL_ACCUM, 0.99f);
  203. glAccum(GL_MULT, 0.5f);
  204. DrawBoundingSphere(&cursor, 1);
  205. SwapBuffers(g_HDC);
  206. }
  207. void GetInput()
  208. {
  209. // Checking for input.  We move the camera based on the button(s) that were pressed.
  210. if(GetKeyState('G') & 0x80)
  211. {
  212. tdata.InitTextures();
  213. }
  214. if(GetKeyState('H') & 0x80)
  215. {
  216. int x = (int)(cursor.x*2);
  217. int z = (int)(cursor.z*2);
  218. tedit.MapTextureToPoint(terrain.m_tiles.texTiles[0].image, x, z);
  219. }
  220. // tedit.SetArea((int)cursor.x, (int)cursor.z, 10, cursor.y);
  221. if(GetKeyState('R') & 0x80)
  222. tedit.SetArea((int)cursor.x, (int)cursor.z, 30, cursor.y, 0.05f);
  223. /* if(GetKeyState('F') & 0x80)
  224. */
  225. if (input.keys[VK_F15])
  226. tedit.DoHill((int)cursor.x, (int)cursor.z, 10, 0.05f);
  227. if (input.keys[VK_F16])
  228. tedit.DoHill((int)cursor.x, (int)cursor.z, 10, -0.05f);
  229. if(GetKeyState('I') & 0x80) tedit.GenerateIsland(64, 64, 64, 64, 100, 20, 3);
  230. if(GetKeyState('T') & 0x80) tedit.GenerateTerrain(30, 10, 2);
  231. if(GetKeyState('N') & 0x80) tedit.Normalize(1);
  232. if(GetKeyState('V') & 0x80) tedit.Flatten(1.1f);
  233. if(GetKeyState('M') & 0x80) tedit.Multiply(1.2f);
  234. if(GetKeyState('B') & 0x80) tedit.Multiply(0.8f);
  235. if(GetKeyState('0') & 0x80) tedit.Zero();
  236. if(GetKeyState('8') & 0x80) terrain.SaveMap("grass.bmp");
  237. if(GetKeyState('9') & 0x80) terrain.LoadMap("grass.bmp");
  238. if(GetKeyState('O') & 0x80) { tedit.Increase(1); cam.AddY(0.1f); }
  239. if(GetKeyState('L') & 0x80) { tedit.Increase(-1); cam.AddY(-0.1f); }
  240. cursor.y = terrain.GetRealHeight(cursor.x, cursor.z);
  241. float y;
  242. y = terrain.GetRealHeight(cam.GetX(), cam.GetZ());
  243. if (y != 0)
  244. {
  245. float change = y + 0.3 - cam.GetY();
  246. cam.AddY(change);
  247. }
  248. if(GetKeyState('E') & 0x80)
  249. {
  250. // erri("x, z, y", cam.GetX(), cam.GetZ(), y);
  251. erri("x, y, z", cam_rot.x, cam_rot.y, cam_rot.z);
  252. }
  253. if(GetKeyState('W') & 0x80) cam.AddX(spd);
  254. if(GetKeyState('S') & 0x80) cam.AddX(-spd);
  255. if(GetKeyState('A') & 0x80) cam.AddZ(-spd);
  256. if(GetKeyState('D') & 0x80) cam.AddZ(spd);
  257. if(GetKeyState('1') & 0x80) spd = 0.001f;
  258. if(GetKeyState('2') & 0x80) spd = 0.01f;
  259. if(GetKeyState('3') & 0x80) spd = 0.1f;
  260. if(GetKeyState('4') & 0x80) spd = 0.5f;
  261. if(GetKeyState('5') & 0x80) spd = 1;
  262. if(GetKeyState('6') & 0x80) spd = 3;
  263. if(GetKeyState('7') & 0x80) spd = 10;
  264. if(GetKeyState('J') & 0x80) tdata.SetMode(GL_LINES);
  265. if(GetKeyState('K') & 0x80) tdata.SetMode(GL_TRIANGLES);
  266. // Here we get the position of the mouse, rotate the camera based on its movements,
  267. // then set the mouse position to the middle of the screen.
  268. /*
  269. POINT mousePos;
  270. GetCursorPos(&mousePos);
  271. ShowCursor(0);
  272. cam.RotateByMouse(mousePos.x, mousePos.y, (ScreenWidth >> 1), (ScreenHeight >> 1));
  273. cam.RotateByMouse(mousePos.x, mousePos.y, (ScreenWidth >> 1), (ScreenHeight >> 1));
  274. SetCursorPos((ScreenWidth >> 1), (ScreenHeight >> 1));
  275. */
  276. }
  277. void Shutdown()
  278. {
  279. tdata.Destroy();
  280. }
  281. // Recap:
  282. // Rendering a mesh using octrees is a lot easier than I am sure many
  283. // people thought.  All we are doing is creating a bounding box around
  284. // the entire terrain.  Then we break that box up into 8 equally sized
  285. // cubes within the box.  We then determine which vertices fall within
  286. // with cubes.  Depending of if we reached the max recursion level or
  287. // if we reached the smallest number of triangles allowed in each cube
  288. // will depend on if we break each cube into another, smaller set of 8
  289. // or if we are done creating the tree.  Technically you can put any mesh
  290. // in a octree, not just terrains.  It might not make sense for character
  291. // models but you can if you want.
  292. // Copyright October 2004
  293. // All Rights Reserved!
  294. // Allen Sherrod
  295. // ProgrammingAce@UltimateGameProgramming.com
  296. // www.UltimateGameProgramming.com