Skip to content

Commit

Permalink
github webassembly sample
Browse files Browse the repository at this point in the history
Summary:
Mostly copy-pasted Timy_Mesh with WebGL reality adjustments
{F1045130706}

Reviewed By: corporateshark

Differential Revision: D47313028

fbshipit-source-id: a19d1fda1588b1065af36478e4eebc0fa18acffd
  • Loading branch information
rudybear authored and facebook-github-bot committed Jul 10, 2023
1 parent 635da20 commit 91a4e0e
Show file tree
Hide file tree
Showing 6 changed files with 676 additions and 44 deletions.
90 changes: 53 additions & 37 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ option(IGL_WITH_OPENGL "Enable IGL/OpenGL" ON)
option(IGL_WITH_OPENGLES "Enable IGL/OpenGL ES" OFF)
option(IGL_WITH_VULKAN "Enable IGL/Vulkan" ON)
option(IGL_WITH_METAL "Enable IGL/Metal" ON)
option(IGL_WITH_WEBGL "Enable IGL/WebGL" OFF)

option(IGL_WITH_IGLU "Enable IGLU utils" ON)
option(IGL_WITH_SHELL "Enable Shell utils" ON)
Expand All @@ -37,6 +38,7 @@ if(IOS)
endif()
set(IGL_WITH_OPENGL OFF)
set(IGL_WITH_VULKAN OFF)
set(IGL_WITH_WEBGL OFF)
endif()

if(NOT APPLE)
Expand All @@ -49,9 +51,18 @@ if(ANDROID)
endif()
set(IGL_WITH_OPENGL OFF)
set(IGL_WITH_VULKAN ON)
set(IGL_WITH_WEBGL OFF)
endif()

if(UNIX AND NOT APPLE AND NOT ANDROID)
if(EMSCRIPTEN)
set(IGL_WITH_OPENGL OFF)
set(IGL_WITH_OPENGLES OFF)
set(IGL_WITH_VULKAN OFF)
set(IGL_WITH_WEBGL ON)
set(IGL_WITH_SHELL OFF) # shell doesn't supported yet
endif()

if(UNIX AND NOT APPLE AND NOT ANDROID AND NOT EMSCRIPTEN)
if(IGL_WITH_SAMPLES OR IGL_WITH_SHELL)
add_definitions("-DIGL_PLATFORM_LINUX_USE_EGL=0")
else()
Expand All @@ -70,6 +81,7 @@ message(STATUS "IGL_WITH_OPENGL = ${IGL_WITH_OPENGL}")
message(STATUS "IGL_WITH_OPENGLES = ${IGL_WITH_OPENGLES}")
message(STATUS "IGL_WITH_VULKAN = ${IGL_WITH_VULKAN}")
message(STATUS "IGL_WITH_METAL = ${IGL_WITH_METAL}")
message(STATUS "IGL_WITH_WEBGL = ${IGL_WITH_WEBGL}")

message(STATUS "IGL_WITH_IGLU = ${IGL_WITH_IGLU}")
message(STATUS "IGL_WITH_SHELL = ${IGL_WITH_SHELL}")
Expand All @@ -85,11 +97,11 @@ if(IGL_ENFORCE_LOGS)
endif()

if(APPLE)
if(NOT (IGL_WITH_OPENGL OR IGL_WITH_VULKAN OR IGL_WITH_OPENGLES OR IGL_WITH_METAL))
if(NOT (IGL_WITH_OPENGL OR IGL_WITH_VULKAN OR IGL_WITH_OPENGLES OR IGL_WITH_METAL OR IGL_WITH_WEBGL))
message(FATAL_ERROR "At least one rendering backend should be defined (OpenGL, Vulkan or Metal).")
endif()
else()
if(NOT (IGL_WITH_OPENGL OR IGL_WITH_VULKAN OR IGL_WITH_OPENGLES))
if(NOT (IGL_WITH_OPENGL OR IGL_WITH_VULKAN OR IGL_WITH_OPENGLES OR IGL_WITH_WEBGL))
message(FATAL_ERROR "At least one rendering backend should be defined (OpenGL or Vulkan).")
endif()
endif()
Expand All @@ -106,7 +118,7 @@ endif()
if(IGL_WITH_OPENGL)
add_definitions("-DIGL_BACKEND_ENABLE_OPENGL=1")
endif()
if(IGL_WITH_OPENGLES)
if(IGL_WITH_OPENGLES OR IGL_WITH_WEBGL)
add_definitions("-DIGL_BACKEND_ENABLE_OPENGL=1")
endif()
if(IGL_WITH_VULKAN)
Expand Down Expand Up @@ -179,39 +191,43 @@ if(IGL_WITH_IGLU)
endif()

if(IGL_WITH_SAMPLES)
include_directories("third-party/deps/src")
include_directories("third-party/deps/src/bc7enc")
include_directories("third-party/deps/src/gli")
include_directories("third-party/deps/src/glm")
include_directories("third-party/deps/src/stb")
include_directories("third-party/deps/src/taskflow")
include_directories("third-party/deps/src/3D-Graphics-Rendering-Cookbook")
if(WIN32 OR (UNIX AND NOT APPLE AND NOT ANDROID))
# cmake-format: off
set(GLFW_BUILD_DOCS OFF CACHE BOOL "")
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "")
set(GLFW_BUILD_TESTS OFF CACHE BOOL "")
set(GLFW_INSTALL OFF CACHE BOOL "")
set(GLFW_VULKAN_STATIC OFF CACHE BOOL "")
# cmake-format: on
add_subdirectory(third-party/deps/src/glfw)
igl_set_folder(update_mappings "third-party/GLFW3")
endif()
if(UNIX AND NOT APPLE AND NOT ANDROID)
find_package(OpenGL REQUIRED)
endif()
add_subdirectory(third-party/deps/src/bc7enc)
igl_set_cxxstd(bc7enc 17)
add_subdirectory(third-party/deps/src/meshoptimizer)
add_subdirectory(third-party/deps/src/tinyobjloader)
igl_set_folder(bc7enc "third-party")
igl_set_folder(meshoptimizer "third-party")
igl_set_folder(tinyobjloader "third-party/tinyobjloader")
igl_set_folder(uninstall "third-party/tinyobjloader")
if(NOT APPLE AND NOT ANDROID)
add_subdirectory(samples/desktop)
igl_set_folder(glfw "third-party/GLFW3")
endif()
if (EMSCRIPTEN)
add_subdirectory(samples/wasm)
else()
include_directories("third-party/deps/src")
include_directories("third-party/deps/src/bc7enc")
include_directories("third-party/deps/src/gli")
include_directories("third-party/deps/src/glm")
include_directories("third-party/deps/src/stb")
include_directories("third-party/deps/src/taskflow")
include_directories("third-party/deps/src/3D-Graphics-Rendering-Cookbook")
if(WIN32 OR (UNIX AND NOT APPLE AND NOT ANDROID))
# cmake-format: off
set(GLFW_BUILD_DOCS OFF CACHE BOOL "")
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "")
set(GLFW_BUILD_TESTS OFF CACHE BOOL "")
set(GLFW_INSTALL OFF CACHE BOOL "")
set(GLFW_VULKAN_STATIC OFF CACHE BOOL "")
# cmake-format: on
add_subdirectory(third-party/deps/src/glfw)
igl_set_folder(update_mappings "third-party/GLFW3")
endif()
if(UNIX AND NOT APPLE AND NOT ANDROID)
find_package(OpenGL REQUIRED)
endif()
add_subdirectory(third-party/deps/src/bc7enc)
igl_set_cxxstd(bc7enc 17)
add_subdirectory(third-party/deps/src/meshoptimizer)
add_subdirectory(third-party/deps/src/tinyobjloader)
igl_set_folder(bc7enc "third-party")
igl_set_folder(meshoptimizer "third-party")
igl_set_folder(tinyobjloader "third-party/tinyobjloader")
igl_set_folder(uninstall "third-party/tinyobjloader")
if(NOT APPLE AND NOT ANDROID)
add_subdirectory(samples/desktop)
igl_set_folder(glfw "third-party/GLFW3")
endif()
endif()
endif()

if(IGL_WITH_TRACY)
Expand Down
25 changes: 25 additions & 0 deletions samples/wasm/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

cmake_minimum_required(VERSION 3.16)

set(PROJECT_NAME "IGL Samples")

macro(ADD_DEMO app shellHTML)
add_executable(${app} "${app}.cpp")
set(CMAKE_EXECUTABLE_SUFFIX ".html")
igl_set_cxxstd(${app} 17)
igl_set_folder(${app} ${PROJECT_NAME})
target_link_libraries(${app} PUBLIC IGLLibrary)
set_target_properties(
${app}
PROPERTIES
LINK_FLAGS
"-s USE_WEBGL2=1 -s GL_SUPPORT_AUTOMATIC_ENABLE_EXTENSIONS=1 -s GL_EMULATE_GLES_VERSION_STRING_FORMAT=1 -s ALLOW_MEMORY_GROWTH=1 -s SINGLE_FILE=1 -s LLD_REPORT_UNDEFINED --shell-file ${shellHTML}"
)

endmacro()

add_demo("tiny" "../samples/wasm/igl.html")
145 changes: 145 additions & 0 deletions samples/wasm/igl.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
<!doctype html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Emscripten-Generated Code</title>
<style>
.emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
textarea.emscripten { font-family: monospace; width: 80%; }
div.emscripten { text-align: center; }
div.emscripten_border { border: 1px solid black; }
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
canvas.emscripten { border: 0px none; background-color: black; }

.spinner {
height: 50px;
width: 50px;
margin: 0px auto;
-webkit-animation: rotation .8s linear infinite;
-moz-animation: rotation .8s linear infinite;
-o-animation: rotation .8s linear infinite;
animation: rotation 0.8s linear infinite;
border-left: 10px solid rgb(0,150,240);
border-right: 10px solid rgb(0,150,240);
border-bottom: 10px solid rgb(0,150,240);
border-top: 10px solid rgb(100,0,200);
border-radius: 100%;
background-color: rgb(200,100,250);
}
@-webkit-keyframes rotation {
from {-webkit-transform: rotate(0deg);}
to {-webkit-transform: rotate(360deg);}
}
@-moz-keyframes rotation {
from {-moz-transform: rotate(0deg);}
to {-moz-transform: rotate(360deg);}
}
@-o-keyframes rotation {
from {-o-transform: rotate(0deg);}
to {-o-transform: rotate(360deg);}
}
@keyframes rotation {
from {transform: rotate(0deg);}
to {transform: rotate(360deg);}
}

</style>
</head>
<body>
<hr/>
<figure style="overflow:visible;" id="spinner"><div class="spinner"></div><center style="margin-top:0.5em"><strong>emscripten</strong></center></figure>
<div class="emscripten" id="status">Downloading...</div>
<div class="emscripten">
<progress value="0" max="100" id="progress" hidden=1></progress>
</div>
<div class="emscripten_border">
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()" tabindex=-1></canvas>
</div>
<hr/>
<div class="emscripten">
<input type="checkbox" id="resize">Resize canvas
<input type="checkbox" id="pointerLock" checked>Lock/hide mouse pointer
&nbsp;&nbsp;&nbsp;
<input type="button" value="Fullscreen" onclick="Module.requestFullscreen(document.getElementById('pointerLock').checked,
document.getElementById('resize').checked)">
</div>

<hr/>
<textarea class="emscripten" id="output" rows="8"></textarea>
<hr>
<script type='text/javascript'>
var statusElement = document.getElementById('status');
var progressElement = document.getElementById('progress');
var spinnerElement = document.getElementById('spinner');

var Module = {
preRun: [],
postRun: [],
print: (function() {
var element = document.getElementById('output');
if (element) element.value = ''; // clear browser cache
return function(text) {
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
// These replacements are necessary if you render to raw HTML
//text = text.replace(/&/g, "&amp;");
//text = text.replace(/</g, "&lt;");
//text = text.replace(/>/g, "&gt;");
//text = text.replace('\n', '<br>', 'g');
console.log(text);
if (element) {
element.value += text + "\n";
element.scrollTop = element.scrollHeight; // focus on bottom
}
};
})(),
canvas: (() => {
var canvas = document.getElementById('canvas');

// As a default initial behavior, pop up an alert when webgl context is lost. To make your
// application robust, you may want to override this behavior before shipping!
// See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
canvas.addEventListener("webglcontextlost", (e) => { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);

return canvas;
})(),
setStatus: (text) => {
if (!Module.setStatus.last) Module.setStatus.last = { time: Date.now(), text: '' };
if (text === Module.setStatus.last.text) return;
var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
var now = Date.now();
if (m && now - Module.setStatus.last.time < 30) return; // if this is a progress update, skip it if too soon
Module.setStatus.last.time = now;
Module.setStatus.last.text = text;
if (m) {
text = m[1];
progressElement.value = parseInt(m[2])*100;
progressElement.max = parseInt(m[4])*100;
progressElement.hidden = false;
spinnerElement.hidden = false;
} else {
progressElement.value = null;
progressElement.max = null;
progressElement.hidden = true;
if (!text) spinnerElement.hidden = true;
}
statusElement.innerHTML = text;
},
totalDependencies: 0,
monitorRunDependencies: (left) => {
this.totalDependencies = Math.max(this.totalDependencies, left);
Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
}
};
Module.setStatus('Downloading...');
window.onerror = () => {
Module.setStatus('Exception thrown, see JavaScript console');
spinnerElement.style.display = 'none';
Module.setStatus = (text) => {
if (text) console.error('[post-exception status] ' + text);
};
};
</script>
{{{ SCRIPT }}}
</body>
</html>
Loading

0 comments on commit 91a4e0e

Please sign in to comment.