diff --git a/src/MultiImageVisualisation.cpp b/src/MultiImageVisualisation.cpp index fb84795..792505b 100644 --- a/src/MultiImageVisualisation.cpp +++ b/src/MultiImageVisualisation.cpp @@ -49,18 +49,13 @@ MultiImageVisualisation::MultiImageVisualisation(const fmri::LayerData &layer) } } -MultiImageVisualisation::~MultiImageVisualisation() -{ - glDeleteTextures(0, &texture); -} - void MultiImageVisualisation::render() { glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); glEnable(GL_TEXTURE_2D); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - glBindTexture(GL_TEXTURE_2D, texture); + texture.bind(GL_TEXTURE_2D); glTexCoordPointer(2, GL_FLOAT, 0, texCoordBuffer.get()); glVertexPointer(3, GL_FLOAT, 0, vertexBuffer.get()); glDrawArrays(GL_QUADS, 0, nodePositions_.size() / 3 * 4); diff --git a/src/MultiImageVisualisation.hpp b/src/MultiImageVisualisation.hpp index 6ebf0dd..c19aec7 100644 --- a/src/MultiImageVisualisation.hpp +++ b/src/MultiImageVisualisation.hpp @@ -5,6 +5,7 @@ #include #include "LayerVisualisation.hpp" #include "LayerData.hpp" +#include "Texture.hpp" namespace fmri { @@ -12,7 +13,6 @@ namespace fmri { public: explicit MultiImageVisualisation(const LayerData&); - ~MultiImageVisualisation() override; void render() override; @@ -23,7 +23,7 @@ namespace fmri 0, 1, 1, 0, -1, 1, }; - GLuint texture; + Texture texture; std::unique_ptr vertexBuffer; std::unique_ptr texCoordBuffer; }; diff --git a/src/Texture.cpp b/src/Texture.cpp new file mode 100644 index 0000000..fb69529 --- /dev/null +++ b/src/Texture.cpp @@ -0,0 +1,36 @@ +#include +#include "Texture.hpp" + +using namespace fmri; + +Texture::Texture() noexcept +{ + glGenTextures(1, &id); +} + +Texture::Texture(GLuint id) noexcept : id(id) +{ +} + +Texture::~Texture() +{ + if (id != 0) { + glDeleteTextures(1, &id); + } +} + +Texture &Texture::operator=(Texture && other) noexcept +{ + std::swap(id, other.id); + return *this; +} + +Texture::Texture(Texture && other) noexcept +{ + std::swap(id, other.id); +} + +void Texture::bind(GLenum target) const +{ + glBindTexture(target, id); +} diff --git a/src/Texture.hpp b/src/Texture.hpp new file mode 100644 index 0000000..7e71f20 --- /dev/null +++ b/src/Texture.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include + +namespace fmri +{ + /** + * Simple owning Texture class. + * + * Encapsulates an OpenGL texture, and enables RAII for it. Copying + * is disallowed for this reason. + */ + class Texture + { + public: + /** + * Allocate a new texture + */ + Texture() noexcept; + Texture(Texture &&) noexcept; + Texture(const Texture &) = delete; + + /** + * Own an existing texture + * @param id original texture ID. + */ + explicit Texture(GLuint id) noexcept; + + ~Texture(); + + Texture &operator=(Texture &&) noexcept; + Texture &operator=(const Texture &) = delete; + + /** + * Bind the owned texture to the given spot. + * @param target valid target for glBindTexture. + */ + void bind(GLenum target) const; + + private: + GLuint id; + + }; +} diff --git a/src/glutils.cpp b/src/glutils.cpp index d86e3e5..0cf6adb 100644 --- a/src/glutils.cpp +++ b/src/glutils.cpp @@ -8,6 +8,7 @@ #include #include "glutils.hpp" #include "Range.hpp" +#include "Texture.hpp" using namespace fmri; using namespace std; @@ -32,17 +33,16 @@ static void rescaleSubImages(vector& textureBuffer, int subImages) { } } -GLuint fmri::loadTexture(DType const *data, int width, int height, int subImages) +fmri::Texture fmri::loadTexture(DType const *data, int width, int height, int subImages) { // Load and scale texture vector textureBuffer(data, data + (width * height)); rescaleSubImages(textureBuffer, subImages); const float color[] = {1, 1, 1}; // Background color for textures. - GLuint texture; - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); + Texture texture; + texture.bind(GL_TEXTURE_2D); // Set up (lack of) repetition glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER); diff --git a/src/glutils.hpp b/src/glutils.hpp index a42e29a..739f74e 100644 --- a/src/glutils.hpp +++ b/src/glutils.hpp @@ -2,6 +2,7 @@ #include "LayerData.hpp" #include "utils.hpp" +#include "Texture.hpp" #include #include @@ -15,7 +16,7 @@ namespace fmri { * @param subImages Number of subimages in the original image. Sub images are rescaled individually to preserve contrast. Optional, default 1. * @return A texture reference. */ - GLuint loadTexture(DType const *data, int width, int height, int subImages = 1); + fmri::Texture loadTexture(DType const *data, int width, int height, int subImages = 1); /** * Callback handler to handle resizing windows.