#include "Texture.h"


Texture::Texture(const std::string& filepath)
	: m_renderer_ID(0), m_filepath(filepath), m_local_buffer(nullptr), m_width(0), m_height(0), m_bits_per_pixel(0)
{
	stbi_set_flip_vertically_on_load(true); // we need to filp vertically because OpenGL (0, 0) is bottom left
	m_local_buffer = stbi_load(filepath.c_str(), &m_width, &m_height, &m_bits_per_pixel, 4); // (Image location, X size, Y size, how many bits in pixel, RGBA)

	// Generate the openGL texture object
	GLCALL(glGenTextures(1, &m_renderer_ID));

	// Bind the texture object
	GLCALL(glBindTexture(GL_TEXTURE_2D, m_renderer_ID));

	// 임시
	//glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);

	// Set texture rendering mode
	GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); // minification filter
	GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); // magnification filter
	GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)); // horizontal clamp (we do not want tiling)
	GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)); // vertical clamp (we do not want tiling) // GL_CLAMP_TO_EDGE = do not repeat

	// Upload the pixels to the texture
	GLCALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_local_buffer));

	// Generate the mipmaps
	GLCALL(glGenerateMipmap(GL_TEXTURE_2D));

	// Unbind the texture
	GLCALL(glBindTexture(GL_TEXTURE_2D, 0));

	if (m_local_buffer) // m_local_buffer != nullptr
	{
		stbi_image_free(m_local_buffer);
	}

}


Texture::~Texture()
{
	GLCALL(glDeleteTextures(1, &m_renderer_ID)); // 힙에 선언 안하면 스코프 넘어가면서 텍스쳐는 지워진다
}


void Texture::Bind(unsigned int slot) const
{
	// first, select texture slot
	GLCALL(glActiveTexture(GL_TEXTURE0 + slot));
	GLCALL(glBindTexture(GL_TEXTURE_2D, m_renderer_ID));
}


void Texture::UnBind() const
{
	GLCALL(glBindTexture(GL_TEXTURE_2D, 0));
}
