WASM compile
This commit is contained in:
parent
35afe7722f
commit
3e94734887
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,3 +1,5 @@
|
||||
build/
|
||||
build-wasm/
|
||||
out/
|
||||
|
||||
.vs/
|
||||
.vscode/
|
||||
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -2,3 +2,6 @@
|
||||
path = external/SDL
|
||||
url = https://github.com/libsdl-org/SDL.git
|
||||
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)
|
||||
|
||||
# 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
|
||||
if(EMSCRIPTEN)
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL Emscripten)
|
||||
|
||||
# Emscripten provides SDL2 via its system libraries
|
||||
message(STATUS "Target platform: WebAssembly (Emscripten)")
|
||||
set(CMAKE_EXECUTABLE_SUFFIX ".html") # Optional: build HTML page
|
||||
|
||||
target_compile_options(PortalGame PRIVATE
|
||||
"-sUSE_SDL=2"
|
||||
)
|
||||
|
||||
target_link_options(PortalGame PRIVATE
|
||||
"-sUSE_SDL=2"
|
||||
"-sASYNCIFY"
|
||||
"--preload-file assets"
|
||||
)
|
||||
"-sUSE_WEBGL2=1"
|
||||
"--shell-file" "${CMAKE_SOURCE_DIR}/shell.html"
|
||||
"--preload-file" "${CMAKE_SOURCE_DIR}/assets"
|
||||
)
|
||||
|
||||
else()
|
||||
message(STATUS "Target platform: Native")
|
||||
# Native platform
|
||||
# find_package(SDL2 REQUIRED)
|
||||
# SDL2 build options to avoid unwanted components
|
||||
@ -28,4 +43,9 @@ else()
|
||||
add_subdirectory(external/SDL)
|
||||
target_include_directories(PortalGame PRIVATE "external/SDL/include")
|
||||
target_link_libraries(PortalGame PRIVATE SDL2main SDL2-static)
|
||||
|
||||
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 <iostream>
|
||||
#include <memory>
|
||||
#include "app.hpp"
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
|
||||
#ifdef EMSCRIPTEN
|
||||
#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;
|
||||
return 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
SDL_Window* win = SDL_CreateWindow("Hello SDL2", 100, 100, 640, 480, SDL_WINDOW_SHOWN);
|
||||
if (!win) {
|
||||
s_window = SDL_CreateWindow("PortalGame", 100, 100, 640, 480, SDL_WINDOW_SHOWN | SDL_WINDOW_MAXIMIZED | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
|
||||
if (!s_window)
|
||||
{
|
||||
std::cerr << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
|
||||
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;
|
||||
}
|
||||
|
||||
SDL_Delay(2000);
|
||||
SDL_DestroyWindow(win);
|
||||
SDL_Quit();
|
||||
if (!InitGL())
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user