diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml new file mode 100644 index 0000000..8d33d78 --- /dev/null +++ b/.github/workflows/build-and-deploy.yml @@ -0,0 +1,64 @@ +name: Build and Deploy web + +on: [push] + +jobs: + build: + runs-on: macos-14 + name: MacOS -> Emscripten, Release + + steps: + - name: Clone DiligentGraphics.github.io repository + uses: actions/checkout@v3 + with: + submodules: recursive + + - name: Check + working-directory: ${{github.workspace}} + if: success() + run: | + python ./combine_artifacts.py + + - name: Clone DiligentEngine repository + uses: actions/checkout@v3 + with: + fetch-depth: 0 + submodules: recursive + repository: DiligentGraphics/DiligentEngine + path: DiligentEngine + + - name: Set up build environment + if: success() + working-directory: ${{github.workspace}}/DiligentEngine + uses: DiligentGraphics/github-action/setup-build-env@v1 + with: + platform: Emscripten + + - name: Configure CMake + if: success() + working-directory: ${{github.workspace}}/DiligentEngine + uses: DiligentGraphics/github-action/configure-cmake@v1 + with: + build-type: Release + cmake-args: -DDILIGENT_NO_WEBGPU=ON + + - name: Build + if: success() + working-directory: ${{github.workspace}}/DiligentEngine + uses: DiligentGraphics/github-action/build@v1 + with: + build-args: --target=Tutorial01_HelloTriangle + + - name: Combine artifacts + working-directory: ${{github.workspace}} + if: success() + run: | + python ./combine_artifacts.py + + - name: Upload artifacts + if: success() + uses: actions/upload-artifact@v3 + with: + path: | + ${{github.workspace}}/BuildArtefacts + retention-days: 90 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5327163 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +CMakeFiles +*.cmake +https_server.py diff --git a/combine_artifacts.py b/combine_artifacts.py new file mode 100644 index 0000000..df6c4ea --- /dev/null +++ b/combine_artifacts.py @@ -0,0 +1,37 @@ +import os +import shutil + + +SOURCE_IMAGES = 'images' +SOURCE_TEMPLATE = 'template' +SOURCE_BUILD = 'build/Emscripten/DiligentSamples' +DESTINATION_DIR = 'BuildArtefacts' +BUILD_TARGETS = [ + "Tutorial01_HelloTriangle" +] + +if __name__ == '__main__': + if not os.path.exists(DESTINATION_DIR): + os.makedirs(DESTINATION_DIR) + + shutil.copytree(SOURCE_IMAGES, os.path.join(DESTINATION_DIR, 'images'), dirs_exist_ok=True) + for item in os.listdir(SOURCE_TEMPLATE): + source_item = os.path.join(SOURCE_TEMPLATE, item) + destination_item = os.path.join(SOURCE_TEMPLATE, item) + + if os.path.isdir(source_item): + shutil.copytree(source_item, destination_item, dirs_exist_ok=True) + else: + shutil.copy2(source_item, destination_item) + + for folder in BUILD_TARGETS: + source_folder_path_tutorials = os.path.join(SOURCE_BUILD, "Tutorials", folder) + source_folder_path_samples = os.path.join(SOURCE_BUILD, "Samples", folder) + destination_folder_path = os.path.join(DESTINATION_DIR, "wasm-modules", folder) + + if os.path.exists(source_folder_path_tutorials): + shutil.copytree(source_folder_path_tutorials, destination_folder_path, dirs_exist_ok=True) + elif os.path.exists(source_folder_path_samples): + shutil.copytree(source_folder_path_samples, destination_folder_path, dirs_exist_ok=True) + else: + print(f"Folder '{folder}' not found.") diff --git a/images/content/samples/Atmosphere.gif b/images/content/samples/Atmosphere.gif new file mode 100644 index 0000000..32521ae Binary files /dev/null and b/images/content/samples/Atmosphere.gif differ diff --git a/images/content/samples/GLTFViewer.jpg b/images/content/samples/GLTFViewer.jpg new file mode 100644 index 0000000..e394b36 Binary files /dev/null and b/images/content/samples/GLTFViewer.jpg differ diff --git a/images/content/samples/ImguiDemo.png b/images/content/samples/ImguiDemo.png new file mode 100644 index 0000000..af2d937 Binary files /dev/null and b/images/content/samples/ImguiDemo.png differ diff --git a/images/content/samples/Shadows.jpg b/images/content/samples/Shadows.jpg new file mode 100644 index 0000000..6ffbbb1 Binary files /dev/null and b/images/content/samples/Shadows.jpg differ diff --git a/images/content/search-bar/search-icon.png b/images/content/search-bar/search-icon.png new file mode 100644 index 0000000..a4ec6c3 Binary files /dev/null and b/images/content/search-bar/search-icon.png differ diff --git a/images/content/tutorials/Tutorial01_HelloTriangle.png b/images/content/tutorials/Tutorial01_HelloTriangle.png new file mode 100644 index 0000000..d6233fc Binary files /dev/null and b/images/content/tutorials/Tutorial01_HelloTriangle.png differ diff --git a/images/content/tutorials/Tutorial02_Cube.gif b/images/content/tutorials/Tutorial02_Cube.gif new file mode 100644 index 0000000..6421028 Binary files /dev/null and b/images/content/tutorials/Tutorial02_Cube.gif differ diff --git a/images/content/tutorials/Tutorial03_Texturing.gif b/images/content/tutorials/Tutorial03_Texturing.gif new file mode 100644 index 0000000..392cd76 Binary files /dev/null and b/images/content/tutorials/Tutorial03_Texturing.gif differ diff --git a/images/content/tutorials/Tutorial04_Instancing.gif b/images/content/tutorials/Tutorial04_Instancing.gif new file mode 100644 index 0000000..e31f344 Binary files /dev/null and b/images/content/tutorials/Tutorial04_Instancing.gif differ diff --git a/images/content/tutorials/Tutorial05_TextureArray.gif b/images/content/tutorials/Tutorial05_TextureArray.gif new file mode 100644 index 0000000..ed53054 Binary files /dev/null and b/images/content/tutorials/Tutorial05_TextureArray.gif differ diff --git a/images/content/tutorials/Tutorial06_Multithreading.gif b/images/content/tutorials/Tutorial06_Multithreading.gif new file mode 100644 index 0000000..f9238c1 Binary files /dev/null and b/images/content/tutorials/Tutorial06_Multithreading.gif differ diff --git a/images/content/tutorials/Tutorial09_Quads.gif b/images/content/tutorials/Tutorial09_Quads.gif new file mode 100644 index 0000000..594796b Binary files /dev/null and b/images/content/tutorials/Tutorial09_Quads.gif differ diff --git a/images/content/tutorials/Tutorial10_DataStreaming.gif b/images/content/tutorials/Tutorial10_DataStreaming.gif new file mode 100644 index 0000000..2ad01f2 Binary files /dev/null and b/images/content/tutorials/Tutorial10_DataStreaming.gif differ diff --git a/images/content/tutorials/Tutorial11_ResourceUpdates.gif b/images/content/tutorials/Tutorial11_ResourceUpdates.gif new file mode 100644 index 0000000..b61f11d Binary files /dev/null and b/images/content/tutorials/Tutorial11_ResourceUpdates.gif differ diff --git a/images/content/tutorials/Tutorial12_RenderTarget.gif b/images/content/tutorials/Tutorial12_RenderTarget.gif new file mode 100644 index 0000000..dba0f13 Binary files /dev/null and b/images/content/tutorials/Tutorial12_RenderTarget.gif differ diff --git a/images/content/tutorials/Tutorial13_ShadowMap.gif b/images/content/tutorials/Tutorial13_ShadowMap.gif new file mode 100644 index 0000000..258634a Binary files /dev/null and b/images/content/tutorials/Tutorial13_ShadowMap.gif differ diff --git a/images/content/tutorials/Tutorial14_ComputeShader.gif b/images/content/tutorials/Tutorial14_ComputeShader.gif new file mode 100644 index 0000000..c0967ca Binary files /dev/null and b/images/content/tutorials/Tutorial14_ComputeShader.gif differ diff --git a/images/content/tutorials/Tutorial16_BindlessResources.gif b/images/content/tutorials/Tutorial16_BindlessResources.gif new file mode 100644 index 0000000..1818ec8 Binary files /dev/null and b/images/content/tutorials/Tutorial16_BindlessResources.gif differ diff --git a/images/content/tutorials/Tutorial17_MSAA.gif b/images/content/tutorials/Tutorial17_MSAA.gif new file mode 100644 index 0000000..40d6053 Binary files /dev/null and b/images/content/tutorials/Tutorial17_MSAA.gif differ diff --git a/images/content/tutorials/Tutorial18_Queries.gif b/images/content/tutorials/Tutorial18_Queries.gif new file mode 100644 index 0000000..708854b Binary files /dev/null and b/images/content/tutorials/Tutorial18_Queries.gif differ diff --git a/images/content/tutorials/Tutorial19_RenderPasses.gif b/images/content/tutorials/Tutorial19_RenderPasses.gif new file mode 100644 index 0000000..4e9d1d2 Binary files /dev/null and b/images/content/tutorials/Tutorial19_RenderPasses.gif differ diff --git a/images/content/tutorials/Tutorial25_StatePackager.jpg b/images/content/tutorials/Tutorial25_StatePackager.jpg new file mode 100644 index 0000000..fee79ec Binary files /dev/null and b/images/content/tutorials/Tutorial25_StatePackager.jpg differ diff --git a/images/content/tutorials/Tutorial26_StateCache.jpg b/images/content/tutorials/Tutorial26_StateCache.jpg new file mode 100644 index 0000000..6480359 Binary files /dev/null and b/images/content/tutorials/Tutorial26_StateCache.jpg differ diff --git a/images/content/tutorials/Tutorial27_PostProcessing.jpg b/images/content/tutorials/Tutorial27_PostProcessing.jpg new file mode 100644 index 0000000..940dee9 Binary files /dev/null and b/images/content/tutorials/Tutorial27_PostProcessing.jpg differ diff --git a/images/header/diligentgraphics-icon.ico b/images/header/diligentgraphics-icon.ico new file mode 100644 index 0000000..beb2e09 Binary files /dev/null and b/images/header/diligentgraphics-icon.ico differ diff --git a/images/header/diligentgraphics-logo.png b/images/header/diligentgraphics-logo.png new file mode 100644 index 0000000..e2cb9f7 Binary files /dev/null and b/images/header/diligentgraphics-logo.png differ diff --git a/images/header/github-mark-white.png b/images/header/github-mark-white.png new file mode 100644 index 0000000..50b8175 Binary files /dev/null and b/images/header/github-mark-white.png differ diff --git a/index.html b/index.html deleted file mode 100644 index e902295..0000000 --- a/index.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - Under Development - - - -
Under Development
- - diff --git a/template/enable-threads.js b/template/enable-threads.js new file mode 100644 index 0000000..70daaca --- /dev/null +++ b/template/enable-threads.js @@ -0,0 +1,76 @@ +// NOTE: This file creates a service worker that cross-origin-isolates the page (read more here: https://web.dev/coop-coep/) which allows us to use wasm threads. +// Normally you would set the COOP and COEP headers on the server to do this, but Github Pages doesn't allow this, so this is a hack to do that. + +/* Edited version of: coi-serviceworker v0.1.6 - Guido Zuidhof, licensed under MIT */ +// From here: https://github.com/gzuidhof/coi-serviceworker +if(typeof window === 'undefined') { + self.addEventListener("install", () => self.skipWaiting()); + self.addEventListener("activate", e => e.waitUntil(self.clients.claim())); + + async function handleFetch(request) { + if(request.cache === "only-if-cached" && request.mode !== "same-origin") { + return; + } + + if(request.mode === "no-cors") { // We need to set `credentials` to "omit" for no-cors requests, per this comment: https://bugs.chromium.org/p/chromium/issues/detail?id=1309901#c7 + request = new Request(request.url, { + cache: request.cache, + credentials: "omit", + headers: request.headers, + integrity: request.integrity, + destination: request.destination, + keepalive: request.keepalive, + method: request.method, + mode: request.mode, + redirect: request.redirect, + referrer: request.referrer, + referrerPolicy: request.referrerPolicy, + signal: request.signal, + }); + } + + let r = await fetch(request).catch(e => console.error(e)); + + if(r.status === 0) { + return r; + } + + const headers = new Headers(r.headers); + headers.set("Cross-Origin-Embedder-Policy", "credentialless"); // or: require-corp + headers.set("Cross-Origin-Opener-Policy", "same-origin"); + + return new Response(r.body, { status: r.status, statusText: r.statusText, headers }); + } + + self.addEventListener("fetch", function(e) { + e.respondWith(handleFetch(e.request)); // respondWith must be executed synchonously (but can be passed a Promise) + }); + + } else { + (async function() { + if(window.crossOriginIsolated !== false) return; + + let registration = await navigator.serviceWorker.register(window.document.currentScript.src).catch(e => console.error("COOP/COEP Service Worker failed to register:", e)); + if(registration) { + console.log("COOP/COEP Service Worker registered", registration.scope); + + registration.addEventListener("updatefound", () => { + console.log("Reloading page to make use of updated COOP/COEP Service Worker."); + window.location.reload(); + }); + + // If the registration is active, but it's not controlling the page + if(registration.active && !navigator.serviceWorker.controller) { + console.log("Reloading page to make use of COOP/COEP Service Worker."); + window.location.reload(); + } + } + })(); + } + + // Code to deregister: + // let registrations = await navigator.serviceWorker.getRegistrations(); + // for(let registration of registrations) { + // await registration.unregister(); + // } + \ No newline at end of file diff --git a/template/index.html b/template/index.html new file mode 100644 index 0000000..85fc7c2 --- /dev/null +++ b/template/index.html @@ -0,0 +1,66 @@ + + + + + + + Diligent Graphics + + + + + +
+ + + + + GitHub + +
+ +
+ + +
+ + +
+

Tutorials

+
+
+
+ +
+

Samples

+
+
+
+
+

Known issues

+
    +
  • 14 - Compute Shader tutorial doesn't work on WebGL.
  • +
  • 18 - Queries tutorial doesn't work on WebGPU.
  • +
  • 19 - Render Passes tutorial doesn't work on WebGL.
  • +
  • Atmosphere sample doesn't work on WebGL.
  • +
  • Shadows sample has artifacts on WebGL.
  • +
+
+
+
+ + + + + + diff --git a/template/script.js b/template/script.js new file mode 100644 index 0000000..b3322b2 --- /dev/null +++ b/template/script.js @@ -0,0 +1,206 @@ +const tutorials = [ + { + id: "Tutorial01_HelloTriangle", + title: "01 - Hello Triangle", + description: "This tutorial demonstrates the basics of Diligent Engine API. It shows how to create shaders, pipeline state object and how to render a simple triangle.", + image: "images/content/tutorials/Tutorial01_HelloTriangle.png", + tutorialLink: "wasm-modules/Tutorial01_HelloTriangle/Tutorial01_HelloTriangle.html", + githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial01_HelloTriangle" + }, + { + id: "Tutorial02_Cube", + title: "02 - Cube", + description: "This tutorial demonstrates how to render an actual 3D object, a cube. It shows how to load shaders from files, create and use vertex, index and uniform buffers.", + image: "images/content/tutorials/Tutorial02_Cube.gif", + tutorialLink: "wasm-modules/Tutorial02_Cube/Tutorial02_Cube.html", + githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial02_Cube" + }, + { + id: "Tutorial03_Texturing", + title: "03 - Texturing", + description: "This tutorial demonstrates how to apply a texture to a 3D object. It shows how to load a texture from file, create shader resource binding object and how to sample a texture in the shader.", + image: "images/content/tutorials/Tutorial03_Texturing.gif", + tutorialLink: "wasm-modules/Tutorial03_Texturing/Tutorial03_Texturing.html", + githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial03_Texturing" + }, + { + id: "Tutorial04_Instancing", + title: "04 - Instancing", + description: "This tutorial demonstrates how to use instancing to render multiple copies of one object using unique transformation matrix for every copy.", + image: "images/content/tutorials/Tutorial04_Instancing.gif", + tutorialLink: "wasm-modules/Tutorial04_Instancing/Tutorial04_Instancing.html", + githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial04_Instancing" + }, + { + id: "Tutorial05_TextureArray", + title: "05 - Texture Array", + description: "This tutorial demonstrates how to combine instancing with texture arrays to use unique texture for every instance.", + image: "images/content/tutorials/Tutorial05_TextureArray.gif", + tutorialLink: "wasm-modules/Tutorial05_TextureArray/Tutorial05_TextureArray.html", + githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial05_TextureArray" + }, + { + id: "Tutorial06_Multithreading", + title: "06 - Multithreading", + description: "This tutorial shows how to generate command lists in parallel from multiple threads.", + image: "images/content/tutorials/Tutorial06_Multithreading.gif", + tutorialLink: "wasm-modules/Tutorial06_Multithreading/Tutorial06_Multithreading.html", + githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial06_Multithreading" + }, + { + id: "Tutorial09_Quads", + title: "09 - Quads", + description: "This tutorial shows how to render multiple 2D quads, frequently switching textures and blend modes.", + image: "images/content/tutorials/Tutorial09_Quads.gif", + tutorialLink: "wasm-modules/Tutorial09_Quads/Tutorial09_Quads.html", + githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial09_Quads" + }, + { + id: "Tutorial10_DataStreaming", + title: "10 - Data Streaming", + description: "This tutorial shows dynamic buffer mapping strategy using MAP_FLAG_DISCARD and MAP_FLAG_DO_NOT_SYNCHRONIZE flags to efficiently stream varying amounts of data to GPU.", + image: "images/content/tutorials/Tutorial10_DataStreaming.gif", + tutorialLink: "wasm-modules/Tutorial10_DataStreaming/Tutorial10_DataStreaming.html", + githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial10_DataStreaming" + }, + { + id: "Tutorial11_ResourceUpdates", + title: "11 - Resource Updates", + description: "This tutorial demonstrates different ways to update buffers and textures in Diligent Engine and explains important internal details and performance implications related to each method.", + image: "images/content/tutorials/Tutorial11_ResourceUpdates.gif", + tutorialLink: "wasm-modules/Tutorial11_ResourceUpdates/Tutorial11_ResourceUpdates.html", + githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial11_ResourceUpdates" + }, + { + id: "Tutorial12_RenderTarget", + title: "12 - Render Target", + description: "This tutorial demonstrates how to render a 3d cube into an offscreen render target and do a simple post-processing effect.", + image: "images/content/tutorials/Tutorial12_RenderTarget.gif", + tutorialLink: "wasm-modules/Tutorial12_RenderTarget/Tutorial12_RenderTarget.html", + githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial12_RenderTarget" + }, + { + id: "Tutorial13_ShadowMap", + title: "13 - Shadow Map", + description: "This tutorial demonstrates how to render basic shadows using a shadow map.", + image: "images/content/tutorials/Tutorial13_ShadowMap.gif", + tutorialLink: "wasm-modules/Tutorial13_ShadowMap/Tutorial13_ShadowMap.html", + githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial13_ShadowMap" + }, + { + id: "Tutorial14_ComputeShader", + title: "14 - Compute Shader", + description: "This tutorial shows how to implement a simple particle simulation system using compute shaders.", + image: "images/content/tutorials/Tutorial14_ComputeShader.gif", + tutorialLink: "wasm-modules/Tutorial14_ComputeShader/Tutorial14_ComputeShader.html", + githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial14_ComputeShader" + }, + { + id: "Tutorial16_BindlessResources", + title: "16 - Bindless Resources", + description: "This tutorial shows how to implement bindless resources, a technique that leverages dynamic shader resource indexing feature enabled by the next-gen APIs to significantly improve rendering performance.", + image: "images/content/tutorials/Tutorial16_BindlessResources.gif", + tutorialLink: "wasm-modules/Tutorial16_BindlessResources/Tutorial16_BindlessResources.html", + githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial16_BindlessResources" + }, + { + id: "Tutorial17_MSAA", + title: "17 - MSAA", + description: "This tutorial demonstrates how to use multisample anti-aliasing (MSAA) to make geometrical edges look smoother and more temporarily stable.", + image: "images/content/tutorials/Tutorial17_MSAA.gif", + tutorialLink: "wasm-modules/Tutorial17_MSAA/Tutorial17_MSAA.html", + githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial17_MSAA" + }, + { + id: "Tutorial18_Queries", + title: "18 - Queries", + description: "This tutorial demonstrates how to use queries to retrieve various information about the GPU operation, such as the number of primitives rendered, command processing duration, etc.", + image: "images/content/tutorials/Tutorial18_Queries.gif", + tutorialLink: "wasm-modules/Tutorial18_Queries/Tutorial18_Queries.html", + githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial18_Queries" + }, + { + id: "Tutorial19_RenderPasses", + title: "19 - Render Passes", + description: "This tutorial demonstrates how to use the render passes API to implement simple deferred shading.", + image: "images/content/tutorials/Tutorial19_RenderPasses.gif", + tutorialLink: "wasm-modules/Tutorial19_RenderPasses/Tutorial19_RenderPasses.html", + githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial19_RenderPasses" + }, + { + id: "Tutorial27_PostProcessing", + title: "27 - Post Processing", + description: "This tutorial demonstrates how to use post-processing effects from the DiligentFX module.", + image: "images/content/tutorials/Tutorial27_PostProcessing.jpg", + tutorialLink: "wasm-modules/Tutorial27_PostProcessing/Tutorial27_PostProcessing.html", + githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial27_PostProcessing" + } +]; + +const samples = [ + { + id: "Sample_Atmosphere", + title: "Atmosphere", + description: "This sample demonstrates how to integrate Epipolar Light Scattering post-processing effect into an application to render physically-based atmosphere.", + image: "images/content/samples/Atmosphere.gif", + tutorialLink: "wasm-modules/Atmosphere/Atmosphere.html", + githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Samples/Atmosphere" + }, + { + id: "Sample_GLTFViewer", + title: "GLTF Viewer", + description: "This sample demonstrates how to use the Asset Loader and PBR Renderer to load and render GLTF models.", + image: "images/content/samples/GLTFViewer.jpg", + tutorialLink: "wasm-modules/GLTFViewer/GLTFViewer.html", + githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Samples/GLTFViewer" + }, + { + id: "Sample_ImguiDemo", + title: "Dear ImGui Demo", + description: "This sample demonstrates the integration of the engine with dear imgui UI library.", + image: "images/content/samples/ImguiDemo.png", + tutorialLink: "wasm-modules/ImguiDemo/ImguiDemo.html", + githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Samples/ImguiDemo" + }, + { + id: "Sample_Shadows", + title: "Shadows", + description: "This sample demonstrates how to use the Shadowing component to render high-quality shadows.", + image: "images/content/samples/Shadows.jpg", + tutorialLink: "wasm-modules/Shadows/Shadows.html", + githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Samples/Shadows" + } +]; + +function createCard(item) { + return ` +
+ ${item.title} +

${item.title}

+

${item.description}

+
+ Run sample + View on GitHub +
+
+ `; +} + +const tutorialGrid = document.getElementById('tutorialGrid'); +const samplesGrid = document.getElementById('samplesGrid'); + +tutorials.forEach(tutorial => { + tutorialGrid.innerHTML += createCard(tutorial); +}); + +samples.forEach(sample => { + samplesGrid.innerHTML += createCard(sample); +}); + +document.querySelector('.search-bar input').addEventListener('input', function(e) { + const query = e.target.value.toLowerCase(); + document.querySelectorAll('.card').forEach(function(card) { + const title = card.querySelector('h3').innerText.toLowerCase(); + card.style.display = title.includes(query) ? '' : 'none'; + }); +}); diff --git a/template/styles.css b/template/styles.css new file mode 100644 index 0000000..47404a4 --- /dev/null +++ b/template/styles.css @@ -0,0 +1,275 @@ +body { + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + margin: 0; + background: linear-gradient(177deg, #22223a, #303e3d, #3a3a3a); + background-size: 180% 180%; + animation: gradient-animation 15s ease infinite; + color: #ffffff; + padding-top: 80px; + padding-right: 20px; + background-attachment: fixed; +} + +@keyframes gradient-animation { + 0% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } + 100% { background-position: 0% 50%; } +} + +header { + background-color: rgba(0, 0, 0, 0.5); + display: flex; + align-items: center; + justify-content: space-between; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + position: fixed; + top: 0; + width: 100%; + z-index: 1000; +} + +.logo { + height: 60px; + padding-left: 40px; + padding-top: 10px; + padding-bottom: 10px; + transition: transform 0.3s ease, filter 0.3s ease; +} + +.logo:hover { + transform: scale(1.1); + filter: brightness(1.2); +} + +.github-link img { + height: 40px; + padding-right: 40px; + padding-top: 10px; + padding-bottom: 10px; + transition: transform 0.3s ease, filter 0.3s ease; +} + +.github-link img:hover { + transform: scale(1.1); + filter: brightness(1.2); +} + +nav { + width: 250px; + background-color: rgba(0, 0, 0, 0.4); + padding: 10px 20px; + border-radius: 8px; + margin-right: 20px; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3); + position: sticky; + top: 100px; + height: fit-content; + max-height: calc(100vh - 40px); + overflow-y: auto; +} + +nav h2 { + font-size: 18px; + margin-bottom: 10px; + color: #ffffff; + text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5); +} + +nav ul { + list-style: none; + padding: 0; + margin: 0; +} + +nav ul li { + margin: 2.5px 0; +} + +nav ul li a { + color: #ddd; + text-decoration: none; + font-size: 16px; + padding: 6px 10px; + display: block; + border-radius: 6px; + transition: background-color 0.3s ease, color 0.3s ease; +} + +nav ul li a:hover { + background-color: #444; + color: #ffffff; +} + +.container { + display: flex; + padding: 20px; + padding-bottom: 200px; +} + +.content { + flex-grow: 1; + margin-left: 20px; +} + +.search-bar { + position: relative; + margin-bottom: 20px; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3); + border-radius: 8px; + overflow: hidden; +} + +.search-bar input { + width: 100%; + padding: 12px; + padding-left: 40px; + font-size: 16px; + border: none; + background-color: rgba(0, 0, 0, 0.4); + color: #ddd; + outline: none; + transition: background-color 0.3s ease; +} + +.search-bar input:focus { + background-color: rgba(0, 0, 0, 0.3); + box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4); + color: #fff; +} + +.search-icon { + position: absolute; + left: 10px; + top: 50%; + transform: translateY(-50%); + width: 20px; + height: 20px; + background-image: url('images/content/search-bar/search-icon.png'); + background-size: cover; + pointer-events: none; + opacity: 0.5; + transition: opacity 0.3s ease; +} + +.search-bar input:focus + .search-icon { + opacity: 1; +} + +.grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); + gap: 18px; +} + +.card { + background-color: rgba(255, 255, 255, 0.15); + padding: 15px; + border-radius: 10px; + text-align: center; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); + transition: transform 0.3s, box-shadow 0.3s; + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + position: relative; + overflow: hidden; + height: 100%; + box-sizing: border-box; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.card:hover { + transform: scale(1.05); + box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4); +} + +.card img { + width: 100%; + height: auto; + border-radius: 8px; + margin-bottom: 10px; +} + +.card h3 { + margin: 10px 0; + font-size: 18px; +} + +.card p { + font-size: 14px; + color: #bbb; + margin-bottom: auto; +} + +.buttons-container { + display: flex; + flex-direction: column; + gap: 10px; + width: 100%; + box-sizing: border-box; + padding-top: 15px; +} + +.github-button, .view-link { + display: inline-block; + padding: 8px 12px; + border-radius: 5px; + background-color: #2c3e50; + color: #ecf0f1; + text-decoration: none; + font-size: 14px; + transition: background-color 0.3s ease; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); + width: 100%; + box-sizing: border-box; + text-align: center; +} + +.github-button:hover, .view-link:hover { + background-color: #1abc9c; + color: #ffffff; + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3); +} + +#known-issues { + margin-top: 40px; + padding: 30px; + background-color: rgba(0, 0, 0, 0.4); + border-radius: 8px; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3); +} + +#known-issues h2 { + margin-bottom: 15px; + color: #ffffff; + text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5); +} + +#known-issues ul { + list-style-type: disc; + padding-left: 35px; + color: #ddd; +} + +#known-issues ul li { + margin-bottom: 10px; +} + +@media (max-width: 768px) { + .container { + flex-direction: column; + } + + nav { + width: 100%; + margin-right: 0; + margin-bottom: 20px; + } + + .grid { + grid-template-columns: 1fr; + } +}