21 int width,
int height,
29 inputEventGenerator_, cliComm_, videoSystem_)
31 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
32 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
33 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 0);
34#if OPENGL_VERSION == OPENGL_ES_2_0
35 #define VERSION_STRING "openGL ES 2.0"
36 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
37 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
38 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
39#elif OPENGL_VERSION == OPENGL_2_1
40 #define VERSION_STRING "openGL 2.1"
41 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
42 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
43 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
44#elif OPENGL_VERSION == OPENGL_3_3
45 #define VERSION_STRING "openGL 3.3"
46 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
47 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
48 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
51 int flags = SDL_WINDOW_OPENGL;
55 glContext = SDL_GL_CreateContext(
window.get());
72 glewExperimental = GL_TRUE;
75 GLenum glew_error = glewInit();
82 if (glew_error != GLEW_OK && glew_error != GLEW_ERROR_NO_GLX_DISPLAY) {
84 "Failed to init GLEW: ",
85 reinterpret_cast<const char*
>(
86 glewGetErrorString(glew_error)));
88 if (!GLEW_VERSION_2_1) {
94 setViewPort(
gl::ivec2(width, height), fullScreen);
101 vSyncObserver.update(
getDisplay().getRenderSettings().getVSyncSetting());
103#if OPENGL_VERSION == OPENGL_3_3
107 glGenVertexArrays(1, &vao);
108 glBindVertexArray(vao);
117 SDL_GL_DeleteContext(glContext);
133 glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, buffer.
data());
136 VLA(
const void*, rowPointers, h);
137 for (
auto i :
xrange(
size_t(h))) {
138 uint8_t* out = &buffer[4 * size_t(w) * i];
139 const uint8_t* in = out;
140 rowPointers[h - 1 - i] = out;
142 for (
auto j :
xrange(
size_t(w))) {
143 out[3 * j + 0] = in[4 * j + 0];
144 out[3 * j + 1] = in[4 * j + 1];
145 out[3 * j + 2] = in[4 * j + 2];
149 PNG::save(w, rowPointers, filename);
154 SDL_GL_SwapWindow(
window.get());
159 return std::make_unique<GLSnow>(
getDisplay());
165 const bool openGL =
true;
167 return std::make_unique<OSDConsoleRenderer>(
168 reactor, console, width, height, openGL);
173 return std::make_unique<GLOSDGUILayer>(gui);
178 return std::make_unique<SDLGLOffScreenSurface>(*
this);
181void SDLGLVisibleSurface::VSyncObserver::update(
const Setting&
setting)
noexcept
184 auto& syncSetting = visSurface.getDisplay().getRenderSettings().getVSyncSetting();
189 int interval = syncSetting.getBoolean() ? -1 : 0;
191 if ((SDL_GL_SetSwapInterval(interval) < 0) && (interval == -1)) {
195 SDL_GL_SetSwapInterval(1);
199void SDLGLVisibleSurface::setViewPort(
gl::ivec2 logicalSize,
bool fullScreen)
217 SDL_GL_GetDrawableSize(
window.get(), &w, &h);
226 glViewport(vx, vy, vw, vh);
Represents the output window/screen of openMSX.
RenderSettings & getRenderSettings()
Thrown when a subsystem initialisation fails.
const T * data() const
Returns pointer to the start of the memory buffer.
A frame buffer where pixels can be written to.
gl::ivec2 getLogicalSize() const
gl::ivec2 getViewOffset() const
void calculateViewPort(gl::ivec2 logSize, gl::ivec2 physSize)
void setOpenGlPixelFormat()
gl::ivec2 getViewSize() const
Contains the main loop of openMSX.
BooleanSetting & getVSyncSetting()
VSync [on, off] ATM this only works when using the SDLGL-PP renderer.
bool getFullScreen() const
Visible surface for SDL openGL renderers.
~SDLGLVisibleSurface() override
void fullScreenUpdated(bool fullScreen) override
void saveScreenshot(const std::string &filename) override
Save the content of this OutputSurface to a PNG file.
std::unique_ptr< Layer > createSnowLayer() override
std::unique_ptr< OutputSurface > createOffScreenSurface() override
Create an off-screen OutputSurface which has similar properties as this VisibleSurface.
std::unique_ptr< Layer > createConsoleLayer(Reactor &reactor, CommandConsole &console) override
std::unique_ptr< Layer > createOSDGUILayer(OSDGUI &gui) override
void finish() override
When a complete frame is finished, call this method.
static void saveScreenshotGL(const OutputSurface &output, const std::string &filename)
SDLGLVisibleSurface(int width, int height, Display &display, RTScheduler &rtScheduler, EventDistributor &eventDistributor, InputEventGenerator &inputEventGenerator, CliComm &cliComm, VideoSystem &videoSystem)
Common functionality for the plain SDL and SDLGL VisibleSurface classes.
void createSurface(int width, int height, unsigned flags)
void detach(Observer< T > &observer)
void attach(Observer< T > &observer)
Display & getDisplay() const
std::optional< Context > context
This file implemented 3 utility functions:
#define OUTER(type, member)
#define VLA(TYPE, NAME, LENGTH)
constexpr auto xrange(T e)