diff --git a/projectfiles/VC14/wesnoth.vcxproj b/projectfiles/VC14/wesnoth.vcxproj
index 1369694fa29e..eda2a94f55aa 100644
--- a/projectfiles/VC14/wesnoth.vcxproj
+++ b/projectfiles/VC14/wesnoth.vcxproj
@@ -2530,6 +2530,13 @@
$(IntDir)OGL\
$(IntDir)OGL\
+
+ $(IntDir)OGL\
+ $(IntDir)OGL\
+ $(IntDir)OGL\
+ $(IntDir)OGL\
+ $(IntDir)OGL\
+
$(IntDir)OGL\
$(IntDir)OGL\
@@ -3878,6 +3885,7 @@
+
diff --git a/projectfiles/VC14/wesnoth.vcxproj.filters b/projectfiles/VC14/wesnoth.vcxproj.filters
index 160ebdd0b430..bd8d7aa9a830 100644
--- a/projectfiles/VC14/wesnoth.vcxproj.filters
+++ b/projectfiles/VC14/wesnoth.vcxproj.filters
@@ -1546,6 +1546,9 @@
Gui\Dialogs
+
+ OGL
+
@@ -3005,6 +3008,9 @@
Gui\Dialogs
+
+ OGL
+
diff --git a/source_lists/libwesnoth_sdl b/source_lists/libwesnoth_sdl
index 09d83e42a4a4..2e2cba63e84d 100644
--- a/source_lists/libwesnoth_sdl
+++ b/source_lists/libwesnoth_sdl
@@ -1,4 +1,5 @@
ogl/context.cpp
+ogl/texture.cpp
ogl/utils.cpp
sdl/exception.cpp
sdl/rect.cpp
diff --git a/src/ogl/context.cpp b/src/ogl/context.cpp
index 327d18f0420d..068768cb7055 100644
--- a/src/ogl/context.cpp
+++ b/src/ogl/context.cpp
@@ -14,6 +14,7 @@
#include "ogl/context.hpp"
#include "log.hpp"
+#include "ogl/texture.hpp"
#include
#include
@@ -54,6 +55,13 @@ void context::init(sdl::window* window)
throw std::runtime_error("error initializing GLEW");
}
+ int maxTextureSize;
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
+ if(maxTextureSize < texture::MAX_DIMENSION) {
+ ERR_GL << "Too low texture size limit\n";
+ throw std::runtime_error("too low texture size limit");
+ }
+
// Print some information.
GLint profile;
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &profile);
diff --git a/src/ogl/texture.cpp b/src/ogl/texture.cpp
new file mode 100644
index 000000000000..233fe86f9535
--- /dev/null
+++ b/src/ogl/texture.cpp
@@ -0,0 +1,62 @@
+/*
+ Copyright (C) 2018 by Jyrki Vesterinen
+
+ This program 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; either version 2 of the License, or
+ (at your option) any later version.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY.
+
+ See the COPYING file for more details.
+*/
+
+#include "ogl/texture.hpp"
+
+#include
+
+#include
+#include
+
+namespace gl
+{
+
+std::pair texture::get_size() const
+{
+ std::pair size;
+ glBindTexture(GL_TEXTURE_2D, name_);
+ glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &size.first);
+ glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &size.second);
+ glBindTexture(GL_TEXTURE_2D, 0u);
+ return size;
+}
+
+void texture::set_size(const std::pair& size)
+{
+ if(size.first > MAX_DIMENSION || size.second > MAX_DIMENSION) {
+ throw std::invalid_argument("Too large texture size");
+ }
+
+ glBindTexture(GL_TEXTURE_2D, name_);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, size.first, size.second, 0,
+ GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
+ glBindTexture(GL_TEXTURE_2D, 0u);
+}
+
+void texture::set_pixels(surface pixels)
+{
+ assert(check_format(*pixels->format));
+ surface_locker lock(pixels);
+
+ glBindTexture(GL_TEXTURE_2D, name_);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pixels->w, pixels->h,
+ GL_BGRA, GL_UNSIGNED_BYTE, lock.pixels());
+ glBindTexture(GL_TEXTURE_2D, 0u);
+}
+
+bool texture::check_format(const SDL_PixelFormat& format)
+{
+ return format.format == SDL_PIXELFORMAT_ARGB8888;
+}
+
+}
\ No newline at end of file
diff --git a/src/ogl/texture.hpp b/src/ogl/texture.hpp
new file mode 100644
index 000000000000..33be60fda380
--- /dev/null
+++ b/src/ogl/texture.hpp
@@ -0,0 +1,80 @@
+/*
+ Copyright (C) 2018 by Jyrki Vesterinen
+
+ This program 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; either version 2 of the License, or
+ (at your option) any later version.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY.
+
+ See the COPYING file for more details.
+*/
+
+#pragma once
+
+#include "sdl/surface.hpp"
+
+#include
+
+#include
+
+namespace gl
+{
+/// Thin wrapper for textures.
+/// All textures are two-dimensional and in the RGBA8 format.
+class texture
+{
+public:
+ static const int MAX_DIMENSION = 8192;
+
+ /** Constructor.
+ Initial texture size is 0x0. Use set_size() to actually allocate memory for
+ the texture. */
+ texture()
+ {
+ glGenTextures(1, &name_);
+ // Bind the texture as 2D to make it two-dimensional.
+ glBindTexture(GL_TEXTURE_2D, name_);
+ // Unbind the 2D texture target.
+ glBindTexture(GL_TEXTURE_2D, 0u);
+ }
+
+ /// Destructor.
+ ~texture()
+ {
+ glDeleteTextures(1, &name_);
+ }
+
+ /** @return the OpenGL texture name.
+ It can be passed directly to the OpenGL API.
+ The name of a texture does not change and can be safely cached.
+ */
+ GLuint get_name() const
+ {
+ return name_;
+ }
+
+ /// @return the size of the texture.
+ std::pair get_size() const;
+
+ /** Resizes the texture.
+ @param size Desired texture size.
+ Invalidates existing content of the texture, if any.
+ @note Maximum texture size is 8192x8192. It's enforced both ways: Wesnoth refuses
+ to launch if the hardware doesn't support 8192x8192 textures, but it doesn't allow
+ larger textures even if the hardware supports them. */
+ void set_size(const std::pair& size);
+
+ /** Uploads the provided texture data.
+ @param pixels Texture data. */
+ void set_pixels(surface pixels);
+
+private:
+ /// OpenGL texture name.
+ GLuint name_;
+
+ /// Checks that the SDL surface format matches the format we expect.
+ static bool check_format(const SDL_PixelFormat& format);
+};
+}