gl3d.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805
  1. ////////////////////////////////////////////////
  2. //gl32 --Vlad Luta --
  3. //built on 2021-04-26
  4. ////////////////////////////////////////////////
  5. ////////////////////////////////////////////////
  6. //Core.h
  7. ////////////////////////////////////////////////
  8. #pragma region Core
  9. #pragma once
  10. #include <glm\vec4.hpp>
  11. #include <glm\vec3.hpp>
  12. #include <GL\glew.h>
  13. #include <iostream>
  14. namespace gl3d
  15. {
  16. inline void clearglErrors()
  17. {
  18. GLenum errorCode;
  19. while ((errorCode = glGetError()) != GL_NO_ERROR) {}
  20. }
  21. //https://learnopengl.com/In-Practice/Debugging
  22. inline GLenum checkglError(const char *file, int line, const char *command = "")
  23. {
  24. GLenum errorCode;
  25. while ((errorCode = glGetError()) != GL_NO_ERROR)
  26. {
  27. const char* error = "";
  28. switch (errorCode)
  29. {
  30. case GL_INVALID_ENUM: error = "INVALID_ENUM"; break;
  31. case GL_INVALID_VALUE: error = "INVALID_VALUE"; break;
  32. case GL_INVALID_OPERATION: error = "INVALID_OPERATION"; break;
  33. case GL_STACK_OVERFLOW: error = "STACK_OVERFLOW"; break;
  34. case GL_STACK_UNDERFLOW: error = "STACK_UNDERFLOW"; break;
  35. case GL_OUT_OF_MEMORY: error = "OUT_OF_MEMORY"; break;
  36. case GL_INVALID_FRAMEBUFFER_OPERATION: error = "INVALID_FRAMEBUFFER_OPERATION"; break;
  37. }
  38. std::cout << error << " | " << file << " (" << line << ")" << " " << command << std::endl;
  39. }
  40. return errorCode;
  41. }
  42. #define glCheck(x) clearglErrors(); x; checkglError(__FILE__, __LINE__, #x);
  43. #define glAnyCheck() checkglError(__FILE__, __LINE__);
  44. template <class T>
  45. struct InterfaceCheckId
  46. {
  47. bool isNotNull()
  48. {
  49. return static_cast<T*>(this)->id_;
  50. }
  51. bool isNull()
  52. {
  53. return !this->isNotNull();
  54. }
  55. };
  56. struct Material : public InterfaceCheckId< Material >
  57. {
  58. int id_ = {};
  59. Material(int id = 0):id_(id) {};
  60. };
  61. struct Object : public InterfaceCheckId< Object >
  62. {
  63. int id_ = {};
  64. Object(int id = 0):id_(id) {};
  65. };
  66. struct Model: public InterfaceCheckId< Model >
  67. {
  68. int id_ = {};
  69. Model(int id = 0):id_(id) {};
  70. };
  71. struct Texture : public InterfaceCheckId< Texture >
  72. {
  73. int id_ = {};
  74. Texture(int id = 0):id_(id) {};
  75. };
  76. struct TextureDataForModel
  77. {
  78. Texture albedoTexture = {};
  79. Texture normalMapTexture = {};
  80. Texture RMA_Texture = {}; //rough metalness ambient oclusion
  81. int RMA_loadedTextures = {};
  82. };
  83. struct GpuMaterial
  84. {
  85. glm::vec4 kd = glm::vec4(1);; //= 0.45;//w component not used
  86. float roughness = 0.5f;
  87. float metallic = 0.1;
  88. float ao = 1;
  89. float notUsed;
  90. GpuMaterial setDefaultMaterial()
  91. {
  92. *this = GpuMaterial();
  93. return *this;
  94. }
  95. };
  96. //todo move
  97. namespace internal
  98. {
  99. //todo move
  100. struct GpuPointLight
  101. {
  102. glm::vec4 position = {};
  103. glm::vec4 color = { 1,1,1,0 };
  104. };
  105. };
  106. void assertFunc(const char *expression,
  107. const char *file_name,
  108. unsigned const line_number,
  109. const char *comment = "---");
  110. };
  111. #define gl3dAssert(expression) (void)( \
  112. (!!(expression)) || \
  113. (gl3d::assertFunc(#expression, __FILE__, (unsigned)(__LINE__)), 0) \
  114. )
  115. #define gl3dAssertComment(expression, comment) (void)( \
  116. (!!(expression)) || \
  117. (gl3d::assertFunc(#expression, __FILE__, (unsigned)(__LINE__)), comment)\
  118. )
  119. #pragma endregion
  120. ////////////////////////////////////////////////
  121. //Texture.h
  122. ////////////////////////////////////////////////
  123. #pragma region Texture
  124. #pragma once
  125. #include <GL/glew.h>
  126. namespace gl3d
  127. {
  128. enum TextureLoadQuality
  129. {
  130. leastPossible = 0,
  131. nearestMipmap,
  132. linearMipmap,
  133. maxQuality
  134. };
  135. struct GpuTexture
  136. {
  137. GLuint id = 0;
  138. GpuTexture() = default;
  139. GpuTexture(const char *file) { loadTextureFromFile(file); };
  140. void loadTextureFromFile(const char *file, int quality = maxQuality);
  141. void loadTextureFromMemory(void *data, int w, int h, int chanels = 4, int quality = maxQuality);
  142. void clear();
  143. void setTextureQuality(int quality);
  144. int getTextureQuality();
  145. };
  146. void gausianBlurRGB(unsigned char *data, int w, int h, int kernel);
  147. };
  148. #pragma endregion
  149. ////////////////////////////////////////////////
  150. //Shader.h
  151. ////////////////////////////////////////////////
  152. #pragma region Shader
  153. #pragma once
  154. #include "GL/glew.h"
  155. #include <glm\mat4x4.hpp>
  156. #include <Core.h>
  157. #include <vector>
  158. namespace gl3d
  159. {
  160. struct Shader
  161. {
  162. GLuint id = 0;
  163. bool loadShaderProgramFromFile(const char *vertexShader, const char *fragmentShader);
  164. bool loadShaderProgramFromFile(const char *vertexShader,
  165. const char *geometryShader, const char *fragmentShader);
  166. void bind();
  167. void clear();
  168. };
  169. GLint getUniform(GLuint id, const char *name);
  170. //todo this will probably dissapear
  171. struct LightShader
  172. {
  173. void create();
  174. void bind(const glm::mat4 &viewProjMat, const glm::mat4 &transformMat,
  175. const glm::vec3 &lightPosition, const glm::vec3 &eyePosition, float gama
  176. , const GpuMaterial &material, std::vector<internal::GpuPointLight> &pointLights);
  177. void setData(const glm::mat4 &viewProjMat, const glm::mat4 &transformMat,
  178. const glm::vec3 &lightPosition, const glm::vec3 &eyePosition, float gama
  179. , const GpuMaterial &material, std::vector<internal::GpuPointLight> &pointLights);
  180. void setMaterial(const GpuMaterial &material);
  181. void getSubroutines();
  182. GLuint quadBuffer = 0;
  183. GLuint quadVAO = 0;
  184. GLint u_transform = -1;
  185. GLint u_modelTransform = -1;
  186. GLint u_motelViewTransform = -1;
  187. GLint normalShaderLightposLocation = -1;
  188. GLint textureSamplerLocation = -1;
  189. GLint normalMapSamplerLocation = -1;
  190. GLint eyePositionLocation = -1;
  191. GLint skyBoxSamplerLocation = -1;
  192. GLint gamaLocation = -1;
  193. GLint RMASamplerLocation = -1;
  194. GLint pointLightCountLocation = -1;
  195. GLint pointLightBufferLocation = -1;
  196. GLint materialIndexLocation = -1;
  197. GLint light_u_albedo = -1;
  198. GLint light_u_normals = -1;
  199. GLint light_u_skybox = -1;
  200. GLint light_u_positions = -1;
  201. GLint light_u_materials = -1;
  202. GLint light_u_eyePosition = -1;
  203. GLint light_u_pointLightCount = -1;
  204. GLint light_u_ssao = -1;
  205. GLint light_u_view = -1;
  206. GLint u_useSSAO = -1;
  207. GLuint materialBlockLocation = GL_INVALID_INDEX;
  208. GLuint materialBlockBuffer = 0;
  209. GLuint pointLightsBlockLocation = GL_INVALID_INDEX;
  210. GLuint pointLightsBlockBuffer = 0;
  211. GLint normalSubroutineLocation = -1;
  212. GLint materialSubroutineLocation = -1;
  213. GLint getAlbedoSubroutineLocation = -1;
  214. GLuint normalSubroutine_noMap = GL_INVALID_INDEX;
  215. GLuint normalSubroutine_normalMap = GL_INVALID_INDEX;
  216. GLuint albedoSubroutine_sampled = GL_INVALID_INDEX;
  217. GLuint albedoSubroutine_notSampled = GL_INVALID_INDEX;
  218. GLuint materialSubroutine_functions[8] = {
  219. GL_INVALID_INDEX, GL_INVALID_INDEX, GL_INVALID_INDEX, GL_INVALID_INDEX,
  220. GL_INVALID_INDEX, GL_INVALID_INDEX, GL_INVALID_INDEX, GL_INVALID_INDEX,
  221. };
  222. Shader geometryPassShader;
  223. Shader lightingPassShader;
  224. bool normalMap = 1;
  225. bool useSSAO = 1;
  226. bool bloom = 1;
  227. //todo clear
  228. };
  229. };
  230. #pragma endregion
  231. ////////////////////////////////////////////////
  232. //Camera.h
  233. ////////////////////////////////////////////////
  234. #pragma region Camera
  235. #pragma once
  236. #include <glm/vec3.hpp>
  237. #include <glm/vec4.hpp>
  238. #include <glm/mat4x4.hpp>
  239. #include <glm/trigonometric.hpp>
  240. #include <cmath>
  241. namespace gl3d
  242. {
  243. constexpr float PI = 3.1415926535897932384626433;
  244. struct Camera
  245. {
  246. Camera() = default;
  247. Camera(float aspectRatio, float fovRadians)
  248. :aspectRatio(aspectRatio),
  249. fovRadians(fovRadians)
  250. {}
  251. glm::vec3 up = { 0.f,1.f,0.f };
  252. float aspectRatio = 1;
  253. float fovRadians = glm::radians(100.f);
  254. float closePlane = 0.01f;
  255. float farPlane = 100.f;
  256. glm::vec3 position = {};
  257. glm::vec3 viewDirection = {0,0,-1};
  258. glm::mat4x4 getProjectionMatrix();
  259. glm::mat4x4 getWorldToViewMatrix();
  260. void rotateCamera(const glm::vec2 delta);
  261. void moveFPS(glm::vec3 direction);
  262. };
  263. };
  264. #pragma endregion
  265. ////////////////////////////////////////////////
  266. //GraphicModel.h
  267. ////////////////////////////////////////////////
  268. #pragma region GraphicModel
  269. #pragma once
  270. #include "GL/glew.h"
  271. #include <glm/vec3.hpp>
  272. #include <glm/gtc/quaternion.hpp>
  273. #include <glm/gtc/matrix_transform.hpp>
  274. #include <glm/gtx/transform.hpp>
  275. #include "OBJ_Loader.h"
  276. #include "Shader.h"
  277. #include "Texture.h"
  278. #include "Core.h"
  279. namespace gl3d
  280. {
  281. glm::mat4 getTransformMatrix(glm::vec3 position, glm::vec3 rotation, glm::vec3 scale);
  282. struct LoadedModelData
  283. {
  284. LoadedModelData() = default;
  285. LoadedModelData(const char *file, float scale = 1.f) { load(file, scale); }
  286. void load(const char *file, float scale = 1.f);
  287. objl::Loader loader;
  288. std::string path;
  289. };
  290. //todo this will dissapear and become an struct of arrays or sthing
  291. struct GraphicModel
  292. {
  293. std::string name = {};
  294. //todo this might disapear
  295. GLuint vertexArray = 0;
  296. GLuint vertexBuffer = 0;
  297. GLuint indexBuffer = 0;
  298. GLsizei primitiveCount = 0;
  299. //todo check if indexes can be uint
  300. void loadFromComputedData(size_t vertexSize, const float * vercies, size_t indexSize = 0, const unsigned int * indexes = nullptr, bool noTexture = false);
  301. //deprecated
  302. void loadFromData(size_t vertexCount, float *vertices, float *normals, float *textureUV,
  303. size_t indexesCount = 0, unsigned int *indexes = nullptr);
  304. void loadFromModelMeshIndex(const LoadedModelData &model, int index);
  305. void loadFromModelMesh(const LoadedModelData &model);
  306. //deprecated
  307. void loadFromFile(const char *fileName);
  308. void clear();
  309. void draw();
  310. //todo probably move this in the final version
  311. glm::vec3 position = {};
  312. glm::vec3 rotation = {};
  313. glm::vec3 scale = {1,1,1};
  314. glm::mat4 getTransformMatrix();
  315. //todo probably teporarily add this things
  316. GpuTexture albedoTexture;
  317. GpuTexture normalMapTexture;
  318. GpuTexture RMA_Texture; //rough metalness ambient oclusion
  319. int RMA_loadedTextures;
  320. GpuMaterial material;
  321. };
  322. //todo this will defenetly dissapear it is just for qucik render
  323. struct MultipleGraphicModels
  324. {
  325. std::vector < GraphicModel >models;
  326. std::vector < char *> subModelsNames;
  327. void loadFromModel(const LoadedModelData &model);
  328. void clear();
  329. glm::vec3 position = {};
  330. glm::vec3 rotation = {};
  331. glm::vec3 scale = { 1,1,1 };
  332. glm::mat4 getTransformMatrix()
  333. {
  334. return gl3d::getTransformMatrix(position, rotation, scale);
  335. }
  336. };
  337. struct GpuGraphicModel
  338. {
  339. std::string name;
  340. GLuint vertexArray = 0;
  341. GLuint vertexBuffer = 0;
  342. GLuint indexBuffer = 0;
  343. GLsizei primitiveCount = 0;
  344. void loadFromComputedData(size_t vertexSize, const float *vercies, size_t indexSize = 0,
  345. const unsigned int *indexes = nullptr, bool noTexture = false);
  346. void clear();
  347. //todo probably teporarily add this things
  348. //Texture albedoTexture;
  349. //Texture normalMapTexture;
  350. //Texture RMA_Texture; //rough metalness ambient oclusion
  351. //int RMA_loadedTextures;
  352. Material material;
  353. };
  354. struct GpuMultipleGraphicModel
  355. {
  356. std::vector < GpuGraphicModel >models;
  357. std::vector < char* > subModelsNames;
  358. void clear();
  359. };
  360. struct LoadedTextures
  361. {
  362. std::string name;
  363. GpuTexture t;
  364. };
  365. struct SkyBox
  366. {
  367. GLuint vertexArray = 0;
  368. GLuint vertexBuffer = 0;
  369. void createGpuData();
  370. void loadTexture(const char *names[6]);
  371. void loadTexture(const char *name, int format = 0); //todo add enum, also it is not working yer
  372. void clearGpuData();
  373. void draw(const glm::mat4 &viewProjMat, float gama);
  374. void bindCubeMap();
  375. Shader shader;
  376. GLuint texture;
  377. GLuint samplerUniformLocation;
  378. GLuint modelViewUniformLocation;
  379. GLuint gamaUniformLocation;
  380. };
  381. /*
  382. "right.jpg",
  383. "left.jpg",
  384. "top.jpg",
  385. "bottom.jpg",
  386. "front.jpg",
  387. "back.jpg"
  388. */
  389. };;;
  390. #pragma endregion
  391. ////////////////////////////////////////////////
  392. //gl3d.h
  393. ////////////////////////////////////////////////
  394. #pragma region gl3d
  395. #pragma once
  396. #include <Core.h>
  397. #include <Texture.h>
  398. #include <Shader.h>
  399. #include <Camera.h>
  400. #include <GraphicModel.h>
  401. #include <algorithm>
  402. namespace gl3d
  403. {
  404. namespace internal
  405. {
  406. template <class T>
  407. int generateNewIndex(T indexesVec)
  408. {
  409. int id = 0;
  410. auto indexesCopy = indexesVec;
  411. std::sort(indexesCopy.begin(), indexesCopy.end());
  412. if (indexesCopy.empty())
  413. {
  414. id = 1;
  415. }
  416. else
  417. {
  418. id = 1;
  419. for (int i = 0; i < indexesCopy.size(); i++)
  420. {
  421. if (indexesCopy[i] != id)
  422. {
  423. break;
  424. }
  425. else
  426. {
  427. id++;
  428. }
  429. }
  430. }
  431. return id;
  432. };
  433. };
  434. struct Renderer3D
  435. {
  436. void init(int x, int y);
  437. #pragma region material
  438. std::vector<GpuMaterial> materials;
  439. std::vector<int> materialIndexes;
  440. std::vector<std::string> materialNames;
  441. std::vector<TextureDataForModel> materialTexturesData;
  442. //todo add texture data function
  443. Material createMaterial(glm::vec3 kd = glm::vec3(1),
  444. float roughness = 0.5f, float metallic = 0.1, float ao = 1, std::string name = "");
  445. Material createMaterial(Material m);
  446. Material loadMaterial(std::string file);
  447. void deleteMaterial(Material m);
  448. void copyMaterialData(Material dest, Material source);
  449. //returns 0 if not found
  450. GpuMaterial *getMaterialData(Material m);
  451. std::string *getMaterialName(Material m);
  452. //probably move this to internal
  453. TextureDataForModel *getMaterialTextures(Material m);
  454. bool getMaterialData(Material m, GpuMaterial *gpuMaterial,
  455. std::string *name, TextureDataForModel *textureData);
  456. //returns true if succeded
  457. bool setMaterialData(Material m, const GpuMaterial &data, std::string *s = nullptr);
  458. GpuMultipleGraphicModel *getObjectData(Object o);
  459. #pragma endregion
  460. #pragma region Texture
  461. std::vector <GpuTexture> loadedTextures;
  462. std::vector<int> loadedTexturesIndexes;
  463. std::vector<std::string> loadedTexturesNames;
  464. GpuTexture defaultTexture;
  465. Texture loadTexture(std::string path, bool defaultToDefaultTexture = true);
  466. GLuint getTextureOpenglId(Texture t);
  467. void deleteTexture(Texture t);
  468. GpuTexture *getTextureData(Texture t);
  469. //internal
  470. Texture createIntenralTexture(GpuTexture t);
  471. #pragma endregion
  472. struct VAO
  473. {
  474. GLuint posNormalTexture;
  475. void createVAOs();
  476. }vao;
  477. std::vector< GpuMultipleGraphicModel > graphicModels;
  478. std::vector<int> graphicModelsIndexes;
  479. Object loadObject(std::string path, float scale = 1);
  480. void deleteObject(Object o);
  481. LightShader lightShader;
  482. Camera camera;
  483. SkyBox skyBox;
  484. std::vector<gl3d::internal::GpuPointLight> pointLights;
  485. void renderObject(Object o, glm::vec3 position, glm::vec3 rotation = {}, glm::vec3 scale = {1,1,1});
  486. void renderObjectNormals(Object o, glm::vec3 position, glm::vec3 rotation = {},
  487. glm::vec3 scale = { 1,1,1 }, float normalSize = 0.5, glm::vec3 normalColor = {0.7, 0.7, 0.1});
  488. void renderSubObjectNormals(Object o, int index, glm::vec3 position, glm::vec3 rotation = {},
  489. glm::vec3 scale = { 1,1,1 }, float normalSize = 0.5, glm::vec3 normalColor = { 0.7, 0.7, 0.1 });
  490. void renderSubObjectBorder(Object o, int index, glm::vec3 position, glm::vec3 rotation = {},
  491. glm::vec3 scale = { 1,1,1 }, float borderSize = 0.5, glm::vec3 borderColor = { 0.7, 0.7, 0.1 });
  492. //internal //todo add internal namespace
  493. int getMaterialIndex(Material m);
  494. int getObjectIndex(Object o);
  495. int getTextureIndex(Texture t);
  496. struct
  497. {
  498. Shader shader;
  499. GLint modelTransformLocation;
  500. GLint projectionLocation;
  501. GLint sizeLocation;
  502. GLint colorLocation;
  503. }showNormalsProgram;
  504. struct
  505. {
  506. enum bufferTargers
  507. {
  508. position = 0,
  509. normal,
  510. albedo,
  511. material,
  512. positionViewSpace,
  513. bufferCount,
  514. };
  515. unsigned int gBuffer;
  516. unsigned int buffers[bufferCount];
  517. unsigned int depthBuffer;
  518. }gBuffer;
  519. struct PostProcess
  520. {
  521. Shader postProcessShader;
  522. Shader gausianBLurShader;
  523. GLint u_colorTexture;
  524. GLint u_bloomTexture;
  525. GLint u_toBlurcolorInput;
  526. GLint u_horizontal;
  527. GLuint fbo;
  528. GLuint blurFbo[2];
  529. GLuint colorBuffers[2]; // 0 for color, 1 for bloom
  530. GLuint bluredColorBuffer[2];
  531. void create(int w, int h);
  532. }postProcess;
  533. struct SSAO
  534. {
  535. //https://learnopengl.com/Advanced-Lighting/SSAO
  536. void create(int w, int h);
  537. GLuint noiseTexture;
  538. GLuint ssaoFBO;
  539. GLuint ssaoColorBuffer;
  540. Shader shader;
  541. GLint u_projection = -1;
  542. GLint u_view = -1;
  543. GLint u_gPosition = -1;
  544. GLint u_gNormal = -1;
  545. GLint u_texNoise = -1;
  546. GLint u_samples = -1;
  547. std::vector<glm::vec3> ssaoKernel;
  548. GLuint blurBuffer;
  549. GLuint blurColorBuffer;
  550. GLint u_ssaoInput;
  551. Shader blurShader;
  552. }ssao;
  553. void render();
  554. void updateWindowMetrics(int x, int y);
  555. int w; int h;
  556. };
  557. void renderLightModel(GraphicModel &model, Camera camera, glm::vec3 lightPos, LightShader lightShader,
  558. GpuTexture texture, GpuTexture normalTexture, GLuint skyBoxTexture, float gama,
  559. const GpuMaterial &material, std::vector<internal::GpuPointLight> &pointLights);
  560. void renderLightModel(MultipleGraphicModels &model, Camera camera, glm::vec3 lightPos, LightShader lightShader,
  561. GLuint skyBoxTexture, float gama, std::vector<internal::GpuPointLight> &pointLights);
  562. };
  563. #pragma endregion