class ArrayTexture;
class BlockTypeRegistry;
+class CubeMap;
class Sound;
class Texture;
class TextureIndex;
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;
#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"
}
}
+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);
#define BLANK_GRAPHICS_ARRAYTEXTURE_HPP_
#include "Format.hpp"
+#include "TextureBase.hpp"
#include <GL/glew.h>
namespace blank {
-class ArrayTexture {
+class ArrayTexture
+: public TextureBase<GL_TEXTURE_2D_ARRAY> {
public:
ArrayTexture();
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;
--- /dev/null
+#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
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;
#ifndef BLANK_GRAPHICS_TEXTURE_HPP_
#define BLANK_GRAPHICS_TEXTURE_HPP_
+#include "TextureBase.hpp"
+
#include <GL/glew.h>
struct SDL_Surface;
struct Format;
-class Texture {
+class Texture
+: public TextureBase<GL_TEXTURE_2D> {
public:
Texture();
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;
};
--- /dev/null
+#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
#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"
SDL_FreeSurface(srf);
}
-Format::Format()
+Format::Format() noexcept
: format(GL_BGRA)
, type(GL_UNSIGNED_INT_8_8_8_8_REV)
, internal(GL_RGBA8) {
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) {
}
+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
}
-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);
}
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;
}
-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
}
-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
+ );
}
}