Camera3D.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. #include "pch.h"
  2. #include <AsynchronCall.h>
  3. #include "Camera3D.h"
  4. #include "CppUnitTest.h"
  5. #include "DX12GraphicsApi.h"
  6. #include "Globals.h"
  7. #include "Image.h"
  8. #include "Model3D.h"
  9. #include "RenderThread.h"
  10. #include "Screen.h"
  11. #include "Texture.h"
  12. #include "Window.h"
  13. #include "World3D.h"
  14. using namespace Microsoft::VisualStudio::CppUnitTestFramework;
  15. namespace FrameworkTests
  16. {
  17. TEST_CLASS (Cam3Tests)
  18. {
  19. public:
  20. TEST_METHOD (TestProjection)
  21. {
  22. Framework::Cam3D cam;
  23. cam.setPosition(Framework::Vec3<float>(0, 0, 0));
  24. cam.setRotation(Framework::Vec3<float>(0, 0, 0));
  25. Framework::Vec3<float> target(0, 1000, 0);
  26. cam.setViewDirection(target);
  27. Framework::Mat4<float> projection = cam.getProjectionMatrix();
  28. Framework::Mat4<float> inverse = cam.getInverseProjectionMatrix();
  29. Framework::Mat4<float> view = cam.getViewMatrix();
  30. Framework::Mat4<float> iView = cam.getInverseViewMatrix();
  31. for (int i = 0; i < 10; i++)
  32. {
  33. for (int j = 0; j < 10; j++)
  34. {
  35. Framework::Vec4<float> origin(0, 0, 0, 1.f);
  36. Framework::Vec4<float> target(
  37. i / 5.f - 1.f, j / 5.f - 1.f, -1.f, 1.f);
  38. Framework::Vec4<float> transformedOrigin = iView * origin;
  39. Framework::Vec4<float> transformedTarget
  40. = iView * (inverse * target);
  41. Framework::Vec4<float> transformedDirection
  42. = transformedTarget - transformedOrigin;
  43. }
  44. }
  45. }
  46. TEST_METHOD (TestRaytracing)
  47. {
  48. Framework::initFramework();
  49. Framework::Logging::zLoggingHandler()->addChannel(
  50. new Framework::Logging::OutputDebugStringLoggingChannel());
  51. Framework::setDebugDX(1);
  52. Framework::NativeWindow window;
  53. WNDCLASS wc = Framework::F_Normal(GetModuleHandle(0));
  54. wc.lpszClassName = "Factory Craft";
  55. window.create(WS_POPUPWINDOW, wc);
  56. Framework::Monitor m = Framework::getMonitor(0);
  57. window.setBounds(Framework::Point(m.x, m.y),
  58. Framework::Point(m.width, m.height));
  59. window.setDisplayMode(SW_SHOWNORMAL);
  60. window.setPreCloseAction([&window](void* p, void* f) {
  61. Framework::StopMessageLoop(window.getWindowHandle());
  62. });
  63. window.setMouseAction(Framework::_ret1ME);
  64. window.setKeyboardAction(Framework::_ret1TE);
  65. Framework::DirectX12* api = new Framework::DirectX12();
  66. Framework::Screen3D screen(
  67. dynamic_cast<Framework::NativeWindow*>(window.getThis()), api);
  68. screen.setHandleUserInputsOnTick(0);
  69. window.setScreen(
  70. dynamic_cast<Framework::Screen*>(screen.getThis()));
  71. screen.setFillColor(0);
  72. screen.setTestRend(0);
  73. Framework::Cam3D cam;
  74. cam.setPosition({0.f, -1000.f, 0.f});
  75. Framework::Vec3<float> target(0, 1000, 0);
  76. cam.setViewDirection(target);
  77. Framework::World3D world;
  78. Framework::Model3DData* data
  79. = screen.zGraphicsApi()->createModel("cube");
  80. data->setAmbientFactor(0.f);
  81. data->setDiffusFactor(1.f);
  82. data->setSpecularFactor(0.f);
  83. float size = 1;
  84. float left, right, top, bottom;
  85. // Calculate the screen coordinates of the left side of the bitmap.
  86. right = (float)((-size / 2.0));
  87. // Calculate the screen coordinates of the right side of the bitmap.
  88. left = right + (float)size;
  89. // Calculate the screen coordinates of the top of the bitmap.
  90. top = (float)(size / 2.0);
  91. // Calculate the screen coordinates of the bottom of the bitmap.
  92. bottom = top - (float)size;
  93. float front = -size / 2;
  94. float back = front + size;
  95. Framework::Vertex3D* vertecies = new Framework::Vertex3D[24];
  96. for (int i = 0; i < 24; i++)
  97. vertecies[i].knochenId = 0;
  98. // front side
  99. vertecies[0].pos = Framework::Vec3<float>(left, front, top);
  100. vertecies[0].tPos = Framework::Vec2<float>(0.f, 0.f);
  101. vertecies[1].pos = Framework::Vec3<float>(right, front, top);
  102. vertecies[1].tPos = Framework::Vec2<float>(1.f, 0.f);
  103. vertecies[2].pos = Framework::Vec3<float>(left, front, bottom);
  104. vertecies[2].tPos = Framework::Vec2<float>(0.f, 1.f);
  105. vertecies[3].pos = Framework::Vec3<float>(right, front, bottom);
  106. vertecies[3].tPos = Framework::Vec2<float>(1.f, 1.f);
  107. // back side
  108. vertecies[4].pos = Framework::Vec3<float>(right, back, top);
  109. vertecies[4].tPos = Framework::Vec2<float>(0.0f, 0.0f);
  110. vertecies[5].pos = Framework::Vec3<float>(left, back, top);
  111. vertecies[5].tPos = Framework::Vec2<float>(1.0f, 0.0f);
  112. vertecies[6].pos = Framework::Vec3<float>(right, back, bottom);
  113. vertecies[6].tPos = Framework::Vec2<float>(0.0f, 1.0f);
  114. vertecies[7].pos = Framework::Vec3<float>(left, back, bottom);
  115. vertecies[7].tPos = Framework::Vec2<float>(1.0f, 1.0f);
  116. // left side
  117. vertecies[8].pos = Framework::Vec3<float>(left, back, top);
  118. vertecies[8].tPos = Framework::Vec2<float>(0.f, 0.f);
  119. vertecies[9].pos = Framework::Vec3<float>(left, front, top);
  120. vertecies[9].tPos = Framework::Vec2<float>(1.f, 0.f);
  121. vertecies[10].pos = Framework::Vec3<float>(left, back, bottom);
  122. vertecies[10].tPos = Framework::Vec2<float>(0.f, 1.f);
  123. vertecies[11].pos = Framework::Vec3<float>(left, front, bottom);
  124. vertecies[11].tPos = Framework::Vec2<float>(1.f, 1.f);
  125. // right side
  126. vertecies[12].pos = Framework::Vec3<float>(right, front, top);
  127. vertecies[12].tPos = Framework::Vec2<float>(0.0f, 0.0f);
  128. vertecies[13].pos = Framework::Vec3<float>(right, back, top);
  129. vertecies[13].tPos = Framework::Vec2<float>(1.0f, 0.0f);
  130. vertecies[14].pos = Framework::Vec3<float>(right, front, bottom);
  131. vertecies[14].tPos = Framework::Vec2<float>(0.0f, 1.0f);
  132. vertecies[15].pos = Framework::Vec3<float>(right, back, bottom);
  133. vertecies[15].tPos = Framework::Vec2<float>(1.0f, 1.0f);
  134. // top side
  135. vertecies[16].pos = Framework::Vec3<float>(left, back, top);
  136. vertecies[16].tPos = Framework::Vec2<float>(0.f, 0.f);
  137. vertecies[17].pos = Framework::Vec3<float>(right, back, top);
  138. vertecies[17].tPos = Framework::Vec2<float>(1.f, 0.f);
  139. vertecies[18].pos = Framework::Vec3<float>(left, front, top);
  140. vertecies[18].tPos = Framework::Vec2<float>(0.f, 1.f);
  141. vertecies[19].pos = Framework::Vec3<float>(right, front, top);
  142. vertecies[19].tPos = Framework::Vec2<float>(1.f, 1.f);
  143. // botom side
  144. vertecies[20].pos = Framework::Vec3<float>(left, front, bottom);
  145. vertecies[20].tPos = Framework::Vec2<float>(0.0f, 0.0f);
  146. vertecies[21].pos = Framework::Vec3<float>(right, front, bottom);
  147. vertecies[21].tPos = Framework::Vec2<float>(1.0f, 0.0f);
  148. vertecies[22].pos = Framework::Vec3<float>(left, back, bottom);
  149. vertecies[22].tPos = Framework::Vec2<float>(0.0f, 1.0f);
  150. vertecies[23].pos = Framework::Vec3<float>(right, back, bottom);
  151. vertecies[23].tPos = Framework::Vec2<float>(1.0f, 1.0f);
  152. data->setVertecies(vertecies, 24);
  153. // the order of the polygons has to be NORTH (front), EAST (left),
  154. // SOUTH (back), WEST (right), TOP, BOTTOM according to the Area
  155. // definition front side
  156. Framework::Polygon3D* p
  157. = new Framework::Polygon3D(); // looking from (0,0,0) to (1,0,0)
  158. // to see this side
  159. p->indexAnz = 6;
  160. p->indexList = new int[p->indexAnz];
  161. p->indexList[0] = 0;
  162. p->indexList[1] = 1;
  163. p->indexList[2] = 2;
  164. p->indexList[3] = 1;
  165. p->indexList[4] = 3;
  166. p->indexList[5] = 2;
  167. data->addPolygon(p);
  168. // left side
  169. p = new Framework::Polygon3D(); // looking from (0,0,0) to (0,1,0)
  170. // to see this
  171. // side
  172. p->indexAnz = 6;
  173. p->indexList = new int[p->indexAnz];
  174. p->indexList[0] = 0 + 8;
  175. p->indexList[1] = 1 + 8;
  176. p->indexList[2] = 2 + 8;
  177. p->indexList[3] = 1 + 8;
  178. p->indexList[4] = 3 + 8;
  179. p->indexList[5] = 2 + 8;
  180. data->addPolygon(p);
  181. // back side
  182. p = new Framework::Polygon3D(); // looking from (0,0,0) to (-1,0,0)
  183. // to see this
  184. // side
  185. p->indexAnz = 6;
  186. p->indexList = new int[p->indexAnz];
  187. p->indexList[0] = 0 + 4;
  188. p->indexList[1] = 1 + 4;
  189. p->indexList[2] = 2 + 4;
  190. p->indexList[3] = 1 + 4;
  191. p->indexList[4] = 3 + 4;
  192. p->indexList[5] = 2 + 4;
  193. data->addPolygon(p);
  194. // right side
  195. p = new Framework::Polygon3D(); // looking from (0,0,0) to (0,-1,0)
  196. // to see this
  197. // side
  198. p->indexAnz = 6;
  199. p->indexList = new int[p->indexAnz];
  200. p->indexList[0] = 0 + 12;
  201. p->indexList[1] = 1 + 12;
  202. p->indexList[2] = 2 + 12;
  203. p->indexList[3] = 1 + 12;
  204. p->indexList[4] = 3 + 12;
  205. p->indexList[5] = 2 + 12;
  206. data->addPolygon(p);
  207. // top side
  208. p = new Framework::Polygon3D(); // looking from (0,0,0) to (0,0,-1)
  209. // to see this
  210. // side
  211. p->indexAnz = 6;
  212. p->indexList = new int[p->indexAnz];
  213. p->indexList[0] = 0 + 16;
  214. p->indexList[1] = 1 + 16;
  215. p->indexList[2] = 2 + 16;
  216. p->indexList[3] = 1 + 16;
  217. p->indexList[4] = 3 + 16;
  218. p->indexList[5] = 2 + 16;
  219. data->addPolygon(p);
  220. // botom side
  221. p = new Framework::Polygon3D(); // looking from (0,0,0) to (0,0,1)
  222. // to see this
  223. // side
  224. p->indexAnz = 6;
  225. p->indexList = new int[p->indexAnz];
  226. p->indexList[0] = 0 + 20;
  227. p->indexList[1] = 1 + 20;
  228. p->indexList[2] = 2 + 20;
  229. p->indexList[3] = 1 + 20;
  230. p->indexList[4] = 3 + 20;
  231. p->indexList[5] = 2 + 20;
  232. data->addPolygon(p);
  233. data->calculateNormals();
  234. Framework::Image* img1 = new Framework::Image();
  235. img1->newImage(1, 1, 0xFFFF0000);
  236. Framework::Texture* red
  237. = screen.zGraphicsApi()->createOrGetTexture("red", img1);
  238. Framework::Image* img2 = new Framework::Image();
  239. img2->newImage(1, 1, 0xFF00FF00);
  240. Framework::Texture* green
  241. = screen.zGraphicsApi()->createOrGetTexture("green", img2);
  242. Framework::Image* img3 = new Framework::Image();
  243. img3->newImage(1, 1, 0xFF0000FF);
  244. Framework::Texture* blue
  245. = screen.zGraphicsApi()->createOrGetTexture("blue", img3);
  246. Framework::Image* img4 = new Framework::Image();
  247. img4->newImage(1, 1, 0xFFFFFF00);
  248. Framework::Texture* yellow
  249. = screen.zGraphicsApi()->createOrGetTexture("yellow", img4);
  250. Framework::Image* img5 = new Framework::Image();
  251. img5->newImage(1, 1, 0xFFFF00FF);
  252. Framework::Texture* pink
  253. = screen.zGraphicsApi()->createOrGetTexture("pink", img5);
  254. Framework::Image* img6 = new Framework::Image();
  255. img6->newImage(1, 1, 0xFFFFFFFF);
  256. Framework::Texture* white
  257. = screen.zGraphicsApi()->createOrGetTexture("white", img6);
  258. Framework::Model3DTexture* texture
  259. = new Framework::Model3DTexture();
  260. texture->setPolygonTexture(0, red);
  261. texture->setPolygonTexture(1, green);
  262. texture->setPolygonTexture(2, blue);
  263. texture->setPolygonTexture(3, yellow);
  264. texture->setPolygonTexture(4, pink);
  265. texture->setPolygonTexture(5, white);
  266. Framework::Array<Framework::Model3D*> cubes;
  267. std::function<void(int, int, int)> addCube
  268. = [&cubes, &world, &data, &texture](int x, int y, int z) {
  269. Framework::Model3D* cube = new Framework::Model3D();
  270. cube->setModelData(dynamic_cast<Framework::Model3DData*>(
  271. data->getThis()));
  272. cube->setPosition(x, y, z);
  273. cube->setSize(5 + rand() % 5);
  274. cube->setRotation(
  275. rand() % 10 / 5, rand() % 10 / 5, rand() % 10 / 5);
  276. cube->setModelTextur(
  277. dynamic_cast<Framework::Model3DTexture*>(
  278. texture->getThis()));
  279. world.addDrawable(cube);
  280. cubes.add(cube);
  281. };
  282. for (int i = 0; i < 10; i++)
  283. {
  284. addCube(rand() % 1000 - 500,
  285. rand() % 1000 - 500,
  286. rand() % 1000 - 500);
  287. }
  288. cam.setWorld(dynamic_cast<Framework::World3D*>(world.getThis()));
  289. cam.addStyle(Framework::Cam3D::Style::Movable
  290. | Framework::Cam3D::Style::Rotatable
  291. | Framework::Cam3D::Style::Zoomable
  292. | Framework::Cam3D::Style::Tick);
  293. cam.setMovementSpeed(0.1f);
  294. cam.setScreenPosition(0, 0);
  295. cam.setScreenSize(screen.getBackBufferSize());
  296. screen.addKamera(dynamic_cast<Framework::Cam3D*>(cam.getThis()));
  297. Framework::RenderTh rTh;
  298. rTh.setMaxFps(-1);
  299. rTh.setQuiet(0);
  300. rTh.setMaxFps(-1);
  301. rTh.setScreen(dynamic_cast<Framework::Screen*>(screen.getThis()));
  302. double sum = 0;
  303. rTh.setTickFunktion([&cubes, &sum, &addCube, &api, &screen](
  304. void* p, void* f, double tick) {
  305. for (Framework::Model3D* cube : cubes)
  306. {
  307. cube->setRotationX(cube->getXRotation() + tick * 2);
  308. cube->setRotationY(cube->getXRotation() + tick / 5);
  309. cube->setRotationZ(cube->getXRotation() + tick / 25);
  310. cube->setSize(
  311. cube->getSize() + tick * 5 * (sum > 2.5 ? 1 : -1));
  312. }
  313. sum += tick;
  314. if (sum > 10)
  315. {
  316. sum -= 10;
  317. screen.render();
  318. addCube(rand() % 1000 - 500,
  319. rand() % 1000 - 500,
  320. rand() % 1000 - 500);
  321. }
  322. });
  323. rTh.beginn();
  324. new Framework::AsynchronCall([&window]() {
  325. Sleep(10000);
  326. Framework::StopMessageLoop(window.getWindowHandle());
  327. });
  328. Framework::StartMessageLoop();
  329. rTh.terminate();
  330. }
  331. };
  332. } // namespace FrameworkTests