Okay, here is a more complete version of my code:
template<typename T>
class GlObject
{
public:
GlObject() :
m_copy_counter(new size_t(1)),
m_id(T::create())
{}
~GlObject()
{
destroy();
}
// copy constructor
GlObject(const GlObject<T>& other) :
m_copy_counter(other.m_copy_counter),
m_id(other.m_id)
{
*m_copy_counter += 1;
}
// copy operator=
GlObject<T>& operator=(const GlObject<T>& other)
{
destroy();
m_id = other.m_id;
m_copy_counter = other.m_copy_counter;
*m_copy_counter += 1;
return *this;
}
// move constructor
GlObject(GlObject<T>&& other) = delete;
// move operator=
GlObject<T>& operator=(GlObject<T>&& other) = delete;
[[nodiscard]] GLuint id() const
{
return m_id;
}
private:
void destroy()
{
assert(m_copy_counter != nullptr);
assert(*m_copy_counter > 0);
*m_copy_counter -= 1;
if (*m_copy_counter == 0)
{
T::destroy(m_id);
m_id = 0;
delete m_copy_counter;
}
}
size_t* m_copy_counter = nullptr;
GLuint m_id = 0;
};
class Texture2D
{
friend class Framebuffer;
friend class Program;
public:
Texture2D(
const GLint internal_format,
const GLsizei width,
const GLsizei height,
const GLenum format,
const GLenum type
)
{
assert(m_object.id() != 0);
glBindTexture(GL_TEXTURE_2D, m_object.id());
glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, format, type, nullptr);
}
Texture2D(const std::vector<unsigned char>& image, const int width, const int height)
{
assert(m_object.id() != 0);
glBindTexture(GL_TEXTURE_2D, m_object.id());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image.data());
//enable mip mapping
glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -0.3f);
}
Texture2D() = default;
void setParameter(const GLenum pname, const GLint param)
{
glBindTexture(GL_TEXTURE_2D, m_object.id());
glTexParameteri(GL_TEXTURE_2D, pname, param);
}
private:
GlObject<GlTextureTraits> m_object;
};
...
for (const auto& o : obj)
{
...
std::vector<unsigned char> image;
unsigned int width, height;
lodepng::decode(image, width, height, o.material.diffuse_map);
gl::Texture2D texture = gl::Texture2D(image, (int)width, (int)height);
lodepng::decode(image, width, height, o.material.normal_map);
gl::Texture2D normal_map = gl::Texture2D(image, (int)width, (int)height);
...
}
To be honest i don’t see a reason why that shouldn’t work but this does:
std::vector<unsigned char> image_texture;
std::vector<unsigned char> image_normal;
unsigned int width, height;
lodepng::decode(image_texture, width, height, o.material.diffuse_map);
gl::Texture2D texture = gl::Texture2D(image_texture, (int)width, (int)height);
lodepng::decode(image_normal, width, height, o.material.normal_map);
gl::Texture2D normal_map = gl::Texture2D(image_normal, (int)width, (int)height);
other than that glTexImage2D returns early. But I may miss something obvious so I won’t rule that out.