Initial commit

This commit is contained in:
alexpete
2021-03-05 11:26:34 -08:00
commit a10351f38d
27091 changed files with 5521199 additions and 0 deletions
+129
View File
@@ -0,0 +1,129 @@
//=============================================================================
//CBBoxInt32
// 3D bounding box with int32 coordinates
//
//=============================================================================
// (C) 2005 ATI Research, Inc., All rights reserved.
//=============================================================================
// modifications by Crytek GmbH
// modifications by Amazon
#include <ImageProcessing_precompiled.h>
#include "CBBoxInt32.h"
#define CP_MIN_INT32 0x80000000
#define CP_MAX_INT32 0x7fffffff
#define CP_MIN(a, b) (((a) < (b)) ? (a) : (b))
#define CP_MAX(a, b) (((a) > (b)) ? (a) : (b))
namespace ImageProcessing
{
//--------------------------------------------------------------------------------------
// CBBoxInt32
//--------------------------------------------------------------------------------------
CBBoxInt32::CBBoxInt32(void)
{
Clear();
}
//--------------------------------------------------------------------------------------
// Text to see if CBBoxInt32 is empty or not
//--------------------------------------------------------------------------------------
bool CBBoxInt32::Empty(void)
{
if ((m_minCoord[0] > m_maxCoord[0]) ||
(m_minCoord[1] > m_maxCoord[1]) ||
(m_minCoord[2] > m_maxCoord[2]))
{
return true;
}
else
{
return false;
}
}
//--------------------------------------------------------------------------------------
// Clear bounding box extents
//--------------------------------------------------------------------------------------
void CBBoxInt32::Clear(void)
{
m_minCoord[0] = CP_MAX_INT32;
m_minCoord[1] = CP_MAX_INT32;
m_minCoord[2] = CP_MAX_INT32;
m_maxCoord[0] = CP_MIN_INT32;
m_maxCoord[1] = CP_MIN_INT32;
m_maxCoord[2] = CP_MIN_INT32;
}
//--------------------------------------------------------------------------------------
// Augment bounding box extents by specifying point to include in bounding box
//--------------------------------------------------------------------------------------
void CBBoxInt32::Augment(int32 aX, int32 aY, int32 aZ)
{
m_minCoord[0] = CP_MIN(m_minCoord[0], aX);
m_minCoord[1] = CP_MIN(m_minCoord[1], aY);
m_minCoord[2] = CP_MIN(m_minCoord[2], aZ);
m_maxCoord[0] = CP_MAX(m_maxCoord[0], aX);
m_maxCoord[1] = CP_MAX(m_maxCoord[1], aY);
m_maxCoord[2] = CP_MAX(m_maxCoord[2], aZ);
}
//--------------------------------------------------------------------------------------
// Augment bounding box extents by specifying x coordinate to include in bounding box
//--------------------------------------------------------------------------------------
void CBBoxInt32::AugmentX(int32 aX)
{
m_minCoord[0] = CP_MIN(m_minCoord[0], aX);
m_maxCoord[0] = CP_MAX(m_maxCoord[0], aX);
}
//--------------------------------------------------------------------------------------
// Augment bounding box extents by specifying x coordinate to include in bounding box
//--------------------------------------------------------------------------------------
void CBBoxInt32::AugmentY(int32 aY)
{
m_minCoord[1] = CP_MIN(m_minCoord[1], aY);
m_maxCoord[1] = CP_MAX(m_maxCoord[1], aY);
}
//--------------------------------------------------------------------------------------
// Augment bounding box extents by specifying x coordinate to include in bounding box
//--------------------------------------------------------------------------------------
void CBBoxInt32::AugmentZ(int32 aZ)
{
m_minCoord[2] = CP_MIN(m_minCoord[2], aZ);
m_maxCoord[2] = CP_MAX(m_maxCoord[2], aZ);
}
//--------------------------------------------------------------------------------------
// Clamp minimum values in bbox to be no larger than aX, aY, aZ
//--------------------------------------------------------------------------------------
void CBBoxInt32::ClampMin(int32 aX, int32 aY, int32 aZ)
{
m_minCoord[0] = CP_MAX(m_minCoord[0], aX);
m_minCoord[1] = CP_MAX(m_minCoord[1], aY);
m_minCoord[2] = CP_MAX(m_minCoord[2], aZ);
}
//--------------------------------------------------------------------------------------
// Clamp maximum values in bbox to be no larger than aX, aY, aZ
//--------------------------------------------------------------------------------------
void CBBoxInt32::ClampMax(int32 aX, int32 aY, int32 aZ)
{
m_maxCoord[0] = CP_MIN(m_maxCoord[0], aX);
m_maxCoord[1] = CP_MIN(m_maxCoord[1], aY);
m_maxCoord[2] = CP_MIN(m_maxCoord[2], aZ);
}
} //namespace ImageProcessing
+32
View File
@@ -0,0 +1,32 @@
//=============================================================================
//CBBoxInt32
// 3D bounding box with int32 coordinates
//
//=============================================================================
// (C) 2005 ATI Research, Inc., All rights reserved.
//=============================================================================
// modifications by Crytek GmbH
// modifications by Amazon
#pragma once
namespace ImageProcessing
{
//bounding box class with coords specified as int32
class CBBoxInt32
{
public:
int32 m_minCoord[3]; //upper left back corner
int32 m_maxCoord[3]; //lower right front corner
CBBoxInt32();
bool Empty(void);
void Clear(void);
void Augment(int32 a_X, int32 a_Y, int32 a_Z);
void AugmentX(int32 a_X);
void AugmentY(int32 a_Y);
void AugmentZ(int32 a_Z);
void ClampMin(int32 a_X, int32 a_Y, int32 a_Z);
void ClampMax(int32 a_X, int32 a_Y, int32 a_Z);
};
} //namespace ImageProcessing
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,595 @@
//--------------------------------------------------------------------------------------
//CCubeMapProcessor
// Class for filtering and processing cubemaps
//
//
//--------------------------------------------------------------------------------------
// (C) 2005 ATI Research, Inc., All rights reserved.
//--------------------------------------------------------------------------------------
// modifications by Crytek GmbH
// modifications by Amazon
#pragma once
#include <math.h>
#include <stdio.h>
#include <AzCore/std/parallel/thread.h>
#include <AzCore/std/parallel/atomic.h>
#include "VectorMacros.h"
#include "CBBoxInt32.h"
#include "CImageSurface.h"
//has routines for saving .rgbe files
#define CG_RGBE_SUPPORT
#ifndef WCHAR
#define WCHAR wchar_t
#endif //WCHAR
//used to index cube faces
#define CP_FACE_X_POS 0
#define CP_FACE_X_NEG 1
#define CP_FACE_Y_POS 2
#define CP_FACE_Y_NEG 3
#define CP_FACE_Z_POS 4
#define CP_FACE_Z_NEG 5
//used to index image edges
// NOTE.. the actual number corresponding to the edge is important
// do not change these, or the code will break
//
// CP_EDGE_LEFT is u = 0
// CP_EDGE_RIGHT is u = width-1
// CP_EDGE_TOP is v = 0
// CP_EDGE_BOTTOM is v = height-1
#define CP_EDGE_LEFT 0
#define CP_EDGE_RIGHT 1
#define CP_EDGE_TOP 2
#define CP_EDGE_BOTTOM 3
//corners of CUBE map (P or N specifys if it corresponds to the
// positive or negative direction each of X, Y, and Z
#define CP_CORNER_NNN 0
#define CP_CORNER_NNP 1
#define CP_CORNER_NPN 2
#define CP_CORNER_NPP 3
#define CP_CORNER_PNN 4
#define CP_CORNER_PNP 5
#define CP_CORNER_PPN 6
#define CP_CORNER_PPP 7
//data types processed by cube map processor
// note that UNORM data types use the full range
// of the unsigned integer to represent the range [0, 1] inclusive
// the float16 datatype is stored as D3Ds S10E5 representation
#define CP_VAL_UNORM8 0
#define CP_VAL_UNORM8_BGRA 1
#define CP_VAL_UNORM16 10
#define CP_VAL_FLOAT16 20
#define CP_VAL_FLOAT32 30
//return codes for thread execution
// warning STILL_ACTIVE maps to 259, so the number 259 is reserved in this case
// and should only be used for STILL_ACTIVE
#define CP_THREAD_COMPLETED 0
#define CP_THREAD_TERMINATED 15
#define CP_THREAD_STILL_ACTIVE STILL_ACTIVE
#define CP_MAX_PROGRESS_STRING 1024
// Type of data used internally by cube map processor
// just in case for any reason more preecision is needed,
// this type can be changed down the road
#define CP_ITYPE float
// Filter type
#define CP_FILTER_TYPE_DISC 0
#define CP_FILTER_TYPE_CONE 1
#define CP_FILTER_TYPE_COSINE 2
#define CP_FILTER_TYPE_ANGULAR_GAUSSIAN 3
#define CP_FILTER_TYPE_COSINE_POWER 4
#define CP_FILTER_TYPE_GGX 5
// Edge fixup type (how to perform smoothing near edge region)
#define CP_FIXUP_NONE 0
#define CP_FIXUP_PULL_LINEAR 1
#define CP_FIXUP_PULL_HERMITE 2
#define CP_FIXUP_AVERAGE_LINEAR 3
#define CP_FIXUP_AVERAGE_HERMITE 4
// Max potential cubemap size is limited to 65k (2^16 texels) on a side
#define CP_MAX_MIPLEVELS 16
//maximum number of threads running for cubemap processor is 2
#define CP_MAX_FILTER_THREADS 2
//initial number of filtering threads for cubemap processor
#define CP_INITIAL_NUM_FILTER_THREADS 1
//current status of cubemap processor
#define CP_STATUS_READY 0
#define CP_STATUS_PROCESSING 1
#define CP_STATUS_FILTER_TERMINATED 2
#define CP_STATUS_FILTER_COMPLETED 3
#define CP_SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
#define CP_SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } }
namespace ImageProcessing
{
//information about cube maps neighboring face after traversing
// across an edge
struct CPCubeMapNeighbor
{
uint8 m_Face; //index of neighboring face
uint8 m_Edge; //edge in neighboring face that abuts this face
};
//--------------------------------------------------------------------------------------------------
//structure used to store current progress of the filtering
//--------------------------------------------------------------------------------------------------
struct SFilterProgress
{
//status of current cube map processing
int32 m_CurrentFace;
int32 m_CurrentRow;
int32 m_CurrentMipLevel;
int32 m_StartFace;
int32 m_EndFace;
float m_FractionCompleted; //Approximate fraction of work completed for this thread
};
//--------------------------------------------------------------------------------------------------
//structure used to pass filtering parameters for Thread 0
//--------------------------------------------------------------------------------------------------
struct SThreadOptionsThread0
{
class CCubeMapProcessor *m_cmProc;
float m_BaseFilterAngle;
float m_InitialMipAngle;
float m_MipAnglePerLevelScale;
float m_GlossScale;
float m_GlossBias;
int32 m_FilterType;
int32 m_FixupType;
int32 m_FixupWidth;
int32 m_SampleCountGGX;
bool m_bUseSolidAngle;
};
//--------------------------------------------------------------------------------------------------
//structure used to pass filtering parameters to the process for Thread 1 (if used)
//--------------------------------------------------------------------------------------------------
struct SThreadOptionsThread1
{
class CCubeMapProcessor *m_cmProc;
CImageSurface *m_SrcCubeMap;
CImageSurface *m_DstCubeMap;
float m_FilterConeAngle;
int32 m_FilterType;
bool m_bUseSolidAngle;
int32 m_FaceIdxStart;
int32 m_FaceIdxEnd;
int32 m_ThreadIdx;
};
//--------------------------------------------------------------------------------------------------
//Class to filter, perform edge fixup, and build a mip chain for a cubemap
//--------------------------------------------------------------------------------------------------
class CCubeMapProcessor
{
public:
//cubemap processor status
int32 m_Status;
//information about threads actively processing the cubemap
int32 m_NumFilterThreads;
bool m_bThreadInitialized[CP_MAX_FILTER_THREADS];
AZStd::thread m_ThreadHandle[CP_MAX_FILTER_THREADS];
AZ::u32 m_ThreadID[CP_MAX_FILTER_THREADS];
SFilterProgress m_ThreadProgress[CP_MAX_FILTER_THREADS];
WCHAR m_ProgressString[CP_MAX_PROGRESS_STRING];
//filtering parameters last used for filtering
float m_BaseFilterAngle;
float m_InitialMipAngle;
float m_MipAnglePerLevelScale;
int32 m_InputSize; //input cubemap size (e.g. face width and height of topmost mip level)
int32 m_OutputSize; //output cubemap size (e.g. face width and height of topmost mip level)
int32 m_NumMipLevels; //number of output mip levels
int32 m_NumChannels; //number of channels in cube map processor
CP_ITYPE *m_FilterLUT; //filter weight lookup table (scale dot product 0-1 range to index into it)
int32 m_NumFilterLUTEntries; //number of filter lookup table entries
CImageSurface m_NormCubeMap[6]; //normalizer cube map and solid angle lookup table
CImageSurface m_InputSurface[6]; //input faces for topmost mip level
CImageSurface m_OutputSurface[CP_MAX_MIPLEVELS][6]; //output faces for all mip levels
private:
//==========================================================================================================
//BuildNormalizerCubemap(int32 a_Size, CImageSurface *a_Surface );
// Builds a normalizer cubemap of size a_Size. This routine deallocates the CImageSurfaces passed
// into the the function and reallocates them with the correct size and 3 channels to store the
// normalized vector for each texel.
//
// a_Size [in] size of normalizer cubemap
// a_Surface [out] Pointer to array of 6 CImageSurfaces where normalizer cube faces will be stored
//
//==========================================================================================================
void BuildNormalizerCubemap(int32 a_Size, CImageSurface *a_Surface);
//==========================================================================================================
//void BuildNormalizerSolidAngleCubemap(int32 a_Size, CImageSurface *a_Surface );
// Builds a normalizer|solid angle cubemap of size a_Size. This routine deallocates the CImageSurfaces
// passed into the the function and reallocates them with the correct size and 4 channels to store the
// normalized vector, and solid angle for each texel.
//
// a_Size [in]
// a_Surface [out] Pointer to array of 6 CImageSurfaces where normalizer cube faces will be stored
//
//==========================================================================================================
void BuildNormalizerSolidAngleCubemap(int32 a_Size, CImageSurface *a_Surface);
//==========================================================================================================
//Clears filter extent bounding boxes for each face of the cubemap
//
// a_FilterExtents [in] Array of 6 bounding boxes (corresponding to the 6 cubemap faces) to clear
//==========================================================================================================
void ClearFilterExtents(CBBoxInt32 *a_FilterExtents);
//==========================================================================================================
//void DetermineFilterExtents(float *a_CenterTapDir, int32 a_SrcSize, int32 a_BBoxSize,
// CBBoxInt32 *a_FilterExtents);
//
//Determines bounding boxes for each cube face for a single kernels angular extent
// a_CenterTapDir [in] Vector of 3 float32s specifying the center tap direction
// a_SrcSize [in] Source cubemap size (for the miplevel used as input to the filtering)
// a_BBoxSize [in] Maximum length in texels of the bbox extent derived from the filtering
// cone angle
// a_FilterExtents [out] Array of 6 bounding boxes (corresponding to the 6 cubemap faces) to clear
//==========================================================================================================
void DetermineFilterExtents(float *a_CenterTapDir, int32 a_SrcSize, int32 a_BBoxSize, CBBoxInt32 *a_FilterExtents);
//==========================================================================================================
//void ProcessFilterExtents(float *a_CenterTapDir, float a_DotProdThresh, CBBoxInt32 *a_FilterExtents,
// CImageSurface *a_NormCubeMap, CImageSurface *a_SrcCubeMap, CP_ITYPE *a_DstVal, uint32 a_FilterType,
// bool a_bUseSolidAngle );
//
//Processes all the texels within the bounding boxes in order to accumulate all the weighted taps to
// compute a single fitered texel value.
//
//a_CenterTapDir [in] Center tap directions
//a_DotProdThresh [in] Threshhold on dot product between center tap and
//a_FilterExtents [in] array of 6 bounding boxes describing rough filter extents for each face
//a_NormCubeMap [in] normalizer|solid angle cubemap
//a_SrcCubeMap [in] array of 6 faces comprising the miplevel of the source cubemap the filter is
// generated from
//a_DstVal [out] resulting filtered texel color
//a_FilterType [in] filter type: Choose one of the following options: CP_FILTER_TYPE_DISC,
// CP_FILTER_TYPE_CONE, CP_FILTER_TYPE_COSINE, CP_FILTER_TYPE_ANGULAR_GAUSSIAN
//a_bUseSolidAngle [in] Set this to true in order to incorporate the solid angle subtended
// each texel in the filter kernel in the filtering.
//
//==========================================================================================================
void ProcessFilterExtents(float *a_CenterTapDir, float a_DotProdThresh, CBBoxInt32 *a_FilterExtents,
CImageSurface *a_NormCubeMap, CImageSurface *a_SrcCubeMap, CP_ITYPE *a_DstVal, uint32 a_FilterType,
bool a_bUseSolidAngle, float a_SpecularPower);
//==========================================================================================================
//void FixupCubeEdges(CImageSurface *a_CubeMap, int32 a_FixupType, int32 a_FixupWidth);
//
//Apply edge fixup to a cubemap mip level.
//
//a_CubeMap [in/out] Array of 6 images comprising cubemap miplevel to apply edge fixup to.
//a_FixupType [in] Specifies the technique used for edge fixup. Choose one of the following,
// CP_FIXUP_NONE, CP_FIXUP_PULL_LINEAR, CP_FIXUP_PULL_HERMITE, CP_FIXUP_AVERAGE_LINEAR,
// CP_FIXUP_AVERAGE_HERMITE
//a_FixupWidth [in] Fixup width in texels
//
//==========================================================================================================
void FixupCubeEdges(CImageSurface *a_CubeMap, int32 a_FixupType, int32 a_FixupWidth);
//==========================================================================================================
//void BuildAngleWeightLUT(int32 a_NumFilterLUTEntries, int32 a_FilterType, float a_FilterAngle);
//
// Builds filter weight lookup table in order to quickly evaluate the weight of a particular texel
// for the Cone and Angular Gaussian fiter types. This lookup table is quickly indexed using the
// same dot product between the center tap and current texel that is used to determine whether a
// texel is inside or outside the filtering kernel.
//
//a_NumFilterLUTEntries [in] Number of entries in filter weight lookup table
//a_FilterType [in] Filter type
//a_FilterAngle [in] Filtering half cone angle
//==========================================================================================================
void BuildAngleWeightLUT(int32 a_NumFilterLUTEntries, int32 a_FilterType, float a_FilterAngle);
//==========================================================================================================
//void PrecomputeFilterLookupTables(uint32 a_FilterType, int32 a_SrcCubeMapWidth, float a_FilterConeAngle);
//
// Builds the following lookup tables prior to filtering:
// -normalizer cube map
// -filter weight lookup table
//
//a_FilterType [in] Filter type
//a_SrcCubeMapWidth [in] source cubemap size
//a_FilterConeAngle [in] Filtering half cone angle
//==========================================================================================================
void PrecomputeFilterLookupTables(uint32 a_FilterType, int32 a_SrcCubeMapWidth, float a_FilterConeAngle);
//==========================================================================================================
//void EstimateFilterThreadProgress(SFilterProgress *a_FilterProgress);
//
// Estimates percentage complete for a filtering thread for the current tap that is being filtered
//
//a_FilterProgress [in/out] Information about the filtereing thread's current position, and range of faces
// that it will process.
//==========================================================================================================
void EstimateFilterThreadProgress(SFilterProgress *a_FilterProgress);
public:
//==========================================================================================================
//note that these functions are only public so that they can be called from within the global scope
// from the thread starting point functions. These should not be called by any other functions external
// to the class.
//==========================================================================================================
void FilterCubeMapMipChain(float a_BaseFilterAngle, float a_InitialMipAngle, float a_MipAnglePerLevelScale,
int32 a_FilterType, int32 a_FixupType, int32 a_FixupWidth, bool a_bUseSolidAngle, float a_GlossScale, float a_GlossBias,
int32 a_SampleCountGGX);
void FilterCubeSurfaces(CImageSurface *a_SrcCubeMap, CImageSurface *a_DstCubeMap, float a_FilterConeAngle,
int32 a_FilterType, bool a_bUseSolidAngle, int32 a_FaceIdxStart, int32 a_FaceIdxEnd, int32 aThreadIdx,
float a_SpecularPower = 1.0f);
void FilterCubeSurfacesGGX(CImageSurface *a_SrcCubeMap, CImageSurface *a_DstCubeMap, int32 a_SampleCount, float a_Roughness,
int32 a_FaceIdxStart, int32 a_FaceIdxEnd, int32 aThreadIdx);
public:
CCubeMapProcessor(void);
~CCubeMapProcessor();
//==========================================================================================================
// void Init(int32 a_InputSize, int32 a_OutputSize, int32 a_NumMipLevels, int32 a_NumChannels);
//
// Initializes cube map processor class
//
// a_InputSize [in] Size of the input cubemap
// a_OutputSize [in] Size of the input cubemap
// a_NumMipLevels [in] Number of miplevels in the output cubemap
// a_NumChannels [in] Number of color channels (internally) in the input and output cubemap
//==========================================================================================================
void Init(int32 a_InputSize, int32 a_OutputSize, int32 a_NumMipLevels, int32 a_NumChannels);
//==========================================================================================================
// void GetInputFaceData(int32 a_FaceIdx, int32 a_DstType, int32 a_DstNumChannels, int32 a_DstPitch,
// void *a_DstDataPtr, float a_Scale, float a_Gamma);
//
// Copies image data from the input cube map into a destination image. These routine describe the output
// image layout using a pitch and a pointer so that the image can be copied from a subrect of a locked
// D3D surface easily. Note that when reading out the image data, the intensity scale is applied first,
// and then degamma.
//
// a_FaceIdx [in] Index (0-5) of the input cubemap cube face to read the image data from.
// a_DstType [in] Data type for the image data being copied out the input cube map.
// choose one of the following: CP_VAL_UNORM8, CP_VAL_UNORM8_BGRA, CP_VAL_UNORM16
// CP_VAL_FLOAT16, CP_VAL_FLOAT32.
// a_DstNumChannels [in] Number of channels in the destination image.
// a_DstPitch [in] Pitch in bytes of the destination image.
// a_DstDataPtr [in] Pointer to the top-left pixel in the destination image.
// a_Scale [in] Scale factor to apply to intensities.
// a_Gamma [in] Degamma to apply to intensities.
//
//==========================================================================================================
void GetInputFaceData(int32 a_FaceIdx, int32 a_DstType, int32 a_DstNumChannels, int32 a_DstPitch,
void *a_DstDataPtr, float a_Scale, float a_Gamma);
//==========================================================================================================
// void SetInputFaceData(int32 a_FaceIdx, int32 a_SrcType, int32 a_SrcNumChannels, int32 a_SrcPitch,
// void *a_SrcDataPtr, float a_MaxClamp, float a_Scale, float a_Gamma );
//
// Copies image data from a source image into one of the faces in the input cubemap in the cubemap.
// processor. These routines describe the output image layout using a pitch and a pointer so that the image
// can be copied from a subrect of a locked D3D surface easily. Note that the clamping is applied first,
// followed by the scale and then gamma.
//
// a_FaceIdx [in] Index (0-5) of the input cubemap cube face to write the image data into
// a_SrcType [in] Data type for the image data being copied into the cube map processor.
// choose one of the following: CP_VAL_UNORM8, CP_VAL_UNORM8_BGRA, CP_VAL_UNORM16
// CP_VAL_FLOAT16, CP_VAL_FLOAT32.
// a_SrcNumChannels [in] Number of channels in the source image.
// a_SrcPitch [in] Pitch in bytes of the source image.
// a_SrcDataPtr [in] Pointer to the top-left pixel in the source image.
// a_MaxClamp [in] Max value to clamp the input intensity values to.
// a_Degamma [in] Degamma to apply to input intensities.
// a_Scale [in] Scale factor to apply to input intensities.
//
//==========================================================================================================
void SetInputFaceData(int32 a_FaceIdx, int32 a_SrcType, int32 a_SrcNumChannels, int32 a_SrcPitch,
void *a_SrcDataPtr, float a_MaxClamp, float a_Degamma, float a_Scale);
//==========================================================================================================
// void GetOutputFaceData(int32 a_FaceIdx, int32 a_Level, int32 a_DstType, int32 a_DstNumChannels, int32 a_DstPitch,
// void *a_DstDataPtr, float a_Scale, float a_Gamma );
//
// a_FaceIdx [in] Index (0-5) of the output cubemap cube face to read the image data from.
// a_Level [in] Miplevel of the output cubemap to read from
// a_DstType [in] Data type for the image data being copied out the input cube map.
// choose one of the following: CP_VAL_UNORM8, CP_VAL_UNORM8_BGRA, CP_VAL_UNORM16
// CP_VAL_FLOAT16, CP_VAL_FLOAT32
// a_DstNumChannels [in] Number of channels in the destination image.
// a_DstPitch [in] Pitch in bytes of the destination image.
// a_DstDataPtr [in] Pointer to the top-left pixel in the destination image.
// a_Scale [in] Scale factor to apply to intensities.
// a_Gamma [in] Degamma to apply to intensities.
//
//==========================================================================================================
void GetOutputFaceData(int32 a_FaceIdx, int32 a_Level, int32 a_DstType, int32 a_DstNumChannels, int32 a_DstPitch,
void *a_DstDataPtr, float a_Scale, float a_Gamma);
//==========================================================================================================
//void InitiateFiltering(float a_BaseFilterAngle, float a_InitialMipAngle, float a_MipAnglePerLevelScale,
// int32 a_FilterType, int32 a_FixupType, int32 a_FixupWidth, bool a_bUseSolidAngle );
//
// Starts filtering the cubemap.
// If the number of filter threads is zero, the function does not return until the filtering is complete
// If the number of filter threads is non-zero, a filtering thread (or multiple threads) are started and
// the function returns immediately, with the threads running in the background.
//
// The cube map filtereing is specified using a number of parameters:
// Filtering per miplevel is specified using 2D cone angle (in degrees) that
// indicates the region of the hemisphere to filter over for each tap.
//
// Note that the top mip level is also a filtered version of the original input images
// as well in order to create mip chains for diffuse environment illumination.
// The cone angle for the top level is specified by a_BaseAngle. This can be used to
// generate mipchains used to store the results of preintegration across the hemisphere.
//
// The angle for the subsequent levels of the mip chain are specified by their parents
// filtering angle and a per-level scale and bias
// newAngle = oldAngle * a_MipAnglePerLevelScale;
//
// a_BaseFilterAngle [in] Base filter angle
// a_InitialMipAngle [in] Mip angle used to generate the next level of the mip chain from the base level
// a_MipAnglePerLevelScale [in] Scale factor to iteratively apply to the filtering angle to filter subsequent
// mip-levels.
// a_FilterType [in] Specifies the filtering type for angular extent filtering. Choose one of the
// following options: CP_FILTER_TYPE_DISC, CP_FILTER_TYPE_CONE,
// CP_FILTER_TYPE_COSINE, CP_FILTER_TYPE_ANGULAR_GAUSSIAN
// a_FixupType [in] Specifies the technique used for edge fixup. Choose one of the following,
// CP_FIXUP_NONE, CP_FIXUP_PULL_LINEAR, CP_FIXUP_PULL_HERMITE,
// CP_FIXUP_AVERAGE_LINEAR, CP_FIXUP_AVERAGE_HERMITE
// a_FixupWidth [in] Width in texels of the fixup region.
// a_bUseSolidAngle [in] Set this to true in order to incorporate the solid angle subtended
// each texel in the filter kernel in the filtering.
//==========================================================================================================
void InitiateFiltering(float a_BaseFilterAngle, float a_InitialMipAngle, float a_MipAnglePerLevelScale,
int32 a_FilterType, int32 a_FixupType, int32 a_FixupWidth, bool a_bUseSolidAngle,
float a_GlossScale, float a_GlossBias, int32 a_SampleCountGGX);
//==========================================================================================================
// void WriteMipLevelIntoAlpha(void)
//
// Encodes the miplevel in the alpha channel of the output cubemap.
// The miplevel is encoded as (miplevel * 16.0f / 255.0f) so that the miplevel has an exact encoding in an
// 8-bit or 16-bit UNORM representation.
//
//==========================================================================================================
void WriteMipLevelIntoAlpha(void);
//==========================================================================================================
// Horizontally flips all the faces in the input cubemap
//
//==========================================================================================================
void FlipInputCubemapFaces(void);
//==========================================================================================================
// Horizontally flips all the faces in the output cubemap
//
//==========================================================================================================
void FlipOutputCubemapFaces(void);
//==========================================================================================================
// Allows for in-place color channel swapping of the input cubemap. This routine can be useful for
// converting RGBA format data to BGRA format data.
//
// a_Channel0Src [in] Index of the color channel used as the source for the new channel 0
// a_Channel1Src [in] Index of the color channel used as the source for the new channel 1
// a_Channel2Src [in] Index of the color channel used as the source for the new channel 0
// a_Channel3Src [in] Index of the color channel used as the source for the new channel 1
//
//==========================================================================================================
void ChannelSwapInputFaceData(int32 a_Channel0Src, int32 a_Channel1Src, int32 a_Channel2Src, int32 a_Channel3Src);
//==========================================================================================================
// Allows for in-place color channel swapping of the output cubemap. This routine can be useful for
// converting RGBA format data to BGRA format data.
//
// a_Channel0Src [in] Index of the color channel used as the source for the new channel 0
// a_Channel1Src [in] Index of the color channel used as the source for the new channel 1
// a_Channel2Src [in] Index of the color channel used as the source for the new channel 0
// a_Channel3Src [in] Index of the color channel used as the source for the new channel 1
//==========================================================================================================
void ChannelSwapOutputFaceData(int32 a_Channel0Src, int32 a_Channel1Src, int32 a_Channel2Src, int32 a_Channel3Src);
//==========================================================================================================
// Resets the current cubemap processor, and deallocates the input and output cubemaps.
//
// This function is automatically called by destructor.
//==========================================================================================================
void Clear(void);
//==========================================================================================================
// Terminates any active filtering threads. This stops the filtering of the current cubemap.
//
//==========================================================================================================
void TerminateActiveThreads(void);
//==========================================================================================================
// Gets the current filtering progress string
//
//==========================================================================================================
WCHAR *GetFilterProgressString(void);
//==========================================================================================================
// Checks to see if either of the filtering threads is active
//
//==========================================================================================================
bool IsFilterThreadActive(uint32 a_ThreadIdx);
//==========================================================================================================
// Gets the current status of the cubemap processing threads. The possible return values and their
// associated meanings are:
//
// CP_STATUS_READY: The cubemap processor is currently ready to change settings, and to load a
// new input cubemap.
// CP_STATUS_PROCESSING: The cubemap processor is currently filtering a cubemap
// CP_STATUS_FILTER_TERMINATED: The cubemap processor was terminated before the filtering was completed.
// CP_STATUS_FILTER_COMPLETED: The cubemap processor fully completed filtering the cubemap.
//
//==========================================================================================================
int32 GetStatus(void);
//==========================================================================================================
// This signifies to the cubemap processor that you have acknowledged a
// CP_STATUS_FILTER_TERMINATED or CP_STATUS_FILTER_COMPLETED status code, and would like to
// reset the cubemap processor to CP_STATUS_READY.
//==========================================================================================================
void RefreshStatus(void);
AZStd::atomic_bool m_shutdownWorkerThreadSignal; ///< Signals the worker threads to stop.
};
} // namespace ImageProcessing
@@ -0,0 +1,695 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
//--------------------------------------------------------------------------------------
//CImageSurface
// Class for storing, manipulating, and copying image data to and from D3D Surfaces
//
//--------------------------------------------------------------------------------------
// (C) 2005 ATI Research, Inc., All rights reserved.
//--------------------------------------------------------------------------------------
// modifications by Crytek GmbH
// modifications by Amazon
#include <ImageProcessing_precompiled.h>
#include "CImageSurface.h"
namespace ImageProcessing
{
//--------------------------------------------------------------------------------------
// convert D3D 16 bit float to standard 32 bit float
// Format:
//
// 1 sign bit in MSB, (s)
// 5 bits of biased exponent, (e)
// 10 bits of fraction, (f), with an additional hidden bit
// A float16 value, v, made from the format above takes the following meaning:
//
// (a) if e == 31 and f != 0, then v is NaN regardless of s
// (b) if e == 31 and f == 0, then v = (-1)^s * infinity (signed infinity)
// (c) if 0 < e < 31, then v = (-1)^s * 2^(e-15) * (1.f)
// (d) if e == 0 and f != 0, then v = (-1)^s * 2^(e-14) * (0.f) (denormalized numbers)
// (e) if e == 0 and f == 0, then v = (-1)^s *0 (signed zero)
//
//--------------------------------------------------------------------------------------
float CPf16Tof32(uint16 aVal)
{
uint32 signVal = (aVal >> 15); //sign bit in MSB
uint32 exponent = ((aVal >> 10) & 0x01f); //next 5 bits after signbit
uint32 mantissa = (aVal & 0x03ff); //lower 10 bits
uint32 rawFloat32Data; //raw binary float data
//convert s10e5 5-bit exponent to IEEE754 s23e8 8-bit exponent
if (exponent == 31)
{ // infinity or Nan depending on mantissa
exponent = 255;
}
else if (exponent == 0)
{ // denormalized floats mantissa is treated as = 0.f
exponent = 0;
}
else
{ //change 15base exponent to 127base exponent
//normalized floats mantissa is treated as = 1.f
exponent += (127 - 15);
}
//convert 10-bit mantissa to 23-bit mantissa
mantissa <<= (23 - 10);
//assemble s23e8 number using logical operations
rawFloat32Data = (signVal << 31) | (exponent << 23) | mantissa;
//treat raw data as a 32 bit float
return *((float *)&rawFloat32Data);
}
//--------------------------------------------------------------------------------------
// convert standard 32 bit float to D3D 16 bit float
//
// 16-bit float format:
//
// 1 sign bit in MSB, (s)
// 5 bits of biased exponent, (e)
// 10 bits of fraction, (f), with an additional hidden bit
// A float16 value, v, made from the format above takes the following meaning:
//
// (a) if e == 31 and f != 0, then v is NaN regardless of s
// (b) if e == 31 and f == 0, then v = (-1)s*infinity (signed infinity)
// (c) if 0 < e < 31, then v = (-1)s*2(e-15)*(1.f)
// (d) if e == 0 and f != 0, then v = (-1)s*2(e-14)*(0.f) (denormalized numbers)
// (e) if e == 0 and f == 0, then v = (-1)s*0 (signed zero)
//--------------------------------------------------------------------------------------
uint16 CPf32Tof16(float aVal)
{
uint32 rawf32Data = *((uint32 *)&aVal); //raw binary float data
uint32 signVal = (rawf32Data >> 31); //sign bit in MSB
uint32 exponent = ((rawf32Data >> 23) & 0xff); //next 8 bits after signbit
uint32 mantissa = (rawf32Data & 0x7fffff); //mantissa = lower 23 bits
uint16 rawf16Data;
//convert IEEE754 s23e8 8-bit exponent to s10e5 5-bit exponent
if (exponent == 255)
{//special case 32 bit float is inf or NaN, use mantissa as is
exponent = 31;
}
else if (exponent < ((127 - 15) - 10))
{//special case, if 32-bit float exponent is out of 16-bit float range, then set 16-bit float to 0
exponent = 0;
mantissa = 0;
}
else if (exponent >= (127 + (31 - 15)))
{ // max 15based exponent for s10e5 is 31
// force s10e5 number to represent infinity by setting mantissa to 0
// and exponent to 31
exponent = 31;
mantissa = 0;
}
else if (exponent <= (127 - 15))
{ //convert normalized s23e8 float to denormalized s10e5 float
//add implicit 1.0 to mantissa to convert from 1.f to use as a 0.f mantissa
mantissa |= (1 << 23);
//shift over mantissa number of bits equal to exponent underflow
mantissa = mantissa >> (1 + ((127 - 15) - exponent));
//zero exponent to treat value as a denormalized number
exponent = 0;
}
else
{ //change 127base exponent to 15base exponent
// no underflow or overflow of exponent
//normalized floats mantissa is treated as= 1.f, so
// no denormalization or exponent derived shifts to the mantissa
exponent -= (127 - 15);
}
//convert 23-bit mantissa to 10-bit mantissa
mantissa >>= (23 - 10);
//assemble s10e5 number using logical operations
rawf16Data = (signVal << 15) | (exponent << 10) | mantissa;
//return re-assembled raw data as a 32 bit float
return rawf16Data;
}
//--------------------------------------------------------------------------------------
//size of data types in bytes
//--------------------------------------------------------------------------------------
int32 CPTypeSizeOf(int32 a_Type)
{
switch (a_Type)
{
case CP_VAL_UNORM8:
case CP_VAL_UNORM8_BGRA:
return 1;
break;
case CP_VAL_UNORM16:
return 2;
break;
case CP_VAL_FLOAT16:
return 2;
break;
case CP_VAL_FLOAT32:
return 4;
break;
default:
return 1;
break;
}
}
//--------------------------------------------------------------------------------------
//get value of data pointed to by a_Ptr given type information
//--------------------------------------------------------------------------------------
CP_ITYPE CPTypeGetVal(int32 a_Type, void *a_Ptr)
{
switch (a_Type)
{
case CP_VAL_UNORM8:
case CP_VAL_UNORM8_BGRA:
return (1.0f / 255.0f) * *((uint8 *)a_Ptr);
break;
case CP_VAL_UNORM16:
return (1.0f / 65535.0f) * *((uint16 *)a_Ptr);
break;
case CP_VAL_FLOAT16:
return CPf16Tof32(*((uint16 *)a_Ptr));
break;
case CP_VAL_FLOAT32:
return *((float *)a_Ptr);
break;
default:
return 0;
break;
}
}
//--------------------------------------------------------------------------------------
//Given a CP_ITYPE value as input, convert it to the given type specified by a_Type
// and write the value to a_Ptr
//--------------------------------------------------------------------------------------
void CPTypeSetVal(CP_ITYPE a_Val, int32 a_Type, void *a_Ptr)
{
CP_ITYPE clampVal; //clamp value to 0-1 range to output UNORM types
switch (a_Type)
{
case CP_VAL_UNORM8:
case CP_VAL_UNORM8_BGRA:
clampVal = VM_MIN(VM_MAX(a_Val, 0.0f), 1.0f);
*((uint8 *)a_Ptr) = (uint8)(clampVal * 255.0f);
break;
case CP_VAL_UNORM16:
clampVal = VM_MIN(VM_MAX(a_Val, 0.0f), 1.0f);
*((uint16 *)a_Ptr) = (uint16)(clampVal * 65535.0f);
break;
case CP_VAL_FLOAT16:
*((uint16 *)a_Ptr) = CPf32Tof16(a_Val);
break;
case CP_VAL_FLOAT32:
*((float *)a_Ptr) = a_Val;
break;
default:
break;
}
}
//--------------------------------------------------------------------------------------
//Error handling for imagesurface class
// Pop up dialog box, and terminate application
//--------------------------------------------------------------------------------------
void CImageSurface::FatalError([[maybe_unused]] const WCHAR *a_Msg)
{
AZ_Error("Image Processing", false, "CImageSurface Error: %s", a_Msg);
}
//--------------------------------------------------------------------------------------
// Image surface
//--------------------------------------------------------------------------------------
CImageSurface::CImageSurface(void)
{
m_Width = 0; //cubemap face width
m_Height = 0; //cubemap face height
m_NumChannels = 0; //number of channels
m_ImgData = NULL;
}
//--------------------------------------------------------------------------------------
// Clear
//--------------------------------------------------------------------------------------
void CImageSurface::Clear(void)
{
m_Width = 0; //cubemap face width
m_Height = 0; //cubemap face height
m_NumChannels = 0; //number of channels
SAFE_DELETE_ARRAY(m_ImgData); //safe delete old image data
}
//--------------------------------------------------------------------------------------
// Initialize surface and associated memory
//--------------------------------------------------------------------------------------
void CImageSurface::Init(int32 a_Width, int32 a_Height, int32 a_NumChannels)
{
m_Width = a_Width; //cubemap face width
m_Height = a_Height; //cubemap face height
m_NumChannels = a_NumChannels; //number of channels
SAFE_DELETE_ARRAY(m_ImgData); //safe delete old image data
m_ImgData = new(std::nothrow) CP_ITYPE[m_Width * m_Height * m_NumChannels]; //assume tight data packing
if (!m_ImgData)
{
FatalError(L"Unable to allocate data for image in CImageSurface::Init.");
}
}
//--------------------------------------------------------------------------------------
//copy and convert data from external buffer into this surface
//
// note that srcPitch == the source pitch in bytes
//--------------------------------------------------------------------------------------
void CImageSurface::SetImageData(int32 a_SrcType, int32 a_SrcNumChannels, int32 a_SrcPitch, void *a_SrcDataPtr)
{
int32 i, j, k;
CP_ITYPE *dstDataWalk = m_ImgData;
uint8 *srcDataWalk = (uint8 *)a_SrcDataPtr;
int32 srcValueSize = CPTypeSizeOf(a_SrcType);
int32 srcTexelStep = srcValueSize * a_SrcNumChannels;
int32 numChannelsSet = VM_MIN(a_SrcNumChannels, m_NumChannels);
int32 srcChannelSelect;
//loop over rows
for (j = 0; j < m_Height; j++)
{
//pointer arithmetic to offset pointer by pitch in bytes
srcDataWalk = ((uint8 *)a_SrcDataPtr + (j * a_SrcPitch));
//loop over texels within row
for (i = 0; i < m_Width; i++)
{
srcChannelSelect = 0;
//loop over channels within texel
for (k = 0; k < numChannelsSet; k++)
{
if (a_SrcType == CP_VAL_UNORM8_BGRA) //swap channels 0, and 2 if in BGRA format
{
switch (k)
{
case 0:
*(dstDataWalk + 2) = CPTypeGetVal(a_SrcType, srcDataWalk + srcChannelSelect);
break;
case 2:
*(dstDataWalk + 0) = CPTypeGetVal(a_SrcType, srcDataWalk + srcChannelSelect);
break;
default:
*(dstDataWalk + k) = CPTypeGetVal(a_SrcType, srcDataWalk + srcChannelSelect);
break;
}
}
else
{
*(dstDataWalk + k) = CPTypeGetVal(a_SrcType, srcDataWalk + srcChannelSelect);
}
srcChannelSelect += srcValueSize;
}
dstDataWalk += m_NumChannels;
srcDataWalk += srcTexelStep;
}
}
}
//--------------------------------------------------------------------------------------
// Copy and convert data from external buffer into this surface set image data degamma
// and scale
//
//--------------------------------------------------------------------------------------
void CImageSurface::SetImageDataClampDegammaScale(int32 a_SrcType, int32 a_SrcNumChannels, int32 a_SrcPitch,
void *a_SrcDataPtr, float a_MaxClamp, float a_Gamma, float a_Scale)
{
int32 i, j, k;
CP_ITYPE *dstDataWalk = m_ImgData;
uint8 *srcDataWalk = (uint8 *)a_SrcDataPtr;
int32 srcValueSize = CPTypeSizeOf(a_SrcType);
int32 srcTexelStep = srcValueSize * a_SrcNumChannels;
int32 numChannelsSet = VM_MIN(a_SrcNumChannels, m_NumChannels);
int32 srcChannelSelect;
//loop over rows
for (j = 0; j < m_Height; j++)
{
//pointer arithmetic to offset pointer by pitch in bytes
srcDataWalk = ((uint8 *)a_SrcDataPtr + (j * a_SrcPitch));
//loop over texels within row
for (i = 0; i < m_Width; i++)
{
srcChannelSelect = 0;
//loop over channels within texel
for (k = 0; k < numChannelsSet; k++)
{
CP_ITYPE texelVal;
//get texel value from external buffer
texelVal = CPTypeGetVal(a_SrcType, srcDataWalk + srcChannelSelect);
//clamp texelVal using max value only
// (using texelVal as the min clamping arguement means no minimum clamping)
VM_CLAMP(texelVal, texelVal, texelVal, a_MaxClamp);
if (k < 3) //only apply gamma and scale to RGB channels
{
//degamma texel val, by raising to the power gamma
texelVal = pow(texelVal, a_Gamma);
//scale texel val in linear space (after degamma)
texelVal *= a_Scale;
}
//write data
if ((a_SrcType == CP_VAL_UNORM8_BGRA) && (k == 0))
{
*(dstDataWalk + 2) = texelVal;
}
else if ((a_SrcType == CP_VAL_UNORM8_BGRA) && (k == 2))
{
*(dstDataWalk + 0) = texelVal;
}
else
{
*(dstDataWalk + k) = texelVal;
}
srcChannelSelect += srcValueSize;
}
dstDataWalk += m_NumChannels;
srcDataWalk += srcTexelStep;
}
}
}
//--------------------------------------------------------------------------------------
//copy data from this image surface into an external buffer
//
//--------------------------------------------------------------------------------------
void CImageSurface::GetImageData(int32 a_DstType, int32 a_DstNumChannels, int32 a_DstPitch, void *a_DstDataPtr)
{
int32 i, j, k;
CP_ITYPE *srcDataWalk = m_ImgData;
uint8 *dstDataWalk = (uint8 *)a_DstDataPtr;
int32 dstValueSize = CPTypeSizeOf(a_DstType);
int32 dstTexelStep = dstValueSize * a_DstNumChannels;
int32 numChannelsSet = VM_MIN(a_DstNumChannels, m_NumChannels);
int32 dstChannelSelect;
//loop over rows
for (j = 0; j < m_Height; j++)
{
//pointer arithmetic to offset pointer by pitch in bytes
dstDataWalk = ((uint8 *)a_DstDataPtr + (j * a_DstPitch));
//loop over texels within row
for (i = 0; i < m_Width; i++)
{
dstChannelSelect = 0;
//loop over channels within texel
for (k = 0; k < numChannelsSet; k++)
{
//write data
if ((a_DstType == CP_VAL_UNORM8_BGRA) && (k == 0))
{
CPTypeSetVal(*(srcDataWalk + 2), a_DstType, dstDataWalk + dstChannelSelect);
}
else if ((a_DstType == CP_VAL_UNORM8_BGRA) && (k == 2))
{
CPTypeSetVal(*(srcDataWalk + 0), a_DstType, dstDataWalk + dstChannelSelect);
}
else
{
CPTypeSetVal(*(srcDataWalk + k), a_DstType, dstDataWalk + dstChannelSelect);
}
dstChannelSelect += dstValueSize;
}
srcDataWalk += m_NumChannels;
dstDataWalk += dstTexelStep;
}
}
}
//--------------------------------------------------------------------------------------
// Scale and then apply gamma to image data, then copy image data into an external buffer
// note: only apply scale and gamma to RGB channels (e.g. first 3 channels)
//
//--------------------------------------------------------------------------------------
void CImageSurface::GetImageDataScaleGamma(int32 a_DstType, int32 a_DstNumChannels, int32 a_DstPitch,
void *a_DstDataPtr, float a_Scale, float a_Gamma)
{
int32 i, j, k;
CP_ITYPE *srcDataWalk = m_ImgData;
uint8 *dstDataWalk = (uint8 *)a_DstDataPtr;
int32 dstValueSize = CPTypeSizeOf(a_DstType);
int32 dstTexelStep = dstValueSize * a_DstNumChannels;
int32 numChannelsSet = VM_MIN(a_DstNumChannels, m_NumChannels);
int32 dstChannelSelect;
//loop over rows
for (j = 0; j < m_Height; j++)
{
//pointer arithmetic to offset pointer by pitch in bytes
dstDataWalk = ((uint8 *)a_DstDataPtr + (j * a_DstPitch));
//loop over texels within row
for (i = 0; i < m_Width; i++)
{
dstChannelSelect = 0;
//loop over channels within texel
for (k = 0; k < numChannelsSet; k++)
{
CP_ITYPE texelVal;
texelVal = *(srcDataWalk + k);
if (k < 3) //only apply gamma and scale to RGB channels
{
//scale texel val
texelVal *= a_Scale;
//apply gamma to texel val by raising the texelVal to the power of (1/gamma)
texelVal = pow(texelVal, 1.0f / a_Gamma);
}
//write out texture value
if ((a_DstType == CP_VAL_UNORM8_BGRA) && (k == 0))
{
CPTypeSetVal(texelVal, a_DstType, dstDataWalk + (dstValueSize * 2));
}
else if ((a_DstType == CP_VAL_UNORM8_BGRA) && (k == 2))
{
CPTypeSetVal(texelVal, a_DstType, dstDataWalk + (dstValueSize * 0));
}
else
{
CPTypeSetVal(texelVal, a_DstType, dstDataWalk + dstChannelSelect);
}
dstChannelSelect += dstValueSize;
}
srcDataWalk += m_NumChannels;
dstDataWalk += dstTexelStep;
}
}
}
//--------------------------------------------------------------------------------------
//Set image channel a_ChannelIdx to a_ClearColor for all pixels.
//
//--------------------------------------------------------------------------------------
void CImageSurface::ClearChannelConst(int32 a_ChannelIdx, CP_ITYPE a_ClearColor)
{
int32 u, v;
CP_ITYPE *texelPtr;
//if channel does not exist, do not attempt to clear the channel
if (a_ChannelIdx > (m_NumChannels - 1))
{
return;
}
for (v = 0; v < m_Height; v++)
{
for (u = 0; u < m_Width; u++)
{
texelPtr = GetSurfaceTexelPtr(u, v);
*(texelPtr + a_ChannelIdx) = a_ClearColor;
}
}
}
//--------------------------------------------------------------------------------------
//Gets texel ptr in a surface given u and v coordinates,
//
//--------------------------------------------------------------------------------------
CP_ITYPE *CImageSurface::GetSurfaceTexelPtr(int32 u, int32 v)
{
return(m_ImgData + (((m_Width * v) + u) * m_NumChannels));
}
//--------------------------------------------------------------------------------------
//flips surface image in place horizontally
//
//--------------------------------------------------------------------------------------
void CImageSurface::InPlaceHorizonalFlip(void)
{
int32 u, v, k;
CP_ITYPE *texelPtrTop, *texelPtrBottom;
//iterate over V
for (v = 0; v < (m_Height / 2); v++)
{
for (u = 0; u < m_Height; u++)
{
texelPtrTop = GetSurfaceTexelPtr(u, v);
texelPtrBottom = GetSurfaceTexelPtr(u, (m_Height - 1) - v);
//iterate over channels
for (k = 0; k < m_NumChannels; k++)
{
CP_ITYPE tmpTexelVal;
tmpTexelVal = *(texelPtrTop + k);
*(texelPtrTop + k) = *(texelPtrBottom + k);
*(texelPtrBottom + k) = tmpTexelVal;
}
}
}
}
//--------------------------------------------------------------------------------------
//flips surface image in place vertically
//
//--------------------------------------------------------------------------------------
void CImageSurface::InPlaceVerticalFlip(void)
{
int32 u, v, k;
CP_ITYPE *texelPtrLeft, *texelPtrRight;
for (u = 0; u < (m_Width / 2); u++)
{
for (v = 0; v < m_Height; v++)
{
texelPtrLeft = GetSurfaceTexelPtr(u, v);
texelPtrRight = GetSurfaceTexelPtr((m_Width - 1) - u, v);
//iterate over channels
for (k = 0; k < m_NumChannels; k++)
{
CP_ITYPE tmpTexelVal;
tmpTexelVal = *(texelPtrLeft + k);
*(texelPtrLeft + k) = *(texelPtrRight + k);
*(texelPtrRight + k) = tmpTexelVal;
}
}
}
}
//--------------------------------------------------------------------------------------
//flip image around line defined by u = v (effectively swaps the u and v axises)
//--------------------------------------------------------------------------------------
void CImageSurface::InPlaceDiagonalUVFlip(void)
{
int32 u, v, k;
CP_ITYPE *texelPtrLeft, *texelPtrRight;
if (m_Width != m_Height)
{ //only flip image if square
return;
}
for (v = 0; v < m_Height; v++)
{
for (u = 0; u < v; u++) //only iterate over lower left triangle
{
texelPtrLeft = GetSurfaceTexelPtr(u, v);
texelPtrRight = GetSurfaceTexelPtr(v, u);
//iterate over channels
for (k = 0; k < m_NumChannels; k++)
{
CP_ITYPE tmpTexelVal;
tmpTexelVal = *(texelPtrLeft + k);
*(texelPtrLeft + k) = *(texelPtrRight + k);
*(texelPtrRight + k) = tmpTexelVal;
}
}
}
}
//--------------------------------------------------------------------------------------
// destructor, free all memory used
//--------------------------------------------------------------------------------------
CImageSurface::~CImageSurface()
{
SAFE_DELETE_ARRAY(m_ImgData);
}
} // namespace ImageProcessing
@@ -0,0 +1,94 @@
//--------------------------------------------------------------------------------------
//CImageSurface
// Class for storing, manipulating, and copying image data to and from D3D Surfaces
//
//--------------------------------------------------------------------------------------
// (C) 2005 ATI Research, Inc., All rights reserved.
//--------------------------------------------------------------------------------------
// modifications by Crytek GmbH
// modifications by Amazon
#pragma once
#include <math.h>
#include <stdio.h>
#include "VectorMacros.h"
#ifndef WCHAR
#define WCHAR wchar_t
#endif //WCHAR
#ifndef SAFE_DELETE
#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
#endif
#ifndef SAFE_DELETE_ARRAY
#define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } }
#endif
//Data types processed by cube map processor
// note that UNORM data types use the full range
// of the unsigned integer to represent the range [0, 1] inclusive
// the float16 datatype is stored as D3Ds S10E5 representation
#define CP_VAL_UNORM8 0
#define CP_VAL_UNORM8_BGRA 1
#define CP_VAL_UNORM16 10
#define CP_VAL_FLOAT16 20
#define CP_VAL_FLOAT32 30
// Type of data used internally by CSurfaceImage
#define CP_ITYPE float
namespace ImageProcessing
{
//2D images used to store cube faces for processing, note that this class is
// meant to facilitate the copying of data to and from D3D surfaces hence the name ImageSurface
class CImageSurface
{
public:
int32 m_Width; //image width
int32 m_Height; //image height
int32 m_NumChannels; //number of channels
CP_ITYPE *m_ImgData; //cubemap image data
private:
//fatal error
void FatalError(const WCHAR *a_Msg);
public:
CImageSurface(void);
void Clear(void);
void Init(int32 a_Width, int32 a_Height, int32 a_NumChannels);
//copy data from external buffer into this CImageSurface
void SetImageData(int32 a_SrcType, int32 a_SrcNumChannels, int32 a_SrcPitch, void *a_SrcDataPtr);
// copy image data from an external buffer and scale and degamma the data
void SetImageDataClampDegammaScale(int32 a_SrcType, int32 a_SrcNumChannels, int32 a_SrcPitch, void *a_SrcDataPtr,
float a_MaxClamp, float a_Degamma, float a_Scale);
//copy data from this CImageSurface into an external buffer
void GetImageData(int32 a_DstType, int32 a_DstNumChannels, int32 a_DstPitch, void *a_DstDataPtr);
//copy image data from an external buffer and scale and gamma the data
void GetImageDataScaleGamma(int32 a_DstType, int32 a_DstNumChannels, int32 a_DstPitch, void *a_DstDataPtr,
float a_Scale, float a_Gamma);
//clear one of the channels in the CSurfaceImage to a particular color
void ClearChannelConst(int32 a_ChannelIdx, CP_ITYPE a_ClearColor);
//various image operations that can be performed on the CImageSurface
void InPlaceVerticalFlip(void);
void InPlaceHorizonalFlip(void);
void InPlaceDiagonalUVFlip(void);
CP_ITYPE *GetSurfaceTexelPtr(int32 a_U, int32 a_V);
~CImageSurface();
};
} // namespace ImageProcessing
Binary file not shown.
+176
View File
@@ -0,0 +1,176 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
//--------------------------------------------------------------------------------------
// VectorMacros.h
//
// Fast operations on vectors, stored as arrays of floats
//
//--------------------------------------------------------------------------------------
// (C) 2001-2005 ATI Research, Inc. All rights reserved.
//--------------------------------------------------------------------------------------
// modifications by Crytek GmbH
//disable warning about doubles being converted down to float
#pragma warning (disable : 4244 )
#define VM_LARGE_FLOAT 3.7e37f
#define VM_MIN(a, b) (((a) < (b)) ? (a) : (b))
#define VM_MAX(a, b) (((a) > (b)) ? (a) : (b))
//clamping macros
#define VM_CLAMP(d, s, mn, mx){(d) = ((s)<(mx))?( ((s)>(mn))?(s):(mn) ):(mx); }
#define VM_CLAMP2_UNTYPED(d, s, mn, mx) {VM_CLAMP(d[0], s[0], mn, mx); VM_CLAMP(d[1], s[1], mn, mx);}
#define VM_CLAMP2(d, s, mn, mx) VM_CLAMP2_UNTYPED(((float *)(d)), ((float *)(s)), (float)(mn), (float)(mx))
#define VM_CLAMP3_UNTYPED(d, s, mn, mx) {VM_CLAMP(d[0], s[0], mn, mx); VM_CLAMP(d[1], s[1], mn, mx); VM_CLAMP(d[2], s[2], mn, mx);}
#define VM_CLAMP3(d, s, mn, mx) VM_CLAMP3_UNTYPED(((float *)(d)), ((float *)(s)), (float)(mn), (float)(mx))
#define VM_CLAMP4_UNTYPED(d, s, mn, mx) {VM_CLAMP(d[0], s[0], mn, mx); VM_CLAMP(d[1], s[1], mn, mx); VM_CLAMP(d[2], s[2], mn, mx); VM_CLAMP(d[3], s[3], mn, mx);}
#define VM_CLAMP4(d, s, mn, mx) VM_CLAMP4_UNTYPED(((float *)(d)), ((float *)(s)), (float)(mn), (float)(mx))
//set vectors
#define VM_SET2_UNTYPED(d, f) { d[0]=f; d[1]=f;}
#define VM_SET2(d, f) VM_SET2_UNTYPED(((float *)(d)), ((float)(f)))
#define VM_SET3_UNTYPED(d, f) { d[0]=f; d[1]=f; d[2]=f; }
#define VM_SET3(d, f) VM_SET3_UNTYPED(((float *)(d)), ((float)(f)))
#define VM_SET4_UNTYPED(d, f) { d[0]=f; d[1]=f; d[2]=f; d[3]=f; }
#define VM_SET4(d, f) VM_SET4_UNTYPED(((float *)(d)), ((float)(f)))
//copy vectors
#define VM_COPY2_UNTYPED(d, s) { d[0]=s[0]; d[1]=s[1];}
#define VM_COPY2(d, s) VM_COPY2_UNTYPED(((float *)(d)), ((float *)(s)))
#define VM_COPY3_UNTYPED(d, s) { d[0]=s[0]; d[1]=s[1]; d[2]=s[2]; }
#define VM_COPY3(d, s) VM_COPY3_UNTYPED(((float *)(d)), ((float *)(s)))
#define VM_COPY4_UNTYPED(d, s) { d[0]=s[0]; d[1]=s[1]; d[2]=s[2]; d[3]=s[3]; }
#define VM_COPY4(d, s) VM_COPY4_UNTYPED(((float *)(d)), ((float *)(s)))
//add two vectors
#define VM_ADD2_UNTYPED(d, sa, sb) { d[0]=sa[0]+sb[0]; d[1]=sa[1]+sb[1]; }
#define VM_ADD2(d, sa, sb) VM_ADD3_UNTYPED(((float *)(d)), ((float *)(sa)), ((float *)(sb)))
#define VM_ADD3_UNTYPED(d, sa, sb) { d[0]=sa[0]+sb[0]; d[1]=sa[1]+sb[1]; d[2]=sa[2]+sb[2]; }
#define VM_ADD3(d, sa, sb) VM_ADD3_UNTYPED(((float *)(d)), ((float *)(sa)), ((float *)(sb)))
#define VM_ADD4_UNTYPED(d, sa, sb) { d[0]=sa[0]+sb[0]; d[1]=sa[1]+sb[1]; d[2]=sa[2]+sb[2]; d[3]=sa[3]+sb[3]; }
#define VM_ADD4(d, sa, sb) VM_ADD4_UNTYPED(((float *)(d)), ((float *)(sa)), ((float *)(sb)))
//subtract two vectors
#define VM_SUB2_UNTYPED(d, sa, sb) { d[0]=sa[0]-sb[0]; d[1]=sa[1]-sb[1]; }
#define VM_SUB2(d, sa, sb) VM_SUB2_UNTYPED(((float *)(d)), ((float *)(sa)), ((float *)(sb)))
#define VM_SUB3_UNTYPED(d, sa, sb) { d[0]=sa[0]-sb[0]; d[1]=sa[1]-sb[1]; d[2]=sa[2]-sb[2]; }
#define VM_SUB3(d, sa, sb) VM_SUB3_UNTYPED(((float *)(d)), ((float *)(sa)), ((float *)(sb)))
#define VM_SUB4_UNTYPED(d, sa, sb) { d[0]=sa[0]-sb[0]; d[1]=sa[1]-sb[1]; d[2]=sa[2]-sb[2]; d[3]=sa[3]-sb[3]; }
#define VM_SUB4(d, sa, sb) VM_SUB4_UNTYPED(((float *)(d)), ((float *)(sa)), ((float *)(sb)))
//multiply all elements of a vector by a scalar
#define VM_SCALE2_UNTYPED(d, s, f) {d[0]=s[0]*f; d[1]=s[1]*f; }
#define VM_SCALE2(d, s, f) VM_SCALE2_UNTYPED(((float *)(d)), ((float *)(s)), ((float)(f)) )
#define VM_SCALE3_UNTYPED(d, s, f) {d[0]=s[0]*f; d[1]=s[1]*f; d[2]=s[2]*f; }
#define VM_SCALE3(d, s, f) VM_SCALE3_UNTYPED(((float *)(d)), ((float *)(s)), ((float)(f)) )
#define VM_SCALE4_UNTYPED(d, s, f) {d[0]=s[0]*f; d[1]=s[1]*f; d[2]=s[2]*f; d[3]=s[3]*f; }
#define VM_SCALE4(d, s, f) VM_SCALE4_UNTYPED(((float *)(d)), ((float *)(s)), ((float)(f)) )
//add a scalar to all elements of a vector
#define VM_BIAS2_UNTYPED(d, s, f) { d[0]=s[0]+f; d[1]=s[1]+f; }
#define VM_BIAS2(d, s, f) VM_BIAS2_UNTYPED(((float *)(d)), ((float *)(s)), ((float)(f)))
#define VM_BIAS3_UNTYPED(d, s, f) { d[0]=s[0]+f; d[1]=s[1]+f; d[2]=s[2]+f; }
#define VM_BIAS3(d, s, f) VM_BIAS3_UNTYPED(((float *)(d)), ((float *)(s)), ((float)(f)))
#define VM_BIAS4_UNTYPED(d, s, f) { d[0]=s[0]+f; d[1]=s[1]+f; d[2]=s[2]+f; d[3]=s[3]+f; }
#define VM_BIAS4(d, s, f) VM_BIAS4_UNTYPED(((float *)(d)), ((float *)(s)), ((float)(f)))
//3D cross product
#define VM_XPROD3_UNTYPED(d, sa, sb) { d[0]=sa[1]*sb[2]-sa[2]*sb[1]; d[1]=sa[2]*sb[0]-sa[0]*sb[2]; d[2]=sa[0]*sb[1]-sa[1]*sb[0]; }
#define VM_XPROD3(d, sa, sb) VM_XPROD3_UNTYPED(((float *)(d)), ((float *)(sa)), ((float *)(sb)))
//dot products
#define VM_DOTPROD2_UNTYPED(sa, sb) (sa[0]*sb[0]+ sa[1]*sb[1])
#define VM_DOTPROD2(sa, sb) VM_DOTPROD2_UNTYPED(((float *)(sa)), ((float *)(sb)))
#define VM_DOTPROD3_UNTYPED(sa, sb) (sa[0]*sb[0]+ sa[1]*sb[1]+ sa[2]*sb[2])
#define VM_DOTPROD3(sa, sb) VM_DOTPROD3_UNTYPED(((float *)(sa)), ((float *)(sb)))
#define VM_DOTPROD4_UNTYPED(sa, sb) (sa[0]*sb[0]+ sa[1]*sb[1]+ sa[2]*sb[2] + sa[3]*sb[3])
#define VM_DOTPROD4(sa, sb) VM_DOTPROD4_UNTYPED(((float *)(sa)), ((float *)(sb)))
//dp3 then and add 4th component from second arguement
#define VM_DOTPROD3ADD_UNTYPED(pt, pl) (pt[0]*pl[0]+ pt[1]*pl[1]+ pt[2]*pl[2] + pl[3])
#define VM_DOTPROD3ADD(pt, pl) VM_DOTPROD3ADD_UNTYPED(((float *)(pt)), ((float *)(pl)))
//normalize vectors
#define VM_NORM3_UNTYPED(d, s) {double __idsq; __idsq=1.0/sqrt(VM_DOTPROD3_UNTYPED(s,s)); d[0]=s[0]*__idsq; d[1]=s[1]*__idsq; d[2]=s[2]*__idsq; }
#define VM_NORM3_UNTYPED_F32(d, s) {float __idsq; __idsq=1.0/sqrt(VM_DOTPROD3_UNTYPED(s,s)); d[0]=s[0]*__idsq; d[1]=s[1]*__idsq; d[2]=s[2]*__idsq; }
#define VM_NORM3(d, s) VM_NORM3_UNTYPED_F32(((float *)(d)), ((float *)(s)))
#define VM_NORM4_UNTYPED(d, s) {double __idsq; __idsq=1.0/sqrt(VM_DOTPROD4_UNTYPED(s,s)); d[0]=s[0]*__idsq; d[1]=s[1]*__idsq; d[2]=s[2]*__idsq; d[3]=s[3]*__idsq; }
#define VM_NORM4_UNTYPED_F32(d, s) {float __idsq; __idsq=1.0/sqrt(VM_DOTPROD4_UNTYPED(s,s)); d[0]=s[0]*__idsq; d[1]=s[1]*__idsq; d[2]=s[2]*__idsq; d[3]=s[3]*__idsq; }
#define VM_NORM4(d, s) VM_NORM4_UNTYPED_F32(((float *)(d)), ((float *)(s)))
//safely normalize vectors, deal with 0 length case
#define VM_SAFENORM3_UNTYPED(d, s) {float __idsq, __dp; __dp = VM_DOTPROD3_UNTYPED(s,s); \
__idsq=( (__dp > 0.0f)?(1.0/sqrt(__dp)):0.0f ) ; d[0]=s[0]*__idsq; d[1]=s[1]*__idsq; d[2]=s[2]*__idsq; }
#define VM_SAFENORM3(d, s) VM_NORM3_UNTYPED_F32(((float *)(d)), ((float *)(s)))
//absolute value
#define VM_ABS2_UNTYPED(d, s) { d[0] = fabs(s[0]); d[1] = fabs(s[1]); }
#define VM_ABS2(d, s) VM_ABS2_UNTYPED(((float *)(d)), ((float *)(s)) )
#define VM_ABS3_UNTYPED(d, s) { d[0] = fabs(s[0]); d[1] = fabs(s[1]); d[2] = fabs(s[2]); }
#define VM_ABS3(d, s) VM_ABS3_UNTYPED(((float *)(d)), ((float *)(s)) )
#define VM_ABS4_UNTYPED(d, s) { d[0] = fabs(s[0]); d[1] = fabs(s[1]); d[2] = fabs(s[2]); d[3] = fabs(s[3]); }
#define VM_ABS4(d, s) VM_ABS4_UNTYPED(((float *)(d)), ((float *)(s)) )
//projection of a vector onto another vector (assumes vector v is normalized)
// computes d, which is the parallel component of s onto vector v
#define VM_PROJ3_UNTYPED(d, s, v) { double __dp; __dp = VM_DOTPROD3_UNTYPED(s, v); VM_SCALE3_UNTYPED(d, s, __dp); }
#define VM_PROJ3(d, s, v) VM_PROJ3_UNTYPED(((float *)(d)), ((float *)(s)), ((float *)(v)) )
#define VM_PROJ3_F64(d, s, v) VM_PROJ3_UNTYPED(((double *)(d)), ((double *)(s)), ((double *)(v)) )
//compute component of a vector perpendicular to another vector
// d is perpendicular component of s onto vector v
// this macro first computes the parallel projection, then subtracts off from the original vector
// to obtain the perpendicular component
#define VM_PERP3_UNTYPED(d, s, v) {double __proj[3]; VM_PROJ3_UNTYPED(__proj, s, v); VM_SUB3_UNTYPED(d, s, __proj); }
#define VM_PERP3(d, s, v) VM_PERP3_UNTYPED(((float *)(d)), ((float *)(s)), ((float *)(v)) )
#define VM_PERP3_F64(d, s, v) VM_PERP3_UNTYPED(((double *)(d)), ((double *)(s)), ((double *)(v)) )
+19
View File
@@ -0,0 +1,19 @@
Modified BSD License (2009):
Copyright (c) 2011, Advanced Micro Devices, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
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.
Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
If you use the software (in whole or in part), you shall adhere to all applicable U.S., European, and other export laws, including but not limited to the U.S. Export Administration Regulations (“EAR”), (15 C.F.R. Sections 730 through 774), and E.U. Council Regulation (EC) No 1334/2000 of 22 June 2000. Further, pursuant to Section 740.6 of the EAR, you hereby certify that, except pursuant to a license granted by the United States Department of Commerce Bureau of Industry and Security or as otherwise permitted pursuant to a License Exception under the U.S. Export Administration Regulations ("EAR"), you will not (1) export, re-export or release to a national of a country in Country Groups D:1, E:1 or E:2 any restricted technology, software, or source code you receive hereunder, or (2) export to Country Groups D:1, E:1 or E:2 the direct product of such technology or software, if such foreign produced direct product is subject to national security controls as identified on the Commerce Control List (currently found in Supplement 1 to Part 774 of EAR). For the most current Country Group listings, or for additional information about the EAR or your obligations under those regulations, please refer to the U.S. Bureau of Industry and Securitys website at http://www.bis.doc.gov/.
+5
View File
@@ -0,0 +1,5 @@
Cropped version of CubeMapGen-1.4-Source.zip
More detail and download access:
https://gpuopen.com/archive/gamescgi/cubemapgen/