feat: assignment 3

This commit is contained in:
2025-10-13 18:23:01 +02:00
parent db6e548476
commit 49219fc597
13 changed files with 364 additions and 61 deletions

83
src/texture.cpp Normal file
View 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_);
}