Changeset - r24917:32c68f7840b0
[Not reviewed]
master
0 1 2
Patric Stout - 3 years ago 2021-01-17 14:46:38
truebrain@openttd.org
Feature: [SDL2] OpenGL support
3 files changed with 222 insertions and 0 deletions:
0 comments (0 inline, 0 general)
src/video/CMakeLists.txt
Show inline comments
 
@@ -26,6 +26,12 @@ if(NOT OPTION_DEDICATED)
 
    )
 

	
 
    add_files(
 
        sdl2_opengl_v.cpp
 
        sdl2_opengl_v.h
 
        CONDITION SDL2_FOUND AND OPENGL_FOUND
 
    )
 

	
 
    add_files(
 
        win32_v.cpp
 
        win32_v.h
 
        CONDITION WIN32
src/video/sdl2_opengl_v.cpp
Show inline comments
 
new file 100644
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file sdl2_opengl_v.cpp Implementation of the OpenGL backend for SDL2 video driver. */
 

	
 
/* XXX -- Temporary hack for Windows compile */
 
#define WINGDIAPI
 
#define APIENTRY
 

	
 
#include "../stdafx.h"
 
#include "../openttd.h"
 
#include "../gfx_func.h"
 
#include "../rev.h"
 
#include "../blitter/factory.hpp"
 
#include "../network/network.h"
 
#include "../thread.h"
 
#include "../progress.h"
 
#include "../core/random_func.hpp"
 
#include "../core/math_func.hpp"
 
#include "../core/mem_func.hpp"
 
#include "../core/geometry_func.hpp"
 
#include "../fileio_func.h"
 
#include "../framerate_type.h"
 
#include "../window_func.h"
 
#include "sdl2_opengl_v.h"
 
#include <SDL.h>
 
#include <mutex>
 
#include <condition_variable>
 
#include <GL/gl.h>
 
#include "../3rdparty/opengl/glext.h"
 
#include "opengl.h"
 
#ifdef __EMSCRIPTEN__
 
#	include <emscripten.h>
 
#	include <emscripten/html5.h>
 
#endif
 

	
 
#include "../safeguards.h"
 

	
 
static FVideoDriver_SDL_OpenGL iFVideoDriver_SDL_OpenGL;
 

	
 
/** Platform-specific callback to get an OpenGL funtion pointer. */
 
static OGLProc GetOGLProcAddressCallback(const char *proc)
 
{
 
	return reinterpret_cast<OGLProc>(SDL_GL_GetProcAddress(proc));
 
}
 

	
 
bool VideoDriver_SDL_OpenGL::CreateMainWindow(uint w, uint h, uint flags)
 
{
 
	return this->VideoDriver_SDL::CreateMainWindow(w, h, SDL_WINDOW_OPENGL);
 
}
 

	
 
const char *VideoDriver_SDL_OpenGL::Start(const StringList &param)
 
{
 
	const char *error = VideoDriver_SDL::Start(param);
 
	if (error != nullptr) return error;
 

	
 
	error = this->AllocateContext();
 
	if (error != nullptr) {
 
		this->Stop();
 
		return error;
 
	}
 

	
 
	/* Now we have a OpenGL context, force a client-size-changed event,
 
	 * so all buffers are allocated correctly. */
 
	int w, h;
 
	SDL_GetWindowSize(this->sdl_window, &w, &h);
 
	this->ClientSizeChanged(w, h, true);
 

	
 
	SDL_GL_SetSwapInterval(GetDriverParamBool(param, "vsync") ? 1 : 0);
 
	this->draw_threaded = false;
 

	
 
	return nullptr;
 
}
 

	
 
void VideoDriver_SDL_OpenGL::Stop()
 
{
 
	this->DestroyContext();
 
	this->VideoDriver_SDL::Stop();
 
}
 

	
 
void VideoDriver_SDL_OpenGL::DestroyContext()
 
{
 
	OpenGLBackend::Destroy();
 

	
 
	if (this->gl_context != nullptr) {
 
		SDL_GL_DeleteContext(this->gl_context);
 
		this->gl_context = nullptr;
 
	}
 
}
 

	
 
const char *VideoDriver_SDL_OpenGL::AllocateContext()
 
{
 
	this->gl_context = SDL_GL_CreateContext(this->sdl_window);
 
	if (this->gl_context == nullptr) return "SDL2: Can't active GL context";
 

	
 
	return OpenGLBackend::Create(&GetOGLProcAddressCallback);
 
}
 

	
 
void VideoDriver_SDL_OpenGL::ClearSystemSprites()
 
{
 
	OpenGLBackend::Get()->ClearCursorCache();
 
}
 

	
 
bool VideoDriver_SDL_OpenGL::AllocateBackingStore(int w, int h, bool force)
 
{
 
	if (this->gl_context == nullptr) return false;
 

	
 
	if (_screen.dst_ptr != nullptr) this->ReleaseVideoPointer();
 

	
 
	w = std::max(w, 64);
 
	h = std::max(h, 64);
 
	MemSetT(&this->dirty_rect, 0);
 

	
 
	bool res = OpenGLBackend::Get()->Resize(w, h, force);
 
	_screen.dst_ptr = this->GetVideoPointer();
 

	
 
	_cur_palette.first_dirty = 0;
 
	_cur_palette.count_dirty = 256;
 
	this->local_palette = _cur_palette;
 

	
 
	return res;
 
}
 

	
 
void *VideoDriver_SDL_OpenGL::GetVideoPointer()
 
{
 
	if (BlitterFactory::GetCurrentBlitter()->NeedsAnimationBuffer()) {
 
		this->anim_buffer = OpenGLBackend::Get()->GetAnimBuffer();
 
	}
 
	return OpenGLBackend::Get()->GetVideoBuffer();
 
}
 

	
 
void VideoDriver_SDL_OpenGL::ReleaseVideoPointer()
 
{
 
	if (this->anim_buffer != nullptr) OpenGLBackend::Get()->ReleaseAnimBuffer(this->dirty_rect);
 
	OpenGLBackend::Get()->ReleaseVideoBuffer(this->dirty_rect);
 
	MemSetT(&this->dirty_rect, 0);
 
	this->anim_buffer = nullptr;
 
}
 

	
 
void VideoDriver_SDL_OpenGL::Paint()
 
{
 
	PerformanceMeasurer framerate(PFE_VIDEO);
 

	
 
	if (_cur_palette.count_dirty != 0) {
 
		Blitter *blitter = BlitterFactory::GetCurrentBlitter();
 

	
 
		/* Always push a changed palette to OpenGL. */
 
		OpenGLBackend::Get()->UpdatePalette(this->local_palette.palette, this->local_palette.first_dirty, this->local_palette.count_dirty);
 
		if (blitter->UsePaletteAnimation() == Blitter::PALETTE_ANIMATION_BLITTER) {
 
			blitter->PaletteAnimate(this->local_palette);
 
		}
 

	
 
		_cur_palette.count_dirty = 0;
 
	}
 

	
 
	OpenGLBackend::Get()->Paint();
 
	if (_cursor.in_window) OpenGLBackend::Get()->DrawMouseCursor();
 

	
 
	SDL_GL_SwapWindow(this->sdl_window);
 
}
src/video/sdl2_opengl_v.h
Show inline comments
 
new file 100644
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file sdl2_opengl_v.h OpenGL backend of the SDL2 video driver. */
 

	
 
#include "sdl2_v.h"
 

	
 
/** The OpenGL video driver for windows. */
 
class VideoDriver_SDL_OpenGL : public VideoDriver_SDL {
 
public:
 
	VideoDriver_SDL_OpenGL() : gl_context(nullptr), anim_buffer(nullptr) {}
 

	
 
	const char *Start(const StringList &param) override;
 

	
 
	void Stop() override;
 

	
 
	bool HasEfficient8Bpp() const override { return true; }
 

	
 
	bool UseSystemCursor() override { return true; }
 

	
 
	void ClearSystemSprites() override;
 

	
 
	bool HasAnimBuffer() override { return true; }
 
	uint8 *GetAnimBuffer() override { return this->anim_buffer; }
 

	
 
	const char *GetName() const override { return "sdl-opengl"; }
 

	
 
protected:
 
	bool AllocateBackingStore(int w, int h, bool force = false) override;
 
	void *GetVideoPointer() override;
 
	void ReleaseVideoPointer() override;
 
	void Paint() override;
 
	bool CreateMainWindow(uint w, uint h, uint flags) override;
 

	
 
private:
 
	void  *gl_context;  ///< OpenGL context.
 
	uint8 *anim_buffer; ///< Animation buffer from OpenGL back-end.
 

	
 
	const char *AllocateContext();
 
	void DestroyContext();
 
};
 

	
 
/** The factory for SDL' OpenGL video driver. */
 
class FVideoDriver_SDL_OpenGL : public DriverFactoryBase {
 
public:
 
	FVideoDriver_SDL_OpenGL() : DriverFactoryBase(Driver::DT_VIDEO, 8, "sdl-opengl", "SDL OpenGL Video Driver") {}
 
	/* virtual */ Driver *CreateInstance() const override { return new VideoDriver_SDL_OpenGL(); }
 
};
0 comments (0 inline, 0 general)