2
0

gl3d.cpp 83 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314
  1. ////////////////////////////////////////////////
  2. //gl32 --Vlad Luta --
  3. //built on 2021-04-26
  4. ////////////////////////////////////////////////
  5. #include "gl3d.h"
  6. ////////////////////////////////////////////////
  7. //Core.cpp
  8. ////////////////////////////////////////////////
  9. #pragma region Core
  10. #include <stdio.h>
  11. #include <Windows.h>
  12. #include <signal.h>
  13. namespace gl3d
  14. {
  15. void assertFunc(const char *expression,
  16. const char *file_name,
  17. unsigned const line_number,
  18. const char *comment)
  19. {
  20. char c[1024] = {};
  21. sprintf(c,
  22. "Assertion failed\n\n"
  23. "File:\n"
  24. "%s\n\n"
  25. "Line:\n"
  26. "%u\n\n"
  27. "Expresion:\n"
  28. "%s\n\n"
  29. "Comment:\n"
  30. "%s",
  31. file_name,
  32. line_number,
  33. expression,
  34. comment
  35. );
  36. int const action = MessageBox(0, c, "Platform Layer", MB_TASKMODAL
  37. | MB_ICONHAND | MB_ABORTRETRYIGNORE | MB_SETFOREGROUND);
  38. switch (action)
  39. {
  40. case IDABORT: // Abort the program:
  41. {
  42. raise(SIGABRT);
  43. // We won't usually get here, but it's possible that a user-registered
  44. // abort handler returns, so exit the program immediately. Note that
  45. // even though we are "aborting," we do not call abort() because we do
  46. // not want to invoke Watson (the user has already had an opportunity
  47. // to debug the error and chose not to).
  48. _exit(3);
  49. }
  50. case IDRETRY: // Break into the debugger then return control to caller
  51. {
  52. __debugbreak();
  53. return;
  54. }
  55. case IDIGNORE: // Return control to caller
  56. {
  57. return;
  58. }
  59. default: // This should not happen; treat as fatal error:
  60. {
  61. abort();
  62. }
  63. }
  64. }
  65. };
  66. #pragma endregion
  67. ////////////////////////////////////////////////
  68. //Texture.cpp
  69. ////////////////////////////////////////////////
  70. #pragma region Texture
  71. #include <stb_image.h>
  72. #include <iostream>
  73. #include <glm\vec3.hpp>
  74. #include <algorithm>
  75. namespace gl3d
  76. {
  77. void GpuTexture::loadTextureFromFile(const char *file, int quality)
  78. {
  79. int w, h, nrChannels;
  80. stbi_set_flip_vertically_on_load(true);
  81. unsigned char *data = stbi_load(file, &w, &h, &nrChannels, 4);
  82. if (!data)
  83. {
  84. //todo err messages
  85. std::cout << "err: " << file << "\n";
  86. id = 0;
  87. }
  88. else
  89. {
  90. loadTextureFromMemory(data, w, h, 4, quality);
  91. stbi_image_free(data);
  92. }
  93. }
  94. //todo add srgb
  95. //todo add quality enum
  96. void GpuTexture::loadTextureFromMemory(void *data, int w, int h, int chanels,
  97. int quality)
  98. {
  99. GLenum format = GL_RGBA;
  100. if(chanels == 3)
  101. {
  102. format = GL_RGB;
  103. }
  104. gl3dAssertComment(chanels == 3 || chanels == 4, "invalid chanel number");
  105. glGenTextures(1, &id);
  106. glBindTexture(GL_TEXTURE_2D, id);
  107. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, format, GL_UNSIGNED_BYTE, data);
  108. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  109. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  110. setTextureQuality(quality);
  111. glGenerateMipmap(GL_TEXTURE_2D);
  112. }
  113. void GpuTexture::clear()
  114. {
  115. glDeleteTextures(1, &id);
  116. id = 0;
  117. }
  118. void GpuTexture::setTextureQuality(int quality)
  119. {
  120. if (!id)
  121. return;
  122. glBindTexture(GL_TEXTURE_2D, id);
  123. switch (quality)
  124. {
  125. case leastPossible:
  126. {
  127. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  128. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  129. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY, 1);
  130. glAnyCheck();
  131. }
  132. break;
  133. case nearestMipmap:
  134. {
  135. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
  136. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  137. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY, 1);
  138. }
  139. break;
  140. case linearMipmap:
  141. {
  142. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
  143. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  144. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY, 4);
  145. }
  146. break;
  147. case maxQuality:
  148. {
  149. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  150. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  151. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY, 4);
  152. }
  153. break;
  154. default:
  155. gl3dAssertComment(0, "invalid quality");
  156. break;
  157. }
  158. }
  159. int GpuTexture::getTextureQuality()
  160. {
  161. if(id == leastPossible)
  162. {
  163. return 0;
  164. }
  165. glBindTexture(GL_TEXTURE_2D, id);
  166. int param = 0;
  167. glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, &param);
  168. switch (param)
  169. {
  170. case GL_NEAREST:
  171. {
  172. return leastPossible;
  173. }
  174. break;
  175. case GL_NEAREST_MIPMAP_NEAREST:
  176. {
  177. return nearestMipmap;
  178. }
  179. break;
  180. case GL_LINEAR_MIPMAP_NEAREST:
  181. {
  182. return linearMipmap;
  183. }
  184. break;
  185. case GL_LINEAR_MIPMAP_LINEAR:
  186. {
  187. return maxQuality;
  188. }
  189. break;
  190. }
  191. return leastPossible;
  192. }
  193. void gausianBlurRGB(unsigned char *data, int w, int h, int kernel)
  194. {
  195. unsigned char *newImage = new unsigned char[w * h * 3];
  196. //todo refactor refactor refactor
  197. //todo actually compute this on the gpu
  198. auto horiz = [&](int kernel)
  199. {
  200. //horizontal blur
  201. for (int y = 0; y < h; y++)
  202. {
  203. for (int x = 0; x < w; x++)
  204. {
  205. glm::tvec3<int> colors = {};
  206. int beg = std::max(0, x - kernel);
  207. int end = std::min(x + kernel + 1, w);
  208. for (int i = beg; i < end; i++)
  209. {
  210. colors.r += data[(i + y * w) * 3 + 0];
  211. colors.g += data[(i + y * w) * 3 + 1];
  212. colors.b += data[(i + y * w) * 3 + 2];
  213. }
  214. if (x - kernel < 0)
  215. for (int i = kernel - x - 1; i >= 0; i--)
  216. {
  217. colors.r += data[(i + y * w) * 3 + 0];
  218. colors.g += data[(i + y * w) * 3 + 1];
  219. colors.b += data[(i + y * w) * 3 + 2];
  220. }
  221. if (x + kernel >= w)
  222. for (int i = w - 1; i >= w - (x + kernel - w + 1); i--)
  223. {
  224. colors.r += data[(i + y * w) * 3 + 0];
  225. colors.g += data[(i + y * w) * 3 + 1];
  226. colors.b += data[(i + y * w) * 3 + 2];
  227. }
  228. colors /= kernel * 2 + 1;
  229. //colors /= end - beg;
  230. newImage[(x + y * w) * 3 + 0] = colors.r;
  231. newImage[(x + y * w) * 3 + 1] = colors.g;
  232. newImage[(x + y * w) * 3 + 2] = colors.b;
  233. }
  234. }
  235. };
  236. auto vert = [&](int kernel)
  237. {
  238. //vertical blur
  239. for (int x = 0; x < w; x++)
  240. {
  241. for (int y = 0; y < h; y++)
  242. {
  243. glm::tvec3<int> colors = {};
  244. int beg = std::max(0, y - kernel);
  245. int end = std::min(y + kernel + 1, h);
  246. for (int j = beg; j < end; j++)
  247. {
  248. colors.r += data[(x + j * w) * 3 + 0];
  249. colors.g += data[(x + j * w) * 3 + 1];
  250. colors.b += data[(x + j * w) * 3 + 2];
  251. }
  252. if (y - kernel < 0)
  253. for (int j = kernel - y - 1; j >= 0; j--)
  254. {
  255. colors.r += data[(x + j * w) * 3 + 0];
  256. colors.g += data[(x + j * w) * 3 + 1];
  257. colors.b += data[(x + j * w) * 3 + 2];
  258. }
  259. if (y + kernel >= h)
  260. for (int j = h - 1; j >= h - (y + kernel - h + 1); j--)
  261. {
  262. colors.r += data[(x + j * w) * 3 + 0];
  263. colors.g += data[(x + j * w) * 3 + 1];
  264. colors.b += data[(x + j * w) * 3 + 2];
  265. }
  266. colors /= kernel * 2 + 1;
  267. //colors /= end - beg;
  268. newImage[(x + y * w) * 3 + 0] = colors.r;
  269. newImage[(x + y * w) * 3 + 1] = colors.g;
  270. newImage[(x + y * w) * 3 + 2] = colors.b;
  271. }
  272. }
  273. };
  274. int iterations = 2;
  275. for(int i=0;i<iterations;i++)
  276. {
  277. horiz(kernel);
  278. vert(kernel);
  279. }
  280. for (int i = 0; i < w * h * 3; i++)
  281. {
  282. data[i] = newImage[i];
  283. }
  284. delete newImage;
  285. }
  286. };
  287. #pragma endregion
  288. ////////////////////////////////////////////////
  289. //Shader.cpp
  290. ////////////////////////////////////////////////
  291. #pragma region Shader
  292. #include <fstream>
  293. #include <iostream>
  294. namespace gl3d
  295. {
  296. GLint createShaderFromFile(const char *source, GLenum shaderType)
  297. {
  298. std::ifstream file;
  299. file.open(source);
  300. if (!file.is_open())
  301. {
  302. std::cout << "Error openning file: " << source << "\n";
  303. return 0;
  304. }
  305. GLint size = 0;
  306. file.seekg(0, file.end);
  307. size = file.tellg();
  308. file.seekg(0, file.beg);
  309. char *fileContent = new char[size] {};
  310. file.read(fileContent, size);
  311. file.close();
  312. GLuint shaderId = glCreateShader(shaderType);
  313. glShaderSource(shaderId, 1, &fileContent, &size);
  314. glCompileShader(shaderId);
  315. delete[] fileContent;
  316. GLint rezult = 0;
  317. glGetShaderiv(shaderId, GL_COMPILE_STATUS, &rezult);
  318. if (!rezult)
  319. {
  320. char *message = 0;
  321. int l = 0;
  322. glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &l);
  323. if(l)
  324. {
  325. message = new char[l];
  326. glGetShaderInfoLog(shaderId, l, &l, message);
  327. message[l - 1] = 0;
  328. std::cout << source << ": " << message << "\n";
  329. delete[] message;
  330. }else
  331. {
  332. std::cout << source << ": " << "unknown error"<< "\n";
  333. }
  334. glDeleteShader(shaderId);
  335. shaderId = 0;
  336. return shaderId;
  337. }
  338. return shaderId;
  339. }
  340. bool Shader::loadShaderProgramFromFile(const char *vertexShader, const char *fragmentShader)
  341. {
  342. auto vertexId = createShaderFromFile(vertexShader, GL_VERTEX_SHADER);
  343. auto fragmentId = createShaderFromFile(fragmentShader, GL_FRAGMENT_SHADER);
  344. if (vertexId == 0 || fragmentId == 0)
  345. {
  346. return 0;
  347. }
  348. id = glCreateProgram();
  349. glAttachShader(id, vertexId);
  350. glAttachShader(id, fragmentId);
  351. glLinkProgram(id);
  352. glDeleteShader(vertexId);
  353. glDeleteShader(fragmentId);
  354. GLint info = 0;
  355. glGetProgramiv(id, GL_LINK_STATUS, &info);
  356. if (info != GL_TRUE)
  357. {
  358. char *message = 0;
  359. int l = 0;
  360. glGetProgramiv(id, GL_INFO_LOG_LENGTH, &l);
  361. message = new char[l];
  362. glGetProgramInfoLog(id, l, &l, message);
  363. std::cout << "Link error: " << message << "\n";
  364. delete[] message;
  365. glDeleteProgram(id);
  366. id = 0;
  367. return 0;
  368. }
  369. glValidateProgram(id);
  370. return true;
  371. }
  372. bool Shader::loadShaderProgramFromFile(const char *vertexShader, const char *geometryShader, const char *fragmentShader)
  373. {
  374. auto vertexId = createShaderFromFile(vertexShader, GL_VERTEX_SHADER);
  375. auto geometryId = createShaderFromFile(geometryShader, GL_GEOMETRY_SHADER);
  376. auto fragmentId = createShaderFromFile(fragmentShader, GL_FRAGMENT_SHADER);
  377. if (vertexId == 0 || fragmentId == 0 || geometryId == 0)
  378. {
  379. return 0;
  380. }
  381. id = glCreateProgram();
  382. glAttachShader(id, vertexId);
  383. glAttachShader(id, geometryId);
  384. glAttachShader(id, fragmentId);
  385. glLinkProgram(id);
  386. glDeleteShader(vertexId);
  387. glDeleteShader(geometryId);
  388. glDeleteShader(fragmentId);
  389. GLint info = 0;
  390. glGetProgramiv(id, GL_LINK_STATUS, &info);
  391. if (info != GL_TRUE)
  392. {
  393. char *message = 0;
  394. int l = 0;
  395. glGetProgramiv(id, GL_INFO_LOG_LENGTH, &l);
  396. message = new char[l];
  397. glGetProgramInfoLog(id, l, &l, message);
  398. std::cout << "Link error: " << message << "\n";
  399. delete[] message;
  400. glDeleteProgram(id);
  401. id = 0;
  402. return 0;
  403. }
  404. glValidateProgram(id);
  405. return true;
  406. }
  407. void Shader::bind()
  408. {
  409. glUseProgram(id);
  410. }
  411. void Shader::clear()
  412. {
  413. glDeleteProgram(id);
  414. id = 0;
  415. }
  416. GLint getUniformSubroutine(GLuint id, GLenum shaderType, const char *name)
  417. {
  418. GLint uniform = glGetSubroutineUniformLocation(id, shaderType, name);
  419. if (uniform == -1)
  420. {
  421. std::cout << "uniform subroutine error " << name << "\n";
  422. }
  423. return uniform;
  424. };
  425. GLint getUniform(GLuint id, const char *name)
  426. {
  427. GLint uniform = glGetUniformLocation(id, name);
  428. if (uniform == -1)
  429. {
  430. std::cout << "uniform error " << name << "\n";
  431. }
  432. return uniform;
  433. };
  434. GLuint getUniformBlock(GLuint id, const char *name)
  435. {
  436. GLuint uniform = glGetUniformBlockIndex(id, name);
  437. if (uniform == GL_INVALID_INDEX)
  438. {
  439. std::cout << "uniform block error " << name << "\n";
  440. }
  441. return uniform;
  442. };
  443. GLuint getUniformSubroutineIndex(GLuint id, GLenum shaderType, const char *name)
  444. {
  445. GLuint uniform = glGetSubroutineIndex(id, shaderType, name);
  446. if (uniform == GL_INVALID_INDEX)
  447. {
  448. std::cout << "uniform subroutine index error " << name << "\n";
  449. }
  450. return uniform;
  451. };
  452. GLuint getStorageBlockIndex(GLuint id, const char *name)
  453. {
  454. GLuint uniform = glGetProgramResourceIndex(id, GL_SHADER_STORAGE_BLOCK, name);
  455. if (uniform == GL_INVALID_INDEX)
  456. {
  457. std::cout << "storage block index error " << name << "\n";
  458. }
  459. return uniform;
  460. };
  461. void LightShader::create()
  462. {
  463. geometryPassShader.loadShaderProgramFromFile("shaders/deferred/geometryPass.vert", "shaders/deferred/geometryPass.frag");
  464. geometryPassShader.bind();
  465. u_transform = getUniform(geometryPassShader.id, "u_transform");
  466. u_modelTransform = getUniform(geometryPassShader.id, "u_modelTransform");
  467. u_motelViewTransform = getUniform(geometryPassShader.id, "u_motelViewTransform");
  468. //normalShaderLightposLocation = getUniform(shader.id, "u_lightPosition");
  469. textureSamplerLocation = getUniform(geometryPassShader.id, "u_albedoSampler");
  470. normalMapSamplerLocation = getUniform(geometryPassShader.id, "u_normalSampler");
  471. //eyePositionLocation = getUniform(shader.id, "u_eyePosition");
  472. //skyBoxSamplerLocation = getUniform(textureSamplerLocation.id, "u_skybox");
  473. //gamaLocation = getUniform(shader.id, "u_gama");
  474. RMASamplerLocation = getUniform(geometryPassShader.id, "u_RMASampler");
  475. //pointLightCountLocation = getUniform(shader.id, "u_pointLightCount");
  476. materialIndexLocation = getUniform(geometryPassShader.id, "u_materialIndex");
  477. //pointLightBufferLocation = getUniform(shader.id, "u_pointLights");
  478. //todo geb buffer for each material
  479. materialBlockLocation = getStorageBlockIndex(geometryPassShader.id, "u_material");
  480. glShaderStorageBlockBinding(geometryPassShader.id, materialBlockLocation, 0);
  481. glGenBuffers(1, &materialBlockBuffer);
  482. glBindBuffer(GL_SHADER_STORAGE_BUFFER, materialBlockBuffer);
  483. lightingPassShader.loadShaderProgramFromFile("shaders/deferred/lightingPass.vert", "shaders/deferred/lightingPass.frag");
  484. lightingPassShader.bind();
  485. light_u_albedo = getUniform(lightingPassShader.id, "u_albedo");
  486. light_u_normals = getUniform(lightingPassShader.id, "u_normals");
  487. light_u_skybox = getUniform(lightingPassShader.id, "u_skybox");
  488. light_u_positions = getUniform(lightingPassShader.id, "u_positions");
  489. light_u_materials = getUniform(lightingPassShader.id, "u_materials");
  490. light_u_eyePosition = getUniform(lightingPassShader.id, "u_eyePosition");
  491. light_u_pointLightCount = getUniform(lightingPassShader.id, "u_pointLightCount");
  492. light_u_ssao = getUniform(lightingPassShader.id, "u_ssao");
  493. light_u_view = getUniform(lightingPassShader.id, "u_view");
  494. u_useSSAO = getUniform(lightingPassShader.id, "u_useSSAO");
  495. pointLightsBlockLocation = getStorageBlockIndex(lightingPassShader.id, "u_pointLights");
  496. glShaderStorageBlockBinding(lightingPassShader.id, pointLightsBlockLocation, 1);
  497. glGenBuffers(1, &pointLightsBlockBuffer);
  498. glBindBuffer(GL_SHADER_STORAGE_BUFFER, pointLightsBlockBuffer);
  499. glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, pointLightsBlockBuffer);
  500. glGenVertexArrays(1, &quadVAO);
  501. glBindVertexArray(quadVAO);
  502. glGenBuffers(1, &quadBuffer);
  503. glBindBuffer(GL_ARRAY_BUFFER, quadBuffer);
  504. float quadVertices[] = {
  505. // positions // texture Coords
  506. -1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
  507. -1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
  508. 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
  509. 1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
  510. };
  511. // setup plane VAO
  512. glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
  513. glEnableVertexAttribArray(0);
  514. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *)0);
  515. glEnableVertexAttribArray(1);
  516. glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *)(3 * sizeof(float)));
  517. glBindVertexArray(0);
  518. }
  519. void LightShader::bind(const glm::mat4 &viewProjMat, const glm::mat4 &transformMat,
  520. const glm::vec3 &lightPosition, const glm::vec3 &eyePosition, float gama,
  521. const GpuMaterial &material, std::vector<internal::GpuPointLight> &pointLights)
  522. {
  523. geometryPassShader.bind();
  524. this->setData(viewProjMat, transformMat, lightPosition, eyePosition, gama,
  525. material, pointLights);
  526. }
  527. void LightShader::setData(const glm::mat4 &viewProjMat,
  528. const glm::mat4 &transformMat, const glm::vec3 &lightPosition, const glm::vec3 &eyePosition,
  529. float gama, const GpuMaterial &material, std::vector<internal::GpuPointLight> &pointLights)
  530. {
  531. glUniformMatrix4fv(u_transform, 1, GL_FALSE, &viewProjMat[0][0]);
  532. glUniformMatrix4fv(u_modelTransform, 1, GL_FALSE, &transformMat[0][0]);
  533. glUniform3fv(normalShaderLightposLocation, 1, &lightPosition[0]);
  534. glUniform3fv(eyePositionLocation, 1, &eyePosition[0]);
  535. glUniform1i(textureSamplerLocation, 0);
  536. glUniform1i(normalMapSamplerLocation, 1);
  537. glUniform1i(skyBoxSamplerLocation, 2);
  538. glUniform1i(RMASamplerLocation, 3);
  539. if(pointLights.size())
  540. {
  541. glBindBuffer(GL_SHADER_STORAGE_BUFFER, pointLightsBlockBuffer);
  542. glBufferData(GL_SHADER_STORAGE_BUFFER, pointLights.size() * sizeof(internal::GpuPointLight)
  543. ,&pointLights[0], GL_STREAM_DRAW);
  544. glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, pointLightsBlockBuffer);
  545. }
  546. //glUniform1fv(pointLightBufferLocation, pointLights.size() * 8, (float*)pointLights.data());
  547. glUniform1i(pointLightCountLocation, pointLights.size());
  548. setMaterial(material);
  549. }
  550. void LightShader::setMaterial(const GpuMaterial &material)
  551. {
  552. glBindBuffer(GL_SHADER_STORAGE_BUFFER, materialBlockBuffer);
  553. glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(material)
  554. , &material, GL_STREAM_DRAW);
  555. glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, materialBlockBuffer);
  556. glUniform1i(materialIndexLocation, 0);
  557. }
  558. void LightShader::getSubroutines()
  559. {
  560. normalSubroutine_noMap = getUniformSubroutineIndex(geometryPassShader.id, GL_FRAGMENT_SHADER,
  561. "noNormalMapped");
  562. normalSubroutine_normalMap = getUniformSubroutineIndex(geometryPassShader.id, GL_FRAGMENT_SHADER,
  563. "normalMapped");
  564. //
  565. albedoSubroutine_sampled = getUniformSubroutineIndex(geometryPassShader.id, GL_FRAGMENT_SHADER,
  566. "sampledAlbedo");
  567. albedoSubroutine_notSampled = getUniformSubroutineIndex(geometryPassShader.id, GL_FRAGMENT_SHADER,
  568. "notSampledAlbedo");
  569. //
  570. normalSubroutineLocation = getUniformSubroutine(geometryPassShader.id, GL_FRAGMENT_SHADER,
  571. "getNormalMapFunc");
  572. materialSubroutineLocation = getUniformSubroutine(geometryPassShader.id, GL_FRAGMENT_SHADER,
  573. "u_getMaterialMapped");
  574. getAlbedoSubroutineLocation = getUniformSubroutine(geometryPassShader.id, GL_FRAGMENT_SHADER,
  575. "u_getAlbedo");
  576. const char *materiaSubroutineFunctions[8] = {
  577. "materialNone",
  578. "materialR",
  579. "materialM",
  580. "materialA",
  581. "materialRM",
  582. "materialRA",
  583. "materialMA",
  584. "materialRMA" };
  585. for(int i=0; i<8; i++)
  586. {
  587. materialSubroutine_functions[i] = getUniformSubroutineIndex(geometryPassShader.id, GL_FRAGMENT_SHADER,
  588. materiaSubroutineFunctions[i]);
  589. }
  590. }
  591. };
  592. #pragma endregion
  593. ////////////////////////////////////////////////
  594. //Camera.cpp
  595. ////////////////////////////////////////////////
  596. #pragma region Camera
  597. #define GLM_ENABLE_EXPERIMENTAL
  598. #include <glm/gtc/matrix_transform.hpp>
  599. #include <glm/gtc/type_ptr.hpp>
  600. #include <glm/mat3x3.hpp>
  601. #include <glm/gtx/transform.hpp>
  602. namespace gl3d
  603. {
  604. glm::mat4x4 Camera::getProjectionMatrix()
  605. {
  606. auto mat = glm::perspective(this->fovRadians, this->aspectRatio, this->closePlane,
  607. this->farPlane);
  608. return mat;
  609. }
  610. glm::mat4x4 Camera::getWorldToViewMatrix()
  611. {
  612. glm::vec3 lookingAt = this->position;
  613. lookingAt += viewDirection;
  614. auto mat = glm::lookAt(this->position, lookingAt, this->up);
  615. return mat;
  616. }
  617. void Camera::rotateCamera(const glm::vec2 delta)
  618. {
  619. glm::vec3 rotateYaxe = glm::cross(viewDirection, up);
  620. viewDirection = glm::mat3(glm::rotate(delta.x, up)) * viewDirection;
  621. if (delta.y < 0)
  622. { //down
  623. if (viewDirection.y < -0.99)
  624. goto noMove;
  625. }
  626. else
  627. { //up
  628. if (viewDirection.y > 0.99)
  629. goto noMove;
  630. }
  631. viewDirection = glm::mat3(glm::rotate(delta.y, rotateYaxe)) * viewDirection;
  632. noMove:
  633. viewDirection = glm::normalize(viewDirection);
  634. }
  635. void Camera::moveFPS(glm::vec3 direction)
  636. {
  637. viewDirection = glm::normalize(viewDirection);
  638. //forward
  639. float forward = -direction.z;
  640. float leftRight = direction.x;
  641. float upDown = direction.y;
  642. glm::vec3 move = {};
  643. move += up * upDown;
  644. move += glm::normalize(glm::cross(viewDirection, up)) * leftRight;
  645. move += viewDirection * forward;
  646. this->position += move;
  647. }
  648. };
  649. #pragma endregion
  650. ////////////////////////////////////////////////
  651. //GraphicModel.cpp
  652. ////////////////////////////////////////////////
  653. #pragma region GraphicModel
  654. #include "OBJ_Loader.h"
  655. #include <stb_image.h>
  656. #include <algorithm>
  657. namespace gl3d
  658. {
  659. void GraphicModel::loadFromComputedData(size_t vertexSize, const float * vercies, size_t indexSize,
  660. const unsigned int * indexes, bool noTexture)
  661. {
  662. gl3dAssertComment(indexSize % 3 == 0, "Index count must be multiple of 3");
  663. if (indexSize % 3 != 0)return;
  664. glGenVertexArrays(1, &vertexArray);
  665. glBindVertexArray(vertexArray);
  666. glGenBuffers(1, &vertexBuffer);
  667. glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
  668. glBufferData(GL_ARRAY_BUFFER, vertexSize, vercies, GL_STATIC_DRAW);
  669. if(noTexture)
  670. {
  671. glEnableVertexAttribArray(0);
  672. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)0);
  673. glEnableVertexAttribArray(1);
  674. glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)(3 * sizeof(float)));
  675. }else
  676. {
  677. glEnableVertexAttribArray(0);
  678. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)0);
  679. glEnableVertexAttribArray(1);
  680. glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(3 * sizeof(float)));
  681. glEnableVertexAttribArray(2);
  682. glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(6 * sizeof(float)));
  683. }
  684. if (indexSize && indexes)
  685. {
  686. glGenBuffers(1, &indexBuffer);
  687. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
  688. glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexSize, indexes, GL_STATIC_DRAW);
  689. primitiveCount = indexSize / sizeof(*indexes);
  690. }
  691. else
  692. {
  693. primitiveCount = vertexSize / sizeof(float);
  694. }
  695. glBindVertexArray(0);
  696. }
  697. //deprecated
  698. void GraphicModel::loadFromData(size_t vertexCount, float *vertices, float *normals, float *textureUV, size_t indexesCount, unsigned int *indexes)
  699. {
  700. gl3dAssertComment(vertices, "Vertices are not optional");
  701. gl3dAssertComment(normals, "Normals are not optional"); //todo compute
  702. if (!vertices || !normals) { return; }
  703. std::vector<float> dataForModel;
  704. dataForModel.reserve(vertexCount * 8);
  705. for (unsigned int i = 0; i < vertexCount; i++)
  706. {
  707. //positions normals uv
  708. dataForModel.push_back(vertices[(8*i)+0]);
  709. dataForModel.push_back(vertices[(8*i)+1]);
  710. dataForModel.push_back(vertices[(8*i)+2]);
  711. dataForModel.push_back(normals[(8 * i) + 3]);
  712. dataForModel.push_back(normals[(8 * i) + 4]);
  713. dataForModel.push_back(normals[(8 * i) + 5]);
  714. if (textureUV)
  715. {
  716. dataForModel.push_back(normals[(8 * i) + 6]);
  717. dataForModel.push_back(normals[(8 * i) + 7]);
  718. }
  719. else
  720. {
  721. dataForModel.push_back(0.f);
  722. dataForModel.push_back(0.f);
  723. }
  724. }
  725. this->loadFromComputedData(vertexCount * 4,
  726. &dataForModel[0],
  727. indexesCount * 4, &indexes[0], (textureUV == nullptr));
  728. }
  729. int max(int x, int y, int z)
  730. {
  731. return std::max(std::max(x, y), z);
  732. }
  733. void GraphicModel::loadFromModelMeshIndex(const LoadedModelData &model, int index)
  734. {
  735. auto &mesh = model.loader.LoadedMeshes[index];
  736. loadFromComputedData(mesh.Vertices.size() * 8 * 4,
  737. (float *)&mesh.Vertices[0],
  738. mesh.Indices.size() * 4, &mesh.Indices[0]);
  739. auto &mat = model.loader.LoadedMeshes[index].MeshMaterial;
  740. material.setDefaultMaterial();
  741. material.kd = glm::vec4(glm::vec3(mat.Kd), 1);
  742. //material.ks = glm::vec4(glm::vec3(mat.Ks), mat.Ns);
  743. //material.ka = glm::vec4(glm::vec3(mat.Ka), 0);
  744. material.metallic = mat.metallic;
  745. material.roughness = mat.roughness;
  746. //material.ao = mat.ao;
  747. albedoTexture.clear();
  748. normalMapTexture.clear();
  749. RMA_Texture.clear();
  750. if (!mat.map_Kd.empty())
  751. {
  752. albedoTexture.loadTextureFromFile(std::string(model.path + mat.map_Kd).c_str());
  753. }
  754. if (!mat.map_Kn.empty())
  755. {
  756. normalMapTexture.loadTextureFromFile(std::string(model.path + mat.map_Kn).c_str(),
  757. TextureLoadQuality::linearMipmap);
  758. }
  759. RMA_loadedTextures = 0;
  760. auto rmaQuality = TextureLoadQuality::linearMipmap;
  761. if(!mat.map_RMA.empty()) //todo not tested
  762. {
  763. RMA_Texture.loadTextureFromFile(mat.map_RMA.c_str(),
  764. rmaQuality);
  765. if(RMA_Texture.id)
  766. {
  767. RMA_loadedTextures = 7; //all textures loaded
  768. }
  769. }
  770. if (!mat.map_ORM.empty() && RMA_loadedTextures == 0)
  771. {
  772. stbi_set_flip_vertically_on_load(true);
  773. int w = 0, h = 0;
  774. unsigned char *data = 0;
  775. {
  776. data = stbi_load(std::string(model.path + mat.map_ORM).c_str(),
  777. &w, &h, 0, 4);
  778. if (!data)
  779. { std::cout << "err loading " << std::string(model.path + mat.map_ORM) << "\n"; }
  780. else
  781. {
  782. //convert from ORM ro RMA
  783. for (int j = 0; j < h; j++)
  784. for (int i = 0; i < w; i++)
  785. {
  786. unsigned char R = data[(i + j*w) * 4 + 1];
  787. unsigned char M = data[(i + j*w) * 4 + 2];
  788. unsigned char A = data[(i + j*w) * 4 + 0];
  789. data[(i + j * w) * 4 + 0] = R;
  790. data[(i + j * w) * 4 + 1] = M;
  791. data[(i + j * w) * 4 + 2] = A;
  792. }
  793. RMA_Texture.loadTextureFromMemory(data, w, h, 4, rmaQuality);
  794. RMA_loadedTextures = 7; //all textures loaded
  795. stbi_image_free(data);
  796. }
  797. }
  798. }
  799. //RMA trexture
  800. if(RMA_loadedTextures == 0)
  801. {
  802. stbi_set_flip_vertically_on_load(true);
  803. int w1=0, h1=0;
  804. unsigned char *data1 = 0;
  805. unsigned char *data2 = 0;
  806. unsigned char *data3 = 0;
  807. if(!mat.map_Pr.empty())
  808. {
  809. data1 = stbi_load(std::string(model.path + mat.map_Pr).c_str(),
  810. &w1, &h1, 0, 1);
  811. if (!data1) { std::cout << "err loading " << std::string(model.path + mat.map_Pr) << "\n"; }
  812. }
  813. int w2=0, h2=0;
  814. if(!mat.map_Pm.empty())
  815. {
  816. data2 = stbi_load(std::string(model.path + mat.map_Pm).c_str(),
  817. &w2, &h2, 0, 1);
  818. if (!data2) { std::cout << "err loading " << std::string(model.path + mat.map_Pm) << "\n"; }
  819. }
  820. int w3=0, h3=0;
  821. if(!mat.map_Ka.empty())
  822. {
  823. data3 = stbi_load(std::string(model.path + mat.map_Ka).c_str(),
  824. &w3, &h3, 0, 1);
  825. if (!data3) { std::cout << "err loading " << std::string(model.path + mat.map_Ka) << "\n"; }
  826. }
  827. int w = max(w1, w2, w3);
  828. int h = max(h1, h2, h3);
  829. //calculate which function to use
  830. if(data1 && data2 && data3){ RMA_loadedTextures = 7;}else
  831. if( data2 && data3){ RMA_loadedTextures = 6;}else
  832. if(data1 && data3){ RMA_loadedTextures = 5;}else
  833. if(data1 && data2 ){ RMA_loadedTextures = 4;}else
  834. if( data3){ RMA_loadedTextures = 3;}else
  835. if( data2 ){ RMA_loadedTextures = 2;}else
  836. if(data1 ){ RMA_loadedTextures = 1;}else
  837. { RMA_loadedTextures = 0;};
  838. if (RMA_loadedTextures)
  839. {
  840. unsigned char *finalData = new unsigned char[w * h * 4];
  841. //todo mabe add bilinear filtering
  842. //todo load less chanels if necessary
  843. for (int j = 0; j < h; j++)
  844. {
  845. for (int i = 0; i < w; i++)
  846. {
  847. if (data1) //rough
  848. {
  849. int texelI = (i / (float)w) * w1;
  850. int texelJ = (j / float(h)) * h1;
  851. finalData[((j * w) + i) * 4 + 0] =
  852. data1[(texelJ * w1) + texelI];
  853. }
  854. else
  855. {
  856. finalData[((j * w) + i) * 4 + 0] = 0;
  857. }
  858. if (data2) //metalic
  859. {
  860. int texelI = (i / (float)w) * w2;
  861. int texelJ = (j / float(h)) * h2;
  862. finalData[((j * w) + i) * 4 + 1] =
  863. data2[(texelJ * w2) + texelI];
  864. }
  865. else
  866. {
  867. finalData[((j * w) + i) * 4 + 1] = 0;
  868. }
  869. if (data3) //ambient
  870. {
  871. int texelI = (i / (float)w) * w3;
  872. int texelJ = (j / float(h)) * h3;
  873. finalData[((j * w) + i) * 4 + 2] =
  874. data3[(texelJ * w3) + texelI];
  875. }
  876. else
  877. {
  878. finalData[((j * w) + i) * 4 + 2] = 0;
  879. }
  880. finalData[((j * w) + i) * 4 + 3] = 255; //used only for imgui, remove later
  881. }
  882. }
  883. RMA_Texture.loadTextureFromMemory(finalData, w, h, 4,
  884. rmaQuality);
  885. stbi_image_free(data1);
  886. stbi_image_free(data2);
  887. stbi_image_free(data3);
  888. delete[] finalData;
  889. }
  890. }
  891. }
  892. void GraphicModel::loadFromModelMesh(const LoadedModelData &model)
  893. {
  894. auto &mesh = model.loader.LoadedVertices;
  895. loadFromComputedData(mesh.size() * 8 * 4,
  896. (float *)&mesh[0],
  897. model.loader.LoadedIndices.size() * 4,
  898. &model.loader.LoadedIndices[0]);
  899. }
  900. //deprecated
  901. void GraphicModel::loadFromFile(const char *fileName)
  902. {
  903. objl::Loader loader;
  904. loader.LoadFile(fileName);
  905. std::vector<float> dataForModel;
  906. auto &mesh = loader.LoadedMeshes[0];
  907. dataForModel.reserve(mesh.Vertices.size() * 8);
  908. for (unsigned int i = 0; i < mesh.Vertices.size(); i++)
  909. {
  910. //positions normals uv
  911. dataForModel.push_back(mesh.Vertices[i].Position.X);
  912. dataForModel.push_back(mesh.Vertices[i].Position.Y);
  913. dataForModel.push_back(mesh.Vertices[i].Position.Z);
  914. dataForModel.push_back(mesh.Vertices[i].Normal.X);
  915. dataForModel.push_back(mesh.Vertices[i].Normal.Y);
  916. dataForModel.push_back(mesh.Vertices[i].Normal.Z);
  917. dataForModel.push_back(mesh.Vertices[i].TextureCoordinate.X);
  918. dataForModel.push_back(mesh.Vertices[i].TextureCoordinate.Y);
  919. }
  920. std::vector<unsigned int> indicesForModel;
  921. indicesForModel.reserve(mesh.Indices.size());
  922. for (unsigned int i = 0; i < mesh.Indices.size(); i++)
  923. {
  924. indicesForModel.push_back(mesh.Indices[i]);
  925. }
  926. this->loadFromComputedData(dataForModel.size() * 4,
  927. &dataForModel[0],
  928. indicesForModel.size() * 4, &indicesForModel[0]);
  929. //vb = vertexBuffer(dataForModel.data(), dataForModel.size() * sizeof(float), GL_STATIC_DRAW);
  930. //ib = indexBuffer(indicesForModel.data(), indicesForModel.size() * sizeof(unsigned int));
  931. //va = std::move(vertexAttribute{ 3, 2, 3 });
  932. //
  933. //
  934. //if (model.m.LoadedMaterials.size() > 0)
  935. //{
  936. //
  937. // material.ka = glm::vec3(model.m.LoadedMaterials[0].Ka.X, model.m.LoadedMaterials[0].Ka.Y, model.m.LoadedMaterials[0].Ka.Z);
  938. // material.kd = glm::vec3(model.m.LoadedMaterials[0].Kd.X, model.m.LoadedMaterials[0].Kd.Y, model.m.LoadedMaterials[0].Kd.Z);
  939. // material.ks = glm::vec3(model.m.LoadedMaterials[0].Ks.X, model.m.LoadedMaterials[0].Ks.Y, model.m.LoadedMaterials[0].Ks.Z);
  940. // material.shiny = model.m.LoadedMaterials[0].Ns;
  941. // if (material.shiny == 0) { material.shiny = 1; }
  942. //
  943. // if (model.m.LoadedMaterials[0].map_Kd != "")
  944. // {
  945. //
  946. // texture = manager->getData(model.m.LoadedMaterials[0].map_Kd.c_str());
  947. //
  948. // }
  949. //}
  950. }
  951. void GraphicModel::clear()
  952. {
  953. glDeleteBuffers(1, &vertexBuffer);
  954. glDeleteBuffers(1, &indexBuffer);
  955. glDeleteVertexArrays(1, &vertexArray);
  956. albedoTexture.clear();
  957. normalMapTexture.clear();
  958. RMA_Texture.clear();
  959. vertexBuffer = 0;
  960. indexBuffer = 0;
  961. primitiveCount = 0;
  962. vertexArray = 0;
  963. }
  964. void GraphicModel::draw()
  965. {
  966. glBindVertexArray(vertexArray);
  967. //glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
  968. //glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0);
  969. //glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)(3 * sizeof(float)));
  970. if (indexBuffer)
  971. {
  972. glDrawElements(GL_TRIANGLES, primitiveCount, GL_UNSIGNED_INT, 0);
  973. }
  974. else
  975. {
  976. glDrawArrays(GL_TRIANGLES, 0, primitiveCount);
  977. }
  978. glBindVertexArray(0);
  979. }
  980. glm::mat4 GraphicModel::getTransformMatrix()
  981. {
  982. return gl3d::getTransformMatrix(position, rotation, scale);
  983. }
  984. void LoadedModelData::load(const char *file, float scale)
  985. {
  986. loader.LoadFile(file);
  987. //parse path
  988. path = file;
  989. while (!path.empty() &&
  990. *(path.end() - 1) != '\\' &&
  991. *(path.end() - 1) != '/'
  992. )
  993. {
  994. path.pop_back();
  995. }
  996. for (auto &i : loader.LoadedMeshes)
  997. {
  998. for(auto &j : i.Vertices)
  999. {
  1000. j.Position.X *= scale;
  1001. j.Position.Y *= scale;
  1002. j.Position.Z *= scale;
  1003. }
  1004. }
  1005. for (auto &j : loader.LoadedVertices)
  1006. {
  1007. j.Position.X *= scale;
  1008. j.Position.Y *= scale;
  1009. j.Position.Z *= scale;
  1010. }
  1011. std::cout << "Loaded: " << loader.LoadedMeshes.size() << " meshes\n";
  1012. }
  1013. float skyboxVertices[] = {
  1014. // positions
  1015. -1.0f, 1.0f, -1.0f,
  1016. -1.0f, -1.0f, -1.0f,
  1017. 1.0f, -1.0f, -1.0f,
  1018. 1.0f, -1.0f, -1.0f,
  1019. 1.0f, 1.0f, -1.0f,
  1020. -1.0f, 1.0f, -1.0f,
  1021. -1.0f, -1.0f, 1.0f,
  1022. -1.0f, -1.0f, -1.0f,
  1023. -1.0f, 1.0f, -1.0f,
  1024. -1.0f, 1.0f, -1.0f,
  1025. -1.0f, 1.0f, 1.0f,
  1026. -1.0f, -1.0f, 1.0f,
  1027. 1.0f, -1.0f, -1.0f,
  1028. 1.0f, -1.0f, 1.0f,
  1029. 1.0f, 1.0f, 1.0f,
  1030. 1.0f, 1.0f, 1.0f,
  1031. 1.0f, 1.0f, -1.0f,
  1032. 1.0f, -1.0f, -1.0f,
  1033. -1.0f, -1.0f, 1.0f,
  1034. -1.0f, 1.0f, 1.0f,
  1035. 1.0f, 1.0f, 1.0f,
  1036. 1.0f, 1.0f, 1.0f,
  1037. 1.0f, -1.0f, 1.0f,
  1038. -1.0f, -1.0f, 1.0f,
  1039. -1.0f, 1.0f, -1.0f,
  1040. 1.0f, 1.0f, -1.0f,
  1041. 1.0f, 1.0f, 1.0f,
  1042. 1.0f, 1.0f, 1.0f,
  1043. -1.0f, 1.0f, 1.0f,
  1044. -1.0f, 1.0f, -1.0f,
  1045. -1.0f, -1.0f, -1.0f,
  1046. -1.0f, -1.0f, 1.0f,
  1047. 1.0f, -1.0f, -1.0f,
  1048. 1.0f, -1.0f, -1.0f,
  1049. -1.0f, -1.0f, 1.0f,
  1050. 1.0f, -1.0f, 1.0f
  1051. };
  1052. void SkyBox::createGpuData()
  1053. {
  1054. shader.loadShaderProgramFromFile("shaders/skyBox.vert", "shaders/skyBox.frag");
  1055. samplerUniformLocation = getUniform(shader.id, "u_skybox");
  1056. modelViewUniformLocation = getUniform(shader.id, "u_viewProjection");
  1057. gamaUniformLocation = getUniform(shader.id, "u_gama");
  1058. glGenVertexArrays(1, &vertexArray);
  1059. glBindVertexArray(vertexArray);
  1060. glGenBuffers(1, &vertexBuffer);
  1061. glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
  1062. glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), skyboxVertices, GL_STATIC_DRAW);
  1063. glEnableVertexAttribArray(0);
  1064. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
  1065. glBindVertexArray(0);
  1066. }
  1067. //todo add srgb
  1068. void SkyBox::loadTexture(const char *names[6])
  1069. {
  1070. glGenTextures(1, &texture);
  1071. glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
  1072. int w, h, nrChannels;
  1073. unsigned char *data;
  1074. for (unsigned int i = 0; i <6; i++)
  1075. {
  1076. stbi_set_flip_vertically_on_load(false);
  1077. data = stbi_load(names[i], &w, &h, &nrChannels, 3);
  1078. if (data)
  1079. {
  1080. glTexImage2D(
  1081. GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
  1082. 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data
  1083. );
  1084. //gausianBlurRGB(data, w, h, 10);
  1085. //glTexImage2D(
  1086. // GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
  1087. // 1, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data
  1088. //);
  1089. stbi_image_free(data);
  1090. }
  1091. else
  1092. {
  1093. std::cout << "err loading " << names[i] << "\n";
  1094. }
  1095. }
  1096. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  1097. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  1098. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  1099. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  1100. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
  1101. }
  1102. //todo add srgb
  1103. void SkyBox::loadTexture(const char *name, int format)
  1104. {
  1105. glGenTextures(1, &texture);
  1106. glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
  1107. int width, height, nrChannels;
  1108. unsigned char *data;
  1109. stbi_set_flip_vertically_on_load(false);
  1110. data = stbi_load(name, &width, &height, &nrChannels, 3);
  1111. //right
  1112. //left
  1113. //top
  1114. //bottom
  1115. //front
  1116. //back
  1117. auto getPixel = [&](int x, int y, unsigned char *data)
  1118. {
  1119. return data + 3 * (x + y * width);
  1120. };
  1121. glm::ivec2 paddings[6];
  1122. glm::ivec2 immageRatio = {};
  1123. if(format == 0)
  1124. {
  1125. immageRatio = { 4, 3 };
  1126. glm::ivec2 paddingscopy[6] =
  1127. {
  1128. { (width / 4) * 2, (height / 3) * 1, },
  1129. { (width / 4) * 0, (height / 3) * 1, },
  1130. { (width / 4) * 1, (height / 3) * 0, },
  1131. { (width / 4) * 1, (height / 3) * 2, },
  1132. { (width / 4) * 1, (height / 3) * 1, },
  1133. { (width / 4) * 3, (height / 3) * 1, },
  1134. };
  1135. memcpy(paddings, paddingscopy, sizeof(paddings));
  1136. }else if (format == 1)
  1137. {
  1138. immageRatio = { 3, 4 };
  1139. glm::ivec2 paddingscopy[6] =
  1140. {
  1141. { (width / 3) * 2, (height / 4) * 1, },
  1142. { (width / 3) * 0, (height / 4) * 1, },
  1143. { (width / 3) * 1, (height / 4) * 0, },
  1144. { (width / 3) * 1, (height / 4) * 2, },
  1145. { (width / 3) * 1, (height / 4) * 3, },
  1146. { (width / 3) * 1, (height / 4) * 1, },
  1147. };
  1148. memcpy(paddings, paddingscopy, sizeof(paddings));
  1149. }
  1150. if (data)
  1151. {
  1152. for (unsigned int i = 0; i < 6; i++)
  1153. {
  1154. unsigned char *extractedData = new unsigned char[3 *
  1155. (width / immageRatio.x) * (height / immageRatio.y)];
  1156. int index = 0;
  1157. int paddingX = paddings[i].x;
  1158. int paddingY = paddings[i].y;
  1159. for (int j = 0; j < height / immageRatio.y; j++)
  1160. for (int i = 0; i < width / immageRatio.x; i++)
  1161. {
  1162. extractedData[index] = *getPixel(i + paddingX, j + paddingY, data);
  1163. extractedData[index + 1] = *(getPixel(i + paddingX, j + paddingY, data)+1);
  1164. extractedData[index + 2] = *(getPixel(i + paddingX, j + paddingY, data)+2);
  1165. //extractedData[index] = 100;
  1166. //extractedData[index + 1] = 100;
  1167. //extractedData[index + 2] = 100;
  1168. index += 3;
  1169. }
  1170. glTexImage2D(
  1171. GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
  1172. 0, GL_RGB, width/ immageRatio.x, height/ immageRatio.y, 0,
  1173. GL_RGB, GL_UNSIGNED_BYTE, extractedData
  1174. );
  1175. delete[] extractedData;
  1176. }
  1177. stbi_image_free(data);
  1178. }else
  1179. {
  1180. std::cout << "err loading " << name << "\n";
  1181. }
  1182. //glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
  1183. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  1184. //glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  1185. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  1186. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  1187. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  1188. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
  1189. }
  1190. void SkyBox::clearGpuData()
  1191. {
  1192. }
  1193. void SkyBox::draw(const glm::mat4 &viewProjMat, float gama)
  1194. {
  1195. glBindVertexArray(vertexArray);
  1196. bindCubeMap();
  1197. shader.bind();
  1198. glUniformMatrix4fv(modelViewUniformLocation, 1, GL_FALSE, &viewProjMat[0][0]);
  1199. glUniform1i(samplerUniformLocation, 0);
  1200. glUniform1f(gamaUniformLocation, gama);
  1201. glDepthFunc(GL_LEQUAL);
  1202. glDrawArrays(GL_TRIANGLES, 0, 6*6);
  1203. glDepthFunc(GL_LESS);
  1204. glBindVertexArray(0);
  1205. }
  1206. void SkyBox::bindCubeMap()
  1207. {
  1208. glActiveTexture(GL_TEXTURE0);
  1209. glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
  1210. }
  1211. void MultipleGraphicModels::loadFromModel(const LoadedModelData &model)
  1212. {
  1213. clear();
  1214. int s = model.loader.LoadedMeshes.size();
  1215. models.reserve(s);
  1216. for(int i=0;i<s;i++)
  1217. {
  1218. GraphicModel gm;
  1219. gm.loadFromModelMeshIndex(model, i);
  1220. gm.name = model.loader.LoadedMeshes[i].MeshName;
  1221. char *c = new char[gm.name.size() + 1];
  1222. strcpy(c, gm.name.c_str());
  1223. subModelsNames.push_back(c);
  1224. models.push_back(gm);
  1225. }
  1226. }
  1227. void MultipleGraphicModels::clear()
  1228. {
  1229. for(auto &i : models)
  1230. {
  1231. i.clear();
  1232. }
  1233. for (auto &i : subModelsNames)
  1234. {
  1235. delete[] i;
  1236. }
  1237. subModelsNames.clear();
  1238. models.clear();
  1239. //todo clear material buffer
  1240. }
  1241. //todo optimize
  1242. glm::mat4 getTransformMatrix(glm::vec3 position, glm::vec3 rotation, glm::vec3 scale)
  1243. {
  1244. auto s = glm::scale(scale);
  1245. auto r = glm::rotate(rotation.x, glm::vec3(1, 0, 0)) *
  1246. glm::rotate(rotation.y, glm::vec3(0, 1, 0)) *
  1247. glm::rotate(rotation.z, glm::vec3(0, 0, 1));
  1248. auto t = glm::translate(position);
  1249. return t * r * s;
  1250. }
  1251. void GpuMultipleGraphicModel::clear()
  1252. {
  1253. for (auto &i : models)
  1254. {
  1255. i.clear();
  1256. }
  1257. for (auto &i : subModelsNames)
  1258. {
  1259. delete[] i;
  1260. }
  1261. subModelsNames.clear();
  1262. models.clear();
  1263. }
  1264. void GpuGraphicModel::loadFromComputedData(size_t vertexSize, const float *vercies, size_t indexSize, const unsigned int *indexes, bool noTexture)
  1265. {
  1266. gl3dAssertComment(indexSize % 3 == 0, "Index count must be multiple of 3");
  1267. if (indexSize % 3 != 0)return;
  1268. glGenVertexArrays(1, &vertexArray);
  1269. glBindVertexArray(vertexArray);
  1270. glGenBuffers(1, &vertexBuffer);
  1271. glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
  1272. glBufferData(GL_ARRAY_BUFFER, vertexSize, vercies, GL_STATIC_DRAW);
  1273. //todo if the object doesn't have texture data we should not render any material to it or just refuze to load it
  1274. if (noTexture)
  1275. {
  1276. glEnableVertexAttribArray(0);
  1277. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)0);
  1278. glEnableVertexAttribArray(1);
  1279. glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)(3 * sizeof(float)));
  1280. }
  1281. else
  1282. {
  1283. glEnableVertexAttribArray(0);
  1284. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)0);
  1285. glEnableVertexAttribArray(1);
  1286. glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(3 * sizeof(float)));
  1287. glEnableVertexAttribArray(2);
  1288. glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(6 * sizeof(float)));
  1289. }
  1290. if (indexSize && indexes)
  1291. {
  1292. glGenBuffers(1, &indexBuffer);
  1293. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
  1294. glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexSize, indexes, GL_STATIC_DRAW);
  1295. primitiveCount = indexSize / sizeof(*indexes);
  1296. }
  1297. else
  1298. {
  1299. primitiveCount = vertexSize / sizeof(float);
  1300. }
  1301. glBindVertexArray(0);
  1302. }
  1303. void GpuGraphicModel::clear()
  1304. {
  1305. glDeleteBuffers(1, &vertexBuffer);
  1306. glDeleteBuffers(1, &indexBuffer);
  1307. glDeleteVertexArrays(1, &vertexArray);
  1308. //albedoTexture.clear();
  1309. //normalMapTexture.clear();
  1310. //RMA_Texture.clear();
  1311. vertexBuffer = 0;
  1312. indexBuffer = 0;
  1313. primitiveCount = 0;
  1314. vertexArray = 0;
  1315. }
  1316. };
  1317. #pragma endregion
  1318. ////////////////////////////////////////////////
  1319. //gl3d.cpp
  1320. ////////////////////////////////////////////////
  1321. #pragma region gl3d
  1322. #include <algorithm>
  1323. #include <stb_image.h>
  1324. #include <random>
  1325. #include <string>
  1326. namespace gl3d
  1327. {
  1328. void Renderer3D::init(int x, int y)
  1329. {
  1330. w = x; h = y;
  1331. lightShader.create();
  1332. skyBox.createGpuData();
  1333. vao.createVAOs();
  1334. showNormalsProgram.shader.loadShaderProgramFromFile("shaders/showNormals.vert",
  1335. "shaders/showNormals.geom", "shaders/showNormals.frag");
  1336. showNormalsProgram.modelTransformLocation = glGetUniformLocation(showNormalsProgram.shader.id, "u_modelTransform");
  1337. showNormalsProgram.projectionLocation = glGetUniformLocation(showNormalsProgram.shader.id, "u_projection");
  1338. showNormalsProgram.sizeLocation = glGetUniformLocation(showNormalsProgram.shader.id, "u_size");
  1339. showNormalsProgram.colorLocation = glGetUniformLocation(showNormalsProgram.shader.id, "u_color");
  1340. unsigned char textureData[] =
  1341. {
  1342. 20, 20, 20, 255,
  1343. 212, 0, 219, 255,
  1344. 212, 0, 219, 255,
  1345. 20, 20, 20, 255,
  1346. };
  1347. defaultTexture.loadTextureFromMemory(textureData, 2, 2, 4, TextureLoadQuality::leastPossible);
  1348. //create gBuffer
  1349. glCheck(glGenFramebuffers(1, &gBuffer.gBuffer));
  1350. glCheck(glBindFramebuffer(GL_FRAMEBUFFER, gBuffer.gBuffer));
  1351. glCheck(glGenTextures(gBuffer.bufferCount, gBuffer.buffers));
  1352. glCheck(glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.position]));
  1353. glCheck(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, x, y, 0, GL_RGBA, GL_FLOAT, NULL));
  1354. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  1355. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  1356. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  1357. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  1358. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gBuffer.buffers[gBuffer.position], 0);
  1359. glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.normal]);
  1360. glCheck(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, x, y, 0, GL_RGBA, GL_FLOAT, NULL));
  1361. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  1362. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  1363. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  1364. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  1365. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, gBuffer.buffers[gBuffer.normal], 0);
  1366. glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.albedo]);
  1367. glCheck(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL));
  1368. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  1369. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  1370. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  1371. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  1372. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, gBuffer.buffers[gBuffer.albedo], 0);
  1373. glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.material]);
  1374. glCheck(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL));
  1375. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  1376. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  1377. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  1378. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  1379. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, gBuffer.buffers[gBuffer.material], 0);
  1380. glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.positionViewSpace]);
  1381. glCheck(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, x, y, 0, GL_RGBA, GL_FLOAT, NULL));
  1382. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  1383. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  1384. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  1385. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  1386. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT4, GL_TEXTURE_2D, gBuffer.buffers[gBuffer.positionViewSpace], 0);
  1387. unsigned int attachments[decltype(gBuffer)::bufferCount] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
  1388. GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3, GL_COLOR_ATTACHMENT4 };
  1389. glDrawBuffers(decltype(gBuffer)::bufferCount, attachments);
  1390. glGenRenderbuffers(1, &gBuffer.depthBuffer);
  1391. glBindRenderbuffer(GL_RENDERBUFFER, gBuffer.depthBuffer);
  1392. glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, x, y);
  1393. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, gBuffer.depthBuffer);
  1394. if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
  1395. {
  1396. std::cout << "Gbuffer failed\n";
  1397. }
  1398. glBindFramebuffer(GL_FRAMEBUFFER, 0);
  1399. ssao.create(x, y);
  1400. postProcess.create(x, y);
  1401. }
  1402. void Renderer3D::VAO::createVAOs()
  1403. {
  1404. glGenVertexArrays(1, &posNormalTexture);
  1405. glBindVertexArray(posNormalTexture);
  1406. glEnableVertexAttribArray(0);
  1407. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)0);
  1408. glEnableVertexAttribArray(1);
  1409. glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(3 * sizeof(float)));
  1410. glEnableVertexAttribArray(2);
  1411. glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(6 * sizeof(float)));
  1412. glBindVertexArray(0);
  1413. }
  1414. Material Renderer3D::createMaterial(glm::vec3 kd, float roughness, float metallic, float ao
  1415. , std::string name)
  1416. {
  1417. int id = internal::generateNewIndex(materialIndexes);
  1418. GpuMaterial gpuMaterial;
  1419. gpuMaterial.kd = glm::vec4(kd, 0);
  1420. gpuMaterial.roughness = roughness;
  1421. gpuMaterial.metallic = metallic;
  1422. gpuMaterial.ao = ao;
  1423. materialIndexes.push_back(id);
  1424. materials.push_back(gpuMaterial);
  1425. materialNames.push_back(name);
  1426. materialTexturesData.push_back({});
  1427. Material m;
  1428. m.id_ = id;
  1429. return m;
  1430. }
  1431. Material Renderer3D::createMaterial(Material m)
  1432. {
  1433. auto newM = createMaterial();
  1434. copyMaterialData(newM, m);
  1435. return newM;
  1436. }
  1437. Material Renderer3D::loadMaterial(std::string file)
  1438. {
  1439. objl::Loader loader;
  1440. loader.LoadFile(file);
  1441. return Material();
  1442. }
  1443. void Renderer3D::deleteMaterial(Material m)
  1444. {
  1445. auto pos = std::find(materialIndexes.begin(), materialIndexes.end(), m.id_);
  1446. if (pos == materialIndexes.end())
  1447. {
  1448. gl3dAssertComment(pos == materialIndexes.end(), "invalid delete material");
  1449. return;
  1450. }
  1451. int index = pos - materialIndexes.begin();
  1452. materialIndexes.erase(pos);
  1453. materials.erase(materials.begin() + index);
  1454. materialNames.erase(materialNames.begin() + index);
  1455. materialTexturesData.erase(materialTexturesData.begin() + index);
  1456. m.id_ = 0;
  1457. }
  1458. void Renderer3D::copyMaterialData(Material dest, Material source)
  1459. {
  1460. int destId = getMaterialIndex(dest);
  1461. int sourceId = getMaterialIndex(source);
  1462. if(destId == -1 || sourceId == -1)
  1463. {
  1464. gl3dAssertComment(destId != -1, "invaled dest material index");
  1465. gl3dAssertComment(sourceId != -1, "invaled source material index");
  1466. return;
  1467. }
  1468. materials[destId] = materials[sourceId];
  1469. materialNames[destId] = materialNames[sourceId];
  1470. materialTexturesData[destId] = materialTexturesData[destId];
  1471. }
  1472. GpuMaterial *Renderer3D::getMaterialData(Material m)
  1473. {
  1474. int id = getMaterialIndex(m);
  1475. if(id == -1)
  1476. {
  1477. return nullptr;
  1478. }
  1479. auto data = &materials[id];
  1480. return data;
  1481. }
  1482. TextureDataForModel *Renderer3D::getMaterialTextures(Material m)
  1483. {
  1484. int id = getMaterialIndex(m);
  1485. if (id == -1)
  1486. {
  1487. return nullptr;
  1488. }
  1489. auto data = &materialTexturesData[id];
  1490. return data;
  1491. }
  1492. std::string *Renderer3D::getMaterialName(Material m)
  1493. {
  1494. int id = getMaterialIndex(m);
  1495. if (id == -1)
  1496. {
  1497. return nullptr;
  1498. }
  1499. auto data = &materialNames[id];
  1500. return data;
  1501. }
  1502. bool Renderer3D::getMaterialData(Material m, GpuMaterial *gpuMaterial, std::string *name, TextureDataForModel *textureData)
  1503. {
  1504. int id = getMaterialIndex(m);
  1505. if (id == -1)
  1506. {
  1507. return false;
  1508. }
  1509. if(gpuMaterial)
  1510. {
  1511. gpuMaterial = &materials[id];
  1512. }
  1513. if(name)
  1514. {
  1515. name = &materialNames[id];
  1516. }
  1517. if(textureData)
  1518. {
  1519. textureData = &materialTexturesData[id];
  1520. }
  1521. return true;
  1522. }
  1523. bool Renderer3D::setMaterialData(Material m, const GpuMaterial &data, std::string *s)
  1524. {
  1525. int id = getMaterialIndex(m);
  1526. if (id == -1)
  1527. {
  1528. return 0;
  1529. }
  1530. materials[id] = data;
  1531. if (s)
  1532. {
  1533. materialNames[id] = *s;
  1534. }
  1535. return 1;
  1536. }
  1537. GpuMultipleGraphicModel *Renderer3D::getObjectData(Object o)
  1538. {
  1539. int id = getObjectIndex(o);
  1540. if (id == -1)
  1541. {
  1542. return nullptr;
  1543. }
  1544. auto data = &graphicModels[id];
  1545. return data;
  1546. }
  1547. Texture Renderer3D::loadTexture(std::string path, bool defaultToDefaultTexture)
  1548. {
  1549. if(path == "")
  1550. {
  1551. return Texture{ 0 };
  1552. }
  1553. int pos = 0;
  1554. for (auto &i : loadedTexturesNames)
  1555. {
  1556. if (i == path)
  1557. {
  1558. Texture t;
  1559. t.id_ = loadedTexturesIndexes[pos];
  1560. return t;
  1561. }
  1562. pos++;
  1563. }
  1564. GpuTexture t(path.c_str());
  1565. if(t.id == 0 && defaultToDefaultTexture == false)
  1566. {
  1567. return Texture{ 0 };
  1568. }
  1569. int id = internal::generateNewIndex(loadedTexturesIndexes);
  1570. //if texture is not loaded, set it to default
  1571. if(t.id == 0)
  1572. {
  1573. t.id = defaultTexture.id;
  1574. }
  1575. loadedTexturesIndexes.push_back(id);
  1576. loadedTextures.push_back(t);
  1577. loadedTexturesNames.push_back(path);
  1578. return Texture{ id };
  1579. }
  1580. GLuint Renderer3D::getTextureOpenglId(Texture t)
  1581. {
  1582. auto p = getTextureData(t);
  1583. if(p == nullptr)
  1584. {
  1585. return 0;
  1586. }else
  1587. {
  1588. return p->id;
  1589. }
  1590. }
  1591. void Renderer3D::deleteTexture(Texture t)
  1592. {
  1593. int index = getTextureIndex(t);
  1594. if(index < 0)
  1595. {
  1596. return;
  1597. }
  1598. auto gpuTexture = loadedTextures[index];
  1599. if(gpuTexture.id != defaultTexture.id)
  1600. {
  1601. gpuTexture.clear();
  1602. }
  1603. loadedTexturesIndexes.erase(loadedTexturesIndexes.begin() + index);
  1604. loadedTextures.erase(loadedTextures.begin() + index);
  1605. loadedTexturesNames.erase(loadedTexturesNames.begin() + index);
  1606. t.id_ = 0;
  1607. }
  1608. GpuTexture *Renderer3D::getTextureData(Texture t)
  1609. {
  1610. int id = getTextureIndex(t);
  1611. if (id == -1)
  1612. {
  1613. return nullptr;
  1614. }
  1615. auto data = &loadedTextures[id];
  1616. return data;
  1617. }
  1618. Texture Renderer3D::createIntenralTexture(GpuTexture t)
  1619. {
  1620. int id = internal::generateNewIndex(loadedTexturesIndexes);
  1621. //if t is null initialize to default texture
  1622. if (t.id == 0)
  1623. {
  1624. t.id = defaultTexture.id;
  1625. }
  1626. loadedTexturesIndexes.push_back(id);
  1627. loadedTextures.push_back(t);
  1628. loadedTexturesNames.push_back("");
  1629. return Texture{ id };
  1630. }
  1631. static int max(int x, int y, int z)
  1632. {
  1633. return std::max(std::max(x, y), z);
  1634. }
  1635. Object Renderer3D::loadObject(std::string path, float scale)
  1636. {
  1637. gl3d::LoadedModelData model(path.c_str(), scale);
  1638. if(model.loader.LoadedMeshes.empty())
  1639. {
  1640. std::cout << "err loading " + path + "\n";
  1641. return { 0 };
  1642. }
  1643. int id = internal::generateNewIndex(graphicModelsIndexes);
  1644. GpuMultipleGraphicModel returnModel;
  1645. {
  1646. int s = model.loader.LoadedMeshes.size();
  1647. returnModel.models.reserve(s);
  1648. std::vector<gl3d::Material> loadedMaterials;
  1649. loadedMaterials.reserve(model.loader.LoadedMaterials.size());
  1650. for(int i=0;i<model.loader.LoadedMaterials.size(); i++)
  1651. {
  1652. auto &mat = model.loader.LoadedMaterials[i];
  1653. auto m = this->createMaterial(mat.Kd, mat.roughness,
  1654. mat.metallic, mat.ao);
  1655. {
  1656. //load textures for materials
  1657. TextureDataForModel *textureData = this->getMaterialTextures(m);
  1658. //auto &mat = model.loader.LoadedMeshes[index].MeshMaterial;
  1659. //gm.material = loadedMaterials[model.loader.LoadedMeshes[index].materialIndex];
  1660. //gm.albedoTexture.clear();
  1661. //gm.normalMapTexture.clear();
  1662. //gm.RMA_Texture.clear();
  1663. if (!mat.map_Kd.empty())
  1664. {
  1665. //gm.albedoTexture.loadTextureFromFile(std::string(model.path + mat.map_Kd).c_str());
  1666. textureData->albedoTexture = this->loadTexture(std::string(model.path + mat.map_Kd), 0);
  1667. }
  1668. if (!mat.map_Kn.empty())
  1669. {
  1670. //todo add texture load quality options
  1671. textureData->normalMapTexture = this->loadTexture(std::string(model.path + mat.map_Kn), 0);
  1672. //gm.normalMapTexture.loadTextureFromFile(std::string(model.path + mat.map_Kn).c_str(),
  1673. // TextureLoadQuality::linearMipmap);
  1674. }
  1675. textureData->RMA_loadedTextures = 0;
  1676. auto rmaQuality = TextureLoadQuality::linearMipmap;
  1677. if (!mat.map_RMA.empty()) //todo not tested
  1678. {
  1679. //gm.RMA_Texture.loadTextureFromFile(mat.map_RMA.c_str(),
  1680. //rmaQuality);
  1681. textureData->RMA_Texture = this->loadTexture(mat.map_RMA.c_str());
  1682. //todo add a function to check if a function is valid
  1683. if (getTextureData(textureData->RMA_Texture)->id == defaultTexture.id)
  1684. {
  1685. textureData->RMA_loadedTextures = 7; //all textures loaded
  1686. }
  1687. //if (gm.RMA_Texture.id)
  1688. //{
  1689. // gm.RMA_loadedTextures = 7; //all textures loaded
  1690. //}
  1691. }
  1692. if (!mat.map_ORM.empty() && textureData->RMA_loadedTextures == 0)
  1693. {
  1694. stbi_set_flip_vertically_on_load(true);
  1695. int w = 0, h = 0;
  1696. unsigned char *data = 0;
  1697. {
  1698. data = stbi_load(std::string(model.path + mat.map_ORM).c_str(),
  1699. &w, &h, 0, 4);
  1700. if (!data)
  1701. {
  1702. std::cout << "err loading " << std::string(model.path + mat.map_ORM) << "\n";
  1703. }
  1704. else
  1705. {
  1706. //convert from ORM ro RMA
  1707. for (int j = 0; j < h; j++)
  1708. for (int i = 0; i < w; i++)
  1709. {
  1710. unsigned char R = data[(i + j * w) * 4 + 1];
  1711. unsigned char M = data[(i + j * w) * 4 + 2];
  1712. unsigned char A = data[(i + j * w) * 4 + 0];
  1713. data[(i + j * w) * 4 + 0] = R;
  1714. data[(i + j * w) * 4 + 1] = M;
  1715. data[(i + j * w) * 4 + 2] = A;
  1716. }
  1717. //gm.RMA_Texture.loadTextureFromMemory(data, w, h, 4, rmaQuality);
  1718. GpuTexture t;
  1719. t.loadTextureFromMemory(data, w, h, 4, rmaQuality);
  1720. textureData->RMA_Texture = this->createIntenralTexture(t);
  1721. textureData->RMA_loadedTextures = 7; //all textures loaded
  1722. stbi_image_free(data);
  1723. }
  1724. }
  1725. }
  1726. //RMA trexture
  1727. if (textureData->RMA_loadedTextures == 0)
  1728. {
  1729. stbi_set_flip_vertically_on_load(true);
  1730. int w1 = 0, h1 = 0;
  1731. unsigned char *data1 = 0;
  1732. unsigned char *data2 = 0;
  1733. unsigned char *data3 = 0;
  1734. if (!mat.map_Pr.empty())
  1735. {
  1736. data1 = stbi_load(std::string(model.path + mat.map_Pr).c_str(),
  1737. &w1, &h1, 0, 1);
  1738. if (!data1) { std::cout << "err loading " << std::string(model.path + mat.map_Pr) << "\n"; }
  1739. }
  1740. int w2 = 0, h2 = 0;
  1741. if (!mat.map_Pm.empty())
  1742. {
  1743. data2 = stbi_load(std::string(model.path + mat.map_Pm).c_str(),
  1744. &w2, &h2, 0, 1);
  1745. if (!data2) { std::cout << "err loading " << std::string(model.path + mat.map_Pm) << "\n"; }
  1746. }
  1747. int w3 = 0, h3 = 0;
  1748. if (!mat.map_Ka.empty())
  1749. {
  1750. data3 = stbi_load(std::string(model.path + mat.map_Ka).c_str(),
  1751. &w3, &h3, 0, 1);
  1752. if (!data3) { std::cout << "err loading " << std::string(model.path + mat.map_Ka) << "\n"; }
  1753. }
  1754. int w = max(w1, w2, w3);
  1755. int h = max(h1, h2, h3);
  1756. //calculate which function to use
  1757. if (data1 && data2 && data3) { textureData->RMA_loadedTextures = 7; }
  1758. else
  1759. if (data2 && data3) { textureData->RMA_loadedTextures = 6; }
  1760. else
  1761. if (data1 && data3) { textureData->RMA_loadedTextures = 5; }
  1762. else
  1763. if (data1 && data2) { textureData->RMA_loadedTextures = 4; }
  1764. else
  1765. if (data3) { textureData->RMA_loadedTextures = 3; }
  1766. else
  1767. if (data2) { textureData->RMA_loadedTextures = 2; }
  1768. else
  1769. if (data1) { textureData->RMA_loadedTextures = 1; }
  1770. else { textureData->RMA_loadedTextures = 0; }
  1771. if (textureData->RMA_loadedTextures)
  1772. {
  1773. unsigned char *finalData = new unsigned char[w * h * 4];
  1774. //todo mabe add bilinear filtering
  1775. //todo load less chanels if necessary
  1776. for (int j = 0; j < h; j++)
  1777. {
  1778. for (int i = 0; i < w; i++)
  1779. {
  1780. if (data1) //rough
  1781. {
  1782. int texelI = (i / (float)w) * w1;
  1783. int texelJ = (j / float(h)) * h1;
  1784. finalData[((j * w) + i) * 4 + 0] =
  1785. data1[(texelJ * w1) + texelI];
  1786. }
  1787. else
  1788. {
  1789. finalData[((j * w) + i) * 4 + 0] = 0;
  1790. }
  1791. if (data2) //metalic
  1792. {
  1793. int texelI = (i / (float)w) * w2;
  1794. int texelJ = (j / float(h)) * h2;
  1795. finalData[((j * w) + i) * 4 + 1] =
  1796. data2[(texelJ * w2) + texelI];
  1797. }
  1798. else
  1799. {
  1800. finalData[((j * w) + i) * 4 + 1] = 0;
  1801. }
  1802. if (data3) //ambient
  1803. {
  1804. int texelI = (i / (float)w) * w3;
  1805. int texelJ = (j / float(h)) * h3;
  1806. finalData[((j * w) + i) * 4 + 2] =
  1807. data3[(texelJ * w3) + texelI];
  1808. }
  1809. else
  1810. {
  1811. finalData[((j * w) + i) * 4 + 2] = 0;
  1812. }
  1813. finalData[((j * w) + i) * 4 + 3] = 255; //used only for imgui, remove later
  1814. }
  1815. }
  1816. //gm.RMA_Texture.loadTextureFromMemory(finalData, w, h, 4,
  1817. // rmaQuality);
  1818. GpuTexture t;
  1819. t.loadTextureFromMemory(finalData, w, h, 4, rmaQuality);
  1820. textureData->RMA_Texture = this->createIntenralTexture(t);
  1821. stbi_image_free(data1);
  1822. stbi_image_free(data2);
  1823. stbi_image_free(data3);
  1824. delete[] finalData;
  1825. }
  1826. }
  1827. }
  1828. loadedMaterials.push_back(m);
  1829. }
  1830. for (int i = 0; i < s; i++)
  1831. {
  1832. GpuGraphicModel gm;
  1833. int index = i;
  1834. GpuMaterial material;
  1835. //TextureDataForModel textureData = {};
  1836. auto &mesh = model.loader.LoadedMeshes[index];
  1837. gm.loadFromComputedData(mesh.Vertices.size() * 8 * 4,
  1838. (float *)&mesh.Vertices[0],
  1839. mesh.Indices.size() * 4, &mesh.Indices[0]);
  1840. gm.material = loadedMaterials[model.loader.LoadedMeshes[index].materialIndex];
  1841. gm.name = model.loader.LoadedMeshes[i].MeshName;
  1842. char *c = new char[gm.name.size() + 1];
  1843. strcpy(c, gm.name.c_str());
  1844. returnModel.subModelsNames.push_back(c);
  1845. returnModel.models.push_back(gm);
  1846. }
  1847. }
  1848. graphicModelsIndexes.push_back(id);
  1849. graphicModels.push_back(returnModel);
  1850. Object o;
  1851. o.id_ = id;
  1852. return o;
  1853. }
  1854. void Renderer3D::deleteObject(Object o)
  1855. {
  1856. auto pos = std::find(graphicModelsIndexes.begin(), graphicModelsIndexes.end(), o.id_);
  1857. if (pos == graphicModelsIndexes.end())
  1858. {
  1859. gl3dAssertComment(pos == graphicModelsIndexes.end(), "invalid delete object");
  1860. return;
  1861. }
  1862. int index = pos - graphicModelsIndexes.begin();
  1863. graphicModelsIndexes.erase(pos);
  1864. graphicModels[index].clear();
  1865. graphicModels.erase(graphicModels.begin() + index);
  1866. o.id_ = 0;
  1867. }
  1868. void Renderer3D::renderObject(Object o, glm::vec3 position, glm::vec3 rotation, glm::vec3 scale)
  1869. {
  1870. glBindFramebuffer(GL_FRAMEBUFFER, gBuffer.gBuffer);
  1871. auto found = std::find(graphicModelsIndexes.begin(), graphicModelsIndexes.end(), o.id_);
  1872. if (found == graphicModelsIndexes.end())
  1873. {
  1874. gl3dAssertComment(found == graphicModelsIndexes.end(), "invalid render object");
  1875. return;
  1876. }
  1877. int id = found - graphicModelsIndexes.begin();
  1878. auto &model = graphicModels[id];
  1879. if (model.models.empty())
  1880. {
  1881. return;
  1882. }
  1883. auto projMat = camera.getProjectionMatrix();
  1884. auto viewMat = camera.getWorldToViewMatrix();
  1885. auto transformMat = gl3d::getTransformMatrix(position, rotation, scale);
  1886. auto modelViewProjMat = projMat * viewMat * transformMat;
  1887. //auto modelView = viewMat * transformMat;
  1888. lightShader.geometryPassShader.bind();
  1889. lightShader.getSubroutines();
  1890. glUniformMatrix4fv(lightShader.u_transform, 1, GL_FALSE, &modelViewProjMat[0][0]);
  1891. glUniformMatrix4fv(lightShader.u_modelTransform, 1, GL_FALSE, &transformMat[0][0]);
  1892. glUniformMatrix4fv(lightShader.u_motelViewTransform, 1, GL_FALSE, &(viewMat * transformMat)[0][0]);
  1893. //glUniform3fv(normalShaderLightposLocation, 1, &lightPosition[0]);
  1894. //glUniform3fv(eyePositionLocation, 1, &eyePosition[0]);
  1895. glUniform1i(lightShader.textureSamplerLocation, 0);
  1896. glUniform1i(lightShader.normalMapSamplerLocation, 1);
  1897. //glUniform1i(lightShader.skyBoxSamplerLocation, 2);
  1898. glUniform1i(lightShader.RMASamplerLocation, 3);
  1899. //material buffer
  1900. glBindBuffer(GL_SHADER_STORAGE_BUFFER, lightShader.materialBlockBuffer);
  1901. glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GpuMaterial) * materials.size()
  1902. , &materials[0], GL_STREAM_DRAW);
  1903. glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, lightShader.materialBlockBuffer);
  1904. //glBindVertexArray(vao.posNormalTexture);
  1905. glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  1906. for (auto &i : model.models)
  1907. {
  1908. glBindVertexArray(i.vertexArray);
  1909. //glBindBuffer(GL_ARRAY_BUFFER, i.vertexBuffer);
  1910. if (i.indexBuffer)
  1911. {
  1912. //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i.indexBuffer);
  1913. glDrawElements(GL_TRIANGLES, i.primitiveCount, GL_UNSIGNED_INT, 0);
  1914. }
  1915. else
  1916. {
  1917. glDrawArrays(GL_TRIANGLES, 0, i.primitiveCount);
  1918. }
  1919. }
  1920. glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  1921. glDepthFunc(GL_EQUAL);
  1922. GLsizei n;
  1923. glGetProgramStageiv(lightShader.geometryPassShader.id,
  1924. GL_FRAGMENT_SHADER,
  1925. GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS,
  1926. &n);
  1927. GLuint *indices = new GLuint[n]{ 0 };
  1928. bool changed = 1;
  1929. for (auto &i : model.models)
  1930. {
  1931. int materialId = getMaterialIndex(i.material);
  1932. if (materialId == -1)
  1933. { continue; }
  1934. glUniform1i(lightShader.materialIndexLocation, materialId);
  1935. TextureDataForModel textureData = materialTexturesData[materialId];
  1936. int rmaLoaded = 0;
  1937. int albedoLoaded = 0;
  1938. int normalLoaded = 0;
  1939. GpuTexture *albedoTextureData = this->getTextureData(textureData.albedoTexture);
  1940. if(albedoTextureData != nullptr )
  1941. {
  1942. albedoLoaded = 1;
  1943. glActiveTexture(GL_TEXTURE0);
  1944. glBindTexture(GL_TEXTURE_2D, albedoTextureData->id);
  1945. }
  1946. GpuTexture *normalMapTextureData = this->getTextureData(textureData.normalMapTexture);
  1947. if(normalMapTextureData != nullptr && normalMapTextureData->id != defaultTexture.id)
  1948. {
  1949. normalLoaded = 1;
  1950. glActiveTexture(GL_TEXTURE1);
  1951. glBindTexture(GL_TEXTURE_2D, normalMapTextureData->id);
  1952. }
  1953. //todo refactor default texture, just keep it totally separate and treat -1 as default texture
  1954. GpuTexture *rmaTextureData = this->getTextureData(textureData.RMA_Texture);
  1955. if(rmaTextureData != nullptr && rmaTextureData->id != defaultTexture.id)
  1956. {
  1957. rmaLoaded = 1;
  1958. glActiveTexture(GL_TEXTURE3);
  1959. glBindTexture(GL_TEXTURE_2D, rmaTextureData->id);
  1960. }
  1961. //glActiveTexture(GL_TEXTURE2);
  1962. //glBindTexture(GL_TEXTURE_CUBE_MAP, skyBox.texture); //note(vlod): this can be bound onlt once (refactor)
  1963. if (normalLoaded && lightShader.normalMap)
  1964. {
  1965. if (indices[lightShader.normalSubroutineLocation] != lightShader.normalSubroutine_normalMap)
  1966. {
  1967. indices[lightShader.normalSubroutineLocation] = lightShader.normalSubroutine_normalMap;
  1968. changed = 1;
  1969. }
  1970. }
  1971. else
  1972. {
  1973. if (indices[lightShader.normalSubroutineLocation] != lightShader.normalSubroutine_noMap)
  1974. {
  1975. indices[lightShader.normalSubroutineLocation] = lightShader.normalSubroutine_noMap;
  1976. changed = 1;
  1977. }
  1978. }
  1979. if(rmaLoaded)
  1980. {
  1981. if (indices[lightShader.materialSubroutineLocation] != lightShader.materialSubroutine_functions[textureData.RMA_loadedTextures])
  1982. {
  1983. indices[lightShader.materialSubroutineLocation] = lightShader.materialSubroutine_functions[textureData.RMA_loadedTextures];
  1984. changed = 1;
  1985. }
  1986. }else
  1987. {
  1988. if(indices[lightShader.materialSubroutineLocation] != lightShader.materialSubroutine_functions[0])
  1989. {
  1990. indices[lightShader.materialSubroutineLocation] = lightShader.materialSubroutine_functions[0];
  1991. changed = 1;
  1992. }
  1993. }
  1994. if(albedoLoaded != 0)
  1995. {
  1996. if (indices[lightShader.getAlbedoSubroutineLocation] != lightShader.albedoSubroutine_sampled)
  1997. {
  1998. indices[lightShader.getAlbedoSubroutineLocation] = lightShader.albedoSubroutine_sampled;
  1999. changed = 1;
  2000. }
  2001. }
  2002. else
  2003. if (indices[lightShader.getAlbedoSubroutineLocation] != lightShader.albedoSubroutine_notSampled)
  2004. {
  2005. indices[lightShader.getAlbedoSubroutineLocation] = lightShader.albedoSubroutine_notSampled;
  2006. changed = 1;
  2007. }
  2008. if (changed)
  2009. {
  2010. glUniformSubroutinesuiv(GL_FRAGMENT_SHADER, n, indices);
  2011. }
  2012. changed = 0;
  2013. {
  2014. glBindVertexArray(i.vertexArray);
  2015. if (i.indexBuffer)
  2016. {
  2017. glDrawElements(GL_TRIANGLES, i.primitiveCount, GL_UNSIGNED_INT, 0);
  2018. }
  2019. else
  2020. {
  2021. glDrawArrays(GL_TRIANGLES, 0, i.primitiveCount);
  2022. }
  2023. }
  2024. }
  2025. glBindVertexArray(0);
  2026. delete[] indices;
  2027. glDepthFunc(GL_LESS);
  2028. glBindFramebuffer(GL_FRAMEBUFFER, 0);
  2029. }
  2030. void Renderer3D::renderObjectNormals(Object o, glm::vec3 position, glm::vec3 rotation,
  2031. glm::vec3 scale, float normalSize, glm::vec3 normalColor)
  2032. {
  2033. auto obj = getObjectData(o);
  2034. if(!obj)
  2035. {
  2036. return;
  2037. }
  2038. for(int i=0; i<obj->models.size(); i++)
  2039. {
  2040. renderSubObjectNormals(o, i, position, rotation, scale, normalSize, normalColor);
  2041. }
  2042. }
  2043. void Renderer3D::renderSubObjectNormals(Object o, int index, glm::vec3 position, glm::vec3 rotation,
  2044. glm::vec3 scale, float normalSize, glm::vec3 normalColor)
  2045. {
  2046. showNormalsProgram.shader.bind();
  2047. auto projMat = camera.getProjectionMatrix();
  2048. auto viewMat = camera.getWorldToViewMatrix();
  2049. auto transformMat = gl3d::getTransformMatrix(position, rotation, scale);
  2050. auto viewTransformMat = viewMat * transformMat;
  2051. glUniformMatrix4fv(showNormalsProgram.modelTransformLocation,
  2052. 1, GL_FALSE, &viewTransformMat[0][0]);
  2053. glUniformMatrix4fv(showNormalsProgram.projectionLocation,
  2054. 1, GL_FALSE, &projMat[0][0]);
  2055. glUniform1f(showNormalsProgram.sizeLocation, normalSize);
  2056. glUniform3fv(showNormalsProgram.colorLocation, 1, &(normalColor[0]));
  2057. auto modelIndex = this->getObjectIndex(o);
  2058. auto obj = getObjectData(o);
  2059. if(obj == nullptr)
  2060. {
  2061. return;
  2062. }
  2063. {
  2064. if(index >= obj->models.size())
  2065. {
  2066. return;
  2067. }
  2068. auto &i = obj->models[index];
  2069. glBindVertexArray(i.vertexArray);
  2070. if (i.indexBuffer)
  2071. {
  2072. glDrawElements(GL_TRIANGLES, i.primitiveCount, GL_UNSIGNED_INT, 0);
  2073. }
  2074. else
  2075. {
  2076. glDrawArrays(GL_TRIANGLES, 0, i.primitiveCount);
  2077. }
  2078. glBindVertexArray(0);
  2079. }
  2080. }
  2081. void Renderer3D::renderSubObjectBorder(Object o, int index, glm::vec3 position, glm::vec3 rotation, glm::vec3 scale, float borderSize, glm::vec3 borderColor)
  2082. {
  2083. //auto modelIndex = this->getObjectIndex(o);
  2084. //
  2085. //auto obj = getObjectData(o);
  2086. //if (obj == nullptr)
  2087. //{
  2088. // return;
  2089. //}
  2090. //
  2091. //if (index >= obj->models.size())
  2092. //{
  2093. // return;
  2094. //}
  2095. //
  2096. //
  2097. //glEnable(GL_STENCIL_TEST);
  2098. //glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
  2099. //glStencilFunc(GL_ALWAYS, 1, 0xFF);
  2100. //glStencilMask(0xFF);
  2101. //
  2102. //auto projMat = renderer.camera.getProjectionMatrix();
  2103. //auto viewMat = renderer.camera.getWorldToViewMatrix();
  2104. //auto transformMat = models[0].getTransformMatrix();
  2105. //
  2106. //auto viewProjMat = projMat * viewMat * transformMat;
  2107. //
  2108. ////todo implement a light weight shader here
  2109. ////lightShader.bind(viewProjMat, transformMat,
  2110. //// lightCubeModel.position, renderer.camera.position, gamaCorection,
  2111. //// models[itemCurrent].models[subItemCurent].material, renderer.pointLights);
  2112. //
  2113. //glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  2114. //models[itemCurrent].models[subItemCurent].draw();
  2115. //glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  2116. //
  2117. //glDisable(GL_STENCIL_TEST);
  2118. //
  2119. //glEnable(GL_STENCIL_TEST);
  2120. //glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
  2121. //glDepthFunc(GL_ALWAYS);
  2122. //glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
  2123. //glStencilMask(0x00);
  2124. //
  2125. //auto &m = models[itemCurrent].models[subItemCurent];
  2126. //projMat = renderer.camera.getProjectionMatrix();
  2127. //viewMat = renderer.camera.getWorldToViewMatrix();
  2128. //
  2129. //auto rotation = models[itemCurrent].rotation;
  2130. //auto scale = models[itemCurrent].scale;
  2131. //scale *= 1.05;
  2132. //auto position = models[itemCurrent].position;
  2133. //
  2134. //
  2135. //auto s = glm::scale(scale);
  2136. //auto r = glm::rotate(rotation.x, glm::vec3(1, 0, 0)) *
  2137. // glm::rotate(rotation.y, glm::vec3(0, 1, 0)) *
  2138. // glm::rotate(rotation.z, glm::vec3(0, 0, 1));
  2139. //auto t = glm::translate(position);
  2140. //
  2141. //transformMat = t * r * s;
  2142. //
  2143. //viewProjMat = projMat * viewMat * transformMat;
  2144. //
  2145. //shader.bind();
  2146. //glUniformMatrix4fv(location, 1, GL_FALSE, &viewProjMat[0][0]);
  2147. //
  2148. //glBindBuffer(GL_ARRAY_BUFFER, m.vertexBuffer);
  2149. //
  2150. //glEnableVertexAttribArray(0);
  2151. //glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)0);
  2152. //glVertexAttrib3f(1, 98 / 255.f, 24 / 255.f, 201 / 255.f);
  2153. //
  2154. //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m.indexBuffer);
  2155. //glDrawElements(GL_TRIANGLES, m.primitiveCount, GL_UNSIGNED_INT, 0);
  2156. //
  2157. //glDisable(GL_STENCIL_TEST);
  2158. //glDepthFunc(GL_LESS);
  2159. }
  2160. int Renderer3D::getMaterialIndex(Material m)
  2161. {
  2162. int id = m.id_;
  2163. auto found = std::find(materialIndexes.begin(), materialIndexes.end(), id);
  2164. if (found == materialIndexes.end())
  2165. {
  2166. gl3dAssertComment(found == materialIndexes.end(), "invalid material");
  2167. return -1;
  2168. }
  2169. id = found - materialIndexes.begin();
  2170. return id;
  2171. }
  2172. int Renderer3D::getObjectIndex(Object o)
  2173. {
  2174. int id = o.id_;
  2175. auto found = std::find(graphicModelsIndexes.begin(), graphicModelsIndexes.end(), id);
  2176. if (found == graphicModelsIndexes.end())
  2177. {
  2178. gl3dAssertComment(found == graphicModelsIndexes.end(), "invalid object");
  2179. return -1;
  2180. }
  2181. id = found - graphicModelsIndexes.begin();
  2182. return id;
  2183. }
  2184. int Renderer3D::getTextureIndex(Texture t)
  2185. {
  2186. int id = t.id_;
  2187. if (id == 0) { return -1; }//todo add this optimization to other gets
  2188. auto found = std::find(loadedTexturesIndexes.begin(), loadedTexturesIndexes.end(), id);
  2189. if (found == loadedTexturesIndexes.end())
  2190. {
  2191. gl3dAssertComment(found == loadedTexturesIndexes.end(), "invalid texture");
  2192. return -1;
  2193. }
  2194. id = found - loadedTexturesIndexes.begin();
  2195. return id;
  2196. }
  2197. void Renderer3D::render()
  2198. {
  2199. //glAnyCheck();
  2200. //we draw a rect several times so we keep this vao binded
  2201. glBindVertexArray(lightShader.quadVAO);
  2202. #pragma region ssao
  2203. glViewport(0, 0, w / 2, h / 2);
  2204. glUseProgram(ssao.shader.id);
  2205. glUniformMatrix4fv(ssao.u_projection, 1, GL_FALSE,
  2206. &(camera.getProjectionMatrix())[0][0] );
  2207. glUniformMatrix4fv(ssao.u_view, 1, GL_FALSE,
  2208. &(camera.getWorldToViewMatrix())[0][0]);
  2209. glUniform3fv(ssao.u_samples, 64, &(ssao.ssaoKernel[0][0]));
  2210. glBindFramebuffer(GL_FRAMEBUFFER, ssao.ssaoFBO);
  2211. glClear(GL_COLOR_BUFFER_BIT);
  2212. glActiveTexture(GL_TEXTURE0);
  2213. glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.positionViewSpace]);
  2214. glUniform1i(ssao.u_gPosition, 0);
  2215. glActiveTexture(GL_TEXTURE1);
  2216. glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.normal]);
  2217. glUniform1i(ssao.u_gNormal, 1);
  2218. glActiveTexture(GL_TEXTURE2);
  2219. glBindTexture(GL_TEXTURE_2D, ssao.noiseTexture);
  2220. glUniform1i(ssao.u_texNoise, 2);
  2221. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  2222. glViewport(0, 0, w, h);
  2223. #pragma endregion
  2224. #pragma region ssao "blur" (more like average blur)
  2225. glViewport(0, 0, w/4, h/4);
  2226. glBindFramebuffer(GL_FRAMEBUFFER, ssao.blurBuffer);
  2227. ssao.blurShader.bind();
  2228. glClear(GL_COLOR_BUFFER_BIT);
  2229. glActiveTexture(GL_TEXTURE0);
  2230. glBindTexture(GL_TEXTURE_2D, ssao.ssaoColorBuffer);
  2231. glUniform1i(ssao.u_ssaoInput, 0);
  2232. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  2233. glViewport(0, 0, w, h);
  2234. #pragma endregion
  2235. #pragma region render into the bloom post processing fbo
  2236. glBindFramebuffer(GL_FRAMEBUFFER, postProcess.fbo);
  2237. glClear(GL_COLOR_BUFFER_BIT);
  2238. glUseProgram(lightShader.lightingPassShader.id);
  2239. glUniform1i(lightShader.light_u_positions, 0);
  2240. glActiveTexture(GL_TEXTURE0);
  2241. glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.position]);
  2242. glUniform1i(lightShader.light_u_normals, 1);
  2243. glActiveTexture(GL_TEXTURE1);
  2244. glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.normal]);
  2245. glUniform1i(lightShader.light_u_albedo, 2);
  2246. glActiveTexture(GL_TEXTURE2);
  2247. glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.albedo]);
  2248. glUniform1i(lightShader.light_u_materials, 3);
  2249. glActiveTexture(GL_TEXTURE3);
  2250. glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.material]);
  2251. glUniform1i(lightShader.light_u_ssao, 4);
  2252. glActiveTexture(GL_TEXTURE4);
  2253. glBindTexture(GL_TEXTURE_2D, ssao.blurColorBuffer);
  2254. //glBindTexture(GL_TEXTURE_2D, ssao.ssaoColorBuffer);
  2255. glUniform3f(lightShader.light_u_eyePosition, camera.position.x, camera.position.y, camera.position.z);
  2256. glUniformMatrix4fv(lightShader.light_u_view, 1, GL_FALSE, &(camera.getWorldToViewMatrix()[0][0]) );
  2257. if (pointLights.size())
  2258. {
  2259. glBindBuffer(GL_SHADER_STORAGE_BUFFER, lightShader.pointLightsBlockBuffer);
  2260. glBufferData(GL_SHADER_STORAGE_BUFFER, pointLights.size() * sizeof(internal::GpuPointLight)
  2261. , &pointLights[0], GL_STREAM_DRAW);
  2262. glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, lightShader.pointLightsBlockBuffer);
  2263. }
  2264. glUniform1i(lightShader.light_u_pointLightCount, pointLights.size());
  2265. glUniform1i(lightShader.u_useSSAO, lightShader.useSSAO);
  2266. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  2267. #pragma endregion
  2268. #pragma region bloom blur
  2269. if(lightShader.bloom)
  2270. {
  2271. int blurs = 16;
  2272. bool horizontal = 1; bool firstTime = 1;
  2273. postProcess.gausianBLurShader.bind();
  2274. glActiveTexture(GL_TEXTURE0);
  2275. glUniform1i(postProcess.u_toBlurcolorInput, 0);
  2276. glViewport(0, 0, w/2, h/2);
  2277. for (int i = 0; i < blurs; i++)
  2278. {
  2279. glBindFramebuffer(GL_FRAMEBUFFER, postProcess.blurFbo[horizontal]);
  2280. glClear(GL_COLOR_BUFFER_BIT);
  2281. glUniform1i(postProcess.u_horizontal, horizontal);
  2282. glBindTexture(GL_TEXTURE_2D,
  2283. firstTime ? postProcess.colorBuffers[1] : postProcess.bluredColorBuffer[!horizontal]);
  2284. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  2285. horizontal = !horizontal;
  2286. firstTime = false;
  2287. }
  2288. glViewport(0, 0, w, h);
  2289. }
  2290. #pragma endregion
  2291. #pragma region do the post process stuff and draw to screen
  2292. glBindFramebuffer(GL_FRAMEBUFFER, 0);
  2293. glUseProgram(postProcess.postProcessShader.id);
  2294. //color data
  2295. glUniform1i(postProcess.u_colorTexture, 0);
  2296. glActiveTexture(GL_TEXTURE0);
  2297. glBindTexture(GL_TEXTURE_2D, postProcess.colorBuffers[0]);
  2298. //bloom data
  2299. glUniform1i(postProcess.u_bloomTexture, 1);
  2300. glActiveTexture(GL_TEXTURE1);
  2301. if(lightShader.bloom)
  2302. {
  2303. glBindTexture(GL_TEXTURE_2D, postProcess.bluredColorBuffer[1]);
  2304. }else
  2305. {
  2306. glBindTexture(GL_TEXTURE_2D, postProcess.colorBuffers[1]);
  2307. }
  2308. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  2309. #pragma endregion
  2310. #pragma region copy depth buffer for later forward rendering
  2311. glBindVertexArray(0);
  2312. glBindFramebuffer(GL_READ_FRAMEBUFFER, gBuffer.gBuffer);
  2313. glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); // write to default framebuffer
  2314. glBlitFramebuffer(
  2315. 0, 0, w, h, 0, 0, w, h, GL_DEPTH_BUFFER_BIT, GL_NEAREST
  2316. );
  2317. glBindFramebuffer(GL_FRAMEBUFFER, gBuffer.gBuffer);
  2318. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  2319. glBindFramebuffer(GL_FRAMEBUFFER, 0);
  2320. #pragma endregion
  2321. }
  2322. void Renderer3D::updateWindowMetrics(int x, int y)
  2323. {
  2324. w = x; h = y;
  2325. glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.position]);
  2326. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, x, y, 0, GL_RGBA, GL_FLOAT, NULL);
  2327. glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.normal]);
  2328. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, x, y, 0, GL_RGBA, GL_FLOAT, NULL);
  2329. glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.albedo]);
  2330. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  2331. glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.material]);
  2332. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  2333. glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.positionViewSpace]);
  2334. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, x, y, 0, GL_RGBA, GL_FLOAT, NULL);
  2335. glBindRenderbuffer(GL_RENDERBUFFER, gBuffer.depthBuffer);
  2336. glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, x, y);
  2337. //ssao
  2338. glBindTexture(GL_TEXTURE_2D, ssao.ssaoColorBuffer);
  2339. glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w/2, h/2, 0, GL_RED, GL_FLOAT, NULL);
  2340. glBindTexture(GL_TEXTURE_2D, ssao.blurColorBuffer);
  2341. glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w/4, h/4, 0, GL_RED, GL_FLOAT, NULL);
  2342. //bloom
  2343. for (int i = 0; i < 2; i++)
  2344. {
  2345. glBindTexture(GL_TEXTURE_2D, postProcess.colorBuffers[i]);
  2346. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  2347. }
  2348. for(int i=0;i<2;i++)
  2349. {
  2350. glBindTexture(GL_TEXTURE_2D, postProcess.bluredColorBuffer[i]);
  2351. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w/2, h/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  2352. }
  2353. }
  2354. float lerp(float a, float b, float f)
  2355. {
  2356. return a + f * (b - a);
  2357. }
  2358. void Renderer3D::SSAO::create(int w, int h)
  2359. {
  2360. std::uniform_real_distribution<float> randomFloats(0.0f, 1.0f);
  2361. std::uniform_real_distribution<float> randomFloatsSmaller(0.1f, 0.9f); //avoid ssao artefacts
  2362. std::default_random_engine generator;
  2363. ssaoKernel.reserve(64);
  2364. for (unsigned int i = 0; i < 64; ++i)
  2365. {
  2366. glm::vec3 sample(
  2367. randomFloats(generator) * 2.0 - 1.0,
  2368. randomFloats(generator) * 2.0 - 1.0,
  2369. randomFloats(generator) // z component is always positive
  2370. );
  2371. sample = glm::normalize(sample);
  2372. float scale = (float)i / 64.0;
  2373. scale = lerp(0.1f, 1.0f, scale * scale);
  2374. sample *= scale;
  2375. ssaoKernel.push_back(sample);
  2376. }
  2377. //std::shuffle(ssaoKernel.begin(), ssaoKernel.end(), generator);
  2378. std::vector<glm::vec3> ssaoNoise;
  2379. for (unsigned int i = 0; i < 16; i++)
  2380. {
  2381. glm::vec3 noise(
  2382. randomFloats(generator) * 2.0 - 1.0,
  2383. randomFloats(generator) * 2.0 - 1.0,
  2384. 0.0f);
  2385. ssaoNoise.push_back(noise);
  2386. }
  2387. glGenTextures(1, &noiseTexture);
  2388. glBindTexture(GL_TEXTURE_2D, noiseTexture);
  2389. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, 4, 4, 0, GL_RGB, GL_FLOAT, &ssaoNoise[0]);
  2390. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  2391. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  2392. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  2393. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  2394. glGenFramebuffers(1, &ssaoFBO);
  2395. glBindFramebuffer(GL_FRAMEBUFFER, ssaoFBO);
  2396. glGenTextures(1, &ssaoColorBuffer);
  2397. glBindTexture(GL_TEXTURE_2D, ssaoColorBuffer);
  2398. glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w/2, h/2, 0, GL_RED, GL_FLOAT, NULL);
  2399. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  2400. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  2401. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  2402. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  2403. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ssaoColorBuffer, 0);
  2404. if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
  2405. {
  2406. std::cout << "ssaoFBO failed\n";
  2407. }
  2408. shader.loadShaderProgramFromFile("shaders/ssao/ssao.vert", "shaders/ssao/ssao.frag");
  2409. u_projection = getUniform(shader.id, "u_projection");
  2410. u_view = getUniform(shader.id, "u_view");
  2411. u_gPosition = getUniform(shader.id, "u_gPosition");
  2412. u_gNormal = getUniform(shader.id, "u_gNormal");
  2413. u_texNoise = getUniform(shader.id, "u_texNoise");
  2414. u_samples = getUniform(shader.id, "samples[0]");
  2415. //blur
  2416. blurShader.loadShaderProgramFromFile("shaders/ssao/blur.vert", "shaders/ssao/blur.frag");
  2417. glGenFramebuffers(1, &blurBuffer);
  2418. glBindFramebuffer(GL_FRAMEBUFFER, blurBuffer);
  2419. glGenTextures(1, &blurColorBuffer);
  2420. glBindTexture(GL_TEXTURE_2D, blurColorBuffer);
  2421. glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w/4, h/4, 0, GL_RED, GL_FLOAT, NULL);
  2422. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  2423. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  2424. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  2425. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  2426. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, blurColorBuffer, 0);
  2427. u_ssaoInput = getUniform(blurShader.id, "u_ssaoInput");
  2428. if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
  2429. {
  2430. std::cout << "blur ssao buffer failed\n";
  2431. }
  2432. glBindFramebuffer(GL_FRAMEBUFFER, 0);
  2433. }
  2434. void Renderer3D::PostProcess::create(int w, int h)
  2435. {
  2436. glGenFramebuffers(1, &fbo);
  2437. glBindFramebuffer(GL_FRAMEBUFFER, fbo);
  2438. glGenTextures(2, colorBuffers);
  2439. for (int i = 0; i < 2; i++)
  2440. {
  2441. glBindTexture(GL_TEXTURE_2D, colorBuffers[i]);
  2442. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  2443. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  2444. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  2445. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  2446. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  2447. // attach texture to framebuffer
  2448. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, colorBuffers[i], 0);
  2449. }
  2450. unsigned int attachments[2] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
  2451. glDrawBuffers(2, attachments);
  2452. if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
  2453. {
  2454. std::cout << "post process fbo failed\n";
  2455. }
  2456. postProcessShader.loadShaderProgramFromFile("shaders/postProcess/postProcess.vert", "shaders/postProcess/postProcess.frag");
  2457. u_colorTexture = getUniform(postProcessShader.id, "u_colorTexture");
  2458. u_bloomTexture = getUniform(postProcessShader.id, "u_bloomTexture");
  2459. gausianBLurShader.loadShaderProgramFromFile("shaders/postProcess/gausianBlur.vert", "shaders/postProcess/gausianBlur.frag");
  2460. u_toBlurcolorInput = getUniform(gausianBLurShader.id, "u_toBlurcolorInput");
  2461. u_horizontal = getUniform(gausianBLurShader.id, "u_horizontal");
  2462. glGenFramebuffers(2, blurFbo);
  2463. glGenTextures(2, bluredColorBuffer);
  2464. for(int i=0;i <2; i++)
  2465. {
  2466. glBindFramebuffer(GL_FRAMEBUFFER, blurFbo[i]);
  2467. glBindTexture(GL_TEXTURE_2D, bluredColorBuffer[i]);
  2468. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w/2, h/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  2469. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  2470. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  2471. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  2472. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  2473. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, bluredColorBuffer[i], 0);
  2474. if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
  2475. {
  2476. std::cout << "blur post process fbo " << i << " failed\n";
  2477. }
  2478. }
  2479. glBindFramebuffer(GL_FRAMEBUFFER, 0);
  2480. }
  2481. };
  2482. #pragma endregion