main.cpp 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124
  1. #include <Windows.h>
  2. #include <iostream>
  3. #define STB_IMAGE_IMPLEMENTATION
  4. #include "stb_image.h"
  5. #include <GLFW/glfw3.h>
  6. #include <GL/glew.h>
  7. #include <imgui.h>
  8. #include <backends/imgui_impl_glfw.h>
  9. #include <backends/imgui_impl_opengl3.h>
  10. #include <glm/gtx/transform.hpp>
  11. #include "src/gl3d.h"
  12. #include "profiler.h"
  13. #include <ctime>
  14. #include <functional>
  15. #include <algorithm>
  16. int w = 840;
  17. int h = 640;
  18. gl3d::GpuMaterial material = gl3d::GpuMaterial().setDefaultMaterial();
  19. #define USE_GPU_ENGINE 0
  20. #pragma region gpu
  21. extern "C"
  22. {
  23. __declspec(dllexport) unsigned long NvOptimusEnablement = USE_GPU_ENGINE;
  24. __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = USE_GPU_ENGINE;
  25. }
  26. #pragma endregion
  27. struct ObjectAndTransform
  28. {
  29. gl3d::Object obj = {};
  30. glm::vec3 position = {};
  31. glm::vec3 rotation = {};
  32. glm::vec3 scale = {1,1,1};
  33. };
  34. int main()
  35. {
  36. #pragma region init
  37. if (!glfwInit())
  38. {
  39. std::cout << "err initializing glfw";
  40. }
  41. glfwWindowHint(GLFW_SAMPLES, 4);
  42. //glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  43. //glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
  44. //glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  45. GLFWwindow *wind = glfwCreateWindow(w, h, "geam", nullptr, nullptr);
  46. glfwMakeContextCurrent(wind);
  47. glfwSwapInterval(0);
  48. if (glewInit() != GLEW_OK)
  49. {
  50. std::cout << "err initializing glew";
  51. }
  52. ImGui::CreateContext();
  53. ImGui::StyleColorsDark();
  54. ImGuiIO &io = ImGui::GetIO(); (void)io;
  55. io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
  56. //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
  57. io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
  58. io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
  59. //io.ConfigViewportsNoAutoMerge = true;
  60. //io.ConfigViewportsNoTaskBarIcon = true;
  61. ImGuiStyle &style = ImGui::GetStyle();
  62. if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
  63. {
  64. //style.WindowRounding = 0.0f;
  65. style.Colors[ImGuiCol_WindowBg].w = 0.f;
  66. style.Colors[ImGuiCol_DockingEmptyBg].w = 0.f;
  67. }
  68. ImGui_ImplGlfw_InitForOpenGL(wind, true);
  69. ImGui_ImplOpenGL3_Init("#version 330");
  70. glEnable(GL_DEPTH_TEST);
  71. #pragma endregion
  72. gl3d::Renderer3D renderer;
  73. renderer.init();
  74. #pragma region shader
  75. gl3d::Shader shader;
  76. shader.loadShaderProgramFromFile("shaders/color.vert", "shaders/color.frag");
  77. shader.bind();
  78. GLint location = glGetUniformLocation(shader.id, "u_transform");
  79. if (location == -1)
  80. {
  81. std::cout << "uniform error u_transform\n";
  82. }
  83. gl3d::LightShader lightShader;
  84. lightShader.create();
  85. gl3d::Shader showNormalsShader;
  86. showNormalsShader.loadShaderProgramFromFile("shaders/showNormals.vert",
  87. "shaders/showNormals.geom", "shaders/showNormals.frag");
  88. GLint normalsModelTransformLocation = glGetUniformLocation(showNormalsShader.id, "u_modelTransform");
  89. GLint normalsProjectionLocation = glGetUniformLocation(showNormalsShader.id, "u_projection");
  90. #pragma endregion
  91. #pragma region texture
  92. //gl3d::Texture crateTexture("resources/other/crate.png");
  93. //gl3d::Texture crateNormalTexture("resources/other/crateNormal.png");
  94. //gl3d::Texture rockTexture("resources/other/boulder.png");
  95. //gl3d::Texture rockNormalTexture("resources/other/boulderNormal.png");
  96. //gl3d::Texture levelTexture("resources/obj/level.png");
  97. #pragma endregion
  98. {
  99. const char *names[6] =
  100. { "resources/skyBoxes/ocean/right.jpg",
  101. "resources/skyBoxes/ocean/left.jpg",
  102. "resources/skyBoxes/ocean/top.jpg",
  103. "resources/skyBoxes/ocean/bottom.jpg",
  104. "resources/skyBoxes/ocean/front.jpg",
  105. "resources/skyBoxes/ocean/back.jpg" };
  106. renderer.skyBox.loadTexture(names);
  107. //skyBox.loadTexture("resources/skyBoxes/ocean_1.png");
  108. //skyBox.loadTexture("resources/skyBoxes/uffizi_cross.png", 1);
  109. }
  110. //VertexArrayContext va;
  111. //va.create();
  112. float bufferData[] =
  113. {
  114. 0.f, 1.5f, 0.f,
  115. -0.5f, 0.5f, 0.f,
  116. 0.5f, 0.5f, 0.f,
  117. };
  118. float bufferData2[] =
  119. {
  120. 0.f, 0.5f, -1.f,
  121. -0.5f, -0.5f, -1.f,
  122. 0.5f, -0.5f, 0-1.f,
  123. };
  124. float cubePositions[] = {
  125. -1.0f, +1.0f, +1.0f, // 0
  126. +1.0f, +0.0f, +0.0f, // Color
  127. +1.0f, +1.0f, +1.0f, // 1
  128. +1.0f, +0.0f, +0.0f, // Color
  129. +1.0f, +1.0f, -1.0f, // 2
  130. +1.0f, +0.0f, +0.0f, // Color
  131. -1.0f, +1.0f, -1.0f, // 3
  132. +1.0f, +0.0f, +0.0f, // Color
  133. -1.0f, +1.0f, -1.0f, // 4
  134. +0.0f, +1.0f, +0.0f, // Color
  135. +1.0f, +1.0f, -1.0f, // 5
  136. +0.0f, +1.0f, +0.0f, // Color
  137. +1.0f, -1.0f, -1.0f, // 6
  138. +0.0f, +1.0f, +0.0f, // Color
  139. -1.0f, -1.0f, -1.0f, // 7
  140. +0.0f, +1.0f, +0.0f, // Color
  141. +1.0f, +1.0f, -1.0f, // 8
  142. +0.0f, +0.0f, +1.0f, // Color
  143. +1.0f, +1.0f, +1.0f, // 9
  144. +0.0f, +0.0f, +1.0f, // Color
  145. +1.0f, -1.0f, +1.0f, // 10
  146. +0.0f, +0.0f, +1.0f, // Color
  147. +1.0f, -1.0f, -1.0f, // 11
  148. +0.0f, +0.0f, +1.0f, // Color
  149. -1.0f, +1.0f, +1.0f, // 12
  150. +1.0f, +1.0f, +0.0f, // Color
  151. -1.0f, +1.0f, -1.0f, // 13
  152. +1.0f, +1.0f, +0.0f, // Color
  153. -1.0f, -1.0f, -1.0f, // 14
  154. +1.0f, +1.0f, +0.0f, // Color
  155. -1.0f, -1.0f, +1.0f, // 15
  156. +1.0f, +1.0f, +0.0f, // Color
  157. +1.0f, +1.0f, +1.0f, // 16
  158. +0.0f, +1.0f, +1.0f, // Color
  159. -1.0f, +1.0f, +1.0f, // 17
  160. +0.0f, +1.0f, +1.0f, // Color
  161. -1.0f, -1.0f, +1.0f, // 18
  162. +0.0f, +1.0f, +1.0f, // Color
  163. +1.0f, -1.0f, +1.0f, // 19
  164. +0.0f, +1.0f, +1.0f, // Color
  165. +1.0f, -1.0f, -1.0f, // 20
  166. +1.0f, +0.0f, +1.0f, // Color
  167. -1.0f, -1.0f, -1.0f, // 21
  168. +1.0f, +0.0f, +1.0f, // Color
  169. -1.0f, -1.0f, +1.0f, // 22
  170. +1.0f, +0.0f, +1.0f, // Color
  171. +1.0f, -1.0f, +1.0f, // 23
  172. +1.0f, +0.0f, +1.0f, // Color
  173. };
  174. float uv = 1;
  175. float cubePositionsNormals[] = {
  176. -1.0f, +1.0f, +1.0f, // 0
  177. +0.0f, +1.0f, +0.0f, // Normal
  178. 0, 0, //uv
  179. //0,0,0, //tangent
  180. //0,0,0, //btangent
  181. +1.0f, +1.0f, +1.0f, // 1
  182. +0.0f, +1.0f, +0.0f, // Normal
  183. 1* uv, 0, //uv
  184. //0,0,0, //tangent
  185. //0,0,0, //btangent
  186. +1.0f, +1.0f, -1.0f, // 2
  187. +0.0f, +1.0f, +0.0f, // Normal
  188. 1* uv, 1* uv, //uv
  189. //0,0,0, //tangent
  190. //0,0,0, //btangent
  191. -1.0f, +1.0f, -1.0f, // 3
  192. +0.0f, +1.0f, +0.0f, // Normal
  193. 0, 1* uv, //uv
  194. //0,0,0, //tangent
  195. //0,0,0, //btangent
  196. -1.0f, +1.0f, -1.0f, // 4
  197. 0.0f, +0.0f, -1.0f, // Normal
  198. 0, 1* uv, //uv
  199. //0,0,0, //tangent
  200. //0,0,0, //btangent
  201. +1.0f, +1.0f, -1.0f, // 5
  202. 0.0f, +0.0f, -1.0f, // Normal
  203. 1* uv, 1* uv, //uv
  204. //0,0,0, //tangent
  205. //0,0,0, //btangent
  206. +1.0f, -1.0f, -1.0f, // 6
  207. 0.0f, +0.0f, -1.0f, // Normal
  208. 1* uv, 0, //uv
  209. //0,0,0, //tangent
  210. //0,0,0, //btangent
  211. -1.0f, -1.0f, -1.0f, // 7
  212. 0.0f, +0.0f, -1.0f, // Normal
  213. 0, 0, //uv
  214. //0,0,0, //tangent
  215. //0,0,0, //btangent
  216. +1.0f, +1.0f, -1.0f, // 8
  217. +1.0f, +0.0f, +0.0f, // Normal
  218. 1* uv, 0, //uv
  219. //0,0,0, //tangent
  220. //0,0,0, //btangent
  221. +1.0f, +1.0f, +1.0f, // 9
  222. +1.0f, +0.0f, +0.0f, // Normal
  223. 1* uv, 1* uv, //uv
  224. //0,0,0, //tangent
  225. //0,0,0, //btangent
  226. +1.0f, -1.0f, +1.0f, // 10
  227. +1.0f, +0.0f, +0.0f, // Normal
  228. 0, 1* uv, //uv
  229. //0,0,0, //tangent
  230. //0,0,0, //btangent
  231. +1.0f, -1.0f, -1.0f, // 11
  232. +1.0f, +0.0f, +0.0f, // Normal
  233. 0, 0, //uv
  234. //0,0,0, //tangent
  235. //0,0,0, //btangent
  236. -1.0f, +1.0f, +1.0f, // 12
  237. -1.0f, +0.0f, +0.0f, // Normal
  238. 1* uv, 1* uv, //uv
  239. //0,0,0, //tangent
  240. //0,0,0, //btangent
  241. -1.0f, +1.0f, -1.0f, // 13
  242. -1.0f, +0.0f, +0.0f, // Normal
  243. 1* uv, 0, //uv
  244. //0,0,0, //tangent
  245. //0,0,0, //btangent
  246. -1.0f, -1.0f, -1.0f, // 14
  247. -1.0f, +0.0f, +0.0f, // Normal
  248. 0, 0, //uv
  249. //0,0,0, //tangent
  250. //0,0,0, //btangent
  251. -1.0f, -1.0f, +1.0f, // 15
  252. -1.0f, +0.0f, +0.0f, // Normal
  253. 0, 1* uv, //uv
  254. //0,0,0, //tangent
  255. //0,0,0, //btangent
  256. +1.0f, +1.0f, +1.0f, // 16
  257. +0.0f, +0.0f, +1.0f, // Normal
  258. 1* uv, 1* uv, //uv
  259. //0,0,0, //tangent
  260. //0,0,0, //btangent
  261. -1.0f, +1.0f, +1.0f, // 17
  262. +0.0f, +0.0f, +1.0f, // Normal
  263. 0, 1* uv, //uv
  264. //0, 0, 0, //tangent
  265. //0, 0, 0, //btangent
  266. -1.0f, -1.0f, +1.0f, // 18
  267. +0.0f, +0.0f, +1.0f, // Normal
  268. 0, 0, //uv
  269. //0, 0, 0, //tangent
  270. //0, 0, 0, //btangent
  271. +1.0f, -1.0f, +1.0f, // 19
  272. +0.0f, +0.0f, +1.0f, // Normal
  273. 1* uv, 0, //uv
  274. //0, 0, 0, //tangent
  275. //0, 0, 0, //btangent
  276. +1.0f, -1.0f, -1.0f, // 20
  277. +0.0f, -1.0f, +0.0f, // Normal
  278. 1* uv, 0, //uv
  279. //0, 0, 0, //tangent
  280. //0, 0, 0, //btangent
  281. -1.0f, -1.0f, -1.0f, // 21
  282. +0.0f, -1.0f, +0.0f, // Normal
  283. 0, 0, //uv
  284. //0, 0, 0, //tangent
  285. //0, 0, 0, //btangent
  286. -1.0f, -1.0f, +1.0f, // 22
  287. +0.0f, -1.0f, +0.0f, // Normal
  288. 0, 1* uv, //uv
  289. //0, 0, 0, //tangent
  290. //0, 0, 0, //btangent
  291. +1.0f, -1.0f, +1.0f, // 23
  292. +0.0f, -1.0f, +0.0f, // Normal
  293. 1* uv, 1* uv, //uv
  294. //0, 0, 0, //tangent
  295. //0, 0, 0, //btangent
  296. };
  297. unsigned int cubeIndices[] = {
  298. 0, 1, 2, 0, 2, 3, // Top
  299. 4, 5, 6, 4, 6, 7, // Back
  300. 8, 9, 10, 8, 10, 11, // Right
  301. 12, 13, 14, 12, 14, 15, // Left
  302. 16, 17, 18, 16, 18, 19, // Front
  303. 20, 22, 21, 20, 23, 22, // Bottom
  304. };
  305. renderer.pointLights.push_back(gl3d::internal::GpuPointLight());
  306. renderer.pointLights[0].position = glm::vec4(0, 0.42, 2.44, 0);
  307. gl3d::GraphicModel lightCubeModel;
  308. lightCubeModel.loadFromComputedData(sizeof(cubePositions),
  309. cubePositions,
  310. sizeof(cubeIndices), cubeIndices, true);
  311. lightCubeModel.scale = glm::vec3(0.05);
  312. //gl3d::GraphicModel cube;
  313. //cube.loadFromComputedData(sizeof(cubePositionsNormals), cubePositionsNormals,
  314. // sizeof(cubeIndices), cubeIndices);
  315. //cube.loadFromFile("resources/obj/sphere.obj");
  316. //cube.loadFromFile("resources/other/barrel.obj");
  317. //gl3d::LoadedModelData barelModel("resources/other/barrel.obj", 0.1);
  318. auto barelModel = renderer.loadObject("resources/barrel/Barrel_01.obj", 1);
  319. auto rockModel = renderer.loadObject("resources/other/boulder.obj", 0.1);
  320. auto levelModel = renderer.loadObject("resources/sponza/sponza.obj");
  321. //gl3d::LoadedModelData levelModel("resources/sponza2/sponza.obj", 0.008);
  322. //auto levelModel = renderer.loadObject("resources/other/crate.obj", 0.01);
  323. auto sphereModel = renderer.loadObject("resources/obj/sphere3.obj");
  324. //cube.loadFromModelMeshIndex(barelModel, 0);
  325. //cube.scale = glm::vec3(0.1);
  326. //auto objectTest = renderer.loadObject("resources/other/crate.obj", 0.01);
  327. //auto objectTest = renderer.loadObject("resources/sponza2/sponza.obj", 0.008);
  328. //auto objectTest = renderer.loadObject("resources/barrel/Barrel_01.obj");
  329. //auto objectTest2 = renderer.loadObject("resources/other/crate.obj", 0.01);
  330. std::vector< ObjectAndTransform > models;
  331. static std::vector < const char* > items = {}; //just models names
  332. renderer.camera.aspectRatio = (float)w / h;
  333. renderer.camera.fovRadians = glm::radians(100.f);
  334. renderer.camera.position = { 0.f,0.f,2.f };
  335. static int itemCurrent = 0;
  336. static int subItemCurent = 0;
  337. static bool borderItem = 0;
  338. static bool showNormals = 0;
  339. static bool normalMap = 1;
  340. static int currnetFps = 0;
  341. const int FPS_RECORD_ARR_SIZE = 20;
  342. int recordPos = 0;
  343. static float fpsArr[FPS_RECORD_ARR_SIZE] = { };
  344. const int DELTA_TIME_ARR_SIZE = 60;
  345. int recordPosDeltaTime = 0;
  346. static float deltaTimeArr[DELTA_TIME_ARR_SIZE] = { };
  347. int timeBeg = clock();
  348. //static PL::AverageProfiler renderProfiler;
  349. //static PL::ProfileRezults lastProfilerRezult = {};
  350. //const int Profiler_ARR_SIZE = 60;
  351. //int profilePos = 0;
  352. //static float profileeArr[Profiler_ARR_SIZE] = { };
  353. //const int ProfilerAverage_ARR_SIZE = 20;
  354. //int profileAveragePos = 0;
  355. //static float profileAverageArr[ProfilerAverage_ARR_SIZE] = { };
  356. PL::ImguiProfiler renderDurationProfiler("Render duration (ms) (avg over one sec)", 0, 30);
  357. PL::ImguiProfiler renderDurationProfilerFine("Render duration (ms) ", 0, 30);
  358. PL::ImguiProfiler imguiRenderDuration("Imgui render duration (ms) ", 0, 30);
  359. PL::ImguiProfiler swapBuffersDuration("Swap buffers duration (ms) ", 0, 30);
  360. while (!glfwWindowShouldClose(wind))
  361. {
  362. glfwGetWindowSize(wind, &w, &h);
  363. w = std::max(w, 1);
  364. h = std::max(h, 1);
  365. glStencilMask(0xFF);
  366. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  367. int timeEnd = clock();
  368. float deltaTime = (timeEnd - timeBeg) / 1000.f;
  369. timeBeg = clock();
  370. #pragma region profiler ui code
  371. {
  372. static float fpsCounterFloat;
  373. static float currentFpsCounter;
  374. fpsCounterFloat += deltaTime;
  375. currentFpsCounter += 1;
  376. if (fpsCounterFloat >= 1)
  377. {
  378. fpsCounterFloat -= 1;
  379. currnetFps = currentFpsCounter;
  380. currentFpsCounter = 0;
  381. if (recordPos < FPS_RECORD_ARR_SIZE)
  382. {
  383. fpsArr[recordPos] = currnetFps;
  384. recordPos++;
  385. }
  386. else
  387. {
  388. for (int i = 0; i < FPS_RECORD_ARR_SIZE - 1; i++)
  389. {
  390. fpsArr[i] = fpsArr[i + 1];
  391. }
  392. fpsArr[FPS_RECORD_ARR_SIZE - 1] = currnetFps;
  393. }
  394. //if (profileAveragePos < ProfilerAverage_ARR_SIZE)
  395. //{
  396. //
  397. // profileAverageArr[profileAveragePos] = renderProfiler.getAverageAndResetData().timeSeconds * 1000;
  398. // profileAveragePos++;
  399. //}
  400. //else
  401. //{
  402. // for (int i = 0; i < ProfilerAverage_ARR_SIZE - 1; i++)
  403. // {
  404. // profileAverageArr[i] = profileAverageArr[i + 1];
  405. // }
  406. // profileAverageArr[ProfilerAverage_ARR_SIZE - 1] = renderProfiler.getAverageAndResetData().timeSeconds * 1000;
  407. //}
  408. renderDurationProfiler.updateValue(1000);
  409. imguiRenderDuration.updateValue(1000);
  410. swapBuffersDuration.updateValue(1000);
  411. }
  412. if (recordPosDeltaTime < DELTA_TIME_ARR_SIZE)
  413. {
  414. deltaTimeArr[recordPosDeltaTime] = deltaTime;
  415. recordPosDeltaTime++;
  416. }
  417. else
  418. {
  419. for (int i = 0; i < DELTA_TIME_ARR_SIZE - 1; i++)
  420. {
  421. deltaTimeArr[i] = deltaTimeArr[i + 1];
  422. }
  423. deltaTimeArr[DELTA_TIME_ARR_SIZE - 1] = deltaTime;
  424. }
  425. //if (profilePos < Profiler_ARR_SIZE)
  426. //{
  427. // profileeArr[profilePos] = lastProfilerRezult.timeSeconds;
  428. // profilePos++;
  429. //}
  430. //else
  431. //{
  432. // for (int i = 0; i < Profiler_ARR_SIZE - 1; i++)
  433. // {
  434. // profileeArr[i] = profileeArr[i + 1];
  435. // }
  436. // profileeArr[Profiler_ARR_SIZE - 1] = lastProfilerRezult.timeSeconds;
  437. //}
  438. renderDurationProfilerFine.updateValue(1000);
  439. }
  440. #pragma endregion
  441. #pragma region imgui
  442. static float gamaCorection = 1;
  443. ImGui_ImplOpenGL3_NewFrame();
  444. ImGui_ImplGlfw_NewFrame();
  445. ImGui::NewFrame();
  446. //ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
  447. //window_flags |= ImGuiWindowFlags_NoBackground;
  448. //static bool open = true;
  449. //ImGui::Begin("DockSpace Demo", &open, window_flags);
  450. //static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_None;
  451. //dockspace_flags &= ~ImGuiDockNodeFlags_PassthruCentralNode;
  452. //ImGuiID dockspace_id = ImGui::GetID("MyDockSpace");
  453. //ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
  454. //
  455. //ImGui::End();
  456. ImGui::DockSpaceOverViewport(ImGui::GetMainViewport());
  457. static bool lightEditor = 1;
  458. static bool cubeEditor = 1;
  459. static bool showStats = 0;
  460. //imgui main menu
  461. {
  462. ImGui::Begin("Menu");
  463. ImGui::SetWindowFontScale(1.2f);
  464. ImGui::Checkbox("Light Editor##check", &lightEditor);
  465. ImGui::Checkbox("Object Editor##check", &cubeEditor);
  466. ImGui::Checkbox("Stats##check", &showStats);
  467. ImGui::NewLine();
  468. ImGui::Text("Settings");
  469. ImGui::SliderFloat("Gama Corections", &gamaCorection, 1, 3);
  470. static bool antiAliasing = 0;
  471. ImGui::Checkbox("Anti aliasing", &antiAliasing);
  472. if (antiAliasing)
  473. {
  474. glEnable(GL_MULTISAMPLE);
  475. }
  476. else
  477. {
  478. glDisable(GL_MULTISAMPLE);
  479. }
  480. static bool sampleShading = 0;
  481. ImGui::Checkbox("Sample Shading", &sampleShading);
  482. if (sampleShading)
  483. {
  484. glEnable(GL_SAMPLE_SHADING);
  485. }
  486. else
  487. {
  488. glDisable(GL_SAMPLE_SHADING);
  489. }
  490. static bool cullFace = 0;
  491. ImGui::Checkbox("CullFace", &cullFace);
  492. if (cullFace)
  493. {
  494. glEnable(GL_CULL_FACE);
  495. }
  496. else
  497. {
  498. glDisable(GL_CULL_FACE);
  499. }
  500. ImGui::Checkbox("Normal map", &normalMap);
  501. lightShader.normalMap = normalMap;
  502. renderer.lightShader.normalMap = normalMap;
  503. ImGui::Checkbox("Display item border", &borderItem);
  504. ImGui::Checkbox("Display normals", &showNormals);
  505. ImGui::End();
  506. }
  507. ImGuiWindowFlags flags = {};
  508. //imgui light editor
  509. if(lightEditor)
  510. {
  511. ImGui::PushID(6996);
  512. ImGui::Begin("Light Editor", &lightEditor, flags);
  513. ImGui::SetWindowFontScale(1.2f);
  514. static int pointLightSelector = -1;
  515. ImGui::Text("Point lightd Count %d", renderer.pointLights.size());
  516. ImGui::InputInt("Current Point light:", &pointLightSelector);
  517. int n = ImGui::Button("New Light"); ImGui::SameLine();
  518. int remove = ImGui::Button("Remove Light");
  519. if(pointLightSelector < -1)
  520. {
  521. pointLightSelector = -1;
  522. }
  523. if(n || pointLightSelector >= (int)renderer.pointLights.size())
  524. {
  525. gl3d::internal::GpuPointLight l = {};
  526. l.color = { 1,1,1,0 };
  527. renderer.pointLights.push_back(l);
  528. }
  529. pointLightSelector = std::min(pointLightSelector, (int)renderer.pointLights.size() - 1);
  530. if(remove)
  531. {
  532. if(pointLightSelector>=0)
  533. {
  534. renderer.pointLights.erase(renderer.pointLights.begin() + pointLightSelector);
  535. pointLightSelector = std::min(pointLightSelector, (int)renderer.pointLights.size() - 1);
  536. }
  537. }
  538. ImGui::NewLine();
  539. if(pointLightSelector >= 0)
  540. {
  541. ImGui::PushID(12);
  542. ImGui::ColorEdit3("Color", &renderer.pointLights[pointLightSelector].color[0]);
  543. ImGui::DragFloat3("Position", &renderer.pointLights[pointLightSelector].position[0], 0.1);
  544. ImGui::PopID();
  545. }
  546. ImGui::NewLine();
  547. ImGui::End();
  548. ImGui::PopID();
  549. }
  550. //imgui objectEditor
  551. if (cubeEditor)
  552. {
  553. ImGui::Begin("Object Editor", &cubeEditor, flags);
  554. ImGui::SetWindowFontScale(1.2f);
  555. ImGui::ListBox("World objects", &itemCurrent, items.data(), models.size(), 4);
  556. if (ImGui::Button("Add barrel"))
  557. {
  558. items.push_back("Barrel");
  559. ObjectAndTransform model;
  560. model.obj = barelModel;
  561. models.push_back(model);
  562. }
  563. ImGui::SameLine();
  564. if (ImGui::Button("Add rock"))
  565. {
  566. items.push_back("Rock");
  567. ObjectAndTransform model;
  568. model.obj = rockModel;
  569. models.push_back(model);
  570. }
  571. ImGui::SameLine();
  572. if (ImGui::Button("Add crate"))
  573. {
  574. items.push_back("Crate");
  575. ObjectAndTransform model;
  576. model.obj = levelModel;
  577. models.push_back(model);
  578. }
  579. ImGui::SameLine();
  580. if (ImGui::Button("Add sphere"))
  581. {
  582. items.push_back("Sphere");
  583. ObjectAndTransform model;
  584. model.obj = sphereModel;
  585. models.push_back(model);
  586. }
  587. if (ImGui::Button("Remove object") && itemCurrent < items.size() )
  588. {
  589. items.erase(items.begin() + itemCurrent);
  590. models.erase(models.begin() + itemCurrent);
  591. if(itemCurrent) itemCurrent--;
  592. }
  593. if (itemCurrent < models.size())
  594. {
  595. auto curentModel = renderer.getObjectData(models[itemCurrent].obj);
  596. int subitemsCount = curentModel->subModelsNames.size();
  597. ImGui::ListBox("Object components", &subItemCurent,
  598. curentModel->subModelsNames.data(), subitemsCount);
  599. }
  600. ImGui::NewLine();
  601. if(!models.empty() && itemCurrent < items.size())
  602. {
  603. auto curentModel = renderer.getObjectData(models[itemCurrent].obj);
  604. ImGui::NewLine();
  605. ImGui::Text("Object transform");
  606. ImGui::DragFloat3("position", &models[itemCurrent].position[0], 0.1);
  607. ImGui::DragFloat3("rotation", &models[itemCurrent].rotation[0], 0.1);
  608. ImGui::DragFloat3("scale", &models[itemCurrent].scale[0], 0.1);
  609. float s = 0;
  610. ImGui::InputFloat("sameScale", &s);
  611. if (s > 0)
  612. {
  613. models[itemCurrent].scale = glm::vec3(s);
  614. }
  615. if(subItemCurent < curentModel->models.size())
  616. {
  617. auto &material = *renderer.getMaterialData(curentModel->models[subItemCurent].material);
  618. ImGui::Text("Object material");
  619. ImGui::ColorEdit3("difuse", &material.kd[0]);
  620. ImGui::SliderFloat("roughness", &material.roughness, 0, 1);
  621. ImGui::SliderFloat("metallic", &material.metallic, 0, 1);
  622. ImGui::SliderFloat("ambient oclusion", &material.ao, 0, 1);
  623. auto drawImage = [io](const char *c, GLuint id, int w, int h)
  624. {
  625. ImGui::PushID(id);
  626. ImGui::Text(c, id);
  627. ImGui::SameLine();
  628. int my_tex_w = 20;
  629. int my_tex_h = 20;
  630. ImVec2 pos = ImGui::GetCursorScreenPos();
  631. ImVec2 uv_min = ImVec2(0.0f, 0.0f); // Top-left
  632. ImVec2 uv_max = ImVec2(1.0f, 1.0f); // Lower-right
  633. ImVec4 tint_col = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // No tint
  634. ImVec4 border_col = ImVec4(1.0f, 1.0f, 1.0f, 0.5f); // 50% opaque white
  635. ImGui::Image((void *)(id),
  636. ImVec2(my_tex_w, my_tex_h), uv_min, uv_max, tint_col, border_col);
  637. if (ImGui::IsItemHovered())
  638. {
  639. ImGui::BeginTooltip();
  640. float region_sz = 64.0f * 4;
  641. ImGui::Image((void *)(id)
  642. , ImVec2(region_sz, region_sz ));
  643. ImGui::EndTooltip();
  644. }
  645. gl3d::Texture t;
  646. t.id = id;
  647. int quality = t.getTextureQuality();
  648. //ImGui::RadioButton("leastPossible", &quality, 0);
  649. //ImGui::RadioButton("nearestMipmap", &quality, 1);
  650. //ImGui::RadioButton("linearMipmap", &quality, 2);
  651. //ImGui::RadioButton("maxQuality", &quality, 3);
  652. //if (ImGui::RadioButton("leastPossible", quality == gl3d::leastPossible)) { quality = gl3d::leastPossible; }
  653. //if (ImGui::RadioButton("nearestMipmap", quality == gl3d::nearestMipmap)) { quality = gl3d::nearestMipmap; }
  654. //if (ImGui::RadioButton("linearMipmap", quality == gl3d::linearMipmap)) { quality = gl3d::linearMipmap; }
  655. //if (ImGui::RadioButton("maxQuality", quality == gl3d::maxQuality)) { quality = gl3d::maxQuality; }
  656. static const char const *items[] =
  657. {
  658. "leastPossible",
  659. "nearestMipmap",
  660. "linearMipmap",
  661. "maxQuality",
  662. };
  663. ImGui::Combo("Texture Quality", &quality, items, 4);
  664. t.setTextureQuality(quality);
  665. ImGui::PopID();
  666. };
  667. drawImage("Object albedo, id: %d", curentModel->models[subItemCurent].albedoTexture.id, 20, 20);
  668. drawImage("Object normal map, id: %d", curentModel->models[subItemCurent].normalMapTexture.id, 20, 20);
  669. drawImage("Object RMA map, id: %d", curentModel->models[subItemCurent].RMA_Texture.id, 20, 20);
  670. }
  671. }
  672. ImGui::End();
  673. }
  674. if(showStats)
  675. {
  676. ImGui::Begin("Stats", &showStats, flags);
  677. ImGui::SetWindowFontScale(2.0f);
  678. ImGui::PlotHistogram("Fps graph", fpsArr, FPS_RECORD_ARR_SIZE, 0, 0,
  679. 0, 60);
  680. ImGui::Text("Fps %d", currnetFps);
  681. ImGui::PlotHistogram("Frame duration graph", deltaTimeArr, DELTA_TIME_ARR_SIZE, 0, 0,
  682. 0, 0.32);
  683. ImGui::Text("Frame duration (ms) %f", deltaTime * 1000);
  684. //ImGui::PlotHistogram("Render duration graph", profileeArr, Profiler_ARR_SIZE, 0, 0,
  685. //0, 0.32);
  686. //ImGui::Text("Render duration (ms) %f", lastProfilerRezult.timeSeconds * 1000);
  687. renderDurationProfilerFine.imguiPlotValues();
  688. renderDurationProfiler.imguiPlotValues();
  689. imguiRenderDuration.imguiPlotValues();
  690. swapBuffersDuration.imguiPlotValues();
  691. ImGui::End();
  692. }
  693. //ImGui::ShowDemoWindow(0);
  694. #pragma endregion
  695. #pragma region camera
  696. float speed = 4;
  697. glm::vec3 dir = {};
  698. if(GetAsyncKeyState('W'))
  699. {
  700. dir.z -= speed * deltaTime;
  701. }
  702. if (GetAsyncKeyState('S'))
  703. {
  704. dir.z += speed * deltaTime;
  705. }
  706. if (GetAsyncKeyState('A'))
  707. {
  708. dir.x -= speed * deltaTime;
  709. }
  710. if (GetAsyncKeyState('D'))
  711. {
  712. dir.x += speed * deltaTime;
  713. }
  714. if (GetAsyncKeyState('Q'))
  715. {
  716. dir.y -= speed * deltaTime;
  717. }
  718. if (GetAsyncKeyState('E'))
  719. {
  720. dir.y += speed * deltaTime;
  721. }
  722. renderer.camera.moveFPS(dir);
  723. {
  724. static glm::dvec2 lastMousePos = {};
  725. if (glfwGetMouseButton(wind, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS)
  726. {
  727. glm::dvec2 currentMousePos = {};
  728. glfwGetCursorPos(wind, &currentMousePos.x, &currentMousePos.y);
  729. float speed = 0.8f;
  730. glm::vec2 delta = lastMousePos - currentMousePos;
  731. delta *= speed * deltaTime;
  732. renderer.camera.rotateCamera(delta);
  733. lastMousePos = currentMousePos;
  734. }
  735. else
  736. {
  737. glfwGetCursorPos(wind, &lastMousePos.x, &lastMousePos.y);
  738. }
  739. }
  740. renderer.camera.aspectRatio = (float)w / h;
  741. #pragma endregion
  742. //cube.rotation.y += (glm::radians(360.f)/ 5 )* deltaTime;
  743. #pragma region light cube
  744. for(auto &i : renderer.pointLights)
  745. {
  746. lightCubeModel.position = i.position;
  747. auto projMat = renderer.camera.getProjectionMatrix();
  748. auto viewMat = renderer.camera.getWorldToViewMatrix();
  749. auto transformMat = lightCubeModel.getTransformMatrix();
  750. auto viewProjMat = projMat * viewMat * transformMat;
  751. shader.bind();
  752. glUniformMatrix4fv(location, 1, GL_FALSE, &viewProjMat[0][0]);
  753. lightCubeModel.draw();
  754. }
  755. #pragma endregion
  756. renderDurationProfiler.start();
  757. renderDurationProfilerFine.start();
  758. for (int i = 0; i < models.size(); i++)
  759. {
  760. //models[i].models[0].position = models[i].position;
  761. //models[i].models[0].scale = models[i].scale;
  762. //models[i].models[0].rotation = models[i].rotation;
  763. //todo here change the uniform
  764. //gl3d::renderLightModel(models[i], renderer.camera, lightCubeModel.position, lightShader,
  765. // renderer.skyBox.texture, gamaCorection, renderer.pointLights);
  766. renderer.renderObject(models[i].obj, models[i].position, models[i].rotation, models[i].scale);
  767. }
  768. //renderer.renderObject(objectTest, { 0,0,0 });
  769. //renderer.renderObject(objectTest2, { 3,0,0 });
  770. //lastProfilerRezult = renderDurationProfiler.end();
  771. renderDurationProfiler.end();
  772. renderDurationProfilerFine.end();
  773. //todo show normals routine
  774. //if (itemCurrent < models.size() &&
  775. // !models[itemCurrent].models.empty() && showNormals
  776. // && subItemCurent < models[itemCurrent].models.size())
  777. //{
  778. // showNormalsShader.bind();
  779. //
  780. // auto projMat = renderer.camera.getProjectionMatrix();
  781. // auto viewMat = renderer.camera.getWorldToViewMatrix();
  782. // auto transformMat = models[itemCurrent].getTransformMatrix();
  783. //
  784. // auto viewTransformMat = viewMat * transformMat;
  785. //
  786. // glUniformMatrix4fv(normalsModelTransformLocation,
  787. // 1, GL_FALSE, &viewTransformMat[0][0]);
  788. //
  789. // glUniformMatrix4fv(normalsProjectionLocation,
  790. // 1, GL_FALSE, &projMat[0][0]);
  791. //
  792. // models[itemCurrent].models[subItemCurent].draw();
  793. //
  794. //}
  795. //todo border item routine
  796. //if (itemCurrent < models.size() && borderItem &&
  797. // models[itemCurrent].models.size() > subItemCurent)
  798. //{
  799. //
  800. // glEnable(GL_STENCIL_TEST);
  801. // glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
  802. // glStencilFunc(GL_ALWAYS, 1, 0xFF);
  803. // glStencilMask(0xFF);
  804. //
  805. // auto projMat = renderer.camera.getProjectionMatrix();
  806. // auto viewMat = renderer.camera.getWorldToViewMatrix();
  807. // auto transformMat = models[0].getTransformMatrix();
  808. //
  809. // auto viewProjMat = projMat * viewMat * transformMat;
  810. //
  811. // //todo here also change the uniform
  812. // lightShader.bind(viewProjMat, transformMat,
  813. // lightCubeModel.position, renderer.camera.position, gamaCorection,
  814. // models[itemCurrent].models[subItemCurent].material, renderer.pointLights);
  815. //
  816. // glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  817. // models[itemCurrent].models[subItemCurent].draw();
  818. // glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  819. //
  820. // glDisable(GL_STENCIL_TEST);
  821. //
  822. // glEnable(GL_STENCIL_TEST);
  823. // glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
  824. // glDepthFunc(GL_ALWAYS);
  825. // glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
  826. // glStencilMask(0x00);
  827. //
  828. // auto &m = models[itemCurrent].models[subItemCurent];
  829. // projMat = renderer.camera.getProjectionMatrix();
  830. // viewMat = renderer.camera.getWorldToViewMatrix();
  831. //
  832. // auto rotation = models[itemCurrent].rotation;
  833. // auto scale = models[itemCurrent].scale;
  834. // scale *= 1.05;
  835. // auto position = models[itemCurrent].position;
  836. //
  837. //
  838. // auto s = glm::scale(scale);
  839. // auto r = glm::rotate(rotation.x, glm::vec3(1, 0, 0)) *
  840. // glm::rotate(rotation.y, glm::vec3(0, 1, 0)) *
  841. // glm::rotate(rotation.z, glm::vec3(0, 0, 1));
  842. // auto t = glm::translate(position);
  843. //
  844. // transformMat = t * r * s;
  845. //
  846. // viewProjMat = projMat * viewMat * transformMat;
  847. //
  848. // shader.bind();
  849. // glUniformMatrix4fv(location, 1, GL_FALSE, &viewProjMat[0][0]);
  850. //
  851. // glBindBuffer(GL_ARRAY_BUFFER, m.vertexBuffer);
  852. //
  853. // glEnableVertexAttribArray(0);
  854. // glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)0);
  855. // glVertexAttrib3f(1, 98 / 255.f, 24 / 255.f, 201 / 255.f);
  856. //
  857. // glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m.indexBuffer);
  858. // glDrawElements(GL_TRIANGLES, m.primitiveCount, GL_UNSIGNED_INT, 0);
  859. //
  860. // glDisable(GL_STENCIL_TEST);
  861. // glDepthFunc(GL_LESS);
  862. //}
  863. {
  864. auto projMat = renderer.camera.getProjectionMatrix();
  865. auto viewMat = renderer.camera.getWorldToViewMatrix();
  866. viewMat = glm::mat4(glm::mat3(viewMat));
  867. auto viewProjMat = projMat * viewMat;
  868. renderer.skyBox.draw(viewProjMat, gamaCorection);
  869. }
  870. #pragma region render and events
  871. imguiRenderDuration.start();
  872. ImGui::Render();
  873. int display_w, display_h;
  874. glfwGetFramebufferSize(wind, &display_w, &display_h);
  875. glViewport(0, 0, display_w, display_h);
  876. ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
  877. // Update and Render additional Platform Windows
  878. // (Platform functions may change the current OpenGL context, so we save/restore it to make it easier to paste this code elsewhere.
  879. // For this specific demo app we could also call glfwMakeContextCurrent(window) directly)
  880. if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
  881. {
  882. GLFWwindow *backup_current_context = glfwGetCurrentContext();
  883. ImGui::UpdatePlatformWindows();
  884. ImGui::RenderPlatformWindowsDefault();
  885. glfwMakeContextCurrent(backup_current_context);
  886. }
  887. imguiRenderDuration.end();
  888. swapBuffersDuration.start();
  889. glViewport(0, 0, w, h);
  890. glfwSwapBuffers(wind);
  891. glfwPollEvents();
  892. swapBuffersDuration.end();
  893. #pragma endregion
  894. }
  895. return 0;
  896. }