#pragma once #include #include /* * NOTE: * in glTexImage2D, border MUST be 0, so this parameter is left out in this interface. */ namespace moggle { struct texture { explicit texture(bool create_now = false) { if(create_now) create(); } ~texture() { destroy(); } texture(texture const &) = delete; texture & operator=(texture const&) = delete; texture(texture && t) : id(t.id) { t.id = 0; } texture & operator=(texture && t) { std::swap(id, t.id); return *this; } bool created() const { return id; } explicit operator bool() const { return created(); } void create(){ if(!id) gl::generate_textures(1, &id); } void destroy(){ gl::delete_textures(1, &id); id = 0; } void bind(GLenum target) { create(); gl::bind_texture(target, id); } GLuint get_id() const { return id; } template void image_2d(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLenum format, const T * data){ bind(target); auto type = gl_type_traits::gl_constant; gl::texture_image_2d(target, level, internalformat, width, height, 0, format, type, data); } void image_2d(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, std::nullptr_t){ bind(target); gl::texture_image_2d(target, level, internalformat, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); } //! creates empty texture static texture create(GLsizei width, GLsizei height, GLint internalformat = GL_RGBA, GLenum target = GL_TEXTURE_2D){ texture t; t.image_2d(target, 0, internalformat, width, height, nullptr); return t; } private: GLuint id = 0; }; }