genoview.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903
  1. #include "raylib.h"
  2. #include "raymath.h"
  3. #define RAYGUI_IMPLEMENTATION
  4. #include "raygui.h"
  5. #include "rlgl.h"
  6. #include <assert.h>
  7. //----------------------------------------------------------------------------------
  8. // Camera
  9. //----------------------------------------------------------------------------------
  10. // Basic Orbit Camera with simple controls
  11. typedef struct {
  12. Camera3D cam3d;
  13. float azimuth;
  14. float altitude;
  15. float distance;
  16. Vector3 offset;
  17. } OrbitCamera;
  18. static inline void OrbitCameraInit(OrbitCamera* camera)
  19. {
  20. memset(&camera->cam3d, 0, sizeof(Camera3D));
  21. camera->cam3d.position = (Vector3){ 2.0f, 3.0f, 5.0f };
  22. camera->cam3d.target = (Vector3){ -0.5f, 1.0f, 0.0f };
  23. camera->cam3d.up = (Vector3){ 0.0f, 1.0f, 0.0f };
  24. camera->cam3d.fovy = 45.0f;
  25. camera->cam3d.projection = CAMERA_PERSPECTIVE;
  26. camera->azimuth = 0.0f;
  27. camera->altitude = 0.4f;
  28. camera->distance = 4.0f;
  29. camera->offset = Vector3Zero();
  30. }
  31. static inline void OrbitCameraUpdate(
  32. OrbitCamera* camera,
  33. Vector3 target,
  34. float azimuthDelta,
  35. float altitudeDelta,
  36. float offsetDeltaX,
  37. float offsetDeltaY,
  38. float mouseWheel,
  39. float dt)
  40. {
  41. camera->azimuth = camera->azimuth + 1.0f * dt * -azimuthDelta;
  42. camera->altitude = Clamp(camera->altitude + 1.0f * dt * altitudeDelta, 0.0, 0.4f * PI);
  43. camera->distance = Clamp(camera->distance + 20.0f * dt * -mouseWheel, 0.1f, 100.0f);
  44. Quaternion rotationAzimuth = QuaternionFromAxisAngle((Vector3){0, 1, 0}, camera->azimuth);
  45. Vector3 position = Vector3RotateByQuaternion((Vector3){0, 0, camera->distance}, rotationAzimuth);
  46. Vector3 axis = Vector3Normalize(Vector3CrossProduct(position, (Vector3){0, 1, 0}));
  47. Quaternion rotationAltitude = QuaternionFromAxisAngle(axis, camera->altitude);
  48. Vector3 localOffset = (Vector3){ dt * offsetDeltaX, dt * -offsetDeltaY, 0.0f };
  49. localOffset = Vector3RotateByQuaternion(localOffset, rotationAzimuth);
  50. camera->offset = Vector3Add(camera->offset, Vector3RotateByQuaternion(localOffset, rotationAltitude));
  51. Vector3 cameraTarget = Vector3Add(camera->offset, target);
  52. Vector3 eye = Vector3Add(cameraTarget, Vector3RotateByQuaternion(position, rotationAltitude));
  53. camera->cam3d.target = cameraTarget;
  54. camera->cam3d.position = eye;
  55. }
  56. //----------------------------------------------------------------------------------
  57. // Shadow Maps
  58. //----------------------------------------------------------------------------------
  59. typedef struct
  60. {
  61. Vector3 target;
  62. Vector3 position;
  63. Vector3 up;
  64. double width;
  65. double height;
  66. double near;
  67. double far;
  68. } ShadowLight;
  69. RenderTexture2D LoadShadowMap(int width, int height)
  70. {
  71. RenderTexture2D target = { 0 };
  72. target.id = rlLoadFramebuffer();
  73. target.texture.width = width;
  74. target.texture.height = height;
  75. assert(target.id);
  76. rlEnableFramebuffer(target.id);
  77. target.depth.id = rlLoadTextureDepth(width, height, false);
  78. target.depth.width = width;
  79. target.depth.height = height;
  80. target.depth.format = 19; //DEPTH_COMPONENT_24BIT?
  81. target.depth.mipmaps = 1;
  82. rlFramebufferAttach(target.id, target.depth.id, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_TEXTURE2D, 0);
  83. assert(rlFramebufferComplete(target.id));
  84. rlDisableFramebuffer();
  85. return target;
  86. }
  87. void UnloadShadowMap(RenderTexture2D target)
  88. {
  89. if (target.id > 0)
  90. {
  91. rlUnloadFramebuffer(target.id);
  92. }
  93. }
  94. void BeginShadowMap(RenderTexture2D target, ShadowLight shadowLight)
  95. {
  96. BeginTextureMode(target);
  97. ClearBackground(WHITE);
  98. rlDrawRenderBatchActive(); // Update and draw internal render batch
  99. rlMatrixMode(RL_PROJECTION); // Switch to projection matrix
  100. rlPushMatrix(); // Save previous matrix, which contains the settings for the 2d ortho projection
  101. rlLoadIdentity(); // Reset current matrix (projection)
  102. rlOrtho(
  103. -shadowLight.width/2, shadowLight.width/2,
  104. -shadowLight.height/2, shadowLight.height/2,
  105. shadowLight.near, shadowLight.far);
  106. rlMatrixMode(RL_MODELVIEW); // Switch back to modelview matrix
  107. rlLoadIdentity(); // Reset current matrix (modelview)
  108. // Setup Camera view
  109. Matrix matView = MatrixLookAt(shadowLight.position, shadowLight.target, shadowLight.up);
  110. rlMultMatrixf(MatrixToFloat(matView)); // Multiply modelview matrix by view matrix (camera)
  111. rlEnableDepthTest(); // Enable DEPTH_TEST for 3D
  112. }
  113. void EndShadowMap()
  114. {
  115. rlDrawRenderBatchActive(); // Update and draw internal render batch
  116. rlMatrixMode(RL_PROJECTION); // Switch to projection matrix
  117. rlPopMatrix(); // Restore previous matrix (projection) from matrix stack
  118. rlMatrixMode(RL_MODELVIEW); // Switch back to modelview matrix
  119. rlLoadIdentity(); // Reset current matrix (modelview)
  120. rlDisableDepthTest(); // Disable DEPTH_TEST for 2D
  121. EndTextureMode();
  122. }
  123. void SetShaderValueShadowMap(Shader shader, int locIndex, RenderTexture2D target)
  124. {
  125. if (locIndex > -1)
  126. {
  127. rlEnableShader(shader.id);
  128. int slot = 10; // Can be anything 0 to 15, but 0 will probably be taken up
  129. rlActiveTextureSlot(slot);
  130. rlEnableTexture(target.depth.id);
  131. rlSetUniform(locIndex, &slot, SHADER_UNIFORM_INT, 1);
  132. }
  133. }
  134. //----------------------------------------------------------------------------------
  135. // GBuffer
  136. //----------------------------------------------------------------------------------
  137. typedef struct
  138. {
  139. unsigned int id; // OpenGL framebuffer object id
  140. Texture color; // Color buffer attachment texture
  141. Texture normal; // Normal buffer attachment texture
  142. Texture depth; // Depth buffer attachment texture
  143. } GBuffer;
  144. GBuffer LoadGBuffer(int width, int height)
  145. {
  146. GBuffer target = { 0 };
  147. target.id = rlLoadFramebuffer();
  148. assert(target.id);
  149. rlEnableFramebuffer(target.id);
  150. target.color.id = rlLoadTexture(NULL, width, height, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, 1);
  151. target.color.width = width;
  152. target.color.height = height;
  153. target.color.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
  154. target.color.mipmaps = 1;
  155. rlFramebufferAttach(target.id, target.color.id, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_TEXTURE2D, 0);
  156. target.normal.id = rlLoadTexture(NULL, width, height, PIXELFORMAT_UNCOMPRESSED_R16G16B16A16, 1);
  157. target.normal.width = width;
  158. target.normal.height = height;
  159. target.normal.format = PIXELFORMAT_UNCOMPRESSED_R16G16B16A16;
  160. target.normal.mipmaps = 1;
  161. rlFramebufferAttach(target.id, target.normal.id, RL_ATTACHMENT_COLOR_CHANNEL1, RL_ATTACHMENT_TEXTURE2D, 0);
  162. target.depth.id = rlLoadTextureDepth(width, height, false);
  163. target.depth.width = width;
  164. target.depth.height = height;
  165. target.depth.format = 19; //DEPTH_COMPONENT_24BIT?
  166. target.depth.mipmaps = 1;
  167. rlFramebufferAttach(target.id, target.depth.id, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_TEXTURE2D, 0);
  168. assert(rlFramebufferComplete(target.id));
  169. rlDisableFramebuffer();
  170. return target;
  171. }
  172. void UnloadGBuffer(GBuffer target)
  173. {
  174. if (target.id > 0)
  175. {
  176. rlUnloadFramebuffer(target.id);
  177. }
  178. }
  179. void BeginGBuffer(GBuffer target, Camera3D camera)
  180. {
  181. rlDrawRenderBatchActive(); // Update and draw internal render batch
  182. rlEnableFramebuffer(target.id); // Enable render target
  183. rlActiveDrawBuffers(2);
  184. // Set viewport and RLGL internal framebuffer size
  185. rlViewport(0, 0, target.color.width, target.color.height);
  186. rlSetFramebufferWidth(target.color.width);
  187. rlSetFramebufferHeight(target.color.height);
  188. ClearBackground(BLACK);
  189. rlMatrixMode(RL_PROJECTION); // Switch to projection matrix
  190. rlPushMatrix(); // Save previous matrix, which contains the settings for the 2d ortho projection
  191. rlLoadIdentity(); // Reset current matrix (projection)
  192. float aspect = (float)target.color.width/(float)target.color.height;
  193. // NOTE: zNear and zFar values are important when computing depth buffer values
  194. if (camera.projection == CAMERA_PERSPECTIVE)
  195. {
  196. // Setup perspective projection
  197. double top = rlGetCullDistanceNear()*tan(camera.fovy*0.5*DEG2RAD);
  198. double right = top*aspect;
  199. rlFrustum(-right, right, -top, top, rlGetCullDistanceNear(), rlGetCullDistanceFar());
  200. }
  201. else if (camera.projection == CAMERA_ORTHOGRAPHIC)
  202. {
  203. // Setup orthographic projection
  204. double top = camera.fovy/2.0;
  205. double right = top*aspect;
  206. rlOrtho(-right, right, -top,top, rlGetCullDistanceNear(), rlGetCullDistanceFar());
  207. }
  208. rlMatrixMode(RL_MODELVIEW); // Switch back to modelview matrix
  209. rlLoadIdentity(); // Reset current matrix (modelview)
  210. // Setup Camera view
  211. Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
  212. rlMultMatrixf(MatrixToFloat(matView)); // Multiply modelview matrix by view matrix (camera)
  213. rlEnableDepthTest(); // Enable DEPTH_TEST for 3D
  214. }
  215. void EndGBuffer(int windowWidth, int windowHeight)
  216. {
  217. rlDrawRenderBatchActive(); // Update and draw internal render batch
  218. rlDisableDepthTest(); // Disable DEPTH_TEST for 2D
  219. rlActiveDrawBuffers(1);
  220. rlDisableFramebuffer(); // Disable render target (fbo)
  221. rlMatrixMode(RL_PROJECTION); // Switch to projection matrix
  222. rlPopMatrix(); // Restore previous matrix (projection) from matrix stack
  223. rlLoadIdentity(); // Reset current matrix (projection)
  224. rlOrtho(0, windowWidth, windowHeight, 0, 0.0f, 1.0f);
  225. rlMatrixMode(RL_MODELVIEW); // Switch back to modelview matrix
  226. rlLoadIdentity(); // Reset current matrix (modelview)
  227. }
  228. //----------------------------------------------------------------------------------
  229. // Geno Character and Animation
  230. //----------------------------------------------------------------------------------
  231. Model LoadGenoModel(const char* fileName)
  232. {
  233. Model model = { 0 };
  234. model.transform = MatrixIdentity();
  235. FILE* f = fopen(fileName, "rb");
  236. if (f == NULL)
  237. {
  238. TRACELOG(LOG_ERROR, "MODEL Unable to read skinned model file %s", fileName);
  239. return model;
  240. }
  241. model.materialCount = 1;
  242. model.materials = RL_CALLOC(model.materialCount, sizeof(Mesh));
  243. model.materials[0] = LoadMaterialDefault();
  244. model.meshCount = 1;
  245. model.meshes = RL_CALLOC(model.meshCount, sizeof(Mesh));
  246. model.meshMaterial = RL_CALLOC(model.meshCount, sizeof(Mesh));
  247. model.meshMaterial[0] = 0;
  248. fread(&model.meshes[0].vertexCount, sizeof(int), 1, f);
  249. fread(&model.meshes[0].triangleCount, sizeof(int), 1, f);
  250. fread(&model.boneCount, sizeof(int), 1, f);
  251. model.meshes[0].boneCount = model.boneCount;
  252. model.meshes[0].vertices = RL_CALLOC(model.meshes[0].vertexCount * 3, sizeof(float));
  253. model.meshes[0].texcoords = RL_CALLOC(model.meshes[0].vertexCount * 2, sizeof(float));
  254. model.meshes[0].normals = RL_CALLOC(model.meshes[0].vertexCount * 3, sizeof(float));
  255. model.meshes[0].boneIds = RL_CALLOC(model.meshes[0].vertexCount * 4, sizeof(unsigned char));
  256. model.meshes[0].boneWeights = RL_CALLOC(model.meshes[0].vertexCount * 4, sizeof(float));
  257. model.meshes[0].indices = RL_CALLOC(model.meshes[0].triangleCount * 3, sizeof(unsigned short));
  258. model.meshes[0].animVertices = RL_CALLOC(model.meshes[0].vertexCount * 3, sizeof(float));
  259. model.meshes[0].animNormals = RL_CALLOC(model.meshes[0].vertexCount * 3, sizeof(float));
  260. model.bones = RL_CALLOC(model.boneCount, sizeof(BoneInfo));
  261. model.bindPose = RL_CALLOC(model.boneCount, sizeof(Transform));
  262. fread(model.meshes[0].vertices, sizeof(float), model.meshes[0].vertexCount * 3, f);
  263. fread(model.meshes[0].texcoords, sizeof(float), model.meshes[0].vertexCount * 2, f);
  264. fread(model.meshes[0].normals, sizeof(float), model.meshes[0].vertexCount * 3, f);
  265. fread(model.meshes[0].boneIds, sizeof(unsigned char), model.meshes[0].vertexCount * 4, f);
  266. fread(model.meshes[0].boneWeights, sizeof(float), model.meshes[0].vertexCount * 4, f);
  267. fread(model.meshes[0].indices, sizeof(unsigned short), model.meshes[0].triangleCount * 3, f);
  268. memcpy(model.meshes[0].animVertices, model.meshes[0].vertices, sizeof(float) * model.meshes[0].vertexCount * 3);
  269. memcpy(model.meshes[0].animNormals, model.meshes[0].normals, sizeof(float) * model.meshes[0].vertexCount * 3);
  270. fread(model.bones, sizeof(BoneInfo), model.boneCount, f);
  271. fread(model.bindPose, sizeof(Transform), model.boneCount, f);
  272. fclose(f);
  273. model.meshes[0].boneMatrices = RL_CALLOC(model.boneCount, sizeof(Matrix));
  274. for (int i = 0; i < model.boneCount; i++)
  275. {
  276. model.meshes[0].boneMatrices[i] = MatrixIdentity();
  277. }
  278. UploadMesh(&model.meshes[0], true);
  279. return model;
  280. }
  281. ModelAnimation LoadGenoModelAnimation(const char* fileName)
  282. {
  283. ModelAnimation animation = { 0 };
  284. FILE* f = fopen(fileName, "rb");
  285. if (f == NULL)
  286. {
  287. TRACELOG(LOG_ERROR, "MODEL ANIMATION Unable to read animation file %s", fileName);
  288. return animation;
  289. }
  290. fread(&animation.frameCount, sizeof(int), 1, f);
  291. fread(&animation.boneCount, sizeof(int), 1, f);
  292. animation.bones = RL_CALLOC(animation.boneCount, sizeof(BoneInfo));
  293. fread(animation.bones, sizeof(BoneInfo), animation.boneCount, f);
  294. animation.framePoses = RL_CALLOC(animation.frameCount, sizeof(Transform*));
  295. for (int i = 0; i < animation.frameCount; i++)
  296. {
  297. animation.framePoses[i] = RL_CALLOC(animation.boneCount, sizeof(Transform));
  298. fread(animation.framePoses[i], sizeof(Transform), animation.boneCount, f);
  299. }
  300. fclose(f);
  301. return animation;
  302. }
  303. ModelAnimation LoadEmptyModelAnimation(Model model)
  304. {
  305. ModelAnimation animation = { 0 };
  306. animation.frameCount = 1;
  307. animation.boneCount = model.boneCount;
  308. animation.bones = RL_CALLOC(animation.boneCount, sizeof(BoneInfo));
  309. memcpy(animation.bones, model.bones, animation.boneCount * sizeof(BoneInfo));
  310. animation.framePoses = RL_CALLOC(animation.frameCount, sizeof(Transform*));
  311. for (int i = 0; i < animation.frameCount; i++)
  312. {
  313. animation.framePoses[i] = RL_CALLOC(animation.boneCount, sizeof(Transform));
  314. memcpy(animation.framePoses[i], model.bindPose, animation.boneCount * sizeof(Transform));
  315. }
  316. return animation;
  317. }
  318. //----------------------------------------------------------------------------------
  319. // Debug Draw
  320. //----------------------------------------------------------------------------------
  321. static inline void DrawTransform(Transform t, float scale)
  322. {
  323. Matrix rotMatrix = QuaternionToMatrix(t.rotation);
  324. DrawLine3D(
  325. t.translation,
  326. Vector3Add(t.translation, (Vector3){ scale * rotMatrix.m0, scale * rotMatrix.m1, scale * rotMatrix.m2 }),
  327. RED);
  328. DrawLine3D(
  329. t.translation,
  330. Vector3Add(t.translation, (Vector3){ scale * rotMatrix.m4, scale * rotMatrix.m5, scale * rotMatrix.m6 }),
  331. GREEN);
  332. DrawLine3D(
  333. t.translation,
  334. Vector3Add(t.translation, (Vector3){ scale * rotMatrix.m8, scale * rotMatrix.m9, scale * rotMatrix.m10 }),
  335. BLUE);
  336. }
  337. static inline void DrawModelBindPose(Model model, Color color)
  338. {
  339. for (int i = 0; i < model.boneCount; i++)
  340. {
  341. DrawSphereWires(
  342. model.bindPose[i].translation,
  343. 0.01f,
  344. 4,
  345. 6,
  346. color);
  347. DrawTransform(model.bindPose[i], 0.1f);
  348. if (model.bones[i].parent != -1)
  349. {
  350. DrawLine3D(
  351. model.bindPose[i].translation,
  352. model.bindPose[model.bones[i].parent].translation,
  353. color);
  354. }
  355. }
  356. }
  357. static inline void DrawModelAnimationFrameSkeleton(ModelAnimation animation, int frame, Color color)
  358. {
  359. for (int i = 0; i < animation.boneCount; i++)
  360. {
  361. DrawSphereWires(
  362. animation.framePoses[frame][i].translation,
  363. 0.01f,
  364. 4,
  365. 6,
  366. color);
  367. DrawTransform(animation.framePoses[frame][i], 0.1f);
  368. if (animation.bones[i].parent != -1)
  369. {
  370. DrawLine3D(
  371. animation.framePoses[frame][i].translation,
  372. animation.framePoses[frame][animation.bones[i].parent].translation,
  373. color);
  374. }
  375. }
  376. }
  377. //----------------------------------------------------------------------------------
  378. // App
  379. //----------------------------------------------------------------------------------
  380. int main(int argc, char **argv)
  381. {
  382. // Init Window
  383. const int screenWidth = 1280;
  384. const int screenHeight = 720;
  385. SetConfigFlags(FLAG_VSYNC_HINT);
  386. InitWindow(screenWidth, screenHeight, "GenoView");
  387. SetTargetFPS(60);
  388. // Shaders
  389. Shader shadowShader = LoadShader("./resources/shadow.vs", "./resources/shadow.fs");
  390. int shadowShaderLightClipNear = GetShaderLocation(shadowShader, "lightClipNear");
  391. int shadowShaderLightClipFar = GetShaderLocation(shadowShader, "lightClipFar");
  392. Shader skinnedShadowShader = LoadShader("./resources/skinnedShadow.vs", "./resources/shadow.fs");
  393. int skinnedShadowShaderLightClipNear = GetShaderLocation(skinnedShadowShader, "lightClipNear");
  394. int skinnedShadowShaderLightClipFar = GetShaderLocation(skinnedShadowShader, "lightClipFar");
  395. Shader skinnedBasicShader = LoadShader("./resources/skinnedBasic.vs", "./resources/basic.fs");
  396. int skinnedBasicShaderSpecularity = GetShaderLocation(skinnedBasicShader, "specularity");
  397. int skinnedBasicShaderGlossiness = GetShaderLocation(skinnedBasicShader, "glossiness");
  398. int skinnedBasicShaderCamClipNear = GetShaderLocation(skinnedBasicShader, "camClipNear");
  399. int skinnedBasicShaderCamClipFar = GetShaderLocation(skinnedBasicShader, "camClipFar");
  400. Shader basicShader = LoadShader("./resources/basic.vs", "./resources/basic.fs");
  401. int basicShaderSpecularity = GetShaderLocation(basicShader, "specularity");
  402. int basicShaderGlossiness = GetShaderLocation(basicShader, "glossiness");
  403. int basicShaderCamClipNear = GetShaderLocation(basicShader, "camClipNear");
  404. int basicShaderCamClipFar = GetShaderLocation(basicShader, "camClipFar");
  405. Shader lightingShader = LoadShader("./resources/post.vs", "./resources/lighting.fs");
  406. int lightingShaderGBufferColor = GetShaderLocation(lightingShader, "gbufferColor");
  407. int lightingShaderGBufferNormal = GetShaderLocation(lightingShader, "gbufferNormal");
  408. int lightingShaderGBufferDepth = GetShaderLocation(lightingShader, "gbufferDepth");
  409. int lightingShaderSSAO = GetShaderLocation(lightingShader, "ssao");
  410. int lightingShaderCamPos = GetShaderLocation(lightingShader, "camPos");
  411. int lightingShaderCamInvViewProj = GetShaderLocation(lightingShader, "camInvViewProj");
  412. int lightingShaderLightDir = GetShaderLocation(lightingShader, "lightDir");
  413. int lightingShaderSunColor = GetShaderLocation(lightingShader, "sunColor");
  414. int lightingShaderSunStrength = GetShaderLocation(lightingShader, "sunStrength");
  415. int lightingShaderSkyColor = GetShaderLocation(lightingShader, "skyColor");
  416. int lightingShaderSkyStrength = GetShaderLocation(lightingShader, "skyStrength");
  417. int lightingShaderGroundStrength = GetShaderLocation(lightingShader, "groundStrength");
  418. int lightingShaderAmbientStrength = GetShaderLocation(lightingShader, "ambientStrength");
  419. int lightingShaderExposure = GetShaderLocation(lightingShader, "exposure");
  420. int lightingShaderCamClipNear = GetShaderLocation(lightingShader, "camClipNear");
  421. int lightingShaderCamClipFar = GetShaderLocation(lightingShader, "camClipFar");
  422. Shader ssaoShader = LoadShader("./resources/post.vs", "./resources/ssao.fs");
  423. int ssaoShaderGBufferNormal = GetShaderLocation(ssaoShader, "gbufferNormal");
  424. int ssaoShaderGBufferDepth = GetShaderLocation(ssaoShader, "gbufferDepth");
  425. int ssaoShaderCamView = GetShaderLocation(ssaoShader, "camView");
  426. int ssaoShaderCamProj = GetShaderLocation(ssaoShader, "camProj");
  427. int ssaoShaderCamInvProj = GetShaderLocation(ssaoShader, "camInvProj");
  428. int ssaoShaderCamInvViewProj = GetShaderLocation(ssaoShader, "camInvViewProj");
  429. int ssaoShaderLightViewProj = GetShaderLocation(ssaoShader, "lightViewProj");
  430. int ssaoShaderShadowMap = GetShaderLocation(ssaoShader, "shadowMap");
  431. int ssaoShaderShadowInvResolution = GetShaderLocation(ssaoShader, "shadowInvResolution");
  432. int ssaoShaderCamClipNear = GetShaderLocation(ssaoShader, "camClipNear");
  433. int ssaoShaderCamClipFar = GetShaderLocation(ssaoShader, "camClipFar");
  434. int ssaoShaderLightClipNear = GetShaderLocation(ssaoShader, "lightClipNear");
  435. int ssaoShaderLightClipFar = GetShaderLocation(ssaoShader, "lightClipFar");
  436. int ssaoShaderLightDir = GetShaderLocation(ssaoShader, "lightDir");
  437. Shader blurShader = LoadShader("./resources/post.vs", "./resources/blur.fs");
  438. int blurShaderGBufferNormal = GetShaderLocation(blurShader, "gbufferNormal");
  439. int blurShaderGBufferDepth = GetShaderLocation(blurShader, "gbufferDepth");
  440. int blurShaderInputTexture = GetShaderLocation(blurShader, "inputTexture");
  441. int blurShaderCamInvProj = GetShaderLocation(blurShader, "camInvProj");
  442. int blurShaderCamClipNear = GetShaderLocation(blurShader, "camClipNear");
  443. int blurShaderCamClipFar = GetShaderLocation(blurShader, "camClipFar");
  444. int blurShaderInvTextureResolution = GetShaderLocation(blurShader, "invTextureResolution");
  445. int blurShaderBlurDirection = GetShaderLocation(blurShader, "blurDirection");
  446. Shader fxaaShader = LoadShader("./resources/post.vs", "./resources/fxaa.fs");
  447. int fxaaShaderInputTexture = GetShaderLocation(fxaaShader, "inputTexture");
  448. int fxaaShaderInvTextureResolution = GetShaderLocation(fxaaShader, "invTextureResolution");
  449. // Objects
  450. Mesh groundMesh = GenMeshPlane(20.0f, 20.0f, 10, 10);
  451. Model groundModel = LoadModelFromMesh(groundMesh);
  452. Vector3 groundPosition = (Vector3){ 0.0f, -0.01f, 0.0f };
  453. Model genoModel = LoadGenoModel("./resources/Geno.bin");
  454. Vector3 genoPosition = (Vector3){ 0.0f, 0.0f, 0.0f };
  455. // Animation
  456. // ModelAnimation testAnimation = LoadGenoModelAnimation("./resources/ground1_subject1.bin");
  457. //ModelAnimation testAnimation = LoadGenoModelAnimation("./resources/kthstreet_gPO_sFM_cAll_d02_mPO_ch01_atombounce_001.bin");
  458. ModelAnimation testAnimation = LoadEmptyModelAnimation(genoModel);
  459. int animationFrame = 0;
  460. assert(testAnimation.boneCount == genoModel.boneCount);
  461. // Camera
  462. OrbitCamera camera;
  463. OrbitCameraInit(&camera);
  464. rlSetClipPlanes(0.01f, 50.0f);
  465. // Shadows
  466. Vector3 lightDir = Vector3Normalize((Vector3){ 0.35f, -1.0f, -0.35f });
  467. ShadowLight shadowLight = (ShadowLight){ 0 };
  468. shadowLight.target = Vector3Zero();
  469. shadowLight.position = Vector3Scale(lightDir, -5.0f);
  470. shadowLight.up = (Vector3){ 0.0f, 1.0f, 0.0f };
  471. shadowLight.width = 5.0f;
  472. shadowLight.height = 5.0f;
  473. shadowLight.near = 0.01f;
  474. shadowLight.far = 10.0f;
  475. int shadowWidth = 1024;
  476. int shadowHeight = 1024;
  477. Vector2 shadowInvResolution = (Vector2){ 1.0f / shadowWidth, 1.0f / shadowHeight };
  478. RenderTexture2D shadowMap = LoadShadowMap(shadowWidth, shadowHeight);
  479. // GBuffer and Render Textures
  480. GBuffer gbuffer = LoadGBuffer(screenWidth, screenHeight);
  481. RenderTexture2D lighted = LoadRenderTexture(screenWidth, screenHeight);
  482. RenderTexture2D ssaoFront = LoadRenderTexture(screenWidth, screenHeight);
  483. RenderTexture2D ssaoBack = LoadRenderTexture(screenWidth, screenHeight);
  484. // UI
  485. bool drawBoneTransforms = false;
  486. // Go
  487. while (!WindowShouldClose())
  488. {
  489. // Animation
  490. animationFrame = (animationFrame + 1) % testAnimation.frameCount;
  491. UpdateModelAnimationBones(genoModel, testAnimation, animationFrame);
  492. // Shadow Light Tracks Character
  493. Vector3 hipPosition = testAnimation.framePoses[animationFrame][0].translation;
  494. shadowLight.target = (Vector3){ hipPosition.x, 0.0f, hipPosition.z };
  495. shadowLight.position = Vector3Add(shadowLight.target, Vector3Scale(lightDir, -5.0f));
  496. // Update Camera
  497. OrbitCameraUpdate(
  498. &camera,
  499. (Vector3){ hipPosition.x, 0.75f, hipPosition.z },
  500. (IsKeyDown(KEY_LEFT_CONTROL) && IsMouseButtonDown(0)) ? GetMouseDelta().x : 0.0f,
  501. (IsKeyDown(KEY_LEFT_CONTROL) && IsMouseButtonDown(0)) ? GetMouseDelta().y : 0.0f,
  502. (IsKeyDown(KEY_LEFT_CONTROL) && IsMouseButtonDown(1)) ? GetMouseDelta().x : 0.0f,
  503. (IsKeyDown(KEY_LEFT_CONTROL) && IsMouseButtonDown(1)) ? GetMouseDelta().y : 0.0f,
  504. GetMouseWheelMove(),
  505. GetFrameTime());
  506. // Render
  507. rlDisableColorBlend();
  508. BeginDrawing();
  509. // Render Shadow Maps
  510. BeginShadowMap(shadowMap, shadowLight);
  511. Matrix lightViewProj = MatrixMultiply(rlGetMatrixModelview(), rlGetMatrixProjection());
  512. float lightClipNear = rlGetCullDistanceNear();
  513. float lightClipFar = rlGetCullDistanceFar();
  514. SetShaderValue(shadowShader, shadowShaderLightClipNear, &lightClipNear, SHADER_UNIFORM_FLOAT);
  515. SetShaderValue(shadowShader, shadowShaderLightClipFar, &lightClipFar, SHADER_UNIFORM_FLOAT);
  516. SetShaderValue(skinnedShadowShader, skinnedShadowShaderLightClipNear, &lightClipNear, SHADER_UNIFORM_FLOAT);
  517. SetShaderValue(skinnedShadowShader, skinnedShadowShaderLightClipFar, &lightClipFar, SHADER_UNIFORM_FLOAT);
  518. groundModel.materials[0].shader = shadowShader;
  519. DrawModel(groundModel, groundPosition, 1.0f, WHITE);
  520. genoModel.materials[0].shader = skinnedShadowShader;
  521. DrawModel(genoModel, genoPosition, 1.0f, WHITE);
  522. EndShadowMap();
  523. // Render GBuffer
  524. BeginGBuffer(gbuffer, camera.cam3d);
  525. Matrix camView = rlGetMatrixModelview();
  526. Matrix camProj = rlGetMatrixProjection();
  527. Matrix camInvProj = MatrixInvert(camProj);
  528. Matrix camInvViewProj = MatrixInvert(MatrixMultiply(camView, camProj));
  529. float camClipNear = rlGetCullDistanceNear();
  530. float camClipFar = rlGetCullDistanceFar();
  531. float specularity = 0.5f;
  532. float glossiness = 10.0f;
  533. SetShaderValue(basicShader, basicShaderSpecularity, &specularity, SHADER_UNIFORM_FLOAT);
  534. SetShaderValue(basicShader, basicShaderGlossiness, &glossiness, SHADER_UNIFORM_FLOAT);
  535. SetShaderValue(basicShader, basicShaderCamClipNear, &camClipNear, SHADER_UNIFORM_FLOAT);
  536. SetShaderValue(basicShader, basicShaderCamClipFar, &camClipFar, SHADER_UNIFORM_FLOAT);
  537. SetShaderValue(skinnedBasicShader, skinnedBasicShaderSpecularity, &specularity, SHADER_UNIFORM_FLOAT);
  538. SetShaderValue(skinnedBasicShader, skinnedBasicShaderGlossiness, &glossiness, SHADER_UNIFORM_FLOAT);
  539. SetShaderValue(skinnedBasicShader, skinnedBasicShaderCamClipNear, &camClipNear, SHADER_UNIFORM_FLOAT);
  540. SetShaderValue(skinnedBasicShader, skinnedBasicShaderCamClipFar, &camClipFar, SHADER_UNIFORM_FLOAT);
  541. groundModel.materials[0].shader = basicShader;
  542. DrawModel(groundModel, groundPosition, 1.0f, (Color){ 190, 190, 190, 255 });
  543. genoModel.materials[0].shader = skinnedBasicShader;
  544. DrawModel(genoModel, genoPosition, 1.0f, ORANGE);
  545. EndGBuffer(screenWidth, screenHeight);
  546. // Render SSAO and Shadows
  547. BeginTextureMode(ssaoFront);
  548. BeginShaderMode(ssaoShader);
  549. SetShaderValueTexture(ssaoShader, ssaoShaderGBufferNormal, gbuffer.normal);
  550. SetShaderValueTexture(ssaoShader, ssaoShaderGBufferDepth, gbuffer.depth);
  551. SetShaderValueMatrix(ssaoShader, ssaoShaderCamView, camView);
  552. SetShaderValueMatrix(ssaoShader, ssaoShaderCamProj, camProj);
  553. SetShaderValueMatrix(ssaoShader, ssaoShaderCamInvProj, camInvProj);
  554. SetShaderValueMatrix(ssaoShader, ssaoShaderCamInvViewProj, camInvViewProj);
  555. SetShaderValueMatrix(ssaoShader, ssaoShaderLightViewProj, lightViewProj);
  556. SetShaderValueShadowMap(ssaoShader, ssaoShaderShadowMap, shadowMap);
  557. SetShaderValue(ssaoShader, ssaoShaderShadowInvResolution, &shadowInvResolution, SHADER_UNIFORM_VEC2);
  558. SetShaderValue(ssaoShader, ssaoShaderCamClipNear, &camClipNear, SHADER_UNIFORM_FLOAT);
  559. SetShaderValue(ssaoShader, ssaoShaderCamClipFar, &camClipFar, SHADER_UNIFORM_FLOAT);
  560. SetShaderValue(ssaoShader, ssaoShaderLightClipNear, &lightClipNear, SHADER_UNIFORM_FLOAT);
  561. SetShaderValue(ssaoShader, ssaoShaderLightClipFar, &lightClipFar, SHADER_UNIFORM_FLOAT);
  562. SetShaderValue(ssaoShader, ssaoShaderLightDir, &lightDir, SHADER_UNIFORM_VEC3);
  563. ClearBackground(WHITE);
  564. DrawTextureRec(
  565. ssaoFront.texture,
  566. (Rectangle){ 0, 0, ssaoFront.texture.width, -ssaoFront.texture.height },
  567. (Vector2){ 0, 0 },
  568. WHITE);
  569. EndShaderMode();
  570. EndTextureMode();
  571. // Blur Horizontal
  572. BeginTextureMode(ssaoBack);
  573. BeginShaderMode(blurShader);
  574. Vector2 blurDirection = (Vector2){ 1.0f, 0.0f };
  575. Vector2 blurInvTextureResolution = (Vector2){ 1.0f / ssaoFront.texture.width, 1.0f / ssaoFront.texture.height };
  576. SetShaderValueTexture(blurShader, blurShaderGBufferNormal, gbuffer.normal);
  577. SetShaderValueTexture(blurShader, blurShaderGBufferDepth, gbuffer.depth);
  578. SetShaderValueTexture(blurShader, blurShaderInputTexture, ssaoFront.texture);
  579. SetShaderValueMatrix(blurShader, blurShaderCamInvProj, camInvProj);
  580. SetShaderValue(blurShader, blurShaderCamClipNear, &camClipNear, SHADER_UNIFORM_FLOAT);
  581. SetShaderValue(blurShader, blurShaderCamClipFar, &camClipFar, SHADER_UNIFORM_FLOAT);
  582. SetShaderValue(blurShader, blurShaderInvTextureResolution, &blurInvTextureResolution, SHADER_UNIFORM_VEC2);
  583. SetShaderValue(blurShader, blurShaderBlurDirection, &blurDirection, SHADER_UNIFORM_VEC2);
  584. DrawTextureRec(
  585. ssaoBack.texture,
  586. (Rectangle){ 0, 0, ssaoBack.texture.width, -ssaoBack.texture.height },
  587. (Vector2){ 0, 0 },
  588. WHITE);
  589. EndShaderMode();
  590. EndTextureMode();
  591. // Blur Vertical
  592. BeginTextureMode(ssaoFront);
  593. BeginShaderMode(blurShader);
  594. blurDirection = (Vector2){ 0.0f, 1.0f };
  595. SetShaderValueTexture(blurShader, blurShaderInputTexture, ssaoBack.texture);
  596. SetShaderValue(blurShader, blurShaderBlurDirection, &blurDirection, SHADER_UNIFORM_VEC2);
  597. DrawTextureRec(
  598. ssaoFront.texture,
  599. (Rectangle){ 0, 0, ssaoFront.texture.width, -ssaoFront.texture.height },
  600. (Vector2){ 0, 0 },
  601. WHITE);
  602. EndShaderMode();
  603. EndTextureMode();
  604. // Light GBuffer
  605. BeginTextureMode(lighted);
  606. BeginShaderMode(lightingShader);
  607. Vector3 sunColor = (Vector3){ 253.0f / 255.0f, 255.0f / 255.0f, 232.0f / 255.0f };
  608. float sunStrength = 0.25f;
  609. Vector3 skyColor = (Vector3){ 174.0f / 255.0f, 183.0f / 255.0f, 190.0f / 255.0f };
  610. float skyStrength = 0.15f;
  611. float groundStrength = 0.1f;
  612. float ambientStrength = 1.0f;
  613. float exposure = 0.9f;
  614. SetShaderValueTexture(lightingShader, lightingShaderGBufferColor, gbuffer.color);
  615. SetShaderValueTexture(lightingShader, lightingShaderGBufferNormal, gbuffer.normal);
  616. SetShaderValueTexture(lightingShader, lightingShaderGBufferDepth, gbuffer.depth);
  617. SetShaderValueTexture(lightingShader, lightingShaderSSAO, ssaoFront.texture);
  618. SetShaderValue(lightingShader, lightingShaderCamPos, &camera.cam3d.position, SHADER_UNIFORM_VEC3);
  619. SetShaderValueMatrix(lightingShader, lightingShaderCamInvViewProj, camInvViewProj);
  620. SetShaderValue(lightingShader, lightingShaderLightDir, &lightDir, SHADER_UNIFORM_VEC3);
  621. SetShaderValue(lightingShader, lightingShaderSunColor, &sunColor, SHADER_UNIFORM_VEC3);
  622. SetShaderValue(lightingShader, lightingShaderSunStrength, &sunStrength, SHADER_UNIFORM_FLOAT);
  623. SetShaderValue(lightingShader, lightingShaderSkyColor, &skyColor, SHADER_UNIFORM_VEC3);
  624. SetShaderValue(lightingShader, lightingShaderSkyStrength, &skyStrength, SHADER_UNIFORM_FLOAT);
  625. SetShaderValue(lightingShader, lightingShaderGroundStrength, &groundStrength, SHADER_UNIFORM_FLOAT);
  626. SetShaderValue(lightingShader, lightingShaderAmbientStrength, &ambientStrength, SHADER_UNIFORM_FLOAT);
  627. SetShaderValue(lightingShader, lightingShaderExposure, &exposure, SHADER_UNIFORM_FLOAT);
  628. SetShaderValue(lightingShader, lightingShaderCamClipNear, &camClipNear, SHADER_UNIFORM_FLOAT);
  629. SetShaderValue(lightingShader, lightingShaderCamClipFar, &camClipFar, SHADER_UNIFORM_FLOAT);
  630. ClearBackground(RAYWHITE);
  631. DrawTextureRec(
  632. gbuffer.color,
  633. (Rectangle){ 0, 0, gbuffer.color.width, -gbuffer.color.height },
  634. (Vector2){ 0, 0 },
  635. WHITE);
  636. EndShaderMode();
  637. // Debug Draw
  638. BeginMode3D(camera.cam3d);
  639. if (drawBoneTransforms)
  640. {
  641. DrawModelAnimationFrameSkeleton(testAnimation, animationFrame, GRAY);
  642. }
  643. EndMode3D();
  644. EndTextureMode();
  645. // Render Final with FXAA
  646. BeginShaderMode(fxaaShader);
  647. Vector2 fxaaInvTextureResolution = (Vector2){ 1.0f / lighted.texture.width, 1.0f / lighted.texture.height };
  648. SetShaderValueTexture(fxaaShader, fxaaShaderInputTexture, lighted.texture);
  649. SetShaderValue(fxaaShader, fxaaShaderInvTextureResolution, &fxaaInvTextureResolution, SHADER_UNIFORM_VEC2);
  650. DrawTextureRec(
  651. lighted.texture,
  652. (Rectangle){ 0, 0, lighted.texture.width, -lighted.texture.height },
  653. (Vector2){ 0, 0 },
  654. WHITE);
  655. EndShaderMode();
  656. // UI
  657. rlEnableColorBlend();
  658. GuiGroupBox((Rectangle){ 20, 10, 190, 180 }, "Camera");
  659. GuiLabel((Rectangle){ 30, 20, 150, 20 }, "Ctrl + Left Click - Rotate");
  660. GuiLabel((Rectangle){ 30, 40, 150, 20 }, "Ctrl + Right Click - Pan");
  661. GuiLabel((Rectangle){ 30, 60, 150, 20 }, "Mouse Scroll - Zoom");
  662. GuiLabel((Rectangle){ 30, 80, 150, 20 }, TextFormat("Target: [% 5.3f % 5.3f % 5.3f]", camera.cam3d.target.x, camera.cam3d.target.y, camera.cam3d.target.z));
  663. GuiLabel((Rectangle){ 30, 100, 150, 20 }, TextFormat("Offset: [% 5.3f % 5.3f % 5.3f]", camera.offset.x, camera.offset.y, camera.offset.z));
  664. GuiLabel((Rectangle){ 30, 120, 150, 20 }, TextFormat("Azimuth: %5.3f", camera.azimuth));
  665. GuiLabel((Rectangle){ 30, 140, 150, 20 }, TextFormat("Altitude: %5.3f", camera.altitude));
  666. GuiLabel((Rectangle){ 30, 160, 150, 20 }, TextFormat("Distance: %5.3f", camera.distance));
  667. GuiGroupBox((Rectangle){ screenWidth - 260, 10, 240, 40 }, "Rendering");
  668. GuiCheckBox((Rectangle){ screenWidth - 250, 20, 20, 20 }, "Draw Transforms", &drawBoneTransforms);
  669. EndDrawing();
  670. }
  671. UnloadRenderTexture(lighted);
  672. UnloadRenderTexture(ssaoBack);
  673. UnloadRenderTexture(ssaoFront);
  674. UnloadRenderTexture(lighted);
  675. UnloadGBuffer(gbuffer);
  676. UnloadShadowMap(shadowMap);
  677. UnloadModelAnimation(testAnimation);
  678. UnloadModel(genoModel);
  679. UnloadModel(groundModel);
  680. UnloadShader(fxaaShader);
  681. UnloadShader(blurShader);
  682. UnloadShader(ssaoShader);
  683. UnloadShader(lightingShader);
  684. UnloadShader(basicShader);
  685. UnloadShader(skinnedBasicShader);
  686. UnloadShader(skinnedShadowShader);
  687. UnloadShader(shadowShader);
  688. CloseWindow();
  689. return 0;
  690. }