mirror of
https://github.com/libsdl-org/SDL.git
synced 2024-11-23 10:53:27 +08:00
examples: Added initial examples infrastructure.
This commit is contained in:
parent
2f6e34d2d0
commit
5339b4458d
183
build-scripts/build-web-examples.pl
Executable file
183
build-scripts/build-web-examples.pl
Executable file
@ -0,0 +1,183 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
# Simple DirectMedia Layer
|
||||
# Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
#
|
||||
# This software is provided 'as-is', without any express or implied
|
||||
# warranty. In no event will the authors be held liable for any damages
|
||||
# arising from the use of this software.
|
||||
#
|
||||
# Permission is granted to anyone to use this software for any purpose,
|
||||
# including commercial applications, and to alter it and redistribute it
|
||||
# freely, subject to the following restrictions:
|
||||
#
|
||||
# 1. The origin of this software must not be misrepresented; you must not
|
||||
# claim that you wrote the original software. If you use this software
|
||||
# in a product, an acknowledgment in the product documentation would be
|
||||
# appreciated but is not required.
|
||||
# 2. Altered source versions must be plainly marked as such, and must not be
|
||||
# misrepresented as being the original software.
|
||||
# 3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
use File::Basename;
|
||||
use Cwd qw(abs_path);
|
||||
use IPC::Open2;
|
||||
|
||||
my $examples_dir = abs_path(dirname(__FILE__) . "/../examples");
|
||||
my $project = undef;
|
||||
my $emsdk_dir = undef;
|
||||
my $compile_dir = undef;
|
||||
my $output_dir = undef;
|
||||
|
||||
sub usage {
|
||||
die("USAGE: $0 <project_name> <emsdk_dir> <compiler_output_directory> <html_output_directory>\n\n");
|
||||
}
|
||||
|
||||
sub do_system {
|
||||
my $cmd = shift;
|
||||
$cmd = "exec /usr/bin/bash -c \"$cmd\"";
|
||||
print("$cmd\n");
|
||||
return system($cmd);
|
||||
}
|
||||
|
||||
sub do_mkdir {
|
||||
my $d = shift;
|
||||
if ( ! -d $d ) {
|
||||
print("mkdir '$d'\n");
|
||||
mkdir($d) or die("Couldn't mkdir('$d'): $!\n");
|
||||
}
|
||||
}
|
||||
|
||||
sub build_latest {
|
||||
# Try to build just the latest without re-running cmake, since that is SLOW.
|
||||
print("Building latest version of $project ...\n");
|
||||
if (do_system("EMSDK_QUIET=1 source '$emsdk_dir/emsdk_env.sh' && cd '$compile_dir' && ninja") != 0) {
|
||||
# Build failed? Try nuking the build dir and running CMake from scratch.
|
||||
print("\n\nBuilding latest version of $project FROM SCRATCH ...\n");
|
||||
if (do_system("EMSDK_QUIET=1 source '$emsdk_dir/emsdk_env.sh' && rm -rf '$compile_dir' && mkdir '$compile_dir' && cd '$compile_dir' && emcmake cmake -G Ninja -DCMAKE_BUILD_TYPE=MinSizeRel .. && ninja") != 0) {
|
||||
die("Failed to build latest version of $project!\n"); # oh well.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub handle_example_dir {
|
||||
my $category = shift;
|
||||
my $example = shift;
|
||||
|
||||
my @files = ();
|
||||
my $files_str = '';
|
||||
opendir(my $dh, "$examples_dir/$category/$example") or die("Couldn't opendir '$examples_dir/$category/$example': $!\n");
|
||||
my $spc = '';
|
||||
while (readdir($dh)) {
|
||||
next if not /\.c\Z/; # only care about .c files.
|
||||
my $path = "$examples_dir/$category/$example/$_";
|
||||
next if not -f $path; # only care about files.
|
||||
push @files, $path;
|
||||
$files_str .= "$spc$path";
|
||||
$spc = ' ';
|
||||
}
|
||||
closedir($dh);
|
||||
|
||||
my $dst = "$output_dir/$category/$example";
|
||||
|
||||
do_mkdir($dst);
|
||||
print("Building $category/$example ...\n");
|
||||
|
||||
# !!! FIXME: hardcoded SDL3 references, need to fix this for satellite libraries and SDL2.
|
||||
do_system("EMSDK_QUIET=1 source '$emsdk_dir/emsdk_env.sh' && emcc -s USE_SDL=0 -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s MAXIMUM_MEMORY=1gb -s ASSERTIONS=0 -o '$dst/index.js' '-I$examples_dir/../include' $files_str '$compile_dir/libSDL3.a'") == 0
|
||||
or die("Failed to build $category/$example!\n");
|
||||
|
||||
my $highlight_cmd = "highlight '--outdir=$dst' --style-outfile=highlight.css --fragment --stdout --syntax=c '--plug-in=$examples_dir/highlight-plugin.lua'";
|
||||
print("$highlight_cmd\n");
|
||||
my $pid = open2(my $child_out, my $child_in, $highlight_cmd);
|
||||
|
||||
my $htmlified_source_code = '';
|
||||
foreach (@files) {
|
||||
my $path = $_;
|
||||
open my $srccode, '<', $path or die("Couldn't open '$path': $!\n");
|
||||
my $fname = "$path";
|
||||
$fname =~ s/\A.*\///;
|
||||
print $child_in "/* $fname ... */\n\n";
|
||||
while (<$srccode>) {
|
||||
print $child_in $_;
|
||||
}
|
||||
close($srccode);
|
||||
}
|
||||
|
||||
close($child_in);
|
||||
|
||||
while (<$child_out>) {
|
||||
$htmlified_source_code .= $_;
|
||||
}
|
||||
close($child_out);
|
||||
|
||||
waitpid($pid, 0);
|
||||
|
||||
|
||||
my $html = '';
|
||||
open my $htmltemplate, '<', "$examples_dir/template.html" or die("Couldn't open '$examples_dir/template.html': $!\n");
|
||||
while (<$htmltemplate>) {
|
||||
s/\@project_name\@/$project/g;
|
||||
s/\@category_name\@/$category/g;
|
||||
s/\@example_name\@/$example/g;
|
||||
s/\@htmlified_source_code\@/$htmlified_source_code/g;
|
||||
$html .= $_;
|
||||
}
|
||||
close($htmltemplate);
|
||||
|
||||
open my $htmloutput, '>', "$dst/index.html" or die("Couldn't open '$dst/index.html': $!\n");
|
||||
print $htmloutput $html;
|
||||
close($htmloutput);
|
||||
|
||||
|
||||
}
|
||||
|
||||
sub handle_category_dir {
|
||||
my $category = shift;
|
||||
|
||||
do_mkdir("$output_dir/$category");
|
||||
|
||||
opendir(my $dh, "$examples_dir/$category") or die("Couldn't opendir '$examples_dir/$category': $!\n");
|
||||
|
||||
while (readdir($dh)) {
|
||||
next if ($_ eq '.') || ($_ eq '..'); # obviously skip current and parent entries.
|
||||
next if not -d "$examples_dir/$category/$_"; # only care about subdirectories.
|
||||
handle_example_dir($category, $_);
|
||||
}
|
||||
|
||||
closedir($dh);
|
||||
}
|
||||
|
||||
|
||||
# Mainline!
|
||||
|
||||
foreach (@ARGV) {
|
||||
$project = $_, next if not defined $project;
|
||||
$emsdk_dir = $_, next if not defined $emsdk_dir;
|
||||
$compile_dir = $_, next if not defined $compile_dir;
|
||||
$output_dir = $_, next if not defined $output_dir;
|
||||
usage(); # too many arguments.
|
||||
}
|
||||
|
||||
usage() if not defined $output_dir;
|
||||
|
||||
build_latest();
|
||||
|
||||
do_mkdir($output_dir);
|
||||
|
||||
print("Examples dir: $examples_dir\n");
|
||||
|
||||
opendir(my $dh, $examples_dir) or die("Couldn't opendir '$examples_dir': $!\n");
|
||||
|
||||
while (readdir($dh)) {
|
||||
next if ($_ eq '.') || ($_ eq '..'); # obviously skip current and parent entries.
|
||||
next if not -d "$examples_dir/$_"; # only care about subdirectories.
|
||||
handle_category_dir($_);
|
||||
}
|
||||
|
||||
closedir($dh);
|
||||
|
||||
exit(0); # success!
|
||||
|
67
examples/README.md
Normal file
67
examples/README.md
Normal file
@ -0,0 +1,67 @@
|
||||
# Examples
|
||||
|
||||
## What is this?
|
||||
|
||||
In here are a collection of standalone SDL application examples. Unless
|
||||
otherwise stated, they should work on all supported platforms out of the box.
|
||||
If they don't [please file a bug to let us know](https://github.com/libsdl-org/SDL/issues/new).
|
||||
|
||||
|
||||
## What is this SDL_AppIterate thing?
|
||||
|
||||
SDL can optionally build apps as a collection of callbacks instead of the
|
||||
usual program structure that starts and ends in a function called `main`.
|
||||
The examples use this format for two reasons.
|
||||
|
||||
First, it allows the examples to work when built as web applications without
|
||||
a pile of ugly `#ifdef`s, and all of these examples are published on the web
|
||||
at [examples.libsdl.org](https://examples.libsdl.org/), so you can easily see
|
||||
them in action.
|
||||
|
||||
Second, it's example code! The callbacks let us cleanly break the program up
|
||||
into the four logical pieces most apps care about:
|
||||
|
||||
- Program startup
|
||||
- Event handling
|
||||
- What the program actually does in a single frame
|
||||
- Program shutdown
|
||||
|
||||
A detailed technical explanation of these callbacks is in
|
||||
docs/README-main-functions.md (or view that page on the web on
|
||||
[the wiki](https://wiki.libsdl.org/SDL3/README/main-functions#main-callbacks-in-sdl3).
|
||||
|
||||
|
||||
## I would like to build and run these examples myself.
|
||||
|
||||
When you build SDL with CMake, you can add `-DSDL_BUILD_EXAMPLES=On` to the
|
||||
CMake command line. When you build SDL, these examples will be built with it.
|
||||
|
||||
But most of these can just be built as a single .c file, as long as you point
|
||||
your compiler at SDL3's headers and link against SDL.
|
||||
|
||||
|
||||
## What is the license on the example code? Can I paste this into my project?
|
||||
|
||||
All code in the examples directory is considered public domain! You can do
|
||||
anything you like with it, including copy/paste it into your closed-source
|
||||
project, sell it, and pretend you wrote it yourself. We do not require you to
|
||||
give us credit for this code (but we always appreciate if you do!).
|
||||
|
||||
This is only true for the examples directory. The rest of SDL falls under the
|
||||
[zlib license](https://github.com/libsdl-org/SDL/blob/main/LICENSE.txt).
|
||||
|
||||
|
||||
## What is template.html and highlight-plugin.lua in this directory?
|
||||
|
||||
This is what [examples.libsdl.org](https://examples.libsdl.org/) uses when
|
||||
generating the web versions of these example programs. You can ignore this,
|
||||
unless you are improving it, in which case we definitely would love to hear
|
||||
from you!
|
||||
|
||||
|
||||
## What is template.c in this directory?
|
||||
|
||||
If writing new examples, this is the skeleton code we start from, to keep
|
||||
everything consistent. You can ignore it.
|
||||
|
||||
|
77
examples/highlight-plugin.lua
Normal file
77
examples/highlight-plugin.lua
Normal file
@ -0,0 +1,77 @@
|
||||
-- This code adapted from https://gitlab.com/saalen/highlight/-/wikis/Plug-Ins
|
||||
|
||||
-- first add a description of what the plug-in does
|
||||
Description="Add wiki.libsdl.org reference links to HTML, LaTeX or RTF output"
|
||||
|
||||
-- define the plugin categories (ie. supported output formats; languages)
|
||||
Categories = { "c", "c++" }
|
||||
|
||||
-- the syntaxUpdate function contains code related to syntax recognition
|
||||
function syntaxUpdate(desc)
|
||||
|
||||
-- if the current file is not C/C++ file we exit
|
||||
if desc~="C and C++" then
|
||||
return
|
||||
end
|
||||
|
||||
-- this function returns a qt-project reference link of the given token
|
||||
function getURL(token)
|
||||
-- generate the URL
|
||||
url='https://wiki.libsdl.org/SDL3/'.. token
|
||||
|
||||
-- embed the URL in a hyperlink according to the output format
|
||||
-- first HTML, then LaTeX and RTF
|
||||
if (HL_OUTPUT== HL_FORMAT_HTML or HL_OUTPUT == HL_FORMAT_XHTML) then
|
||||
return '<a class="hl" target="new" href="'
|
||||
.. url .. '">'.. token .. '</a>'
|
||||
elseif (HL_OUTPUT == HL_FORMAT_LATEX) then
|
||||
return '\\href{'..url..'}{'..token..'}'
|
||||
elseif (HL_OUTPUT == HL_FORMAT_RTF) then
|
||||
return '{{\\field{\\*\\fldinst HYPERLINK "'
|
||||
..url..'" }{\\fldrslt\\ul\\ulc0 '..token..'}}}'
|
||||
end
|
||||
end
|
||||
|
||||
-- the Decorate function will be invoked for every recognized token
|
||||
function Decorate(token, state)
|
||||
|
||||
-- we are only interested in keywords, preprocessor or default items
|
||||
if (state ~= HL_STANDARD and state ~= HL_KEYWORD and
|
||||
state ~=HL_PREPROC) then
|
||||
return
|
||||
end
|
||||
|
||||
-- SDL keywords start with SDL_
|
||||
-- if this pattern applies to the token, we return the URL
|
||||
-- if we return nothing, the token is outputted as is
|
||||
if string.find(token, "SDL_")==1 then
|
||||
return getURL(token)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
-- the themeUpdate function contains code related to the theme
|
||||
function themeUpdate(desc)
|
||||
-- the Injections table can be used to add style information to the theme
|
||||
|
||||
-- HTML: we add additional CSS style information to beautify hyperlinks,
|
||||
-- they should have the same color as their surrounding tags
|
||||
if (HL_OUTPUT == HL_FORMAT_HTML or HL_OUTPUT == HL_FORMAT_XHTML) then
|
||||
Injections[#Injections+1]=
|
||||
"a.hl, a.hl:visited {color:inherit;font-weight:inherit;text-decoration:none}"
|
||||
|
||||
-- LaTeX: hyperlinks require the hyperref package, so we add this here
|
||||
-- the colorlinks and pdfborderstyle options remove ugly boxes in the output
|
||||
elseif (HL_OUTPUT==HL_FORMAT_LATEX) then
|
||||
Injections[#Injections+1]=
|
||||
"\\usepackage[colorlinks=false, pdfborderstyle={/S/U/W 1}]{hyperref}"
|
||||
end
|
||||
end
|
||||
|
||||
-- let highlight load the chunks
|
||||
Plugins={
|
||||
{ Type="lang", Chunk=syntaxUpdate },
|
||||
{ Type="theme", Chunk=themeUpdate },
|
||||
}
|
||||
|
80
examples/renderer/clear/renderer-clear.c
Normal file
80
examples/renderer/clear/renderer-clear.c
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* This example code creates an SDL window and renderer, and then clears the
|
||||
* window to a different color every frame, so you'll effectively get a window
|
||||
* that's smoothly fading between colors.
|
||||
*
|
||||
* This code is public domain. Feel free to use it for any purpose!
|
||||
*/
|
||||
|
||||
#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_main.h>
|
||||
|
||||
|
||||
/* We will use this renderer to draw into this window every frame. */
|
||||
static SDL_Window *window = NULL;
|
||||
static SDL_Renderer *renderer = NULL;
|
||||
|
||||
/* the current red color we're clearing to. */
|
||||
static Uint8 red = 0;
|
||||
|
||||
/* When fading up, this is 1, when fading down, it's -1. */
|
||||
static int fade_direction = 1;
|
||||
|
||||
|
||||
/* This function runs once at startup. */
|
||||
int SDL_AppInit(void **appstate, int argc, char *argv[])
|
||||
{
|
||||
if (SDL_CreateWindowAndRenderer("examples/renderer/clear", 640, 480, 0, &window, &renderer) == -1) {
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't create window/renderer!", SDL_GetError(), NULL);
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
SDL_SetRenderVSync(renderer, 1); /* try to show frames at the monitor refresh rate. */
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
|
||||
int SDL_AppEvent(void *appstate, const SDL_Event *event)
|
||||
{
|
||||
if (event->type == SDL_EVENT_QUIT) {
|
||||
return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
|
||||
}
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once per frame, and is the heart of the program. */
|
||||
int SDL_AppIterate(void *appstate)
|
||||
{
|
||||
/* since we're always fading red, we leave green and blue at zero.
|
||||
alpha doesn't mean much here, so leave it at full (255, no transparency). */
|
||||
SDL_SetRenderDrawColor(renderer, red, 0, 0, 255);
|
||||
|
||||
/* clear the window to the draw color. */
|
||||
SDL_RenderClear(renderer);
|
||||
|
||||
/* put the newly-cleared rendering on the screen. */
|
||||
SDL_RenderPresent(renderer);
|
||||
|
||||
/* update the color for the next frame we will draw. */
|
||||
if (fade_direction > 0) {
|
||||
if (red == 255) {
|
||||
fade_direction = -1;
|
||||
} else {
|
||||
red++;
|
||||
}
|
||||
} else if (fade_direction < 0) {
|
||||
if (red == 0) {
|
||||
fade_direction = 1;
|
||||
} else {
|
||||
red--;
|
||||
}
|
||||
}
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once at shutdown. */
|
||||
void SDL_AppQuit(void *appstate)
|
||||
{
|
||||
/* SDL will clean up the window/renderer for us. */
|
||||
}
|
||||
|
45
examples/template.c
Normal file
45
examples/template.c
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* This example code $WHAT_IT_DOES.
|
||||
*
|
||||
* This code is public domain. Feel free to use it for any purpose!
|
||||
*/
|
||||
|
||||
#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_main.h>
|
||||
|
||||
/* We will use this renderer to draw into this window every frame. */
|
||||
static SDL_Window *window = NULL;
|
||||
static SDL_Renderer *renderer = NULL;
|
||||
|
||||
|
||||
/* This function runs once at startup. */
|
||||
int SDL_AppInit(void **appstate, int argc, char *argv[])
|
||||
{
|
||||
if (SDL_CreateWindowAndRenderer("examples/renderer/clear", 640, 480, 0, &window, &renderer) == -1) {
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't create window/renderer!", SDL_GetError(), NULL);
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
|
||||
int SDL_AppEvent(void *appstate, const SDL_Event *event)
|
||||
{
|
||||
if (event->type == SDL_EVENT_QUIT) {
|
||||
return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
|
||||
}
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once per frame, and is the heart of the program. */
|
||||
int SDL_AppIterate(void *appstate)
|
||||
{
|
||||
}
|
||||
|
||||
/* This function runs once at shutdown. */
|
||||
void SDL_AppQuit(void *appstate)
|
||||
{
|
||||
/* SDL will clean up the window/renderer for us. */
|
||||
}
|
||||
|
117
examples/template.html
Normal file
117
examples/template.html
Normal file
@ -0,0 +1,117 @@
|
||||
<!doctype html>
|
||||
<html lang="en-us">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>@project_name@ Example: @category_name@/@example_name@</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: arial;
|
||||
margin: 0;
|
||||
padding: none;
|
||||
}
|
||||
|
||||
.emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
|
||||
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; }
|
||||
|
||||
@-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);}
|
||||
}
|
||||
|
||||
#output {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
margin: 0 auto;
|
||||
margin-top: 10px;
|
||||
border-left: 0px;
|
||||
border-right: 0px;
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
display: none;
|
||||
background-color: black;
|
||||
color: white;
|
||||
font-family: 'Lucida Console', Monaco, monospace;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.source_code {
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" type="text/css" href="highlight.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="emscripten_border">
|
||||
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()" tabindex=-1></canvas>
|
||||
</div>
|
||||
<textarea id="output" rows="8"></textarea>
|
||||
|
||||
<div class="source_code">@htmlified_source_code@</div>
|
||||
|
||||
<script type='text/javascript'>
|
||||
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, "&");
|
||||
//text = text.replace(/</g, "<");
|
||||
//text = text.replace(/>/g, ">");
|
||||
//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) => {},
|
||||
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 = (event) => {
|
||||
// TODO: do not warn on ok events like simulating an infinite loop or exitStatus
|
||||
Module.setStatus('Exception thrown, see JavaScript console');
|
||||
Module.setStatus = (text) => {
|
||||
if (text) console.error('[post-exception status] ' + text);
|
||||
};
|
||||
};
|
||||
</script>
|
||||
<script async type="text/javascript" src="index.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user