132 lines
3.2 KiB
C++
132 lines
3.2 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
|
|
namespace Lightmass
|
|
{
|
|
/** Texture formats used by FTexture2D */
|
|
enum ETexture2DFormats
|
|
{
|
|
TF_UNKNOWN,
|
|
TF_ARGB8,
|
|
TF_ARGB16F
|
|
};
|
|
|
|
/** A 2D texture */
|
|
class FTexture2D
|
|
{
|
|
protected:
|
|
/** Texture dimensions */
|
|
int32 SizeX;
|
|
int32 SizeY;
|
|
/** Format of texture which indicates how to interpret Data */
|
|
ETexture2DFormats Format;
|
|
/** The size of each element in the data array */
|
|
int32 ElementSize;
|
|
/** Mip 0 texture data */
|
|
uint8* Data;
|
|
|
|
public:
|
|
FTexture2D() :
|
|
SizeX(0)
|
|
, SizeY(0)
|
|
, Format(TF_UNKNOWN)
|
|
, ElementSize(0)
|
|
, Data(NULL)
|
|
{
|
|
}
|
|
|
|
FTexture2D(ETexture2DFormats InFormat, int32 InSizeX, int32 InSizeY) :
|
|
SizeX(InSizeX)
|
|
, SizeY(InSizeY)
|
|
, Format(InFormat)
|
|
, ElementSize(0)
|
|
, Data(NULL)
|
|
{
|
|
Init(InFormat, InSizeX, InSizeY);
|
|
}
|
|
|
|
virtual ~FTexture2D()
|
|
{
|
|
FMemory::Free(Data);
|
|
}
|
|
|
|
/** Accessors */
|
|
int32 GetSizeX() const { return SizeX; }
|
|
int32 GetSizeY() const { return SizeY; }
|
|
uint8* GetData() { return Data; }
|
|
|
|
void Init(ETexture2DFormats InFormat, int32 InSizeX, int32 InSizeY)
|
|
{
|
|
check(InSizeX > 0 && InSizeY > 0);
|
|
SizeX = InSizeX;
|
|
SizeY = InSizeY;
|
|
Format = InFormat;
|
|
|
|
// Only supporting these formats
|
|
check(InFormat == TF_ARGB8 || InFormat == TF_ARGB16F);
|
|
|
|
switch (InFormat)
|
|
{
|
|
case TF_ARGB8: ElementSize = sizeof(FColor); break;
|
|
case TF_ARGB16F: ElementSize = sizeof(FFloat16Color); break;
|
|
}
|
|
|
|
Data = (uint8*)(FMemory::Malloc(ElementSize * SizeX * SizeY));
|
|
FMemory::Memzero(Data, ElementSize * SizeX * SizeY);
|
|
}
|
|
|
|
inline uint8* SampleRawPtr(const FVector2f& UV) const
|
|
{
|
|
// Wrapped addressing (uses FMath::FloorToInt and not appFractional, as appFractional causes the
|
|
// following mapping:
|
|
// .4 -> .4
|
|
// -1.4 -> .4
|
|
// (.4 - 1 = -.6) -> .6
|
|
//
|
|
// we need:
|
|
// .4 -> .4
|
|
// -1.4 -> .6
|
|
// (.4 - 1 = -.6) -> .4
|
|
//
|
|
// because when you subtract 1 from a UV it needs to have the exact same fractional part
|
|
const int32 X = FMath::Clamp(FMath::TruncToInt((UV.X - FMath::FloorToInt(UV.X)) * SizeX), 0, SizeX - 1);
|
|
const int32 Y = FMath::Clamp(FMath::TruncToInt((UV.Y - FMath::FloorToInt(UV.Y)) * SizeY), 0, SizeY - 1);
|
|
// Byte index into Data
|
|
const int32 DataIndex = Y * SizeX * ElementSize + X * ElementSize;
|
|
return &Data[DataIndex];
|
|
}
|
|
|
|
inline FLinearColor Sample(const FVector2f& UV) const
|
|
{
|
|
uint8* RawPtr = SampleRawPtr( UV );
|
|
|
|
// Only supporting these formats
|
|
checkSlow(Format == TF_ARGB8 || Format == TF_ARGB16F);
|
|
|
|
if (Format == TF_ARGB16F)
|
|
{
|
|
// Lookup and convert to FP32, no filtering
|
|
return FLinearColor(*(FFloat16Color*)RawPtr);
|
|
}
|
|
// Lookup and convert linear space and FP32, no filtering
|
|
return FLinearColor(*(FColor*)RawPtr);
|
|
}
|
|
|
|
inline FVector4f SampleNormal(const FVector2f& UV) const
|
|
{
|
|
uint8* RawPtr = SampleRawPtr( UV );
|
|
|
|
// Only supporting these formats
|
|
checkSlow(Format == TF_ARGB16F);
|
|
FFloat16Color* Float16Color = (FFloat16Color*)RawPtr;
|
|
|
|
FVector4f Normal( Float16Color->R.GetFloat(), Float16Color->G.GetFloat(), Float16Color->B.GetFloat(), 0.0f );
|
|
return Normal;
|
|
}
|
|
};
|
|
|
|
} //namespace Lightmass
|