Camera3D.cpp 16 KB

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