Implement a small texture wrapper.

Allows for RAII use of OpenGL textures.
This commit is contained in:
2018-02-25 19:03:10 +01:00
parent 23ae9717ea
commit 17d4e07025
6 changed files with 89 additions and 13 deletions

View File

@@ -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);

View File

@@ -5,6 +5,7 @@
#include <memory>
#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<float[]> vertexBuffer;
std::unique_ptr<float[]> texCoordBuffer;
};

36
src/Texture.cpp Normal file
View File

@@ -0,0 +1,36 @@
#include <algorithm>
#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);
}

44
src/Texture.hpp Normal file
View File

@@ -0,0 +1,44 @@
#pragma once
#include <GL/gl.h>
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;
};
}

View File

@@ -8,6 +8,7 @@
#include <thread>
#include "glutils.hpp"
#include "Range.hpp"
#include "Texture.hpp"
using namespace fmri;
using namespace std;
@@ -32,17 +33,16 @@ static void rescaleSubImages(vector<float>& 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<float> 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);

View File

@@ -2,6 +2,7 @@
#include "LayerData.hpp"
#include "utils.hpp"
#include "Texture.hpp"
#include <GL/glut.h>
#include <string_view>
@@ -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.