2019-10-05 17:28:05 +00:00
|
|
|
/*
|
|
|
|
** textures.h
|
|
|
|
**
|
|
|
|
**---------------------------------------------------------------------------
|
|
|
|
** Copyright 2005-2016 Randy Heit
|
2019-10-12 20:49:46 +00:00
|
|
|
** Copyright 2005-2019 Christoph Oelckers
|
2019-10-05 17:28:05 +00:00
|
|
|
** All rights reserved.
|
|
|
|
**
|
|
|
|
** Redistribution and use in source and binary forms, with or without
|
|
|
|
** modification, are permitted provided that the following conditions
|
|
|
|
** are met:
|
|
|
|
**
|
|
|
|
** 1. Redistributions of source code must retain the above copyright
|
|
|
|
** notice, this list of conditions and the following disclaimer.
|
|
|
|
** 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
** notice, this list of conditions and the following disclaimer in the
|
|
|
|
** documentation and/or other materials provided with the distribution.
|
|
|
|
** 3. The name of the author may not be used to endorse or promote products
|
|
|
|
** derived from this software without specific prior written permission.
|
|
|
|
**
|
|
|
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
|
|
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
|
|
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
|
|
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
|
|
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
**---------------------------------------------------------------------------
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __TEXTURES_H
|
|
|
|
#define __TEXTURES_H
|
|
|
|
|
2020-05-24 17:12:22 +00:00
|
|
|
#include "basics.h"
|
|
|
|
#include "vectors.h"
|
|
|
|
#include "colormatcher.h"
|
|
|
|
#include "renderstyle.h"
|
2019-10-05 17:28:05 +00:00
|
|
|
#include "textureid.h"
|
2020-05-24 17:12:22 +00:00
|
|
|
#include <vector>
|
|
|
|
#include "hw_texcontainer.h"
|
2020-05-25 21:59:07 +00:00
|
|
|
#include "floatrect.h"
|
|
|
|
#include "refcounted.h"
|
2020-05-24 17:12:22 +00:00
|
|
|
|
|
|
|
typedef TMap<int, bool> SpriteHits;
|
2020-05-24 11:53:27 +00:00
|
|
|
class FImageSource;
|
2020-05-25 21:59:07 +00:00
|
|
|
class FGameTexture;
|
|
|
|
class IHardwareTexture;
|
|
|
|
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
CLAMP_NONE = 0,
|
2020-05-28 21:48:50 +00:00
|
|
|
CLAMP_X,
|
|
|
|
CLAMP_Y,
|
|
|
|
CLAMP_XY,
|
|
|
|
CLAMP_XY_NOMIP,
|
|
|
|
CLAMP_NOFILTER,
|
|
|
|
CLAMP_NOFILTER_X,
|
|
|
|
CLAMP_NOFILTER_Y,
|
|
|
|
CLAMP_NOFILTER_XY,
|
|
|
|
CLAMP_CAMTEX,
|
|
|
|
NUMSAMPLERS
|
2020-05-25 21:59:07 +00:00
|
|
|
};
|
2019-10-05 17:28:05 +00:00
|
|
|
|
2020-05-24 11:53:27 +00:00
|
|
|
enum MaterialShaderIndex
|
2019-10-12 20:49:46 +00:00
|
|
|
{
|
2020-05-24 11:53:27 +00:00
|
|
|
SHADER_Default,
|
|
|
|
SHADER_Warp1,
|
|
|
|
SHADER_Warp2,
|
|
|
|
SHADER_Specular,
|
|
|
|
SHADER_PBR,
|
|
|
|
SHADER_Paletted,
|
|
|
|
SHADER_NoTexture,
|
|
|
|
SHADER_BasicFuzz,
|
|
|
|
SHADER_SmoothFuzz,
|
|
|
|
SHADER_SwirlyFuzz,
|
|
|
|
SHADER_TranslucentFuzz,
|
|
|
|
SHADER_JaggedFuzz,
|
|
|
|
SHADER_NoiseFuzz,
|
|
|
|
SHADER_SmoothNoiseFuzz,
|
|
|
|
SHADER_SoftwareFuzz,
|
|
|
|
FIRST_USER_SHADER
|
2019-10-12 20:49:46 +00:00
|
|
|
};
|
|
|
|
|
2020-05-25 21:59:07 +00:00
|
|
|
enum texflags
|
2019-10-05 17:28:05 +00:00
|
|
|
{
|
2020-05-25 21:59:07 +00:00
|
|
|
// These get Or'ed into uTextureMode because it only uses its 3 lowermost bits.
|
|
|
|
TEXF_Brightmap = 0x10000,
|
|
|
|
TEXF_Detailmap = 0x20000,
|
|
|
|
TEXF_Glowmap = 0x40000,
|
2021-09-22 08:20:39 +00:00
|
|
|
TEXF_ClampY = 0x80000,
|
2019-10-05 17:28:05 +00:00
|
|
|
};
|
|
|
|
|
2019-10-14 21:11:01 +00:00
|
|
|
|
2019-10-05 17:28:05 +00:00
|
|
|
|
2020-05-25 21:59:07 +00:00
|
|
|
enum
|
2019-10-12 20:49:46 +00:00
|
|
|
{
|
2020-05-25 21:59:07 +00:00
|
|
|
SFlag_Brightmap = 1,
|
|
|
|
SFlag_Detailmap = 2,
|
|
|
|
SFlag_Glowmap = 4,
|
2019-10-12 20:49:46 +00:00
|
|
|
};
|
|
|
|
|
2020-05-25 21:59:07 +00:00
|
|
|
struct UserShaderDesc
|
2019-10-12 20:49:46 +00:00
|
|
|
{
|
2020-05-25 21:59:07 +00:00
|
|
|
FString shader;
|
|
|
|
MaterialShaderIndex shaderType;
|
|
|
|
FString defines;
|
|
|
|
bool disablealphatest = false;
|
|
|
|
uint8_t shaderFlags = 0;
|
2019-10-12 20:49:46 +00:00
|
|
|
};
|
|
|
|
|
2020-05-25 21:59:07 +00:00
|
|
|
extern TArray<UserShaderDesc> usershaders;
|
2020-05-24 11:53:27 +00:00
|
|
|
|
2019-10-05 17:28:05 +00:00
|
|
|
class FBitmap;
|
|
|
|
struct FRemapTable;
|
|
|
|
struct FCopyInfo;
|
|
|
|
class FScanner;
|
|
|
|
|
|
|
|
// Texture IDs
|
|
|
|
class FTextureManager;
|
|
|
|
class FTerrainTypeArray;
|
|
|
|
class IHardwareTexture;
|
|
|
|
class FMaterial;
|
|
|
|
class FMultipatchTextureBuilder;
|
|
|
|
|
|
|
|
extern int r_spriteadjustSW, r_spriteadjustHW;
|
|
|
|
|
2020-05-24 11:53:27 +00:00
|
|
|
enum FTextureFormat : uint32_t
|
|
|
|
{
|
|
|
|
TEX_Pal,
|
|
|
|
TEX_Gray,
|
|
|
|
TEX_RGB, // Actually ARGB
|
2019-10-05 17:28:05 +00:00
|
|
|
|
2020-05-24 11:53:27 +00:00
|
|
|
TEX_Count
|
|
|
|
};
|
2019-10-05 17:28:05 +00:00
|
|
|
|
2020-05-25 21:59:07 +00:00
|
|
|
class ISoftwareTexture
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
virtual ~ISoftwareTexture() = default;
|
|
|
|
};
|
|
|
|
|
2019-10-05 17:28:05 +00:00
|
|
|
class FGLRenderState;
|
|
|
|
|
2020-05-24 11:53:27 +00:00
|
|
|
struct spriteframewithrotate;
|
2019-10-05 17:28:05 +00:00
|
|
|
class FSerializer;
|
|
|
|
namespace OpenGLRenderer
|
|
|
|
{
|
|
|
|
class FGLRenderState;
|
2020-05-24 11:53:27 +00:00
|
|
|
class FHardwareTexture;
|
2019-10-05 17:28:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
union FContentIdBuilder
|
|
|
|
{
|
|
|
|
uint64_t id;
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
unsigned imageID : 24;
|
|
|
|
unsigned translation : 16;
|
|
|
|
unsigned expand : 1;
|
|
|
|
unsigned scaler : 4;
|
|
|
|
unsigned scalefactor : 4;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
struct FTextureBuffer
|
|
|
|
{
|
|
|
|
uint8_t *mBuffer = nullptr;
|
|
|
|
int mWidth = 0;
|
|
|
|
int mHeight = 0;
|
2020-05-24 11:53:27 +00:00
|
|
|
uint64_t mContentId = 0; // unique content identifier. (Two images created from the same image source with the same settings will return the same value.)
|
2019-10-05 17:28:05 +00:00
|
|
|
|
|
|
|
FTextureBuffer() = default;
|
|
|
|
|
|
|
|
~FTextureBuffer()
|
|
|
|
{
|
|
|
|
if (mBuffer) delete[] mBuffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
FTextureBuffer(const FTextureBuffer &other) = delete;
|
|
|
|
FTextureBuffer(FTextureBuffer &&other)
|
|
|
|
{
|
|
|
|
mBuffer = other.mBuffer;
|
|
|
|
mWidth = other.mWidth;
|
|
|
|
mHeight = other.mHeight;
|
2020-05-24 11:53:27 +00:00
|
|
|
mContentId = other.mContentId;
|
2019-10-05 17:28:05 +00:00
|
|
|
other.mBuffer = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
FTextureBuffer& operator=(FTextureBuffer &&other)
|
|
|
|
{
|
|
|
|
mBuffer = other.mBuffer;
|
|
|
|
mWidth = other.mWidth;
|
|
|
|
mHeight = other.mHeight;
|
2020-05-24 11:53:27 +00:00
|
|
|
mContentId = other.mContentId;
|
2019-10-05 17:28:05 +00:00
|
|
|
other.mBuffer = nullptr;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
// Base texture class
|
2020-05-25 21:59:07 +00:00
|
|
|
class FTexture : public RefCountedBase
|
2019-10-05 17:28:05 +00:00
|
|
|
{
|
2020-05-25 21:59:07 +00:00
|
|
|
friend class FGameTexture; // only for the porting work
|
|
|
|
|
|
|
|
public:
|
|
|
|
FHardwareTextureContainer SystemTextures;
|
|
|
|
protected:
|
|
|
|
FloatRect* areas = nullptr;
|
|
|
|
int SourceLump;
|
|
|
|
uint16_t Width = 0, Height = 0;
|
|
|
|
|
|
|
|
bool Masked = false; // Texture (might) have holes
|
|
|
|
bool bHasCanvas = false;
|
2023-08-19 14:57:37 +00:00
|
|
|
bool bHdr = false; // only canvas textures for now.
|
2020-05-25 21:59:07 +00:00
|
|
|
int8_t bTranslucent = -1;
|
|
|
|
int8_t areacount = 0; // this is capped at 4 sections.
|
2019-10-14 21:11:01 +00:00
|
|
|
|
2019-10-05 19:59:03 +00:00
|
|
|
|
2020-05-24 17:12:22 +00:00
|
|
|
public:
|
2020-05-25 21:59:07 +00:00
|
|
|
|
|
|
|
IHardwareTexture* GetHardwareTexture(int translation, int scaleflags);
|
2019-10-05 17:28:05 +00:00
|
|
|
virtual FImageSource *GetImage() const { return nullptr; }
|
2020-05-24 17:12:22 +00:00
|
|
|
void CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasAlpha, bool checkonly);
|
|
|
|
|
2020-05-25 21:59:07 +00:00
|
|
|
void CleanHardwareTextures()
|
2020-05-24 17:12:22 +00:00
|
|
|
{
|
2020-05-25 21:59:07 +00:00
|
|
|
SystemTextures.Clean();
|
2020-05-24 17:12:22 +00:00
|
|
|
}
|
2019-10-05 17:28:05 +00:00
|
|
|
|
2020-05-25 21:59:07 +00:00
|
|
|
void CleanPrecacheMarker()
|
|
|
|
{
|
|
|
|
SystemTextures.UnmarkAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MarkForPrecache(int translation, int scaleflags)
|
|
|
|
{
|
|
|
|
SystemTextures.MarkForPrecache(translation, scaleflags);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CleanUnused()
|
|
|
|
{
|
|
|
|
SystemTextures.CleanUnused();
|
|
|
|
}
|
|
|
|
|
|
|
|
int GetWidth() { return Width; }
|
|
|
|
int GetHeight() { return Height; }
|
2021-12-30 09:30:21 +00:00
|
|
|
|
2020-05-24 17:12:22 +00:00
|
|
|
bool isHardwareCanvas() const { return bHasCanvas; } // There's two here so that this can deal with software canvases in the hardware renderer later.
|
|
|
|
bool isCanvas() const { return bHasCanvas; }
|
2021-12-30 09:30:21 +00:00
|
|
|
|
2023-08-19 14:57:37 +00:00
|
|
|
bool IsHDR() const { return bHdr; }
|
|
|
|
|
2020-05-25 21:59:07 +00:00
|
|
|
int GetSourceLump() { return SourceLump; } // needed by the scripted GetName method.
|
2020-06-11 07:15:44 +00:00
|
|
|
void SetSourceLump(int sl) { SourceLump = sl; }
|
2020-05-24 17:12:22 +00:00
|
|
|
bool FindHoles(const unsigned char * buffer, int w, int h);
|
|
|
|
|
|
|
|
void CopySize(FTexture* BaseTexture)
|
|
|
|
{
|
2020-05-25 21:59:07 +00:00
|
|
|
Width = BaseTexture->GetWidth();
|
|
|
|
Height = BaseTexture->GetHeight();
|
2020-05-24 17:12:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// This is only used for the null texture and for Heretic's skies.
|
|
|
|
void SetSize(int w, int h)
|
|
|
|
{
|
|
|
|
Width = w;
|
|
|
|
Height = h;
|
|
|
|
}
|
|
|
|
|
2020-05-25 21:59:07 +00:00
|
|
|
bool TrimBorders(uint16_t* rect);
|
|
|
|
int GetAreas(FloatRect** pAreas) const;
|
2019-10-05 17:28:05 +00:00
|
|
|
|
|
|
|
// Returns the whole texture, stored in column-major order
|
2020-05-24 17:12:22 +00:00
|
|
|
virtual TArray<uint8_t> Get8BitPixels(bool alphatex);
|
2019-10-18 17:06:57 +00:00
|
|
|
virtual FBitmap GetBgraBitmap(const PalEntry *remap, int *trans = nullptr);
|
2019-10-05 17:28:05 +00:00
|
|
|
|
2020-05-24 17:12:22 +00:00
|
|
|
static bool SmoothEdges(unsigned char * buffer,int w, int h);
|
2019-10-05 17:28:05 +00:00
|
|
|
|
2020-05-24 17:12:22 +00:00
|
|
|
|
|
|
|
virtual void ResolvePatches() {}
|
|
|
|
|
|
|
|
|
2020-05-25 21:59:07 +00:00
|
|
|
FTexture (int lumpnum = -1);
|
2020-05-24 17:12:22 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
FTextureBuffer CreateTexBuffer(int translation, int flags = 0);
|
2020-04-10 16:17:26 +00:00
|
|
|
virtual bool DetermineTranslucency();
|
|
|
|
bool GetTranslucency()
|
|
|
|
{
|
|
|
|
return bTranslucent != -1 ? bTranslucent : DetermineTranslucency();
|
|
|
|
}
|
2020-05-24 17:12:22 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
void CheckTrans(unsigned char * buffer, int size, int trans);
|
|
|
|
bool ProcessData(unsigned char * buffer, int w, int h, bool ispatch);
|
|
|
|
int CheckRealHeight();
|
|
|
|
|
|
|
|
friend class FTextureManager;
|
2019-10-05 19:59:03 +00:00
|
|
|
};
|
2019-10-05 17:28:05 +00:00
|
|
|
|
2022-08-03 11:27:48 +00:00
|
|
|
class FCanvas;
|
|
|
|
extern TArray<FCanvas*> AllCanvases;
|
2020-05-24 17:12:22 +00:00
|
|
|
|
|
|
|
// A texture that can be drawn to.
|
|
|
|
|
2020-03-29 12:01:46 +00:00
|
|
|
class FCanvasTexture : public FTexture
|
|
|
|
{
|
|
|
|
public:
|
2020-05-25 21:59:07 +00:00
|
|
|
FCanvasTexture(int width, int height)
|
2020-03-29 12:01:46 +00:00
|
|
|
{
|
2020-05-24 17:12:22 +00:00
|
|
|
Width = width;
|
|
|
|
Height = height;
|
2020-03-29 12:01:46 +00:00
|
|
|
|
2020-05-24 17:12:22 +00:00
|
|
|
bHasCanvas = true;
|
2020-05-25 21:59:07 +00:00
|
|
|
aspectRatio = (float)width / height;
|
2020-03-29 12:01:46 +00:00
|
|
|
}
|
|
|
|
|
2022-08-03 11:27:48 +00:00
|
|
|
~FCanvasTexture()
|
|
|
|
{
|
|
|
|
if (Canvas)
|
|
|
|
{
|
|
|
|
AllCanvases.Delete(AllCanvases.Find(Canvas));
|
|
|
|
Canvas = nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-29 12:01:46 +00:00
|
|
|
void NeedUpdate() { bNeedsUpdate = true; }
|
|
|
|
void SetUpdated(bool rendertype) { bNeedsUpdate = false; bFirstUpdate = false; bLastUpdateType = rendertype; }
|
2022-08-03 11:27:48 +00:00
|
|
|
bool CheckNeedsUpdate() const { return bNeedsUpdate; }
|
2020-03-29 12:01:46 +00:00
|
|
|
|
2022-04-25 09:13:55 +00:00
|
|
|
void SetAspectRatio(double aspectScale, bool useTextureRatio) { aspectRatio = (float)aspectScale * (useTextureRatio? ((float)Width / Height) : 1); }
|
|
|
|
|
2022-08-03 11:27:48 +00:00
|
|
|
FCanvas* Canvas = nullptr;
|
|
|
|
|
2020-03-29 12:01:46 +00:00
|
|
|
protected:
|
|
|
|
|
|
|
|
bool bLastUpdateType = false;
|
|
|
|
bool bNeedsUpdate = true;
|
|
|
|
public:
|
|
|
|
bool bFirstUpdate = true;
|
2020-05-25 21:59:07 +00:00
|
|
|
float aspectRatio;
|
2020-03-29 12:01:46 +00:00
|
|
|
|
|
|
|
friend struct FCanvasTextureInfo;
|
2023-08-19 14:57:37 +00:00
|
|
|
friend class FTextureAnimator;
|
|
|
|
|
|
|
|
private:
|
|
|
|
void SetHDR(bool hdr) {
|
|
|
|
bHdr = hdr;
|
|
|
|
}
|
2020-03-29 12:01:46 +00:00
|
|
|
};
|
2019-10-18 09:37:07 +00:00
|
|
|
|
2020-05-24 17:12:22 +00:00
|
|
|
|
|
|
|
// A wrapper around a hardware texture, to allow using it in the 2D drawing interface.
|
|
|
|
class FWrapperTexture : public FTexture
|
|
|
|
{
|
|
|
|
int Format;
|
|
|
|
public:
|
|
|
|
FWrapperTexture(int w, int h, int bits = 1);
|
|
|
|
IHardwareTexture *GetSystemTexture()
|
|
|
|
{
|
2020-05-25 21:59:07 +00:00
|
|
|
return SystemTextures.GetHardwareTexture(0, 0);
|
2020-05-24 17:12:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int GetColorFormat() const
|
|
|
|
{
|
|
|
|
return Format;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class FImageTexture : public FTexture
|
|
|
|
{
|
|
|
|
FImageSource* mImage;
|
2020-05-25 21:59:07 +00:00
|
|
|
bool bNoRemap0 = false;
|
|
|
|
protected:
|
|
|
|
void SetFromImage();
|
2020-05-24 17:12:22 +00:00
|
|
|
public:
|
2020-05-25 21:59:07 +00:00
|
|
|
FImageTexture(FImageSource* image) noexcept;
|
2020-10-15 18:10:52 +00:00
|
|
|
~FImageTexture();
|
2020-05-26 21:12:04 +00:00
|
|
|
TArray<uint8_t> Get8BitPixels(bool alphatex) override;
|
2020-05-24 17:12:22 +00:00
|
|
|
|
2020-05-25 21:59:07 +00:00
|
|
|
void SetImage(FImageSource* img)
|
2020-05-24 17:12:22 +00:00
|
|
|
{
|
|
|
|
mImage = img;
|
2020-05-25 21:59:07 +00:00
|
|
|
SetFromImage();
|
2020-05-24 17:12:22 +00:00
|
|
|
}
|
2020-05-25 21:59:07 +00:00
|
|
|
void SetNoRemap0() { bNoRemap0 = true; }
|
2020-05-24 17:12:22 +00:00
|
|
|
|
|
|
|
FImageSource* GetImage() const override { return mImage; }
|
|
|
|
FBitmap GetBgraBitmap(const PalEntry* p, int* trans) override;
|
2020-04-10 16:17:26 +00:00
|
|
|
bool DetermineTranslucency() override;
|
2020-05-24 17:12:22 +00:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2020-05-25 21:59:07 +00:00
|
|
|
#include "gametexture.h"
|
2019-10-05 17:28:05 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|