html5 glcontext
This commit is contained in:
Родитель
0479b4bda3
Коммит
142470237e
|
@ -9,6 +9,7 @@
|
|||
#include "glcontext_egl.cpp"
|
||||
#include "glcontext_glx.cpp"
|
||||
#include "glcontext_wgl.cpp"
|
||||
#include "glcontext_html5.cpp"
|
||||
#include "nvapi.cpp"
|
||||
#include "renderer_d3d11.cpp"
|
||||
#include "renderer_d3d12.cpp"
|
||||
|
|
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
* Copyright 2011-2019 Branimir Karadzic. All rights reserved.
|
||||
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
|
||||
*/
|
||||
|
||||
#include "bgfx_p.h"
|
||||
|
||||
#if BGFX_CONFIG_RENDERER_OPENGLES
|
||||
# include "renderer_gl.h"
|
||||
|
||||
# if BGFX_USE_HTML5
|
||||
|
||||
#include <emscripten/emscripten.h>
|
||||
#include <emscripten/html5.h>
|
||||
|
||||
// from emscripten gl.c, because we're not going to go
|
||||
// through egl
|
||||
extern "C" void* emscripten_GetProcAddress(const char *name_);
|
||||
|
||||
namespace bgfx { namespace gl
|
||||
{
|
||||
|
||||
# define GL_IMPORT(_optional, _proto, _func, _import) _proto _func = NULL
|
||||
# include "glimports.h"
|
||||
|
||||
static EmscriptenWebGLContextAttributes s_attrs;
|
||||
|
||||
struct SwapChainGL
|
||||
{
|
||||
SwapChainGL(int _context, const char* _canvas)
|
||||
: m_context(_context)
|
||||
{
|
||||
BX_ALLOC(g_allocator, strlen(_canvas) + 1);
|
||||
strcpy(m_canvas, _canvas);
|
||||
|
||||
makeCurrent();
|
||||
GL_CHECK(glClearColor(0.0f, 0.0f, 0.0f, 0.0f) );
|
||||
GL_CHECK(glClear(GL_COLOR_BUFFER_BIT) );
|
||||
swapBuffers();
|
||||
GL_CHECK(glClear(GL_COLOR_BUFFER_BIT) );
|
||||
swapBuffers();
|
||||
}
|
||||
|
||||
~SwapChainGL()
|
||||
{
|
||||
emscripten_webgl_destroy_context(m_context);
|
||||
BX_FREE(g_allocator, m_canvas);
|
||||
}
|
||||
|
||||
void makeCurrent()
|
||||
{
|
||||
emscripten_webgl_make_context_current(m_context);
|
||||
}
|
||||
|
||||
void swapBuffers()
|
||||
{
|
||||
// There is no swapBuffers equivalent. A swap happens whenever control is returned back
|
||||
// to the browser.
|
||||
}
|
||||
|
||||
int m_context;
|
||||
char* m_canvas;
|
||||
};
|
||||
|
||||
void GlContext::create(uint32_t _width, uint32_t _height)
|
||||
{
|
||||
// assert?
|
||||
if (m_primary != NULL)
|
||||
return;
|
||||
|
||||
const char* canvas = (const char*) g_platformData.nwh; // if 0, Module.canvas is used
|
||||
|
||||
m_primary = createSwapChain((void*)canvas);
|
||||
|
||||
if (_width && _height)
|
||||
emscripten_set_canvas_element_size(canvas, (int)_width, (int)_height);
|
||||
|
||||
makeCurrent(m_primary);
|
||||
}
|
||||
|
||||
void GlContext::destroy()
|
||||
{
|
||||
if (m_primary)
|
||||
{
|
||||
if (m_current == m_primary)
|
||||
m_current = NULL;
|
||||
BX_DELETE(g_allocator, m_primary);
|
||||
m_primary = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void GlContext::resize(uint32_t _width, uint32_t _height, uint32_t /* _flags */)
|
||||
{
|
||||
if (m_primary == NULL)
|
||||
return;
|
||||
|
||||
emscripten_set_canvas_element_size(m_primary->m_canvas, (int) _width, (int) _height);
|
||||
}
|
||||
|
||||
SwapChainGL* GlContext::createSwapChain(void* _nwh)
|
||||
{
|
||||
emscripten_webgl_init_context_attributes(&s_attrs);
|
||||
|
||||
s_attrs.alpha = false;
|
||||
s_attrs.depth = true;
|
||||
s_attrs.stencil = true;
|
||||
s_attrs.enableExtensionsByDefault = true;
|
||||
|
||||
// let emscripten figure out the best WebGL context to create
|
||||
// TODO this isn't necessarily the right thing, I don't think the code actually does the fallback like it should
|
||||
s_attrs.majorVersion = 0;
|
||||
s_attrs.majorVersion = 0;
|
||||
|
||||
const char* canvas = (const char*) _nwh;
|
||||
|
||||
int context = emscripten_webgl_create_context(canvas, &s_attrs);
|
||||
|
||||
if (context <= 0)
|
||||
{
|
||||
BX_TRACE("Failed to create WebGL context. (Canvas handle: '%s', error %d)", canvas, (int)context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int result = emscripten_webgl_make_context_current(context);
|
||||
if (EMSCRIPTEN_RESULT_SUCCESS != result)
|
||||
{
|
||||
BX_TRACE("emscripten_webgl_make_context_current failed (%d)", result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SwapChainGL* swapChain = BX_NEW(g_allocator, SwapChainGL)(context, canvas);
|
||||
|
||||
import();
|
||||
|
||||
return swapChain;
|
||||
}
|
||||
|
||||
uint64_t GlContext::getCaps() const
|
||||
{
|
||||
return BGFX_CAPS_SWAP_CHAIN;
|
||||
}
|
||||
|
||||
void GlContext::destroySwapChain(SwapChainGL* _swapChain)
|
||||
{
|
||||
BX_DELETE(g_allocator, _swapChain);
|
||||
}
|
||||
|
||||
void GlContext::swap(SwapChainGL* /* _swapChain */)
|
||||
{
|
||||
}
|
||||
|
||||
void GlContext::makeCurrent(SwapChainGL* _swapChain)
|
||||
{
|
||||
if (m_current != _swapChain)
|
||||
{
|
||||
m_current = _swapChain;
|
||||
|
||||
if (NULL == _swapChain)
|
||||
{
|
||||
if (NULL != m_primary)
|
||||
{
|
||||
m_primary->makeCurrent();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_swapChain->makeCurrent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GlContext::import()
|
||||
{
|
||||
BX_TRACE("Import:");
|
||||
# define GL_EXTENSION(_optional, _proto, _func, _import) \
|
||||
{ \
|
||||
if (NULL == _func) \
|
||||
{ \
|
||||
_func = (_proto)emscripten_GetProcAddress(#_import); \
|
||||
BX_TRACE("\t%p " #_func " (" #_import ")", _func); \
|
||||
BGFX_FATAL(_optional || NULL != _func, Fatal::UnableToInitialize, "Failed to create WebGL/OpenGLES context. GetProcAddress(\"%s\")", #_import); \
|
||||
} \
|
||||
}
|
||||
|
||||
# include "glimports.h"
|
||||
}
|
||||
|
||||
} /* namespace gl */ } // namespace bgfx
|
||||
|
||||
# endif // BGFX_USE_EGL
|
||||
#endif // (BGFX_CONFIG_RENDERER_OPENGLES || BGFX_CONFIG_RENDERER_OPENGL)
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright 2011-2019 Branimir Karadzic. All rights reserved.
|
||||
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
|
||||
*/
|
||||
|
||||
#ifndef BGFX_GLCONTEXT_HTML5_H_HEADER_GUARD
|
||||
#define BGFX_GLCONTEXT_HTML5_H_HEADER_GUARD
|
||||
|
||||
#if BGFX_USE_HTML5
|
||||
|
||||
namespace bgfx { namespace gl
|
||||
{
|
||||
struct SwapChainGL;
|
||||
|
||||
struct GlContext
|
||||
{
|
||||
GlContext()
|
||||
: m_current(NULL)
|
||||
, m_primary(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
void create(uint32_t _width, uint32_t _height);
|
||||
void destroy();
|
||||
void resize(uint32_t _width, uint32_t _height, uint32_t _flags);
|
||||
|
||||
uint64_t getCaps() const;
|
||||
SwapChainGL* createSwapChain(void* _nwh);
|
||||
void destroySwapChain(SwapChainGL* _swapChain);
|
||||
void swap(SwapChainGL* _swapChain = NULL);
|
||||
void makeCurrent(SwapChainGL* _swapChain = NULL);
|
||||
|
||||
void import();
|
||||
|
||||
bool isValid() const
|
||||
{
|
||||
return NULL != m_primary;
|
||||
}
|
||||
|
||||
SwapChainGL* m_current;
|
||||
SwapChainGL* m_primary;
|
||||
};
|
||||
} /* namespace gl */ } // namespace bgfx
|
||||
|
||||
#endif // BGFX_USE_HTML5
|
||||
|
||||
#endif // BGFX_GLCONTEXT_HTML5_H_HEADER_GUARD
|
|
@ -9,7 +9,6 @@
|
|||
#define BGFX_USE_EGL (BGFX_CONFIG_RENDERER_OPENGLES && (0 \
|
||||
|| BX_PLATFORM_ANDROID \
|
||||
|| BX_PLATFORM_BSD \
|
||||
|| BX_PLATFORM_EMSCRIPTEN \
|
||||
|| BX_PLATFORM_LINUX \
|
||||
|| BX_PLATFORM_NX \
|
||||
|| BX_PLATFORM_RPI \
|
||||
|
@ -17,6 +16,10 @@
|
|||
|| BX_PLATFORM_WINDOWS \
|
||||
) )
|
||||
|
||||
#define BGFX_USE_HTML5 (BGFX_CONFIG_RENDERER_OPENGLES && (0 \
|
||||
|| BX_PLATFORM_EMSCRIPTEN \
|
||||
) )
|
||||
|
||||
#define BGFX_USE_WGL (BGFX_CONFIG_RENDERER_OPENGL && BX_PLATFORM_WINDOWS)
|
||||
#define BGFX_USE_GLX (BGFX_CONFIG_RENDERER_OPENGL && (0 \
|
||||
|| BX_PLATFORM_BSD \
|
||||
|
@ -125,6 +128,10 @@ typedef uint64_t GLuint64;
|
|||
# include "glcontext_egl.h"
|
||||
# endif // BGFX_USE_EGL
|
||||
|
||||
# if BGFX_USE_HTML5
|
||||
# include "glcontext_html5.h"
|
||||
# endif // BGFX_USE_EGL
|
||||
|
||||
# if BX_PLATFORM_EMSCRIPTEN
|
||||
# include <emscripten/emscripten.h>
|
||||
# endif // BX_PLATFORM_EMSCRIPTEN
|
||||
|
|
Загрузка…
Ссылка в новой задаче