~ WIP port emscripen (WebGL)
This commit is contained in:
@@ -23,7 +23,7 @@
|
||||
#define Lseek lseek
|
||||
#define Open_def open
|
||||
#define Ftruncate ftruncate
|
||||
#elif defined(NAZARA_PLATFORM_LINUX)
|
||||
#elif defined(NAZARA_PLATFORM_LINUX) || defined(NAZARA_PLATFORM_WEB)
|
||||
#define Stat stat64
|
||||
#define Fstat fstat64
|
||||
#define Off_t off64_t
|
||||
|
||||
@@ -5,12 +5,13 @@
|
||||
#include <Nazara/Core/Posix/HardwareInfoImpl.hpp>
|
||||
#include <unistd.h>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
void HardwareInfoImpl::Cpuid(UInt32 functionId, UInt32 subFunctionId, UInt32 registers[4])
|
||||
{
|
||||
#if defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL)
|
||||
#if (defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL)) && !defined(NAZARA_PLATFORM_WEB)
|
||||
// https://en.wikipedia.org/wiki/CPUID
|
||||
asm volatile(
|
||||
#ifdef NAZARA_PLATFORM_x64
|
||||
@@ -50,6 +51,8 @@ namespace Nz
|
||||
{
|
||||
#ifdef NAZARA_PLATFORM_x64
|
||||
return true; // cpuid is always supported on x64 arch
|
||||
#elif defined(NAZARA_PLATFORM_WEB)
|
||||
return false;
|
||||
#else
|
||||
#if defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL)
|
||||
int supported;
|
||||
|
||||
@@ -135,7 +135,7 @@ namespace Nz
|
||||
* Reads the stream until a line separator or the end of the stream is found.
|
||||
*
|
||||
* If lineSize does not equal zero, it represents the maximum character count to be read from the stream.
|
||||
*
|
||||
*
|
||||
* \param lineSize Maximum number of characters to read, or zero for no limit
|
||||
*
|
||||
* \return Line read from file
|
||||
@@ -264,7 +264,7 @@ namespace Nz
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
std::string temp(string);
|
||||
ReplaceStr(temp, "\n", "\r\n");
|
||||
#elif defined(NAZARA_PLATFORM_LINUX)
|
||||
#elif defined(NAZARA_PLATFORM_LINUX) || defined(NAZARA_PLATFORM_WEB)
|
||||
std::string_view temp(string);
|
||||
// Nothing to do
|
||||
#elif defined(NAZARA_PLATFORM_MACOS)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#ifdef NAZARA_PLATFORM_WINDOWS
|
||||
#include <objbase.h>
|
||||
#elif defined(NAZARA_PLATFORM_LINUX) || defined(NAZARA_PLATFORM_MACOS)
|
||||
#elif defined(NAZARA_PLATFORM_LINUX) || defined(NAZARA_PLATFORM_MACOS) || defined(NAZARA_PLATFORM_WEB)
|
||||
#include <uuid/uuid.h>
|
||||
#endif
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace Nz
|
||||
|
||||
for (unsigned int i = 0; i < 8; ++i)
|
||||
uuid[8 + i] = static_cast<UInt8>(id.Data4[i]);
|
||||
#elif defined(NAZARA_PLATFORM_LINUX) || defined(NAZARA_PLATFORM_MACOS)
|
||||
#elif defined(NAZARA_PLATFORM_LINUX) || defined(NAZARA_PLATFORM_MACOS) || defined(NAZARA_PLATFORM_WEB)
|
||||
uuid_t id;
|
||||
uuid_generate(id);
|
||||
|
||||
|
||||
@@ -322,8 +322,8 @@ namespace Nz
|
||||
}
|
||||
}
|
||||
|
||||
if (!invalidateAttachments.empty())
|
||||
context->glInvalidateFramebuffer(GL_FRAMEBUFFER, GLsizei(invalidateAttachments.size()), invalidateAttachments.data());
|
||||
/*if (!invalidateAttachments.empty())
|
||||
context->glInvalidateFramebuffer(GL_FRAMEBUFFER, GLsizei(invalidateAttachments.size()), invalidateAttachments.data());*/
|
||||
}
|
||||
else
|
||||
static_assert(AlwaysFalse<T>::value, "non-exhaustive visitor");
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
#include <Nazara/OpenGLRenderer/Wrapper/EGL/EGLLoader.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WEB)
|
||||
#include <Nazara/OpenGLRenderer/Wrapper/Web/WebLoader.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef NAZARA_PLATFORM_WINDOWS
|
||||
#include <Nazara/OpenGLRenderer/Wrapper/WGL/WGLLoader.hpp>
|
||||
#endif
|
||||
@@ -82,6 +86,17 @@ namespace Nz
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WEB)
|
||||
try
|
||||
{
|
||||
return std::make_unique<GL::WebLoader>();
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
NazaraWarning(std::string("Failed to load WebGL: ") + e.what());
|
||||
}
|
||||
#endif
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
@@ -54,11 +54,13 @@ namespace Nz
|
||||
if (!context.DidLastCallSucceed())
|
||||
throw std::runtime_error("failed to create texture");
|
||||
|
||||
#ifndef NAZARA_PLATFORM_WEB
|
||||
m_texture.SetParameteri(GL_TEXTURE_MAX_LEVEL, m_textureInfo.levelCount);
|
||||
m_texture.SetParameteri(GL_TEXTURE_SWIZZLE_R, format->swizzleR);
|
||||
m_texture.SetParameteri(GL_TEXTURE_SWIZZLE_G, format->swizzleG);
|
||||
m_texture.SetParameteri(GL_TEXTURE_SWIZZLE_B, format->swizzleB);
|
||||
m_texture.SetParameteri(GL_TEXTURE_SWIZZLE_A, format->swizzleA);
|
||||
#endif
|
||||
}
|
||||
|
||||
OpenGLTexture::OpenGLTexture(std::shared_ptr<OpenGLTexture> parentTexture, const TextureViewInfo& viewInfo) :
|
||||
|
||||
@@ -130,6 +130,10 @@ namespace Nz::GL
|
||||
|
||||
void Context::BindBuffer(BufferTarget target, GLuint buffer, bool force) const
|
||||
{
|
||||
#ifdef NAZARA_PLATFORM_WEB
|
||||
force = true;
|
||||
#endif
|
||||
|
||||
if (m_state.bufferTargets[UnderlyingCast(target)] != buffer || force)
|
||||
{
|
||||
if (!SetCurrentContext(this))
|
||||
@@ -162,7 +166,12 @@ namespace Nz::GL
|
||||
void Context::BindFramebuffer(FramebufferTarget target, GLuint fbo) const
|
||||
{
|
||||
auto& currentFbo = (target == FramebufferTarget::Draw) ? m_state.boundDrawFBO : m_state.boundReadFBO;
|
||||
if (currentFbo != fbo)
|
||||
#ifdef NAZARA_PLATFORM_WEB
|
||||
constexpr bool isWeb = true;
|
||||
#else
|
||||
constexpr bool isWeb = false;
|
||||
#endif
|
||||
if (currentFbo != fbo || isWeb);
|
||||
{
|
||||
if (!SetCurrentContext(this))
|
||||
throw std::runtime_error("failed to activate context");
|
||||
@@ -427,7 +436,7 @@ namespace Nz::GL
|
||||
|
||||
try
|
||||
{
|
||||
#define NAZARA_OPENGLRENDERER_FUNC(name, sig) loader.Load<sig, UnderlyingCast(FunctionIndex:: name)>(name, #name, true, true);
|
||||
#define NAZARA_OPENGLRENDERER_FUNC(name, sig) loader.Load<sig, UnderlyingCast(FunctionIndex:: name)>(name, #name, false, true);
|
||||
#define NAZARA_OPENGLRENDERER_EXT_FUNC(name, sig) //< Do nothing
|
||||
NAZARA_OPENGLRENDERER_FOREACH_GLES_FUNC(NAZARA_OPENGLRENDERER_FUNC, NAZARA_OPENGLRENDERER_EXT_FUNC)
|
||||
#undef NAZARA_OPENGLRENDERER_EXT_FUNC
|
||||
|
||||
255
src/Nazara/OpenGLRenderer/Wrapper/Web/WebContext.cpp
Normal file
255
src/Nazara/OpenGLRenderer/Wrapper/Web/WebContext.cpp
Normal file
@@ -0,0 +1,255 @@
|
||||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - OpenGL renderer"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/OpenGLRenderer/Wrapper/Web/WebContext.hpp>
|
||||
#include <Nazara/Core/Log.hpp>
|
||||
#include <Nazara/Core/StringExt.hpp>
|
||||
#include <Nazara/OpenGLRenderer/Wrapper/Web/WebLoader.hpp>
|
||||
#include <Nazara/Utils/CallOnExit.hpp>
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <Nazara/OpenGLRenderer/Debug.hpp>
|
||||
|
||||
namespace Nz::GL
|
||||
{
|
||||
WebContext::~WebContext()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool WebContext::Create(const ContextParams& params, const WebContext* shareContext)
|
||||
{
|
||||
Destroy(); //< In case a previous display or surface hasn't been released
|
||||
|
||||
m_params = params;
|
||||
|
||||
std::size_t configCount;
|
||||
std::array<EmscriptenWebGLContextAttributes, 0xFF> configs;
|
||||
if (!ChooseConfig(configs.data(), configs.size(), &configCount))
|
||||
return false;
|
||||
|
||||
std::size_t configIndex = 0;
|
||||
|
||||
return CreateInternal(configs[configIndex], shareContext);
|
||||
}
|
||||
|
||||
bool WebContext::Create(const ContextParams& params, WindowHandle /*window*/, const WebContext* /*shareContext*/)
|
||||
{
|
||||
/*NazaraError("Unexpected context creation call");
|
||||
return false;*/
|
||||
|
||||
return Create(params, nullptr);
|
||||
}
|
||||
|
||||
void WebContext::Destroy()
|
||||
{
|
||||
if (s_handle > 0)
|
||||
{
|
||||
assert(s_handle > 0);
|
||||
|
||||
OnContextRelease();
|
||||
NotifyContextDestruction(this);
|
||||
|
||||
s_handleCounter--;
|
||||
|
||||
if(s_handleCounter == 0)
|
||||
{
|
||||
emscripten_webgl_destroy_context(s_handle);
|
||||
s_handle = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WebContext::EnableVerticalSync(bool /*enabled*/)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void WebContext::SwapBuffers()
|
||||
{
|
||||
emscripten_webgl_commit_frame();
|
||||
}
|
||||
|
||||
bool WebContext::ChooseConfig(EmscriptenWebGLContextAttributes* configs, std::size_t maxConfigCount, std::size_t* configCount)
|
||||
{
|
||||
EmscriptenWebGLContextAttributes configAttributes;
|
||||
emscripten_webgl_init_context_attributes(&configAttributes);
|
||||
|
||||
// https://emscripten.org/docs/api_reference/html5.h.html#c.EmscriptenWebGLContextAttributes
|
||||
configAttributes.alpha = true;
|
||||
configAttributes.depth = m_params.depthBits > 0;
|
||||
configAttributes.stencil = m_params.stencilBits > 0;
|
||||
configAttributes.antialias = false;
|
||||
configAttributes.premultipliedAlpha = true;
|
||||
configAttributes.preserveDrawingBuffer = false;
|
||||
configAttributes.powerPreference = EM_WEBGL_POWER_PREFERENCE_DEFAULT;
|
||||
configAttributes.failIfMajorPerformanceCaveat = false;
|
||||
configAttributes.majorVersion = m_params.glMajorVersion;
|
||||
configAttributes.minorVersion = m_params.glMinorVersion;
|
||||
configAttributes.enableExtensionsByDefault = true;
|
||||
configAttributes.explicitSwapControl = false; // todo
|
||||
configAttributes.renderViaOffscreenBackBuffer = false; // todo
|
||||
configAttributes.proxyContextToMainThread = false; // todo
|
||||
|
||||
size_t numConfig = 1;
|
||||
|
||||
configs[0] = configAttributes;
|
||||
|
||||
*configCount = numConfig;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WebContext::CreateInternal(EmscriptenWebGLContextAttributes config, const WebContext* shareContext)
|
||||
{
|
||||
if(s_handleCounter > 0)
|
||||
{
|
||||
s_handleCounter++;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (shareContext)
|
||||
{
|
||||
NazaraWarning(std::string("shared contexes are not supported by WebGL but shareContext is not null"));
|
||||
}
|
||||
|
||||
struct Version
|
||||
{
|
||||
unsigned int major;
|
||||
unsigned int minor;
|
||||
};
|
||||
|
||||
if (m_params.type == ContextType::OpenGL_ES)
|
||||
{
|
||||
// Create OpenGL ES context
|
||||
std::array<Version, 3> supportedGL_ESVersions = {
|
||||
{
|
||||
{ 2, 0 },
|
||||
{ 1, 0 }
|
||||
}
|
||||
};
|
||||
|
||||
for (const Version& version : supportedGL_ESVersions)
|
||||
{
|
||||
if (m_params.glMajorVersion != 0)
|
||||
{
|
||||
if (version.major > m_params.glMajorVersion)
|
||||
continue;
|
||||
|
||||
if (m_params.glMinorVersion != 0 && version.minor > m_params.glMinorVersion)
|
||||
continue;
|
||||
}
|
||||
|
||||
config.majorVersion = version.major;
|
||||
config.minorVersion = version.minor;
|
||||
|
||||
s_handle = emscripten_webgl_create_context("canvas", &config);
|
||||
if (s_handle > 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NazaraError(std::string("failed to create WebGL context: OpenGL is not supported"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s_handle <= 0)
|
||||
{
|
||||
NazaraError(std::string("failed to create Web context: ") + WebLoader::TranslateError(static_cast<EMSCRIPTEN_RESULT>(s_handle)));
|
||||
return false;
|
||||
}
|
||||
|
||||
LoadExt();
|
||||
|
||||
s_handleCounter++;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WebContext::ImplementFallback(const std::string_view& function)
|
||||
{
|
||||
if (Context::ImplementFallback(function))
|
||||
return true;
|
||||
|
||||
if (m_params.type == ContextType::OpenGL_ES)
|
||||
return false; //< Implement fallback only for OpenGL (when emulating OpenGL ES)
|
||||
|
||||
if (function == "glClearDepthf")
|
||||
{
|
||||
fallbacks.glClearDepth = reinterpret_cast<Fallback::glClearDepthProc>(m_loader.LoadFunction("glClearDepth"));
|
||||
if (!fallbacks.glClearDepth)
|
||||
return false;
|
||||
|
||||
glClearDepthf = [](GLfloat depth)
|
||||
{
|
||||
const WebContext* context = static_cast<const WebContext*>(GetCurrentContext());
|
||||
assert(context);
|
||||
context->fallbacks.glClearDepth(depth);
|
||||
};
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WebContext::Activate() const
|
||||
{
|
||||
EMSCRIPTEN_RESULT succeeded = emscripten_webgl_make_context_current(s_handle);
|
||||
if (succeeded != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
NazaraError("failed to activate context");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WebContext::Desactivate() const
|
||||
{
|
||||
assert(GetCurrentContext() == this);
|
||||
EMSCRIPTEN_RESULT succeeded = emscripten_webgl_make_context_current(0);
|
||||
if (succeeded != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
NazaraError("failed to desactivate context");
|
||||
}
|
||||
|
||||
const Loader& WebContext::GetLoader()
|
||||
{
|
||||
return m_loader;
|
||||
}
|
||||
|
||||
bool WebContext::LoadExt()
|
||||
{
|
||||
if (!SetCurrentContext(this))
|
||||
return false;
|
||||
|
||||
char* extensionString = emscripten_webgl_get_supported_extensions();
|
||||
if (extensionString)
|
||||
{
|
||||
SplitString(extensionString, " ", [&](std::string_view extension)
|
||||
{
|
||||
m_supportedPlatformExtensions.emplace(extension);
|
||||
|
||||
std::string ext(extension);
|
||||
|
||||
emscripten_webgl_enable_extension(s_handle, ext.c_str());
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
free(extensionString);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE WebContext::s_handle = 0;
|
||||
size_t WebContext::s_handleCounter = 0;
|
||||
}
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
#include <Nazara/Core/AntiWindows.hpp>
|
||||
#endif
|
||||
142
src/Nazara/OpenGLRenderer/Wrapper/Web/WebLoader.cpp
Normal file
142
src/Nazara/OpenGLRenderer/Wrapper/Web/WebLoader.cpp
Normal file
@@ -0,0 +1,142 @@
|
||||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - OpenGL renderer"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/OpenGLRenderer/Wrapper/Web/WebLoader.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/Log.hpp>
|
||||
#include <Nazara/OpenGLRenderer/Wrapper/Web/WebContext.hpp>
|
||||
|
||||
#include <Nazara/OpenGLRenderer/Debug.hpp>
|
||||
|
||||
namespace Nz::GL
|
||||
{
|
||||
struct WebLoader::SymbolLoader
|
||||
{
|
||||
SymbolLoader(WebLoader& parent) :
|
||||
loader(parent)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename FuncType, typename Func>
|
||||
bool Load(Func& func, const char* funcName, bool mandatory, bool implementFallback = true)
|
||||
{
|
||||
func = LoadRaw<FuncType>(funcName);
|
||||
if (!func)
|
||||
{
|
||||
if (!implementFallback || (!loader.ImplementFallback(funcName) && !func)) //< double-check
|
||||
{
|
||||
if (mandatory)
|
||||
throw std::runtime_error("failed to load core function " + std::string(funcName));
|
||||
}
|
||||
}
|
||||
|
||||
return func != nullptr;
|
||||
}
|
||||
|
||||
template<typename FuncType>
|
||||
FuncType LoadRaw(const char* funcName)
|
||||
{
|
||||
return reinterpret_cast<FuncType>(loader.LoadFunction(funcName));
|
||||
}
|
||||
|
||||
WebLoader& loader;
|
||||
};
|
||||
|
||||
std::unique_ptr<Context> WebLoader::CreateContext(const OpenGLDevice* device, const ContextParams& params, Context* shareContext) const
|
||||
{
|
||||
std::unique_ptr<WebContext> context = std::make_unique<WebContext>(device, *this);
|
||||
|
||||
if (!context->Create(params, static_cast<WebContext*>(shareContext)))
|
||||
{
|
||||
NazaraError("failed to create context");
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!context->Initialize(params))
|
||||
{
|
||||
NazaraError("failed to initialize context");
|
||||
return {};
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
std::unique_ptr<Context> WebLoader::CreateContext(const OpenGLDevice* device, const ContextParams& params, WindowHandle handle, Context* shareContext) const
|
||||
{
|
||||
std::unique_ptr<WebContext> context;
|
||||
switch (handle.type)
|
||||
{
|
||||
case WindowBackend::Invalid:
|
||||
break;
|
||||
|
||||
case WindowBackend::Web:
|
||||
context = std::make_unique<WebContext>(device, *this);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!context)
|
||||
{
|
||||
NazaraError("unsupported window type");
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!context->Create(params, handle, static_cast<WebContext*>(shareContext)))
|
||||
{
|
||||
NazaraError("failed to create context");
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!context->Initialize(params))
|
||||
{
|
||||
NazaraError("failed to initialize context");
|
||||
return {};
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
ContextType WebLoader::GetPreferredContextType() const
|
||||
{
|
||||
return ContextType::OpenGL_ES;
|
||||
}
|
||||
|
||||
GLFunction WebLoader::LoadFunction(const char* name) const
|
||||
{
|
||||
/*GLFunction func = reinterpret_cast<GLFunction>(m_WebLib.GetSymbol(name));
|
||||
if (!func && WebGetProcAddress)
|
||||
func = reinterpret_cast<GLFunction>(WebGetProcAddress(name));
|
||||
|
||||
return func;*/
|
||||
|
||||
return reinterpret_cast<GLFunction>(emscripten_webgl_get_proc_address(name));
|
||||
|
||||
//return nullptr;
|
||||
}
|
||||
|
||||
const char* WebLoader::TranslateError(EMSCRIPTEN_RESULT errorId)
|
||||
{
|
||||
switch (errorId)
|
||||
{
|
||||
case EMSCRIPTEN_RESULT_SUCCESS: return "The last function succeeded without error.";
|
||||
case EMSCRIPTEN_RESULT_DEFERRED: return "The requested operation cannot be completed now for web security reasons, and has been deferred for completion in the next event handler.";
|
||||
case EMSCRIPTEN_RESULT_NOT_SUPPORTED: return "The given operation is not supported by this browser or the target element. This value will be returned at the time the callback is registered if the operation is not supported.";
|
||||
case EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED: return "The requested operation could not be completed now for web security reasons. It failed because the user requested the operation not be deferred.";
|
||||
case EMSCRIPTEN_RESULT_INVALID_TARGET: return "The operation failed because the specified target element is invalid.";
|
||||
case EMSCRIPTEN_RESULT_UNKNOWN_TARGET: return "The operation failed because the specified target element was not found.";
|
||||
case EMSCRIPTEN_RESULT_INVALID_PARAM: return "The operation failed because an invalid parameter was passed to the function.";
|
||||
case EMSCRIPTEN_RESULT_FAILED: return "Unknown error (EMSCRIPTEN_RESULT_FAILED).";
|
||||
case EMSCRIPTEN_RESULT_NO_DATA: return "The operation failed because no data is currently available.";
|
||||
default: return "Invalid or unknown error.";
|
||||
}
|
||||
}
|
||||
|
||||
bool WebLoader::ImplementFallback(const std::string_view& /*function*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
#include <Nazara/Core/AntiWindows.hpp>
|
||||
#endif
|
||||
@@ -199,8 +199,10 @@ namespace Nz
|
||||
|
||||
if (SDL_GetWindowWMInfo(m_handle, &wmInfo) != SDL_TRUE)
|
||||
{
|
||||
#ifndef NAZARA_PLATFORM_WEB
|
||||
ErrorFlags flags(ErrorMode::ThrowException, true);
|
||||
NazaraError(std::string("failed to retrieve window manager info: ") + SDL_GetError());
|
||||
#endif
|
||||
}
|
||||
|
||||
WindowHandle handle;
|
||||
@@ -244,8 +246,12 @@ namespace Nz
|
||||
#endif
|
||||
default:
|
||||
{
|
||||
#if defined(NAZARA_PLATFORM_WEB)
|
||||
handle.type = WindowBackend::Web;
|
||||
#else
|
||||
ErrorFlags flags(ErrorMode::ThrowException, true);
|
||||
NazaraError("unhandled window subsystem");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
#ifdef NAZARA_PLATFORM_WEB
|
||||
#include <Nazara/OpenGLRenderer/OpenGLRenderer.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef NAZARA_COMPILER_MSVC
|
||||
#define NazaraRendererPrefix ""
|
||||
#else
|
||||
@@ -77,6 +81,7 @@ namespace Nz
|
||||
|
||||
void Renderer::LoadBackend(const Config& config)
|
||||
{
|
||||
#ifndef NAZARA_PLATFORM_WEB
|
||||
constexpr std::array<const char*, RenderAPICount> rendererPaths = {
|
||||
NazaraRendererPrefix "NazaraDirect3DRenderer" NazaraRendererDebugSuffix, // Direct3D
|
||||
NazaraRendererPrefix "NazaraMantleRenderer" NazaraRendererDebugSuffix, // Mantle
|
||||
@@ -201,6 +206,16 @@ namespace Nz
|
||||
m_rendererLib = std::move(chosenLib);
|
||||
#endif
|
||||
|
||||
#else
|
||||
std::unique_ptr<Nz::OpenGLRenderer> impl = std::make_unique<Nz::OpenGLRenderer>();
|
||||
if (!impl || !impl->Prepare({}))
|
||||
{
|
||||
NazaraError("Failed to create renderer implementation");
|
||||
}
|
||||
|
||||
m_rendererImpl = std::move(impl);
|
||||
#endif
|
||||
|
||||
NazaraDebug("Using " + m_rendererImpl->QueryAPIString() + " as renderer");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user