#include "Texture.h" #include "Asset/Asset_ImagePack.h" #include "EngineCore/Game.h" Texture::Texture() { } Texture::~Texture() { glDeleteTextures(1, &m_TextureID); } bool Texture::Init(std::string PngPath) { SDL_Surface *surface = IMG_Load(PngPath.c_str()); if (!surface) { SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Couldn't load image %s: %s", PngPath.c_str(), IMG_GetError()); return false; } SDL_Surface *rgbaSurface = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ABGR8888, 0); SDL_FreeSurface(surface); if (!rgbaSurface) { SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Failed to convert surface: %s\n", SDL_GetError()); return false; } // 生成OpenGL纹理 glGenTextures(1, &m_TextureID); glBindTexture(GL_TEXTURE_2D, m_TextureID); // 环绕方式 // 对2D纹理设置环绕模式(S=X轴,T=Y轴) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // 缩小过滤:使用最近邻采样 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // 放大过滤:使用最近邻采样 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 处理像素对齐(确保SDL的像素行对齐与OpenGL兼容) glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // 记录纹理信息 m_TextureSize.width = rgbaSurface->w; m_TextureSize.height = rgbaSurface->h; m_FrameSize.width = rgbaSurface->w; m_FrameSize.height = rgbaSurface->h; m_Path = PngPath; // 将像素数据上传到GPU glTexImage2D( GL_TEXTURE_2D, 0, // 纹理级别(基础级) GL_RGBA8, // 内部存储格式(8位RGBA) m_TextureSize.width, m_TextureSize.height, 0, // 边框(必须为0) GL_RGBA, // 源数据格式(与SDL转换后的格式一致) GL_UNSIGNED_BYTE, // 源数据类型(无符号字节) rgbaSurface->pixels); // 释放转换后的表面(数据已上传到GPU) SDL_FreeSurface(rgbaSurface); return true; } bool Texture::Init(std::string ImgPath, int Index) { m_Path = ImgPath; m_TextureIndex = Index; Asset_ImagePack::IMG *Info = Asset_ImagePack::GetInstance().GetIMG(ImgPath); if (Info->lpImgName == "sprite/interface/base.img") return false; Asset_ImagePack::ImgInfo &Buf = Info->lp_lplist[Index]; // 检查像素数据是否有效 if (!Buf.PNGdata || Buf.Width <= 0 || Buf.Height <= 0) { SDL_LogError(SDL_LOG_CATEGORY_ERROR, "无效的图像数据: %s (index: %d)", ImgPath.c_str(), Index); return false; } int pixelCount = Buf.Width * Buf.Height; uint32_t *srcPixels = reinterpret_cast(Buf.PNGdata); uint32_t *dstPixels = new uint32_t[pixelCount]; for (int i = 0; i < pixelCount; ++i) { uint8_t b = (srcPixels[i] >> 0) & 0xFF; // 蓝 uint8_t g = (srcPixels[i] >> 8) & 0xFF; // 绿 uint8_t r = (srcPixels[i] >> 16) & 0xFF; // 红 uint8_t a = (srcPixels[i] >> 24) & 0xFF; // 透明 dstPixels[i] = (a << 24) | (b << 16) | (g << 8) | r; // 重组为 RGBA } // 生成OpenGL纹理 glGenTextures(1, &m_TextureID); glBindTexture(GL_TEXTURE_2D, m_TextureID); // 设置纹理参数(保持与原有SDL纹理相同的采样模式) // 环绕方式:重复 // 对2D纹理设置环绕模式(S=X轴,T=Y轴) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // 过滤方式:最近邻(与SDL_ScaleModeNearest对应) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 处理像素对齐(SDL表面可能有不同的行对齐方式) glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // 记录纹理信息 m_TextureSize.width = Buf.Width; m_TextureSize.height = Buf.Height; m_FrameSize.width = Buf.FrameXpos; m_FrameSize.height = Buf.FrameYpos; m_TexturePos.x = Buf.Xpos; m_TexturePos.y = Buf.Ypos; // 上传纹理数据到GPU glTexImage2D( GL_TEXTURE_2D, 0, // 基础纹理级别 GL_RGBA8, // 内部存储格式(8位RGBA) m_TextureSize.width, m_TextureSize.height, 0, // 无边框 GL_RGBA, // 源数据格式(根据实际数据格式调整) GL_UNSIGNED_BYTE, // 源数据类型 dstPixels); return true; } bool Texture::Init(SDL_Surface *rgbaSurface) { // 生成OpenGL纹理 glGenTextures(1, &m_TextureID); glBindTexture(GL_TEXTURE_2D, m_TextureID); // 环绕方式 // 对2D纹理设置环绕模式(S=X轴,T=Y轴) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // 缩小过滤:使用最近邻采样 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // 放大过滤:使用最近邻采样 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 处理像素对齐(确保SDL的像素行对齐与OpenGL兼容) glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // 记录纹理信息 m_TextureSize.width = rgbaSurface->w; m_TextureSize.height = rgbaSurface->h; m_FrameSize.width = rgbaSurface->w; m_FrameSize.height = rgbaSurface->h; // 将像素数据上传到GPU glTexImage2D( GL_TEXTURE_2D, 0, // 纹理级别(基础级) GL_RGBA8, // 内部存储格式(8位RGBA) m_TextureSize.width, m_TextureSize.height, 0, // 边框(必须为0) GL_RGBA, // 源数据格式(与SDL转换后的格式一致) GL_UNSIGNED_BYTE, // 源数据类型(无符号字节) rgbaSurface->pixels); return true; } bool Texture::Init(VecSize size) { glGenTextures(1, &m_TextureID); glBindTexture(GL_TEXTURE_2D, m_TextureID); // 设置纹理参数(根据需求调整尺寸、格式) glTexImage2D( GL_TEXTURE_2D, 0, // 多级渐远纹理级别 GL_RGBA, // 内部格式(存储格式) size.width, // 纹理宽度 size.height, // 纹理高度 0, // 边框(必须为0) GL_RGBA, // 源数据格式 GL_UNSIGNED_BYTE, // 源数据类型 nullptr // 初始数据(为空,后续绘制填充) ); // 记录纹理信息 m_TextureSize = size; m_FrameSize = size; // 环绕方式 // 对2D纹理设置环绕模式(S=X轴,T=Y轴) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // 缩小过滤:使用最近邻采样 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // 放大过滤:使用最近邻采样 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); // 解绑 return true; }