]> git.localhorst.tv Git - blank.git/commitdiff
cube map textures
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 23 Sep 2015 09:41:39 +0000 (11:41 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 23 Sep 2015 15:32:14 +0000 (17:32 +0200)
src/app/Assets.hpp
src/app/app.cpp
src/graphics/ArrayTexture.hpp
src/graphics/CubeMap.hpp [new file with mode: 0644]
src/graphics/Format.hpp
src/graphics/Texture.hpp
src/graphics/TextureBase.hpp [new file with mode: 0644]
src/graphics/render.cpp

index d1a4ae710d0cc832fbcb155b2756eebcc9718cba..db0933f961c1520156d52caecb060cc3c753d22e 100644 (file)
@@ -10,6 +10,7 @@ namespace blank {
 
 class ArrayTexture;
 class BlockTypeRegistry;
+class CubeMap;
 class Sound;
 class Texture;
 class TextureIndex;
@@ -20,6 +21,7 @@ public:
        explicit AssetLoader(const std::string &base);
 
        void LoadBlockTypes(const std::string &set_name, BlockTypeRegistry &, TextureIndex &) const;
+       CubeMap LoadCubeMap(const std::string &name) const;
        Font LoadFont(const std::string &name, int size) const;
        Sound LoadSound(const std::string &name) const;
        Texture LoadTexture(const std::string &name) const;
index 4368022eb59dbddc5c981f9e5e172af4af8f56cf..6e7201a6f9b2239405255d2413aa0f06dca35007 100644 (file)
@@ -9,6 +9,7 @@
 #include "init.hpp"
 #include "../audio/Sound.hpp"
 #include "../graphics/ArrayTexture.hpp"
+#include "../graphics/CubeMap.hpp"
 #include "../graphics/Font.hpp"
 #include "../graphics/Texture.hpp"
 #include "../io/TokenStreamReader.hpp"
@@ -374,6 +375,45 @@ void AssetLoader::LoadBlockTypes(const std::string &set_name, BlockTypeRegistry
        }
 }
 
+CubeMap AssetLoader::LoadCubeMap(const string &name) const {
+       string full = textures + name;
+       string right = full + "-right.png";
+       string left = full + "-left.png";
+       string top = full + "-top.png";
+       string bottom = full + "-bottom.png";
+       string back = full + "-back.png";
+       string front = full + "-front.png";
+
+       CubeMap cm;
+       SDL_Surface *srf;
+
+       if (!(srf = IMG_Load(right.c_str()))) throw SDLError("IMG_Load");
+       cm.Data(CubeMap::RIGHT, *srf);
+       SDL_FreeSurface(srf);
+
+       if (!(srf = IMG_Load(left.c_str()))) throw SDLError("IMG_Load");
+       cm.Data(CubeMap::LEFT, *srf);
+       SDL_FreeSurface(srf);
+
+       if (!(srf = IMG_Load(top.c_str()))) throw SDLError("IMG_Load");
+       cm.Data(CubeMap::TOP, *srf);
+       SDL_FreeSurface(srf);
+
+       if (!(srf = IMG_Load(bottom.c_str()))) throw SDLError("IMG_Load");
+       cm.Data(CubeMap::BOTTOM, *srf);
+       SDL_FreeSurface(srf);
+
+       if (!(srf = IMG_Load(back.c_str()))) throw SDLError("IMG_Load");
+       cm.Data(CubeMap::BACK, *srf);
+       SDL_FreeSurface(srf);
+
+       if (!(srf = IMG_Load(front.c_str()))) throw SDLError("IMG_Load");
+       cm.Data(CubeMap::FRONT, *srf);
+       SDL_FreeSurface(srf);
+
+       return cm;
+}
+
 Font AssetLoader::LoadFont(const string &name, int size) const {
        string full = fonts + name + ".ttf";
        return Font(full.c_str(), size);
index 93b560e3ad2b4bd852e81331563771749a83d16e..3adb44e6461422bc598165ea7b18ba5bfaf045d5 100644 (file)
@@ -2,6 +2,7 @@
 #define BLANK_GRAPHICS_ARRAYTEXTURE_HPP_
 
 #include "Format.hpp"
+#include "TextureBase.hpp"
 
 #include <GL/glew.h>
 
@@ -10,7 +11,8 @@ struct SDL_Surface;
 
 namespace blank {
 
-class ArrayTexture {
+class ArrayTexture
+: public TextureBase<GL_TEXTURE_2D_ARRAY> {
 
 public:
        ArrayTexture();
@@ -27,19 +29,11 @@ public:
        GLsizei Height() const noexcept { return height; }
        GLsizei Depth() const noexcept { return depth; }
 
-       void Bind() noexcept;
-
        void Reserve(GLsizei w, GLsizei h, GLsizei d, const Format &) noexcept;
        void Data(GLsizei l, const SDL_Surface &);
        void Data(GLsizei l, const Format &, GLvoid *data) noexcept;
 
-       void FilterNearest() noexcept;
-       void FilterLinear() noexcept;
-       void FilterTrilinear() noexcept;
-
 private:
-       GLuint handle;
-
        GLsizei width, height, depth;
 
        Format format;
diff --git a/src/graphics/CubeMap.hpp b/src/graphics/CubeMap.hpp
new file mode 100644 (file)
index 0000000..b328196
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef BLANK_GRAPHICS_CUBEMAP_HPP_
+#define BLANK_GRAPHICS_CUBEMAP_HPP_
+
+#include "Format.hpp"
+#include "TextureBase.hpp"
+
+#include <GL/glew.h>
+
+struct SDL_Surface;
+
+
+namespace blank {
+
+class CubeMap
+: public TextureBase<GL_TEXTURE_CUBE_MAP> {
+
+public:
+       enum Face {
+               RIGHT = GL_TEXTURE_CUBE_MAP_POSITIVE_X,
+               LEFT = GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
+               TOP = GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
+               BOTTOM = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
+               BACK = GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
+               FRONT = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
+       };
+
+public:
+       CubeMap();
+       ~CubeMap();
+
+       CubeMap(CubeMap &&) noexcept;
+       CubeMap &operator =(CubeMap &&) noexcept;
+
+       CubeMap(const CubeMap &) = delete;
+       CubeMap &operator =(const CubeMap &) = delete;
+
+public:
+       void Data(Face, const SDL_Surface &) noexcept;
+       void Data(Face, GLsizei w, GLsizei h, const Format &, GLvoid *data) noexcept;
+
+};
+
+}
+
+#endif
index 5762aab6c13a374da74b6cc6c86b938545e6ef53..194cc1c8c1c3241cee1c52f64e94b0d601823f72 100644 (file)
@@ -15,8 +15,8 @@ struct Format {
 
        SDL_PixelFormat sdl_format;
 
-       Format();
-       explicit Format(const SDL_PixelFormat &);
+       Format() noexcept;
+       explicit Format(const SDL_PixelFormat &) noexcept;
 
        bool Compatible(const Format &other) const noexcept;
 
index 9e24a8dc873882e85904acb07928b2eb7f6b3313..f8388080675986aeec6c0e15b61f5b0a920b9270 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef BLANK_GRAPHICS_TEXTURE_HPP_
 #define BLANK_GRAPHICS_TEXTURE_HPP_
 
+#include "TextureBase.hpp"
+
 #include <GL/glew.h>
 
 struct SDL_Surface;
@@ -10,7 +12,8 @@ namespace blank {
 
 struct Format;
 
-class Texture {
+class Texture
+: public TextureBase<GL_TEXTURE_2D> {
 
 public:
        Texture();
@@ -26,22 +29,14 @@ public:
        GLsizei Width() const noexcept { return width; }
        GLsizei Height() const noexcept { return height; }
 
-       void Bind() noexcept;
-
        void Data(const SDL_Surface &, bool pad2 = true) noexcept;
        void Data(GLsizei w, GLsizei h, const Format &, GLvoid *data) noexcept;
 
-       void FilterNearest() noexcept;
-       void FilterLinear() noexcept;
-       void FilterTrilinear() noexcept;
-
        static void UnpackAlignment(GLint) noexcept;
        static int UnpackAlignmentFromPitch(int) noexcept;
        static void UnpackRowLength(GLint) noexcept;
 
 private:
-       GLuint handle;
-
        GLsizei width, height;
 
 };
diff --git a/src/graphics/TextureBase.hpp b/src/graphics/TextureBase.hpp
new file mode 100644 (file)
index 0000000..4c3e8a8
--- /dev/null
@@ -0,0 +1,69 @@
+#ifndef BLANK_GRAPHICS_TEXTUREBASE_HPP_
+#define BLANK_GRAPHICS_TEXTUREBASE_HPP_
+
+#include <GL/glew.h>
+
+
+namespace blank {
+
+template<GLenum TARGET, GLsizei COUNT = 1>
+class TextureBase {
+
+public:
+       TextureBase();
+       ~TextureBase();
+
+       TextureBase(TextureBase &&other) noexcept;
+       TextureBase &operator =(TextureBase &&) noexcept;
+
+       TextureBase(const TextureBase &) = delete;
+       TextureBase &operator =(const TextureBase &) = delete;
+
+public:
+       void Bind(GLsizei which = 0) noexcept {
+               glBindTexture(TARGET, handle[which]);
+       }
+
+       void FilterNearest() noexcept {
+               glTexParameteri(TARGET, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+               glTexParameteri(TARGET, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+       }
+       void FilterLinear() noexcept {
+               glTexParameteri(TARGET, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+               glTexParameteri(TARGET, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+       }
+       void FilterTrilinear() noexcept {
+               glTexParameteri(TARGET, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+               glTexParameteri(TARGET, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+               glGenerateMipmap(TARGET);
+       }
+
+       void WrapEdge() noexcept {
+               glTexParameteri(TARGET, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+               glTexParameteri(TARGET, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+               glTexParameteri(TARGET, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+       }
+       void WrapBorder() noexcept {
+               glTexParameteri(TARGET, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER);
+               glTexParameteri(TARGET, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
+               glTexParameteri(TARGET, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+       }
+       void WrapRepeat() noexcept {
+               glTexParameteri(TARGET, GL_TEXTURE_WRAP_R, GL_REPEAT);
+               glTexParameteri(TARGET, GL_TEXTURE_WRAP_S, GL_REPEAT);
+               glTexParameteri(TARGET, GL_TEXTURE_WRAP_T, GL_REPEAT);
+       }
+       void WrapMirror() noexcept {
+               glTexParameteri(TARGET, GL_TEXTURE_WRAP_R, GL_MIRRORED_REPEAT);
+               glTexParameteri(TARGET, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
+               glTexParameteri(TARGET, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
+       }
+
+private:
+       GLuint handle[COUNT];
+
+};
+
+}
+
+#endif
index 470cb191f4185ca893bdd683158b84e4042fbb15..fdf751e4248390e6f2b37a80a9707b139953e5cc 100644 (file)
@@ -1,7 +1,9 @@
 #include "ArrayTexture.hpp"
+#include "CubeMap.hpp"
 #include "Font.hpp"
 #include "Format.hpp"
 #include "Texture.hpp"
+#include "TextureBase.hpp"
 #include "Viewport.hpp"
 
 #include "../app/init.hpp"
@@ -128,7 +130,7 @@ void Font::Render(const char *text, Texture &tex) const {
        SDL_FreeSurface(srf);
 }
 
-Format::Format()
+Format::Format() noexcept
 : format(GL_BGRA)
 , type(GL_UNSIGNED_INT_8_8_8_8_REV)
 , internal(GL_RGBA8) {
@@ -152,7 +154,7 @@ Format::Format()
        sdl_format.next = nullptr;
 }
 
-Format::Format(const SDL_PixelFormat &fmt)
+Format::Format(const SDL_PixelFormat &fmt) noexcept
 : sdl_format(fmt) {
        if (fmt.BytesPerPixel == 4) {
                if (fmt.Amask == 0xFF) {
@@ -187,38 +189,54 @@ bool Format::Compatible(const Format &other) const noexcept {
 }
 
 
+template<GLenum TARGET, GLsizei COUNT>
+TextureBase<TARGET, COUNT>::TextureBase() {
+       glGenTextures(COUNT, handle);
+}
+
+template<GLenum TARGET, GLsizei COUNT>
+TextureBase<TARGET, COUNT>::~TextureBase() {
+       glDeleteTextures(COUNT, handle);
+}
+
+template<GLenum TARGET, GLsizei COUNT>
+TextureBase<TARGET, COUNT>::TextureBase(TextureBase &&other) noexcept {
+       std::memcpy(handle, other.handle, sizeof(handle));
+       std::memset(other.handle, 0, sizeof(handle));
+}
+
+template<GLenum TARGET, GLsizei COUNT>
+TextureBase<TARGET, COUNT> &TextureBase<TARGET, COUNT>::operator =(TextureBase &&other) noexcept {
+       std::swap(handle, other.handle);
+       return *this;
+}
+
+
 Texture::Texture()
-: handle(0)
+: TextureBase()
 , width(0)
 , height(0) {
-       glGenTextures(1, &handle);
+
 }
 
 Texture::~Texture() {
-       if (handle != 0) {
-               glDeleteTextures(1, &handle);
-       }
+
 }
 
 Texture::Texture(Texture &&other) noexcept
-: handle(other.handle) {
-       other.handle = 0;
+: TextureBase(std::move(other)) {
        width = other.width;
        height = other.height;
 }
 
 Texture &Texture::operator =(Texture &&other) noexcept {
-       std::swap(handle, other.handle);
+       TextureBase::operator =(std::move(other));
        width = other.width;
        height = other.height;
        return *this;
 }
 
 
-void Texture::Bind() noexcept {
-       glBindTexture(GL_TEXTURE_2D, handle);
-}
-
 namespace {
        bool ispow2(unsigned int i) {
                // don't care about i == 0 here
@@ -289,25 +307,6 @@ void Texture::Data(GLsizei w, GLsizei h, const Format &format, GLvoid *data) noe
 }
 
 
-void Texture::FilterNearest() noexcept {
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-}
-
-void Texture::FilterLinear() noexcept {
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-}
-
-void Texture::FilterTrilinear() noexcept {
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
-       glGenerateMipmap(GL_TEXTURE_2D);
-}
-
-
 void Texture::UnpackAlignment(GLint i) noexcept {
        glPixelStorei(GL_UNPACK_ALIGNMENT, i);
 }
@@ -327,29 +326,26 @@ void Texture::UnpackRowLength(GLint i) noexcept {
 
 
 ArrayTexture::ArrayTexture()
-: handle(0)
+: TextureBase()
 , width(0)
 , height(0)
 , depth(0) {
-       glGenTextures(1, &handle);
+
 }
 
 ArrayTexture::~ArrayTexture() {
-       if (handle != 0) {
-               glDeleteTextures(1, &handle);
-       }
+
 }
 
 ArrayTexture::ArrayTexture(ArrayTexture &&other) noexcept
-: handle(other.handle) {
-       other.handle = 0;
+: TextureBase(std::move(other)) {
        width = other.width;
        height = other.height;
        depth = other.depth;
 }
 
 ArrayTexture &ArrayTexture::operator =(ArrayTexture &&other) noexcept {
-       std::swap(handle, other.handle);
+       TextureBase::operator =(std::move(other));
        width = other.width;
        height = other.height;
        depth = other.depth;
@@ -357,11 +353,6 @@ ArrayTexture &ArrayTexture::operator =(ArrayTexture &&other) noexcept {
 }
 
 
-void ArrayTexture::Bind() noexcept {
-       glBindTexture(GL_TEXTURE_2D_ARRAY, handle);
-}
-
-
 void ArrayTexture::Reserve(GLsizei w, GLsizei h, GLsizei d, const Format &f) noexcept {
        glTexStorage3D(
                GL_TEXTURE_2D_ARRAY, // which
@@ -413,22 +404,40 @@ void ArrayTexture::Data(GLsizei l, const Format &f, GLvoid *data) noexcept {
 }
 
 
-void ArrayTexture::FilterNearest() noexcept {
-       glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-       glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+CubeMap::CubeMap()
+: TextureBase() {
+
 }
 
-void ArrayTexture::FilterLinear() noexcept {
-       glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-       glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+CubeMap::~CubeMap() {
+
 }
 
-void ArrayTexture::FilterTrilinear() noexcept {
-       glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
-       glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
-       glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-       glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
-       glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
+CubeMap::CubeMap(CubeMap &&other) noexcept
+: TextureBase(std::move(other)) {
+
+}
+
+CubeMap &CubeMap::operator =(CubeMap &&other) noexcept {
+       TextureBase::operator =(std::move(other));
+       return *this;
+}
+
+
+void CubeMap::Data(Face f, const SDL_Surface &srf) noexcept {
+       Data(f, srf.w, srf.h, Format(*srf.format), srf.pixels);
+}
+
+void CubeMap::Data(Face face, GLsizei w, GLsizei h, const Format &f, GLvoid *data) noexcept {
+       glTexImage2D(
+               face,             // which
+               0,                // mipmap level
+               f.internal,       // internal format
+               w, h,             // size
+               0,                // border
+               f.format, f.type, // pixel format
+               data              // pixel data
+       );
 }
 
 }