#include <GL++/Texture.hpp>
#include <GL/glew.h>
#include <SDL.h>
#include <SDL_image.h>
#include <memory>
Texture::Texture(char const* path) : id(0) {
std::unique_ptr<SDL_Surface, void(*)(SDL_Surface*)> image(IMG_Load(path), SDL_FreeSurface);
if(image.get() == nullptr) {
error_log = std::string("could't open the given file (") + SDL_GetError() + ")";
return;
}
glGenTextures(1, &id);
glBindTexture(GL_TEXTURE_2D, id);
GLint internalFormat;
GLenum format;
if(image->format->BytesPerPixel == 3) {
internalFormat = GL_RGB;
if(image->format->Rmask == 0xFF) {
format = GL_RGB;
} else {
format = GL_BGR;
}
} else if(image->format->BytesPerPixel == 4) {
internalFormat = GL_RGBA;
if(image->format->Rmask == 0xFF) {
format = GL_RGBA;
} else {
format = GL_BGRA;
}
} else {
error_log = "wrong image format";
glDeleteTextures(1, &id);
id = 0;
return;
}
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, image->w, image->h, 0,
format, GL_UNSIGNED_BYTE, image->pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);
}
Texture::Texture(GLsizei width, GLsizei height) {
glGenTextures(1, &id);
glBindTexture(GL_TEXTURE_2D, id);
/* void glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width,
* GLsizei height, GLint border, GLenum format, GLenum type,
* const GLvoid * data);
* data may be a null pointer. In this case, texture memory is allocated to accommodate
* a texture of width width and height height. You can then download subtextures to
* initialize this texture memory. The image is undefined if the user tries to apply
* an uninitialized portion of the texture image to a primitive.*/
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
}
Texture::Texture(Texture&& texture) : id(texture.id) {
texture.id = 0;
}
Texture& Texture::operator=(Texture&& texture) {
if(this != &texture) {
glDeleteTextures(1, &id);
id = texture.id;
texture.id = 0;
}
return *this;
}
Texture::~Texture() {
glDeleteTextures(1, &id);
}
GLuint Texture::get_id() const {
return id;
}
std::string const& Texture::log() const {
return error_log;
}
Texture::operator bool() const {
return !(id == 0);
}