1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
#define NCINE_INCLUDE_OPENGL
#include "../CommonHeaders.h"
#include "../../Main.h"
#include "IGfxDevice.h"
#include "../Primitives/Colorf.h"
#include "GL/GLDepthTest.h"
#include "GL/GLBlending.h"
#include "GL/GLClearColor.h"
#include "GL/GLViewport.h"
#if defined(DEATH_TARGET_EMSCRIPTEN)
# include <emscripten/html5.h>
# include "../Application.h"
#endif
namespace nCine
{
#if defined(DEATH_TARGET_EMSCRIPTEN)
bool IGfxDevice::emscriptenHandleResize(int eventType, const EmscriptenUiEvent* event, void* userData)
{
# if defined(DEATH_TRACE)
double cssWidth = 0.0;
double cssHeight = 0.0;
emscripten_get_element_css_size("canvas", &cssWidth, &cssHeight);
float pixelRatio2 = emscripten_get_device_pixel_ratio();
LOGI("Canvas was resized to {}x{} (canvas size is {}x{}; ratio is {})", (int)(event->windowInnerWidth * pixelRatio2), (int)(event->windowInnerHeight * pixelRatio2), (int)cssWidth, (int)cssHeight, pixelRatio2);
# endif
if (event->windowInnerWidth > 0 && event->windowInnerHeight > 0) {
IGfxDevice* gfxDevice = static_cast<IGfxDevice*>(userData);
# if defined(EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3)
// `contrib.glfw3` should handle HiDPI automatically
gfxDevice->setResolutionInternal(static_cast<int>(event->windowInnerWidth), static_cast<int>(event->windowInnerHeight));
# else
float pixelRatio = emscripten_get_device_pixel_ratio();
gfxDevice->setResolutionInternal(static_cast<int>(event->windowInnerWidth * pixelRatio), static_cast<int>(event->windowInnerHeight * pixelRatio));
# endif
}
return true;
}
bool IGfxDevice::emscriptenHandleFullscreen(int eventType, const EmscriptenFullscreenChangeEvent* event, void* userData)
{
# if defined(DEATH_TRACE)
double cssWidth = 0.0;
double cssHeight = 0.0;
emscripten_get_element_css_size("canvas", &cssWidth, &cssHeight);
float pixelRatio2 = emscripten_get_device_pixel_ratio();
LOGI("Canvas was resized to {}x{} (canvas size is {}x{}; ratio is {})", (int)(event->elementWidth * pixelRatio2), (int)(event->elementHeight * pixelRatio2), (int)cssWidth, (int)cssHeight, pixelRatio2);
# endif
IGfxDevice* gfxDevice = static_cast<IGfxDevice*>(userData);
gfxDevice->isFullscreen_ = event->isFullscreen;
if (event->elementWidth > 0 && event->elementHeight > 0) {
# if defined(EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3)
// `contrib.glfw3` should handle HiDPI automatically
gfxDevice->setResolutionInternal(static_cast<int>(event->elementWidth), static_cast<int>(event->elementHeight));
# else
float pixelRatio = emscripten_get_device_pixel_ratio();
gfxDevice->setResolutionInternal(static_cast<int>(event->elementWidth * pixelRatio), static_cast<int>(event->elementHeight * pixelRatio));
# endif
}
return true;
}
# if defined(WITH_GLFW)
bool IGfxDevice::emscriptenHandleFocus(int eventType, const EmscriptenFocusEvent* event, void* userData)
{
if (eventType == EMSCRIPTEN_EVENT_FOCUS) {
theApplication().SetFocus(true);
} else if (eventType == EMSCRIPTEN_EVENT_BLUR) {
theApplication().SetFocus(false);
}
return true;
}
# endif
#endif
IGfxDevice::IGfxDevice(const WindowMode& windowMode, const GLContextInfo& glContextInfo, const DisplayMode& displayMode)
: drawableWidth_(windowMode.width), drawableHeight_(windowMode.height), width_(windowMode.width), height_(windowMode.height),
glContextInfo_(glContextInfo), isFullscreen_(windowMode.isFullscreen), displayMode_(displayMode), numMonitors_(0)
{
#if defined(DEATH_TARGET_EMSCRIPTEN)
double cssWidth = 0.0;
double cssHeight = 0.0;
// Referring to the first element of type <canvas> in the DOM
emscripten_get_element_css_size("canvas", &cssWidth, &cssHeight);
# if defined(EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3)
// `contrib.glfw3` should handle HiDPI automatically
width_ = static_cast<int>(cssWidth);
height_ = static_cast<int>(cssHeight);
# else
float pixelRatio = emscripten_get_device_pixel_ratio();
width_ = static_cast<int>(cssWidth * pixelRatio);
height_ = static_cast<int>(cssHeight * pixelRatio);
# endif
drawableWidth_ = width_;
drawableHeight_ = height_;
EmscriptenFullscreenChangeEvent fsce;
emscripten_get_fullscreen_status(&fsce);
if (isFullscreen_ != fsce.isFullscreen) {
isFullscreen_ = fsce.isFullscreen;
// TODO: Broadcast event here?
}
emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, this, true, IGfxDevice::emscriptenHandleResize);
emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, this, true, IGfxDevice::emscriptenHandleFullscreen);
# if defined(WITH_GLFW)
// GLFW does not seem to correctly handle Emscripten focus and blur events
emscripten_set_blur_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, nullptr, true, IGfxDevice::emscriptenHandleFocus);
emscripten_set_focus_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, nullptr, true, IGfxDevice::emscriptenHandleFocus);
# endif
#endif
currentVideoMode_.width = width_;
currentVideoMode_.height = height_;
currentVideoMode_.refreshRate = 0.0f;
currentVideoMode_.redBits = displayMode.redBits();
currentVideoMode_.greenBits = displayMode.greenBits();
currentVideoMode_.blueBits = displayMode.blueBits();
}
/*! \internal Having this method inlined does not seem to work correctly with Qt5 on Linux */
unsigned int IGfxDevice::numMonitors() const
{
return numMonitors_;
}
const IGfxDevice::Monitor& IGfxDevice::monitor(unsigned int index) const
{
DEATH_ASSERT(index < numMonitors_);
if (index >= numMonitors_) {
index = 0;
}
return monitors_[index];
}
float IGfxDevice::windowScalingFactor() const
{
#if defined(DEATH_TARGET_APPLE)
float factor = drawableWidth() / static_cast<float>(width());
#else
Vector2f scale = monitor().scale;
float factor = (scale.X > scale.Y ? scale.X : scale.Y);
#endif
return factor;
}
void IGfxDevice::initGLViewport()
{
GLViewport::InitRect(0, 0, drawableWidth_, drawableHeight_);
}
void IGfxDevice::setupGL()
{
glDisable(GL_DITHER);
GLBlending::SetBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
GLDepthTest::Enable();
}
}
|