WASM compile
This commit is contained in:
parent
35afe7722f
commit
3e94734887
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,3 +1,5 @@
|
|||||||
build/
|
build/
|
||||||
|
build-wasm/
|
||||||
out/
|
out/
|
||||||
|
.vs/
|
||||||
|
.vscode/
|
||||||
|
|||||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -2,3 +2,6 @@
|
|||||||
path = external/SDL
|
path = external/SDL
|
||||||
url = https://github.com/libsdl-org/SDL.git
|
url = https://github.com/libsdl-org/SDL.git
|
||||||
branch = release-2.32.x
|
branch = release-2.32.x
|
||||||
|
[submodule "external/glm"]
|
||||||
|
path = external/glm
|
||||||
|
url = https://github.com/g-truc/glm.git
|
||||||
|
|||||||
@ -6,19 +6,34 @@ set(CMAKE_CXX_STANDARD 17)
|
|||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
# Add src directory
|
# Add src directory
|
||||||
add_executable(PortalGame src/main.cpp)
|
add_executable(PortalGame
|
||||||
|
"src/main.cpp"
|
||||||
|
"src/app.hpp"
|
||||||
|
"src/app.cpp"
|
||||||
|
"src/gl.hpp"
|
||||||
|
)
|
||||||
|
|
||||||
# Platform-specific SDL2 handling
|
# Platform-specific SDL2 handling
|
||||||
if(EMSCRIPTEN)
|
if (CMAKE_SYSTEM_NAME STREQUAL Emscripten)
|
||||||
|
|
||||||
# Emscripten provides SDL2 via its system libraries
|
# Emscripten provides SDL2 via its system libraries
|
||||||
message(STATUS "Target platform: WebAssembly (Emscripten)")
|
message(STATUS "Target platform: WebAssembly (Emscripten)")
|
||||||
set(CMAKE_EXECUTABLE_SUFFIX ".html") # Optional: build HTML page
|
set(CMAKE_EXECUTABLE_SUFFIX ".html") # Optional: build HTML page
|
||||||
|
|
||||||
|
target_compile_options(PortalGame PRIVATE
|
||||||
|
"-sUSE_SDL=2"
|
||||||
|
)
|
||||||
|
|
||||||
target_link_options(PortalGame PRIVATE
|
target_link_options(PortalGame PRIVATE
|
||||||
"-sUSE_SDL=2"
|
"-sUSE_SDL=2"
|
||||||
"-sASYNCIFY"
|
"-sASYNCIFY"
|
||||||
"--preload-file assets"
|
"-sUSE_WEBGL2=1"
|
||||||
)
|
"--shell-file" "${CMAKE_SOURCE_DIR}/shell.html"
|
||||||
|
"--preload-file" "${CMAKE_SOURCE_DIR}/assets"
|
||||||
|
)
|
||||||
|
|
||||||
else()
|
else()
|
||||||
|
message(STATUS "Target platform: Native")
|
||||||
# Native platform
|
# Native platform
|
||||||
# find_package(SDL2 REQUIRED)
|
# find_package(SDL2 REQUIRED)
|
||||||
# SDL2 build options to avoid unwanted components
|
# SDL2 build options to avoid unwanted components
|
||||||
@ -28,4 +43,9 @@ else()
|
|||||||
add_subdirectory(external/SDL)
|
add_subdirectory(external/SDL)
|
||||||
target_include_directories(PortalGame PRIVATE "external/SDL/include")
|
target_include_directories(PortalGame PRIVATE "external/SDL/include")
|
||||||
target_link_libraries(PortalGame PRIVATE SDL2main SDL2-static)
|
target_link_libraries(PortalGame PRIVATE SDL2main SDL2-static)
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
add_subdirectory(external/glm)
|
||||||
|
# target_include_directories(PortalGame PRIVATE "external/glm")
|
||||||
|
target_link_libraries(PortalGame PRIVATE glm)
|
||||||
53
CMakeUserPresets.json
Normal file
53
CMakeUserPresets.json
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"cmakeMinimumRequired": {
|
||||||
|
"major": 3,
|
||||||
|
"minor": 21,
|
||||||
|
"patch": 0
|
||||||
|
},
|
||||||
|
"configurePresets": [
|
||||||
|
{
|
||||||
|
"name": "emscripten",
|
||||||
|
"displayName": "Emscripten",
|
||||||
|
"binaryDir": "build-wasm",
|
||||||
|
"generator": "Ninja Multi-Config",
|
||||||
|
"toolchainFile": "c:/dev/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "VS",
|
||||||
|
"displayName": "Visual Studio 17 2022",
|
||||||
|
"description": "Using compilers for Visual Studio 17 2022 (x64 architecture)",
|
||||||
|
"generator": "Visual Studio 17 2022",
|
||||||
|
"toolset": "host=x64",
|
||||||
|
"architecture": "x64",
|
||||||
|
"binaryDir": "${sourceDir}/out/build/${presetName}",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}",
|
||||||
|
"CMAKE_C_COMPILER": "cl.exe",
|
||||||
|
"CMAKE_CXX_COMPILER": "cl.exe"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buildPresets": [
|
||||||
|
{
|
||||||
|
"name": "Emscripten Debug",
|
||||||
|
"configurePreset": "emscripten",
|
||||||
|
"configuration": "Debug"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Emscripten Release",
|
||||||
|
"configurePreset": "emscripten",
|
||||||
|
"configuration": "Release"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "VS Debug",
|
||||||
|
"configurePreset": "VS",
|
||||||
|
"configuration": "Debug"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "VS Release",
|
||||||
|
"configurePreset": "VS",
|
||||||
|
"configuration": "Release"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
1
assets/test.txt
Normal file
1
assets/test.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
Test
|
||||||
59
shell.html
Normal file
59
shell.html
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>PortalGame</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
height: 100%;
|
||||||
|
background: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas {
|
||||||
|
display: block;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<canvas id="canvas" oncontextmenu="event.preventDefault()"></canvas>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var Module = {
|
||||||
|
preRun: [],
|
||||||
|
postRun: [],
|
||||||
|
canvas: (function() {
|
||||||
|
return document.getElementById('canvas');
|
||||||
|
})()
|
||||||
|
};
|
||||||
|
|
||||||
|
// Resize canvas to fit the window and inform SDL (via Emscripten)
|
||||||
|
function resizeCanvas() {
|
||||||
|
const canvas = document.getElementById('canvas');
|
||||||
|
canvas.width = window.innerWidth;
|
||||||
|
canvas.height = window.innerHeight;
|
||||||
|
|
||||||
|
// // Notify Emscripten SDL2
|
||||||
|
// if (typeof Module !== 'undefined' && Module.canvas) {
|
||||||
|
// const evt = new CustomEvent('resize');
|
||||||
|
// window.dispatchEvent(evt);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('resize', resizeCanvas);
|
||||||
|
window.addEventListener('load', resizeCanvas);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{{{ SCRIPT }}}
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
14
src/app.cpp
Normal file
14
src/app.cpp
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include "app.hpp"
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include "gl.hpp"
|
||||||
|
|
||||||
|
App::App()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::Frame()
|
||||||
|
{
|
||||||
|
glm::vec3 clear_color(glm::abs(glm::sin(m_time)), 0.2f, 0.3f);
|
||||||
|
glClearColor(clear_color.r, clear_color.g, clear_color.b, 1.0f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
}
|
||||||
15
src/app.hpp
Normal file
15
src/app.hpp
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class App
|
||||||
|
{
|
||||||
|
float m_time = 0.0f;
|
||||||
|
|
||||||
|
public:
|
||||||
|
App();
|
||||||
|
|
||||||
|
void Frame();
|
||||||
|
|
||||||
|
void SetTime(float time) { m_time = time; }
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
3
src/gl.hpp
Normal file
3
src/gl.hpp
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#ifdef EMSCRIPTEN
|
||||||
|
#include <GLES2/gl2.h>
|
||||||
|
#endif
|
||||||
129
src/main.cpp
129
src/main.cpp
@ -1,21 +1,134 @@
|
|||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include "app.hpp"
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
#ifdef EMSCRIPTEN
|
||||||
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
|
#include <emscripten.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static SDL_Window *s_window = nullptr;
|
||||||
|
static SDL_GLContext s_context = nullptr;
|
||||||
|
static bool s_quit = false;
|
||||||
|
static std::unique_ptr<App> s_app;
|
||||||
|
|
||||||
|
static bool InitSDL()
|
||||||
|
{
|
||||||
|
if (SDL_Init(SDL_INIT_VIDEO) != 0)
|
||||||
|
{
|
||||||
std::cerr << "SDL_Init Error: " << SDL_GetError() << std::endl;
|
std::cerr << "SDL_Init Error: " << SDL_GetError() << std::endl;
|
||||||
return 1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Window* win = SDL_CreateWindow("Hello SDL2", 100, 100, 640, 480, SDL_WINDOW_SHOWN);
|
s_window = SDL_CreateWindow("PortalGame", 100, 100, 640, 480, SDL_WINDOW_SHOWN | SDL_WINDOW_MAXIMIZED | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
|
||||||
if (!win) {
|
if (!s_window)
|
||||||
|
{
|
||||||
std::cerr << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
|
std::cerr << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool InitGL()
|
||||||
|
{
|
||||||
|
#ifdef EMSCRIPTEN
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
||||||
|
#else
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
s_context = SDL_GL_CreateContext(s_window);
|
||||||
|
if (!s_context)
|
||||||
|
{
|
||||||
|
std::cerr << "SDL_GL_CreateContext Error: " << SDL_GetError() << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make context current
|
||||||
|
if (SDL_GL_MakeCurrent(s_window, s_context) != 0)
|
||||||
|
{
|
||||||
|
std::cerr << "SDL_GL_MakeCurrent Error: " << SDL_GetError() << std::endl;
|
||||||
|
SDL_GL_DeleteContext(s_context);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ShutdownGL()
|
||||||
|
{
|
||||||
|
if (s_context)
|
||||||
|
{
|
||||||
|
SDL_GL_DeleteContext(s_context);
|
||||||
|
s_context = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ShutdownSDL()
|
||||||
|
{
|
||||||
|
if (s_window)
|
||||||
|
{
|
||||||
|
SDL_DestroyWindow(s_window);
|
||||||
|
s_window = nullptr;
|
||||||
|
}
|
||||||
|
SDL_Quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PollEvents()
|
||||||
|
{
|
||||||
|
SDL_Event event;
|
||||||
|
while (SDL_PollEvent(&event))
|
||||||
|
{
|
||||||
|
if (event.type == SDL_QUIT)
|
||||||
|
{
|
||||||
|
s_quit = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Frame()
|
||||||
|
{
|
||||||
|
Uint32 current_time = SDL_GetTicks();
|
||||||
|
s_app->SetTime(current_time / 1000.0f); // Set time in seconds
|
||||||
|
PollEvents();
|
||||||
|
s_app->Frame();
|
||||||
|
SDL_GL_SwapWindow(s_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
if (!InitSDL())
|
||||||
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Delay(2000);
|
if (!InitGL())
|
||||||
SDL_DestroyWindow(win);
|
{
|
||||||
SDL_Quit();
|
ShutdownSDL();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
s_app = std::make_unique<App>();
|
||||||
|
|
||||||
|
#ifdef EMSCRIPTEN
|
||||||
|
emscripten_set_main_loop(Frame, 0, true);
|
||||||
|
#else
|
||||||
|
while (!s_quit)
|
||||||
|
{
|
||||||
|
Frame();
|
||||||
|
}
|
||||||
|
|
||||||
|
s_app.reset();
|
||||||
|
|
||||||
|
ShutdownGL();
|
||||||
|
ShutdownSDL();
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user