mirror of
https://gitlab.com/skmp/dca3-game.git
synced 2025-04-28 13:07:59 +03:00
226 lines
7.2 KiB
C
226 lines
7.2 KiB
C
#pragma once
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
|
|
#include "pixel.h"
|
|
#include "pvr_texture.h"
|
|
#include "stb_image_resize.h"
|
|
|
|
typedef enum {
|
|
PTE_MIP_NONE,
|
|
PTE_MIP_QUALITY,
|
|
PTE_MIP_FAST,
|
|
} pteMipGen;
|
|
|
|
typedef enum {
|
|
PTE_FIX_NONE,
|
|
PTE_FIX_UP,
|
|
PTE_FIX_DOWN,
|
|
PTE_FIX_NEAREST,
|
|
} pteFixSizeMethod;
|
|
typedef enum {
|
|
PTE_FIX_MIP_NONE, //Must be square
|
|
PTE_FIX_MIP_NARROW_X2, //If not square, take narrower dimension and double it (512x32->64x64)
|
|
PTE_FIX_MIP_NARROW_X4, //If not square, take narrower dimension and quadruple it (512x32->128x128)
|
|
PTE_FIX_MIP_MAX, //Take largest dimension (512x32->512x512)
|
|
PTE_FIX_MIP_MIN, //Take narrowest dimension (512x32->32x32)
|
|
} pteFixMipSizeMethod;
|
|
|
|
|
|
typedef uint8_t VQIndex;
|
|
|
|
typedef enum {
|
|
//The values for following seven formats match up with the values used by the hardware
|
|
PTE_ARGB1555,
|
|
PTE_RGB565,
|
|
PTE_ARGB4444,
|
|
PTE_YUV,
|
|
PTE_NORMAL,
|
|
PTE_PALETTE_4B,
|
|
PTE_PALETTE_8B,
|
|
|
|
//The following are not real, supported PVR formats, but used internally by some functions
|
|
PTE_YUV_TWID = PT_YUV_TWID,
|
|
|
|
//The following cannot be used as a ptPixelFormat. They are used by pte* functions only
|
|
PTE_ABGR8888,
|
|
PTE_BUMP, //Signals input is height map that needs to be converted to normal map
|
|
PTE_AUTO, //Selects RGB565, ARGB1555, or ARGB4444 automatically based on alpha of input image
|
|
PTE_AUTO_YUV, //Selects YUV, ARGB1555, or ARGB4444 automatically based on alpha of input image
|
|
} ptePixelFormat;
|
|
|
|
typedef struct {
|
|
unsigned w, h;
|
|
int channels;
|
|
pxlABGR8888 *pixels;
|
|
} pteImage;
|
|
static inline size_t pteImgPixelCnt(const pteImage *img) {
|
|
return img->w * img->h;
|
|
}
|
|
static inline size_t pteImgSize(const pteImage *img) {
|
|
return img->w * img->h * sizeof(pxlABGR8888);
|
|
}
|
|
|
|
typedef struct PvrTexEncoder {
|
|
//
|
|
// The following should be set by the user before using the encoder
|
|
//
|
|
|
|
//If true, generating a nontwiddled stride texture.
|
|
//Texture width can 8, 16, or be any multiple of 32 that is less than or equal to 1024
|
|
//If false, texture will be twiddled
|
|
bool stride;
|
|
|
|
//Method of generating mipmaps, or no mipmaps generated
|
|
pteMipGen want_mips;
|
|
|
|
//Number of mipmap levels, always 1 if no mipmaps
|
|
//Not set to final mipmap count until mipmaps have been generated
|
|
unsigned mip_cnt;
|
|
|
|
//Color format of texture
|
|
ptePixelFormat pixel_format;
|
|
|
|
//Size of codebook in indicies, ranges from 0 to 256
|
|
//0 means uncompressed, >0 will result in a VQ compressed texture
|
|
unsigned codebook_size;
|
|
|
|
//Offset (in entries) into full codebook where the first element is
|
|
//If you have a 128 entry codebook, and want to use the first half, set this to zero
|
|
//If you want to the last half, set this to 128
|
|
//codebook_size + pvr_idx_offset must be <= 256
|
|
unsigned pvr_idx_offset;
|
|
|
|
unsigned perfect_mips; //number of mipmap levels to generate losslessly
|
|
bool mip_shift_correction; //preform correction for mipmap shifting
|
|
|
|
//mips between top-high_weight and perfect_mips are given extra weight (quality) when compressing,
|
|
//0 means no high weight, 1 means all mips below highest have extra priority,
|
|
//2 means all mips below second highest are given prio, etc.
|
|
unsigned high_weight_mips;
|
|
|
|
//Resize method to nearest valid size
|
|
pteFixSizeMethod resize;
|
|
|
|
//Resize method to make square
|
|
pteFixMipSizeMethod mipresize;
|
|
|
|
//Amount of dithering, 0 is none, 1 is full
|
|
float dither;
|
|
|
|
//How to downsample on the edges
|
|
stbir_edge edge_method;
|
|
|
|
//Generate small codebook size based on texture dimensions
|
|
bool auto_small_vq;
|
|
|
|
//Unprocessed source images specified by user
|
|
unsigned src_img_cnt;
|
|
pteImage src_imgs[PVR_MAX_MIPMAPS];
|
|
|
|
float rgb_gamma;
|
|
float alpha_gamma;
|
|
|
|
//
|
|
// Below here is used internally by encoder. User should avoid messing with most of these.
|
|
//
|
|
//Width and height of texture in pixels (if we have mipmaps, this is largest mip level)
|
|
unsigned w, h;
|
|
|
|
//If true, raw_mips contains twiddled data, otherwise data is normal, linear
|
|
bool raw_is_twiddled;
|
|
|
|
unsigned palette_size; //size in colors, ranges from 0 to 256
|
|
pxlABGR8888 *palette;
|
|
|
|
//Preview with all mips in one image
|
|
//height is h
|
|
unsigned final_preview_w;
|
|
pxlABGR8888 *final_preview;
|
|
|
|
//Codebook in pvr format, uses pixel_format pixel
|
|
void *pvr_codebook;
|
|
|
|
//PVR texture data, in the same format used by the pvr, including all mipmaps laid out in order, including padding
|
|
//If compressed, this is just the indices, and does NOT include the codebook
|
|
void *pvr_tex;
|
|
|
|
//Uncompressed PVR texture data, as pvr_tex, but in 32-bit color. This is generated first, then pvr_tex is generated from it
|
|
pxlABGR8888 *pvr_tex32;
|
|
|
|
//For the following three *_mips arrays...
|
|
//If mip_cnt > 1, 0 is 1x1, 1 is 2x2, 3 is 4x4...
|
|
//If mip_cnt == 1, 0 is only level, and its size is equal to this->w, this->h
|
|
|
|
//Uncompressed source, 4-bytes per pixel
|
|
pxlABGR8888 *raw_mips[PVR_MAX_MIPMAPS];
|
|
|
|
//Raw PVR data
|
|
//If texture is not compresed, this is in pixel_format
|
|
//If texture is compressed, these are indicies
|
|
uint8_t *pvr_mips[PVR_MAX_MIPMAPS];
|
|
|
|
//Output preview
|
|
//What you get after compressing and reducing color depth
|
|
pxlABGR8888 *preview_mips[PVR_MAX_MIPMAPS];
|
|
} PvrTexEncoder;
|
|
|
|
//For both FOR_EACH, width and height of current mipmap level are in variables mw and mh
|
|
|
|
//Go through each level from small to large
|
|
#define FOR_EACH_MIP(pte, mipidx) \
|
|
for(int mipidx = 0, mw = pteHasMips(pte) ? 1 : pte->w, mh = pteHasMips(pte) ? 1 : pte->h; mipidx < pte->mip_cnt; mipidx++, mw <<= 1, mh <<= 1)
|
|
|
|
//Go through each level from large to small
|
|
#define FOR_EACH_MIP_REV(pte, mipidx) \
|
|
for(int mipidx = pte->mip_cnt-1, mw = pte->w, mh = pte->h; mipidx >= 0; mipidx--, mw >>= 1, mh >>= 1)
|
|
|
|
static inline unsigned pteTopMipLvl(const PvrTexEncoder *pte) {
|
|
return pte->mip_cnt - 1;
|
|
}
|
|
|
|
static inline bool pteHasMips(const PvrTexEncoder *pte) {
|
|
return pte->want_mips != PTE_MIP_NONE;
|
|
}
|
|
static inline bool pteIsCompressed(const PvrTexEncoder *pte) {
|
|
return pte->codebook_size > 0;
|
|
}
|
|
static inline bool pteIsStrided(const PvrTexEncoder *pte) {
|
|
return pte->stride;
|
|
}
|
|
static inline bool pteIsPalettized(const PvrTexEncoder *pte) {
|
|
return pte->pixel_format == PTE_PALETTE_4B || pte->pixel_format == PTE_PALETTE_8B;
|
|
}
|
|
|
|
void pteInit(PvrTexEncoder *pte);
|
|
void pteFree(PvrTexEncoder *pte);
|
|
void pteLoadFromFiles(PvrTexEncoder *pte, const char **fnames, unsigned filecnt);
|
|
void pteEncodeTexture(PvrTexEncoder *pte);
|
|
void pteMakeSquare(PvrTexEncoder *pte);
|
|
int pteSetSize(PvrTexEncoder *pte);
|
|
void pteSetCompressed(PvrTexEncoder *pte, int codebook_size);
|
|
void pteGeneratePreviews(PvrTexEncoder *pte);
|
|
void pteAutoSelectPixelFormat(PvrTexEncoder *pte);
|
|
|
|
///////////
|
|
void ErrorExitOn(int cond, const char *fmt, ...);
|
|
void ErrorExit(const char *fmt, ...) __attribute__((noreturn));
|
|
|
|
typedef enum pteLogLevel {
|
|
//When changing these, make sure to update logtypes[] in pteLogLocV
|
|
LOG_NONE, //Disables logs, do not log to this type
|
|
|
|
LOG_WARNING, //Important warnings or errors
|
|
LOG_COMPLETION, //Encode completion
|
|
LOG_PROGRESS, //Progress of encoding
|
|
LOG_INFO, //Useful info on encoding
|
|
|
|
LOG_ALL, //Prints all normal user visible logs, do not log to this type
|
|
|
|
LOG_DEBUG, //Debug info. Must be the highest level, used as bounds check in pteLogLocV
|
|
} pteLogLevel;
|
|
|
|
#define pteLog(level, ...) //pteLogLoc(level, __FILE__, __LINE__, __VA_ARGS__)
|
|
extern void pteLogLoc(unsigned level, const char *file, unsigned line, const char *fmt, ...);
|
|
|