feat: assignment 3
This commit is contained in:
		
							
								
								
									
										83
									
								
								src/texture.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								src/texture.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | ||||
| #include "texture.h" | ||||
|  | ||||
| #include <algorithm> | ||||
|  | ||||
| #include "../lib/glew/GL/glew.h" | ||||
| #include "../lib/glfw/glfw3.h" | ||||
|  | ||||
| #define STB_IMAGE_IMPLEMENTATION | ||||
| #include "../lib/stb/stb_image.h" | ||||
|  | ||||
| #include "logger.h" | ||||
|  | ||||
| Texture::Texture(uint32_t id, const glm::ivec2& size) | ||||
|     : id_(id), size_(size) | ||||
| { | ||||
| } | ||||
|  | ||||
| Texture::~Texture() | ||||
| { | ||||
| 	if (id_ != 0) { | ||||
| 		glDeleteTextures(1, &id_); | ||||
| 		Logger::info(sstr("Texture ", id_, " destroyed")); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| std::shared_ptr<Texture> Texture::load(const char* filename) | ||||
| { | ||||
| 	Logger::info(sstr("Loading texture: ", filename)); | ||||
|  | ||||
| 	// Load image | ||||
| 	int	 width, height, channels; | ||||
| 	stbi_uc* pixels = | ||||
| 	    stbi_load(filename, &width, &height, &channels, STBI_rgb_alpha); | ||||
|  | ||||
| 	if (!pixels) { | ||||
| 		Logger::error(sstr("Failed to load texture: ", filename, " - ", | ||||
| 				   stbi_failure_reason())); | ||||
| 		return nullptr; | ||||
| 	} | ||||
|  | ||||
| 	// Flip image vertically (OpenGL expects bottom row first) | ||||
| 	const int row_size   = width * 4; // 4 channels (RGBA) | ||||
| 	auto*	  row_buffer = new stbi_uc[row_size]; | ||||
| 	for (int y = 0; y < height / 2; ++y) { | ||||
| 		stbi_uc* row1 = pixels + y * row_size; | ||||
| 		stbi_uc* row2 = pixels + (height - 1 - y) * row_size; | ||||
| 		std::copy(row1, row1 + row_size, row_buffer); | ||||
| 		std::copy(row2, row2 + row_size, row1); | ||||
| 		std::copy(row_buffer, row_buffer + row_size, row2); | ||||
| 	} | ||||
| 	delete[] row_buffer; | ||||
|  | ||||
| 	// Generate OpenGL texture | ||||
| 	GLuint texture_id; | ||||
| 	glGenTextures(1, &texture_id); | ||||
| 	glBindTexture(GL_TEXTURE_2D, texture_id); | ||||
|  | ||||
| 	// Upload texture data | ||||
| 	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, | ||||
| 		     GL_UNSIGNED_BYTE, pixels); | ||||
|  | ||||
| 	// Set trilinear filtering | ||||
| 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, | ||||
| 			GL_LINEAR_MIPMAP_LINEAR); | ||||
| 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||||
|  | ||||
| 	// Generate mipmaps | ||||
| 	glGenerateMipmap(GL_TEXTURE_2D); | ||||
|  | ||||
| 	// Free image data | ||||
| 	stbi_image_free(pixels); | ||||
|  | ||||
| 	Logger::info(sstr("Texture loaded successfully: ", filename, " (", | ||||
| 			  width, "x", height, ", ", channels, " channels)")); | ||||
|  | ||||
| 	return std::shared_ptr<Texture>( | ||||
| 	    new Texture(texture_id, glm::ivec2(width, height))); | ||||
| } | ||||
|  | ||||
| void Texture::bind() const | ||||
| { | ||||
| 	glBindTexture(GL_TEXTURE_2D, id_); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user