N64: Add support for non power of two textures for UI texures to squeeze a bit more into the 4 kb TMEM

This commit is contained in:
UnknownShadow200 2023-12-04 20:14:39 +11:00
parent b92327e40c
commit 9661c34b4f
6 changed files with 29 additions and 15 deletions

View File

@ -152,9 +152,11 @@ void Context2D_Alloc(struct Context2D* ctx, int width, int height) {
ctx->height = height;
ctx->meta = NULL;
/* Allocates a power-of-2 sized bitmap equal to or greater than the given size, and clears it to 0 */
width = Math_NextPowOf2(width);
height = Math_NextPowOf2(height);
if (!Gfx.SupportsNonPowTwoTextures) {
/* Allocate power-of-2 sized bitmap equal to or greater than the given size */
width = Math_NextPowOf2(width);
height = Math_NextPowOf2(height);
}
ctx->bmp.width = width;
ctx->bmp.height = height;
@ -299,7 +301,7 @@ void Drawer2D_MakeTextTexture(struct Texture* tex, struct DrawTextArgs* args) {
}
void Context2D_MakeTexture(struct Texture* tex, struct Context2D* ctx) {
Gfx_RecreateTexture(&tex->ID, &ctx->bmp, 0, false);
Gfx_RecreateTexture(&tex->ID, &ctx->bmp, TEXTURE_FLAG_NONPOW2, false);
tex->Width = ctx->width;
tex->Height = ctx->height;

View File

@ -332,7 +332,7 @@ static cc_result ApplySkin(struct Entity* e, struct Bitmap* bmp, struct Stream*
if (e->Model->flags & MODEL_FLAG_CLEAR_HAT)
Entity_ClearHat(bmp, e->SkinType);
Gfx_RecreateTexture(&e->TextureId, bmp, TEXTURE_FLAG_MANAGED, false);
e->TextureId = Gfx_CreateTexture(bmp, TEXTURE_FLAG_MANAGED, false);
Entity_SetSkinAll(e, false);
}
return 0;

View File

@ -40,9 +40,12 @@ void Gfx_Create(void);
void Gfx_Free(void);
CC_VAR extern struct _GfxData {
/* Maximum dimensions textures can be created up to. (usually 1024 to 16384) */
/* Maximum dimensions in pixels that a texture can be created up to */
/* NOTE: usually 1024 to 16384 */
int MaxTexWidth, MaxTexHeight;
float _unused;
/* Maximum total size in pixels a texture can consist of */
/* NOTE: Not all graphics backends specify a value for this */
int MaxTexSize;
/* Whether context graphics has been lost (all creation/render calls fail) */
cc_bool LostContext;
/* Whether some textures are created with mipmaps */
@ -53,9 +56,8 @@ CC_VAR extern struct _GfxData {
/* Whether graphics context has been created */
cc_bool Created;
struct Matrix View, Projection;
/* Maximum size in pixels a texture can consist of */
/* NOTE: Not all graphics backends specify a value for this */
int MaxTexSize;
/* Whether the graphics backend supports non power of two textures */
cc_bool SupportsNonPowTwoTextures;
} Gfx;
extern GfxResourceID Gfx_defaultIb;
@ -69,6 +71,8 @@ extern const cc_string Gfx_LowPerfMessage;
#define TEXTURE_FLAG_MANAGED 0x01
/* Texture should allow updating via Gfx_UpdateTexture */
#define TEXTURE_FLAG_DYNAMIC 0x02
/* Texture is deliberately (and not accidentally) being created with non power of two dimensions */
#define TEXTURE_FLAG_NONPOW2 0x04
#define LOWPERF_EXIT_MESSAGE "&eExited reduced performance mode"
@ -77,7 +81,7 @@ void* Gfx_RecreateAndLockVb(GfxResourceID* vb, VertexFormat fmt, int count);
cc_bool Gfx_CheckTextureSize(int width, int height);
/* Creates a new texture. (and also generates mipmaps if mipmaps) */
/* Supported flags: TEXTURE_FLAG_MANAGED, TEXTURE_FLAG_DYNAMIC */
/* See TEXTURE_FLAG values for supported flags */
/* NOTE: Only set mipmaps to true if Gfx_Mipmaps is also true, because whether textures
use mipmapping may be either a per-texture or global state depending on the backend */
CC_API GfxResourceID Gfx_CreateTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps);

View File

@ -33,6 +33,7 @@ void Gfx_Create(void) {
Gfx.MaxTexSize = 1024; // TMEM only has 4 KB in it
Gfx.Created = true;
Gfx.SupportsNonPowTwoTextures = true;
Gfx_RestoreState();
GL_UpdateVsync();
}
@ -137,9 +138,10 @@ static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, cc_uint8 flags, cc_boo
bmp->width * 4);
}
rdpq_texparms_t params = (rdpq_texparms_t){
.s.repeats = REPEAT_INFINITE,
.t.repeats = REPEAT_INFINITE,
rdpq_texparms_t params =
{
.s.repeats = (flags & TEXTURE_FLAG_NONPOW2) ? 1 : REPEAT_INFINITE,
.t.repeats = (flags & TEXTURE_FLAG_NONPOW2) ? 1 : REPEAT_INFINITE,
};
// rdpq_tex_upload(TILE0, &tex->surface, &params);

View File

@ -36,6 +36,8 @@ void Window_Init(void) {
WindowInfo.Exists = true;
Input.Sources = INPUT_SOURCE_GAMEPAD;
DisplayInfo.ContentOffsetX = 10;
DisplayInfo.ContentOffsetY = 10;
joypad_init();
}

View File

@ -362,9 +362,13 @@ cc_bool Gfx_CheckTextureSize(int width, int height) {
static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps);
GfxResourceID Gfx_CreateTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) {
if (!Math_IsPowOf2(bmp->width) || !Math_IsPowOf2(bmp->height)) {
if (Gfx.SupportsNonPowTwoTextures && (flags & TEXTURE_FLAG_NONPOW2)) {
/* Texture is being deliberately created and can be successfully created */
/* with non power of two dimensions. Typically used for UI textures */
} else if (!Math_IsPowOf2(bmp->width) || !Math_IsPowOf2(bmp->height)) {
Logger_Abort("Textures must have power of two dimensions");
}
if (Gfx.LostContext) return 0;
if (!Gfx_CheckTextureSize(bmp->width, bmp->height)) return 0;