mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
Additional 3d support
This commit is contained in:
parent
70680fdf39
commit
f26df6c86b
32 changed files with 2370 additions and 165 deletions
|
@ -727,7 +727,7 @@ namespace Beefy
|
||||||
0.10f, 0.00f, 1.05f, 0,
|
0.10f, 0.00f, 1.05f, 0,
|
||||||
0, 0, 0, 1);*/
|
0, 0, 0, 1);*/
|
||||||
|
|
||||||
mGraphics.SetShaderConstantData(0, &mColorMatrix.ValueRef, mColorMatrixDataDef);
|
mGraphics.SetVertexShaderConstantData(0, &mColorMatrix.ValueRef, mColorMatrixDataDef);
|
||||||
}
|
}
|
||||||
window.Draw(mGraphics);
|
window.Draw(mGraphics);
|
||||||
window.PostDraw(mGraphics);
|
window.PostDraw(mGraphics);
|
||||||
|
|
|
@ -79,6 +79,10 @@ namespace Beefy.gfx
|
||||||
const int32 CLIP_STACK_SIZE = 256;
|
const int32 CLIP_STACK_SIZE = 256;
|
||||||
public Rect?[] mClipStack = new Rect?[CLIP_STACK_SIZE] ~ delete _;
|
public Rect?[] mClipStack = new Rect?[CLIP_STACK_SIZE] ~ delete _;
|
||||||
|
|
||||||
|
public bool mTexWrap;
|
||||||
|
protected DisposeProxy mTexWrapDisableProxy ~ delete _;
|
||||||
|
protected DisposeProxy mTexWrapEnableProxy ~ delete _;
|
||||||
|
|
||||||
public int32 mClipStackIdx = 0;
|
public int32 mClipStackIdx = 0;
|
||||||
public Rect? mClipRect = null;
|
public Rect? mClipRect = null;
|
||||||
|
|
||||||
|
@ -106,6 +110,10 @@ namespace Beefy.gfx
|
||||||
mClipDisposeProxy = new DisposeProxy();
|
mClipDisposeProxy = new DisposeProxy();
|
||||||
mClipDisposeProxy.mDisposeProxyDelegate = new => PopClip;
|
mClipDisposeProxy.mDisposeProxyDelegate = new => PopClip;
|
||||||
mRenderStateDisposeProxy = new DisposeProxy();
|
mRenderStateDisposeProxy = new DisposeProxy();
|
||||||
|
mTexWrapDisableProxy = new DisposeProxy();
|
||||||
|
mTexWrapDisableProxy.mDisposeProxyDelegate = new () => { PopTexWrap(false); };
|
||||||
|
mTexWrapEnableProxy = new DisposeProxy();
|
||||||
|
mTexWrapEnableProxy.mDisposeProxyDelegate = new () => { PopTexWrap(true); };
|
||||||
|
|
||||||
mWhiteDot = Image.LoadFromFile("!white");
|
mWhiteDot = Image.LoadFromFile("!white");
|
||||||
|
|
||||||
|
@ -341,7 +349,7 @@ namespace Beefy.gfx
|
||||||
Rect rectThing = mClipRect.Value;
|
Rect rectThing = mClipRect.Value;
|
||||||
mClipRect = rectThing;
|
mClipRect = rectThing;
|
||||||
|
|
||||||
var clipRenderState = AllocRenderState(mDefaultShader, mClipRect);
|
var clipRenderState = AllocRenderState(mDefaultShader, mClipRect, mTexWrap);
|
||||||
|
|
||||||
//clipRenderState.ClipRect = mClipRect;
|
//clipRenderState.ClipRect = mClipRect;
|
||||||
PushRenderState(clipRenderState);
|
PushRenderState(clipRenderState);
|
||||||
|
@ -349,7 +357,7 @@ namespace Beefy.gfx
|
||||||
return mClipDisposeProxy;
|
return mClipDisposeProxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderState AllocRenderState(Shader shader, Rect? clipRect)
|
RenderState AllocRenderState(Shader shader, Rect? clipRect, bool texWrap)
|
||||||
{
|
{
|
||||||
RenderState renderState = null;
|
RenderState renderState = null;
|
||||||
var curRenderState = mRenderStateStack[mRenderStateStackIdx];
|
var curRenderState = mRenderStateStack[mRenderStateStackIdx];
|
||||||
|
@ -365,6 +373,7 @@ namespace Beefy.gfx
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
renderState = RenderState.Create(curRenderState);
|
renderState = RenderState.Create(curRenderState);
|
||||||
|
renderState.TexWrap = texWrap;
|
||||||
renderState.Shader = shader;
|
renderState.Shader = shader;
|
||||||
renderState.ClipRect = clipRect;
|
renderState.ClipRect = clipRect;
|
||||||
return renderState;
|
return renderState;
|
||||||
|
@ -375,16 +384,33 @@ namespace Beefy.gfx
|
||||||
mClipStackIdx++;
|
mClipStackIdx++;
|
||||||
mClipStack[mClipStackIdx] = null;
|
mClipStack[mClipStackIdx] = null;
|
||||||
mClipRect = null;
|
mClipRect = null;
|
||||||
var clipRenderState = AllocRenderState(mDefaultShader, null);
|
var clipRenderState = AllocRenderState(mDefaultShader, mClipRect, mTexWrap);
|
||||||
//clipRenderState.ClipRect = null;
|
//clipRenderState.ClipRect = null;
|
||||||
PushRenderState(clipRenderState);
|
PushRenderState(clipRenderState);
|
||||||
|
|
||||||
return mClipDisposeProxy;
|
return mClipDisposeProxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DisposeProxy PushTexWrap(bool texWrap)
|
||||||
|
{
|
||||||
|
bool prevTexWrap = mTexWrap;
|
||||||
|
mTexWrap = texWrap;
|
||||||
|
|
||||||
|
var clipRenderState = AllocRenderState(mDefaultShader, mClipRect, mTexWrap);
|
||||||
|
PushRenderState(clipRenderState);
|
||||||
|
|
||||||
|
return prevTexWrap ? mTexWrapEnableProxy : mTexWrapDisableProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void PopTexWrap(bool texWrap)
|
||||||
|
{
|
||||||
|
mTexWrap = texWrap;
|
||||||
|
PopRenderState();
|
||||||
|
}
|
||||||
|
|
||||||
public void PushTextRenderState()
|
public void PushTextRenderState()
|
||||||
{
|
{
|
||||||
var textRenderState = AllocRenderState(mTextShader, mClipRect);
|
var textRenderState = AllocRenderState(mTextShader, mClipRect, mTexWrap);
|
||||||
//textRenderState.ClipRect = mClipRect;
|
//textRenderState.ClipRect = mClipRect;
|
||||||
//textRenderState.Shader = mTextShader;
|
//textRenderState.Shader = mTextShader;
|
||||||
PushRenderState(textRenderState);
|
PushRenderState(textRenderState);
|
||||||
|
@ -419,10 +445,10 @@ namespace Beefy.gfx
|
||||||
static extern void Gfx_DrawIndexedVertices2D(int32 vertexSize, void* vtxData, int32 vtxCount, uint16* idxData, int32 idxCount, float a, float b, float c, float d, float tx, float ty, float z);
|
static extern void Gfx_DrawIndexedVertices2D(int32 vertexSize, void* vtxData, int32 vtxCount, uint16* idxData, int32 idxCount, float a, float b, float c, float d, float tx, float ty, float z);
|
||||||
|
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
static extern void Gfx_SetShaderConstantData(int32 slotIdx, void* data, int32 size);
|
static extern void Gfx_SetShaderConstantData(int32 usageIdx, int32 slotIdx, void* data, int32 size);
|
||||||
|
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
static extern void Gfx_SetShaderConstantDataTyped(int32 slotIdx, void* data, int32 size, int32* typeData, int32 typeCount);
|
static extern void Gfx_SetShaderConstantDataTyped(int usageIdx, int32 slotIdx, void* data, int32 size, int32* typeData, int32 typeCount);
|
||||||
|
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
static extern void Gfx_DrawQuads(void* textureSegment, Vertex3D* vertices, int32 vtxCount);
|
static extern void Gfx_DrawQuads(void* textureSegment, Vertex3D* vertices, int32 vtxCount);
|
||||||
|
@ -778,21 +804,32 @@ namespace Beefy.gfx
|
||||||
mMatrix.a, mMatrix.b, mMatrix.c, mMatrix.d, mMatrix.tx, mMatrix.ty, ZDepth);
|
mMatrix.a, mMatrix.b, mMatrix.c, mMatrix.d, mMatrix.tx, mMatrix.ty, ZDepth);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetShaderConstantData(int slotIdx, void* data, int size)
|
public void SetVertexShaderConstantData(int slotIdx, void* data, int size)
|
||||||
{
|
{
|
||||||
Gfx_SetShaderConstantData((int32)slotIdx, data, (int32)size);
|
Gfx_SetShaderConstantData(0, (int32)slotIdx, data, (int32)size);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetShaderConstantData(int32 slotIdx, void* data, ConstantDataDefinition constantDataDefinition)
|
public void SetPixelShaderConstantData(int slotIdx, void* data, int size)
|
||||||
|
{
|
||||||
|
Gfx_SetShaderConstantData(1, (int32)slotIdx, data, (int32)size);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetVertexShaderConstantData(int32 slotIdx, void* data, ConstantDataDefinition constantDataDefinition)
|
||||||
{
|
{
|
||||||
int32* dataTypesPtr = (int32*)constantDataDefinition.mDataTypes.CArray();
|
int32* dataTypesPtr = (int32*)constantDataDefinition.mDataTypes.CArray();
|
||||||
Gfx_SetShaderConstantDataTyped(slotIdx, data, constantDataDefinition.mDataSize, dataTypesPtr, (int32)constantDataDefinition.mDataTypes.Count);
|
Gfx_SetShaderConstantDataTyped(0, slotIdx, data, constantDataDefinition.mDataSize, dataTypesPtr, (int32)constantDataDefinition.mDataTypes.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetShaderConstantData(int32 slotIdx, Matrix4 matrix)
|
public void SetVertexShaderConstantData(int32 slotIdx, Matrix4 matrix)
|
||||||
|
{
|
||||||
|
var mtx = matrix;
|
||||||
|
Gfx_SetShaderConstantData(0, slotIdx, &mtx, (int32)sizeof(Matrix4));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetPixelShaderConstantData(int32 slotIdx, Matrix4 matrix)
|
||||||
{
|
{
|
||||||
var mtx = matrix;
|
var mtx = matrix;
|
||||||
Gfx_SetShaderConstantData(slotIdx, &mtx, (int32)sizeof(Matrix4));
|
Gfx_SetShaderConstantData(1, slotIdx, &mtx, (int32)sizeof(Matrix4));
|
||||||
}
|
}
|
||||||
|
|
||||||
public float DrawString(StringView theString, float x, float y, FontAlign alignment = FontAlign.Left, float width = 0, FontOverflowMode overflowMode = FontOverflowMode.Overflow, FontMetrics* fontMetrics = null)
|
public float DrawString(StringView theString, float x, float y, FontAlign alignment = FontAlign.Left, float width = 0, FontOverflowMode overflowMode = FontOverflowMode.Overflow, FontMetrics* fontMetrics = null)
|
||||||
|
|
|
@ -90,15 +90,24 @@ namespace Beefy.gfx
|
||||||
public void* mNativeModelDef;
|
public void* mNativeModelDef;
|
||||||
public float mFrameRate;
|
public float mFrameRate;
|
||||||
public int32 mJointCount;
|
public int32 mJointCount;
|
||||||
public Animation[] mAnims;
|
public Animation[] mAnims ~ DeleteContainerAndItems!(_);
|
||||||
public Dictionary<String, Animation> mAnimMap = new Dictionary<String, Animation>();
|
public Dictionary<String, Animation> mAnimMap = new Dictionary<String, Animation>() ~ DeleteDictionaryAndKeys!(_);
|
||||||
|
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
extern static void* Res_OpenFBX(String fileName, void* nativeVertexDef);
|
extern static void* Res_OpenFBX(char8* fileName, void* nativeVertexDef);
|
||||||
|
|
||||||
|
[CallingConvention(.Stdcall), CLink]
|
||||||
|
extern static void* Res_OpenGLTF(char8* fileName, char8* baseDir, void* nativeVertexDef);
|
||||||
|
|
||||||
|
[CallingConvention(.Stdcall), CLink]
|
||||||
|
extern static void* Res_OpenModel(char8* fileName, char8* baseDir, void* nativeVertexDef);
|
||||||
|
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
extern static void* ModelDef_CreateModelInstance(void* nativeModel);
|
extern static void* ModelDef_CreateModelInstance(void* nativeModel);
|
||||||
|
|
||||||
|
[CallingConvention(.Stdcall), CLink]
|
||||||
|
extern static char8* ModelDef_GetInfo(void* nativeModel);
|
||||||
|
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
extern static float ModelDef_GetFrameRate(void* nativeModel);
|
extern static float ModelDef_GetFrameRate(void* nativeModel);
|
||||||
|
|
||||||
|
@ -111,6 +120,12 @@ namespace Beefy.gfx
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
extern static void* ModelDef_GetAnimation(void* nativeModel, int32 animIdx);
|
extern static void* ModelDef_GetAnimation(void* nativeModel, int32 animIdx);
|
||||||
|
|
||||||
|
[CallingConvention(.Stdcall), CLink]
|
||||||
|
extern static void ModelDef_SetTextures(void* nativeModel, int32 meshIdx, int32 primitivesIdx, char8** paths, int32 pathCount);
|
||||||
|
|
||||||
|
[CallingConvention(.Stdcall), CLink]
|
||||||
|
extern static Span<uint8> Res_SerializeModel(void* nativeModel);
|
||||||
|
|
||||||
this(void* nativeModelDef)
|
this(void* nativeModelDef)
|
||||||
{
|
{
|
||||||
mNativeModelDef = nativeModelDef;
|
mNativeModelDef = nativeModelDef;
|
||||||
|
@ -129,9 +144,15 @@ namespace Beefy.gfx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ModelDef LoadModel(String fileName)
|
public static ModelDef LoadModel(String fileName, String baseDir)
|
||||||
{
|
{
|
||||||
void* nativeModelDef = Res_OpenFBX(fileName, VertexDef.sVertexDefinition.mNativeVertexDefinition);
|
void* nativeModelDef = null;
|
||||||
|
if (fileName.EndsWith(".bfm", .OrdinalIgnoreCase))
|
||||||
|
nativeModelDef = Res_OpenModel(fileName, baseDir, VertexDef.sVertexDefinition.mNativeVertexDefinition);
|
||||||
|
else if (fileName.EndsWith(".fbx", .OrdinalIgnoreCase))
|
||||||
|
nativeModelDef = Res_OpenFBX(fileName, VertexDef.sVertexDefinition.mNativeVertexDefinition);
|
||||||
|
else
|
||||||
|
nativeModelDef = Res_OpenGLTF(fileName, baseDir, VertexDef.sVertexDefinition.mNativeVertexDefinition);
|
||||||
if (nativeModelDef == null)
|
if (nativeModelDef == null)
|
||||||
return null;
|
return null;
|
||||||
return new ModelDef(nativeModelDef);
|
return new ModelDef(nativeModelDef);
|
||||||
|
@ -150,6 +171,22 @@ namespace Beefy.gfx
|
||||||
{
|
{
|
||||||
return mAnimMap[name];
|
return mAnimMap[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void GetInfo(String str)
|
||||||
|
{
|
||||||
|
str.Append(ModelDef_GetInfo(mNativeModelDef));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetTextures(int meshIdx, int primitivesIdx, Span<char8*> paths)
|
||||||
|
{
|
||||||
|
ModelDef_SetTextures(mNativeModelDef, (.)meshIdx, (.)primitivesIdx, paths.Ptr, (.)paths.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Serialize(List<uint8> data)
|
||||||
|
{
|
||||||
|
var span = Res_SerializeModel(mNativeModelDef);
|
||||||
|
data.AddRange(span);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ModelInstance : RenderCmd
|
public class ModelInstance : RenderCmd
|
||||||
|
|
|
@ -31,6 +31,9 @@ namespace Beefy.gfx
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
static extern void RenderState_SetClip(void* renderState, float x, float y, float width, float height);
|
static extern void RenderState_SetClip(void* renderState, float x, float y, float width, float height);
|
||||||
|
|
||||||
|
[CallingConvention(.Stdcall), CLink]
|
||||||
|
static extern void RenderState_SetTexWrap(void* renderState, bool texWrap);
|
||||||
|
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
static extern void RenderState_DisableClip(void* renderState);
|
static extern void RenderState_DisableClip(void* renderState);
|
||||||
|
|
||||||
|
@ -104,6 +107,14 @@ namespace Beefy.gfx
|
||||||
RenderState_DisableClip(mNativeRenderState);
|
RenderState_DisableClip(mNativeRenderState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool TexWrap
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
RenderState_SetTexWrap(mNativeRenderState, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
public class RenderState
|
public class RenderState
|
||||||
|
|
|
@ -410,7 +410,8 @@ namespace System
|
||||||
AppData_LocalLow,
|
AppData_LocalLow,
|
||||||
AppData_Roaming,
|
AppData_Roaming,
|
||||||
Programs,
|
Programs,
|
||||||
Programs_Common
|
Programs_Common,
|
||||||
|
Documents
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result<void, Platform.Result> GetStrHelper(String outStr, delegate void (char8* outPtr, int32* outSize, Result* outResult) func)
|
public static Result<void, Platform.Result> GetStrHelper(String outStr, delegate void (char8* outPtr, int32* outSize, Result* outResult) func)
|
||||||
|
|
|
@ -1,5 +1,35 @@
|
||||||
namespace System.Security.Cryptography
|
namespace System.Security.Cryptography
|
||||||
{
|
{
|
||||||
|
struct HashEncode
|
||||||
|
{
|
||||||
|
// Only 63 chars - skip zero
|
||||||
|
const char8[?] cHash64bToChar = .( 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
|
||||||
|
'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F',
|
||||||
|
'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
|
||||||
|
'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '_' );
|
||||||
|
public static void HashEncode64(uint64 val, String outStr)
|
||||||
|
{
|
||||||
|
var val;
|
||||||
|
if ((int64)val < 0)
|
||||||
|
{
|
||||||
|
uint64 flippedNum = (uint64)-(int64)val;
|
||||||
|
// Only flip if the encoded result would actually be shorter
|
||||||
|
if (flippedNum <= 0x00FFFFFFFFFFFFFFL)
|
||||||
|
{
|
||||||
|
val = flippedNum;
|
||||||
|
outStr.Append('_');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
int charIdx = (int)((val >> (i * 6)) & 0x3F) - 1;
|
||||||
|
if (charIdx != -1)
|
||||||
|
outStr.Append(cHash64bToChar[charIdx]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct MD5Hash
|
struct MD5Hash
|
||||||
{
|
{
|
||||||
public uint8[16] mHash;
|
public uint8[16] mHash;
|
||||||
|
@ -50,6 +80,14 @@ namespace System.Security.Cryptography
|
||||||
val.ToString(strBuffer, "X2", null);
|
val.ToString(strBuffer, "X2", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Encode(String outStr)
|
||||||
|
{
|
||||||
|
#unwarn
|
||||||
|
HashEncode.HashEncode64(((uint64*)&mHash)[0], outStr);
|
||||||
|
#unwarn
|
||||||
|
HashEncode.HashEncode64(((uint64*)&mHash)[1], outStr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MD5
|
class MD5
|
||||||
|
|
|
@ -643,14 +643,14 @@ BF_EXPORT void BF_CALLTYPE Gfx_DrawIndexedVertices2D(int vertexSize, void* vtxDa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BF_EXPORT void BF_CALLTYPE Gfx_SetShaderConstantData(int slotIdx, void* constData, int size)
|
BF_EXPORT void BF_CALLTYPE Gfx_SetShaderConstantData(int usageIdx, int slotIdx, void* constData, int size)
|
||||||
{
|
{
|
||||||
gBFApp->mRenderDevice->mCurDrawLayer->SetShaderConstantData(slotIdx, constData, size);
|
gBFApp->mRenderDevice->mCurDrawLayer->SetShaderConstantData(usageIdx, slotIdx, constData, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
BF_EXPORT void BF_CALLTYPE Gfx_SetShaderConstantDataTyped(int slotIdx, void* constData, int size, int* typeData, int typeCount)
|
BF_EXPORT void BF_CALLTYPE Gfx_SetShaderConstantDataTyped(int usageIdx, int slotIdx, void* constData, int size, int* typeData, int typeCount)
|
||||||
{
|
{
|
||||||
gBFApp->mRenderDevice->mCurDrawLayer->SetShaderConstantDataTyped(slotIdx, constData, size, typeData, typeCount);
|
gBFApp->mRenderDevice->mCurDrawLayer->SetShaderConstantDataTyped(usageIdx, slotIdx, constData, size, typeData, typeCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
BF_EXPORT void BF_CALLTYPE Gfx_QueueRenderCmd(RenderCmd* renderCmd)
|
BF_EXPORT void BF_CALLTYPE Gfx_QueueRenderCmd(RenderCmd* renderCmd)
|
||||||
|
@ -678,6 +678,11 @@ BF_EXPORT void BF_CALLTYPE RenderState_Delete(RenderState* renderState)
|
||||||
delete renderState;
|
delete renderState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BF_EXPORT void BF_CALLTYPE RenderState_SetTexWrap(RenderState* renderState, bool texWrap)
|
||||||
|
{
|
||||||
|
renderState->SetTexWrap(texWrap);
|
||||||
|
}
|
||||||
|
|
||||||
BF_EXPORT void BF_CALLTYPE RenderState_SetClip(RenderState* renderState, float x, float y, float width, float height)
|
BF_EXPORT void BF_CALLTYPE RenderState_SetClip(RenderState* renderState, float x, float y, float width, float height)
|
||||||
{
|
{
|
||||||
BF_ASSERT((width >= 0) && (height >= 0));
|
BF_ASSERT((width >= 0) && (height >= 0));
|
||||||
|
|
|
@ -445,6 +445,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\"</Co
|
||||||
<ClCompile Include="FileStream.cpp" />
|
<ClCompile Include="FileStream.cpp" />
|
||||||
<ClCompile Include="gfx\DrawLayer.cpp" />
|
<ClCompile Include="gfx\DrawLayer.cpp" />
|
||||||
<ClCompile Include="gfx\FTFont.cpp" />
|
<ClCompile Include="gfx\FTFont.cpp" />
|
||||||
|
<ClCompile Include="gfx\glTF.cpp" />
|
||||||
<ClCompile Include="gfx\ModelDef.cpp" />
|
<ClCompile Include="gfx\ModelDef.cpp" />
|
||||||
<ClCompile Include="gfx\ModelInstance.cpp" />
|
<ClCompile Include="gfx\ModelInstance.cpp" />
|
||||||
<ClCompile Include="gfx\RenderCmd.cpp" />
|
<ClCompile Include="gfx\RenderCmd.cpp" />
|
||||||
|
@ -1933,6 +1934,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\"</Co
|
||||||
<ClCompile Include="util\CubicSpline.cpp" />
|
<ClCompile Include="util\CubicSpline.cpp" />
|
||||||
<ClCompile Include="util\Hash.cpp" />
|
<ClCompile Include="util\Hash.cpp" />
|
||||||
<ClCompile Include="util\Heap.cpp" />
|
<ClCompile Include="util\Heap.cpp" />
|
||||||
|
<ClCompile Include="util\Json.cpp" />
|
||||||
<ClCompile Include="util\MappedFile.cpp" />
|
<ClCompile Include="util\MappedFile.cpp" />
|
||||||
<ClCompile Include="util\Matrix4.cpp" />
|
<ClCompile Include="util\Matrix4.cpp" />
|
||||||
<ClCompile Include="util\PerfTimer.cpp" />
|
<ClCompile Include="util\PerfTimer.cpp" />
|
||||||
|
@ -1958,6 +1960,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\"</Co
|
||||||
<ClInclude Include="gfx\DrawLayer.h" />
|
<ClInclude Include="gfx\DrawLayer.h" />
|
||||||
<ClInclude Include="gfx\Font.h" />
|
<ClInclude Include="gfx\Font.h" />
|
||||||
<ClInclude Include="gfx\FTFont.h" />
|
<ClInclude Include="gfx\FTFont.h" />
|
||||||
|
<ClInclude Include="gfx\glTF.h" />
|
||||||
<ClInclude Include="gfx\ModelDef.h" />
|
<ClInclude Include="gfx\ModelDef.h" />
|
||||||
<ClInclude Include="gfx\ModelInstance.h" />
|
<ClInclude Include="gfx\ModelInstance.h" />
|
||||||
<ClInclude Include="gfx\RenderCmd.h" />
|
<ClInclude Include="gfx\RenderCmd.h" />
|
||||||
|
@ -2161,6 +2164,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\"</Co
|
||||||
<ClInclude Include="util\Hash.h" />
|
<ClInclude Include="util\Hash.h" />
|
||||||
<ClInclude Include="util\HashSet.h" />
|
<ClInclude Include="util\HashSet.h" />
|
||||||
<ClInclude Include="util\Heap.h" />
|
<ClInclude Include="util\Heap.h" />
|
||||||
|
<ClInclude Include="util\Json.h" />
|
||||||
<ClInclude Include="util\MappedFile.h" />
|
<ClInclude Include="util\MappedFile.h" />
|
||||||
<ClInclude Include="util\Matrix4.h" />
|
<ClInclude Include="util\Matrix4.h" />
|
||||||
<ClInclude Include="util\MultiHashSet.h" />
|
<ClInclude Include="util\MultiHashSet.h" />
|
||||||
|
|
|
@ -707,6 +707,12 @@
|
||||||
<ClCompile Include="util\Heap.cpp">
|
<ClCompile Include="util\Heap.cpp">
|
||||||
<Filter>src\util</Filter>
|
<Filter>src\util</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="gfx\glTF.cpp">
|
||||||
|
<Filter>src\gfx</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="util\Json.cpp">
|
||||||
|
<Filter>src\util</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Common.h">
|
<ClInclude Include="Common.h">
|
||||||
|
@ -1075,6 +1081,12 @@
|
||||||
<ClInclude Include="util\Heap.h">
|
<ClInclude Include="util\Heap.h">
|
||||||
<Filter>src\util</Filter>
|
<Filter>src\util</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="gfx\glTF.h">
|
||||||
|
<Filter>src\gfx</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="util\Json.h">
|
||||||
|
<Filter>src\util</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<CustomBuild Include="third_party\libffi\i686-pc-cygwin\src\x86\win32.asm">
|
<CustomBuild Include="third_party\libffi\i686-pc-cygwin\src\x86\win32.asm">
|
||||||
|
|
|
@ -943,6 +943,21 @@ char* Beefy::LoadTextData(const StringImpl& path, int* size)
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Beefy::LoadTextData(const StringImpl& path, StringImpl& str)
|
||||||
|
{
|
||||||
|
int size = 0;
|
||||||
|
char* data = LoadTextData(path, &size);
|
||||||
|
if (data == NULL)
|
||||||
|
return false;
|
||||||
|
if ((str.mAllocSizeAndFlags & StringImpl::DynAllocFlag) != 0)
|
||||||
|
str.Release();
|
||||||
|
str.mPtr = data;
|
||||||
|
str.mAllocSizeAndFlags = size | StringImpl::DynAllocFlag | StringImpl::StrPtrFlag;
|
||||||
|
str.mLength = size;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef BF_MINGW
|
#ifdef BF_MINGW
|
||||||
unsigned long long __cdecl _byteswap_uint64(unsigned long long _Int64)
|
unsigned long long __cdecl _byteswap_uint64(unsigned long long _Int64)
|
||||||
{
|
{
|
||||||
|
@ -1263,3 +1278,4 @@ void Beefy::BFFatalError(const char* message, const char* file, int line)
|
||||||
{
|
{
|
||||||
BFFatalError(String(message), String(file), line);
|
BFFatalError(String(message), String(file), line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -220,6 +220,7 @@ int32 GetHighestBitSet(int32 n);
|
||||||
|
|
||||||
uint8* LoadBinaryData(const StringImpl& path, int* size);
|
uint8* LoadBinaryData(const StringImpl& path, int* size);
|
||||||
char* LoadTextData(const StringImpl& path, int* size);
|
char* LoadTextData(const StringImpl& path, int* size);
|
||||||
|
bool LoadTextData(const StringImpl& path, StringImpl& str);
|
||||||
int64 GetFileTimeWrite(const StringImpl& path);
|
int64 GetFileTimeWrite(const StringImpl& path);
|
||||||
String GetFileDir(const StringImpl& path);
|
String GetFileDir(const StringImpl& path);
|
||||||
String GetFileName(const StringImpl& path);
|
String GetFileName(const StringImpl& path);
|
||||||
|
|
|
@ -49,6 +49,14 @@ public:
|
||||||
Read((void*) &val, sizeof(T));
|
Read((void*) &val, sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T ReadT()
|
||||||
|
{
|
||||||
|
T val;
|
||||||
|
Read((void*)&val, sizeof(T));
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void Write(float val);
|
virtual void Write(float val);
|
||||||
virtual void Write(uint8 val);
|
virtual void Write(uint8 val);
|
||||||
virtual void Write(int8 val);
|
virtual void Write(int8 val);
|
||||||
|
|
|
@ -339,9 +339,9 @@ void DrawLayer::SetTexture(int texIdx, Texture* texture)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawLayer::SetShaderConstantDataTyped(int slotIdx, void* constData, int size, int* typeData, int typeCount)
|
void DrawLayer::SetShaderConstantDataTyped(int usageIdx, int slotIdx, void* constData, int size, int* typeData, int typeCount)
|
||||||
{
|
{
|
||||||
SetShaderConstantData(slotIdx, constData, size);
|
SetShaderConstantData(usageIdx, slotIdx, constData, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -390,5 +390,6 @@ BF_EXPORT void BF_CALLTYPE DrawLayer_DrawToRenderTarget(DrawLayer* drawLayer, Te
|
||||||
renderDevice->PhysSetRenderState(renderDevice->mDefaultRenderState);
|
renderDevice->PhysSetRenderState(renderDevice->mDefaultRenderState);
|
||||||
renderDevice->PhysSetRenderTarget(textureSegment->mTexture);
|
renderDevice->PhysSetRenderTarget(textureSegment->mTexture);
|
||||||
drawLayer->Draw();
|
drawLayer->Draw();
|
||||||
|
drawLayer->Clear();
|
||||||
renderDevice->mCurRenderTarget = prevTarget;
|
renderDevice->mCurRenderTarget = prevTarget;
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,8 +99,8 @@ public:
|
||||||
virtual DrawBatch* AllocateBatch(int minVtxCount, int minIdxCount);
|
virtual DrawBatch* AllocateBatch(int minVtxCount, int minIdxCount);
|
||||||
void QueueRenderCmd(RenderCmd* renderCmd);
|
void QueueRenderCmd(RenderCmd* renderCmd);
|
||||||
virtual RenderCmd* CreateSetTextureCmd(int textureIdx, Texture* texture) = 0;
|
virtual RenderCmd* CreateSetTextureCmd(int textureIdx, Texture* texture) = 0;
|
||||||
virtual void SetShaderConstantData(int slotIdx, void* constData, int size) = 0;
|
virtual void SetShaderConstantData(int usageIdx, int slotIdx, void* constData, int size) = 0;
|
||||||
virtual void SetShaderConstantDataTyped(int slotIdx, void* constData, int size, int* typeData, int typeCount);
|
virtual void SetShaderConstantDataTyped(int usageIdx, int slotIdx, void* constData, int size, int* typeData, int typeCount);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DrawLayer();
|
DrawLayer();
|
||||||
|
|
|
@ -2,9 +2,24 @@
|
||||||
#include "BFApp.h"
|
#include "BFApp.h"
|
||||||
#include "gfx/RenderDevice.h"
|
#include "gfx/RenderDevice.h"
|
||||||
#include "gfx/ModelInstance.h"
|
#include "gfx/ModelInstance.h"
|
||||||
|
#include "util/Dictionary.h"
|
||||||
|
#include "util/TLSingleton.h"
|
||||||
|
#include "FileStream.h"
|
||||||
|
#include "MemStream.h"
|
||||||
|
|
||||||
|
#pragma warning(disable:4190)
|
||||||
|
|
||||||
USING_NS_BF;
|
USING_NS_BF;
|
||||||
|
|
||||||
|
struct ModelManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Dictionary<String, ModelMaterialDef*> mMaterialMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
ModelManager sModelManager;
|
||||||
|
static TLSingleton<String> gModelDef_TLStrReturn;
|
||||||
|
|
||||||
void Beefy::ModelAnimation::GetJointTranslation(int jointIdx, float frameNum, ModelJointTranslation* outJointTranslation)
|
void Beefy::ModelAnimation::GetJointTranslation(int jointIdx, float frameNum, ModelJointTranslation* outJointTranslation)
|
||||||
{
|
{
|
||||||
// Frame 35
|
// Frame 35
|
||||||
|
@ -40,6 +55,28 @@ BF_EXPORT ModelInstance* BF_CALLTYPE ModelDef_CreateModelInstance(ModelDef* mode
|
||||||
return gBFApp->mRenderDevice->CreateModelInstance(modelDef);
|
return gBFApp->mRenderDevice->CreateModelInstance(modelDef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BF_EXPORT const char* BF_CALLTYPE ModelDef_GetInfo(ModelDef* modelDef)
|
||||||
|
{
|
||||||
|
String& outString = *gModelDef_TLStrReturn.Get();
|
||||||
|
for (int meshIdx = 0; meshIdx < (int)modelDef->mMeshes.mSize; meshIdx++)
|
||||||
|
{
|
||||||
|
auto mesh = modelDef->mMeshes[meshIdx];
|
||||||
|
for (int primIdx = 0; primIdx < (int)mesh.mPrimitives.mSize; primIdx++)
|
||||||
|
{
|
||||||
|
auto prims = mesh.mPrimitives[primIdx];
|
||||||
|
outString += StrFormat("%d\t%d\t%d\t%d", meshIdx, primIdx, prims.mIndices.size(), prims.mVertices.size());
|
||||||
|
for (auto& texPath : prims.mTexPaths)
|
||||||
|
{
|
||||||
|
outString += "\t";
|
||||||
|
outString += texPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
outString += "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return outString.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
BF_EXPORT float BF_CALLTYPE ModelDef_GetFrameRate(ModelDef* modelDef)
|
BF_EXPORT float BF_CALLTYPE ModelDef_GetFrameRate(ModelDef* modelDef)
|
||||||
{
|
{
|
||||||
return modelDef->mFrameRate;
|
return modelDef->mFrameRate;
|
||||||
|
@ -60,6 +97,14 @@ BF_EXPORT ModelAnimation* BF_CALLTYPE ModelDef_GetAnimation(ModelDef* modelDef,
|
||||||
return &modelDef->mAnims[animIdx];
|
return &modelDef->mAnims[animIdx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BF_EXPORT void BF_CALLTYPE ModelDef_SetTextures(ModelDef* modelDef, int32 meshIdx, int32 primitivesIdx, char** paths, int32 pathCount)
|
||||||
|
{
|
||||||
|
auto& prims = modelDef->mMeshes[meshIdx].mPrimitives[primitivesIdx];
|
||||||
|
prims.mTexPaths.Clear();
|
||||||
|
for (int i = 0; i < pathCount; i++)
|
||||||
|
prims.mTexPaths.Add(paths[i]);
|
||||||
|
}
|
||||||
|
|
||||||
BF_EXPORT void BF_CALLTYPE ModelDefAnimation_GetJointTranslation(ModelAnimation* modelAnimation, int jointIdx, float frame, ModelJointTranslation* outJointTranslation)
|
BF_EXPORT void BF_CALLTYPE ModelDefAnimation_GetJointTranslation(ModelAnimation* modelAnimation, int jointIdx, float frame, ModelJointTranslation* outJointTranslation)
|
||||||
{
|
{
|
||||||
modelAnimation->GetJointTranslation(jointIdx, frame, outJointTranslation);
|
modelAnimation->GetJointTranslation(jointIdx, frame, outJointTranslation);
|
||||||
|
@ -77,9 +122,169 @@ BF_EXPORT const char* BF_CALLTYPE ModelDefAnimation_GetName(ModelAnimation* mode
|
||||||
|
|
||||||
BF_EXPORT void BF_CALLTYPE ModelDefAnimation_Clip(ModelAnimation* modelAnimation, int startFrame, int numFrames)
|
BF_EXPORT void BF_CALLTYPE ModelDefAnimation_Clip(ModelAnimation* modelAnimation, int startFrame, int numFrames)
|
||||||
{
|
{
|
||||||
modelAnimation->mFrames.erase(modelAnimation->mFrames.begin(), modelAnimation->mFrames.begin() + startFrame);
|
modelAnimation->mFrames.RemoveRange(0, startFrame);
|
||||||
modelAnimation->mFrames.erase(modelAnimation->mFrames.begin() + numFrames, modelAnimation->mFrames.end());
|
modelAnimation->mFrames.RemoveRange(numFrames, modelAnimation->mFrames.Count() - numFrames);
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelDef::~ModelDef()
|
||||||
|
{
|
||||||
|
for (auto& materialInstance : mMaterials)
|
||||||
|
{
|
||||||
|
materialInstance.mDef->mRefCount--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelMaterialDef* ModelMaterialDef::CreateOrGet(const StringImpl& prefix, const StringImpl& path)
|
||||||
|
{
|
||||||
|
StringT<128> key = prefix;
|
||||||
|
key += ":";
|
||||||
|
key += path;
|
||||||
|
ModelMaterialDef** modelMaterialDefPtr = NULL;
|
||||||
|
if (sModelManager.mMaterialMap.TryAdd(key, NULL, &modelMaterialDefPtr))
|
||||||
|
*modelMaterialDefPtr = new ModelMaterialDef();
|
||||||
|
return *modelMaterialDefPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
class ModelReader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ModelDef* mModelDef;
|
||||||
|
DataStream* mFS;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ModelReader(ModelDef* modelDef)
|
||||||
|
{
|
||||||
|
mFS = NULL;
|
||||||
|
mModelDef = modelDef;
|
||||||
|
}
|
||||||
|
|
||||||
|
~ModelReader()
|
||||||
|
{
|
||||||
|
delete mFS;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReadFile()
|
||||||
|
{
|
||||||
|
int sig = mFS->ReadInt32();
|
||||||
|
if (sig != 0xBEEF0001)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int flags = mFS->ReadInt32();
|
||||||
|
Array<String> texNames;
|
||||||
|
int texNameSize = mFS->ReadInt32();
|
||||||
|
for (int i = 0; i < texNameSize; i++)
|
||||||
|
{
|
||||||
|
String path = mFS->ReadAscii32SizedString();
|
||||||
|
texNames.Add(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
int idxCount = mFS->ReadInt32();
|
||||||
|
|
||||||
|
mModelDef->mMeshes.Add(ModelMesh());
|
||||||
|
auto& modelMesh = mModelDef->mMeshes[0];
|
||||||
|
modelMesh.mPrimitives.Add(ModelPrimitives());
|
||||||
|
auto& modelPrimitives = modelMesh.mPrimitives[0];
|
||||||
|
|
||||||
|
modelPrimitives.mFlags = (ModelPrimitives::Flags)flags;
|
||||||
|
modelPrimitives.mTexPaths = texNames;
|
||||||
|
|
||||||
|
modelPrimitives.mIndices.Resize(idxCount);
|
||||||
|
mFS->Read(modelPrimitives.mIndices.mVals, idxCount * 2);
|
||||||
|
|
||||||
|
int vtxCount = mFS->ReadInt32();
|
||||||
|
modelPrimitives.mVertices.Resize(vtxCount);
|
||||||
|
for (int i = 0; i < vtxCount; i++)
|
||||||
|
{
|
||||||
|
if ((flags & ModelPrimitives::Flags_Vertex_Position) != 0)
|
||||||
|
mFS->ReadT(modelPrimitives.mVertices[i].mPosition);
|
||||||
|
if ((flags & ModelPrimitives::Flags_Vertex_Tex0) != 0)
|
||||||
|
mFS->ReadT(modelPrimitives.mVertices[i].mTexCoords);
|
||||||
|
if ((flags & ModelPrimitives::Flags_Vertex_Tex1) != 0)
|
||||||
|
mFS->ReadT(modelPrimitives.mVertices[i].mBumpTexCoords);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReadFile(const StringImpl& fileName, const StringImpl& baseDir)
|
||||||
|
{
|
||||||
|
if (fileName.Contains(':'))
|
||||||
|
{
|
||||||
|
int colon = (int)fileName.IndexOf(':');
|
||||||
|
String addrStr = fileName.Substring(1, colon - 1);
|
||||||
|
String lenStr = fileName.Substring(colon + 1);
|
||||||
|
void* addr = (void*)(intptr)strtoll(addrStr.c_str(), NULL, 16);
|
||||||
|
int len = (int)strtol(lenStr.c_str(), NULL, 10);
|
||||||
|
MemStream* memStream = new MemStream(addr, len, false);
|
||||||
|
mFS = memStream;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FileStream* fs = new FileStream();
|
||||||
|
mFS = fs;
|
||||||
|
if (!fs->Open(fileName, "rb"))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ReadFile();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BF_EXPORT void* BF_CALLTYPE Res_OpenModel(const char* fileName, const char* baseDir, void* vertexDefinition)
|
||||||
|
{
|
||||||
|
ModelDef* modelDef = new ModelDef();
|
||||||
|
modelDef->mLoadDir = baseDir;
|
||||||
|
ModelReader reader(modelDef);
|
||||||
|
if (!reader.ReadFile(fileName, baseDir))
|
||||||
|
{
|
||||||
|
delete modelDef;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return modelDef;
|
||||||
|
}
|
||||||
|
|
||||||
|
BF_EXPORT StringView BF_CALLTYPE Res_SerializeModel(ModelDef* modelDef)
|
||||||
|
{
|
||||||
|
DynMemStream ms;
|
||||||
|
ms.Write((int)0xBEEF0001);
|
||||||
|
|
||||||
|
for (auto& mesh : modelDef->mMeshes)
|
||||||
|
{
|
||||||
|
for (auto& prims : mesh.mPrimitives)
|
||||||
|
{
|
||||||
|
ms.Write((int)prims.mFlags);
|
||||||
|
ms.Write(prims.mTexPaths.mSize);
|
||||||
|
for (auto& path : prims.mTexPaths)
|
||||||
|
ms.Write(path);
|
||||||
|
|
||||||
|
ms.Write((int)prims.mIndices.mSize);
|
||||||
|
ms.Write(prims.mIndices.mVals, prims.mIndices.mSize * 2);
|
||||||
|
|
||||||
|
ms.Write((int)prims.mVertices.mSize);
|
||||||
|
|
||||||
|
for (int i = 0; i < prims.mVertices.mSize; i++)
|
||||||
|
{
|
||||||
|
auto& vtx = prims.mVertices[i];
|
||||||
|
if ((prims.mFlags & ModelPrimitives::Flags_Vertex_Position) != 0)
|
||||||
|
ms.WriteT(vtx.mPosition);
|
||||||
|
if ((prims.mFlags & ModelPrimitives::Flags_Vertex_Tex0) != 0)
|
||||||
|
ms.WriteT(vtx.mTexCoords);
|
||||||
|
if ((prims.mFlags & ModelPrimitives::Flags_Vertex_Tex1) != 0)
|
||||||
|
ms.WriteT(vtx.mBumpTexCoords);
|
||||||
|
if ((prims.mFlags & ModelPrimitives::Flags_Vertex_Color) != 0)
|
||||||
|
ms.WriteT(vtx.mColor);
|
||||||
|
if ((prims.mFlags & ModelPrimitives::Flags_Vertex_Normal) != 0)
|
||||||
|
ms.WriteT(vtx.mNormal);
|
||||||
|
if ((prims.mFlags & ModelPrimitives::Flags_Vertex_Tangent) != 0)
|
||||||
|
ms.WriteT(vtx.mTangent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String& outString = *gModelDef_TLStrReturn.Get();
|
||||||
|
return outString;
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "util/Quaternion.h"
|
#include "util/Quaternion.h"
|
||||||
#include "util/Vector.h"
|
#include "util/Vector.h"
|
||||||
|
#include "util/Array.h"
|
||||||
|
#include "gfx/Texture.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
NS_BF_BEGIN;
|
NS_BF_BEGIN;
|
||||||
|
@ -18,14 +20,14 @@ public:
|
||||||
class ModelAnimationFrame
|
class ModelAnimationFrame
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::vector<ModelJointTranslation> mJointTranslations;
|
Array<ModelJointTranslation> mJointTranslations;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ModelAnimation
|
class ModelAnimation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
String mName;
|
String mName;
|
||||||
std::vector<ModelAnimationFrame> mFrames;
|
Array<ModelAnimationFrame> mFrames;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void GetJointTranslation(int jointIdx, float frameNum, ModelJointTranslation* outJointTranslation);
|
void GetJointTranslation(int jointIdx, float frameNum, ModelJointTranslation* outJointTranslation);
|
||||||
|
@ -55,14 +57,113 @@ public:
|
||||||
Matrix4 mPoseInvMatrix;
|
Matrix4 mPoseInvMatrix;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ModelMetalicRoughness
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Vector3 mBaseColorFactor;
|
||||||
|
float mMetallicFactor;
|
||||||
|
float mRoughnessFactor;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ModelMetalicRoughness()
|
||||||
|
{
|
||||||
|
mMetallicFactor = 0;
|
||||||
|
mRoughnessFactor = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ModelMaterialDef
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
class TextureParameterValue
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
String mName;
|
||||||
|
String mTexturePath;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TextureParameterValue()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
~TextureParameterValue()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
String mName;
|
||||||
|
int mRefCount;
|
||||||
|
bool mInitialized;
|
||||||
|
OwnedArray<TextureParameterValue> mTextureParameterValues;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ModelMaterialDef()
|
||||||
|
{
|
||||||
|
mRefCount = 0;
|
||||||
|
mInitialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ModelMaterialDef* CreateOrGet(const StringImpl& prefix, const StringImpl& path);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ModelMaterialInstance
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ModelMaterialDef* mDef;
|
||||||
|
String mName;
|
||||||
|
ModelMetalicRoughness mModelMetalicRoughness;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ModelPrimitives
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Flags
|
||||||
|
{
|
||||||
|
Flags_None = 0,
|
||||||
|
Flags_Vertex_Position = 1,
|
||||||
|
Flags_Vertex_Tex0 = 2,
|
||||||
|
Flags_Vertex_Tex1 = 4,
|
||||||
|
Flags_Vertex_Tex2 = 8,
|
||||||
|
Flags_Vertex_Color = 0x10,
|
||||||
|
Flags_Vertex_Normal = 0x20,
|
||||||
|
Flags_Vertex_Tangent = 0x40,
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
Array<ModelVertex> mVertices;
|
||||||
|
Array<uint16> mIndices;
|
||||||
|
ModelMaterialInstance* mMaterial;
|
||||||
|
Array<String> mTexPaths;
|
||||||
|
Flags mFlags;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ModelPrimitives()
|
||||||
|
{
|
||||||
|
mMaterial = NULL;
|
||||||
|
mFlags = Flags_None;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class ModelMesh
|
class ModelMesh
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
String mName;
|
String mName;
|
||||||
std::vector<ModelVertex> mVertices;
|
//String mTexFileName;
|
||||||
std::vector<uint16> mIndices;
|
//String mBumpFileName;
|
||||||
String mTexFileName;
|
Array<ModelPrimitives> mPrimitives;
|
||||||
String mBumpFileName;
|
};
|
||||||
|
|
||||||
|
class ModelNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
String mName;
|
||||||
|
Vector3 mTranslation;
|
||||||
|
Vector4 mRotation;
|
||||||
|
ModelMesh* mMesh;
|
||||||
|
Array<ModelNode*> mChildren;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ModelDef
|
class ModelDef
|
||||||
|
@ -70,9 +171,14 @@ class ModelDef
|
||||||
public:
|
public:
|
||||||
String mLoadDir;
|
String mLoadDir;
|
||||||
float mFrameRate;
|
float mFrameRate;
|
||||||
std::vector<ModelMesh> mMeshes;
|
Array<ModelMesh> mMeshes;
|
||||||
std::vector<ModelJoint> mJoints;
|
Array<ModelJoint> mJoints;
|
||||||
std::vector<ModelAnimation> mAnims;
|
Array<ModelAnimation> mAnims;
|
||||||
|
Array<ModelNode> mNodes;
|
||||||
|
Array<ModelMaterialInstance> mMaterials;
|
||||||
|
|
||||||
|
public:
|
||||||
|
~ModelDef();
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_BF_END;
|
NS_BF_END;
|
||||||
|
|
|
@ -6,8 +6,8 @@ ModelInstance::ModelInstance(ModelDef* modelDef)
|
||||||
{
|
{
|
||||||
mNext = NULL;
|
mNext = NULL;
|
||||||
mModelDef = modelDef;
|
mModelDef = modelDef;
|
||||||
mJointTranslations.resize(mModelDef->mJoints.size());
|
mJointTranslations.Resize(mModelDef->mJoints.size());
|
||||||
mMeshesVisible.insert(mMeshesVisible.begin(), mModelDef->mMeshes.size(), true);
|
mMeshesVisible.Insert(0, mModelDef->mMeshes.size(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Beefy::ModelInstance::SetJointPosition(int jointIdx, const ModelJointTranslation& jointTranslation)
|
void Beefy::ModelInstance::SetJointPosition(int jointIdx, const ModelJointTranslation& jointTranslation)
|
||||||
|
|
|
@ -11,8 +11,8 @@ class ModelInstance : public RenderCmd
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ModelDef* mModelDef;
|
ModelDef* mModelDef;
|
||||||
std::vector<ModelJointTranslation> mJointTranslations;
|
Array<ModelJointTranslation> mJointTranslations;
|
||||||
std::vector<bool> mMeshesVisible;
|
Array<bool> mMeshesVisible;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ModelInstance(ModelDef* modelDef);
|
ModelInstance(ModelDef* modelDef);
|
||||||
|
|
|
@ -21,6 +21,7 @@ RenderState::RenderState()
|
||||||
mDepthFunc = DepthFunc_Always;
|
mDepthFunc = DepthFunc_Always;
|
||||||
mShader = NULL;
|
mShader = NULL;
|
||||||
mClipped = false;
|
mClipped = false;
|
||||||
|
mTexWrap = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderTarget::RenderTarget()
|
RenderTarget::RenderTarget()
|
||||||
|
|
|
@ -182,6 +182,7 @@ public:
|
||||||
bool mWriteDepthBuffer;
|
bool mWriteDepthBuffer;
|
||||||
DepthFunc mDepthFunc;
|
DepthFunc mDepthFunc;
|
||||||
bool mClipped;
|
bool mClipped;
|
||||||
|
bool mTexWrap;
|
||||||
Rect mClipRect;
|
Rect mClipRect;
|
||||||
CullMode mCullMode;
|
CullMode mCullMode;
|
||||||
|
|
||||||
|
@ -190,6 +191,7 @@ public:
|
||||||
virtual ~RenderState() {}
|
virtual ~RenderState() {}
|
||||||
|
|
||||||
virtual void SetShader(Shader* shader) { mShader = shader; }
|
virtual void SetShader(Shader* shader) { mShader = shader; }
|
||||||
|
virtual void SetTexWrap(bool wrap) { mTexWrap = wrap; }
|
||||||
virtual void SetClipped(bool clipped) { mClipped = clipped; }
|
virtual void SetClipped(bool clipped) { mClipped = clipped; }
|
||||||
virtual void SetClipRect(const Rect& rect) { mClipRect = rect; }
|
virtual void SetClipRect(const Rect& rect) { mClipRect = rect; }
|
||||||
virtual void SetWriteDepthBuffer(bool writeDepthBuffer) { mWriteDepthBuffer = writeDepthBuffer; }
|
virtual void SetWriteDepthBuffer(bool writeDepthBuffer) { mWriteDepthBuffer = writeDepthBuffer; }
|
||||||
|
|
875
BeefySysLib/gfx/glTF.cpp
Normal file
875
BeefySysLib/gfx/glTF.cpp
Normal file
|
@ -0,0 +1,875 @@
|
||||||
|
#include "glTF.h"
|
||||||
|
#include "gfx/ModelInstance.h"
|
||||||
|
#include "util/Json.h"
|
||||||
|
#include "gfx/RenderDevice.h"
|
||||||
|
#include "BFApp.h"
|
||||||
|
|
||||||
|
USING_NS_BF;
|
||||||
|
|
||||||
|
static bool IsWhitespace(char c)
|
||||||
|
{
|
||||||
|
return (c == ' ') || (c == '\t') || (c == '\n') || (c == '\r');
|
||||||
|
}
|
||||||
|
|
||||||
|
class GLTFPropsParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum NodeKind
|
||||||
|
{
|
||||||
|
NodeKind_None,
|
||||||
|
NodeKind_End,
|
||||||
|
NodeKind_LBrace,
|
||||||
|
NodeKind_RBrace,
|
||||||
|
NodeKind_LBracket,
|
||||||
|
NodeKind_RBracket,
|
||||||
|
NodeKind_Equals,
|
||||||
|
NodeKind_Index,
|
||||||
|
NodeKind_Integer,
|
||||||
|
NodeKind_Float,
|
||||||
|
NodeKind_String
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NodeKind mKind;
|
||||||
|
int mStart;
|
||||||
|
int mEnd;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
int mValueInt;
|
||||||
|
float mValueFloat;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
Node()
|
||||||
|
{
|
||||||
|
mKind = NodeKind_None;
|
||||||
|
mStart = -1;
|
||||||
|
mEnd = -1;
|
||||||
|
mValueInt = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
char* mStart;
|
||||||
|
char* mPtr;
|
||||||
|
char* mEnd;
|
||||||
|
Node mNext;
|
||||||
|
|
||||||
|
public:
|
||||||
|
GLTFPropsParser(const StringImpl& str)
|
||||||
|
{
|
||||||
|
mStart = str.mPtr;
|
||||||
|
mPtr = mStart;
|
||||||
|
mEnd = mStart + str.mLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
// double ParseLiteralDouble()
|
||||||
|
// {
|
||||||
|
// char buf[256];
|
||||||
|
// int len = BF_MAX(mTokenEnd - mTokenStart, 255);
|
||||||
|
//
|
||||||
|
// memcpy(buf, &mSrc[mTokenStart], len);
|
||||||
|
// char c = buf[len - 1];
|
||||||
|
// if ((c == 'd') || (c == 'D') || (c == 'f') || (c == 'F'))
|
||||||
|
// buf[len - 1] = '\0';
|
||||||
|
// else
|
||||||
|
// buf[len] = '\0';
|
||||||
|
//
|
||||||
|
// return strtod(buf, NULL);
|
||||||
|
// }
|
||||||
|
|
||||||
|
Node PeekNext()
|
||||||
|
{
|
||||||
|
if (mNext.mKind != NodeKind_None)
|
||||||
|
return mNext;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (mPtr >= mEnd)
|
||||||
|
{
|
||||||
|
mNext.mKind = NodeKind_End;
|
||||||
|
return mNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* start = mPtr;
|
||||||
|
char c = *(mPtr++);
|
||||||
|
|
||||||
|
if (c == '{')
|
||||||
|
mNext.mKind = NodeKind_LBrace;
|
||||||
|
else if (c == '}')
|
||||||
|
mNext.mKind = NodeKind_RBrace;
|
||||||
|
else if (c == '[')
|
||||||
|
mNext.mKind = NodeKind_LBracket;
|
||||||
|
else if (c == ']')
|
||||||
|
mNext.mKind = NodeKind_RBracket;
|
||||||
|
else if (c == '=')
|
||||||
|
mNext.mKind = NodeKind_Equals;
|
||||||
|
|
||||||
|
if (mNext.mKind != NodeKind_None)
|
||||||
|
{
|
||||||
|
mNext.mStart = (int)(mPtr - mStart - 1);
|
||||||
|
mNext.mEnd = (int)(mPtr - mStart);
|
||||||
|
return mNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((c >= '0') && (c <= '9'))
|
||||||
|
{
|
||||||
|
bool hadDot = false;
|
||||||
|
while (mPtr < mEnd)
|
||||||
|
{
|
||||||
|
char c = *mPtr;
|
||||||
|
if (c == '.')
|
||||||
|
{
|
||||||
|
mPtr++;
|
||||||
|
hadDot = true;
|
||||||
|
}
|
||||||
|
else if ((c >= '0') && (c <= '9'))
|
||||||
|
{
|
||||||
|
mPtr++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
mNext.mStart = (int)(start - mStart);
|
||||||
|
mNext.mEnd = (int)(mPtr - mStart);
|
||||||
|
|
||||||
|
char buf[256];
|
||||||
|
int len = BF_MIN((int)(mPtr - start), 255);
|
||||||
|
|
||||||
|
memcpy(buf, start, len);
|
||||||
|
char c = buf[len - 1];
|
||||||
|
if ((c == 'd') || (c == 'D') || (c == 'f') || (c == 'F'))
|
||||||
|
buf[len - 1] = '\0';
|
||||||
|
else
|
||||||
|
buf[len] = '\0';
|
||||||
|
|
||||||
|
if (hadDot)
|
||||||
|
{
|
||||||
|
mNext.mKind = NodeKind_Float;
|
||||||
|
mNext.mValueFloat = (float)strtod(buf, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mNext.mKind = NodeKind_Integer;
|
||||||
|
mNext.mValueInt = atoi(buf);
|
||||||
|
}
|
||||||
|
return mNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsWhitespace(c))
|
||||||
|
{
|
||||||
|
char* lastCPtr = start;
|
||||||
|
while (mPtr < mEnd)
|
||||||
|
{
|
||||||
|
char c = *mPtr;
|
||||||
|
if ((c == '}') || (c == '=') || (c == '[') || (c == '\r') || (c == '\n'))
|
||||||
|
break;
|
||||||
|
if (c != ' ')
|
||||||
|
lastCPtr = mPtr;
|
||||||
|
mPtr++;
|
||||||
|
}
|
||||||
|
mPtr = lastCPtr + 1;
|
||||||
|
|
||||||
|
mNext.mStart = (int)(start - mStart);
|
||||||
|
mNext.mEnd = (int)(mPtr - mStart);
|
||||||
|
mNext.mKind = NodeKind_String;
|
||||||
|
return mNext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Node GetNext()
|
||||||
|
{
|
||||||
|
auto node = PeekNext();
|
||||||
|
mNext = Node();
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringView GetStringView(const Node& node)
|
||||||
|
{
|
||||||
|
return StringView(mStart + node.mStart, node.mEnd - node.mStart);
|
||||||
|
}
|
||||||
|
|
||||||
|
StringView GetStringView(const Node& node, StringView& prefix)
|
||||||
|
{
|
||||||
|
auto stringView = StringView(mStart + node.mStart, node.mEnd - node.mStart);
|
||||||
|
if (!stringView.EndsWith('\''))
|
||||||
|
{
|
||||||
|
prefix = "";
|
||||||
|
return stringView;
|
||||||
|
}
|
||||||
|
|
||||||
|
int strStartIdx = (int)stringView.IndexOf('\'');
|
||||||
|
prefix = StringView(stringView, 0, strStartIdx);
|
||||||
|
return StringView(stringView, strStartIdx + 1, (int)stringView.mLength - strStartIdx - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetNextStringView(StringView& prefix, StringView& value)
|
||||||
|
{
|
||||||
|
auto node = GetNext();
|
||||||
|
if (node.mKind != NodeKind_String)
|
||||||
|
return false;
|
||||||
|
auto stringView = StringView(mStart + node.mStart, node.mEnd - node.mStart);
|
||||||
|
if (!stringView.EndsWith('\''))
|
||||||
|
{
|
||||||
|
prefix = "";
|
||||||
|
value = stringView;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
int strStartIdx = (int)stringView.IndexOf('\'');
|
||||||
|
prefix = StringView(stringView, 0, strStartIdx);
|
||||||
|
value = StringView(stringView, strStartIdx + 1, (int)stringView.mLength - strStartIdx - 2);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ComponentType
|
||||||
|
{
|
||||||
|
Int8 = 5120,
|
||||||
|
UInt8 = 5121,
|
||||||
|
Int16 = 5122,
|
||||||
|
UInt16 = 5123,
|
||||||
|
UInt32 = 5125,
|
||||||
|
Float = 5126,
|
||||||
|
};
|
||||||
|
|
||||||
|
BF_EXPORT void* BF_CALLTYPE Res_OpenGLTF(const char* fileName, const char* baseDir, void* vertexDefinition)
|
||||||
|
{
|
||||||
|
ModelDef* modelDef = new ModelDef();
|
||||||
|
GLTFReader reader(modelDef);
|
||||||
|
if (!reader.ReadFile(fileName, baseDir))
|
||||||
|
{
|
||||||
|
delete modelDef;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return modelDef;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLTFReader::GLTFReader(ModelDef* modelDef)
|
||||||
|
{
|
||||||
|
mModelDef = modelDef;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLTFReader::~GLTFReader()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DataSpan
|
||||||
|
{
|
||||||
|
uint8* mPtr;
|
||||||
|
int mSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DataAccessor
|
||||||
|
{
|
||||||
|
uint8* mPtr;
|
||||||
|
int mSize;
|
||||||
|
int mCount;
|
||||||
|
ComponentType mComponentType;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static void ReadBuffer(DataAccessor& dataAccessor, T* outPtr, int outStride)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < dataAccessor.mCount; i++)
|
||||||
|
*(T*)((uint8*)outPtr + i * outStride) = ((T*)dataAccessor.mPtr)[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static void ReadBuffer(DataAccessor& dataAccessor, T* outPtr, int outStride, int inStride)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < dataAccessor.mCount; i++)
|
||||||
|
*(T*)((uint8*)outPtr + i * outStride) = *(T*)(dataAccessor.mPtr + i * inStride);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TrySkipValue(GLTFPropsParser& propsParser)
|
||||||
|
{
|
||||||
|
auto nextNode = propsParser.PeekNext();
|
||||||
|
|
||||||
|
if (nextNode.mKind == GLTFPropsParser::NodeKind_LBracket)
|
||||||
|
{
|
||||||
|
propsParser.GetNext();
|
||||||
|
propsParser.GetNext();
|
||||||
|
propsParser.GetNext();
|
||||||
|
nextNode = propsParser.PeekNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextNode.mKind == GLTFPropsParser::NodeKind_Equals)
|
||||||
|
{
|
||||||
|
propsParser.GetNext();
|
||||||
|
|
||||||
|
int depth = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
auto node = propsParser.GetNext();
|
||||||
|
if (node.mKind == GLTFPropsParser::NodeKind_End)
|
||||||
|
return;
|
||||||
|
if (node.mKind == GLTFPropsParser::NodeKind_LBrace)
|
||||||
|
depth++;
|
||||||
|
else if (node.mKind == GLTFPropsParser::NodeKind_RBrace)
|
||||||
|
depth--;
|
||||||
|
if (node.mKind == GLTFPropsParser::NodeKind_LBracket)
|
||||||
|
depth++;
|
||||||
|
if (node.mKind == GLTFPropsParser::NodeKind_LBracket)
|
||||||
|
depth--;
|
||||||
|
} while (depth > 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ExpectIndex(GLTFPropsParser& propsParser, int& idx)
|
||||||
|
{
|
||||||
|
auto node = propsParser.GetNext();
|
||||||
|
if (node.mKind != GLTFPropsParser::NodeKind_LBracket)
|
||||||
|
return false;
|
||||||
|
node = propsParser.GetNext();
|
||||||
|
if (node.mKind != GLTFPropsParser::NodeKind_Integer)
|
||||||
|
return false;
|
||||||
|
idx = node.mValueInt;
|
||||||
|
node = propsParser.GetNext();
|
||||||
|
if (node.mKind != GLTFPropsParser::NodeKind_RBracket)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool ExpectOpen(GLTFPropsParser& propsParser)
|
||||||
|
{
|
||||||
|
if (propsParser.GetNext().mKind != GLTFPropsParser::NodeKind_LBrace)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool ExpectClose(GLTFPropsParser& propsParser)
|
||||||
|
{
|
||||||
|
if (propsParser.GetNext().mKind != GLTFPropsParser::NodeKind_RBrace)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool ExpectEquals(GLTFPropsParser& propsParser)
|
||||||
|
{
|
||||||
|
if (propsParser.GetNext().mKind != GLTFPropsParser::NodeKind_Equals)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool GLTFReader::ParseMaterialDef(ModelMaterialDef* materialDef, const StringImpl& matText)
|
||||||
|
{
|
||||||
|
GLTFPropsParser propsParser(matText);
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
auto node = propsParser.GetNext();
|
||||||
|
if (node.mKind == GLTFPropsParser::NodeKind_End)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (node.mKind == GLTFPropsParser::NodeKind_String)
|
||||||
|
{
|
||||||
|
auto key = propsParser.GetStringView(node);
|
||||||
|
if (key == "Parent")
|
||||||
|
{
|
||||||
|
if (propsParser.GetNext().mKind != GLTFPropsParser::NodeKind_Equals)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto valueNode = propsParser.GetNext();
|
||||||
|
if (valueNode.mKind != GLTFPropsParser::NodeKind_String)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
StringView prefix;
|
||||||
|
StringView str = propsParser.GetStringView(valueNode, prefix);
|
||||||
|
auto parentMaterialDef = LoadMaterial(str);
|
||||||
|
}
|
||||||
|
else if (key == "TextureParameterValues")
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
if (!ExpectIndex(propsParser, count))
|
||||||
|
return false;
|
||||||
|
if (!ExpectEquals(propsParser))
|
||||||
|
return false;
|
||||||
|
if (!ExpectOpen(propsParser))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
node = propsParser.GetNext();
|
||||||
|
if (node.mKind == GLTFPropsParser::NodeKind_RBrace)
|
||||||
|
break;
|
||||||
|
if (node.mKind != GLTFPropsParser::NodeKind_String)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
StringView prefix;
|
||||||
|
StringView str = propsParser.GetStringView(node, prefix);
|
||||||
|
if (str == "TextureParameterValues")
|
||||||
|
{
|
||||||
|
auto textureParamValue = materialDef->mTextureParameterValues.Alloc();
|
||||||
|
|
||||||
|
int idx = 0;
|
||||||
|
if (!ExpectIndex(propsParser, idx))
|
||||||
|
return false;
|
||||||
|
if (!ExpectEquals(propsParser))
|
||||||
|
return false;
|
||||||
|
if (!ExpectOpen(propsParser))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
node = propsParser.GetNext();
|
||||||
|
if (node.mKind == GLTFPropsParser::NodeKind_RBrace)
|
||||||
|
break;
|
||||||
|
if (node.mKind != GLTFPropsParser::NodeKind_String)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
str = propsParser.GetStringView(node, prefix);
|
||||||
|
if (str == "ParameterInfo")
|
||||||
|
{
|
||||||
|
if (!ExpectEquals(propsParser))
|
||||||
|
return false;
|
||||||
|
if (!ExpectOpen(propsParser))
|
||||||
|
return false;
|
||||||
|
if (!propsParser.GetNextStringView(prefix, str))
|
||||||
|
return false;
|
||||||
|
if (!ExpectEquals(propsParser))
|
||||||
|
return false;
|
||||||
|
if (!propsParser.GetNextStringView(prefix, str))
|
||||||
|
return false;
|
||||||
|
textureParamValue->mName = str;
|
||||||
|
|
||||||
|
if (!ExpectClose(propsParser))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (str == "ParameterValue")
|
||||||
|
{
|
||||||
|
if (!ExpectEquals(propsParser))
|
||||||
|
return false;
|
||||||
|
if (!propsParser.GetNextStringView(prefix, str))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
String path = mRootDir;
|
||||||
|
path += str;
|
||||||
|
int dotPos = (int)path.IndexOf('.');
|
||||||
|
if (dotPos != -1)
|
||||||
|
path.RemoveToEnd(dotPos);
|
||||||
|
path += ".tga";
|
||||||
|
|
||||||
|
textureParamValue->mTexturePath = path;
|
||||||
|
|
||||||
|
// Texture* texture = gBFApp->mRenderDevice->LoadTexture(path, 0);
|
||||||
|
// textureParamValue->mTexture = texture;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
TrySkipValue(propsParser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TrySkipValue(propsParser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TrySkipValue(propsParser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelMaterialDef* GLTFReader::LoadMaterial(const StringImpl& relPath)
|
||||||
|
{
|
||||||
|
String propsPath;
|
||||||
|
if (relPath.StartsWith('/'))
|
||||||
|
{
|
||||||
|
propsPath = mRootDir + relPath;
|
||||||
|
int dotPos = (int)propsPath.LastIndexOf('.');
|
||||||
|
if (dotPos > 0)
|
||||||
|
propsPath.RemoveToEnd(dotPos);
|
||||||
|
propsPath += ".props.txt";
|
||||||
|
}
|
||||||
|
else if (mBasePathName.Contains("staticmesh"))
|
||||||
|
propsPath = GetFileDir(mBasePathName) + "/" + relPath + ".props.txt";
|
||||||
|
else
|
||||||
|
propsPath = GetFileDir(mBasePathName) + "/materials/" + relPath + ".props.txt";
|
||||||
|
|
||||||
|
ModelMaterialDef* materialDef = ModelMaterialDef::CreateOrGet("GLTF", propsPath);
|
||||||
|
|
||||||
|
if (materialDef->mInitialized)
|
||||||
|
return materialDef;
|
||||||
|
|
||||||
|
materialDef->mInitialized = true;
|
||||||
|
|
||||||
|
String propText;
|
||||||
|
if (LoadTextData(propsPath, propText))
|
||||||
|
{
|
||||||
|
if (!ParseMaterialDef(materialDef, propText))
|
||||||
|
{
|
||||||
|
// Had error
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return materialDef;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GLTFReader::LoadModelProps(const StringImpl& propsPath)
|
||||||
|
{
|
||||||
|
String propText;
|
||||||
|
if (!LoadTextData(propsPath, propText))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
GLTFPropsParser propsParser(propText);
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
auto node = propsParser.GetNext();
|
||||||
|
if (node.mKind == GLTFPropsParser::NodeKind_End)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (node.mKind == GLTFPropsParser::NodeKind_String)
|
||||||
|
{
|
||||||
|
auto key = propsParser.GetStringView(node);
|
||||||
|
if (key == "StaticMaterials")
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
if (!ExpectIndex(propsParser, count))
|
||||||
|
return false;
|
||||||
|
if (!ExpectEquals(propsParser))
|
||||||
|
return false;
|
||||||
|
if (!ExpectOpen(propsParser))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
node = propsParser.GetNext();
|
||||||
|
if (node.mKind == GLTFPropsParser::NodeKind_RBrace)
|
||||||
|
break;
|
||||||
|
if (node.mKind != GLTFPropsParser::NodeKind_String)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
StringView prefix;
|
||||||
|
StringView str = propsParser.GetStringView(node, prefix);
|
||||||
|
if (str == "StaticMaterials")
|
||||||
|
{
|
||||||
|
StaticMaterial staticMaterial;
|
||||||
|
|
||||||
|
int idx = 0;
|
||||||
|
if (!ExpectIndex(propsParser, idx))
|
||||||
|
return false;
|
||||||
|
if (!ExpectEquals(propsParser))
|
||||||
|
return false;
|
||||||
|
if (!ExpectOpen(propsParser))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
node = propsParser.GetNext();
|
||||||
|
if (node.mKind == GLTFPropsParser::NodeKind_RBrace)
|
||||||
|
break;
|
||||||
|
if (node.mKind != GLTFPropsParser::NodeKind_String)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
str = propsParser.GetStringView(node, prefix);
|
||||||
|
if (str == "MaterialSlotName")
|
||||||
|
{
|
||||||
|
if (!ExpectEquals(propsParser))
|
||||||
|
return false;
|
||||||
|
if (!propsParser.GetNextStringView(prefix, str))
|
||||||
|
return false;
|
||||||
|
staticMaterial.mMaterialSlotName = str;
|
||||||
|
}
|
||||||
|
else if (str == "MaterialInterface")
|
||||||
|
{
|
||||||
|
if (!ExpectEquals(propsParser))
|
||||||
|
return false;
|
||||||
|
if (!propsParser.GetNextStringView(prefix, str))
|
||||||
|
return false;
|
||||||
|
staticMaterial.mMaterialDef = LoadMaterial(str);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
TrySkipValue(propsParser);
|
||||||
|
}
|
||||||
|
|
||||||
|
mStaticMaterials.Add(staticMaterial);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TrySkipValue(propsParser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TrySkipValue(propsParser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GLTFReader::ReadFile(const StringImpl& filePath, const StringImpl& rootDir)
|
||||||
|
{
|
||||||
|
String basePathName;
|
||||||
|
int dotPos = (int)filePath.LastIndexOf('.');
|
||||||
|
if (dotPos > 0)
|
||||||
|
basePathName = filePath.Substring(0, dotPos);
|
||||||
|
else
|
||||||
|
basePathName = basePathName;
|
||||||
|
mBasePathName = basePathName;
|
||||||
|
mRootDir = rootDir;
|
||||||
|
|
||||||
|
String jsonPath = basePathName + ".gltf";
|
||||||
|
|
||||||
|
char* textData = LoadTextData(jsonPath, NULL);
|
||||||
|
if (textData == NULL)
|
||||||
|
return false;
|
||||||
|
defer({ delete textData; });
|
||||||
|
|
||||||
|
Json* jRoot = Json::Parse(textData);
|
||||||
|
if (jRoot == NULL)
|
||||||
|
return false;
|
||||||
|
defer({ delete jRoot; });
|
||||||
|
|
||||||
|
LoadModelProps(basePathName + ".props.txt");
|
||||||
|
|
||||||
|
Array<Array<uint8>> buffers;
|
||||||
|
Array<DataSpan> bufferViews;
|
||||||
|
Array<DataAccessor> dataAccessors;
|
||||||
|
|
||||||
|
if (auto jBuffers = jRoot->GetObjectItem("buffers"))
|
||||||
|
{
|
||||||
|
for (auto jBuffer = jBuffers->mChild; jBuffer != NULL; jBuffer = jBuffer->mNext)
|
||||||
|
{
|
||||||
|
Array<uint8> data;
|
||||||
|
if (auto jName = jBuffer->GetObjectItem("uri"))
|
||||||
|
{
|
||||||
|
if (jName->mValueString != NULL)
|
||||||
|
{
|
||||||
|
String dataPath = GetFileDir(basePathName) + "/" + jName->mValueString;
|
||||||
|
|
||||||
|
int size = 0;
|
||||||
|
uint8* rawData = LoadBinaryData(dataPath, &size);
|
||||||
|
if (rawData != NULL)
|
||||||
|
data.Insert(0, rawData, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buffers.Add(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto jBufferViews = jRoot->GetObjectItem("bufferViews"))
|
||||||
|
{
|
||||||
|
for (auto jBufferView = jBufferViews->mChild; jBufferView != NULL; jBufferView = jBufferView->mNext)
|
||||||
|
{
|
||||||
|
int bufferIdx = 0;
|
||||||
|
int byteOffset = 0;
|
||||||
|
int byteLength = 0;
|
||||||
|
|
||||||
|
if (auto jBufferIdx = jBufferView->GetObjectItem("buffer"))
|
||||||
|
bufferIdx = jBufferIdx->mValueInt;
|
||||||
|
if (auto jByteOffset = jBufferView->GetObjectItem("byteOffset"))
|
||||||
|
byteOffset = jByteOffset->mValueInt;
|
||||||
|
if (auto jByteLength = jBufferView->GetObjectItem("byteLength"))
|
||||||
|
byteLength = jByteLength->mValueInt;
|
||||||
|
bufferViews.Add(DataSpan{ buffers[bufferIdx].mVals + byteOffset, byteLength });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto jAccessors = jRoot->GetObjectItem("accessors"))
|
||||||
|
{
|
||||||
|
for (auto jAccessor = jAccessors->mChild; jAccessor != NULL; jAccessor = jAccessor->mNext)
|
||||||
|
{
|
||||||
|
DataAccessor dataAccessor = { 0 };
|
||||||
|
if (auto jBufferIdx = jAccessor->GetObjectItem("bufferView"))
|
||||||
|
{
|
||||||
|
DataSpan& dataSpan = bufferViews[jBufferIdx->mValueInt];
|
||||||
|
dataAccessor.mPtr = dataSpan.mPtr;
|
||||||
|
dataAccessor.mSize = dataSpan.mSize;
|
||||||
|
}
|
||||||
|
if (auto jCount = jAccessor->GetObjectItem("count"))
|
||||||
|
dataAccessor.mCount = jCount->mValueInt;
|
||||||
|
if (auto jCount = jAccessor->GetObjectItem("componentType"))
|
||||||
|
dataAccessor.mComponentType = (ComponentType)jCount->mValueInt;
|
||||||
|
|
||||||
|
dataAccessors.Add(dataAccessor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto _GetFloat3 = [&](Json* json, Vector3& vec)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
for (auto jItem = json->mChild; jItem != NULL; jItem = jItem->mNext)
|
||||||
|
{
|
||||||
|
if (i == 0)
|
||||||
|
vec.mX = (float)jItem->mValueDouble;
|
||||||
|
if (i == 1)
|
||||||
|
vec.mY = (float)jItem->mValueDouble;
|
||||||
|
if (i == 2)
|
||||||
|
vec.mZ = (float)jItem->mValueDouble;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto _GetFloat4 = [&](Json* json, Vector4& vec)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
for (auto jItem = json->mChild; jItem != NULL; jItem = jItem->mNext)
|
||||||
|
{
|
||||||
|
if (i == 0)
|
||||||
|
vec.mX = (float)jItem->mValueDouble;
|
||||||
|
if (i == 1)
|
||||||
|
vec.mY = (float)jItem->mValueDouble;
|
||||||
|
if (i == 2)
|
||||||
|
vec.mZ = (float)jItem->mValueDouble;
|
||||||
|
if (i == 3)
|
||||||
|
vec.mW = (float)jItem->mValueDouble;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (auto jMaterials = jRoot->GetObjectItem("materials"))
|
||||||
|
{
|
||||||
|
int materialIdx = 0;
|
||||||
|
for (auto jMaterial = jMaterials->mChild; jMaterial != NULL; jMaterial = jMaterial->mNext)
|
||||||
|
{
|
||||||
|
ModelMaterialInstance modelMaterialInstance;
|
||||||
|
if (auto jName = jMaterial->GetObjectItem("name"))
|
||||||
|
{
|
||||||
|
if (jName->mValueString != NULL)
|
||||||
|
{
|
||||||
|
modelMaterialInstance.mName = jName->mValueString;
|
||||||
|
String matPath = jName->mValueString;
|
||||||
|
|
||||||
|
if (materialIdx < mStaticMaterials.mSize)
|
||||||
|
matPath = mStaticMaterials[materialIdx].mMaterialSlotName;
|
||||||
|
|
||||||
|
ModelMaterialDef* materialDef = LoadMaterial(matPath);
|
||||||
|
modelMaterialInstance.mDef = materialDef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (auto jPBRMetallicRoughness = jMaterial->GetObjectItem("pbrMetallicRoughness"))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
mModelDef->mMaterials.Add(modelMaterialInstance);
|
||||||
|
materialIdx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto jMeshes = jRoot->GetObjectItem("meshes"))
|
||||||
|
{
|
||||||
|
for (auto jMesh = jMeshes->mChild; jMesh != NULL; jMesh = jMesh->mNext)
|
||||||
|
{
|
||||||
|
ModelMesh modelMesh;
|
||||||
|
|
||||||
|
if (auto jName = jMesh->GetObjectItem("name"))
|
||||||
|
{
|
||||||
|
if (jName->mValueString != NULL)
|
||||||
|
modelMesh.mName = jName->mValueString;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto jPrimitives = jMesh->GetObjectItem("primitives"))
|
||||||
|
{
|
||||||
|
modelMesh.mPrimitives.Resize(jPrimitives->GetArraySize());
|
||||||
|
|
||||||
|
int primCount = 0;
|
||||||
|
for (auto jPrimitive = jPrimitives->mChild; jPrimitive != NULL; jPrimitive = jPrimitive->mNext)
|
||||||
|
{
|
||||||
|
ModelPrimitives& modelPrimitives = modelMesh.mPrimitives[primCount];
|
||||||
|
|
||||||
|
if (auto jIndices = jPrimitive->GetObjectItem("indices"))
|
||||||
|
{
|
||||||
|
auto& dataAccessor = dataAccessors[jIndices->mValueInt];
|
||||||
|
modelPrimitives.mIndices.ResizeRaw(dataAccessor.mCount);
|
||||||
|
for (int i = 0; i < dataAccessor.mCount; i++)
|
||||||
|
modelPrimitives.mIndices[i] = *(uint16*)(dataAccessor.mPtr + i * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto jIndices = jPrimitive->GetObjectItem("material"))
|
||||||
|
modelPrimitives.mMaterial = &mModelDef->mMaterials[jIndices->mValueInt];
|
||||||
|
|
||||||
|
if (auto jAttributes = jPrimitive->GetObjectItem("attributes"))
|
||||||
|
{
|
||||||
|
if (auto jPosition = jAttributes->GetObjectItem("POSITION"))
|
||||||
|
{
|
||||||
|
auto& dataAccessor = dataAccessors[jPosition->mValueInt];
|
||||||
|
modelPrimitives.mVertices.Resize(dataAccessor.mCount);
|
||||||
|
ReadBuffer<Vector3>(dataAccessor, &modelPrimitives.mVertices[0].mPosition, sizeof(ModelVertex));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto jNormal = jAttributes->GetObjectItem("NORMAL"))
|
||||||
|
ReadBuffer<Vector3>(dataAccessors[jNormal->mValueInt], &modelPrimitives.mVertices[0].mNormal, sizeof(ModelVertex));
|
||||||
|
if (auto jTangent = jAttributes->GetObjectItem("TANGENT"))
|
||||||
|
ReadBuffer<Vector3>(dataAccessors[jTangent->mValueInt], &modelPrimitives.mVertices[0].mTangent, sizeof(ModelVertex), sizeof(Vector4));
|
||||||
|
if (auto jColor = jAttributes->GetObjectItem("COLOR_0"))
|
||||||
|
ReadBuffer<uint32>(dataAccessors[jColor->mValueInt], &modelPrimitives.mVertices[0].mColor, sizeof(ModelVertex));
|
||||||
|
if (auto jTexCoords = jAttributes->GetObjectItem("TEXCOORD_0"))
|
||||||
|
{
|
||||||
|
ReadBuffer<TexCoords>(dataAccessors[jTexCoords->mValueInt], &modelPrimitives.mVertices[0].mTexCoords, sizeof(ModelVertex));
|
||||||
|
for (auto& vertex : modelPrimitives.mVertices)
|
||||||
|
{
|
||||||
|
vertex.mTexCoords.mV = 1.0f - vertex.mTexCoords.mV;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (auto jTexCoords = jAttributes->GetObjectItem("TEXCOORD_1"))
|
||||||
|
{
|
||||||
|
ReadBuffer<TexCoords>(dataAccessors[jTexCoords->mValueInt], &modelPrimitives.mVertices[0].mTexCoords, sizeof(ModelVertex));
|
||||||
|
for (auto& vertex : modelPrimitives.mVertices)
|
||||||
|
{
|
||||||
|
//vertex.mTexCoords.mU = 1.0f - vertex.mTexCoords.mU;
|
||||||
|
vertex.mTexCoords.mV = 1.0f - vertex.mTexCoords.mV;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (auto& vertex : modelPrimitives.mVertices)
|
||||||
|
vertex.mBumpTexCoords = vertex.mTexCoords;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
primCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mModelDef->mMeshes.Add(modelMesh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto jNodes = jRoot->GetObjectItem("nodes"))
|
||||||
|
{
|
||||||
|
mModelDef->mNodes.Reserve(jNodes->GetArraySize());
|
||||||
|
for (auto jNode = jNodes->mChild; jNode != NULL; jNode = jNode->mNext)
|
||||||
|
{
|
||||||
|
ModelNode modelNode;
|
||||||
|
if (auto jName = jNode->GetObjectItem("name"))
|
||||||
|
{
|
||||||
|
if (jName->mValueString != NULL)
|
||||||
|
modelNode.mName = jName->mValueString;
|
||||||
|
}
|
||||||
|
if (auto jChildren = jNode->GetObjectItem("children"))
|
||||||
|
{
|
||||||
|
for (auto jChild = jChildren->mChild; jChild != NULL; jChild = jChild->mNext)
|
||||||
|
{
|
||||||
|
int childIdx = jChild->mValueInt;
|
||||||
|
modelNode.mChildren.Add(mModelDef->mNodes.mVals + childIdx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto jTranslation = jNode->GetObjectItem("translation"))
|
||||||
|
_GetFloat3(jTranslation, modelNode.mTranslation);
|
||||||
|
if (auto jTranslation = jNode->GetObjectItem("rotation"))
|
||||||
|
_GetFloat4(jTranslation, modelNode.mRotation);
|
||||||
|
if (auto jMesh = jNode->GetObjectItem("mesh"))
|
||||||
|
modelNode.mMesh = mModelDef->mMeshes.mVals + jMesh->mValueInt;
|
||||||
|
|
||||||
|
mModelDef->mNodes.Add(modelNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
43
BeefySysLib/gfx/glTF.h
Normal file
43
BeefySysLib/gfx/glTF.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "util/Quaternion.h"
|
||||||
|
#include "util/Vector.h"
|
||||||
|
#include "util/Array.h"
|
||||||
|
#include "FileStream.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
NS_BF_BEGIN;
|
||||||
|
|
||||||
|
class ModelDef;
|
||||||
|
class ModelMaterialDef;
|
||||||
|
|
||||||
|
class GLTFReader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
class StaticMaterial
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ModelMaterialDef* mMaterialDef;
|
||||||
|
String mMaterialSlotName;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
String mBasePathName;
|
||||||
|
String mRootDir;
|
||||||
|
ModelDef* mModelDef;
|
||||||
|
Array<StaticMaterial> mStaticMaterials;
|
||||||
|
|
||||||
|
public:
|
||||||
|
GLTFReader(ModelDef* modelDef);
|
||||||
|
~GLTFReader();
|
||||||
|
|
||||||
|
bool ParseMaterialDef(ModelMaterialDef* materialDef, const StringImpl& matText);
|
||||||
|
ModelMaterialDef* LoadMaterial(const StringImpl& path);
|
||||||
|
bool LoadModelProps(const StringImpl& relPath);
|
||||||
|
bool ReadFile(const StringImpl& filePath, const StringImpl& rootDir);
|
||||||
|
};
|
||||||
|
|
||||||
|
NS_BF_END;
|
|
@ -49,7 +49,7 @@ bool TGAData::ReadData()
|
||||||
bool flipped = (hdr->mImageDescriptor & 0x20) != 0;
|
bool flipped = (hdr->mImageDescriptor & 0x20) != 0;
|
||||||
|
|
||||||
mWidth = hdr->mWidth;
|
mWidth = hdr->mWidth;
|
||||||
mHeight = hdr->mWidth;
|
mHeight = hdr->mHeight;
|
||||||
mBits = new uint32[mWidth * mHeight];
|
mBits = new uint32[mWidth * mHeight];
|
||||||
|
|
||||||
if (hdr->mDataTypeCode == 10) // RLE
|
if (hdr->mDataTypeCode == 10) // RLE
|
||||||
|
@ -148,6 +148,67 @@ readSpanHeader:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NOP;
|
||||||
|
}
|
||||||
|
else if (aMode == 3)
|
||||||
|
{
|
||||||
|
int y = 0;
|
||||||
|
int x = 0;
|
||||||
|
|
||||||
|
readSpanHeader3:
|
||||||
|
int spanLen = 0;
|
||||||
|
uint32 spanColor = 0;
|
||||||
|
|
||||||
|
uint8 spanHeader = *(srcPtr++);
|
||||||
|
spanLen = (spanHeader & 0x7F) + 1;
|
||||||
|
if ((spanHeader & 0x80) != 0)
|
||||||
|
{
|
||||||
|
// Repeat color
|
||||||
|
int b = *(srcPtr++);
|
||||||
|
int g = *(srcPtr++);
|
||||||
|
int r = *(srcPtr++);
|
||||||
|
int a = 255;
|
||||||
|
|
||||||
|
spanColor = (a << 24) | (b << 16) | (g << 8) | r;
|
||||||
|
|
||||||
|
for (; y < mHeight; y++)
|
||||||
|
{
|
||||||
|
for (; x < mWidth; x++)
|
||||||
|
{
|
||||||
|
if (spanLen == 0)
|
||||||
|
goto readSpanHeader3;
|
||||||
|
*(destPtr++) = spanColor;
|
||||||
|
spanLen--;
|
||||||
|
}
|
||||||
|
|
||||||
|
x = 0;
|
||||||
|
destPtr += destAdd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (; y < mHeight; y++)
|
||||||
|
{
|
||||||
|
for (; x < mWidth; x++)
|
||||||
|
{
|
||||||
|
if (spanLen == 0)
|
||||||
|
goto readSpanHeader3;
|
||||||
|
|
||||||
|
int b = *(srcPtr++);
|
||||||
|
int g = *(srcPtr++);
|
||||||
|
int r = *(srcPtr++);
|
||||||
|
int a = 255;
|
||||||
|
|
||||||
|
*(destPtr++) = (a << 24) | (b << 16) | (g << 8) | r;
|
||||||
|
|
||||||
|
spanLen--;
|
||||||
|
}
|
||||||
|
|
||||||
|
x = 0;
|
||||||
|
destPtr += destAdd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NOP;
|
NOP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -326,7 +326,8 @@ enum BfpSysDirectoryKind
|
||||||
BfpSysDirectoryKind_AppData_LocalLow,
|
BfpSysDirectoryKind_AppData_LocalLow,
|
||||||
BfpSysDirectoryKind_AppData_Roaming,
|
BfpSysDirectoryKind_AppData_Roaming,
|
||||||
BfpSysDirectoryKind_Programs,
|
BfpSysDirectoryKind_Programs,
|
||||||
BfpSysDirectoryKind_Programs_Common
|
BfpSysDirectoryKind_Programs_Common,
|
||||||
|
BfpSysDirectoryKind_Documents
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BfpFindFileData;
|
struct BfpFindFileData;
|
||||||
|
|
243
BeefySysLib/platform/win/DDS.h
Normal file
243
BeefySysLib/platform/win/DDS.h
Normal file
|
@ -0,0 +1,243 @@
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
// dds.h
|
||||||
|
//
|
||||||
|
// This header defines constants and structures that are useful when parsing
|
||||||
|
// DDS files. DDS files were originally designed to use several structures
|
||||||
|
// and constants that are native to DirectDraw and are defined in ddraw.h,
|
||||||
|
// such as DDSURFACEDESC2 and DDSCAPS2. This file defines similar
|
||||||
|
// (compatible) constants and structures so that one can use DDS files
|
||||||
|
// without needing to include ddraw.h.
|
||||||
|
//
|
||||||
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||||
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||||
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||||
|
// PARTICULAR PURPOSE.
|
||||||
|
//
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
//
|
||||||
|
// http://go.microsoft.com/fwlink/?LinkId=248926
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if defined(_XBOX_ONE) && defined(_TITLE)
|
||||||
|
#include <d3d11_x.h>
|
||||||
|
#else
|
||||||
|
#include <dxgiformat.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace DirectX
|
||||||
|
{
|
||||||
|
|
||||||
|
#pragma pack(push,1)
|
||||||
|
|
||||||
|
const uint32_t DDS_MAGIC = 0x20534444; // "DDS "
|
||||||
|
|
||||||
|
struct DDS_PIXELFORMAT
|
||||||
|
{
|
||||||
|
uint32_t dwSize;
|
||||||
|
uint32_t dwFlags;
|
||||||
|
uint32_t dwFourCC;
|
||||||
|
uint32_t dwRGBBitCount;
|
||||||
|
uint32_t dwRBitMask;
|
||||||
|
uint32_t dwGBitMask;
|
||||||
|
uint32_t dwBBitMask;
|
||||||
|
uint32_t dwABitMask;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DDS_FOURCC 0x00000004 // DDPF_FOURCC
|
||||||
|
#define DDS_RGB 0x00000040 // DDPF_RGB
|
||||||
|
#define DDS_RGBA 0x00000041 // DDPF_RGB | DDPF_ALPHAPIXELS
|
||||||
|
#define DDS_LUMINANCE 0x00020000 // DDPF_LUMINANCE
|
||||||
|
#define DDS_LUMINANCEA 0x00020001 // DDPF_LUMINANCE | DDPF_ALPHAPIXELS
|
||||||
|
#define DDS_ALPHA 0x00000002 // DDPF_ALPHA
|
||||||
|
#define DDS_PAL8 0x00000020 // DDPF_PALETTEINDEXED8
|
||||||
|
#define DDS_BUMPDUDV 0x00080000 // DDPF_BUMPDUDV
|
||||||
|
|
||||||
|
#ifndef MAKEFOURCC
|
||||||
|
#define MAKEFOURCC(ch0, ch1, ch2, ch3) \
|
||||||
|
((uint32_t)(uint8_t)(ch0) | ((uint32_t)(uint8_t)(ch1) << 8) | \
|
||||||
|
((uint32_t)(uint8_t)(ch2) << 16) | ((uint32_t)(uint8_t)(ch3) << 24 ))
|
||||||
|
#endif /* defined(MAKEFOURCC) */
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT1 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT2 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','2'), 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT3 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','3'), 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT4 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','4'), 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT5 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','5'), 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_BC4_UNORM =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B','C','4','U'), 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_BC4_SNORM =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B','C','4','S'), 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_BC5_UNORM =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B','C','5','U'), 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_BC5_SNORM =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B','C','5','S'), 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_R8G8_B8G8 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('R','G','B','G'), 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_G8R8_G8B8 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('G','R','G','B'), 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_YUY2 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('Y','U','Y','2'), 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A8R8G8B8 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_X8R8G8B8 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A8B8G8R8 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_X8B8G8R8 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_G16R16 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0x0000ffff, 0xffff0000, 0x00000000, 0x00000000 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_R5G6B5 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A1R5G5B5 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00008000 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A4R4G4B4 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00000f00, 0x000000f0, 0x0000000f, 0x0000f000 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_R8G8B8 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_L8 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_LUMINANCE, 0, 8, 0xff, 0x00, 0x00, 0x00 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_L16 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_LUMINANCE, 0, 16, 0xffff, 0x0000, 0x0000, 0x0000 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A8L8 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_LUMINANCEA, 0, 16, 0x00ff, 0x0000, 0x0000, 0xff00 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A8 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_ALPHA, 0, 8, 0x00, 0x00, 0x00, 0xff };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_V8U8 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_BUMPDUDV, 0, 16, 0x00ff, 0xff00, 0x0000, 0x0000 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_Q8W8V8U8 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_BUMPDUDV, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 };
|
||||||
|
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_V16U16 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_BUMPDUDV, 0, 32, 0x0000ffff, 0xffff0000, 0x00000000, 0x00000000 };
|
||||||
|
|
||||||
|
// D3DFMT_A2R10G10B10/D3DFMT_A2B10G10R10 should be written using DX10 extension to avoid D3DX 10:10:10:2 reversal issue
|
||||||
|
|
||||||
|
// This indicates the DDS_HEADER_DXT10 extension is present (the format is in dxgiFormat)
|
||||||
|
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DX10 =
|
||||||
|
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','1','0'), 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
#define DDS_HEADER_FLAGS_TEXTURE 0x00001007 // DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT
|
||||||
|
#define DDS_HEADER_FLAGS_MIPMAP 0x00020000 // DDSD_MIPMAPCOUNT
|
||||||
|
#define DDS_HEADER_FLAGS_VOLUME 0x00800000 // DDSD_DEPTH
|
||||||
|
#define DDS_HEADER_FLAGS_PITCH 0x00000008 // DDSD_PITCH
|
||||||
|
#define DDS_HEADER_FLAGS_LINEARSIZE 0x00080000 // DDSD_LINEARSIZE
|
||||||
|
|
||||||
|
#define DDS_HEIGHT 0x00000002 // DDSD_HEIGHT
|
||||||
|
#define DDS_WIDTH 0x00000004 // DDSD_WIDTH
|
||||||
|
|
||||||
|
#define DDS_SURFACE_FLAGS_TEXTURE 0x00001000 // DDSCAPS_TEXTURE
|
||||||
|
#define DDS_SURFACE_FLAGS_MIPMAP 0x00400008 // DDSCAPS_COMPLEX | DDSCAPS_MIPMAP
|
||||||
|
#define DDS_SURFACE_FLAGS_CUBEMAP 0x00000008 // DDSCAPS_COMPLEX
|
||||||
|
|
||||||
|
#define DDS_CUBEMAP_POSITIVEX 0x00000600 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX
|
||||||
|
#define DDS_CUBEMAP_NEGATIVEX 0x00000a00 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX
|
||||||
|
#define DDS_CUBEMAP_POSITIVEY 0x00001200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY
|
||||||
|
#define DDS_CUBEMAP_NEGATIVEY 0x00002200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY
|
||||||
|
#define DDS_CUBEMAP_POSITIVEZ 0x00004200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ
|
||||||
|
#define DDS_CUBEMAP_NEGATIVEZ 0x00008200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ
|
||||||
|
|
||||||
|
#define DDS_CUBEMAP_ALLFACES ( DDS_CUBEMAP_POSITIVEX | DDS_CUBEMAP_NEGATIVEX |\
|
||||||
|
DDS_CUBEMAP_POSITIVEY | DDS_CUBEMAP_NEGATIVEY |\
|
||||||
|
DDS_CUBEMAP_POSITIVEZ | DDS_CUBEMAP_NEGATIVEZ )
|
||||||
|
|
||||||
|
#define DDS_CUBEMAP 0x00000200 // DDSCAPS2_CUBEMAP
|
||||||
|
|
||||||
|
#define DDS_FLAGS_VOLUME 0x00200000 // DDSCAPS2_VOLUME
|
||||||
|
|
||||||
|
// Subset here matches D3D10_RESOURCE_DIMENSION and D3D11_RESOURCE_DIMENSION
|
||||||
|
enum DDS_RESOURCE_DIMENSION
|
||||||
|
{
|
||||||
|
DDS_DIMENSION_TEXTURE1D = 2,
|
||||||
|
DDS_DIMENSION_TEXTURE2D = 3,
|
||||||
|
DDS_DIMENSION_TEXTURE3D = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Subset here matches D3D10_RESOURCE_MISC_FLAG and D3D11_RESOURCE_MISC_FLAG
|
||||||
|
enum DDS_RESOURCE_MISC_FLAG
|
||||||
|
{
|
||||||
|
DDS_RESOURCE_MISC_TEXTURECUBE = 0x4L,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum DDS_MISC_FLAGS2
|
||||||
|
{
|
||||||
|
DDS_MISC_FLAGS2_ALPHA_MODE_MASK = 0x7L,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum DDS_ALPHA_MODE
|
||||||
|
{
|
||||||
|
DDS_ALPHA_MODE_UNKNOWN = 0,
|
||||||
|
DDS_ALPHA_MODE_STRAIGHT = 1,
|
||||||
|
DDS_ALPHA_MODE_PREMULTIPLIED = 2,
|
||||||
|
DDS_ALPHA_MODE_OPAQUE = 3,
|
||||||
|
DDS_ALPHA_MODE_CUSTOM = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DDS_HEADER
|
||||||
|
{
|
||||||
|
uint32_t dwSize;
|
||||||
|
uint32_t dwFlags;
|
||||||
|
uint32_t dwHeight;
|
||||||
|
uint32_t dwWidth;
|
||||||
|
uint32_t dwPitchOrLinearSize;
|
||||||
|
uint32_t dwDepth; // only if DDS_HEADER_FLAGS_VOLUME is set in dwFlags
|
||||||
|
uint32_t dwMipMapCount;
|
||||||
|
uint32_t dwReserved1[11];
|
||||||
|
DDS_PIXELFORMAT ddspf;
|
||||||
|
uint32_t dwCaps;
|
||||||
|
uint32_t dwCaps2;
|
||||||
|
uint32_t dwCaps3;
|
||||||
|
uint32_t dwCaps4;
|
||||||
|
uint32_t dwReserved2;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DDS_HEADER_DXT10
|
||||||
|
{
|
||||||
|
DXGI_FORMAT dxgiFormat;
|
||||||
|
uint32_t resourceDimension;
|
||||||
|
uint32_t miscFlag; // see DDS_RESOURCE_MISC_FLAG
|
||||||
|
uint32_t arraySize;
|
||||||
|
uint32_t miscFlags2; // see DDS_MISC_FLAGS2
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
static_assert( sizeof(DDS_HEADER) == 124, "DDS Header size mismatch" );
|
||||||
|
static_assert( sizeof(DDS_HEADER_DXT10) == 20, "DDS DX10 Extended Header size mismatch");
|
||||||
|
|
||||||
|
}; // namespace
|
|
@ -5,6 +5,10 @@
|
||||||
#include "img/ImageData.h"
|
#include "img/ImageData.h"
|
||||||
#include "util/PerfTimer.h"
|
#include "util/PerfTimer.h"
|
||||||
#include "util/BeefPerf.h"
|
#include "util/BeefPerf.h"
|
||||||
|
#include "FileStream.h"
|
||||||
|
#include "DDS.h"
|
||||||
|
|
||||||
|
using namespace DirectX;
|
||||||
|
|
||||||
#include <D3Dcompiler.h>
|
#include <D3Dcompiler.h>
|
||||||
|
|
||||||
|
@ -37,6 +41,131 @@ USING_NS_BF;
|
||||||
#define DXFAILED(check) ((hr = (check)) != 0)
|
#define DXFAILED(check) ((hr = (check)) != 0)
|
||||||
#define DXCHECK(check) if ((check) != 0) BF_FATAL(StrFormat("DirectX call failed with result 0x%X", check).c_str());
|
#define DXCHECK(check) if ((check) != 0) BF_FATAL(StrFormat("DirectX call failed with result 0x%X", check).c_str());
|
||||||
|
|
||||||
|
static int GetBytesPerPixel(DXGI_FORMAT fmt, int& blockSize)
|
||||||
|
{
|
||||||
|
blockSize = 1;
|
||||||
|
switch (fmt)
|
||||||
|
{
|
||||||
|
case DXGI_FORMAT_UNKNOWN: return 0;
|
||||||
|
case DXGI_FORMAT_R32G32B32A32_TYPELESS: return 4 + 4 + 4 + 4;
|
||||||
|
case DXGI_FORMAT_R32G32B32A32_FLOAT: return 4 + 4 + 4 + 4;
|
||||||
|
case DXGI_FORMAT_R32G32B32A32_UINT: return 4 + 4 + 4 + 4;
|
||||||
|
case DXGI_FORMAT_R32G32B32A32_SINT: return 4 + 4 + 4 + 4;
|
||||||
|
case DXGI_FORMAT_R32G32B32_TYPELESS: return 4 + 4 + 4;
|
||||||
|
case DXGI_FORMAT_R32G32B32_FLOAT: return 4 + 4 + 4;
|
||||||
|
case DXGI_FORMAT_R32G32B32_UINT: return 4 + 4 + 4;
|
||||||
|
case DXGI_FORMAT_R32G32B32_SINT: return 4 + 4 + 4;
|
||||||
|
case DXGI_FORMAT_R16G16B16A16_TYPELESS: return 2 + 2 + 2 + 2;
|
||||||
|
case DXGI_FORMAT_R16G16B16A16_FLOAT: return 2 + 2 + 2 + 2;
|
||||||
|
case DXGI_FORMAT_R16G16B16A16_UNORM: return 2 + 2 + 2 + 2;
|
||||||
|
case DXGI_FORMAT_R16G16B16A16_UINT: return 2 + 2 + 2 + 2;
|
||||||
|
case DXGI_FORMAT_R16G16B16A16_SNORM: return 2 + 2 + 2 + 2;
|
||||||
|
case DXGI_FORMAT_R16G16B16A16_SINT: return 2 + 2 + 2 + 2;
|
||||||
|
case DXGI_FORMAT_R32G32_TYPELESS: return 4 + 4;
|
||||||
|
case DXGI_FORMAT_R32G32_FLOAT: return 4 + 4;
|
||||||
|
case DXGI_FORMAT_R32G32_UINT: return 4 + 4;
|
||||||
|
case DXGI_FORMAT_R32G32_SINT: return 4 + 4;
|
||||||
|
case DXGI_FORMAT_R32G8X24_TYPELESS: return 4 + 3;
|
||||||
|
case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: return 4 + 1 + 3;
|
||||||
|
case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: return 4 + 1 + 3;
|
||||||
|
case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: return 4 + 1 + 1 + 3;
|
||||||
|
case DXGI_FORMAT_R10G10B10A2_TYPELESS: return 4;
|
||||||
|
case DXGI_FORMAT_R10G10B10A2_UNORM: return 4;
|
||||||
|
case DXGI_FORMAT_R10G10B10A2_UINT: return 4;
|
||||||
|
case DXGI_FORMAT_R11G11B10_FLOAT: return 4;
|
||||||
|
case DXGI_FORMAT_R8G8B8A8_TYPELESS: return 4;
|
||||||
|
case DXGI_FORMAT_R8G8B8A8_UNORM: return 4;
|
||||||
|
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: return 4;
|
||||||
|
case DXGI_FORMAT_R8G8B8A8_UINT: return 4;
|
||||||
|
case DXGI_FORMAT_R8G8B8A8_SNORM: return 4;
|
||||||
|
case DXGI_FORMAT_R8G8B8A8_SINT: return 4;
|
||||||
|
case DXGI_FORMAT_R16G16_TYPELESS: return 4;
|
||||||
|
case DXGI_FORMAT_R16G16_FLOAT: return 4;
|
||||||
|
case DXGI_FORMAT_R16G16_UNORM: return 4;
|
||||||
|
case DXGI_FORMAT_R16G16_UINT: return 4;
|
||||||
|
case DXGI_FORMAT_R16G16_SNORM: return 4;
|
||||||
|
case DXGI_FORMAT_R16G16_SINT: return 4;
|
||||||
|
case DXGI_FORMAT_R32_TYPELESS: return 4;
|
||||||
|
case DXGI_FORMAT_D32_FLOAT: return 4;
|
||||||
|
case DXGI_FORMAT_R32_FLOAT: return 4;
|
||||||
|
case DXGI_FORMAT_R32_UINT: return 4;
|
||||||
|
case DXGI_FORMAT_R32_SINT: return 4;
|
||||||
|
case DXGI_FORMAT_R24G8_TYPELESS: return 4;
|
||||||
|
case DXGI_FORMAT_D24_UNORM_S8_UINT: return 4;
|
||||||
|
case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: return 4;
|
||||||
|
case DXGI_FORMAT_X24_TYPELESS_G8_UINT: return 4;
|
||||||
|
case DXGI_FORMAT_R8G8_TYPELESS: return 2;
|
||||||
|
case DXGI_FORMAT_R8G8_UNORM: return 2;
|
||||||
|
case DXGI_FORMAT_R8G8_UINT: return 2;
|
||||||
|
case DXGI_FORMAT_R8G8_SNORM: return 2;
|
||||||
|
case DXGI_FORMAT_R8G8_SINT: return 2;
|
||||||
|
case DXGI_FORMAT_R16_TYPELESS: return 2;
|
||||||
|
case DXGI_FORMAT_R16_FLOAT: return 2;
|
||||||
|
case DXGI_FORMAT_D16_UNORM: return 2;
|
||||||
|
case DXGI_FORMAT_R16_UNORM: return 2;
|
||||||
|
case DXGI_FORMAT_R16_UINT: return 2;
|
||||||
|
case DXGI_FORMAT_R16_SNORM: return 2;
|
||||||
|
case DXGI_FORMAT_R16_SINT: return 2;
|
||||||
|
case DXGI_FORMAT_R8_TYPELESS: return 1;
|
||||||
|
case DXGI_FORMAT_R8_UNORM: return 1;
|
||||||
|
case DXGI_FORMAT_R8_UINT: return 1;
|
||||||
|
case DXGI_FORMAT_R8_SNORM: return 1;
|
||||||
|
case DXGI_FORMAT_R8_SINT: return 1;
|
||||||
|
case DXGI_FORMAT_A8_UNORM: return 1;
|
||||||
|
case DXGI_FORMAT_R1_UNORM: return 1;
|
||||||
|
case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: return 3;
|
||||||
|
case DXGI_FORMAT_R8G8_B8G8_UNORM: return 4;
|
||||||
|
case DXGI_FORMAT_G8R8_G8B8_UNORM: return 4;
|
||||||
|
case DXGI_FORMAT_BC1_TYPELESS: blockSize = 4; return 8;
|
||||||
|
case DXGI_FORMAT_BC1_UNORM: blockSize = 4; return 8;
|
||||||
|
case DXGI_FORMAT_BC1_UNORM_SRGB: blockSize = 4; return 8;
|
||||||
|
case DXGI_FORMAT_BC2_TYPELESS: blockSize = 4; return 16;
|
||||||
|
case DXGI_FORMAT_BC2_UNORM: blockSize = 4; return 16;
|
||||||
|
case DXGI_FORMAT_BC2_UNORM_SRGB: blockSize = 4; return 16;
|
||||||
|
case DXGI_FORMAT_BC3_TYPELESS: blockSize = 4; return 16;
|
||||||
|
case DXGI_FORMAT_BC3_UNORM: blockSize = 4; return 16;
|
||||||
|
case DXGI_FORMAT_BC3_UNORM_SRGB: blockSize = 4; return 16;
|
||||||
|
case DXGI_FORMAT_BC4_TYPELESS: blockSize = 4; return 8;
|
||||||
|
case DXGI_FORMAT_BC4_UNORM: blockSize = 4; return 8;
|
||||||
|
case DXGI_FORMAT_BC4_SNORM: blockSize = 4; return 8;
|
||||||
|
case DXGI_FORMAT_BC5_TYPELESS: blockSize = 4; return 16;
|
||||||
|
case DXGI_FORMAT_BC5_UNORM: blockSize = 4; return 16;
|
||||||
|
case DXGI_FORMAT_BC5_SNORM: blockSize = 4; return 16;
|
||||||
|
case DXGI_FORMAT_B5G6R5_UNORM: return 1;
|
||||||
|
case DXGI_FORMAT_B5G5R5A1_UNORM: return 2;
|
||||||
|
case DXGI_FORMAT_B8G8R8A8_UNORM: return 4;
|
||||||
|
case DXGI_FORMAT_B8G8R8X8_UNORM: return 4;
|
||||||
|
case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: return 4;
|
||||||
|
case DXGI_FORMAT_B8G8R8A8_TYPELESS: return 4;
|
||||||
|
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: return 4;
|
||||||
|
case DXGI_FORMAT_B8G8R8X8_TYPELESS: return 4;
|
||||||
|
case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: return 4;
|
||||||
|
case DXGI_FORMAT_BC6H_TYPELESS: return 1;
|
||||||
|
case DXGI_FORMAT_BC6H_UF16: return 1;
|
||||||
|
case DXGI_FORMAT_BC6H_SF16: return 1;
|
||||||
|
case DXGI_FORMAT_BC7_TYPELESS: return 1;
|
||||||
|
case DXGI_FORMAT_BC7_UNORM: return 1;
|
||||||
|
case DXGI_FORMAT_BC7_UNORM_SRGB: return 1;
|
||||||
|
case DXGI_FORMAT_AYUV: return 1;
|
||||||
|
case DXGI_FORMAT_Y410: return 1;
|
||||||
|
case DXGI_FORMAT_Y416: return 1;
|
||||||
|
case DXGI_FORMAT_NV12: return 1;
|
||||||
|
case DXGI_FORMAT_P010: return 1;
|
||||||
|
case DXGI_FORMAT_P016: return 1;
|
||||||
|
case DXGI_FORMAT_420_OPAQUE: return 1;
|
||||||
|
case DXGI_FORMAT_YUY2: return 1;
|
||||||
|
case DXGI_FORMAT_Y210: return 1;
|
||||||
|
case DXGI_FORMAT_Y216: return 1;
|
||||||
|
case DXGI_FORMAT_NV11: return 1;
|
||||||
|
case DXGI_FORMAT_AI44: return 1;
|
||||||
|
case DXGI_FORMAT_IA44: return 1;
|
||||||
|
case DXGI_FORMAT_P8: return 1;
|
||||||
|
case DXGI_FORMAT_A8P8: return 1;
|
||||||
|
case DXGI_FORMAT_B4G4R4A4_UNORM: return 1;
|
||||||
|
default: return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DXShaderParam::DXShaderParam()
|
DXShaderParam::DXShaderParam()
|
||||||
{
|
{
|
||||||
mD3DVariable = NULL;
|
mD3DVariable = NULL;
|
||||||
|
@ -383,7 +512,7 @@ void DXRenderDevice::PhysSetRenderState(RenderState* renderState)
|
||||||
|
|
||||||
if ((renderState->mShader != mPhysRenderState->mShader) && (renderState->mShader != NULL))
|
if ((renderState->mShader != mPhysRenderState->mShader) && (renderState->mShader != NULL))
|
||||||
{
|
{
|
||||||
mD3DDeviceContext->PSSetSamplers(0, 1, &mD3DDefaultSamplerState);
|
mD3DDeviceContext->PSSetSamplers(0, 1, mPhysRenderState->mTexWrap ? &mD3DWrapSamplerState : &mD3DDefaultSamplerState);
|
||||||
mD3DDeviceContext->IASetInputLayout(dxShader->mD3DLayout);
|
mD3DDeviceContext->IASetInputLayout(dxShader->mD3DLayout);
|
||||||
mD3DDeviceContext->VSSetShader(dxShader->mD3DVertexShader, NULL, 0);
|
mD3DDeviceContext->VSSetShader(dxShader->mD3DVertexShader, NULL, 0);
|
||||||
mD3DDeviceContext->PSSetShader(dxShader->mD3DPixelShader, NULL, 0);
|
mD3DDeviceContext->PSSetShader(dxShader->mD3DPixelShader, NULL, 0);
|
||||||
|
@ -595,6 +724,7 @@ ModelInstance* DXRenderDevice::CreateModelInstance(ModelDef* modelDef)
|
||||||
|
|
||||||
//renderState->mCullMode = CullMode_Front;
|
//renderState->mCullMode = CullMode_Front;
|
||||||
|
|
||||||
|
renderState->mTexWrap = true;
|
||||||
renderState->mDepthFunc = DepthFunc_LessEqual;
|
renderState->mDepthFunc = DepthFunc_LessEqual;
|
||||||
renderState->mWriteDepthBuffer = true;
|
renderState->mWriteDepthBuffer = true;
|
||||||
|
|
||||||
|
@ -603,90 +733,134 @@ ModelInstance* DXRenderDevice::CreateModelInstance(ModelDef* modelDef)
|
||||||
////
|
////
|
||||||
|
|
||||||
dxModelInstance->mD3DRenderDevice = this;
|
dxModelInstance->mD3DRenderDevice = this;
|
||||||
|
dxModelInstance->mDXModelMeshs.Resize(modelDef->mMeshes.size());
|
||||||
dxModelInstance->mDXModelMeshs.resize(modelDef->mMeshes.size());
|
int dxMeshIdx = 0;
|
||||||
|
|
||||||
for (int meshIdx = 0; meshIdx < (int)modelDef->mMeshes.size(); meshIdx++)
|
for (int meshIdx = 0; meshIdx < (int)modelDef->mMeshes.size(); meshIdx++)
|
||||||
{
|
{
|
||||||
ModelMesh* mesh = &modelDef->mMeshes[meshIdx];
|
ModelMesh* mesh = &modelDef->mMeshes[meshIdx];
|
||||||
|
DXModelMesh* dxMesh = &dxModelInstance->mDXModelMeshs[dxMeshIdx];
|
||||||
|
|
||||||
DXModelMesh* dxMesh = &dxModelInstance->mDXModelMeshs[meshIdx];
|
dxMesh->mPrimitives.Resize(mesh->mPrimitives.size());
|
||||||
|
|
||||||
String texPath = mesh->mTexFileName;
|
for (int primitivesIdx = 0 ; primitivesIdx < (int)mesh->mPrimitives.size(); primitivesIdx++)
|
||||||
if ((int)texPath.IndexOf(':') == -1)
|
|
||||||
texPath = modelDef->mLoadDir + "Textures/" + texPath;
|
|
||||||
//texPath = gBFApp->mInstallDir + L"models/Textures/" + texPath;
|
|
||||||
|
|
||||||
dxMesh->mTexture = (DXTexture*)((RenderDevice*)this)->LoadTexture(texPath, TextureFlag_NoPremult);
|
|
||||||
|
|
||||||
dxMesh->mNumIndices = (int)mesh->mIndices.size();
|
|
||||||
dxMesh->mNumVertices = (int)mesh->mVertices.size();
|
|
||||||
|
|
||||||
D3D11_BUFFER_DESC bd;
|
|
||||||
bd.Usage = D3D11_USAGE_DYNAMIC;
|
|
||||||
bd.ByteWidth = (int)mesh->mIndices.size() * sizeof(uint16);
|
|
||||||
bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
|
||||||
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
|
||||||
bd.MiscFlags = 0;
|
|
||||||
bd.StructureByteStride = 0;
|
|
||||||
|
|
||||||
mD3DDevice->CreateBuffer(&bd, NULL, &dxMesh->mD3DIndexBuffer);
|
|
||||||
|
|
||||||
D3D11_MAPPED_SUBRESOURCE mappedSubResource;
|
|
||||||
|
|
||||||
DXCHECK(mD3DDeviceContext->Map(dxMesh->mD3DIndexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedSubResource));
|
|
||||||
uint16* dxIdxData = (uint16*)mappedSubResource.pData;
|
|
||||||
for (int idxIdx = 0; idxIdx < dxMesh->mNumIndices; idxIdx++)
|
|
||||||
dxIdxData[idxIdx] = (uint16)mesh->mIndices[idxIdx];
|
|
||||||
mD3DDeviceContext->Unmap(dxMesh->mD3DIndexBuffer, 0);
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
bd.Usage = D3D11_USAGE_DYNAMIC;
|
|
||||||
bd.ByteWidth = (int)mesh->mVertices.size() * sizeof(DXModelVertex);
|
|
||||||
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
|
||||||
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
|
||||||
bd.MiscFlags = 0;
|
|
||||||
bd.StructureByteStride = 0;
|
|
||||||
|
|
||||||
mD3DDevice->CreateBuffer(&bd, NULL, &dxMesh->mD3DVertexBuffer);
|
|
||||||
|
|
||||||
/*DXCHECK(mD3DDeviceContext->Map(dxMesh->mD3DVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedSubResource));
|
|
||||||
DXModelVertex* dxVtxData = (DXModelVertex*)mappedSubResource.pData;
|
|
||||||
for (int vtxIdx = 0; vtxIdx < (int)mesh->mVertexData.size(); vtxIdx++)
|
|
||||||
{
|
{
|
||||||
VertexData* srcVtxData = &mesh->mVertexData[vtxIdx];
|
auto primitives = &mesh->mPrimitives[primitivesIdx];
|
||||||
DXModelVertex* destVtx = dxVtxData + vtxIdx;
|
auto dxPrimitives = &dxMesh->mPrimitives[primitivesIdx];
|
||||||
|
|
||||||
destVtx->mPosition = srcVtxData->mCoords;
|
// String texPath = mesh->mTexFileName;
|
||||||
destVtx->mTexCoords = srcVtxData->mTexCoords[0];
|
// if (!texPath.IsEmpty())
|
||||||
destVtx->mTexCoords.mV = 1.0f - destVtx->mTexCoords.mV;
|
// {
|
||||||
destVtx->mBumpTexCoords = srcVtxData->mTexCoords[0];
|
// if ((int)texPath.IndexOf(':') == -1)
|
||||||
destVtx->mColor = 0xFFFFFFFF;
|
// texPath = modelDef->mLoadDir + "Textures/" + texPath;
|
||||||
destVtx->mTangent = srcVtxData->mTangent;
|
// //texPath = gBFApp->mInstallDir + L"models/Textures/" + texPath;
|
||||||
|
//
|
||||||
|
// dxPrimitives->mTexture = (DXTexture*)((RenderDevice*)this)->LoadTexture(texPath, TextureFlag_NoPremult);
|
||||||
|
// }
|
||||||
|
|
||||||
|
Array<String> texPaths = primitives->mTexPaths;
|
||||||
|
|
||||||
|
|
||||||
|
if (primitives->mMaterial != NULL)
|
||||||
|
{
|
||||||
|
dxPrimitives->mMaterialName = primitives->mMaterial->mName;
|
||||||
|
if (primitives->mMaterial->mDef != NULL)
|
||||||
|
{
|
||||||
|
for (auto& texParamVal : primitives->mMaterial->mDef->mTextureParameterValues)
|
||||||
|
{
|
||||||
|
if (texPaths.IsEmpty())
|
||||||
|
texPaths.Add(texParamVal->mTexturePath);
|
||||||
|
|
||||||
|
// if (texPath.IsEmpty())
|
||||||
|
// texPath = texParamVal->mTexturePath;
|
||||||
|
// if ((texParamVal->mName == "Albedo_texture") || (texParamVal->mName.EndsWith("_Color")))
|
||||||
|
// texPath = texParamVal->mTexturePath;
|
||||||
|
// else if ((texParamVal->mName == "NM_texture") || (texParamVal->mName.EndsWith("_NM")))
|
||||||
|
// bumpTexPath = texParamVal->mTexturePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& texPath : texPaths)
|
||||||
|
{
|
||||||
|
if (!modelDef->mLoadDir.IsEmpty())
|
||||||
|
texPath = GetAbsPath(texPath, modelDef->mLoadDir);
|
||||||
|
dxPrimitives->mTextures.Add((DXTexture*)((RenderDevice*)this)->LoadTexture(texPath, TextureFlag_NoPremult));
|
||||||
|
}
|
||||||
|
|
||||||
|
dxPrimitives->mNumIndices = (int)primitives->mIndices.size();
|
||||||
|
dxPrimitives->mNumVertices = (int)primitives->mVertices.size();
|
||||||
|
|
||||||
|
D3D11_BUFFER_DESC bd;
|
||||||
|
bd.Usage = D3D11_USAGE_DYNAMIC;
|
||||||
|
bd.ByteWidth = (int)primitives->mIndices.size() * sizeof(uint16);
|
||||||
|
bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
||||||
|
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||||
|
bd.MiscFlags = 0;
|
||||||
|
bd.StructureByteStride = 0;
|
||||||
|
|
||||||
|
mD3DDevice->CreateBuffer(&bd, NULL, &dxPrimitives->mD3DIndexBuffer);
|
||||||
|
|
||||||
|
D3D11_MAPPED_SUBRESOURCE mappedSubResource;
|
||||||
|
|
||||||
|
DXCHECK(mD3DDeviceContext->Map(dxPrimitives->mD3DIndexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedSubResource));
|
||||||
|
uint16* dxIdxData = (uint16*)mappedSubResource.pData;
|
||||||
|
for (int idxIdx = 0; idxIdx < dxPrimitives->mNumIndices; idxIdx++)
|
||||||
|
dxIdxData[idxIdx] = (uint16)primitives->mIndices[idxIdx];
|
||||||
|
mD3DDeviceContext->Unmap(dxPrimitives->mD3DIndexBuffer, 0);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
bd.Usage = D3D11_USAGE_DYNAMIC;
|
||||||
|
bd.ByteWidth = (int)primitives->mVertices.size() * sizeof(DXModelVertex);
|
||||||
|
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||||
|
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||||
|
bd.MiscFlags = 0;
|
||||||
|
bd.StructureByteStride = 0;
|
||||||
|
|
||||||
|
mD3DDevice->CreateBuffer(&bd, NULL, &dxPrimitives->mD3DVertexBuffer);
|
||||||
|
|
||||||
|
DXCHECK(mD3DDeviceContext->Map(dxPrimitives->mD3DVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedSubResource));
|
||||||
|
DXModelVertex* dxVtxData = (DXModelVertex*)mappedSubResource.pData;
|
||||||
|
for (int vtxIdx = 0; vtxIdx < (int)primitives->mVertices.size(); vtxIdx++)
|
||||||
|
{
|
||||||
|
ModelVertex* srcVtxData = &primitives->mVertices[vtxIdx];
|
||||||
|
DXModelVertex* destVtx = dxVtxData + vtxIdx;
|
||||||
|
|
||||||
|
destVtx->mPosition = srcVtxData->mPosition;
|
||||||
|
destVtx->mTexCoords = srcVtxData->mTexCoords;
|
||||||
|
//destVtx->mTexCoords.mV = 1.0f - destVtx->mTexCoords.mV;
|
||||||
|
destVtx->mTexCoords.mV = destVtx->mTexCoords.mV;
|
||||||
|
destVtx->mBumpTexCoords = srcVtxData->mBumpTexCoords;
|
||||||
|
destVtx->mColor = srcVtxData->mColor;
|
||||||
|
destVtx->mTangent = srcVtxData->mTangent;
|
||||||
|
}
|
||||||
|
|
||||||
|
mD3DDeviceContext->Unmap(dxPrimitives->mD3DVertexBuffer, 0);
|
||||||
|
|
||||||
|
dxMeshIdx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
mD3DDeviceContext->Unmap(dxMesh->mD3DVertexBuffer, 0);*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return dxModelInstance;
|
return dxModelInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DXDrawLayer::SetShaderConstantData(int slotIdx, void* constData, int size)
|
void DXDrawLayer::SetShaderConstantData(int usageIdx, int slotIdx, void* constData, int size)
|
||||||
{
|
{
|
||||||
DXSetConstantData* dxSetConstantData = AllocRenderCmd<DXSetConstantData>(size);
|
DXSetConstantData* dxSetConstantData = AllocRenderCmd<DXSetConstantData>(size);
|
||||||
dxSetConstantData->mRenderState = mRenderDevice->mCurRenderState;
|
dxSetConstantData->mRenderState = mRenderDevice->mCurRenderState;
|
||||||
|
dxSetConstantData->mUsageIdx = usageIdx;
|
||||||
dxSetConstantData->mSlotIdx = slotIdx;
|
dxSetConstantData->mSlotIdx = slotIdx;
|
||||||
dxSetConstantData->mSize = size;
|
dxSetConstantData->mSize = size;
|
||||||
|
|
||||||
if (size == 64) // Transpose for shader
|
// if (size == 64) // Transpose for shader
|
||||||
*((Matrix4*)dxSetConstantData->mData) = Matrix4::Transpose(*((Matrix4*)constData));
|
// *((Matrix4*)dxSetConstantData->mData) = Matrix4::Transpose(*((Matrix4*)constData));
|
||||||
else
|
// else
|
||||||
memcpy(dxSetConstantData->mData, constData, size);
|
memcpy(dxSetConstantData->mData, constData, size);
|
||||||
QueueRenderCmd(dxSetConstantData);
|
QueueRenderCmd(dxSetConstantData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DXDrawLayer::SetShaderConstantDataTyped(int slotIdx, void* constData, int size, int* typeData, int typeCount)
|
void DXDrawLayer::SetShaderConstantDataTyped(int usageIdx, int slotIdx, void* constData, int size, int* typeData, int typeCount)
|
||||||
{
|
{
|
||||||
for (int usageIdx = 0; usageIdx < 2; usageIdx++)
|
for (int usageIdx = 0; usageIdx < 2; usageIdx++)
|
||||||
{
|
{
|
||||||
|
@ -770,18 +944,20 @@ void DXDrawLayer::SetShaderConstantDataTyped(int slotIdx, void* constData, int s
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
DXModelMesh::DXModelMesh()
|
DXModelPrimitives::DXModelPrimitives()
|
||||||
{
|
{
|
||||||
mD3DIndexBuffer = NULL;
|
mD3DIndexBuffer = NULL;
|
||||||
mD3DVertexBuffer = NULL;
|
mD3DVertexBuffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
DXModelMesh::~DXModelMesh()
|
DXModelPrimitives::~DXModelPrimitives()
|
||||||
{
|
{
|
||||||
if (mD3DIndexBuffer != NULL)
|
if (mD3DIndexBuffer != NULL)
|
||||||
mD3DIndexBuffer->Release();
|
mD3DIndexBuffer->Release();
|
||||||
if (mD3DVertexBuffer != NULL)
|
if (mD3DVertexBuffer != NULL)
|
||||||
mD3DVertexBuffer->Release();
|
mD3DVertexBuffer->Release();
|
||||||
|
for (auto tex : mTextures)
|
||||||
|
tex->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -839,6 +1015,12 @@ void DXRenderState::SetClipped(bool clipped)
|
||||||
InvalidateRasterizerState();
|
InvalidateRasterizerState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DXRenderState::SetTexWrap(bool wrap)
|
||||||
|
{
|
||||||
|
mTexWrap = wrap;
|
||||||
|
InvalidateRasterizerState();
|
||||||
|
}
|
||||||
|
|
||||||
void DXRenderState::SetClipRect(const Rect& rect)
|
void DXRenderState::SetClipRect(const Rect& rect)
|
||||||
{
|
{
|
||||||
BF_ASSERT((rect.mWidth >= 0) && (rect.mHeight >= 0));
|
BF_ASSERT((rect.mWidth >= 0) && (rect.mHeight >= 0));
|
||||||
|
@ -879,14 +1061,44 @@ void DXModelInstance::Render(RenderDevice* renderDevice, RenderWindow* renderWin
|
||||||
|
|
||||||
DXModelMesh* dxMesh = &mDXModelMeshs[meshIdx];
|
DXModelMesh* dxMesh = &mDXModelMeshs[meshIdx];
|
||||||
|
|
||||||
mD3DRenderDevice->mD3DDeviceContext->PSSetShaderResources(0, 1, &dxMesh->mTexture->mD3DResourceView);
|
for (auto primIdx = 0; primIdx < (int)dxMesh->mPrimitives.size(); primIdx++)
|
||||||
|
{
|
||||||
|
auto dxPrimitives = &dxMesh->mPrimitives[primIdx];
|
||||||
|
|
||||||
// Set vertex buffer
|
if (dxPrimitives->mNumIndices == 11904)
|
||||||
UINT stride = sizeof(DXModelVertex);
|
{
|
||||||
UINT offset = 0;
|
NOP;
|
||||||
mD3DRenderDevice->mD3DDeviceContext->IASetVertexBuffers(0, 1, &dxMesh->mD3DVertexBuffer, &stride, &offset);
|
}
|
||||||
mD3DRenderDevice->mD3DDeviceContext->IASetIndexBuffer(dxMesh->mD3DIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
|
|
||||||
mD3DRenderDevice->mD3DDeviceContext->DrawIndexed(dxMesh->mNumIndices, 0, 0);
|
//TODO:
|
||||||
|
if (dxPrimitives->mNumIndices == 48384)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (::GetAsyncKeyState('1'))
|
||||||
|
{
|
||||||
|
if (dxPrimitives->mNumIndices != 9417)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (::GetAsyncKeyState('2'))
|
||||||
|
{
|
||||||
|
if (dxPrimitives->mNumIndices != 3684)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (dxPrimitives->mTextures.IsEmpty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (int i = 0; i < (int)dxPrimitives->mTextures.mSize; i++)
|
||||||
|
mD3DRenderDevice->mD3DDeviceContext->PSSetShaderResources(i, 1, &dxPrimitives->mTextures[i]->mD3DResourceView);
|
||||||
|
|
||||||
|
// Set vertex buffer
|
||||||
|
UINT stride = sizeof(DXModelVertex);
|
||||||
|
UINT offset = 0;
|
||||||
|
mD3DRenderDevice->mD3DDeviceContext->IASetVertexBuffers(0, 1, &dxPrimitives->mD3DVertexBuffer, &stride, &offset);
|
||||||
|
mD3DRenderDevice->mD3DDeviceContext->IASetIndexBuffer(dxPrimitives->mD3DIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
|
||||||
|
mD3DRenderDevice->mD3DDeviceContext->DrawIndexed(dxPrimitives->mNumIndices, 0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -992,46 +1204,59 @@ void DXSetTextureCmd::Render(RenderDevice* renderDevice, RenderWindow* renderWin
|
||||||
|
|
||||||
void DXSetConstantData::Render(RenderDevice* renderDevice, RenderWindow* renderWindow)
|
void DXSetConstantData::Render(RenderDevice* renderDevice, RenderWindow* renderWindow)
|
||||||
{
|
{
|
||||||
SetRenderState();
|
//SetRenderState();
|
||||||
|
|
||||||
DXShader* dxShader = (DXShader*)renderDevice->mCurRenderState->mShader;
|
DXShader* dxShader = (DXShader*)renderDevice->mCurRenderState->mShader;
|
||||||
DXRenderDevice* dxRenderDevice = (DXRenderDevice*)renderDevice;
|
DXRenderDevice* dxRenderDevice = (DXRenderDevice*)renderDevice;
|
||||||
|
|
||||||
HRESULT result = 0;
|
HRESULT result = 0;
|
||||||
|
|
||||||
int numBlocks = (mSize + 16 - 1) / 16;
|
int bufferSize = BF_ALIGN(mSize, 16);
|
||||||
int mtxBufferNum = mSlotIdx * 32 + (numBlocks - 1) * 2 + mUsageIdx;
|
|
||||||
static ID3D11Buffer* matrixBuffers[32 * 32 * 2] = {NULL};
|
|
||||||
|
|
||||||
if (matrixBuffers[mtxBufferNum] == NULL)
|
int id = (mSlotIdx << 24) | (bufferSize << 1) | (mUsageIdx);
|
||||||
|
ID3D11Buffer* buffer = NULL;
|
||||||
|
ID3D11Buffer** bufferPtr = NULL;
|
||||||
|
if (dxRenderDevice->mBufferMap.TryAdd(id, NULL, &bufferPtr))
|
||||||
{
|
{
|
||||||
D3D11_BUFFER_DESC matrixBufferDesc;
|
D3D11_BUFFER_DESC matrixBufferDesc;
|
||||||
matrixBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
|
matrixBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
|
||||||
matrixBufferDesc.ByteWidth = sizeof(float[4]) * numBlocks;
|
matrixBufferDesc.ByteWidth = bufferSize;
|
||||||
matrixBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
matrixBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||||
matrixBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
matrixBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||||
matrixBufferDesc.MiscFlags = 0;
|
matrixBufferDesc.MiscFlags = 0;
|
||||||
matrixBufferDesc.StructureByteStride = 0;
|
matrixBufferDesc.StructureByteStride = 0;
|
||||||
|
|
||||||
result = dxRenderDevice->mD3DDevice->CreateBuffer(&matrixBufferDesc, NULL, &matrixBuffers[mtxBufferNum]);
|
result = dxRenderDevice->mD3DDevice->CreateBuffer(&matrixBufferDesc, NULL, &buffer);
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
//OutputDebugStrF("Created Buffer %d %p\n", bufferSize, buffer);
|
||||||
|
|
||||||
|
*bufferPtr = buffer;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
buffer = *bufferPtr;
|
||||||
|
|
||||||
D3D11_MAPPED_SUBRESOURCE mappedResource;
|
D3D11_MAPPED_SUBRESOURCE mappedResource;
|
||||||
result = dxRenderDevice->mD3DDeviceContext->Map(matrixBuffers[mtxBufferNum], 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
|
result = dxRenderDevice->mD3DDeviceContext->Map(buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float* dataPtr = (float*) mappedResource.pData;
|
float* dataPtr = (float*)mappedResource.pData;
|
||||||
memset(dataPtr, 0, numBlocks * 16);
|
memset(dataPtr, 0, bufferSize);
|
||||||
memcpy(mappedResource.pData, mData, mSize);
|
memcpy(mappedResource.pData, mData, mSize);
|
||||||
|
|
||||||
dxRenderDevice->mD3DDeviceContext->Unmap(matrixBuffers[mtxBufferNum], 0);
|
dxRenderDevice->mD3DDeviceContext->Unmap(buffer, 0);
|
||||||
if (mUsageIdx == 0)
|
if (mUsageIdx == 0)
|
||||||
dxRenderDevice->mD3DDeviceContext->VSSetConstantBuffers(mSlotIdx, 1, &matrixBuffers[mtxBufferNum]);
|
{
|
||||||
|
//OutputDebugStrF("VSSetConstantBuffers %d %p\n", mSlotIdx, buffer);
|
||||||
|
dxRenderDevice->mD3DDeviceContext->VSSetConstantBuffers(mSlotIdx, 1, &buffer);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
dxRenderDevice->mD3DDeviceContext->PSSetConstantBuffers(mSlotIdx, 1, &matrixBuffers[mtxBufferNum]);
|
{
|
||||||
|
//OutputDebugStrF("PSSetConstantBuffers %d %p\n", mSlotIdx, buffer);
|
||||||
|
dxRenderDevice->mD3DDeviceContext->PSSetConstantBuffers(mSlotIdx, 1, &buffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -1291,7 +1516,8 @@ bool DXRenderDevice::Init(BFApp* app)
|
||||||
|
|
||||||
D3D_FEATURE_LEVEL d3dFeatureLevel = (D3D_FEATURE_LEVEL)0;
|
D3D_FEATURE_LEVEL d3dFeatureLevel = (D3D_FEATURE_LEVEL)0;
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
//flags = D3D11_CREATE_DEVICE_DEBUG;
|
//TODO:
|
||||||
|
flags = D3D11_CREATE_DEVICE_DEBUG;
|
||||||
DXCHECK(D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, featureLevelArr, 6, D3D11_SDK_VERSION, &mD3DDevice, &d3dFeatureLevel, &mD3DDeviceContext));
|
DXCHECK(D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, featureLevelArr, 6, D3D11_SDK_VERSION, &mD3DDevice, &d3dFeatureLevel, &mD3DDeviceContext));
|
||||||
OutputDebugStrF("D3D Feature Level: %X\n", d3dFeatureLevel);
|
OutputDebugStrF("D3D Feature Level: %X\n", d3dFeatureLevel);
|
||||||
|
|
||||||
|
@ -1364,9 +1590,18 @@ bool DXRenderDevice::Init(BFApp* app)
|
||||||
sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
|
sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
|
||||||
sampDesc.MinLOD = 0;
|
sampDesc.MinLOD = 0;
|
||||||
sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
|
sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
|
||||||
|
|
||||||
DXCHECK(mD3DDevice->CreateSamplerState(&sampDesc, &mD3DDefaultSamplerState));
|
DXCHECK(mD3DDevice->CreateSamplerState(&sampDesc, &mD3DDefaultSamplerState));
|
||||||
|
|
||||||
|
ZeroMemory(&sampDesc, sizeof(sampDesc));
|
||||||
|
sampDesc.Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
|
||||||
|
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||||
|
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||||
|
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||||
|
sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
|
||||||
|
sampDesc.MinLOD = 0;
|
||||||
|
sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
|
||||||
|
DXCHECK(mD3DDevice->CreateSamplerState(&sampDesc, &mD3DWrapSamplerState));
|
||||||
|
|
||||||
D3D11_BUFFER_DESC bd;
|
D3D11_BUFFER_DESC bd;
|
||||||
bd.Usage = D3D11_USAGE_DYNAMIC;
|
bd.Usage = D3D11_USAGE_DYNAMIC;
|
||||||
bd.ByteWidth = DX_VTXBUFFER_SIZE;
|
bd.ByteWidth = DX_VTXBUFFER_SIZE;
|
||||||
|
@ -1402,6 +1637,8 @@ void DXRenderDevice::ReleaseNative()
|
||||||
mD3DNormalBlendState = NULL;
|
mD3DNormalBlendState = NULL;
|
||||||
mD3DDefaultSamplerState->Release();
|
mD3DDefaultSamplerState->Release();
|
||||||
mD3DDefaultSamplerState = NULL;
|
mD3DDefaultSamplerState = NULL;
|
||||||
|
mD3DWrapSamplerState->Release();
|
||||||
|
mD3DWrapSamplerState = NULL;
|
||||||
mD3DDeviceContext->Release();
|
mD3DDeviceContext->Release();
|
||||||
mD3DDeviceContext = NULL;
|
mD3DDeviceContext = NULL;
|
||||||
mD3DDevice->Release();
|
mD3DDevice->Release();
|
||||||
|
@ -1468,6 +1705,178 @@ void DXRenderDevice::FrameEnd()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Texture* DXRenderDevice::LoadTexture(const StringImpl& fileName, int flags)
|
||||||
|
{
|
||||||
|
if (fileName.StartsWith("!backbuffer:"))
|
||||||
|
{
|
||||||
|
int colon = (int)fileName.IndexOf(':');
|
||||||
|
String addrStr = fileName.Substring(colon + 1);
|
||||||
|
void* addr = (void*)(intptr)strtoll(addrStr.c_str(), NULL, 16);
|
||||||
|
BFWindow* window = (BFWindow*)addr;
|
||||||
|
DXRenderWindow* renderWindow = (DXRenderWindow*)window->mRenderWindow;
|
||||||
|
|
||||||
|
DXTexture* aTexture = NULL;
|
||||||
|
aTexture->mD3DRenderTargetView = renderWindow->mD3DRenderTargetView;
|
||||||
|
aTexture->mD3DTexture = renderWindow->mD3DBackBuffer;
|
||||||
|
|
||||||
|
aTexture->mD3DRenderTargetView->AddRef();
|
||||||
|
aTexture->mD3DTexture->AddRef();
|
||||||
|
aTexture->AddRef();
|
||||||
|
return aTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
DXTexture* aTexture = NULL;
|
||||||
|
if (mTextureMap.TryGetValue(fileName, &aTexture))
|
||||||
|
{
|
||||||
|
aTexture->AddRef();
|
||||||
|
return aTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dotPos = (int)fileName.LastIndexOf('.');
|
||||||
|
String ext;
|
||||||
|
if (dotPos != -1)
|
||||||
|
ext = fileName.Substring(dotPos);
|
||||||
|
|
||||||
|
if (ext.Equals(".dds", StringImpl::CompareKind_OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
FileStream fs;
|
||||||
|
if (!fs.Open(fileName, "rb"))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
int header = fs.ReadInt32();
|
||||||
|
if (header != 0x20534444)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
auto hdr = fs.ReadT<DDS_HEADER>();
|
||||||
|
|
||||||
|
DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
|
||||||
|
if (hdr.ddspf.dwFlags == DDS_RGBA)
|
||||||
|
{
|
||||||
|
if (hdr.ddspf.dwRGBBitCount == 32)
|
||||||
|
{
|
||||||
|
if (hdr.ddspf.dwRBitMask == 0xff)
|
||||||
|
format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
else if (hdr.ddspf.dwRBitMask = 0xff0000)
|
||||||
|
format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||||
|
else if (hdr.ddspf.dwRBitMask == 0xffff)
|
||||||
|
format = DXGI_FORMAT_R16G16_UNORM;
|
||||||
|
else if (hdr.ddspf.dwRBitMask == 0x3ff)
|
||||||
|
format = DXGI_FORMAT_R10G10B10A2_UNORM;
|
||||||
|
}
|
||||||
|
else if (hdr.ddspf.dwRGBBitCount == 16)
|
||||||
|
{
|
||||||
|
if (hdr.ddspf.dwRBitMask == 0x7c00)
|
||||||
|
format = DXGI_FORMAT_B5G5R5A1_UNORM;
|
||||||
|
else if (hdr.ddspf.dwRBitMask == 0xf800)
|
||||||
|
format = DXGI_FORMAT_B5G6R5_UNORM;
|
||||||
|
}
|
||||||
|
else if (hdr.ddspf.dwRGBBitCount == 8)
|
||||||
|
{
|
||||||
|
if (hdr.ddspf.dwRBitMask == 0xff)
|
||||||
|
format = DXGI_FORMAT_R8_UNORM;
|
||||||
|
else if (hdr.ddspf.dwABitMask == 0xff)
|
||||||
|
format = DXGI_FORMAT_A8_UNORM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hdr.ddspf.dwFourCC == '1TXD')
|
||||||
|
format = DXGI_FORMAT_BC1_UNORM;
|
||||||
|
if (hdr.ddspf.dwFourCC == '3TXD')
|
||||||
|
format = DXGI_FORMAT_BC2_UNORM;
|
||||||
|
if (hdr.ddspf.dwFourCC == '5TXD')
|
||||||
|
format = DXGI_FORMAT_BC3_UNORM;
|
||||||
|
if (hdr.ddspf.dwFourCC == 'U4CB')
|
||||||
|
format = DXGI_FORMAT_BC4_UNORM;
|
||||||
|
if (hdr.ddspf.dwFourCC == 'S4CB')
|
||||||
|
format = DXGI_FORMAT_BC4_SNORM;
|
||||||
|
if (hdr.ddspf.dwFourCC == '2ITA')
|
||||||
|
format = DXGI_FORMAT_BC5_UNORM;
|
||||||
|
if (hdr.ddspf.dwFourCC == 'S5CB')
|
||||||
|
format = DXGI_FORMAT_BC5_SNORM;
|
||||||
|
|
||||||
|
if (hdr.ddspf.dwFourCC == '01XD')
|
||||||
|
{
|
||||||
|
auto hdr10 = fs.ReadT<DDS_HEADER_DXT10>();
|
||||||
|
format = hdr10.dxgiFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
int blockSize = 0;
|
||||||
|
int bytesPerPixel = GetBytesPerPixel(format, blockSize);
|
||||||
|
|
||||||
|
int mipSize = ((hdr.dwWidth + blockSize - 1) / blockSize) * ((hdr.dwHeight + blockSize - 1) / blockSize) * bytesPerPixel;
|
||||||
|
Array<uint8> data;
|
||||||
|
data.Resize(mipSize);
|
||||||
|
fs.Read(data.mVals, data.mSize);
|
||||||
|
|
||||||
|
D3D11_SUBRESOURCE_DATA resData;
|
||||||
|
resData.pSysMem = data.mVals;
|
||||||
|
resData.SysMemPitch = ((hdr.dwWidth + blockSize - 1) / blockSize) * bytesPerPixel;
|
||||||
|
resData.SysMemSlicePitch = mipSize;
|
||||||
|
|
||||||
|
// Create the target texture
|
||||||
|
D3D11_TEXTURE2D_DESC desc;
|
||||||
|
ZeroMemory(&desc, sizeof(desc));
|
||||||
|
desc.Width = hdr.dwWidth;
|
||||||
|
desc.Height = hdr.dwHeight;
|
||||||
|
desc.MipLevels = 1;
|
||||||
|
desc.ArraySize = 1;
|
||||||
|
desc.Format = format;
|
||||||
|
desc.SampleDesc.Count = 1;
|
||||||
|
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||||
|
desc.CPUAccessFlags = 0;
|
||||||
|
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||||
|
|
||||||
|
DXGI_FORMAT viewFormat = format;
|
||||||
|
switch (viewFormat)
|
||||||
|
{
|
||||||
|
case DXGI_FORMAT_B8G8R8A8_TYPELESS: viewFormat = DXGI_FORMAT_B8G8R8A8_UNORM; break;
|
||||||
|
case DXGI_FORMAT_R8G8B8A8_TYPELESS: viewFormat = DXGI_FORMAT_R8G8B8A8_UNORM; break;
|
||||||
|
case DXGI_FORMAT_BC1_TYPELESS: viewFormat = DXGI_FORMAT_BC1_UNORM; break;
|
||||||
|
case DXGI_FORMAT_BC2_TYPELESS: viewFormat = DXGI_FORMAT_BC2_UNORM; break;
|
||||||
|
case DXGI_FORMAT_BC3_TYPELESS: viewFormat = DXGI_FORMAT_BC3_UNORM; break;
|
||||||
|
case DXGI_FORMAT_BC4_TYPELESS: viewFormat = DXGI_FORMAT_BC4_UNORM; break;
|
||||||
|
case DXGI_FORMAT_BC5_TYPELESS: viewFormat = DXGI_FORMAT_BC5_UNORM; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//OutputDebugStrF("Creating texture\n");
|
||||||
|
|
||||||
|
ID3D11Texture2D* d3DTexture = NULL;
|
||||||
|
DXCHECK(mD3DDevice->CreateTexture2D(&desc, &resData, &d3DTexture));
|
||||||
|
|
||||||
|
D3D11_SHADER_RESOURCE_VIEW_DESC srDesc;
|
||||||
|
srDesc.Format = viewFormat;
|
||||||
|
srDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||||
|
srDesc.Texture2D.MostDetailedMip = 0;
|
||||||
|
srDesc.Texture2D.MipLevels = 1;
|
||||||
|
|
||||||
|
ID3D11ShaderResourceView* d3DShaderResourceView = NULL;
|
||||||
|
DXCHECK(mD3DDevice->CreateShaderResourceView(d3DTexture, &srDesc, &d3DShaderResourceView));
|
||||||
|
|
||||||
|
DXTexture* aTexture = new DXTexture();
|
||||||
|
aTexture->mPath = fileName;
|
||||||
|
aTexture->mRenderDevice = this;
|
||||||
|
aTexture->mWidth = hdr.dwWidth;
|
||||||
|
aTexture->mHeight = hdr.dwHeight;
|
||||||
|
aTexture->mD3DTexture = d3DTexture;
|
||||||
|
aTexture->mD3DResourceView = d3DShaderResourceView;
|
||||||
|
aTexture->AddRef();
|
||||||
|
|
||||||
|
mTextureMap[aTexture->mPath] = aTexture;
|
||||||
|
mTextures.Add(aTexture);
|
||||||
|
return aTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
aTexture = (DXTexture*)RenderDevice::LoadTexture(fileName, flags);
|
||||||
|
if (aTexture != NULL)
|
||||||
|
{
|
||||||
|
aTexture->mPath = fileName;
|
||||||
|
mTextureMap[aTexture->mPath] = aTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
return aTexture;
|
||||||
|
}
|
||||||
|
|
||||||
Texture* DXRenderDevice::LoadTexture(ImageData* imageData, int flags)
|
Texture* DXRenderDevice::LoadTexture(ImageData* imageData, int flags)
|
||||||
{
|
{
|
||||||
ID3D11ShaderResourceView* d3DShaderResourceView = NULL;
|
ID3D11ShaderResourceView* d3DShaderResourceView = NULL;
|
||||||
|
@ -1833,6 +2242,7 @@ Texture* DXRenderDevice::CreateRenderTarget(int width, int height, bool destAlph
|
||||||
aRenderTarget->mWidth = width;
|
aRenderTarget->mWidth = width;
|
||||||
aRenderTarget->mHeight = height;
|
aRenderTarget->mHeight = height;
|
||||||
aRenderTarget->mRenderDevice = this;
|
aRenderTarget->mRenderDevice = this;
|
||||||
|
aRenderTarget->mD3DTexture = d3DTexture;
|
||||||
aRenderTarget->mD3DResourceView = d3DShaderResourceView;
|
aRenderTarget->mD3DResourceView = d3DShaderResourceView;
|
||||||
aRenderTarget->mD3DRenderTargetView = d3DRenderTargetView;
|
aRenderTarget->mD3DRenderTargetView = d3DRenderTargetView;
|
||||||
aRenderTarget->AddRef();
|
aRenderTarget->AddRef();
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include "gfx/DrawLayer.h"
|
#include "gfx/DrawLayer.h"
|
||||||
#include "gfx/ModelInstance.h"
|
#include "gfx/ModelInstance.h"
|
||||||
#include "util/HashSet.h"
|
#include "util/HashSet.h"
|
||||||
|
#include "util/Dictionary.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
NS_BF_BEGIN;
|
NS_BF_BEGIN;
|
||||||
|
@ -55,6 +56,7 @@ class DXRenderDevice;
|
||||||
class DXTexture : public Texture
|
class DXTexture : public Texture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
String mPath;
|
||||||
DXRenderDevice* mRenderDevice;
|
DXRenderDevice* mRenderDevice;
|
||||||
ID3D11Texture2D* mD3DTexture;
|
ID3D11Texture2D* mD3DTexture;
|
||||||
ID3D11ShaderResourceView* mD3DResourceView;
|
ID3D11ShaderResourceView* mD3DResourceView;
|
||||||
|
@ -124,8 +126,8 @@ class DXDrawLayer : public DrawLayer
|
||||||
public:
|
public:
|
||||||
virtual DrawBatch* CreateDrawBatch();
|
virtual DrawBatch* CreateDrawBatch();
|
||||||
virtual RenderCmd* CreateSetTextureCmd(int textureIdx, Texture* texture) override;
|
virtual RenderCmd* CreateSetTextureCmd(int textureIdx, Texture* texture) override;
|
||||||
virtual void SetShaderConstantData(int slotIdx, void* constData, int size) override;
|
virtual void SetShaderConstantData(int usageIdx, int slotIdx, void* constData, int size) override;
|
||||||
virtual void SetShaderConstantDataTyped(int slotIdx, void* constData, int size, int* typeData, int typeCount) override;
|
virtual void SetShaderConstantDataTyped(int usageIdx, int slotIdx, void* constData, int size, int* typeData, int typeCount) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DXDrawLayer();
|
DXDrawLayer();
|
||||||
|
@ -203,32 +205,40 @@ public:
|
||||||
void IndalidateDepthStencilState();
|
void IndalidateDepthStencilState();
|
||||||
|
|
||||||
virtual void SetClipped(bool clipped);
|
virtual void SetClipped(bool clipped);
|
||||||
|
virtual void SetTexWrap(bool clipped);
|
||||||
virtual void SetClipRect(const Rect& rect);
|
virtual void SetClipRect(const Rect& rect);
|
||||||
virtual void SetWriteDepthBuffer(bool writeDepthBuffer);
|
virtual void SetWriteDepthBuffer(bool writeDepthBuffer);
|
||||||
virtual void SetDepthFunc(DepthFunc depthFunc);
|
virtual void SetDepthFunc(DepthFunc depthFunc);
|
||||||
};
|
};
|
||||||
|
|
||||||
class DXModelMesh
|
class DXModelPrimitives
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
String mMaterialName;
|
||||||
int mNumIndices;
|
int mNumIndices;
|
||||||
int mNumVertices;
|
int mNumVertices;
|
||||||
DXTexture* mTexture;
|
Array<DXTexture*> mTextures;
|
||||||
|
|
||||||
ID3D11Buffer* mD3DIndexBuffer;
|
ID3D11Buffer* mD3DIndexBuffer;
|
||||||
//TODO: Split the vertex buffer up into static and dynamic buffers
|
//TODO: Split the vertex buffer up into static and dynamic buffers
|
||||||
ID3D11Buffer* mD3DVertexBuffer;
|
ID3D11Buffer* mD3DVertexBuffer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DXModelMesh();
|
DXModelPrimitives();
|
||||||
~DXModelMesh();
|
~DXModelPrimitives();
|
||||||
|
};
|
||||||
|
|
||||||
|
class DXModelMesh
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Array<DXModelPrimitives> mPrimitives;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DXModelInstance : public ModelInstance
|
class DXModelInstance : public ModelInstance
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DXRenderDevice* mD3DRenderDevice;
|
DXRenderDevice* mD3DRenderDevice;
|
||||||
std::vector<DXModelMesh> mDXModelMeshs;
|
Array<DXModelMesh> mDXModelMeshs;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DXModelInstance(ModelDef* modelDef);
|
DXModelInstance(ModelDef* modelDef);
|
||||||
|
@ -274,6 +284,7 @@ public:
|
||||||
ID3D11DeviceContext* mD3DDeviceContext;
|
ID3D11DeviceContext* mD3DDeviceContext;
|
||||||
ID3D11BlendState* mD3DNormalBlendState;
|
ID3D11BlendState* mD3DNormalBlendState;
|
||||||
ID3D11SamplerState* mD3DDefaultSamplerState;
|
ID3D11SamplerState* mD3DDefaultSamplerState;
|
||||||
|
ID3D11SamplerState* mD3DWrapSamplerState;
|
||||||
bool mHasVSync;
|
bool mHasVSync;
|
||||||
|
|
||||||
ID3D11Buffer* mD3DVertexBuffer;
|
ID3D11Buffer* mD3DVertexBuffer;
|
||||||
|
@ -283,6 +294,8 @@ public:
|
||||||
|
|
||||||
HashSet<DXRenderState*> mRenderStates;
|
HashSet<DXRenderState*> mRenderStates;
|
||||||
HashSet<DXTexture*> mTextures;
|
HashSet<DXTexture*> mTextures;
|
||||||
|
Dictionary<String, DXTexture*> mTextureMap;
|
||||||
|
Dictionary<int, ID3D11Buffer*> mBufferMap;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void PhysSetRenderState(RenderState* renderState) override;
|
virtual void PhysSetRenderState(RenderState* renderState) override;
|
||||||
|
@ -302,6 +315,7 @@ public:
|
||||||
void FrameStart() override;
|
void FrameStart() override;
|
||||||
void FrameEnd() override;
|
void FrameEnd() override;
|
||||||
|
|
||||||
|
Texture* LoadTexture(const StringImpl& fileName, int flags) override;
|
||||||
Texture* LoadTexture(ImageData* imageData, int flags) override;
|
Texture* LoadTexture(ImageData* imageData, int flags) override;
|
||||||
Texture* CreateDynTexture(int width, int height) override;
|
Texture* CreateDynTexture(int width, int height) override;
|
||||||
Shader* LoadShader(const StringImpl& fileName, VertexDefinition* vertexDefinition) override;
|
Shader* LoadShader(const StringImpl& fileName, VertexDefinition* vertexDefinition) override;
|
||||||
|
|
|
@ -2637,6 +2637,9 @@ BFP_EXPORT void BFP_CALLTYPE BfpDirectory_GetSysDirectory(BfpSysDirectoryKind sy
|
||||||
case BfpSysDirectoryKind_Programs_Common:
|
case BfpSysDirectoryKind_Programs_Common:
|
||||||
_GetKnownFolder(FOLDERID_CommonPrograms);
|
_GetKnownFolder(FOLDERID_CommonPrograms);
|
||||||
return;
|
return;
|
||||||
|
case BfpSysDirectoryKind_Documents:
|
||||||
|
_GetKnownFolder(FOLDERID_Documents);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TryStringOut(path, outPath, inOutPathLen, (BfpResult*)outResult);
|
TryStringOut(path, outPath, inOutPathLen, (BfpResult*)outResult);
|
||||||
|
|
|
@ -26,11 +26,11 @@ Beefy::Quaternion Beefy::Quaternion::Slerp(float fT, const Quaternion& rkP, cons
|
||||||
if ((fabs(fCos) < 1.0f - BF_MS_EPSILON) && (false))
|
if ((fabs(fCos) < 1.0f - BF_MS_EPSILON) && (false))
|
||||||
{
|
{
|
||||||
// Standard case (slerp)
|
// Standard case (slerp)
|
||||||
float fSin = sqrt(1.0f - (fCos * fCos));
|
float fSin = sqrtf(1.0f - (fCos * fCos));
|
||||||
float fAngle = atan2(fSin, fCos);
|
float fAngle = atan2f(fSin, fCos);
|
||||||
float fInvSin = 1.0f / fSin;
|
float fInvSin = 1.0f / fSin;
|
||||||
float fCoeff0 = sin((1.0f - fT) * fAngle) * fInvSin;
|
float fCoeff0 = sinf((1.0f - fT) * fAngle) * fInvSin;
|
||||||
float fCoeff1 = sin(fT * fAngle) * fInvSin;
|
float fCoeff1 = sinf(fT * fAngle) * fInvSin;
|
||||||
return fCoeff0 * rkP + fCoeff1 * rkT;
|
return fCoeff0 * rkP + fCoeff1 * rkT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -114,7 +114,7 @@ public:
|
||||||
static Quaternion Normalise(const Quaternion& quat)
|
static Quaternion Normalise(const Quaternion& quat)
|
||||||
{
|
{
|
||||||
float len = quat.Norm();
|
float len = quat.Norm();
|
||||||
float factor = 1.0f / sqrt(len);
|
float factor = 1.0f / sqrtf(len);
|
||||||
return quat * factor;
|
return quat * factor;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,7 +13,7 @@ Vector3::Vector3(float x, float y, float z)
|
||||||
|
|
||||||
float Vector3::GetMagnitude() const
|
float Vector3::GetMagnitude() const
|
||||||
{
|
{
|
||||||
return sqrt(mX*mX + mY*mY + mZ*mZ);
|
return sqrtf(mX*mX + mY*mY + mZ*mZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 Vector3::Normalize(const Vector3& vec)
|
Vector3 Vector3::Normalize(const Vector3& vec)
|
||||||
|
@ -76,3 +76,13 @@ Vector3 Vector3::Transform2(const Vector3& vec, const Quaternion& quat)
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
Vector4::Vector4(float x, float y, float z, float w)
|
||||||
|
{
|
||||||
|
mX = x;
|
||||||
|
mY = y;
|
||||||
|
mZ = z;
|
||||||
|
mW = w;
|
||||||
|
}
|
|
@ -94,4 +94,64 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Vector4
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
float mX;
|
||||||
|
float mY;
|
||||||
|
float mZ;
|
||||||
|
float mW;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Vector4(float x = 0, float y = 0, float z = 0, float w = 0);
|
||||||
|
|
||||||
|
bool operator==(const Vector4& check) const
|
||||||
|
{
|
||||||
|
return (mX == check.mX) && (mY == check.mY) && (mZ == check.mZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const Vector4& check) const
|
||||||
|
{
|
||||||
|
return (mX != check.mX) || (mY != check.mY) || (mZ != check.mZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Vector4 Scale(const Vector4& vec, float scale)
|
||||||
|
{
|
||||||
|
return Vector4(vec.mX * scale, vec.mY * scale, vec.mZ * scale, vec.mW * scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector4 operator +(const Vector4& v2) const
|
||||||
|
{
|
||||||
|
return Vector4(mX + v2.mX, mY + v2.mY, mZ + v2.mZ, mW + v2.mW);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector4 operator *(const Vector4& v2) const
|
||||||
|
{
|
||||||
|
return Vector4(mX * v2.mX, mY * v2.mY, mZ * v2.mZ, mW * v2.mW);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector4 operator *(float scale) const
|
||||||
|
{
|
||||||
|
return Vector4(mX * scale, mY * scale, mZ * scale, mW * scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector4& operator -= (const Vector4& vec)
|
||||||
|
{
|
||||||
|
mX -= vec.mX;
|
||||||
|
mY -= vec.mY;
|
||||||
|
mZ -= vec.mZ;
|
||||||
|
mW -= vec.mW;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector4& operator *= (const Vector4& vec)
|
||||||
|
{
|
||||||
|
mX *= vec.mX;
|
||||||
|
mY *= vec.mY;
|
||||||
|
mZ *= vec.mZ;
|
||||||
|
mW *= vec.mW;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
NS_BF_END;
|
NS_BF_END;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue