//#############################################################################
//# texture.cpp
//#############################################################################
//# Written by Colton Staiduhar
//# Date Created:       02/05/2025
//# Last Modification:  02/05/2025
//#############################################################################
//# Super simple OpenGL texture loading using the stb_image.h library 
//#############################################################################
//# This file provides sources of the functions listed in Texture.h
//#############################################################################


// Include STB
#if defined(use_freeglut)
#	include <glad/glad.h>
#   define FREEGLUT_STATIC
#	include <GL/freeglut.h>
#else
#	include <GLUT/glut.h>
#endif
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image/stb_image.h>

// Header file for functions defined here
#include <texture.h>

/**
 * Loads a texture for use in OpenGL with STB
 */
unsigned int LoadTexture(char *location)
{
	// These will be filled with attributes of the file once loaded
	int w,	 // Width of image
		h,	 // Height of image
		bpp; // Number of color channels in the image

	// Load the image and save raw pixel data as unsigned bytes
	unsigned char *pixels = stbi_load(location, &w, &h, &bpp, 3);

	// Declare our texture, this will be filled with the texture ID
	unsigned int texture;

	// Tell OpenGL to generate a texture slot and bind it to the current texture
	glGenTextures(1, &texture);
	glBindTexture(GL_TEXTURE_2D, texture);

	// These are option values, but they are nice to set
	{
		// Set OpenGL texture Wrapping
		// I prefer CLAMP_TO_EDGE but GL_REPEAT works too, look up the different OpenGL Texture Wrap Types
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

		// Set the type of Texture Filtering
		// "GL_LINEAR" is default, I like GL_NEAREST.  Again, look up all the options
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	}

	// If the loaded pixel data is value
	if (pixels)
	{
		// Load the texture data into the currently bound texture slot
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);

		// Generate the mipmap cause why not
		glGenerateMipmap(GL_TEXTURE_2D);
	}

	// Frees the image data stored in ram from stb
	stbi_image_free(pixels);

	// Return the texture ID
	return texture;
}