X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fgraphics%2Frender.cpp;h=9468b68b794b8640558c986870f885c5e171c26d;hb=2e3774eb3f2d5d23a08731175b168566457e2192;hp=470cb191f4185ca893bdd683158b84e4042fbb15;hpb=7bb75960dbf9bfdee9ac865384aca81791b3da5c;p=blank.git diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 470cb19..9468b68 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -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 +TextureBase::TextureBase() { + glGenTextures(COUNT, handle); +} + +template +TextureBase::~TextureBase() { + glDeleteTextures(COUNT, handle); +} + +template +TextureBase::TextureBase(TextureBase &&other) noexcept { + std::memcpy(handle, other.handle, sizeof(handle)); + std::memset(other.handle, 0, sizeof(handle)); +} + +template +TextureBase &TextureBase::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,60 @@ 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() { + +} + +CubeMap::~CubeMap() { + +} + +CubeMap::CubeMap(CubeMap &&other) noexcept +: TextureBase(std::move(other)) { + } -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::operator =(CubeMap &&other) noexcept { + TextureBase::operator =(std::move(other)); + return *this; +} + + +void CubeMap::Data(Face f, const SDL_Surface &srf) { + Format format; + Format fmt(*srf.format); + if (format.Compatible(fmt)) { + Data(f, srf.w, srf.h, fmt, srf.pixels); + } else { + SDL_Surface *converted = SDL_ConvertSurface( + const_cast(&srf), + &format.sdl_format, + 0 + ); + if (!converted) { + throw SDLError("SDL_ConvertSurface"); + } + Format new_fmt(*converted->format); + if (!format.Compatible(new_fmt)) { + SDL_FreeSurface(converted); + throw std::runtime_error("unable to convert texture input"); + } + Data(f, converted->w, converted->h, new_fmt, converted->pixels); + SDL_FreeSurface(converted); + } } -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); +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 + ); } }