收口颜色格式,删除原来的 RGBA8888 的存储和调用
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#include <SDL_image.h>
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
@@ -49,7 +50,7 @@ namespace
|
||||
|
||||
struct Image
|
||||
{
|
||||
std::vector<uint32_t> pixels;
|
||||
std::vector<uint16_t> pixels;
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
|
||||
@@ -65,6 +66,52 @@ namespace
|
||||
}
|
||||
};
|
||||
|
||||
static uint16_t PackRgba5551(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
||||
{
|
||||
return static_cast<uint16_t>(
|
||||
((static_cast<uint16_t>(r) >> 3) << 11) |
|
||||
((static_cast<uint16_t>(g) >> 3) << 6) |
|
||||
((static_cast<uint16_t>(b) >> 3) << 1) |
|
||||
(a ? 1u : 0u));
|
||||
}
|
||||
|
||||
static Uint32 ReadSurfacePixel(const SDL_Surface* surface, int32_t x, int32_t y)
|
||||
{
|
||||
const uint8_t* row = static_cast<const uint8_t*>(surface->pixels) +
|
||||
static_cast<size_t>(y) * static_cast<size_t>(surface->pitch);
|
||||
const uint8_t* src = row + static_cast<size_t>(x) * static_cast<size_t>(surface->format->BytesPerPixel);
|
||||
|
||||
switch (surface->format->BytesPerPixel)
|
||||
{
|
||||
case 1:
|
||||
return src[0];
|
||||
case 2:
|
||||
{
|
||||
uint16_t pixel = 0;
|
||||
std::memcpy(&pixel, src, sizeof(pixel));
|
||||
return static_cast<Uint32>(pixel);
|
||||
}
|
||||
case 3:
|
||||
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
|
||||
{
|
||||
return (static_cast<Uint32>(src[0]) << 16) |
|
||||
(static_cast<Uint32>(src[1]) << 8) |
|
||||
static_cast<Uint32>(src[2]);
|
||||
}
|
||||
return static_cast<Uint32>(src[0]) |
|
||||
(static_cast<Uint32>(src[1]) << 8) |
|
||||
(static_cast<Uint32>(src[2]) << 16);
|
||||
case 4:
|
||||
{
|
||||
Uint32 pixel = 0;
|
||||
std::memcpy(&pixel, src, sizeof(pixel));
|
||||
return pixel;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
struct AtlasRegion
|
||||
{
|
||||
const SourceSpec* source;
|
||||
@@ -105,39 +152,34 @@ namespace
|
||||
return false;
|
||||
}
|
||||
|
||||
SDL_Surface* rgba_surface = SDL_ConvertSurfaceFormat(loaded_surface, SDL_PIXELFORMAT_RGBA8888, 0);
|
||||
SDL_FreeSurface(loaded_surface);
|
||||
if (rgba_surface == nullptr)
|
||||
{
|
||||
std::cerr << "SDL_ConvertSurfaceFormat failed: " << SDL_GetError() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SDL_LockSurface(rgba_surface) != 0)
|
||||
if (SDL_LockSurface(loaded_surface) != 0)
|
||||
{
|
||||
std::cerr << "SDL_LockSurface failed: " << SDL_GetError() << std::endl;
|
||||
SDL_FreeSurface(rgba_surface);
|
||||
SDL_FreeSurface(loaded_surface);
|
||||
return false;
|
||||
}
|
||||
|
||||
image.width = rgba_surface->w;
|
||||
image.height = rgba_surface->h;
|
||||
image.width = loaded_surface->w;
|
||||
image.height = loaded_surface->h;
|
||||
image.pixels.assign(static_cast<size_t>(image.width) * static_cast<size_t>(image.height), 0);
|
||||
|
||||
for (int32_t y = 0; y < image.height; ++y)
|
||||
{
|
||||
const uint8_t* src_row = static_cast<const uint8_t*>(rgba_surface->pixels) + y * rgba_surface->pitch;
|
||||
const uint32_t* src_pixels = reinterpret_cast<const uint32_t*>(src_row);
|
||||
for (int32_t x = 0; x < image.width; ++x)
|
||||
{
|
||||
const uint32_t pixel = src_pixels[x];
|
||||
uint8_t r = 0;
|
||||
uint8_t g = 0;
|
||||
uint8_t b = 0;
|
||||
uint8_t a = 0;
|
||||
const Uint32 surface_pixel = ReadSurfacePixel(loaded_surface, x, y);
|
||||
SDL_GetRGBA(surface_pixel, loaded_surface->format, &r, &g, &b, &a);
|
||||
image.pixels[static_cast<size_t>(y) * static_cast<size_t>(image.width) + static_cast<size_t>(x)] =
|
||||
(pixel & 0xFFu) == 0u ? 0x00000000u : pixel;
|
||||
a == 0 ? 0u : PackRgba5551(r, g, b, a);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_UnlockSurface(rgba_surface);
|
||||
SDL_FreeSurface(rgba_surface);
|
||||
SDL_UnlockSurface(loaded_surface);
|
||||
SDL_FreeSurface(loaded_surface);
|
||||
return image.is_valid();
|
||||
}
|
||||
|
||||
@@ -245,11 +287,11 @@ namespace
|
||||
return atlas_height > 0;
|
||||
}
|
||||
|
||||
static std::vector<uint32_t> BuildAtlasPixels(const std::vector<AtlasRegion>& regions, int32_t atlas_height)
|
||||
static std::vector<uint16_t> BuildAtlasPixels(const std::vector<AtlasRegion>& regions, int32_t atlas_height)
|
||||
{
|
||||
std::vector<uint32_t> atlas_pixels(
|
||||
std::vector<uint16_t> atlas_pixels(
|
||||
static_cast<size_t>(AtlasWidth) * static_cast<size_t>(atlas_height),
|
||||
0x00000000u);
|
||||
0u);
|
||||
|
||||
for (size_t i = 0; i < regions.size(); ++i)
|
||||
{
|
||||
@@ -262,28 +304,15 @@ namespace
|
||||
static_cast<size_t>(region.x);
|
||||
|
||||
std::copy(
|
||||
region.image.pixels.begin() + static_cast<std::vector<uint32_t>::difference_type>(src_offset),
|
||||
region.image.pixels.begin() + static_cast<std::vector<uint32_t>::difference_type>(src_offset + static_cast<size_t>(region.image.width)),
|
||||
atlas_pixels.begin() + static_cast<std::vector<uint32_t>::difference_type>(dst_offset));
|
||||
region.image.pixels.begin() + static_cast<std::vector<uint16_t>::difference_type>(src_offset),
|
||||
region.image.pixels.begin() + static_cast<std::vector<uint16_t>::difference_type>(src_offset + static_cast<size_t>(region.image.width)),
|
||||
atlas_pixels.begin() + static_cast<std::vector<uint16_t>::difference_type>(dst_offset));
|
||||
}
|
||||
}
|
||||
|
||||
return atlas_pixels;
|
||||
}
|
||||
|
||||
static uint16_t rgba8888_to_rgba5551(uint32_t c)
|
||||
{
|
||||
uint32_t r = (c >> 24) & 0xFFu;
|
||||
uint32_t g = (c >> 16) & 0xFFu;
|
||||
uint32_t b = (c >> 8) & 0xFFu;
|
||||
uint32_t a = c & 0xFFu;
|
||||
return static_cast<uint16_t>(
|
||||
((r >> 3) << 11) |
|
||||
((g >> 3) << 6) |
|
||||
((b >> 3) << 1) |
|
||||
(a ? 1u : 0u));
|
||||
}
|
||||
|
||||
static void WritePixel5551(std::ofstream& file, uint16_t pixel)
|
||||
{
|
||||
file << "0x"
|
||||
@@ -299,7 +328,7 @@ namespace
|
||||
|
||||
static bool WriteAtlasHeader(
|
||||
const std::vector<AtlasRegion>& regions,
|
||||
const std::vector<uint32_t>& atlas_pixels,
|
||||
const std::vector<uint16_t>& atlas_pixels,
|
||||
int32_t atlas_height)
|
||||
{
|
||||
std::ofstream file(OutputHeaderPath);
|
||||
@@ -326,7 +355,7 @@ namespace
|
||||
const size_t end = std::min(i + 12, atlas_pixels.size());
|
||||
for (size_t j = i; j < end; ++j)
|
||||
{
|
||||
WritePixel5551(file, rgba8888_to_rgba5551(atlas_pixels[j]));
|
||||
WritePixel5551(file, atlas_pixels[j]);
|
||||
file << ", ";
|
||||
}
|
||||
file << "\n";
|
||||
@@ -375,7 +404,7 @@ namespace
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::vector<uint32_t> atlas_pixels = BuildAtlasPixels(regions, atlas_height);
|
||||
const std::vector<uint16_t> atlas_pixels = BuildAtlasPixels(regions, atlas_height);
|
||||
if (!WriteAtlasHeader(regions, atlas_pixels, atlas_height))
|
||||
{
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user