| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314 |
- ////////////////////////////////////////////////
- //gl32 --Vlad Luta --
- //built on 2021-04-26
- ////////////////////////////////////////////////
- #include "gl3d.h"
- ////////////////////////////////////////////////
- //Core.cpp
- ////////////////////////////////////////////////
- #pragma region Core
- #include <stdio.h>
- #include <Windows.h>
- #include <signal.h>
- namespace gl3d
- {
- void assertFunc(const char *expression,
- const char *file_name,
- unsigned const line_number,
- const char *comment)
- {
-
- char c[1024] = {};
- sprintf(c,
- "Assertion failed\n\n"
- "File:\n"
- "%s\n\n"
- "Line:\n"
- "%u\n\n"
- "Expresion:\n"
- "%s\n\n"
- "Comment:\n"
- "%s",
- file_name,
- line_number,
- expression,
- comment
- );
- int const action = MessageBox(0, c, "Platform Layer", MB_TASKMODAL
- | MB_ICONHAND | MB_ABORTRETRYIGNORE | MB_SETFOREGROUND);
- switch (action)
- {
- case IDABORT: // Abort the program:
- {
- raise(SIGABRT);
- // We won't usually get here, but it's possible that a user-registered
- // abort handler returns, so exit the program immediately. Note that
- // even though we are "aborting," we do not call abort() because we do
- // not want to invoke Watson (the user has already had an opportunity
- // to debug the error and chose not to).
- _exit(3);
- }
- case IDRETRY: // Break into the debugger then return control to caller
- {
- __debugbreak();
- return;
- }
- case IDIGNORE: // Return control to caller
- {
- return;
- }
- default: // This should not happen; treat as fatal error:
- {
- abort();
- }
- }
-
- }
- };
- #pragma endregion
- ////////////////////////////////////////////////
- //Texture.cpp
- ////////////////////////////////////////////////
- #pragma region Texture
- #include <stb_image.h>
- #include <iostream>
- #include <glm\vec3.hpp>
- #include <algorithm>
- namespace gl3d
- {
- void GpuTexture::loadTextureFromFile(const char *file, int quality)
- {
- int w, h, nrChannels;
- stbi_set_flip_vertically_on_load(true);
- unsigned char *data = stbi_load(file, &w, &h, &nrChannels, 4);
- if (!data)
- {
- //todo err messages
- std::cout << "err: " << file << "\n";
- id = 0;
- }
- else
- {
- loadTextureFromMemory(data, w, h, 4, quality);
- stbi_image_free(data);
- }
- }
- //todo add srgb
- //todo add quality enum
-
- void GpuTexture::loadTextureFromMemory(void *data, int w, int h, int chanels,
- int quality)
- {
- GLenum format = GL_RGBA;
- if(chanels == 3)
- {
- format = GL_RGB;
- }
- gl3dAssertComment(chanels == 3 || chanels == 4, "invalid chanel number");
- glGenTextures(1, &id);
- glBindTexture(GL_TEXTURE_2D, id);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, format, GL_UNSIGNED_BYTE, data);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- setTextureQuality(quality);
- glGenerateMipmap(GL_TEXTURE_2D);
- }
- void GpuTexture::clear()
- {
- glDeleteTextures(1, &id);
- id = 0;
- }
- void GpuTexture::setTextureQuality(int quality)
- {
- if (!id)
- return;
- glBindTexture(GL_TEXTURE_2D, id);
- switch (quality)
- {
- case leastPossible:
- {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY, 1);
- glAnyCheck();
- }
- break;
- case nearestMipmap:
- {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY, 1);
- }
- break;
- case linearMipmap:
- {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY, 4);
- }
- break;
- case maxQuality:
- {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY, 4);
- }
- break;
- default:
- gl3dAssertComment(0, "invalid quality");
- break;
- }
- }
- int GpuTexture::getTextureQuality()
- {
- if(id == leastPossible)
- {
- return 0;
- }
- glBindTexture(GL_TEXTURE_2D, id);
- int param = 0;
- glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, ¶m);
- switch (param)
- {
- case GL_NEAREST:
- {
- return leastPossible;
- }
- break;
- case GL_NEAREST_MIPMAP_NEAREST:
- {
- return nearestMipmap;
- }
- break;
- case GL_LINEAR_MIPMAP_NEAREST:
- {
- return linearMipmap;
- }
- break;
- case GL_LINEAR_MIPMAP_LINEAR:
- {
- return maxQuality;
- }
- break;
-
- }
- return leastPossible;
- }
- void gausianBlurRGB(unsigned char *data, int w, int h, int kernel)
- {
- unsigned char *newImage = new unsigned char[w * h * 3];
- //todo refactor refactor refactor
- //todo actually compute this on the gpu
- auto horiz = [&](int kernel)
- {
- //horizontal blur
- for (int y = 0; y < h; y++)
- {
- for (int x = 0; x < w; x++)
- {
- glm::tvec3<int> colors = {};
- int beg = std::max(0, x - kernel);
- int end = std::min(x + kernel + 1, w);
- for (int i = beg; i < end; i++)
- {
- colors.r += data[(i + y * w) * 3 + 0];
- colors.g += data[(i + y * w) * 3 + 1];
- colors.b += data[(i + y * w) * 3 + 2];
- }
- if (x - kernel < 0)
- for (int i = kernel - x - 1; i >= 0; i--)
- {
- colors.r += data[(i + y * w) * 3 + 0];
- colors.g += data[(i + y * w) * 3 + 1];
- colors.b += data[(i + y * w) * 3 + 2];
- }
- if (x + kernel >= w)
- for (int i = w - 1; i >= w - (x + kernel - w + 1); i--)
- {
- colors.r += data[(i + y * w) * 3 + 0];
- colors.g += data[(i + y * w) * 3 + 1];
- colors.b += data[(i + y * w) * 3 + 2];
- }
- colors /= kernel * 2 + 1;
- //colors /= end - beg;
- newImage[(x + y * w) * 3 + 0] = colors.r;
- newImage[(x + y * w) * 3 + 1] = colors.g;
- newImage[(x + y * w) * 3 + 2] = colors.b;
- }
- }
- };
- auto vert = [&](int kernel)
- {
- //vertical blur
- for (int x = 0; x < w; x++)
- {
- for (int y = 0; y < h; y++)
- {
- glm::tvec3<int> colors = {};
- int beg = std::max(0, y - kernel);
- int end = std::min(y + kernel + 1, h);
- for (int j = beg; j < end; j++)
- {
- colors.r += data[(x + j * w) * 3 + 0];
- colors.g += data[(x + j * w) * 3 + 1];
- colors.b += data[(x + j * w) * 3 + 2];
- }
- if (y - kernel < 0)
- for (int j = kernel - y - 1; j >= 0; j--)
- {
- colors.r += data[(x + j * w) * 3 + 0];
- colors.g += data[(x + j * w) * 3 + 1];
- colors.b += data[(x + j * w) * 3 + 2];
- }
- if (y + kernel >= h)
- for (int j = h - 1; j >= h - (y + kernel - h + 1); j--)
- {
- colors.r += data[(x + j * w) * 3 + 0];
- colors.g += data[(x + j * w) * 3 + 1];
- colors.b += data[(x + j * w) * 3 + 2];
- }
- colors /= kernel * 2 + 1;
- //colors /= end - beg;
- newImage[(x + y * w) * 3 + 0] = colors.r;
- newImage[(x + y * w) * 3 + 1] = colors.g;
- newImage[(x + y * w) * 3 + 2] = colors.b;
- }
- }
- };
- int iterations = 2;
- for(int i=0;i<iterations;i++)
- {
- horiz(kernel);
- vert(kernel);
- }
-
- for (int i = 0; i < w * h * 3; i++)
- {
- data[i] = newImage[i];
- }
- delete newImage;
- }
-
- };
- #pragma endregion
- ////////////////////////////////////////////////
- //Shader.cpp
- ////////////////////////////////////////////////
- #pragma region Shader
- #include <fstream>
- #include <iostream>
- namespace gl3d
- {
- GLint createShaderFromFile(const char *source, GLenum shaderType)
- {
- std::ifstream file;
- file.open(source);
- if (!file.is_open())
- {
- std::cout << "Error openning file: " << source << "\n";
- return 0;
- }
- GLint size = 0;
- file.seekg(0, file.end);
- size = file.tellg();
- file.seekg(0, file.beg);
- char *fileContent = new char[size] {};
- file.read(fileContent, size);
- file.close();
- GLuint shaderId = glCreateShader(shaderType);
- glShaderSource(shaderId, 1, &fileContent, &size);
- glCompileShader(shaderId);
- delete[] fileContent;
- GLint rezult = 0;
- glGetShaderiv(shaderId, GL_COMPILE_STATUS, &rezult);
- if (!rezult)
- {
- char *message = 0;
- int l = 0;
- glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &l);
- if(l)
- {
- message = new char[l];
- glGetShaderInfoLog(shaderId, l, &l, message);
- message[l - 1] = 0;
- std::cout << source << ": " << message << "\n";
- delete[] message;
-
- }else
- {
- std::cout << source << ": " << "unknown error"<< "\n";
- }
- glDeleteShader(shaderId);
- shaderId = 0;
- return shaderId;
- }
- return shaderId;
- }
- bool Shader::loadShaderProgramFromFile(const char *vertexShader, const char *fragmentShader)
- {
- auto vertexId = createShaderFromFile(vertexShader, GL_VERTEX_SHADER);
- auto fragmentId = createShaderFromFile(fragmentShader, GL_FRAGMENT_SHADER);
- if (vertexId == 0 || fragmentId == 0)
- {
- return 0;
- }
- id = glCreateProgram();
- glAttachShader(id, vertexId);
- glAttachShader(id, fragmentId);
- glLinkProgram(id);
- glDeleteShader(vertexId);
- glDeleteShader(fragmentId);
- GLint info = 0;
- glGetProgramiv(id, GL_LINK_STATUS, &info);
- if (info != GL_TRUE)
- {
- char *message = 0;
- int l = 0;
- glGetProgramiv(id, GL_INFO_LOG_LENGTH, &l);
- message = new char[l];
- glGetProgramInfoLog(id, l, &l, message);
- std::cout << "Link error: " << message << "\n";
- delete[] message;
- glDeleteProgram(id);
- id = 0;
- return 0;
- }
- glValidateProgram(id);
- return true;
- }
- bool Shader::loadShaderProgramFromFile(const char *vertexShader, const char *geometryShader, const char *fragmentShader)
- {
- auto vertexId = createShaderFromFile(vertexShader, GL_VERTEX_SHADER);
- auto geometryId = createShaderFromFile(geometryShader, GL_GEOMETRY_SHADER);
- auto fragmentId = createShaderFromFile(fragmentShader, GL_FRAGMENT_SHADER);
- if (vertexId == 0 || fragmentId == 0 || geometryId == 0)
- {
- return 0;
- }
- id = glCreateProgram();
- glAttachShader(id, vertexId);
- glAttachShader(id, geometryId);
- glAttachShader(id, fragmentId);
- glLinkProgram(id);
- glDeleteShader(vertexId);
- glDeleteShader(geometryId);
- glDeleteShader(fragmentId);
- GLint info = 0;
- glGetProgramiv(id, GL_LINK_STATUS, &info);
- if (info != GL_TRUE)
- {
- char *message = 0;
- int l = 0;
- glGetProgramiv(id, GL_INFO_LOG_LENGTH, &l);
- message = new char[l];
- glGetProgramInfoLog(id, l, &l, message);
- std::cout << "Link error: " << message << "\n";
- delete[] message;
- glDeleteProgram(id);
- id = 0;
- return 0;
- }
- glValidateProgram(id);
- return true;
- }
- void Shader::bind()
- {
- glUseProgram(id);
- }
- void Shader::clear()
- {
- glDeleteProgram(id);
- id = 0;
- }
- GLint getUniformSubroutine(GLuint id, GLenum shaderType, const char *name)
- {
- GLint uniform = glGetSubroutineUniformLocation(id, shaderType, name);
- if (uniform == -1)
- {
- std::cout << "uniform subroutine error " << name << "\n";
- }
- return uniform;
- };
- GLint getUniform(GLuint id, const char *name)
- {
- GLint uniform = glGetUniformLocation(id, name);
- if (uniform == -1)
- {
- std::cout << "uniform error " << name << "\n";
- }
- return uniform;
- };
- GLuint getUniformBlock(GLuint id, const char *name)
- {
- GLuint uniform = glGetUniformBlockIndex(id, name);
- if (uniform == GL_INVALID_INDEX)
- {
- std::cout << "uniform block error " << name << "\n";
- }
- return uniform;
- };
- GLuint getUniformSubroutineIndex(GLuint id, GLenum shaderType, const char *name)
- {
- GLuint uniform = glGetSubroutineIndex(id, shaderType, name);
- if (uniform == GL_INVALID_INDEX)
- {
- std::cout << "uniform subroutine index error " << name << "\n";
- }
- return uniform;
- };
- GLuint getStorageBlockIndex(GLuint id, const char *name)
- {
- GLuint uniform = glGetProgramResourceIndex(id, GL_SHADER_STORAGE_BLOCK, name);
- if (uniform == GL_INVALID_INDEX)
- {
- std::cout << "storage block index error " << name << "\n";
- }
- return uniform;
- };
- void LightShader::create()
- {
- geometryPassShader.loadShaderProgramFromFile("shaders/deferred/geometryPass.vert", "shaders/deferred/geometryPass.frag");
- geometryPassShader.bind();
- u_transform = getUniform(geometryPassShader.id, "u_transform");
- u_modelTransform = getUniform(geometryPassShader.id, "u_modelTransform");
- u_motelViewTransform = getUniform(geometryPassShader.id, "u_motelViewTransform");
- //normalShaderLightposLocation = getUniform(shader.id, "u_lightPosition");
- textureSamplerLocation = getUniform(geometryPassShader.id, "u_albedoSampler");
- normalMapSamplerLocation = getUniform(geometryPassShader.id, "u_normalSampler");
- //eyePositionLocation = getUniform(shader.id, "u_eyePosition");
- //skyBoxSamplerLocation = getUniform(textureSamplerLocation.id, "u_skybox");
- //gamaLocation = getUniform(shader.id, "u_gama");
- RMASamplerLocation = getUniform(geometryPassShader.id, "u_RMASampler");
- //pointLightCountLocation = getUniform(shader.id, "u_pointLightCount");
- materialIndexLocation = getUniform(geometryPassShader.id, "u_materialIndex");
- //pointLightBufferLocation = getUniform(shader.id, "u_pointLights");
-
- //todo geb buffer for each material
- materialBlockLocation = getStorageBlockIndex(geometryPassShader.id, "u_material");
- glShaderStorageBlockBinding(geometryPassShader.id, materialBlockLocation, 0);
- glGenBuffers(1, &materialBlockBuffer);
- glBindBuffer(GL_SHADER_STORAGE_BUFFER, materialBlockBuffer);
- lightingPassShader.loadShaderProgramFromFile("shaders/deferred/lightingPass.vert", "shaders/deferred/lightingPass.frag");
- lightingPassShader.bind();
- light_u_albedo = getUniform(lightingPassShader.id, "u_albedo");
- light_u_normals = getUniform(lightingPassShader.id, "u_normals");
- light_u_skybox = getUniform(lightingPassShader.id, "u_skybox");
- light_u_positions = getUniform(lightingPassShader.id, "u_positions");
- light_u_materials = getUniform(lightingPassShader.id, "u_materials");
- light_u_eyePosition = getUniform(lightingPassShader.id, "u_eyePosition");
- light_u_pointLightCount = getUniform(lightingPassShader.id, "u_pointLightCount");
- light_u_ssao = getUniform(lightingPassShader.id, "u_ssao");
- light_u_view = getUniform(lightingPassShader.id, "u_view");
- u_useSSAO = getUniform(lightingPassShader.id, "u_useSSAO");
- pointLightsBlockLocation = getStorageBlockIndex(lightingPassShader.id, "u_pointLights");
- glShaderStorageBlockBinding(lightingPassShader.id, pointLightsBlockLocation, 1);
- glGenBuffers(1, &pointLightsBlockBuffer);
- glBindBuffer(GL_SHADER_STORAGE_BUFFER, pointLightsBlockBuffer);
- glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, pointLightsBlockBuffer);
- glGenVertexArrays(1, &quadVAO);
- glBindVertexArray(quadVAO);
- glGenBuffers(1, &quadBuffer);
- glBindBuffer(GL_ARRAY_BUFFER, quadBuffer);
- float quadVertices[] = {
- // positions // texture Coords
- -1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
- -1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
- 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
- 1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
- };
- // setup plane VAO
-
- glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *)0);
- glEnableVertexAttribArray(1);
- glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *)(3 * sizeof(float)));
- glBindVertexArray(0);
- }
- void LightShader::bind(const glm::mat4 &viewProjMat, const glm::mat4 &transformMat,
- const glm::vec3 &lightPosition, const glm::vec3 &eyePosition, float gama,
- const GpuMaterial &material, std::vector<internal::GpuPointLight> &pointLights)
- {
- geometryPassShader.bind();
-
- this->setData(viewProjMat, transformMat, lightPosition, eyePosition, gama,
- material, pointLights);
-
- }
- void LightShader::setData(const glm::mat4 &viewProjMat,
- const glm::mat4 &transformMat, const glm::vec3 &lightPosition, const glm::vec3 &eyePosition,
- float gama, const GpuMaterial &material, std::vector<internal::GpuPointLight> &pointLights)
- {
- glUniformMatrix4fv(u_transform, 1, GL_FALSE, &viewProjMat[0][0]);
- glUniformMatrix4fv(u_modelTransform, 1, GL_FALSE, &transformMat[0][0]);
- glUniform3fv(normalShaderLightposLocation, 1, &lightPosition[0]);
- glUniform3fv(eyePositionLocation, 1, &eyePosition[0]);
- glUniform1i(textureSamplerLocation, 0);
- glUniform1i(normalMapSamplerLocation, 1);
- glUniform1i(skyBoxSamplerLocation, 2);
- glUniform1i(RMASamplerLocation, 3);
- if(pointLights.size())
- {
- glBindBuffer(GL_SHADER_STORAGE_BUFFER, pointLightsBlockBuffer);
- glBufferData(GL_SHADER_STORAGE_BUFFER, pointLights.size() * sizeof(internal::GpuPointLight)
- ,&pointLights[0], GL_STREAM_DRAW);
- glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, pointLightsBlockBuffer);
- }
- //glUniform1fv(pointLightBufferLocation, pointLights.size() * 8, (float*)pointLights.data());
- glUniform1i(pointLightCountLocation, pointLights.size());
- setMaterial(material);
- }
- void LightShader::setMaterial(const GpuMaterial &material)
- {
- glBindBuffer(GL_SHADER_STORAGE_BUFFER, materialBlockBuffer);
- glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(material)
- , &material, GL_STREAM_DRAW);
- glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, materialBlockBuffer);
- glUniform1i(materialIndexLocation, 0);
- }
- void LightShader::getSubroutines()
- {
- normalSubroutine_noMap = getUniformSubroutineIndex(geometryPassShader.id, GL_FRAGMENT_SHADER,
- "noNormalMapped");
- normalSubroutine_normalMap = getUniformSubroutineIndex(geometryPassShader.id, GL_FRAGMENT_SHADER,
- "normalMapped");
-
- //
- albedoSubroutine_sampled = getUniformSubroutineIndex(geometryPassShader.id, GL_FRAGMENT_SHADER,
- "sampledAlbedo");
- albedoSubroutine_notSampled = getUniformSubroutineIndex(geometryPassShader.id, GL_FRAGMENT_SHADER,
- "notSampledAlbedo");
- //
- normalSubroutineLocation = getUniformSubroutine(geometryPassShader.id, GL_FRAGMENT_SHADER,
- "getNormalMapFunc");
- materialSubroutineLocation = getUniformSubroutine(geometryPassShader.id, GL_FRAGMENT_SHADER,
- "u_getMaterialMapped");
- getAlbedoSubroutineLocation = getUniformSubroutine(geometryPassShader.id, GL_FRAGMENT_SHADER,
- "u_getAlbedo");
- const char *materiaSubroutineFunctions[8] = {
- "materialNone",
- "materialR",
- "materialM",
- "materialA",
- "materialRM",
- "materialRA",
- "materialMA",
- "materialRMA" };
- for(int i=0; i<8; i++)
- {
- materialSubroutine_functions[i] = getUniformSubroutineIndex(geometryPassShader.id, GL_FRAGMENT_SHADER,
- materiaSubroutineFunctions[i]);
- }
- }
- };
- #pragma endregion
- ////////////////////////////////////////////////
- //Camera.cpp
- ////////////////////////////////////////////////
- #pragma region Camera
- #define GLM_ENABLE_EXPERIMENTAL
- #include <glm/gtc/matrix_transform.hpp>
- #include <glm/gtc/type_ptr.hpp>
- #include <glm/mat3x3.hpp>
- #include <glm/gtx/transform.hpp>
- namespace gl3d
- {
- glm::mat4x4 Camera::getProjectionMatrix()
- {
- auto mat = glm::perspective(this->fovRadians, this->aspectRatio, this->closePlane,
- this->farPlane);
- return mat;
- }
- glm::mat4x4 Camera::getWorldToViewMatrix()
- {
- glm::vec3 lookingAt = this->position;
- lookingAt += viewDirection;
- auto mat = glm::lookAt(this->position, lookingAt, this->up);
- return mat;
- }
- void Camera::rotateCamera(const glm::vec2 delta)
- {
- glm::vec3 rotateYaxe = glm::cross(viewDirection, up);
- viewDirection = glm::mat3(glm::rotate(delta.x, up)) * viewDirection;
- if (delta.y < 0)
- { //down
- if (viewDirection.y < -0.99)
- goto noMove;
- }
- else
- { //up
- if (viewDirection.y > 0.99)
- goto noMove;
- }
- viewDirection = glm::mat3(glm::rotate(delta.y, rotateYaxe)) * viewDirection;
- noMove:
- viewDirection = glm::normalize(viewDirection);
- }
- void Camera::moveFPS(glm::vec3 direction)
- {
- viewDirection = glm::normalize(viewDirection);
- //forward
- float forward = -direction.z;
- float leftRight = direction.x;
- float upDown = direction.y;
- glm::vec3 move = {};
- move += up * upDown;
- move += glm::normalize(glm::cross(viewDirection, up)) * leftRight;
- move += viewDirection * forward;
- this->position += move;
-
- }
-
- };
- #pragma endregion
- ////////////////////////////////////////////////
- //GraphicModel.cpp
- ////////////////////////////////////////////////
- #pragma region GraphicModel
- #include "OBJ_Loader.h"
- #include <stb_image.h>
- #include <algorithm>
- namespace gl3d
- {
- void GraphicModel::loadFromComputedData(size_t vertexSize, const float * vercies, size_t indexSize,
- const unsigned int * indexes, bool noTexture)
- {
- gl3dAssertComment(indexSize % 3 == 0, "Index count must be multiple of 3");
- if (indexSize % 3 != 0)return;
- glGenVertexArrays(1, &vertexArray);
- glBindVertexArray(vertexArray);
- glGenBuffers(1, &vertexBuffer);
- glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
- glBufferData(GL_ARRAY_BUFFER, vertexSize, vercies, GL_STATIC_DRAW);
- if(noTexture)
- {
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)0);
- glEnableVertexAttribArray(1);
- glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)(3 * sizeof(float)));
- }else
- {
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)0);
- glEnableVertexAttribArray(1);
- glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(3 * sizeof(float)));
- glEnableVertexAttribArray(2);
- glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(6 * sizeof(float)));
-
- }
- if (indexSize && indexes)
- {
- glGenBuffers(1, &indexBuffer);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexSize, indexes, GL_STATIC_DRAW);
- primitiveCount = indexSize / sizeof(*indexes);
- }
- else
- {
- primitiveCount = vertexSize / sizeof(float);
- }
-
- glBindVertexArray(0);
- }
- //deprecated
- void GraphicModel::loadFromData(size_t vertexCount, float *vertices, float *normals, float *textureUV, size_t indexesCount, unsigned int *indexes)
- {
- gl3dAssertComment(vertices, "Vertices are not optional");
- gl3dAssertComment(normals, "Normals are not optional"); //todo compute
- if (!vertices || !normals) { return; }
- std::vector<float> dataForModel;
- dataForModel.reserve(vertexCount * 8);
- for (unsigned int i = 0; i < vertexCount; i++)
- {
- //positions normals uv
- dataForModel.push_back(vertices[(8*i)+0]);
- dataForModel.push_back(vertices[(8*i)+1]);
- dataForModel.push_back(vertices[(8*i)+2]);
- dataForModel.push_back(normals[(8 * i) + 3]);
- dataForModel.push_back(normals[(8 * i) + 4]);
- dataForModel.push_back(normals[(8 * i) + 5]);
- if (textureUV)
- {
- dataForModel.push_back(normals[(8 * i) + 6]);
- dataForModel.push_back(normals[(8 * i) + 7]);
- }
- else
- {
- dataForModel.push_back(0.f);
- dataForModel.push_back(0.f);
- }
- }
- this->loadFromComputedData(vertexCount * 4,
- &dataForModel[0],
- indexesCount * 4, &indexes[0], (textureUV == nullptr));
- }
- int max(int x, int y, int z)
- {
- return std::max(std::max(x, y), z);
- }
- void GraphicModel::loadFromModelMeshIndex(const LoadedModelData &model, int index)
- {
- auto &mesh = model.loader.LoadedMeshes[index];
- loadFromComputedData(mesh.Vertices.size() * 8 * 4,
- (float *)&mesh.Vertices[0],
- mesh.Indices.size() * 4, &mesh.Indices[0]);
- auto &mat = model.loader.LoadedMeshes[index].MeshMaterial;
- material.setDefaultMaterial();
- material.kd = glm::vec4(glm::vec3(mat.Kd), 1);
- //material.ks = glm::vec4(glm::vec3(mat.Ks), mat.Ns);
- //material.ka = glm::vec4(glm::vec3(mat.Ka), 0);
- material.metallic = mat.metallic;
- material.roughness = mat.roughness;
- //material.ao = mat.ao;
- albedoTexture.clear();
- normalMapTexture.clear();
- RMA_Texture.clear();
- if (!mat.map_Kd.empty())
- {
- albedoTexture.loadTextureFromFile(std::string(model.path + mat.map_Kd).c_str());
- }
- if (!mat.map_Kn.empty())
- {
- normalMapTexture.loadTextureFromFile(std::string(model.path + mat.map_Kn).c_str(),
- TextureLoadQuality::linearMipmap);
- }
- RMA_loadedTextures = 0;
-
- auto rmaQuality = TextureLoadQuality::linearMipmap;
- if(!mat.map_RMA.empty()) //todo not tested
- {
- RMA_Texture.loadTextureFromFile(mat.map_RMA.c_str(),
- rmaQuality);
- if(RMA_Texture.id)
- {
- RMA_loadedTextures = 7; //all textures loaded
- }
- }
- if (!mat.map_ORM.empty() && RMA_loadedTextures == 0)
- {
- stbi_set_flip_vertically_on_load(true);
- int w = 0, h = 0;
- unsigned char *data = 0;
-
- {
- data = stbi_load(std::string(model.path + mat.map_ORM).c_str(),
- &w, &h, 0, 4);
- if (!data)
- { std::cout << "err loading " << std::string(model.path + mat.map_ORM) << "\n"; }
- else
- {
- //convert from ORM ro RMA
- for (int j = 0; j < h; j++)
- for (int i = 0; i < w; i++)
- {
- unsigned char R = data[(i + j*w) * 4 + 1];
- unsigned char M = data[(i + j*w) * 4 + 2];
- unsigned char A = data[(i + j*w) * 4 + 0];
- data[(i + j * w) * 4 + 0] = R;
- data[(i + j * w) * 4 + 1] = M;
- data[(i + j * w) * 4 + 2] = A;
- }
- RMA_Texture.loadTextureFromMemory(data, w, h, 4, rmaQuality);
-
- RMA_loadedTextures = 7; //all textures loaded
- stbi_image_free(data);
- }
- }
-
- }
- //RMA trexture
- if(RMA_loadedTextures == 0)
- {
- stbi_set_flip_vertically_on_load(true);
- int w1=0, h1=0;
- unsigned char *data1 = 0;
- unsigned char *data2 = 0;
- unsigned char *data3 = 0;
- if(!mat.map_Pr.empty())
- {
- data1 = stbi_load(std::string(model.path + mat.map_Pr).c_str(),
- &w1, &h1, 0, 1);
- if (!data1) { std::cout << "err loading " << std::string(model.path + mat.map_Pr) << "\n"; }
- }
-
- int w2=0, h2=0;
- if(!mat.map_Pm.empty())
- {
- data2 = stbi_load(std::string(model.path + mat.map_Pm).c_str(),
- &w2, &h2, 0, 1);
- if (!data2) { std::cout << "err loading " << std::string(model.path + mat.map_Pm) << "\n"; }
- }
-
- int w3=0, h3=0;
- if(!mat.map_Ka.empty())
- {
- data3 = stbi_load(std::string(model.path + mat.map_Ka).c_str(),
- &w3, &h3, 0, 1);
- if (!data3) { std::cout << "err loading " << std::string(model.path + mat.map_Ka) << "\n"; }
- }
- int w = max(w1, w2, w3);
- int h = max(h1, h2, h3);
- //calculate which function to use
- if(data1 && data2 && data3){ RMA_loadedTextures = 7;}else
- if( data2 && data3){ RMA_loadedTextures = 6;}else
- if(data1 && data3){ RMA_loadedTextures = 5;}else
- if(data1 && data2 ){ RMA_loadedTextures = 4;}else
- if( data3){ RMA_loadedTextures = 3;}else
- if( data2 ){ RMA_loadedTextures = 2;}else
- if(data1 ){ RMA_loadedTextures = 1;}else
- { RMA_loadedTextures = 0;};
- if (RMA_loadedTextures)
- {
- unsigned char *finalData = new unsigned char[w * h * 4];
- //todo mabe add bilinear filtering
- //todo load less chanels if necessary
- for (int j = 0; j < h; j++)
- {
- for (int i = 0; i < w; i++)
- {
- if (data1) //rough
- {
- int texelI = (i / (float)w) * w1;
- int texelJ = (j / float(h)) * h1;
- finalData[((j * w) + i) * 4 + 0] =
- data1[(texelJ * w1) + texelI];
- }
- else
- {
- finalData[((j * w) + i) * 4 + 0] = 0;
- }
- if (data2) //metalic
- {
- int texelI = (i / (float)w) * w2;
- int texelJ = (j / float(h)) * h2;
- finalData[((j * w) + i) * 4 + 1] =
- data2[(texelJ * w2) + texelI];
- }
- else
- {
- finalData[((j * w) + i) * 4 + 1] = 0;
- }
- if (data3) //ambient
- {
- int texelI = (i / (float)w) * w3;
- int texelJ = (j / float(h)) * h3;
- finalData[((j * w) + i) * 4 + 2] =
- data3[(texelJ * w3) + texelI];
- }
- else
- {
- finalData[((j * w) + i) * 4 + 2] = 0;
- }
- finalData[((j * w) + i) * 4 + 3] = 255; //used only for imgui, remove later
- }
- }
- RMA_Texture.loadTextureFromMemory(finalData, w, h, 4,
- rmaQuality);
- stbi_image_free(data1);
- stbi_image_free(data2);
- stbi_image_free(data3);
- delete[] finalData;
- }
- }
- }
- void GraphicModel::loadFromModelMesh(const LoadedModelData &model)
- {
- auto &mesh = model.loader.LoadedVertices;
- loadFromComputedData(mesh.size() * 8 * 4,
- (float *)&mesh[0],
- model.loader.LoadedIndices.size() * 4,
- &model.loader.LoadedIndices[0]);
- }
- //deprecated
- void GraphicModel::loadFromFile(const char *fileName)
- {
- objl::Loader loader;
- loader.LoadFile(fileName);
- std::vector<float> dataForModel;
- auto &mesh = loader.LoadedMeshes[0];
- dataForModel.reserve(mesh.Vertices.size() * 8);
- for (unsigned int i = 0; i < mesh.Vertices.size(); i++)
- {
- //positions normals uv
- dataForModel.push_back(mesh.Vertices[i].Position.X);
- dataForModel.push_back(mesh.Vertices[i].Position.Y);
- dataForModel.push_back(mesh.Vertices[i].Position.Z);
-
- dataForModel.push_back(mesh.Vertices[i].Normal.X);
- dataForModel.push_back(mesh.Vertices[i].Normal.Y);
- dataForModel.push_back(mesh.Vertices[i].Normal.Z);
- dataForModel.push_back(mesh.Vertices[i].TextureCoordinate.X);
- dataForModel.push_back(mesh.Vertices[i].TextureCoordinate.Y);
- }
- std::vector<unsigned int> indicesForModel;
- indicesForModel.reserve(mesh.Indices.size());
- for (unsigned int i = 0; i < mesh.Indices.size(); i++)
- {
- indicesForModel.push_back(mesh.Indices[i]);
- }
- this->loadFromComputedData(dataForModel.size() * 4,
- &dataForModel[0],
- indicesForModel.size() * 4, &indicesForModel[0]);
- //vb = vertexBuffer(dataForModel.data(), dataForModel.size() * sizeof(float), GL_STATIC_DRAW);
- //ib = indexBuffer(indicesForModel.data(), indicesForModel.size() * sizeof(unsigned int));
- //va = std::move(vertexAttribute{ 3, 2, 3 });
- //
- //
- //if (model.m.LoadedMaterials.size() > 0)
- //{
- //
- // material.ka = glm::vec3(model.m.LoadedMaterials[0].Ka.X, model.m.LoadedMaterials[0].Ka.Y, model.m.LoadedMaterials[0].Ka.Z);
- // material.kd = glm::vec3(model.m.LoadedMaterials[0].Kd.X, model.m.LoadedMaterials[0].Kd.Y, model.m.LoadedMaterials[0].Kd.Z);
- // material.ks = glm::vec3(model.m.LoadedMaterials[0].Ks.X, model.m.LoadedMaterials[0].Ks.Y, model.m.LoadedMaterials[0].Ks.Z);
- // material.shiny = model.m.LoadedMaterials[0].Ns;
- // if (material.shiny == 0) { material.shiny = 1; }
- //
- // if (model.m.LoadedMaterials[0].map_Kd != "")
- // {
- //
- // texture = manager->getData(model.m.LoadedMaterials[0].map_Kd.c_str());
- //
- // }
- //}
-
- }
- void GraphicModel::clear()
- {
- glDeleteBuffers(1, &vertexBuffer);
- glDeleteBuffers(1, &indexBuffer);
- glDeleteVertexArrays(1, &vertexArray);
- albedoTexture.clear();
- normalMapTexture.clear();
- RMA_Texture.clear();
- vertexBuffer = 0;
- indexBuffer = 0;
- primitiveCount = 0;
- vertexArray = 0;
- }
- void GraphicModel::draw()
- {
- glBindVertexArray(vertexArray);
- //glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
- //glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0);
- //glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)(3 * sizeof(float)));
- if (indexBuffer)
- {
- glDrawElements(GL_TRIANGLES, primitiveCount, GL_UNSIGNED_INT, 0);
- }
- else
- {
- glDrawArrays(GL_TRIANGLES, 0, primitiveCount);
- }
- glBindVertexArray(0);
- }
- glm::mat4 GraphicModel::getTransformMatrix()
- {
- return gl3d::getTransformMatrix(position, rotation, scale);
- }
- void LoadedModelData::load(const char *file, float scale)
- {
- loader.LoadFile(file);
- //parse path
- path = file;
- while (!path.empty() &&
- *(path.end() - 1) != '\\' &&
- *(path.end() - 1) != '/'
- )
- {
- path.pop_back();
- }
- for (auto &i : loader.LoadedMeshes)
- {
- for(auto &j : i.Vertices)
- {
- j.Position.X *= scale;
- j.Position.Y *= scale;
- j.Position.Z *= scale;
- }
- }
- for (auto &j : loader.LoadedVertices)
- {
- j.Position.X *= scale;
- j.Position.Y *= scale;
- j.Position.Z *= scale;
- }
- std::cout << "Loaded: " << loader.LoadedMeshes.size() << " meshes\n";
- }
- float skyboxVertices[] = {
- // positions
- -1.0f, 1.0f, -1.0f,
- -1.0f, -1.0f, -1.0f,
- 1.0f, -1.0f, -1.0f,
- 1.0f, -1.0f, -1.0f,
- 1.0f, 1.0f, -1.0f,
- -1.0f, 1.0f, -1.0f,
- -1.0f, -1.0f, 1.0f,
- -1.0f, -1.0f, -1.0f,
- -1.0f, 1.0f, -1.0f,
- -1.0f, 1.0f, -1.0f,
- -1.0f, 1.0f, 1.0f,
- -1.0f, -1.0f, 1.0f,
- 1.0f, -1.0f, -1.0f,
- 1.0f, -1.0f, 1.0f,
- 1.0f, 1.0f, 1.0f,
- 1.0f, 1.0f, 1.0f,
- 1.0f, 1.0f, -1.0f,
- 1.0f, -1.0f, -1.0f,
- -1.0f, -1.0f, 1.0f,
- -1.0f, 1.0f, 1.0f,
- 1.0f, 1.0f, 1.0f,
- 1.0f, 1.0f, 1.0f,
- 1.0f, -1.0f, 1.0f,
- -1.0f, -1.0f, 1.0f,
- -1.0f, 1.0f, -1.0f,
- 1.0f, 1.0f, -1.0f,
- 1.0f, 1.0f, 1.0f,
- 1.0f, 1.0f, 1.0f,
- -1.0f, 1.0f, 1.0f,
- -1.0f, 1.0f, -1.0f,
- -1.0f, -1.0f, -1.0f,
- -1.0f, -1.0f, 1.0f,
- 1.0f, -1.0f, -1.0f,
- 1.0f, -1.0f, -1.0f,
- -1.0f, -1.0f, 1.0f,
- 1.0f, -1.0f, 1.0f
- };
- void SkyBox::createGpuData()
- {
- shader.loadShaderProgramFromFile("shaders/skyBox.vert", "shaders/skyBox.frag");
- samplerUniformLocation = getUniform(shader.id, "u_skybox");
- modelViewUniformLocation = getUniform(shader.id, "u_viewProjection");
- gamaUniformLocation = getUniform(shader.id, "u_gama");
- glGenVertexArrays(1, &vertexArray);
- glBindVertexArray(vertexArray);
-
- glGenBuffers(1, &vertexBuffer);
- glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
- glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), skyboxVertices, GL_STATIC_DRAW);
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
-
- glBindVertexArray(0);
- }
- //todo add srgb
- void SkyBox::loadTexture(const char *names[6])
- {
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
- int w, h, nrChannels;
- unsigned char *data;
- for (unsigned int i = 0; i <6; i++)
- {
- stbi_set_flip_vertically_on_load(false);
- data = stbi_load(names[i], &w, &h, &nrChannels, 3);
- if (data)
- {
- glTexImage2D(
- GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
- 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data
- );
- //gausianBlurRGB(data, w, h, 10);
- //glTexImage2D(
- // GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
- // 1, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data
- //);
- stbi_image_free(data);
- }
- else
- {
- std::cout << "err loading " << names[i] << "\n";
- }
-
- }
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
- }
- //todo add srgb
- void SkyBox::loadTexture(const char *name, int format)
- {
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
- int width, height, nrChannels;
- unsigned char *data;
- stbi_set_flip_vertically_on_load(false);
- data = stbi_load(name, &width, &height, &nrChannels, 3);
- //right
- //left
- //top
- //bottom
- //front
- //back
- auto getPixel = [&](int x, int y, unsigned char *data)
- {
- return data + 3 * (x + y * width);
- };
- glm::ivec2 paddings[6];
- glm::ivec2 immageRatio = {};
- if(format == 0)
- {
- immageRatio = { 4, 3 };
- glm::ivec2 paddingscopy[6] =
- {
- { (width / 4) * 2, (height / 3) * 1, },
- { (width / 4) * 0, (height / 3) * 1, },
- { (width / 4) * 1, (height / 3) * 0, },
- { (width / 4) * 1, (height / 3) * 2, },
- { (width / 4) * 1, (height / 3) * 1, },
- { (width / 4) * 3, (height / 3) * 1, },
- };
-
- memcpy(paddings, paddingscopy, sizeof(paddings));
- }else if (format == 1)
- {
- immageRatio = { 3, 4 };
- glm::ivec2 paddingscopy[6] =
- {
- { (width / 3) * 2, (height / 4) * 1, },
- { (width / 3) * 0, (height / 4) * 1, },
- { (width / 3) * 1, (height / 4) * 0, },
- { (width / 3) * 1, (height / 4) * 2, },
- { (width / 3) * 1, (height / 4) * 3, },
- { (width / 3) * 1, (height / 4) * 1, },
- };
- memcpy(paddings, paddingscopy, sizeof(paddings));
-
- }
-
- if (data)
- {
- for (unsigned int i = 0; i < 6; i++)
- {
- unsigned char *extractedData = new unsigned char[3 *
- (width / immageRatio.x) * (height / immageRatio.y)];
- int index = 0;
- int paddingX = paddings[i].x;
- int paddingY = paddings[i].y;
- for (int j = 0; j < height / immageRatio.y; j++)
- for (int i = 0; i < width / immageRatio.x; i++)
- {
- extractedData[index] = *getPixel(i + paddingX, j + paddingY, data);
- extractedData[index + 1] = *(getPixel(i + paddingX, j + paddingY, data)+1);
- extractedData[index + 2] = *(getPixel(i + paddingX, j + paddingY, data)+2);
- //extractedData[index] = 100;
- //extractedData[index + 1] = 100;
- //extractedData[index + 2] = 100;
- index += 3;
- }
- glTexImage2D(
- GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
- 0, GL_RGB, width/ immageRatio.x, height/ immageRatio.y, 0,
- GL_RGB, GL_UNSIGNED_BYTE, extractedData
- );
- delete[] extractedData;
- }
- stbi_image_free(data);
- }else
- {
- std::cout << "err loading " << name << "\n";
- }
- //glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- //glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
- }
- void SkyBox::clearGpuData()
- {
- }
- void SkyBox::draw(const glm::mat4 &viewProjMat, float gama)
- {
- glBindVertexArray(vertexArray);
- bindCubeMap();
- shader.bind();
- glUniformMatrix4fv(modelViewUniformLocation, 1, GL_FALSE, &viewProjMat[0][0]);
- glUniform1i(samplerUniformLocation, 0);
- glUniform1f(gamaUniformLocation, gama);
- glDepthFunc(GL_LEQUAL);
- glDrawArrays(GL_TRIANGLES, 0, 6*6);
- glDepthFunc(GL_LESS);
- glBindVertexArray(0);
- }
- void SkyBox::bindCubeMap()
- {
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
- }
- void MultipleGraphicModels::loadFromModel(const LoadedModelData &model)
- {
- clear();
- int s = model.loader.LoadedMeshes.size();
- models.reserve(s);
- for(int i=0;i<s;i++)
- {
- GraphicModel gm;
- gm.loadFromModelMeshIndex(model, i);
- gm.name = model.loader.LoadedMeshes[i].MeshName;
- char *c = new char[gm.name.size() + 1];
- strcpy(c, gm.name.c_str());
- subModelsNames.push_back(c);
- models.push_back(gm);
- }
- }
- void MultipleGraphicModels::clear()
- {
- for(auto &i : models)
- {
- i.clear();
- }
- for (auto &i : subModelsNames)
- {
- delete[] i;
- }
- subModelsNames.clear();
- models.clear();
- //todo clear material buffer
- }
- //todo optimize
- glm::mat4 getTransformMatrix(glm::vec3 position, glm::vec3 rotation, glm::vec3 scale)
- {
- auto s = glm::scale(scale);
- auto r = glm::rotate(rotation.x, glm::vec3(1, 0, 0)) *
- glm::rotate(rotation.y, glm::vec3(0, 1, 0)) *
- glm::rotate(rotation.z, glm::vec3(0, 0, 1));
- auto t = glm::translate(position);
- return t * r * s;
- }
- void GpuMultipleGraphicModel::clear()
- {
- for (auto &i : models)
- {
- i.clear();
- }
- for (auto &i : subModelsNames)
- {
- delete[] i;
- }
- subModelsNames.clear();
- models.clear();
- }
-
- void GpuGraphicModel::loadFromComputedData(size_t vertexSize, const float *vercies, size_t indexSize, const unsigned int *indexes, bool noTexture)
- {
- gl3dAssertComment(indexSize % 3 == 0, "Index count must be multiple of 3");
- if (indexSize % 3 != 0)return;
- glGenVertexArrays(1, &vertexArray);
- glBindVertexArray(vertexArray);
- glGenBuffers(1, &vertexBuffer);
- glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
- glBufferData(GL_ARRAY_BUFFER, vertexSize, vercies, GL_STATIC_DRAW);
- //todo if the object doesn't have texture data we should not render any material to it or just refuze to load it
- if (noTexture)
- {
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)0);
- glEnableVertexAttribArray(1);
- glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)(3 * sizeof(float)));
- }
- else
- {
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)0);
- glEnableVertexAttribArray(1);
- glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(3 * sizeof(float)));
- glEnableVertexAttribArray(2);
- glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(6 * sizeof(float)));
- }
- if (indexSize && indexes)
- {
- glGenBuffers(1, &indexBuffer);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexSize, indexes, GL_STATIC_DRAW);
- primitiveCount = indexSize / sizeof(*indexes);
- }
- else
- {
- primitiveCount = vertexSize / sizeof(float);
- }
- glBindVertexArray(0);
- }
- void GpuGraphicModel::clear()
- {
- glDeleteBuffers(1, &vertexBuffer);
- glDeleteBuffers(1, &indexBuffer);
- glDeleteVertexArrays(1, &vertexArray);
- //albedoTexture.clear();
- //normalMapTexture.clear();
- //RMA_Texture.clear();
- vertexBuffer = 0;
- indexBuffer = 0;
- primitiveCount = 0;
- vertexArray = 0;
- }
- };
- #pragma endregion
- ////////////////////////////////////////////////
- //gl3d.cpp
- ////////////////////////////////////////////////
- #pragma region gl3d
- #include <algorithm>
- #include <stb_image.h>
- #include <random>
- #include <string>
- namespace gl3d
- {
-
- void Renderer3D::init(int x, int y)
- {
- w = x; h = y;
- lightShader.create();
- skyBox.createGpuData();
- vao.createVAOs();
- showNormalsProgram.shader.loadShaderProgramFromFile("shaders/showNormals.vert",
- "shaders/showNormals.geom", "shaders/showNormals.frag");
- showNormalsProgram.modelTransformLocation = glGetUniformLocation(showNormalsProgram.shader.id, "u_modelTransform");
- showNormalsProgram.projectionLocation = glGetUniformLocation(showNormalsProgram.shader.id, "u_projection");
- showNormalsProgram.sizeLocation = glGetUniformLocation(showNormalsProgram.shader.id, "u_size");
- showNormalsProgram.colorLocation = glGetUniformLocation(showNormalsProgram.shader.id, "u_color");
- unsigned char textureData[] =
- {
- 20, 20, 20, 255,
- 212, 0, 219, 255,
- 212, 0, 219, 255,
- 20, 20, 20, 255,
- };
- defaultTexture.loadTextureFromMemory(textureData, 2, 2, 4, TextureLoadQuality::leastPossible);
- //create gBuffer
- glCheck(glGenFramebuffers(1, &gBuffer.gBuffer));
- glCheck(glBindFramebuffer(GL_FRAMEBUFFER, gBuffer.gBuffer));
- glCheck(glGenTextures(gBuffer.bufferCount, gBuffer.buffers));
- glCheck(glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.position]));
- glCheck(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, x, y, 0, GL_RGBA, GL_FLOAT, NULL));
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gBuffer.buffers[gBuffer.position], 0);
- glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.normal]);
- glCheck(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, x, y, 0, GL_RGBA, GL_FLOAT, NULL));
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, gBuffer.buffers[gBuffer.normal], 0);
- glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.albedo]);
- glCheck(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL));
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, gBuffer.buffers[gBuffer.albedo], 0);
- glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.material]);
- glCheck(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL));
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, gBuffer.buffers[gBuffer.material], 0);
- glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.positionViewSpace]);
- glCheck(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, x, y, 0, GL_RGBA, GL_FLOAT, NULL));
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT4, GL_TEXTURE_2D, gBuffer.buffers[gBuffer.positionViewSpace], 0);
- unsigned int attachments[decltype(gBuffer)::bufferCount] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
- GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3, GL_COLOR_ATTACHMENT4 };
- glDrawBuffers(decltype(gBuffer)::bufferCount, attachments);
- glGenRenderbuffers(1, &gBuffer.depthBuffer);
- glBindRenderbuffer(GL_RENDERBUFFER, gBuffer.depthBuffer);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, x, y);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, gBuffer.depthBuffer);
- if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
- {
- std::cout << "Gbuffer failed\n";
- }
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
- ssao.create(x, y);
- postProcess.create(x, y);
- }
- void Renderer3D::VAO::createVAOs()
- {
- glGenVertexArrays(1, &posNormalTexture);
- glBindVertexArray(posNormalTexture);
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)0);
- glEnableVertexAttribArray(1);
- glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(3 * sizeof(float)));
- glEnableVertexAttribArray(2);
- glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(6 * sizeof(float)));
- glBindVertexArray(0);
- }
-
- Material Renderer3D::createMaterial(glm::vec3 kd, float roughness, float metallic, float ao
- , std::string name)
- {
- int id = internal::generateNewIndex(materialIndexes);
- GpuMaterial gpuMaterial;
- gpuMaterial.kd = glm::vec4(kd, 0);
- gpuMaterial.roughness = roughness;
- gpuMaterial.metallic = metallic;
- gpuMaterial.ao = ao;
- materialIndexes.push_back(id);
- materials.push_back(gpuMaterial);
- materialNames.push_back(name);
- materialTexturesData.push_back({});
- Material m;
- m.id_ = id;
- return m;
- }
- Material Renderer3D::createMaterial(Material m)
- {
- auto newM = createMaterial();
- copyMaterialData(newM, m);
- return newM;
- }
- Material Renderer3D::loadMaterial(std::string file)
- {
- objl::Loader loader;
- loader.LoadFile(file);
- return Material();
- }
- void Renderer3D::deleteMaterial(Material m)
- {
- auto pos = std::find(materialIndexes.begin(), materialIndexes.end(), m.id_);
- if (pos == materialIndexes.end())
- {
- gl3dAssertComment(pos == materialIndexes.end(), "invalid delete material");
- return;
- }
- int index = pos - materialIndexes.begin();
- materialIndexes.erase(pos);
- materials.erase(materials.begin() + index);
- materialNames.erase(materialNames.begin() + index);
- materialTexturesData.erase(materialTexturesData.begin() + index);
- m.id_ = 0;
- }
- void Renderer3D::copyMaterialData(Material dest, Material source)
- {
- int destId = getMaterialIndex(dest);
- int sourceId = getMaterialIndex(source);
- if(destId == -1 || sourceId == -1)
- {
- gl3dAssertComment(destId != -1, "invaled dest material index");
- gl3dAssertComment(sourceId != -1, "invaled source material index");
- return;
- }
- materials[destId] = materials[sourceId];
- materialNames[destId] = materialNames[sourceId];
- materialTexturesData[destId] = materialTexturesData[destId];
- }
- GpuMaterial *Renderer3D::getMaterialData(Material m)
- {
- int id = getMaterialIndex(m);
- if(id == -1)
- {
- return nullptr;
- }
-
- auto data = &materials[id];
- return data;
- }
- TextureDataForModel *Renderer3D::getMaterialTextures(Material m)
- {
- int id = getMaterialIndex(m);
- if (id == -1)
- {
- return nullptr;
- }
- auto data = &materialTexturesData[id];
- return data;
- }
- std::string *Renderer3D::getMaterialName(Material m)
- {
- int id = getMaterialIndex(m);
- if (id == -1)
- {
- return nullptr;
- }
- auto data = &materialNames[id];
- return data;
- }
- bool Renderer3D::getMaterialData(Material m, GpuMaterial *gpuMaterial, std::string *name, TextureDataForModel *textureData)
- {
- int id = getMaterialIndex(m);
- if (id == -1)
- {
- return false;
- }
- if(gpuMaterial)
- {
- gpuMaterial = &materials[id];
- }
- if(name)
- {
- name = &materialNames[id];
- }
- if(textureData)
- {
- textureData = &materialTexturesData[id];
- }
- return true;
- }
- bool Renderer3D::setMaterialData(Material m, const GpuMaterial &data, std::string *s)
- {
- int id = getMaterialIndex(m);
- if (id == -1)
- {
- return 0;
- }
- materials[id] = data;
-
- if (s)
- {
- materialNames[id] = *s;
- }
- return 1;
- }
- GpuMultipleGraphicModel *Renderer3D::getObjectData(Object o)
- {
- int id = getObjectIndex(o);
-
- if (id == -1)
- {
- return nullptr;
- }
-
- auto data = &graphicModels[id];
-
- return data;
- }
- Texture Renderer3D::loadTexture(std::string path, bool defaultToDefaultTexture)
- {
- if(path == "")
- {
- return Texture{ 0 };
- }
- int pos = 0;
- for (auto &i : loadedTexturesNames)
- {
- if (i == path)
- {
- Texture t;
- t.id_ = loadedTexturesIndexes[pos];
- return t;
- }
- pos++;
- }
- GpuTexture t(path.c_str());
- if(t.id == 0 && defaultToDefaultTexture == false)
- {
- return Texture{ 0 };
- }
- int id = internal::generateNewIndex(loadedTexturesIndexes);
- //if texture is not loaded, set it to default
- if(t.id == 0)
- {
- t.id = defaultTexture.id;
- }
- loadedTexturesIndexes.push_back(id);
- loadedTextures.push_back(t);
- loadedTexturesNames.push_back(path);
- return Texture{ id };
- }
- GLuint Renderer3D::getTextureOpenglId(Texture t)
- {
- auto p = getTextureData(t);
- if(p == nullptr)
- {
- return 0;
- }else
- {
- return p->id;
- }
- }
- void Renderer3D::deleteTexture(Texture t)
- {
- int index = getTextureIndex(t);
- if(index < 0)
- {
- return;
- }
- auto gpuTexture = loadedTextures[index];
- if(gpuTexture.id != defaultTexture.id)
- {
- gpuTexture.clear();
- }
- loadedTexturesIndexes.erase(loadedTexturesIndexes.begin() + index);
- loadedTextures.erase(loadedTextures.begin() + index);
- loadedTexturesNames.erase(loadedTexturesNames.begin() + index);
-
- t.id_ = 0;
- }
- GpuTexture *Renderer3D::getTextureData(Texture t)
- {
- int id = getTextureIndex(t);
- if (id == -1)
- {
- return nullptr;
- }
- auto data = &loadedTextures[id];
- return data;
- }
- Texture Renderer3D::createIntenralTexture(GpuTexture t)
- {
- int id = internal::generateNewIndex(loadedTexturesIndexes);
- //if t is null initialize to default texture
- if (t.id == 0)
- {
- t.id = defaultTexture.id;
- }
- loadedTexturesIndexes.push_back(id);
- loadedTextures.push_back(t);
- loadedTexturesNames.push_back("");
- return Texture{ id };
- }
- static int max(int x, int y, int z)
- {
- return std::max(std::max(x, y), z);
- }
- Object Renderer3D::loadObject(std::string path, float scale)
- {
- gl3d::LoadedModelData model(path.c_str(), scale);
- if(model.loader.LoadedMeshes.empty())
- {
- std::cout << "err loading " + path + "\n";
- return { 0 };
-
- }
- int id = internal::generateNewIndex(graphicModelsIndexes);
-
- GpuMultipleGraphicModel returnModel;
- {
- int s = model.loader.LoadedMeshes.size();
- returnModel.models.reserve(s);
- std::vector<gl3d::Material> loadedMaterials;
- loadedMaterials.reserve(model.loader.LoadedMaterials.size());
- for(int i=0;i<model.loader.LoadedMaterials.size(); i++)
- {
- auto &mat = model.loader.LoadedMaterials[i];
- auto m = this->createMaterial(mat.Kd, mat.roughness,
- mat.metallic, mat.ao);
-
- {
- //load textures for materials
- TextureDataForModel *textureData = this->getMaterialTextures(m);
-
- //auto &mat = model.loader.LoadedMeshes[index].MeshMaterial;
- //gm.material = loadedMaterials[model.loader.LoadedMeshes[index].materialIndex];
- //gm.albedoTexture.clear();
- //gm.normalMapTexture.clear();
- //gm.RMA_Texture.clear();
- if (!mat.map_Kd.empty())
- {
- //gm.albedoTexture.loadTextureFromFile(std::string(model.path + mat.map_Kd).c_str());
- textureData->albedoTexture = this->loadTexture(std::string(model.path + mat.map_Kd), 0);
- }
- if (!mat.map_Kn.empty())
- {
- //todo add texture load quality options
- textureData->normalMapTexture = this->loadTexture(std::string(model.path + mat.map_Kn), 0);
- //gm.normalMapTexture.loadTextureFromFile(std::string(model.path + mat.map_Kn).c_str(),
- // TextureLoadQuality::linearMipmap);
- }
- textureData->RMA_loadedTextures = 0;
- auto rmaQuality = TextureLoadQuality::linearMipmap;
- if (!mat.map_RMA.empty()) //todo not tested
- {
- //gm.RMA_Texture.loadTextureFromFile(mat.map_RMA.c_str(),
- //rmaQuality);
- textureData->RMA_Texture = this->loadTexture(mat.map_RMA.c_str());
- //todo add a function to check if a function is valid
- if (getTextureData(textureData->RMA_Texture)->id == defaultTexture.id)
- {
- textureData->RMA_loadedTextures = 7; //all textures loaded
- }
- //if (gm.RMA_Texture.id)
- //{
- // gm.RMA_loadedTextures = 7; //all textures loaded
- //}
- }
- if (!mat.map_ORM.empty() && textureData->RMA_loadedTextures == 0)
- {
- stbi_set_flip_vertically_on_load(true);
- int w = 0, h = 0;
- unsigned char *data = 0;
- {
- data = stbi_load(std::string(model.path + mat.map_ORM).c_str(),
- &w, &h, 0, 4);
- if (!data)
- {
- std::cout << "err loading " << std::string(model.path + mat.map_ORM) << "\n";
- }
- else
- {
- //convert from ORM ro RMA
- for (int j = 0; j < h; j++)
- for (int i = 0; i < w; i++)
- {
- unsigned char R = data[(i + j * w) * 4 + 1];
- unsigned char M = data[(i + j * w) * 4 + 2];
- unsigned char A = data[(i + j * w) * 4 + 0];
- data[(i + j * w) * 4 + 0] = R;
- data[(i + j * w) * 4 + 1] = M;
- data[(i + j * w) * 4 + 2] = A;
- }
- //gm.RMA_Texture.loadTextureFromMemory(data, w, h, 4, rmaQuality);
- GpuTexture t;
- t.loadTextureFromMemory(data, w, h, 4, rmaQuality);
- textureData->RMA_Texture = this->createIntenralTexture(t);
- textureData->RMA_loadedTextures = 7; //all textures loaded
- stbi_image_free(data);
- }
- }
- }
- //RMA trexture
- if (textureData->RMA_loadedTextures == 0)
- {
- stbi_set_flip_vertically_on_load(true);
- int w1 = 0, h1 = 0;
- unsigned char *data1 = 0;
- unsigned char *data2 = 0;
- unsigned char *data3 = 0;
- if (!mat.map_Pr.empty())
- {
- data1 = stbi_load(std::string(model.path + mat.map_Pr).c_str(),
- &w1, &h1, 0, 1);
- if (!data1) { std::cout << "err loading " << std::string(model.path + mat.map_Pr) << "\n"; }
- }
- int w2 = 0, h2 = 0;
- if (!mat.map_Pm.empty())
- {
- data2 = stbi_load(std::string(model.path + mat.map_Pm).c_str(),
- &w2, &h2, 0, 1);
- if (!data2) { std::cout << "err loading " << std::string(model.path + mat.map_Pm) << "\n"; }
- }
- int w3 = 0, h3 = 0;
- if (!mat.map_Ka.empty())
- {
- data3 = stbi_load(std::string(model.path + mat.map_Ka).c_str(),
- &w3, &h3, 0, 1);
- if (!data3) { std::cout << "err loading " << std::string(model.path + mat.map_Ka) << "\n"; }
- }
- int w = max(w1, w2, w3);
- int h = max(h1, h2, h3);
- //calculate which function to use
- if (data1 && data2 && data3) { textureData->RMA_loadedTextures = 7; }
- else
- if (data2 && data3) { textureData->RMA_loadedTextures = 6; }
- else
- if (data1 && data3) { textureData->RMA_loadedTextures = 5; }
- else
- if (data1 && data2) { textureData->RMA_loadedTextures = 4; }
- else
- if (data3) { textureData->RMA_loadedTextures = 3; }
- else
- if (data2) { textureData->RMA_loadedTextures = 2; }
- else
- if (data1) { textureData->RMA_loadedTextures = 1; }
- else { textureData->RMA_loadedTextures = 0; }
- if (textureData->RMA_loadedTextures)
- {
- unsigned char *finalData = new unsigned char[w * h * 4];
- //todo mabe add bilinear filtering
- //todo load less chanels if necessary
- for (int j = 0; j < h; j++)
- {
- for (int i = 0; i < w; i++)
- {
- if (data1) //rough
- {
- int texelI = (i / (float)w) * w1;
- int texelJ = (j / float(h)) * h1;
- finalData[((j * w) + i) * 4 + 0] =
- data1[(texelJ * w1) + texelI];
- }
- else
- {
- finalData[((j * w) + i) * 4 + 0] = 0;
- }
- if (data2) //metalic
- {
- int texelI = (i / (float)w) * w2;
- int texelJ = (j / float(h)) * h2;
- finalData[((j * w) + i) * 4 + 1] =
- data2[(texelJ * w2) + texelI];
- }
- else
- {
- finalData[((j * w) + i) * 4 + 1] = 0;
- }
- if (data3) //ambient
- {
- int texelI = (i / (float)w) * w3;
- int texelJ = (j / float(h)) * h3;
- finalData[((j * w) + i) * 4 + 2] =
- data3[(texelJ * w3) + texelI];
- }
- else
- {
- finalData[((j * w) + i) * 4 + 2] = 0;
- }
- finalData[((j * w) + i) * 4 + 3] = 255; //used only for imgui, remove later
- }
- }
- //gm.RMA_Texture.loadTextureFromMemory(finalData, w, h, 4,
- // rmaQuality);
- GpuTexture t;
- t.loadTextureFromMemory(finalData, w, h, 4, rmaQuality);
- textureData->RMA_Texture = this->createIntenralTexture(t);
- stbi_image_free(data1);
- stbi_image_free(data2);
- stbi_image_free(data3);
- delete[] finalData;
- }
- }
-
- }
- loadedMaterials.push_back(m);
- }
- for (int i = 0; i < s; i++)
- {
- GpuGraphicModel gm;
- int index = i;
- GpuMaterial material;
- //TextureDataForModel textureData = {};
-
- auto &mesh = model.loader.LoadedMeshes[index];
- gm.loadFromComputedData(mesh.Vertices.size() * 8 * 4,
- (float *)&mesh.Vertices[0],
- mesh.Indices.size() * 4, &mesh.Indices[0]);
- gm.material = loadedMaterials[model.loader.LoadedMeshes[index].materialIndex];
-
- gm.name = model.loader.LoadedMeshes[i].MeshName;
- char *c = new char[gm.name.size() + 1];
- strcpy(c, gm.name.c_str());
- returnModel.subModelsNames.push_back(c);
- returnModel.models.push_back(gm);
- }
- }
-
- graphicModelsIndexes.push_back(id);
- graphicModels.push_back(returnModel);
- Object o;
- o.id_ = id;
- return o;
- }
- void Renderer3D::deleteObject(Object o)
- {
- auto pos = std::find(graphicModelsIndexes.begin(), graphicModelsIndexes.end(), o.id_);
- if (pos == graphicModelsIndexes.end())
- {
- gl3dAssertComment(pos == graphicModelsIndexes.end(), "invalid delete object");
- return;
- }
- int index = pos - graphicModelsIndexes.begin();
- graphicModelsIndexes.erase(pos);
- graphicModels[index].clear();
- graphicModels.erase(graphicModels.begin() + index);
- o.id_ = 0;
- }
- void Renderer3D::renderObject(Object o, glm::vec3 position, glm::vec3 rotation, glm::vec3 scale)
- {
- glBindFramebuffer(GL_FRAMEBUFFER, gBuffer.gBuffer);
- auto found = std::find(graphicModelsIndexes.begin(), graphicModelsIndexes.end(), o.id_);
- if (found == graphicModelsIndexes.end())
- {
- gl3dAssertComment(found == graphicModelsIndexes.end(), "invalid render object");
- return;
- }
- int id = found - graphicModelsIndexes.begin();
- auto &model = graphicModels[id];
- if (model.models.empty())
- {
- return;
- }
- auto projMat = camera.getProjectionMatrix();
- auto viewMat = camera.getWorldToViewMatrix();
- auto transformMat = gl3d::getTransformMatrix(position, rotation, scale);
- auto modelViewProjMat = projMat * viewMat * transformMat;
- //auto modelView = viewMat * transformMat;
- lightShader.geometryPassShader.bind();
- lightShader.getSubroutines();
- glUniformMatrix4fv(lightShader.u_transform, 1, GL_FALSE, &modelViewProjMat[0][0]);
- glUniformMatrix4fv(lightShader.u_modelTransform, 1, GL_FALSE, &transformMat[0][0]);
- glUniformMatrix4fv(lightShader.u_motelViewTransform, 1, GL_FALSE, &(viewMat * transformMat)[0][0]);
- //glUniform3fv(normalShaderLightposLocation, 1, &lightPosition[0]);
- //glUniform3fv(eyePositionLocation, 1, &eyePosition[0]);
- glUniform1i(lightShader.textureSamplerLocation, 0);
- glUniform1i(lightShader.normalMapSamplerLocation, 1);
- //glUniform1i(lightShader.skyBoxSamplerLocation, 2);
- glUniform1i(lightShader.RMASamplerLocation, 3);
- //material buffer
- glBindBuffer(GL_SHADER_STORAGE_BUFFER, lightShader.materialBlockBuffer);
- glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GpuMaterial) * materials.size()
- , &materials[0], GL_STREAM_DRAW);
- glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, lightShader.materialBlockBuffer);
- //glBindVertexArray(vao.posNormalTexture);
- glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
- for (auto &i : model.models)
- {
-
- glBindVertexArray(i.vertexArray);
- //glBindBuffer(GL_ARRAY_BUFFER, i.vertexBuffer);
- if (i.indexBuffer)
- {
- //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i.indexBuffer);
- glDrawElements(GL_TRIANGLES, i.primitiveCount, GL_UNSIGNED_INT, 0);
- }
- else
- {
- glDrawArrays(GL_TRIANGLES, 0, i.primitiveCount);
- }
- }
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- glDepthFunc(GL_EQUAL);
- GLsizei n;
- glGetProgramStageiv(lightShader.geometryPassShader.id,
- GL_FRAGMENT_SHADER,
- GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS,
- &n);
- GLuint *indices = new GLuint[n]{ 0 };
- bool changed = 1;
-
- for (auto &i : model.models)
- {
-
- int materialId = getMaterialIndex(i.material);
- if (materialId == -1)
- { continue; }
- glUniform1i(lightShader.materialIndexLocation, materialId);
-
- TextureDataForModel textureData = materialTexturesData[materialId];
- int rmaLoaded = 0;
- int albedoLoaded = 0;
- int normalLoaded = 0;
- GpuTexture *albedoTextureData = this->getTextureData(textureData.albedoTexture);
- if(albedoTextureData != nullptr )
- {
- albedoLoaded = 1;
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, albedoTextureData->id);
- }
- GpuTexture *normalMapTextureData = this->getTextureData(textureData.normalMapTexture);
- if(normalMapTextureData != nullptr && normalMapTextureData->id != defaultTexture.id)
- {
- normalLoaded = 1;
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, normalMapTextureData->id);
- }
-
- //todo refactor default texture, just keep it totally separate and treat -1 as default texture
- GpuTexture *rmaTextureData = this->getTextureData(textureData.RMA_Texture);
- if(rmaTextureData != nullptr && rmaTextureData->id != defaultTexture.id)
- {
- rmaLoaded = 1;
- glActiveTexture(GL_TEXTURE3);
- glBindTexture(GL_TEXTURE_2D, rmaTextureData->id);
- }
- //glActiveTexture(GL_TEXTURE2);
- //glBindTexture(GL_TEXTURE_CUBE_MAP, skyBox.texture); //note(vlod): this can be bound onlt once (refactor)
-
- if (normalLoaded && lightShader.normalMap)
- {
- if (indices[lightShader.normalSubroutineLocation] != lightShader.normalSubroutine_normalMap)
- {
- indices[lightShader.normalSubroutineLocation] = lightShader.normalSubroutine_normalMap;
- changed = 1;
- }
- }
- else
- {
- if (indices[lightShader.normalSubroutineLocation] != lightShader.normalSubroutine_noMap)
- {
- indices[lightShader.normalSubroutineLocation] = lightShader.normalSubroutine_noMap;
- changed = 1;
- }
- }
-
- if(rmaLoaded)
- {
- if (indices[lightShader.materialSubroutineLocation] != lightShader.materialSubroutine_functions[textureData.RMA_loadedTextures])
- {
- indices[lightShader.materialSubroutineLocation] = lightShader.materialSubroutine_functions[textureData.RMA_loadedTextures];
- changed = 1;
- }
-
- }else
- {
- if(indices[lightShader.materialSubroutineLocation] != lightShader.materialSubroutine_functions[0])
- {
- indices[lightShader.materialSubroutineLocation] = lightShader.materialSubroutine_functions[0];
- changed = 1;
- }
- }
-
- if(albedoLoaded != 0)
- {
- if (indices[lightShader.getAlbedoSubroutineLocation] != lightShader.albedoSubroutine_sampled)
- {
- indices[lightShader.getAlbedoSubroutineLocation] = lightShader.albedoSubroutine_sampled;
- changed = 1;
- }
- }
- else
- if (indices[lightShader.getAlbedoSubroutineLocation] != lightShader.albedoSubroutine_notSampled)
- {
- indices[lightShader.getAlbedoSubroutineLocation] = lightShader.albedoSubroutine_notSampled;
- changed = 1;
- }
- if (changed)
- {
- glUniformSubroutinesuiv(GL_FRAGMENT_SHADER, n, indices);
- }
- changed = 0;
-
- {
- glBindVertexArray(i.vertexArray);
- if (i.indexBuffer)
- {
- glDrawElements(GL_TRIANGLES, i.primitiveCount, GL_UNSIGNED_INT, 0);
- }
- else
- {
- glDrawArrays(GL_TRIANGLES, 0, i.primitiveCount);
- }
- }
-
- }
- glBindVertexArray(0);
- delete[] indices;
-
- glDepthFunc(GL_LESS);
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
- }
- void Renderer3D::renderObjectNormals(Object o, glm::vec3 position, glm::vec3 rotation,
- glm::vec3 scale, float normalSize, glm::vec3 normalColor)
- {
- auto obj = getObjectData(o);
- if(!obj)
- {
- return;
- }
- for(int i=0; i<obj->models.size(); i++)
- {
- renderSubObjectNormals(o, i, position, rotation, scale, normalSize, normalColor);
- }
-
- }
- void Renderer3D::renderSubObjectNormals(Object o, int index, glm::vec3 position, glm::vec3 rotation,
- glm::vec3 scale, float normalSize, glm::vec3 normalColor)
- {
-
- showNormalsProgram.shader.bind();
-
- auto projMat = camera.getProjectionMatrix();
- auto viewMat = camera.getWorldToViewMatrix();
- auto transformMat = gl3d::getTransformMatrix(position, rotation, scale);
-
- auto viewTransformMat = viewMat * transformMat;
-
- glUniformMatrix4fv(showNormalsProgram.modelTransformLocation,
- 1, GL_FALSE, &viewTransformMat[0][0]);
-
- glUniformMatrix4fv(showNormalsProgram.projectionLocation,
- 1, GL_FALSE, &projMat[0][0]);
-
- glUniform1f(showNormalsProgram.sizeLocation, normalSize);
- glUniform3fv(showNormalsProgram.colorLocation, 1, &(normalColor[0]));
- auto modelIndex = this->getObjectIndex(o);
- auto obj = getObjectData(o);
- if(obj == nullptr)
- {
- return;
- }
- {
- if(index >= obj->models.size())
- {
- return;
- }
- auto &i = obj->models[index];
-
- glBindVertexArray(i.vertexArray);
- if (i.indexBuffer)
- {
- glDrawElements(GL_TRIANGLES, i.primitiveCount, GL_UNSIGNED_INT, 0);
- }
- else
- {
- glDrawArrays(GL_TRIANGLES, 0, i.primitiveCount);
- }
- glBindVertexArray(0);
- }
- }
- void Renderer3D::renderSubObjectBorder(Object o, int index, glm::vec3 position, glm::vec3 rotation, glm::vec3 scale, float borderSize, glm::vec3 borderColor)
- {
- //auto modelIndex = this->getObjectIndex(o);
- //
- //auto obj = getObjectData(o);
- //if (obj == nullptr)
- //{
- // return;
- //}
- //
- //if (index >= obj->models.size())
- //{
- // return;
- //}
- //
- //
- //glEnable(GL_STENCIL_TEST);
- //glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
- //glStencilFunc(GL_ALWAYS, 1, 0xFF);
- //glStencilMask(0xFF);
- //
- //auto projMat = renderer.camera.getProjectionMatrix();
- //auto viewMat = renderer.camera.getWorldToViewMatrix();
- //auto transformMat = models[0].getTransformMatrix();
- //
- //auto viewProjMat = projMat * viewMat * transformMat;
- //
- ////todo implement a light weight shader here
- ////lightShader.bind(viewProjMat, transformMat,
- //// lightCubeModel.position, renderer.camera.position, gamaCorection,
- //// models[itemCurrent].models[subItemCurent].material, renderer.pointLights);
- //
- //glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
- //models[itemCurrent].models[subItemCurent].draw();
- //glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- //
- //glDisable(GL_STENCIL_TEST);
- //
- //glEnable(GL_STENCIL_TEST);
- //glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
- //glDepthFunc(GL_ALWAYS);
- //glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
- //glStencilMask(0x00);
- //
- //auto &m = models[itemCurrent].models[subItemCurent];
- //projMat = renderer.camera.getProjectionMatrix();
- //viewMat = renderer.camera.getWorldToViewMatrix();
- //
- //auto rotation = models[itemCurrent].rotation;
- //auto scale = models[itemCurrent].scale;
- //scale *= 1.05;
- //auto position = models[itemCurrent].position;
- //
- //
- //auto s = glm::scale(scale);
- //auto r = glm::rotate(rotation.x, glm::vec3(1, 0, 0)) *
- // glm::rotate(rotation.y, glm::vec3(0, 1, 0)) *
- // glm::rotate(rotation.z, glm::vec3(0, 0, 1));
- //auto t = glm::translate(position);
- //
- //transformMat = t * r * s;
- //
- //viewProjMat = projMat * viewMat * transformMat;
- //
- //shader.bind();
- //glUniformMatrix4fv(location, 1, GL_FALSE, &viewProjMat[0][0]);
- //
- //glBindBuffer(GL_ARRAY_BUFFER, m.vertexBuffer);
- //
- //glEnableVertexAttribArray(0);
- //glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)0);
- //glVertexAttrib3f(1, 98 / 255.f, 24 / 255.f, 201 / 255.f);
- //
- //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m.indexBuffer);
- //glDrawElements(GL_TRIANGLES, m.primitiveCount, GL_UNSIGNED_INT, 0);
- //
- //glDisable(GL_STENCIL_TEST);
- //glDepthFunc(GL_LESS);
- }
- int Renderer3D::getMaterialIndex(Material m)
- {
- int id = m.id_;
- auto found = std::find(materialIndexes.begin(), materialIndexes.end(), id);
- if (found == materialIndexes.end())
- {
- gl3dAssertComment(found == materialIndexes.end(), "invalid material");
- return -1;
- }
- id = found - materialIndexes.begin();
- return id;
- }
- int Renderer3D::getObjectIndex(Object o)
- {
- int id = o.id_;
- auto found = std::find(graphicModelsIndexes.begin(), graphicModelsIndexes.end(), id);
- if (found == graphicModelsIndexes.end())
- {
- gl3dAssertComment(found == graphicModelsIndexes.end(), "invalid object");
- return -1;
- }
- id = found - graphicModelsIndexes.begin();
-
- return id;
- }
- int Renderer3D::getTextureIndex(Texture t)
- {
- int id = t.id_;
-
- if (id == 0) { return -1; }//todo add this optimization to other gets
- auto found = std::find(loadedTexturesIndexes.begin(), loadedTexturesIndexes.end(), id);
- if (found == loadedTexturesIndexes.end())
- {
- gl3dAssertComment(found == loadedTexturesIndexes.end(), "invalid texture");
- return -1;
- }
- id = found - loadedTexturesIndexes.begin();
- return id;
- }
- void Renderer3D::render()
- {
- //glAnyCheck();
- //we draw a rect several times so we keep this vao binded
- glBindVertexArray(lightShader.quadVAO);
-
- #pragma region ssao
- glViewport(0, 0, w / 2, h / 2);
- glUseProgram(ssao.shader.id);
- glUniformMatrix4fv(ssao.u_projection, 1, GL_FALSE,
- &(camera.getProjectionMatrix())[0][0] );
- glUniformMatrix4fv(ssao.u_view, 1, GL_FALSE,
- &(camera.getWorldToViewMatrix())[0][0]);
- glUniform3fv(ssao.u_samples, 64, &(ssao.ssaoKernel[0][0]));
- glBindFramebuffer(GL_FRAMEBUFFER, ssao.ssaoFBO);
- glClear(GL_COLOR_BUFFER_BIT);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.positionViewSpace]);
- glUniform1i(ssao.u_gPosition, 0);
-
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.normal]);
- glUniform1i(ssao.u_gNormal, 1);
- glActiveTexture(GL_TEXTURE2);
- glBindTexture(GL_TEXTURE_2D, ssao.noiseTexture);
- glUniform1i(ssao.u_texNoise, 2);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
- glViewport(0, 0, w, h);
- #pragma endregion
- #pragma region ssao "blur" (more like average blur)
- glViewport(0, 0, w/4, h/4);
- glBindFramebuffer(GL_FRAMEBUFFER, ssao.blurBuffer);
- ssao.blurShader.bind();
- glClear(GL_COLOR_BUFFER_BIT);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, ssao.ssaoColorBuffer);
- glUniform1i(ssao.u_ssaoInput, 0);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- glViewport(0, 0, w, h);
- #pragma endregion
- #pragma region render into the bloom post processing fbo
- glBindFramebuffer(GL_FRAMEBUFFER, postProcess.fbo);
- glClear(GL_COLOR_BUFFER_BIT);
- glUseProgram(lightShader.lightingPassShader.id);
- glUniform1i(lightShader.light_u_positions, 0);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.position]);
- glUniform1i(lightShader.light_u_normals, 1);
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.normal]);
- glUniform1i(lightShader.light_u_albedo, 2);
- glActiveTexture(GL_TEXTURE2);
- glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.albedo]);
- glUniform1i(lightShader.light_u_materials, 3);
- glActiveTexture(GL_TEXTURE3);
- glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.material]);
- glUniform1i(lightShader.light_u_ssao, 4);
- glActiveTexture(GL_TEXTURE4);
- glBindTexture(GL_TEXTURE_2D, ssao.blurColorBuffer);
- //glBindTexture(GL_TEXTURE_2D, ssao.ssaoColorBuffer);
- glUniform3f(lightShader.light_u_eyePosition, camera.position.x, camera.position.y, camera.position.z);
- glUniformMatrix4fv(lightShader.light_u_view, 1, GL_FALSE, &(camera.getWorldToViewMatrix()[0][0]) );
- if (pointLights.size())
- {
- glBindBuffer(GL_SHADER_STORAGE_BUFFER, lightShader.pointLightsBlockBuffer);
-
- glBufferData(GL_SHADER_STORAGE_BUFFER, pointLights.size() * sizeof(internal::GpuPointLight)
- , &pointLights[0], GL_STREAM_DRAW);
-
- glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, lightShader.pointLightsBlockBuffer);
-
- }
- glUniform1i(lightShader.light_u_pointLightCount, pointLights.size());
- glUniform1i(lightShader.u_useSSAO, lightShader.useSSAO);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- #pragma endregion
- #pragma region bloom blur
-
- if(lightShader.bloom)
- {
- int blurs = 16;
- bool horizontal = 1; bool firstTime = 1;
- postProcess.gausianBLurShader.bind();
- glActiveTexture(GL_TEXTURE0);
- glUniform1i(postProcess.u_toBlurcolorInput, 0);
- glViewport(0, 0, w/2, h/2);
- for (int i = 0; i < blurs; i++)
- {
- glBindFramebuffer(GL_FRAMEBUFFER, postProcess.blurFbo[horizontal]);
- glClear(GL_COLOR_BUFFER_BIT);
- glUniform1i(postProcess.u_horizontal, horizontal);
- glBindTexture(GL_TEXTURE_2D,
- firstTime ? postProcess.colorBuffers[1] : postProcess.bluredColorBuffer[!horizontal]);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- horizontal = !horizontal;
- firstTime = false;
- }
- glViewport(0, 0, w, h);
- }
- #pragma endregion
- #pragma region do the post process stuff and draw to screen
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
- glUseProgram(postProcess.postProcessShader.id);
- //color data
- glUniform1i(postProcess.u_colorTexture, 0);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, postProcess.colorBuffers[0]);
- //bloom data
- glUniform1i(postProcess.u_bloomTexture, 1);
- glActiveTexture(GL_TEXTURE1);
- if(lightShader.bloom)
- {
- glBindTexture(GL_TEXTURE_2D, postProcess.bluredColorBuffer[1]);
- }else
- {
- glBindTexture(GL_TEXTURE_2D, postProcess.colorBuffers[1]);
- }
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- #pragma endregion
- #pragma region copy depth buffer for later forward rendering
- glBindVertexArray(0);
- glBindFramebuffer(GL_READ_FRAMEBUFFER, gBuffer.gBuffer);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); // write to default framebuffer
- glBlitFramebuffer(
- 0, 0, w, h, 0, 0, w, h, GL_DEPTH_BUFFER_BIT, GL_NEAREST
- );
- glBindFramebuffer(GL_FRAMEBUFFER, gBuffer.gBuffer);
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
- #pragma endregion
- }
- void Renderer3D::updateWindowMetrics(int x, int y)
- {
- w = x; h = y;
- glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.position]);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, x, y, 0, GL_RGBA, GL_FLOAT, NULL);
- glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.normal]);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, x, y, 0, GL_RGBA, GL_FLOAT, NULL);
- glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.albedo]);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.material]);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- glBindTexture(GL_TEXTURE_2D, gBuffer.buffers[gBuffer.positionViewSpace]);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, x, y, 0, GL_RGBA, GL_FLOAT, NULL);
- glBindRenderbuffer(GL_RENDERBUFFER, gBuffer.depthBuffer);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, x, y);
-
- //ssao
- glBindTexture(GL_TEXTURE_2D, ssao.ssaoColorBuffer);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w/2, h/2, 0, GL_RED, GL_FLOAT, NULL);
- glBindTexture(GL_TEXTURE_2D, ssao.blurColorBuffer);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w/4, h/4, 0, GL_RED, GL_FLOAT, NULL);
- //bloom
- for (int i = 0; i < 2; i++)
- {
- glBindTexture(GL_TEXTURE_2D, postProcess.colorBuffers[i]);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- }
- for(int i=0;i<2;i++)
- {
- glBindTexture(GL_TEXTURE_2D, postProcess.bluredColorBuffer[i]);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w/2, h/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- }
- }
- float lerp(float a, float b, float f)
- {
- return a + f * (b - a);
- }
- void Renderer3D::SSAO::create(int w, int h)
- {
- std::uniform_real_distribution<float> randomFloats(0.0f, 1.0f);
- std::uniform_real_distribution<float> randomFloatsSmaller(0.1f, 0.9f); //avoid ssao artefacts
- std::default_random_engine generator;
- ssaoKernel.reserve(64);
- for (unsigned int i = 0; i < 64; ++i)
- {
- glm::vec3 sample(
- randomFloats(generator) * 2.0 - 1.0,
- randomFloats(generator) * 2.0 - 1.0,
- randomFloats(generator) // z component is always positive
- );
- sample = glm::normalize(sample);
- float scale = (float)i / 64.0;
- scale = lerp(0.1f, 1.0f, scale * scale);
- sample *= scale;
- ssaoKernel.push_back(sample);
- }
- //std::shuffle(ssaoKernel.begin(), ssaoKernel.end(), generator);
- std::vector<glm::vec3> ssaoNoise;
- for (unsigned int i = 0; i < 16; i++)
- {
- glm::vec3 noise(
- randomFloats(generator) * 2.0 - 1.0,
- randomFloats(generator) * 2.0 - 1.0,
- 0.0f);
- ssaoNoise.push_back(noise);
- }
-
- glGenTextures(1, &noiseTexture);
- glBindTexture(GL_TEXTURE_2D, noiseTexture);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, 4, 4, 0, GL_RGB, GL_FLOAT, &ssaoNoise[0]);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glGenFramebuffers(1, &ssaoFBO);
- glBindFramebuffer(GL_FRAMEBUFFER, ssaoFBO);
- glGenTextures(1, &ssaoColorBuffer);
- glBindTexture(GL_TEXTURE_2D, ssaoColorBuffer);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w/2, h/2, 0, GL_RED, GL_FLOAT, NULL);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ssaoColorBuffer, 0);
- if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
- {
- std::cout << "ssaoFBO failed\n";
- }
- shader.loadShaderProgramFromFile("shaders/ssao/ssao.vert", "shaders/ssao/ssao.frag");
- u_projection = getUniform(shader.id, "u_projection");
- u_view = getUniform(shader.id, "u_view");
- u_gPosition = getUniform(shader.id, "u_gPosition");
- u_gNormal = getUniform(shader.id, "u_gNormal");
- u_texNoise = getUniform(shader.id, "u_texNoise");
- u_samples = getUniform(shader.id, "samples[0]");
-
-
- //blur
- blurShader.loadShaderProgramFromFile("shaders/ssao/blur.vert", "shaders/ssao/blur.frag");
-
- glGenFramebuffers(1, &blurBuffer);
- glBindFramebuffer(GL_FRAMEBUFFER, blurBuffer);
- glGenTextures(1, &blurColorBuffer);
- glBindTexture(GL_TEXTURE_2D, blurColorBuffer);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w/4, h/4, 0, GL_RED, GL_FLOAT, NULL);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, blurColorBuffer, 0);
- u_ssaoInput = getUniform(blurShader.id, "u_ssaoInput");
- if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
- {
- std::cout << "blur ssao buffer failed\n";
- }
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
- }
- void Renderer3D::PostProcess::create(int w, int h)
- {
- glGenFramebuffers(1, &fbo);
- glBindFramebuffer(GL_FRAMEBUFFER, fbo);
- glGenTextures(2, colorBuffers);
- for (int i = 0; i < 2; i++)
- {
- glBindTexture(GL_TEXTURE_2D, colorBuffers[i]);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- // attach texture to framebuffer
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, colorBuffers[i], 0);
- }
- unsigned int attachments[2] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
- glDrawBuffers(2, attachments);
- if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
- {
- std::cout << "post process fbo failed\n";
- }
-
- postProcessShader.loadShaderProgramFromFile("shaders/postProcess/postProcess.vert", "shaders/postProcess/postProcess.frag");
- u_colorTexture = getUniform(postProcessShader.id, "u_colorTexture");
- u_bloomTexture = getUniform(postProcessShader.id, "u_bloomTexture");
- gausianBLurShader.loadShaderProgramFromFile("shaders/postProcess/gausianBlur.vert", "shaders/postProcess/gausianBlur.frag");
- u_toBlurcolorInput = getUniform(gausianBLurShader.id, "u_toBlurcolorInput");
- u_horizontal = getUniform(gausianBLurShader.id, "u_horizontal");
- glGenFramebuffers(2, blurFbo);
- glGenTextures(2, bluredColorBuffer);
- for(int i=0;i <2; i++)
- {
- glBindFramebuffer(GL_FRAMEBUFFER, blurFbo[i]);
- glBindTexture(GL_TEXTURE_2D, bluredColorBuffer[i]);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w/2, h/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, bluredColorBuffer[i], 0);
-
- if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
- {
- std::cout << "blur post process fbo " << i << " failed\n";
- }
- }
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
- }
- };
- #pragma endregion
|