Skip to content

Instantly share code, notes, and snippets.

@haruo-wakakusa
Created October 22, 2018 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save haruo-wakakusa/e590ef1cd5d860f1581c1abcbc9429ee to your computer and use it in GitHub Desktop.
Save haruo-wakakusa/e590ef1cd5d860f1581c1abcbc9429ee to your computer and use it in GitHub Desktop.
Kuin-master(2018.10.17差分): DirectX10 -> DirectX11に変更
#include "draw.h"
// DirectX 11 is preinstalled on Windows 7 or later.
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "dxgi.lib")
#include <d3d11.h>
#include "png_decoder.h"
#include "jpg_decoder.h"
#include "bc_decoder.h"
static const int DepthNum = 4;
static const int BlendNum = 5;
static const int SamplerNum = 2;
static const int JointMax = 256;
static const int FontBitmapSize = 1024;
static const int TexEvenNum = 3;
static const double DiscardAlpha = 0.02;
static const int FilterNum = 2;
struct SWndBuf
{
IDXGISwapChain* SwapChain;
ID3D11RenderTargetView* RenderTargetView;
ID3D11DepthStencilView* DepthView;
FLOAT ClearColor[4];
int TexWidth;
int TexHeight;
int ScreenWidth;
int ScreenHeight;
ID3D11Texture2D* TmpTex;
ID3D11ShaderResourceView* TmpShaderResView;
ID3D11RenderTargetView* TmpRenderTargetView;
};
struct SShaderBuf
{
Draw::EShaderKind Kind;
void* Shader;
size_t ConstBufSize;
ID3D11Buffer* ConstBuf;
ID3D11InputLayout* Layout;
};
struct SVertexBuf
{
ID3D11Buffer* Vertex;
size_t VertexLineSize;
ID3D11Buffer* Idx;
};
struct STex
{
SClass Class;
int Width;
int Height;
ID3D11Texture2D* Tex;
ID3D11ShaderResourceView* View;
};
struct SFont
{
SClass Class;
ID3D11Texture2D* Tex;
ID3D11ShaderResourceView* View;
int CellWidth;
int CellHeight;
int CellSizeAligned;
U32 Cnt;
double Advance;
bool Proportional;
HFONT Font;
Char* CharMap;
U32* CntMap;
U8* Pixel;
HBITMAP Bitmap;
HDC Dc;
int* GlyphWidth;
};
struct SObj
{
SClass Class;
struct SPolygon
{
void* VertexBuf;
int VertexNum;
int JointNum;
int Begin;
int End;
float(*Joints)[4][4];
};
int ElementNum;
int* ElementKinds;
void** Elements;
float Mat[4][4];
float NormMat[4][4];
};
struct SObjCommonVsConstBuf
{
float World[4][4];
float NormWorld[4][4];
float ProjView[4][4];
float Eye[4];
float Dir[4];
};
STATIC_ASSERT(sizeof(SObjCommonVsConstBuf) == 4 * 56);
struct SObjCommonPsConstBuf
{
float AmbTopColor[4];
float AmbBottomColor[4];
float DirColor[4];
};
STATIC_ASSERT(sizeof(SObjCommonPsConstBuf) == 4 * 12);
struct SObjVsConstBuf
{
SObjCommonVsConstBuf CommonParam;
float Joint[JointMax][4][4];
};
struct SObjPsConstBuf
{
SObjCommonPsConstBuf CommonParam;
};
struct SObjOutlineVsConstBuf
{
SObjCommonVsConstBuf CommonParam;
float OutlineParam[4];
float Joint[JointMax][4][4];
};
struct SObjOutlinePsConstBuf
{
float OutlineColor[4];
};
static const FLOAT BlendFactor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
const U8* GetTriVsBin(size_t* size);
const U8* GetTriPsBin(size_t* size);
const U8* GetFontPsBin(size_t* size);
const U8* GetRectVsBin(size_t* size);
const U8* GetCircleVsBin(size_t* size);
const U8* GetCirclePsBin(size_t* size);
const U8* GetTexVsBin(size_t* size);
const U8* GetTexRotVsBin(size_t* size);
const U8* GetTexPsBin(size_t* size);
const U8* GetObjVsBin(size_t* size);
const U8* GetObjJointVsBin(size_t* size);
const U8* GetObjPsBin(size_t* size);
const U8* GetObjToonPsBin(size_t* size);
const U8* GetObjOutlineVsBin(size_t* size);
const U8* GetObjOutlineJointVsBin(size_t* size);
const U8* GetObjOutlinePsBin(size_t* size);
const U8* GetFilterVsBin(size_t* size);
const U8* GetFilterNonePsBin(size_t* size);
const U8* GetFilterMonotonePsBin(size_t* size);
const U8* GetToonRampPngBin(size_t* size);
static S64 Cnt;
static U32 PrevTime;
static ID3D11Device* Device = NULL;
static ID3D11DeviceContext* DeviceContext = NULL;
static ID3D11RasterizerState* RasterizerState = NULL;
static ID3D11RasterizerState* RasterizerStateInverted = NULL;
static ID3D11DepthStencilState* DepthState[DepthNum] = { NULL };
static ID3D11BlendState* BlendState[BlendNum] = { NULL };
static ID3D11SamplerState* Sampler[SamplerNum] = { NULL };
static SWndBuf* CurWndBuf = NULL;
static void* TriVertex = NULL;
static void* TriVs = NULL;
static void* TriPs = NULL;
static void* RectVertex = NULL;
static void* LineVertex = NULL;
static void* RectLineVertex = NULL;
static void* RectVs = NULL;
static void* CircleVertex = NULL;
static void* CircleVs = NULL;
static void* CirclePs = NULL;
static void* TexVs = NULL;
static void* TexRotVs = NULL;
static void* TexPs = NULL;
static void* FontPs = NULL;
static void* ObjVs = NULL;
static void* ObjJointVs = NULL;
static void* ObjPs = NULL;
static void* ObjToonPs = NULL;
static void* ObjOutlineVs = NULL;
static void* ObjOutlineJointVs = NULL;
static void* ObjOutlinePs = NULL;
static void* FilterVertex = NULL;
static void* FilterVs = NULL;
static void* FilterPs[FilterNum] = { NULL };
static double ViewMat[4][4];
static double ProjMat[4][4];
static SObjVsConstBuf ObjVsConstBuf;
static SObjPsConstBuf ObjPsConstBuf;
static int CurZBuf = -1;
static int CurBlend = -1;
static int CurSampler = -1;
ID3D11Texture2D* TexToonRamp;
ID3D11ShaderResourceView* ViewToonRamp;
ID3D11Texture2D* TexEven[TexEvenNum];
ID3D11ShaderResourceView* ViewEven[TexEvenNum];
static int FilterIdx = 0;
static float FilterParam[4][4];
EXPORT_CPP void _render(S64 fps)
{
// Draw with a filter.
{
int old_z_buf = CurZBuf;
int old_blend = CurBlend;
int old_sampler = CurSampler;
_resetViewport();
_depth(False, False);
_blend(0);
_sampler(0);
DeviceContext->OMSetRenderTargets(1, &CurWndBuf->RenderTargetView, NULL);
{
Draw::ConstBuf(FilterVs, NULL);
DeviceContext->GSSetShader(NULL, NULL, 0);
Draw::ConstBuf(FilterPs[FilterIdx], FilterIdx == 0 ? NULL : FilterParam);
Draw::VertexBuf(FilterVertex);
DeviceContext->PSSetShaderResources(0, 1, &CurWndBuf->TmpShaderResView);
}
DeviceContext->DrawIndexed(6, 0, 0);
_depth((old_z_buf & 2) != 0, (old_z_buf & 1) != 0);
_blend(old_blend);
_sampler(old_sampler);
}
CurWndBuf->SwapChain->Present(fps == 0 ? 0 : 1, 0);
DeviceContext->OMSetRenderTargets(1, &CurWndBuf->TmpRenderTargetView, CurWndBuf->DepthView);
DeviceContext->ClearRenderTargetView(CurWndBuf->TmpRenderTargetView, CurWndBuf->ClearColor);
DeviceContext->ClearDepthStencilView(CurWndBuf->DepthView, D3D11_CLEAR_DEPTH, 1.0f, 0);
DeviceContext->RSSetState(RasterizerState);
if (fps == 0)
return;
Cnt++;
U32 now = static_cast<U32>(timeGetTime());
U32 diff = now - PrevTime;
int next_wait = 0;
int sleep_time = 0;
switch (fps)
{
case 30:
sleep_time = (Cnt % 3 == 0 ? 34 : 33);
break;
case 60:
sleep_time = (Cnt % 3 == 0 ? 16 : 17);
break;
default:
THROWDBG(True, 0xe9170006);
return;
}
sleep_time -= static_cast<int>(diff);
if (sleep_time > 2)
{
U32 to_time = now + static_cast<U32>(sleep_time);
Sleep(static_cast<DWORD>(sleep_time - 1));
while (static_cast<U32>(timeGetTime()) < to_time)
{
// Do nothing.
}
}
else
{
Sleep(1);
next_wait = sleep_time;
if (next_wait <= -100)
next_wait = 0;
}
PrevTime = static_cast<U32>(static_cast<int>(timeGetTime()) - next_wait);
}
EXPORT_CPP S64 _cnt()
{
return Cnt;
}
EXPORT_CPP void _viewport(double x, double y, double w, double h)
{
D3D11_VIEWPORT viewport =
{
static_cast<INT>(x),
static_cast<INT>(y),
static_cast<UINT>(w),
static_cast<UINT>(h),
0.0f,
1.0f,
};
DeviceContext->RSSetViewports(1, &viewport);
}
EXPORT_CPP void _resetViewport()
{
D3D11_VIEWPORT viewport =
{
0,
0,
static_cast<UINT>(CurWndBuf->TexWidth),
static_cast<UINT>(CurWndBuf->TexHeight),
0.0f,
1.0f,
};
DeviceContext->RSSetViewports(1, &viewport);
}
EXPORT_CPP void _depth(Bool test, Bool write)
{
int kind = (static_cast<int>(test) << 1) | static_cast<int>(write);
if (CurZBuf == kind)
return;
DeviceContext->OMSetDepthStencilState(DepthState[kind], 0);
CurZBuf = kind;
}
EXPORT_CPP void _blend(S64 kind)
{
THROWDBG(kind < 0 || BlendNum <= kind, 0xe9170006);
int kind2 = static_cast<int>(kind);
if (CurBlend == kind2)
return;
DeviceContext->OMSetBlendState(BlendState[kind2], BlendFactor, 0xffffffff);
CurBlend = kind2;
}
EXPORT_CPP void _sampler(S64 kind)
{
THROWDBG(kind < 0 || SamplerNum <= kind, 0xe9170006);
int kind2 = static_cast<int>(kind);
if (CurSampler == kind2)
return;
DeviceContext->PSSetSamplers(0, 1, &Sampler[kind2]);
CurSampler = kind2;
}
EXPORT_CPP void _clearColor(S64 color)
{
double r, g, b, a;
Draw::ColorToArgb(&a, &r, &g, &b, color);
CurWndBuf->ClearColor[0] = static_cast<FLOAT>(r);
CurWndBuf->ClearColor[1] = static_cast<FLOAT>(g);
CurWndBuf->ClearColor[2] = static_cast<FLOAT>(b);
}
EXPORT_CPP void _line(double x1, double y1, double x2, double y2, S64 color)
{
double r, g, b, a;
Draw::ColorToArgb(&a, &r, &g, &b, color);
if (a <= DiscardAlpha)
return;
{
float const_buf_vs[4] =
{
static_cast<float>(x1) / static_cast<float>(CurWndBuf->ScreenWidth) * 2.0f - 1.0f,
-(static_cast<float>(y1) / static_cast<float>(CurWndBuf->ScreenHeight) * 2.0f - 1.0f),
static_cast<float>(x2 - x1) / static_cast<float>(CurWndBuf->ScreenWidth) * 2.0f,
-(static_cast<float>(y2 - y1) / static_cast<float>(CurWndBuf->ScreenHeight) * 2.0f),
};
float const_buf_ps[4] =
{
static_cast<float>(r),
static_cast<float>(g),
static_cast<float>(b),
static_cast<float>(a),
};
Draw::ConstBuf(RectVs, const_buf_vs);
DeviceContext->GSSetShader(NULL, NULL, 0);
Draw::ConstBuf(TriPs, const_buf_ps);
Draw::VertexBuf(LineVertex);
}
DeviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_LINELIST);
DeviceContext->DrawIndexed(2, 0, 0);
DeviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
}
EXPORT_CPP void _tri(double x1, double y1, double x2, double y2, double x3, double y3, S64 color)
{
double r, g, b, a;
Draw::ColorToArgb(&a, &r, &g, &b, color);
if (a <= DiscardAlpha)
return;
if ((x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1) < 0.0)
{
double tmp;
tmp = x2;
x2 = x3;
x3 = tmp;
tmp = y2;
y2 = y3;
y3 = tmp;
}
{
float const_buf_vs[8] =
{
static_cast<float>(x1) / static_cast<float>(CurWndBuf->ScreenWidth) * 2.0f - 1.0f,
-(static_cast<float>(y1) / static_cast<float>(CurWndBuf->ScreenHeight) * 2.0f - 1.0f),
static_cast<float>(x2) / static_cast<float>(CurWndBuf->ScreenWidth) * 2.0f - 1.0f,
-(static_cast<float>(y2) / static_cast<float>(CurWndBuf->ScreenHeight) * 2.0f - 1.0f),
static_cast<float>(x3) / static_cast<float>(CurWndBuf->ScreenWidth) * 2.0f - 1.0f,
-(static_cast<float>(y3) / static_cast<float>(CurWndBuf->ScreenHeight) * 2.0f - 1.0f),
};
float const_buf_ps[4] =
{
static_cast<float>(r),
static_cast<float>(g),
static_cast<float>(b),
static_cast<float>(a),
};
Draw::ConstBuf(TriVs, const_buf_vs);
DeviceContext->GSSetShader(NULL, NULL, 0);
Draw::ConstBuf(TriPs, const_buf_ps);
Draw::VertexBuf(TriVertex);
}
DeviceContext->DrawIndexed(3, 0, 0);
}
EXPORT_CPP void _rect(double x, double y, double w, double h, S64 color)
{
double r, g, b, a;
Draw::ColorToArgb(&a, &r, &g, &b, color);
if (a <= DiscardAlpha)
return;
if (w < 0.0)
{
x += w;
w = -w;
}
if (h < 0.0)
{
y += h;
h = -h;
}
{
float const_buf_vs[4] =
{
static_cast<float>(x) / static_cast<float>(CurWndBuf->ScreenWidth) * 2.0f - 1.0f,
-(static_cast<float>(y) / static_cast<float>(CurWndBuf->ScreenHeight) * 2.0f - 1.0f),
static_cast<float>(w) / static_cast<float>(CurWndBuf->ScreenWidth) * 2.0f,
-(static_cast<float>(h) / static_cast<float>(CurWndBuf->ScreenHeight) * 2.0f),
};
float const_buf_ps[4] =
{
static_cast<float>(r),
static_cast<float>(g),
static_cast<float>(b),
static_cast<float>(a),
};
Draw::ConstBuf(RectVs, const_buf_vs);
DeviceContext->GSSetShader(NULL, NULL, 0);
Draw::ConstBuf(TriPs, const_buf_ps);
Draw::VertexBuf(RectVertex);
}
DeviceContext->DrawIndexed(6, 0, 0);
}
EXPORT_CPP void _rectLine(double x, double y, double w, double h, S64 color)
{
double r, g, b, a;
Draw::ColorToArgb(&a, &r, &g, &b, color);
if (a <= DiscardAlpha)
return;
if (w < 0.0)
{
x += w;
w = -w;
}
if (h < 0.0)
{
y += h;
h = -h;
}
{
float const_buf_vs[4] =
{
static_cast<float>(x) / static_cast<float>(CurWndBuf->ScreenWidth) * 2.0f - 1.0f,
-(static_cast<float>(y) / static_cast<float>(CurWndBuf->ScreenHeight) * 2.0f - 1.0f),
static_cast<float>(w) / static_cast<float>(CurWndBuf->ScreenWidth) * 2.0f,
-(static_cast<float>(h) / static_cast<float>(CurWndBuf->ScreenHeight) * 2.0f),
};
float const_buf_ps[4] =
{
static_cast<float>(r),
static_cast<float>(g),
static_cast<float>(b),
static_cast<float>(a),
};
Draw::ConstBuf(RectVs, const_buf_vs);
DeviceContext->GSSetShader(NULL, NULL, 0);
Draw::ConstBuf(TriPs, const_buf_ps);
Draw::VertexBuf(RectLineVertex);
}
DeviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_LINELIST);
DeviceContext->DrawIndexed(8, 0, 0);
DeviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
}
EXPORT_CPP void _circle(double x, double y, double radiusX, double radiusY, S64 color)
{
double r, g, b, a;
Draw::ColorToArgb(&a, &r, &g, &b, color);
if (a <= DiscardAlpha)
return;
if (radiusX < 0.0)
radiusX = -radiusX;
if (radiusY < 0.0)
radiusY = -radiusY;
{
float const_buf_vs[4] =
{
static_cast<float>(x) / static_cast<float>(CurWndBuf->ScreenWidth) * 2.0f - 1.0f,
-(static_cast<float>(y) / static_cast<float>(CurWndBuf->ScreenHeight) * 2.0f - 1.0f),
static_cast<float>(radiusX) / static_cast<float>(CurWndBuf->ScreenWidth) * 2.0f,
-(static_cast<float>(radiusY) / static_cast<float>(CurWndBuf->ScreenHeight) * 2.0f),
};
float const_buf_ps[4] =
{
static_cast<float>(r),
static_cast<float>(g),
static_cast<float>(b),
static_cast<float>(a),
};
Draw::ConstBuf(CircleVs, const_buf_vs);
DeviceContext->GSSetShader(NULL, NULL, 0);
Draw::ConstBuf(CirclePs, const_buf_ps);
Draw::VertexBuf(CircleVertex);
}
DeviceContext->DrawIndexed(6, 0, 0);
}
EXPORT_CPP void _filterNone()
{
FilterIdx = 0;
}
EXPORT_CPP void _filterMonotone(S64 color, double rate)
{
double r, g, b, a;
Draw::ColorToArgb(&a, &r, &g, &b, color);
if (rate < 0.0)
rate = 0.0;
else if (rate > 1.0)
rate = 1.0;
FilterIdx = 1;
FilterParam[0][0] = static_cast<float>(r);
FilterParam[0][1] = static_cast<float>(g);
FilterParam[0][2] = static_cast<float>(b);
FilterParam[0][3] = static_cast<float>(rate);
}
EXPORT_CPP SClass* _makeTex(SClass* me_, const U8* path)
{
return Draw::MakeTexImpl(me_, path, False);
}
EXPORT_CPP SClass* _makeTexArgb(SClass* me_, const U8* path)
{
return Draw::MakeTexImpl(me_, path, True);
}
EXPORT_CPP SClass* _makeTexEvenArgb(SClass* me_, double a, double r, double g, double b)
{
STex* me2 = reinterpret_cast<STex*>(me_);
float img[4] = { static_cast<float>(r), static_cast<float>(g), static_cast<float>(b), static_cast<float>(a) };
me2->Width = 1;
me2->Height = 1;
{
D3D11_TEXTURE2D_DESC desc;
D3D11_SUBRESOURCE_DATA sub;
desc.Width = 1;
desc.Height = 1;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_IMMUTABLE;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
sub.pSysMem = img;
sub.SysMemPitch = static_cast<UINT>(sizeof(img));
sub.SysMemSlicePitch = 0;
if (FAILED(Device->CreateTexture2D(&desc, &sub, &me2->Tex)))
THROW(0xe9170009);
}
{
D3D11_SHADER_RESOURCE_VIEW_DESC desc;
memset(&desc, 0, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
desc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D;
desc.Texture2D.MostDetailedMip = 0;
desc.Texture2D.MipLevels = 1;
if (FAILED(Device->CreateShaderResourceView(me2->Tex, &desc, &me2->View)))
THROW(0xe9170009);
}
return me_;
}
EXPORT_CPP SClass* _makeTexEvenColor(SClass* me_, S64 color)
{
double r, g, b, a;
Draw::ColorToArgb(&a, &r, &g, &b, color);
return _makeTexEvenArgb(me_, a, r, g, b);
}
EXPORT_CPP void _texDtor(SClass* me_)
{
STex* me2 = reinterpret_cast<STex*>(me_);
if (me2->View != NULL)
me2->View->Release();
if (me2->Tex != NULL)
me2->Tex->Release();
}
EXPORT_CPP void _texDraw(SClass* me_, double dstX, double dstY, double srcX, double srcY, double srcW, double srcH, S64 color)
{
_texDrawScale(me_, dstX, dstY, srcW, srcH, srcX, srcY, srcW, srcH, color);
}
EXPORT_CPP void _texDrawScale(SClass* me_, double dstX, double dstY, double dstW, double dstH, double srcX, double srcY, double srcW, double srcH, S64 color)
{
double r, g, b, a;
Draw::ColorToArgb(&a, &r, &g, &b, color);
if (a <= DiscardAlpha)
return;
STex* me2 = reinterpret_cast<STex*>(me_);
if (dstW < 0.0)
{
dstX += dstW;
dstW = -dstW;
srcX += srcW;
srcW = -srcW;
}
if (dstH < 0.0)
{
dstY += dstH;
dstH = -dstH;
srcY += srcH;
srcH = -srcH;
}
{
float const_buf_vs[8] =
{
static_cast<float>(dstX) / static_cast<float>(CurWndBuf->ScreenWidth) * 2.0f - 1.0f,
-(static_cast<float>(dstY) / static_cast<float>(CurWndBuf->ScreenHeight) * 2.0f - 1.0f),
static_cast<float>(dstW) / static_cast<float>(CurWndBuf->ScreenWidth) * 2.0f,
-(static_cast<float>(dstH) / static_cast<float>(CurWndBuf->ScreenHeight) * 2.0f),
static_cast<float>(srcX) / static_cast<float>(me2->Width),
-(static_cast<float>(srcY) / static_cast<float>(me2->Height)),
static_cast<float>(srcW) / static_cast<float>(me2->Width),
-(static_cast<float>(srcH) / static_cast<float>(me2->Height)),
};
float const_buf_ps[4] =
{
static_cast<float>(r),
static_cast<float>(g),
static_cast<float>(b),
static_cast<float>(a),
};
Draw::ConstBuf(TexVs, const_buf_vs);
DeviceContext->GSSetShader(NULL, NULL, 0);
Draw::ConstBuf(TexPs, const_buf_ps);
Draw::VertexBuf(RectVertex);
DeviceContext->PSSetShaderResources(0, 1, &me2->View);
}
DeviceContext->DrawIndexed(6, 0, 0);
}
EXPORT_CPP void _texDrawRot(SClass* me_, double dstX, double dstY, double dstW, double dstH, double srcX, double srcY, double srcW, double srcH, double centerX, double centerY, double angle, S64 color)
{
double r, g, b, a;
Draw::ColorToArgb(&a, &r, &g, &b, color);
if (a <= DiscardAlpha)
return;
STex* me2 = reinterpret_cast<STex*>(me_);
if (dstW < 0.0)
{
dstX += dstW;
dstW = -dstW;
srcX += srcW;
srcW = -srcW;
}
if (dstH < 0.0)
{
dstY += dstH;
dstH = -dstH;
srcY += srcH;
srcH = -srcH;
}
{
float const_buf_vs[16] =
{
static_cast<float>(dstX) / static_cast<float>(CurWndBuf->ScreenWidth) * 2.0f - 1.0f,
-(static_cast<float>(dstY) / static_cast<float>(CurWndBuf->ScreenHeight) * 2.0f - 1.0f),
static_cast<float>(dstW) / static_cast<float>(CurWndBuf->ScreenWidth) * 2.0f,
-(static_cast<float>(dstH) / static_cast<float>(CurWndBuf->ScreenHeight) * 2.0f),
static_cast<float>(srcX) / static_cast<float>(me2->Width),
-(static_cast<float>(srcY) / static_cast<float>(me2->Height)),
static_cast<float>(srcW) / static_cast<float>(me2->Width),
-(static_cast<float>(srcH) / static_cast<float>(me2->Height)),
static_cast<float>(centerX) / static_cast<float>(CurWndBuf->ScreenWidth) * 2.0f,
-(static_cast<float>(centerY) / static_cast<float>(CurWndBuf->ScreenHeight) * 2.0f),
static_cast<float>(sin(-angle)),
static_cast<float>(cos(-angle)),
static_cast<float>(CurWndBuf->ScreenWidth) / static_cast<float>(CurWndBuf->ScreenHeight),
0.0f,
0.0f,
0.0f,
};
float const_buf_ps[4] =
{
static_cast<float>(r),
static_cast<float>(g),
static_cast<float>(b),
static_cast<float>(a),
};
Draw::ConstBuf(TexRotVs, const_buf_vs);
DeviceContext->GSSetShader(NULL, NULL, 0);
Draw::ConstBuf(TexPs, const_buf_ps);
Draw::VertexBuf(RectVertex);
DeviceContext->PSSetShaderResources(0, 1, &me2->View);
}
DeviceContext->DrawIndexed(6, 0, 0);
}
EXPORT_CPP SClass* _makeFont(SClass* me_, const U8* fontName, S64 size, bool bold, bool italic, bool proportional, double advance)
{
THROWDBG(size < 1, 0xe9170006);
SFont* me2 = reinterpret_cast<SFont*>(me_);
int char_height;
{
HDC dc = GetDC(NULL);
char_height = MulDiv(static_cast<int>(size), GetDeviceCaps(dc, LOGPIXELSY), 72);
ReleaseDC(NULL, dc);
}
me2->Font = CreateFont(-char_height, 0, 0, 0, bold ? FW_BOLD : FW_NORMAL, italic ? TRUE : FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DRAFT_QUALITY, DEFAULT_PITCH, fontName == NULL ? L"Meiryo UI" : reinterpret_cast<const Char*>(fontName + 0x10));
me2->Proportional = proportional;
me2->Advance = advance;
{
BITMAPINFO info = { 0 };
info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
info.bmiHeader.biWidth = static_cast<LONG>(FontBitmapSize);
info.bmiHeader.biHeight = -static_cast<LONG>(FontBitmapSize);
info.bmiHeader.biPlanes = 1;
info.bmiHeader.biBitCount = 24;
info.bmiHeader.biCompression = BI_RGB;
HDC dc = GetDC(NULL);
me2->Bitmap = CreateDIBSection(dc, &info, DIB_RGB_COLORS, reinterpret_cast<void**>(&me2->Pixel), NULL, 0);
me2->Dc = CreateCompatibleDC(dc);
ReleaseDC(NULL, dc);
}
{
HGDIOBJ old_font = SelectObject(me2->Dc, static_cast<HGDIOBJ>(me2->Font));
TEXTMETRIC tm;
GetTextMetrics(me2->Dc, &tm);
me2->CellWidth = tm.tmMaxCharWidth;
me2->CellHeight = tm.tmHeight;
SelectObject(me2->Dc, old_font);
}
me2->CellSizeAligned = 128; // Texture length must not be less than 128.
while (me2->CellSizeAligned < me2->CellWidth + 1 || me2->CellSizeAligned < me2->CellHeight + 1)
me2->CellSizeAligned *= 2;
{
D3D11_TEXTURE2D_DESC desc;
desc.Width = static_cast<UINT>(me2->CellSizeAligned);
desc.Height = static_cast<UINT>(me2->CellSizeAligned);
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8_UNORM;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
if (FAILED(Device->CreateTexture2D(&desc, NULL, &me2->Tex)))
THROW(0xe9170009);
}
{
D3D11_SHADER_RESOURCE_VIEW_DESC desc;
memset(&desc, 0, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
desc.Format = DXGI_FORMAT_R8_UNORM;
desc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D;
desc.Texture2D.MostDetailedMip = 0;
desc.Texture2D.MipLevels = 1;
if (FAILED(Device->CreateShaderResourceView(me2->Tex, &desc, &me2->View)))
THROW(0xe9170009);
}
size_t buf_size = static_cast<size_t>((FontBitmapSize / me2->CellWidth) * (FontBitmapSize / me2->CellHeight));
ASSERT(buf_size != 0);
me2->CharMap = static_cast<Char*>(AllocMem(sizeof(Char) * buf_size));
me2->CntMap = static_cast<U32*>(AllocMem(sizeof(U32) * buf_size));
me2->GlyphWidth = static_cast<int*>(AllocMem(sizeof(int) * buf_size));
for (size_t i = 0; i < buf_size; i++)
me2->GlyphWidth[i] = 0;
for (size_t i = 0; i < buf_size; i++)
{
me2->CharMap[i] = L'\0';
me2->CntMap[i] = 0;
}
me2->Cnt = 0;
return me_;
}
EXPORT_CPP void _fontDtor(SClass* me_)
{
SFont* me2 = reinterpret_cast<SFont*>(me_);
DeleteDC(me2->Dc);
DeleteObject(static_cast<HGDIOBJ>(me2->Bitmap));
if (me2->GlyphWidth != NULL)
FreeMem(me2->GlyphWidth);
FreeMem(me2->CntMap);
FreeMem(me2->CharMap);
if (me2->View != NULL)
me2->View->Release();
if (me2->Tex != NULL)
me2->Tex->Release();
}
EXPORT_CPP void _fontDraw(SClass* me_, double dstX, double dstY, const U8* text, S64 color)
{
THROWDBG(text == NULL, 0xc0000005);
double r, g, b, a;
Draw::ColorToArgb(&a, &r, &g, &b, color);
if (a <= DiscardAlpha)
return;
SFont* me2 = reinterpret_cast<SFont*>(me_);
S64 len = *reinterpret_cast<const S64*>(text + 0x08);
const Char* ptr = reinterpret_cast<const Char*>(text + 0x10);
int cell_num_width = FontBitmapSize / me2->CellWidth;
int cell_num = cell_num_width * (FontBitmapSize / me2->CellHeight);
me2->Cnt++;
if (me2->Cnt == 0)
{
for (int i = 0; i < cell_num; i++)
me2->CntMap[i] = 0;
}
double x = dstX;
for (S64 i = 0; i < len; i++)
{
int pos = -1;
for (int j = 0; j < cell_num; j++)
{
if (me2->CharMap[j] == *ptr)
{
pos = j;
break;
}
}
if (pos == -1)
{
U32 min = 0xffffffff;
for (int j = 0; j < cell_num; j++)
{
if (me2->CharMap[j] == L'\0')
{
pos = j;
break;
}
if (min > static_cast<S64>(me2->CntMap[j]))
{
min = static_cast<S64>(me2->CntMap[j]);
pos = j;
}
}
{
HGDIOBJ old_bitmap = SelectObject(me2->Dc, static_cast<HGDIOBJ>(me2->Bitmap));
HGDIOBJ old_font = SelectObject(me2->Dc, static_cast<HGDIOBJ>(me2->Font));
SetBkMode(me2->Dc, OPAQUE);
SetBkColor(me2->Dc, RGB(0, 0, 0));
SetTextColor(me2->Dc, RGB(255, 255, 255));
RECT rect;
rect.left = static_cast<LONG>((pos % cell_num_width) * me2->CellWidth);
rect.top = static_cast<LONG>((pos / cell_num_width) * me2->CellHeight);
rect.right = rect.left + static_cast<LONG>(me2->CellWidth);
rect.bottom = rect.top + static_cast<LONG>(me2->CellHeight);
ExtTextOut(me2->Dc, static_cast<int>(rect.left), static_cast<int>(rect.top), ETO_CLIPPED | ETO_OPAQUE, &rect, ptr, 1, NULL);
{
GLYPHMETRICS gm;
MAT2 mat = { { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, 1 } };
GetGlyphOutline(me2->Dc, static_cast<UINT>(*ptr), GGO_METRICS, &gm, 0, NULL, &mat);
me2->GlyphWidth[pos] = static_cast<int>(gm.gmCellIncX);
}
SelectObject(me2->Dc, old_font);
SelectObject(me2->Dc, old_bitmap);
}
me2->CharMap[pos] = *ptr;
me2->CntMap[pos] = me2->Cnt;
}
{
D3D11_MAPPED_SUBRESOURCE map;
DeviceContext->Map(me2->Tex, D3D11CalcSubresource(0, 0, 1), D3D11_MAP_WRITE_DISCARD, 0, &map);
U8* dst = static_cast<U8*>(map.pData);
for (int j = 0; j < me2->CellHeight; j++)
{
int begin = ((pos / cell_num_width) * me2->CellHeight + j) * FontBitmapSize + (pos % cell_num_width) * me2->CellWidth;
for (int k = 0; k < me2->CellWidth; k++)
dst[j * me2->CellSizeAligned + k] = me2->Pixel[(begin + k) * 3];
dst[j * me2->CellSizeAligned + me2->CellWidth] = 0;
}
{
int j = me2->CellHeight;
for (int k = 0; k < me2->CellWidth + 1; k++)
dst[j * me2->CellSizeAligned + k] = 0;
}
DeviceContext->Unmap(me2->Tex, D3D11CalcSubresource(0, 0, 1));
}
double half_space = 0.0;
if (!me2->Proportional)
half_space = floor((me2->Advance - static_cast<double>(me2->GlyphWidth[pos])) / 2.0);
{
{
float const_buf_vs[8] =
{
static_cast<float>(half_space + x) / static_cast<float>(CurWndBuf->ScreenWidth) * 2.0f - 1.0f,
-(static_cast<float>(dstY) / static_cast<float>(CurWndBuf->ScreenHeight) * 2.0f - 1.0f),
static_cast<float>(me2->CellWidth) / static_cast<float>(CurWndBuf->ScreenWidth) * 2.0f,
-(static_cast<float>(me2->CellHeight) / static_cast<float>(CurWndBuf->ScreenHeight) * 2.0f),
0.0f,
0.0f,
static_cast<float>(me2->CellWidth) / static_cast<float>(me2->CellSizeAligned),
-(static_cast<float>(me2->CellHeight) / static_cast<float>(me2->CellSizeAligned)),
};
float const_buf_ps[4] =
{
static_cast<float>(r),
static_cast<float>(g),
static_cast<float>(b),
static_cast<float>(a),
};
Draw::ConstBuf(TexVs, const_buf_vs);
DeviceContext->GSSetShader(NULL, NULL, 0);
Draw::ConstBuf(FontPs, const_buf_ps);
Draw::VertexBuf(RectVertex);
DeviceContext->PSSetShaderResources(0, 1, &me2->View);
}
DeviceContext->DrawIndexed(6, 0, 0);
}
x += me2->Advance;
if (me2->Proportional)
x += static_cast<double>(me2->GlyphWidth[pos]);
ptr++;
}
}
EXPORT_CPP double _fontMaxWidth(SClass* me_)
{
return reinterpret_cast<SFont*>(me_)->CellWidth;
}
EXPORT_CPP double _fontMaxHeight(SClass* me_)
{
return reinterpret_cast<SFont*>(me_)->CellHeight;
}
EXPORT_CPP double _fontCalcWidth(SClass* me_, const U8* text)
{
THROWDBG(text == NULL, 0xc0000005);
SFont* me2 = reinterpret_cast<SFont*>(me_);
S64 len = *reinterpret_cast<const S64*>(text + 0x08);
double x = me2->Advance * static_cast<double>(len);
if (me2->Proportional)
{
const Char* ptr = reinterpret_cast<const Char*>(text + 0x10);
HGDIOBJ old_font = SelectObject(me2->Dc, static_cast<HGDIOBJ>(me2->Font));
for (S64 i = 0; i < len; i++)
{
SIZE size;
GetTextExtentPoint32(me2->Dc, ptr, 1, &size);
x += static_cast<double>(size.cx);
ptr++;
}
SelectObject(me2->Dc, old_font);
}
return x;
}
EXPORT_CPP void _camera(double eyeX, double eyeY, double eyeZ, double atX, double atY, double atZ, double upX, double upY, double upZ)
{
double look[3], up[3], right[3], eye[3], pxyz[3], eye_len;
look[0] = atX - eyeX;
look[1] = atY - eyeY;
look[2] = atZ - eyeZ;
eye_len = Draw::Normalize(look);
if (eye_len == 0.0)
return;
up[0] = upX;
up[1] = upY;
up[2] = upZ;
Draw::Cross(right, up, look);
if (Draw::Normalize(right) == 0.0)
return;
Draw::Cross(up, look, right);
eye[0] = eyeX;
eye[1] = eyeY;
eye[2] = eyeZ;
pxyz[0] = Draw::Dot(eye, right);
pxyz[1] = Draw::Dot(eye, up);
pxyz[2] = Draw::Dot(eye, look);
ViewMat[0][0] = right[0];
ViewMat[0][1] = up[0];
ViewMat[0][2] = look[0];
ViewMat[0][3] = 0.0;
ViewMat[1][0] = right[1];
ViewMat[1][1] = up[1];
ViewMat[1][2] = look[1];
ViewMat[1][3] = 0.0;
ViewMat[2][0] = right[2];
ViewMat[2][1] = up[2];
ViewMat[2][2] = look[2];
ViewMat[2][3] = 0.0;
ViewMat[3][0] = -pxyz[0];
ViewMat[3][1] = -pxyz[1];
ViewMat[3][2] = -pxyz[2];
ViewMat[3][3] = 1.0;
ObjVsConstBuf.CommonParam.Eye[0] = static_cast<float>(eyeX);
ObjVsConstBuf.CommonParam.Eye[1] = static_cast<float>(eyeY);
ObjVsConstBuf.CommonParam.Eye[2] = static_cast<float>(eyeZ);
ObjVsConstBuf.CommonParam.Eye[3] = static_cast<float>(eye_len);
Draw::SetProjViewMat(ObjVsConstBuf.CommonParam.ProjView, ProjMat, ViewMat);
}
EXPORT_CPP void _proj(double fovy, double aspectX, double aspectY, double nearZ, double farZ)
{
THROWDBG(fovy <= 0.0 || M_PI / 2.0 <= fovy || aspectX <= 0.0 || aspectY <= 0.0 || nearZ <= 0.0 || farZ <= nearZ, 0xe9170006);
double tan_theta = tan(fovy / 2.0);
ProjMat[0][0] = -1.0 / ((aspectX / aspectY) * tan_theta);
ProjMat[0][1] = 0.0;
ProjMat[0][2] = 0.0;
ProjMat[0][3] = 0.0;
ProjMat[1][0] = 0.0;
ProjMat[1][1] = 1.0 / tan_theta;
ProjMat[1][2] = 0.0;
ProjMat[1][3] = 0.0;
ProjMat[2][0] = 0.0;
ProjMat[2][1] = 0.0;
ProjMat[2][2] = farZ / (farZ - nearZ);
ProjMat[2][3] = 1.0;
ProjMat[3][0] = 0.0;
ProjMat[3][1] = 0.0;
ProjMat[3][2] = -farZ * nearZ / (farZ - nearZ);
ProjMat[3][3] = 0.0;
Draw::SetProjViewMat(ObjVsConstBuf.CommonParam.ProjView, ProjMat, ViewMat);
}
EXPORT_CPP SClass* _makeObj(SClass* me_, const U8* path)
{
SObj* me2 = (SObj*)me_;
me2->ElementKinds = NULL;
me2->Elements = NULL;
Draw::IdentityFloat(me2->Mat);
Draw::IdentityFloat(me2->NormMat);
{
Bool correct = True;
U8* buf = NULL;
U32* idces = NULL;
U8* vertices = NULL;
for (; ; )
{
size_t size;
size_t ptr = 0;
buf = static_cast<U8*>(LoadFileAll(reinterpret_cast<const Char*>(path + 0x10), &size));
if (buf == NULL)
{
THROW(0xe9170007);
return NULL;
}
if (ptr + sizeof(int) > size)
{
correct = False;
break;
}
me2->ElementNum = *reinterpret_cast<const int*>(buf + ptr);
ptr += sizeof(int);
if (me2->ElementNum < 0)
{
correct = False;
break;
}
me2->ElementKinds = static_cast<int*>(AllocMem(sizeof(int) * static_cast<size_t>(me2->ElementNum)));
me2->Elements = static_cast<void**>(AllocMem(sizeof(void*) * static_cast<size_t>(me2->ElementNum)));
for (int i = 0; i < me2->ElementNum; i++)
{
if (ptr + sizeof(int) > size)
{
correct = False;
break;
}
me2->ElementKinds[i] = *reinterpret_cast<const int*>(buf + ptr);
ptr += sizeof(int);
switch (me2->ElementKinds[i])
{
case 0: // Polygon.
{
SObj::SPolygon* element = static_cast<SObj::SPolygon*>(AllocMem(sizeof(SObj::SPolygon)));
element->VertexBuf = NULL;
element->Joints = NULL;
me2->Elements[i] = element;
if (ptr + sizeof(int) > size)
{
correct = False;
break;
}
element->VertexNum = *reinterpret_cast<const int*>(buf + ptr);
ptr += sizeof(int);
idces = static_cast<U32*>(AllocMem(sizeof(U32) * static_cast<size_t>(element->VertexNum)));
if (ptr + sizeof(U32) * static_cast<size_t>(element->VertexNum) > size)
{
correct = False;
break;
}
for (int j = 0; j < element->VertexNum; j++)
{
idces[j] = *reinterpret_cast<const U32*>(buf + ptr);
ptr += sizeof(U32);
}
if (ptr + sizeof(int) > size)
{
correct = False;
break;
}
int idx_num = *reinterpret_cast<const int*>(buf + ptr);
ptr += sizeof(int);
vertices = static_cast<U8*>(AllocMem((sizeof(float) * 15 + sizeof(int) * 4) * static_cast<size_t>(idx_num)));
U8* ptr2 = vertices;
if (ptr + (sizeof(float) * 15 + sizeof(int) * 4) * static_cast<size_t>(idx_num) > size)
{
correct = False;
break;
}
for (int j = 0; j < idx_num; j++)
{
for (int k = 0; k < 15; k++)
{
*reinterpret_cast<float*>(ptr2) = *reinterpret_cast<const float*>(buf + ptr);
ptr += sizeof(float);
ptr2 += sizeof(float);
}
for (int k = 0; k < 4; k++)
{
*reinterpret_cast<int*>(ptr2) = *reinterpret_cast<const int*>(buf + ptr);
ptr += sizeof(int);
ptr2 += sizeof(int);
}
}
element->VertexBuf = Draw::MakeVertexBuf((sizeof(float) * 15 + sizeof(int) * 4) * static_cast<size_t>(idx_num), vertices, sizeof(float) * 15 + sizeof(int) * 4, sizeof(U32) * static_cast<size_t>(element->VertexNum), idces);
if (ptr + sizeof(int) * 3 > size)
{
correct = False;
break;
}
element->JointNum = *reinterpret_cast<int*>(buf + ptr);
ptr += sizeof(int);
element->Begin = *reinterpret_cast<int*>(buf + ptr);
ptr += sizeof(int);
element->End = *reinterpret_cast<int*>(buf + ptr);
ptr += sizeof(int);
element->Joints = static_cast<float(*)[4][4]>(AllocMem(sizeof(float[4][4]) * static_cast<size_t>(element->JointNum * (element->End - element->Begin + 1))));
if (ptr + sizeof(float[4][4]) * static_cast<size_t>(element->JointNum * (element->End - element->Begin + 1)) > size)
{
correct = False;
break;
}
for (int j = 0; j < element->JointNum; j++)
{
for (int k = 0; k < element->End - element->Begin + 1; k++)
{
for (int l = 0; l < 4; l++)
{
for (int m = 0; m < 4; m++)
{
element->Joints[j * (element->End - element->Begin + 1) + k][l][m] = *reinterpret_cast<float*>(buf + ptr);
ptr += sizeof(float);
}
}
}
}
}
break;
default:
THROW(0xe9170008);
break;
}
if (!correct)
break;
}
break;
}
if (vertices != NULL)
FreeMem(vertices);
if (idces != NULL)
FreeMem(idces);
if (buf != NULL)
FreeMem(buf);
if (!correct)
{
_objDtor(me_);
THROW(0xe9170008);
return NULL;
}
}
return me_;
}
EXPORT_CPP void _objDtor(SClass* me_)
{
SObj* me2 = reinterpret_cast<SObj*>(me_);
for (int i = 0; i < me2->ElementNum; i++)
{
switch (me2->ElementKinds[i])
{
case 0: // Polygon.
{
SObj::SPolygon* element = static_cast<SObj::SPolygon*>(me2->Elements[i]);
if (element->Joints != NULL)
FreeMem(element->Joints);
if (element->VertexBuf != NULL)
Draw::FinVertexBuf(element->VertexBuf);
FreeMem(element);
}
break;
default:
ASSERT(False);
break;
}
}
if (me2->Elements != NULL)
FreeMem(me2->Elements);
if (me2->ElementKinds != NULL)
FreeMem(me2->ElementKinds);
}
EXPORT_CPP SClass* _makeBox(SClass* me_, double w, double h, double d, S64 color)
{
double r, g, b, a;
Draw::ColorToArgb(&a, &r, &g, &b, color);
// TODO:
return NULL;
}
EXPORT_CPP void _objDraw(SClass* me_, S64 element, double frame, SClass* diffuse, SClass* specular, SClass* normal)
{
SObj* me2 = (SObj*)me_;
THROWDBG(element < 0 || static_cast<S64>(me2->ElementNum) <= element, 0xe9170006);
switch (me2->ElementKinds[element])
{
case 0: // Polygon.
{
SObj::SPolygon* element2 = static_cast<SObj::SPolygon*>(me2->Elements[element]);
THROWDBG(frame < static_cast<double>(element2->Begin) || element2->End < static_cast<int>(frame), 0xe9170006);
THROWDBG(element2->JointNum < 0 || JointMax < element2->JointNum, 0xe9170006);
Bool joint = element2->JointNum != 0;
memcpy(ObjVsConstBuf.CommonParam.World, me2->Mat, sizeof(float[4][4]));
memcpy(ObjVsConstBuf.CommonParam.NormWorld, me2->NormMat, sizeof(float[4][4]));
if (joint && frame >= 0.0f)
{
Draw::SetJointMat(element2, frame, ObjVsConstBuf.Joint);
Draw::ConstBuf(ObjJointVs, &ObjVsConstBuf);
}
else
Draw::ConstBuf(ObjVs, &ObjVsConstBuf);
DeviceContext->GSSetShader(NULL, NULL, 0);
Draw::ConstBuf(ObjPs, &ObjPsConstBuf);
Draw::VertexBuf(element2->VertexBuf);
DeviceContext->PSSetShaderResources(0, 1, diffuse == NULL ? &ViewEven[0] : &reinterpret_cast<STex*>(diffuse)->View);
DeviceContext->PSSetShaderResources(1, 1, specular == NULL ? &ViewEven[1] : &reinterpret_cast<STex*>(specular)->View);
DeviceContext->PSSetShaderResources(2, 1, normal == NULL ? &ViewEven[2] : &reinterpret_cast<STex*>(normal)->View);
DeviceContext->DrawIndexed(static_cast<UINT>(element2->VertexNum), 0, 0);
}
break;
}
}
EXPORT_CPP void _objDrawToon(SClass* me_, S64 element, double frame, SClass* diffuse, SClass* specular, SClass* normal)
{
SObj* me2 = (SObj*)me_;
THROWDBG(element < 0 || static_cast<S64>(me2->ElementNum) <= element, 0xe9170006);
switch (me2->ElementKinds[element])
{
case 0: // Polygon.
{
SObj::SPolygon* element2 = static_cast<SObj::SPolygon*>(me2->Elements[element]);
THROWDBG(frame < static_cast<double>(element2->Begin) || element2->End < static_cast<int>(frame), 0xe9170006);
THROWDBG(element2->JointNum < 0 || JointMax < element2->JointNum, 0xe9170006);
Bool joint = element2->JointNum != 0;
memcpy(ObjVsConstBuf.CommonParam.World, me2->Mat, sizeof(float[4][4]));
memcpy(ObjVsConstBuf.CommonParam.NormWorld, me2->NormMat, sizeof(float[4][4]));
if (joint && frame >= 0.0f)
{
Draw::SetJointMat(element2, frame, ObjVsConstBuf.Joint);
Draw::ConstBuf(ObjJointVs, &ObjVsConstBuf);
}
else
Draw::ConstBuf(ObjVs, &ObjVsConstBuf);
DeviceContext->GSSetShader(NULL, NULL, 0);
Draw::ConstBuf(ObjToonPs, &ObjPsConstBuf);
Draw::VertexBuf(element2->VertexBuf);
DeviceContext->PSSetShaderResources(0, 1, diffuse == NULL ? &ViewEven[0] : &reinterpret_cast<STex*>(diffuse)->View);
DeviceContext->PSSetShaderResources(1, 1, specular == NULL ? &ViewEven[1] : &reinterpret_cast<STex*>(specular)->View);
DeviceContext->PSSetShaderResources(2, 1, normal == NULL ? &ViewEven[2] : &reinterpret_cast<STex*>(normal)->View);
DeviceContext->PSSetShaderResources(3, 1, &ViewToonRamp);
DeviceContext->DrawIndexed(static_cast<UINT>(element2->VertexNum), 0, 0);
}
break;
}
}
EXPORT_CPP void _objDrawOutline(SClass* me_, S64 element, double frame, double width, S64 color)
{
SObj* me2 = (SObj*)me_;
THROWDBG(element < 0 || static_cast<S64>(me2->ElementNum) <= element, 0xe9170006);
switch (me2->ElementKinds[element])
{
case 0: // Polygon.
{
SObj::SPolygon* element2 = static_cast<SObj::SPolygon*>(me2->Elements[element]);
THROWDBG(frame < static_cast<double>(element2->Begin) || element2->End < static_cast<int>(frame), 0xe9170006);
THROWDBG(element2->JointNum < 0 || JointMax < element2->JointNum, 0xe9170006);
Bool joint = element2->JointNum != 0;
SObjOutlineVsConstBuf vs_const_buf;
SObjOutlinePsConstBuf ps_const_buf;
vs_const_buf.CommonParam = ObjVsConstBuf.CommonParam;
vs_const_buf.OutlineParam[0] = static_cast<float>(width);
{
double r, g, b, a;
Draw::ColorToArgb(&a, &r, &g, &b, color);
ps_const_buf.OutlineColor[0] = static_cast<float>(r);
ps_const_buf.OutlineColor[1] = static_cast<float>(g);
ps_const_buf.OutlineColor[2] = static_cast<float>(b);
ps_const_buf.OutlineColor[3] = static_cast<float>(a);
}
if (joint && frame >= 0.0f)
{
Draw::SetJointMat(element2, frame, vs_const_buf.Joint);
Draw::ConstBuf(ObjOutlineJointVs, &vs_const_buf);
}
else
Draw::ConstBuf(ObjOutlineVs, &vs_const_buf);
DeviceContext->GSSetShader(NULL, NULL, 0);
DeviceContext->RSSetState(RasterizerStateInverted);
Draw::ConstBuf(ObjOutlinePs, &ps_const_buf);
Draw::VertexBuf(element2->VertexBuf);
DeviceContext->DrawIndexed(static_cast<UINT>(element2->VertexNum), 0, 0);
DeviceContext->RSSetState(RasterizerState);
}
break;
}
}
EXPORT_CPP void _objMat(SClass* me_, const U8* mat, const U8* normMat)
{
SObj* me2 = (SObj*)me_;
THROWDBG(*(S64*)(mat + 0x08) != 16 || *(S64*)(normMat + 0x08) != 16, 0xe9170006);
{
const double* ptr = reinterpret_cast<const double*>(mat + 0x10);
me2->Mat[0][0] = static_cast<float>(ptr[0]);
me2->Mat[0][1] = static_cast<float>(ptr[1]);
me2->Mat[0][2] = static_cast<float>(ptr[2]);
me2->Mat[0][3] = static_cast<float>(ptr[3]);
me2->Mat[1][0] = static_cast<float>(ptr[4]);
me2->Mat[1][1] = static_cast<float>(ptr[5]);
me2->Mat[1][2] = static_cast<float>(ptr[6]);
me2->Mat[1][3] = static_cast<float>(ptr[7]);
me2->Mat[2][0] = static_cast<float>(ptr[8]);
me2->Mat[2][1] = static_cast<float>(ptr[9]);
me2->Mat[2][2] = static_cast<float>(ptr[10]);
me2->Mat[2][3] = static_cast<float>(ptr[11]);
me2->Mat[3][0] = static_cast<float>(ptr[12]);
me2->Mat[3][1] = static_cast<float>(ptr[13]);
me2->Mat[3][2] = static_cast<float>(ptr[14]);
me2->Mat[3][3] = static_cast<float>(ptr[15]);
}
{
const double* ptr = reinterpret_cast<const double*>(normMat + 0x10);
me2->NormMat[0][0] = static_cast<float>(ptr[0]);
me2->NormMat[0][1] = static_cast<float>(ptr[1]);
me2->NormMat[0][2] = static_cast<float>(ptr[2]);
me2->NormMat[0][3] = static_cast<float>(ptr[3]);
me2->NormMat[1][0] = static_cast<float>(ptr[4]);
me2->NormMat[1][1] = static_cast<float>(ptr[5]);
me2->NormMat[1][2] = static_cast<float>(ptr[6]);
me2->NormMat[1][3] = static_cast<float>(ptr[7]);
me2->NormMat[2][0] = static_cast<float>(ptr[8]);
me2->NormMat[2][1] = static_cast<float>(ptr[9]);
me2->NormMat[2][2] = static_cast<float>(ptr[10]);
me2->NormMat[2][3] = static_cast<float>(ptr[11]);
me2->NormMat[3][0] = static_cast<float>(ptr[12]);
me2->NormMat[3][1] = static_cast<float>(ptr[13]);
me2->NormMat[3][2] = static_cast<float>(ptr[14]);
me2->NormMat[3][3] = static_cast<float>(ptr[15]);
}
}
EXPORT_CPP void _objPos(SClass* me_, double scaleX, double scaleY, double scaleZ, double rotX, double rotY, double rotZ, double transX, double transY, double transZ)
{
SObj* me2 = (SObj*)me_;
double cos_x = cos(rotX);
double sin_x = sin(rotX);
double cos_y = cos(rotY);
double sin_y = sin(rotY);
double cos_z = cos(rotZ);
double sin_z = sin(rotZ);
me2->Mat[0][0] = static_cast<float>(scaleX * (cos_y * cos_z));
me2->Mat[0][1] = static_cast<float>(scaleX * (cos_y * sin_z));
me2->Mat[0][2] = static_cast<float>(scaleX * (-sin_y));
me2->Mat[0][3] = 0.0f;
me2->Mat[1][0] = static_cast<float>(scaleY * (sin_x * sin_y * cos_z - cos_x * sin_z));
me2->Mat[1][1] = static_cast<float>(scaleY * (sin_x * sin_y * sin_z + cos_x * cos_z));
me2->Mat[1][2] = static_cast<float>(scaleY * (sin_x * cos_y));
me2->Mat[1][3] = 0.0f;
me2->Mat[2][0] = static_cast<float>(scaleZ * (cos_x * sin_y * cos_z + sin_x * sin_z));
me2->Mat[2][1] = static_cast<float>(scaleZ * (cos_x * sin_y * sin_z - sin_x * cos_z));
me2->Mat[2][2] = static_cast<float>(scaleZ * (cos_x * cos_y));
me2->Mat[2][3] = 0.0f;
me2->Mat[3][0] = static_cast<float>(transX);
me2->Mat[3][1] = static_cast<float>(transY);
me2->Mat[3][2] = static_cast<float>(transZ);
me2->Mat[3][3] = 1.0f;
scaleX = 1.0 / scaleX;
scaleY = 1.0 / scaleY;
scaleZ = 1.0 / scaleZ;
me2->NormMat[0][0] = static_cast<float>(scaleX * (cos_y * cos_z));
me2->NormMat[0][1] = static_cast<float>(scaleX * (cos_y * sin_z));
me2->NormMat[0][2] = static_cast<float>(scaleX * (-sin_y));
me2->NormMat[0][3] = 0.0f;
me2->NormMat[1][0] = static_cast<float>(scaleY * (sin_x * sin_y * cos_z - cos_x * sin_z));
me2->NormMat[1][1] = static_cast<float>(scaleY * (sin_x * sin_y * sin_z + cos_x * cos_z));
me2->NormMat[1][2] = static_cast<float>(scaleY * (sin_x * cos_y));
me2->NormMat[1][3] = 0.0f;
me2->NormMat[2][0] = static_cast<float>(scaleZ * (cos_x * sin_y * cos_z + sin_x * sin_z));
me2->NormMat[2][1] = static_cast<float>(scaleZ * (cos_x * sin_y * sin_z - sin_x * cos_z));
me2->NormMat[2][2] = static_cast<float>(scaleZ * (cos_x * cos_y));
me2->NormMat[2][3] = 0.0f;
me2->NormMat[3][0] = 0.0f;
me2->NormMat[3][1] = 0.0f;
me2->NormMat[3][2] = 0.0f;
me2->NormMat[3][3] = 1.0f;
}
EXPORT_CPP void _objLook(SClass* me_, double x, double y, double z, double atX, double atY, double atZ, double upX, double upY, double upZ, Bool fixUp)
{
SObj* me2 = (SObj*)me_;
double at[3] = { atX - x, atY - y, atZ - z }, up[3] = { upX, upY, upZ }, right[3];
if (Draw::Normalize(at) == 0.0)
return;
if (Draw::Normalize(up) == 0.0)
return;
Draw::Cross(right, up, at);
if (Draw::Normalize(right) == 0.0)
return;
if (fixUp)
Draw::Cross(up, at, right);
else
Draw::Cross(at, right, up);
me2->Mat[0][0] = static_cast<float>(right[0]);
me2->Mat[0][1] = static_cast<float>(right[1]);
me2->Mat[0][2] = static_cast<float>(right[2]);
me2->Mat[0][3] = 0.0f;
me2->Mat[1][0] = static_cast<float>(up[0]);
me2->Mat[1][1] = static_cast<float>(up[1]);
me2->Mat[1][2] = static_cast<float>(up[2]);
me2->Mat[1][3] = 0.0f;
me2->Mat[2][0] = static_cast<float>(at[0]);
me2->Mat[2][1] = static_cast<float>(at[1]);
me2->Mat[2][2] = static_cast<float>(at[2]);
me2->Mat[2][3] = 0.0f;
me2->Mat[3][0] = static_cast<float>(x);
me2->Mat[3][1] = static_cast<float>(y);
me2->Mat[3][2] = static_cast<float>(z);
me2->Mat[3][3] = 1.0f;
me2->NormMat[0][0] = static_cast<float>(right[0]);
me2->NormMat[0][1] = static_cast<float>(right[1]);
me2->NormMat[0][2] = static_cast<float>(right[2]);
me2->NormMat[0][3] = 0.0f;
me2->NormMat[1][0] = static_cast<float>(up[0]);
me2->NormMat[1][1] = static_cast<float>(up[1]);
me2->NormMat[1][2] = static_cast<float>(up[2]);
me2->NormMat[1][3] = 0.0f;
me2->NormMat[2][0] = static_cast<float>(at[0]);
me2->NormMat[2][1] = static_cast<float>(at[1]);
me2->NormMat[2][2] = static_cast<float>(at[2]);
me2->NormMat[2][3] = 0.0f;
me2->NormMat[3][0] = 0.0f;
me2->NormMat[3][1] = 0.0f;
me2->NormMat[3][2] = 0.0f;
me2->NormMat[3][3] = 1.0f;
}
EXPORT_CPP void _objLookCamera(SClass* me_, double x, double y, double z, double upX, double upY, double upZ, Bool fixUp)
{
_objLook(me_, x, y, z, static_cast<double>(ObjVsConstBuf.CommonParam.Eye[0]), static_cast<double>(ObjVsConstBuf.CommonParam.Eye[1]), static_cast<double>(ObjVsConstBuf.CommonParam.Eye[2]), upX, upY, upZ, fixUp);
}
EXPORT_CPP void _ambLight(double topR, double topG, double topB, double bottomR, double bottomG, double bottomB)
{
ObjPsConstBuf.CommonParam.AmbTopColor[0] = static_cast<float>(topR);
ObjPsConstBuf.CommonParam.AmbTopColor[1] = static_cast<float>(topG);
ObjPsConstBuf.CommonParam.AmbTopColor[2] = static_cast<float>(topB);
ObjPsConstBuf.CommonParam.AmbBottomColor[0] = static_cast<float>(bottomR);
ObjPsConstBuf.CommonParam.AmbBottomColor[1] = static_cast<float>(bottomG);
ObjPsConstBuf.CommonParam.AmbBottomColor[2] = static_cast<float>(bottomB);
}
EXPORT_CPP void _dirLight(double atX, double atY, double atZ, double r, double g, double b)
{
double dir[3] = { atX, atY, atZ };
Draw::Normalize(dir);
ObjVsConstBuf.CommonParam.Dir[0] = -static_cast<float>(dir[0]);
ObjVsConstBuf.CommonParam.Dir[1] = -static_cast<float>(dir[1]);
ObjVsConstBuf.CommonParam.Dir[2] = -static_cast<float>(dir[2]);
ObjPsConstBuf.CommonParam.DirColor[0] = static_cast<float>(r);
ObjPsConstBuf.CommonParam.DirColor[1] = static_cast<float>(g);
ObjPsConstBuf.CommonParam.DirColor[2] = static_cast<float>(b);
}
EXPORT_CPP S64 _argbToColor(double a, double r, double g, double b)
{
return Draw::ArgbToColor(a, r, g, b);
}
EXPORT_CPP void _colorToArgb(S64 color, double* a, double* r, double* g, double* b)
{
Draw::ColorToArgb(a, r, g, b, color);
}
namespace Draw
{
void Init()
{
D3D_FEATURE_LEVEL pFeatureLevel;
if (FAILED(D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL,
D3D11_CREATE_DEVICE_SINGLETHREADED,
NULL, 0, D3D11_SDK_VERSION, &Device, &pFeatureLevel, &DeviceContext)))
THROW(0xe9170009);
Cnt = 0;
PrevTime = static_cast<U32>(timeGetTime());
// Create a rasterizer state.
{
D3D11_RASTERIZER_DESC desc;
memset(&desc, 0, sizeof(desc));
desc.FillMode = D3D11_FILL_SOLID;
desc.CullMode = D3D11_CULL_FRONT; // Cull the front in order to exchange the right handed system and the left handed system.
desc.FrontCounterClockwise = FALSE;
desc.DepthBias = 0;
desc.DepthBiasClamp = 0.0f;
desc.SlopeScaledDepthBias = 0.0f;
desc.DepthClipEnable = FALSE;
desc.ScissorEnable = FALSE;
desc.MultisampleEnable = FALSE;
desc.AntialiasedLineEnable = FALSE;
if (FAILED(Device->CreateRasterizerState(&desc, &RasterizerState)))
THROW(0xe9170009);
desc.CullMode = D3D11_CULL_BACK;
if (FAILED(Device->CreateRasterizerState(&desc, &RasterizerStateInverted)))
THROW(0xe9170009);
}
// Create depth buffer modes.
for (int i = 0; i < DepthNum; i++)
{
D3D11_DEPTH_STENCIL_DESC desc;
memset(&desc, 0, sizeof(desc));
desc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL;
desc.StencilEnable = FALSE;
switch (i)
{
// Disable test, disable writing.
case 0:
desc.DepthEnable = FALSE;
desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
break;
// Disable test, enable writing.
case 1:
desc.DepthEnable = FALSE;
desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
break;
// Enable test, disable writing.
case 2:
desc.DepthEnable = TRUE;
desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
break;
// Enable test, enable writing.
case 3:
desc.DepthEnable = TRUE;
desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
break;
default:
ASSERT(False);
break;
}
if (FAILED(Device->CreateDepthStencilState(&desc, &DepthState[i])))
THROW(0xe9170009);
}
// Create blend modes.
for (int i = 0; i < BlendNum; i++)
{
D3D11_BLEND_DESC desc;
memset(&desc, 0, sizeof(desc));
desc.AlphaToCoverageEnable = FALSE;
desc.IndependentBlendEnable = FALSE;
desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
switch (i)
{
// None: S * 1 + D * 0.
case 0:
desc.RenderTarget[0].BlendEnable = FALSE;
desc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
desc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO;
desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
break;
// Alpha: S * A + D * (1 - A).
case 1:
desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
break;
// Add: S * A + D * 1.
case 2:
desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
desc.RenderTarget[0].DestBlend = D3D11_BLEND_ONE;
desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
break;
// Sub: S * A - D * 1.
case 3:
desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
desc.RenderTarget[0].DestBlend = D3D11_BLEND_ONE;
desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_REV_SUBTRACT;
break;
// Mul: S * D + D * 0.
case 4:
desc.RenderTarget[0].SrcBlend = D3D11_BLEND_DEST_COLOR;
desc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO;
desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
break;
default:
ASSERT(False);
break;
}
if (FAILED(Device->CreateBlendState(&desc, &BlendState[i])))
THROW(0xe9170009);
}
// Create a sampler.
for (int i = 0; i < SamplerNum; i++)
{
D3D11_SAMPLER_DESC desc;
memset(&desc, 0, sizeof(desc));
switch (i)
{
// Nearest neighbor.
case 0:
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
break;
// Bilinear.
case 1:
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
break;
}
desc.AddressU = D3D11_TEXTURE_ADDRESS_MIRROR;
desc.AddressV = D3D11_TEXTURE_ADDRESS_MIRROR;
desc.AddressW = D3D11_TEXTURE_ADDRESS_MIRROR;
desc.MipLODBias = 0.0f;
desc.MaxAnisotropy = 0;
desc.ComparisonFunc = D3D11_COMPARISON_NEVER;
desc.MinLOD = 0.0f;
desc.MaxLOD = D3D11_FLOAT32_MAX;
if (FAILED(Device->CreateSamplerState(&desc, &Sampler[i])))
THROW(0xe9170009);
}
// Initialize 'Tri'.
{
{
float vertices[] =
{
1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f,
};
U32 idces[] =
{
0, 1, 2,
};
TriVertex = MakeVertexBuf(sizeof(vertices), vertices, sizeof(float) * 3, sizeof(idces), idces);
}
{
ELayoutType layout_types[1] =
{
LayoutType_Float3,
};
const Char* layout_semantics[1] =
{
L"K_WEIGHT",
};
{
size_t size;
const U8* bin = GetTriVsBin(&size);
TriVs = MakeShaderBuf(ShaderKind_Vs, size, bin, sizeof(float) * 8, 1, layout_types, layout_semantics);
}
{
size_t size;
const U8* bin = GetTriPsBin(&size);
TriPs = MakeShaderBuf(ShaderKind_Ps, size, bin, sizeof(float) * 4, 0, NULL, NULL);
}
}
}
// Initialize 'Rect'.
{
{
float vertices[] =
{
0.0, 0.0,
0.0, 1.0,
1.0, 0.0,
1.0, 1.0,
};
U32 idces[] =
{
0, 1, 2,
3, 2, 1,
};
RectVertex = MakeVertexBuf(sizeof(vertices), vertices, sizeof(float) * 2, sizeof(idces), idces);
}
{
float vertices[] =
{
0.0, 0.0,
1.0, 1.0,
};
U32 idces[] =
{
0, 1,
};
LineVertex = MakeVertexBuf(sizeof(vertices), vertices, sizeof(float) * 2, sizeof(idces), idces);
}
{
float vertices[] =
{
0.0, 0.0,
0.0, 1.0,
1.0, 1.0,
1.0, 0.0,
};
U32 idces[] =
{
0, 1,
1, 2,
2, 3,
3, 0,
};
RectLineVertex = MakeVertexBuf(sizeof(vertices), vertices, sizeof(float) * 2, sizeof(idces), idces);
}
{
ELayoutType layout_types[1] =
{
LayoutType_Float2,
};
const Char* layout_semantics[1] =
{
L"K_WEIGHT",
};
{
size_t size;
const U8* bin = GetRectVsBin(&size);
RectVs = MakeShaderBuf(ShaderKind_Vs, size, bin, sizeof(float) * 4, 1, layout_types, layout_semantics);
}
}
}
// Initialize 'Circle'.
if (IsResUsed(UseResFlagsKind_Draw_Circle))
{
{
float vertices[] =
{
-1.0f, -1.0f,
-1.0f, 1.0f,
1.0f, -1.0f,
1.0f, 1.0f,
};
U32 idces[] =
{
0, 1, 2,
3, 2, 1,
};
CircleVertex = MakeVertexBuf(sizeof(vertices), vertices, sizeof(float) * 2, sizeof(idces), idces);
}
{
ELayoutType layout_types[1] =
{
LayoutType_Float2,
};
const Char* layout_semantics[1] =
{
L"K_WEIGHT",
};
{
size_t size;
const U8* bin = GetCircleVsBin(&size);
CircleVs = MakeShaderBuf(ShaderKind_Vs, size, bin, sizeof(float) * 4, 1, layout_types, layout_semantics);
}
{
size_t size;
const U8* bin = GetCirclePsBin(&size);
CirclePs = MakeShaderBuf(ShaderKind_Ps, size, bin, sizeof(float) * 4, 0, NULL, NULL);
}
}
}
// Initialize 'Tex'.
{
{
ELayoutType layout_types[1] =
{
LayoutType_Float2,
};
const Char* layout_semantics[1] =
{
L"K_WEIGHT",
};
{
size_t size;
const U8* bin = GetTexVsBin(&size);
TexVs = MakeShaderBuf(ShaderKind_Vs, size, bin, sizeof(float) * 8, 1, layout_types, layout_semantics);
}
{
size_t size;
const U8* bin = GetTexRotVsBin(&size);
TexRotVs = MakeShaderBuf(ShaderKind_Vs, size, bin, sizeof(float) * 16, 1, layout_types, layout_semantics);
}
{
size_t size;
const U8* bin = GetTexPsBin(&size);
TexPs = MakeShaderBuf(ShaderKind_Ps, size, bin, sizeof(float) * 4, 0, NULL, NULL);
}
{
size_t size;
const U8* bin = GetFontPsBin(&size);
FontPs = MakeShaderBuf(ShaderKind_Ps, size, bin, sizeof(float) * 4, 0, NULL, NULL);
}
}
}
// Initialize 'Obj'.
{
{
ELayoutType layout_types[5] =
{
LayoutType_Float3,
LayoutType_Float3,
LayoutType_Float3,
LayoutType_Float2,
};
const Char* layout_semantics[5] =
{
L"POSITION",
L"NORMAL",
L"TANGENT",
L"TEXCOORD",
};
{
size_t size;
const U8* bin = GetObjVsBin(&size);
ObjVs = MakeShaderBuf(ShaderKind_Vs, size, bin, sizeof(SObjVsConstBuf) - sizeof(SObjVsConstBuf::Joint), 4, layout_types, layout_semantics);
}
{
size_t size;
const U8* bin = GetObjPsBin(&size);
ObjPs = MakeShaderBuf(ShaderKind_Ps, size, bin, sizeof(SObjPsConstBuf), 0, NULL, NULL);
}
{
size_t size;
const U8* bin = GetObjToonPsBin(&size);
ObjToonPs = MakeShaderBuf(ShaderKind_Ps, size, bin, sizeof(SObjPsConstBuf), 0, NULL, NULL);
}
}
{
ELayoutType layout_types[7] =
{
LayoutType_Float3,
LayoutType_Float3,
LayoutType_Float3,
LayoutType_Float2,
LayoutType_Float4,
LayoutType_Int4,
};
const Char* layout_semantics[7] =
{
L"POSITION",
L"NORMAL",
L"TANGENT",
L"TEXCOORD",
L"K_WEIGHT",
L"K_JOINT",
};
{
size_t size;
const U8* bin = GetObjJointVsBin(&size);
ObjJointVs = MakeShaderBuf(ShaderKind_Vs, size, bin, sizeof(SObjVsConstBuf), 6, layout_types, layout_semantics);
}
}
}
// Initialize 'ObjOutline'.
{
{
ELayoutType layout_types[5] =
{
LayoutType_Float3,
LayoutType_Float3,
LayoutType_Float3,
LayoutType_Float2,
};
const Char* layout_semantics[5] =
{
L"POSITION",
L"NORMAL",
L"TANGENT",
L"TEXCOORD",
};
{
size_t size;
const U8* bin = GetObjOutlineVsBin(&size);
ObjOutlineVs = MakeShaderBuf(ShaderKind_Vs, size, bin, sizeof(SObjOutlineVsConstBuf) - sizeof(SObjOutlineVsConstBuf::Joint), 4, layout_types, layout_semantics);
}
{
size_t size;
const U8* bin = GetObjOutlinePsBin(&size);
ObjOutlinePs = MakeShaderBuf(ShaderKind_Ps, size, bin, sizeof(SObjOutlinePsConstBuf), 0, NULL, NULL);
}
}
{
ELayoutType layout_types[7] =
{
LayoutType_Float3,
LayoutType_Float3,
LayoutType_Float3,
LayoutType_Float2,
LayoutType_Float4,
LayoutType_Int4,
};
const Char* layout_semantics[7] =
{
L"POSITION",
L"NORMAL",
L"TANGENT",
L"TEXCOORD",
L"K_WEIGHT",
L"K_JOINT",
};
{
size_t size;
const U8* bin = GetObjOutlineJointVsBin(&size);
ObjOutlineJointVs = MakeShaderBuf(ShaderKind_Vs, size, bin, sizeof(SObjOutlineVsConstBuf), 6, layout_types, layout_semantics);
}
}
}
// Initialize 'Filter'.
{
{
float vertices[] =
{
-1.0f, -1.0f,
1.0f, -1.0f,
-1.0f, 1.0f,
1.0f, 1.0f,
};
U32 idces[] =
{
0, 1, 2,
3, 2, 1,
};
FilterVertex = MakeVertexBuf(sizeof(vertices), vertices, sizeof(float) * 2, sizeof(idces), idces);
}
{
ELayoutType layout_types[1] =
{
LayoutType_Float2,
};
const Char* layout_semantics[1] =
{
L"K_POSITION",
};
{
size_t size;
const U8* bin = GetFilterVsBin(&size);
FilterVs = MakeShaderBuf(ShaderKind_Vs, size, bin, 0, 1, layout_types, layout_semantics);
}
{
size_t size;
const U8* bin = GetFilterNonePsBin(&size);
FilterPs[0] = MakeShaderBuf(ShaderKind_Ps, size, bin, 0, 0, NULL, NULL);
}
if (IsResUsed(UseResFlagsKind_Draw_FilterMonotone))
{
size_t size;
const U8* bin = GetFilterMonotonePsBin(&size);
FilterPs[1] = MakeShaderBuf(ShaderKind_Ps, size, bin, sizeof(float) * 4, 0, NULL, NULL);
}
}
}
// Initialize the toon ramp texture.
{
void* img = NULL;
Bool success = False;
for (; ; )
{
size_t size;
int width;
int height;
const U8* bin = GetToonRampPngBin(&size);
img = DecodePng(size, bin, &width, &height);
if (!IsPowerOf2(static_cast<U64>(width)) || !IsPowerOf2(static_cast<U64>(height)))
img = Draw::AdjustTexSize(static_cast<U8*>(img), &width, &height);
{
D3D11_TEXTURE2D_DESC desc;
D3D11_SUBRESOURCE_DATA sub;
desc.Width = static_cast<UINT>(width);
desc.Height = static_cast<UINT>(height);
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_IMMUTABLE;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
sub.pSysMem = img;
sub.SysMemPitch = 4;
sub.SysMemSlicePitch = 0;
if (FAILED(Device->CreateTexture2D(&desc, &sub, &TexToonRamp)))
break;
}
{
D3D11_SHADER_RESOURCE_VIEW_DESC desc;
memset(&desc, 0, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D;
desc.Texture2D.MostDetailedMip = 0;
desc.Texture2D.MipLevels = 1;
if (FAILED(Device->CreateShaderResourceView(TexToonRamp, &desc, &ViewToonRamp)))
break;
}
success = True;
break;
}
if (img != NULL)
FreeMem(img);
if (!success)
THROW(0xe9170009);
}
for (int i = 0; i < TexEvenNum; i++)
{
float img[4];
switch (i)
{
case 0:
img[0] = 0.6f; // Diffuse red.
img[1] = 0.6f; // Diffuse green.
img[2] = 0.6f; // Diffuse blue.
img[3] = 0.0f; // Not used.
break;
case 1:
img[0] = 0.7f; // Metallic F(0) red.
img[1] = 0.7f; // Metallic F(0) green.
img[2] = 0.7f; // Metallic F(0) blue.
img[3] = 3.0f; // Glossiness = 2.0 / (Roughness ^ 4) - 2.0
break;
case 2:
img[0] = 0.5f; // Normal x.
img[1] = 0.5f; // Normal y.
img[2] = 1.0f; // Normal z.
img[3] = 0.0f; // Not used.
break;
default:
ASSERT(False);
break;
}
{
D3D11_TEXTURE2D_DESC desc;
D3D11_SUBRESOURCE_DATA sub;
desc.Width = 1;
desc.Height = 1;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_IMMUTABLE;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
sub.pSysMem = img;
sub.SysMemPitch = static_cast<UINT>(sizeof(img));
sub.SysMemSlicePitch = 0;
if (FAILED(Device->CreateTexture2D(&desc, &sub, &TexEven[i])))
THROW(0xe9170009);
}
{
D3D11_SHADER_RESOURCE_VIEW_DESC desc;
memset(&desc, 0, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
desc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D;
desc.Texture2D.MostDetailedMip = 0;
desc.Texture2D.MipLevels = 1;
if (FAILED(Device->CreateShaderResourceView(TexEven[i], &desc, &ViewEven[i])))
THROW(0xe9170009);
}
}
memset(&ObjVsConstBuf, 0, sizeof(SObjVsConstBuf));
memset(&ObjPsConstBuf, 0, sizeof(SObjPsConstBuf));
ObjPsConstBuf.CommonParam.AmbTopColor[3] = 0.0f;
ObjPsConstBuf.CommonParam.AmbBottomColor[3] = 0.0f;
ObjVsConstBuf.CommonParam.Dir[3] = 0.0f;
ObjPsConstBuf.CommonParam.DirColor[3] = 0.0f;
_camera(0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
_proj(M_PI / 180.0 * 27.0, 16.0, 9.0, 0.1, 1000.0); // The angle of view of a 50mm lens is 27 degrees.
_ambLight(0.05, 0.05, 0.08, 0.08, 0.05, 0.05);
_dirLight(1.0, -1.0, -1.0, 2.0, 2.0, 2.0);
DeviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
DeviceContext->RSSetState(RasterizerState);
_depth(False, False);
_blend(1);
_sampler(1);
}
void Fin()
{
for (int i = 0; i < TexEvenNum; i++)
{
if (ViewEven[i] != NULL)
ViewEven[i]->Release();
if (TexEven[i] != NULL)
TexEven[i]->Release();
}
if (ViewToonRamp != NULL)
ViewToonRamp->Release();
if (TexToonRamp != NULL)
TexToonRamp->Release();
for (int i = 0; i < FilterNum; i++)
{
if (FilterPs[i] != NULL)
FinShaderBuf(FilterPs[i]);
}
if (FilterVs != NULL)
FinShaderBuf(FilterVs);
if (FilterVertex != NULL)
FinVertexBuf(FilterVertex);
if (ObjOutlinePs != NULL)
FinShaderBuf(ObjOutlinePs);
if (ObjOutlineJointVs != NULL)
FinShaderBuf(ObjOutlineJointVs);
if (ObjOutlineVs != NULL)
FinShaderBuf(ObjOutlineVs);
if (ObjToonPs != NULL)
FinShaderBuf(ObjToonPs);
if (ObjPs != NULL)
FinShaderBuf(ObjPs);
if (ObjJointVs != NULL)
FinShaderBuf(ObjJointVs);
if (ObjVs != NULL)
FinShaderBuf(ObjVs);
if (FontPs != NULL)
FinShaderBuf(FontPs);
if (TexPs != NULL)
FinShaderBuf(TexPs);
if (TexRotVs != NULL)
FinShaderBuf(TexRotVs);
if (TexVs != NULL)
FinShaderBuf(TexVs);
if (CirclePs != NULL)
FinShaderBuf(CirclePs);
if (CircleVs != NULL)
FinShaderBuf(CircleVs);
if (CircleVertex != NULL)
FinVertexBuf(CircleVertex);
if (RectVs != NULL)
FinShaderBuf(RectVs);
if (RectLineVertex != NULL)
FinVertexBuf(RectLineVertex);
if (LineVertex != NULL)
FinVertexBuf(LineVertex);
if (RectVertex != NULL)
FinVertexBuf(RectVertex);
if (TriPs != NULL)
FinShaderBuf(TriPs);
if (TriVs != NULL)
FinShaderBuf(TriVs);
if (TriVertex != NULL)
FinVertexBuf(TriVertex);
for (int i = 0; i < SamplerNum; i++)
{
if (Sampler[i] != NULL)
Sampler[i]->Release();
}
for (int i = 0; i < BlendNum; i++)
{
if (BlendState[i] != NULL)
BlendState[i]->Release();
}
for (int i = 0; i < DepthNum; i++)
{
if (DepthState[i] != NULL)
DepthState[i]->Release();
}
if (RasterizerStateInverted != NULL)
RasterizerStateInverted->Release();
if (RasterizerState != NULL)
RasterizerState->Release();
if (DeviceContext != NULL)
DeviceContext->Release();
if (Device != NULL)
Device->Release();
}
void* MakeDrawBuf(int tex_width, int tex_height, int screen_width, int screen_height, HWND wnd, void* old)
{
SWndBuf* old2 = static_cast<SWndBuf*>(old);
FLOAT clear_color[4];
if (old == NULL)
{
clear_color[0] = 0.0f;
clear_color[1] = 0.0f;
clear_color[2] = 0.0f;
clear_color[3] = 1.0f;
}
else
{
memcpy(clear_color, old2->ClearColor, sizeof(FLOAT) * 4);
Draw::FinDrawBuf(old2);
}
SWndBuf* wnd_buf = static_cast<SWndBuf*>(AllocMem(sizeof(SWndBuf)));
memset(wnd_buf, 0, sizeof(SWndBuf));
memcpy(wnd_buf->ClearColor, clear_color, sizeof(FLOAT) * 4);
wnd_buf->TexWidth = tex_width;
wnd_buf->TexHeight = tex_height;
wnd_buf->ScreenWidth = screen_width;
wnd_buf->ScreenHeight = screen_height;
// Create a swap chain.
{
IDXGIFactory* factory = NULL;
DXGI_SWAP_CHAIN_DESC desc;
Bool success = False;
for (; ; )
{
if (FAILED(CreateDXGIFactory(__uuidof(IDXGIFactory), reinterpret_cast<void**>(&factory))))
break;
desc.BufferDesc.Width = static_cast<UINT>(tex_width);
desc.BufferDesc.Height = static_cast<UINT>(tex_height);
desc.BufferDesc.RefreshRate.Numerator = 60;
desc.BufferDesc.RefreshRate.Denominator = 1;
desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
desc.BufferDesc.Scaling = DXGI_MODE_SCALING_STRETCHED;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
desc.BufferCount = 1;
desc.OutputWindow = wnd;
desc.Windowed = TRUE;
desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
if (FAILED(factory->CreateSwapChain(Device, &desc, &wnd_buf->SwapChain)))
break;
success = True;
break;
}
if (factory != NULL)
factory->Release();
if (!success)
THROW(0xe9170009);
}
// Create a back buffer and a depth buffer.
{
ID3D11Texture2D* back = NULL;
ID3D11Texture2D* depth_stencil = NULL;
Bool success = False;
for (; ; )
{
if (FAILED(wnd_buf->SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&back))))
break;
if (FAILED(Device->CreateRenderTargetView(back, NULL, &wnd_buf->RenderTargetView)))
break;
{
D3D11_TEXTURE2D_DESC desc;
memset(&desc, 0, sizeof(desc));
desc.Width = static_cast<UINT>(tex_width);
desc.Height = static_cast<UINT>(tex_height);
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_D32_FLOAT;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
if (FAILED(Device->CreateTexture2D(&desc, NULL, &depth_stencil)))
break;
}
{
D3D11_DEPTH_STENCIL_VIEW_DESC desc;
memset(&desc, 0, sizeof(desc));
desc.Format = DXGI_FORMAT_D32_FLOAT;
desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
desc.Texture2D.MipSlice = 0;
if (FAILED(Device->CreateDepthStencilView(depth_stencil, &desc, &wnd_buf->DepthView)))
break;
}
success = True;
break;
}
if (depth_stencil != NULL)
depth_stencil->Release();
if (back != NULL)
back->Release();
if (!success)
THROW(0xe9170009);
}
// Create a temporary texture.
{
{
D3D11_TEXTURE2D_DESC desc;
desc.Width = static_cast<UINT>(tex_width);
desc.Height = static_cast<UINT>(tex_height);
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
if (FAILED(Device->CreateTexture2D(&desc, NULL, &wnd_buf->TmpTex)))
THROW(0xe9170009);
}
{
D3D11_SHADER_RESOURCE_VIEW_DESC desc;
memset(&desc, 0, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D;
desc.Texture2D.MostDetailedMip = 0;
desc.Texture2D.MipLevels = 1;
if (FAILED(Device->CreateShaderResourceView(wnd_buf->TmpTex, &desc, &wnd_buf->TmpShaderResView)))
THROW(0xe9170009);
}
if (FAILED(Device->CreateRenderTargetView(wnd_buf->TmpTex, NULL, &wnd_buf->TmpRenderTargetView)))
THROW(0xe9170009);
}
ActiveDrawBuf(wnd_buf);
_resetViewport();
return wnd_buf;
}
void FinDrawBuf(void* wnd_buf)
{
if (CurWndBuf == wnd_buf)
CurWndBuf = NULL;
SWndBuf* wnd_buf2 = static_cast<SWndBuf*>(wnd_buf);
if (wnd_buf2->TmpRenderTargetView != NULL)
wnd_buf2->TmpRenderTargetView->Release();
if (wnd_buf2->TmpShaderResView != NULL)
wnd_buf2->TmpShaderResView->Release();
if (wnd_buf2->TmpTex != NULL)
wnd_buf2->TmpTex->Release();
if (wnd_buf2->DepthView != NULL)
wnd_buf2->DepthView->Release();
if (wnd_buf2->RenderTargetView != NULL)
wnd_buf2->RenderTargetView->Release();
if (wnd_buf2->SwapChain != NULL)
wnd_buf2->SwapChain->Release();
FreeMem(wnd_buf);
}
void ActiveDrawBuf(void* wnd_buf)
{
if (CurWndBuf != wnd_buf)
{
SWndBuf* wnd_buf2 = static_cast<SWndBuf*>(wnd_buf);
CurWndBuf = wnd_buf2;
DeviceContext->OMSetRenderTargets(1, &CurWndBuf->TmpRenderTargetView, CurWndBuf->DepthView);
_resetViewport();
}
}
void* MakeShaderBuf(EShaderKind kind, size_t size, const void* bin, size_t const_buf_size, int layout_num, const ELayoutType* layout_types, const Char** layout_semantics)
{
SShaderBuf* shader_buf = static_cast<SShaderBuf*>(AllocMem(sizeof(SShaderBuf)));
ASSERT(const_buf_size % 16 == 0);
switch (kind)
{
case ShaderKind_Vs:
if (FAILED(Device->CreateVertexShader(bin, size, NULL, reinterpret_cast<ID3D11VertexShader**>(&shader_buf->Shader))))
return NULL;
break;
case ShaderKind_Gs:
if (FAILED(Device->CreateGeometryShader(bin, size, NULL, reinterpret_cast<ID3D11GeometryShader**>(&shader_buf->Shader))))
return NULL;
break;
case ShaderKind_Ps:
if (FAILED(Device->CreatePixelShader(bin, size, NULL, reinterpret_cast<ID3D11PixelShader**>(&shader_buf->Shader))))
return NULL;
break;
default:
ASSERT(False);
break;
}
shader_buf->Kind = kind;
shader_buf->ConstBufSize = const_buf_size;
if (const_buf_size == 0)
shader_buf->ConstBuf = NULL;
else
{
D3D11_BUFFER_DESC desc;
desc.ByteWidth = static_cast<UINT>(const_buf_size);
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
if (FAILED(Device->CreateBuffer(&desc, NULL, &shader_buf->ConstBuf)))
return NULL;
}
if (layout_num == 0)
shader_buf->Layout = NULL;
else
{
D3D11_INPUT_ELEMENT_DESC* descs = static_cast<D3D11_INPUT_ELEMENT_DESC*>(AllocMem(sizeof(D3D11_INPUT_ELEMENT_DESC) * static_cast<size_t>(layout_num)));
char(*semantics)[33] = static_cast<char(*)[33]>(AllocMem(sizeof(char[33]) * static_cast<size_t>(layout_num)));
size_t offset = 0;
for (int i = 0; i < layout_num; i++)
{
{
size_t len = wcslen(layout_semantics[i]);
ASSERT(len <= 32);
for (int j = 0; j < len; j++)
semantics[i][j] = static_cast<char>(layout_semantics[i][j]);
semantics[i][len] = '\0';
descs[i].SemanticName = semantics[i];
descs[i].SemanticIndex = 0;
}
{
DXGI_FORMAT fmt = DXGI_FORMAT_UNKNOWN;
size_t size2;
switch (layout_types[i])
{
case LayoutType_Int1:
fmt = DXGI_FORMAT_R32_SINT;
size2 = sizeof(int);
break;
case LayoutType_Int2:
fmt = DXGI_FORMAT_R32G32_SINT;
size2 = sizeof(int) * 2;
break;
case LayoutType_Int4:
fmt = DXGI_FORMAT_R32G32B32A32_SINT;
size2 = sizeof(int) * 4;
break;
case LayoutType_Float1:
fmt = DXGI_FORMAT_R32_FLOAT;
size2 = sizeof(float);
break;
case LayoutType_Float2:
fmt = DXGI_FORMAT_R32G32_FLOAT;
size2 = sizeof(float) * 2;
break;
case LayoutType_Float3:
fmt = DXGI_FORMAT_R32G32B32_FLOAT;
size2 = sizeof(float) * 3;
break;
case LayoutType_Float4:
fmt = DXGI_FORMAT_R32G32B32A32_FLOAT;
size2 = sizeof(float) * 4;
break;
default:
ASSERT(False);
size2 = 0;
break;
}
descs[i].Format = fmt;
descs[i].InputSlot = 0;
descs[i].AlignedByteOffset = static_cast<UINT>(offset);
descs[i].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
descs[i].InstanceDataStepRate = 0;
offset += size2;
}
}
if (FAILED(Device->CreateInputLayout(descs, static_cast<UINT>(layout_num), bin, size, &shader_buf->Layout)))
return NULL;
FreeMem(semantics);
FreeMem(descs);
}
return shader_buf;
}
void FinShaderBuf(void* shader_buf)
{
SShaderBuf* shader_buf2 = static_cast<SShaderBuf*>(shader_buf);
if (shader_buf2->Layout != NULL)
shader_buf2->Layout->Release();
if (shader_buf2->ConstBuf != NULL)
shader_buf2->ConstBuf->Release();
if (shader_buf2->Shader != NULL)
{
switch (shader_buf2->Kind)
{
case ShaderKind_Vs:
static_cast<ID3D11VertexShader*>(shader_buf2->Shader)->Release();
break;
case ShaderKind_Gs:
static_cast<ID3D11GeometryShader*>(shader_buf2->Shader)->Release();
break;
case ShaderKind_Ps:
static_cast<ID3D11PixelShader*>(shader_buf2->Shader)->Release();
break;
default:
ASSERT(False);
break;
}
}
FreeMem(shader_buf);
}
void ConstBuf(void* shader_buf, const void* data)
{
SShaderBuf* shader_buf2 = static_cast<SShaderBuf*>(shader_buf);
if (data != NULL)
{
D3D11_MAPPED_SUBRESOURCE subresource;
if (DeviceContext->Map(shader_buf2->ConstBuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &subresource))
return;
memcpy(subresource.pData, data, shader_buf2->ConstBufSize);
DeviceContext->Unmap(shader_buf2->ConstBuf, 0);
}
switch (shader_buf2->Kind)
{
case ShaderKind_Vs:
DeviceContext->VSSetConstantBuffers(0, 1, &shader_buf2->ConstBuf);
DeviceContext->VSSetShader(static_cast<ID3D11VertexShader*>(shader_buf2->Shader), NULL, 0);
break;
case ShaderKind_Gs:
DeviceContext->GSSetConstantBuffers(0, 1, &shader_buf2->ConstBuf);
DeviceContext->GSSetShader(static_cast<ID3D11GeometryShader*>(shader_buf2->Shader), NULL, 0);
break;
case ShaderKind_Ps:
DeviceContext->PSSetConstantBuffers(0, 1, &shader_buf2->ConstBuf);
DeviceContext->PSSetShader(static_cast<ID3D11PixelShader*>(shader_buf2->Shader), NULL, 0);
break;
default:
ASSERT(False);
break;
}
if (shader_buf2->Layout != NULL)
DeviceContext->IASetInputLayout(shader_buf2->Layout);
}
void VertexBuf(void* vertex_buf)
{
SVertexBuf* vertex_buf2 = static_cast<SVertexBuf*>(vertex_buf);
const UINT stride = static_cast<UINT>(vertex_buf2->VertexLineSize);
const UINT offset = 0;
DeviceContext->IASetVertexBuffers(0, 1, &vertex_buf2->Vertex, &stride, &offset);
DeviceContext->IASetIndexBuffer(vertex_buf2->Idx, DXGI_FORMAT_R32_UINT, 0);
}
void* MakeVertexBuf(size_t vertex_size, const void* vertices, size_t vertex_line_size, size_t idx_size, const U32* idces)
{
SVertexBuf* vertex_buf = static_cast<SVertexBuf*>(AllocMem(sizeof(SVertexBuf)));
{
D3D11_BUFFER_DESC desc;
desc.ByteWidth = static_cast<UINT>(vertex_size);
desc.Usage = D3D11_USAGE_IMMUTABLE;
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA sub;
sub.pSysMem = vertices;
sub.SysMemPitch = 0;
sub.SysMemSlicePitch = 0;
if (FAILED(Device->CreateBuffer(&desc, &sub, &vertex_buf->Vertex)))
return NULL;
}
vertex_buf->VertexLineSize = vertex_line_size;
{
D3D11_BUFFER_DESC desc;
desc.ByteWidth = static_cast<UINT>(idx_size);
desc.Usage = D3D11_USAGE_IMMUTABLE;
desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA sub;
sub.pSysMem = idces;
sub.SysMemPitch = 0;
sub.SysMemSlicePitch = 0;
if (FAILED(Device->CreateBuffer(&desc, &sub, &vertex_buf->Idx)))
return NULL;
}
return vertex_buf;
}
void FinVertexBuf(void* vertex_buf)
{
SVertexBuf* vertex_buf2 = static_cast<SVertexBuf*>(vertex_buf);
if (vertex_buf2->Idx != NULL)
vertex_buf2->Idx->Release();
if (vertex_buf2->Vertex != NULL)
vertex_buf2->Vertex->Release();
FreeMem(vertex_buf);
}
void Identity(double mat[4][4])
{
mat[0][0] = 1.0;
mat[0][1] = 0.0;
mat[0][2] = 0.0;
mat[0][3] = 0.0;
mat[1][0] = 0.0;
mat[1][1] = 1.0;
mat[1][2] = 0.0;
mat[1][3] = 0.0;
mat[2][0] = 0.0;
mat[2][1] = 0.0;
mat[2][2] = 1.0;
mat[2][3] = 0.0;
mat[3][0] = 0.0;
mat[3][1] = 0.0;
mat[3][2] = 0.0;
mat[3][3] = 1.0;
}
void IdentityFloat(float mat[4][4])
{
mat[0][0] = 1.0f;
mat[0][1] = 0.0f;
mat[0][2] = 0.0f;
mat[0][3] = 0.0f;
mat[1][0] = 0.0f;
mat[1][1] = 1.0f;
mat[1][2] = 0.0f;
mat[1][3] = 0.0f;
mat[2][0] = 0.0f;
mat[2][1] = 0.0f;
mat[2][2] = 1.0f;
mat[2][3] = 0.0f;
mat[3][0] = 0.0f;
mat[3][1] = 0.0f;
mat[3][2] = 0.0f;
mat[3][3] = 1.0f;
}
double Normalize(double vec[3])
{
double len = sqrt(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]);
if (len != 0.0)
{
vec[0] /= len;
vec[1] /= len;
vec[2] /= len;
}
return len;
}
double Dot(const double a[3], const double b[3])
{
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
}
void Cross(double out[3], const double a[3], const double b[3])
{
out[0] = a[1] * b[2] - a[2] * b[1];
out[1] = a[2] * b[0] - a[0] * b[2];
out[2] = a[0] * b[1] - a[1] * b[0];
}
void SetProjViewMat(float out[4][4], const double proj[4][4], const double view[4][4])
{
out[0][0] = static_cast<float>(proj[0][0] * view[0][0] + proj[1][0] * view[0][1] + proj[2][0] * view[0][2] + proj[3][0] * view[0][3]);
out[0][1] = static_cast<float>(proj[0][1] * view[0][0] + proj[1][1] * view[0][1] + proj[2][1] * view[0][2] + proj[3][1] * view[0][3]);
out[0][2] = static_cast<float>(proj[0][2] * view[0][0] + proj[1][2] * view[0][1] + proj[2][2] * view[0][2] + proj[3][2] * view[0][3]);
out[0][3] = static_cast<float>(proj[0][3] * view[0][0] + proj[1][3] * view[0][1] + proj[2][3] * view[0][2] + proj[3][3] * view[0][3]);
out[1][0] = static_cast<float>(proj[0][0] * view[1][0] + proj[1][0] * view[1][1] + proj[2][0] * view[1][2] + proj[3][0] * view[1][3]);
out[1][1] = static_cast<float>(proj[0][1] * view[1][0] + proj[1][1] * view[1][1] + proj[2][1] * view[1][2] + proj[3][1] * view[1][3]);
out[1][2] = static_cast<float>(proj[0][2] * view[1][0] + proj[1][2] * view[1][1] + proj[2][2] * view[1][2] + proj[3][2] * view[1][3]);
out[1][3] = static_cast<float>(proj[0][3] * view[1][0] + proj[1][3] * view[1][1] + proj[2][3] * view[1][2] + proj[3][3] * view[1][3]);
out[2][0] = static_cast<float>(proj[0][0] * view[2][0] + proj[1][0] * view[2][1] + proj[2][0] * view[2][2] + proj[3][0] * view[2][3]);
out[2][1] = static_cast<float>(proj[0][1] * view[2][0] + proj[1][1] * view[2][1] + proj[2][1] * view[2][2] + proj[3][1] * view[2][3]);
out[2][2] = static_cast<float>(proj[0][2] * view[2][0] + proj[1][2] * view[2][1] + proj[2][2] * view[2][2] + proj[3][2] * view[2][3]);
out[2][3] = static_cast<float>(proj[0][3] * view[2][0] + proj[1][3] * view[2][1] + proj[2][3] * view[2][2] + proj[3][3] * view[2][3]);
out[3][0] = static_cast<float>(proj[0][0] * view[3][0] + proj[1][0] * view[3][1] + proj[2][0] * view[3][2] + proj[3][0] * view[3][3]);
out[3][1] = static_cast<float>(proj[0][1] * view[3][0] + proj[1][1] * view[3][1] + proj[2][1] * view[3][2] + proj[3][1] * view[3][3]);
out[3][2] = static_cast<float>(proj[0][2] * view[3][0] + proj[1][2] * view[3][1] + proj[2][2] * view[3][2] + proj[3][2] * view[3][3]);
out[3][3] = static_cast<float>(proj[0][3] * view[3][0] + proj[1][3] * view[3][1] + proj[2][3] * view[3][2] + proj[3][3] * view[3][3]);
}
HFONT ToFontHandle(SClass* font)
{
return reinterpret_cast<SFont*>(font)->Font;
}
void ColorToArgb(double* a, double* r, double* g, double* b, S64 color)
{
THROWDBG(color < 0 || 0xffffffff < color, 0xe9170006);
*a = static_cast<double>((color >> 24) & 0xff) / 255.0;
*r = Gamma(static_cast<double>((color >> 16) & 0xff) / 255.0);
*g = Gamma(static_cast<double>((color >> 8) & 0xff) / 255.0);
*b = Gamma(static_cast<double>(color & 0xff) / 255.0);
}
S64 ArgbToColor(double a, double r, double g, double b)
{
if (a < 0.0)
a = 0.0;
else if (a > 1.0)
a = 1.0;
if (r < 0.0)
r = 0.0;
else if (r > 1.0)
r = 1.0;
if (g < 0.0)
g = 0.0;
else if (g > 1.0)
g = 1.0;
if (b < 0.0)
b = 0.0;
else if (b > 1.0)
b = 1.0;
return (static_cast<S64>(a * 255.0 + 0.5) << 24) |
(static_cast<S64>(Degamma(r) * 255.0 + 0.5) << 16) |
(static_cast<S64>(Degamma(g) * 255.0 + 0.5) << 8) |
static_cast<S64>(Degamma(b) * 255.0 + 0.5);
}
double Gamma(double value)
{
return value * (value * (value * 0.305306011 + 0.682171111) + 0.012522878);
}
double Degamma(double value)
{
value = 1.055 * pow(value, 0.416666667) - 0.055;
if (value < 0.0)
value = 0.0;
return value;
}
U8* AdjustTexSize(U8* argb, int* width, int* height)
{
int width2 = 1;
int height2 = 1;
while (width2 < *width)
width2 *= 2;
while (height2 < *height)
height2 *= 2;
U8* rgba2 = static_cast<U8*>(AllocMem(static_cast<size_t>(width2 * height2 * 4)));
memset(rgba2, 0, static_cast<size_t>(width2 * height2 * 4));
for (int i = 0; i < *height; i++)
memcpy(rgba2 + width2 * 4 * i, argb + *width * 4 * i, *width * 4);
*width = width2;
*height = height2;
FreeMem(argb);
return rgba2;
}
void SetJointMat(const void* element, double frame, float (*joint)[4][4])
{
const SObj::SPolygon* element2 = static_cast<const SObj::SPolygon*>(element);
for (int i = 0; i < element2->JointNum; i++)
{
int offset = i * (element2->End - element2->Begin + 1);
int mat_a = static_cast<int>(frame);
int mat_b = mat_a == element2->End ? mat_a : mat_a + 1;
float rate_b = static_cast<float>(frame - static_cast<double>(static_cast<int>(frame)));
float rate_a = 1.0f - rate_b;
for (int j = 0; j < 4; j++)
{
for (int k = 0; k < 4; k++)
joint[i][j][k] = rate_a * element2->Joints[offset + mat_a][j][k] + rate_b * element2->Joints[offset + mat_b][j][k];
}
}
}
SClass* MakeTexImpl(SClass* me_, const U8* path, Bool as_argb)
{
THROWDBG(path == NULL, 0xc0000005);
S64 path_len = *reinterpret_cast<const S64*>(path + 0x08);
const Char* path2 = reinterpret_cast<const Char*>(path + 0x10);
STex* me2 = reinterpret_cast<STex*>(me_);
void* bin = NULL;
void* img = NULL;
Bool img_ref = False; // Set to true when 'img' should not be released.
DXGI_FORMAT fmt;
int width;
int height;
{
size_t size;
bin = LoadFileAll(path2, &size);
if (bin == NULL)
{
THROW(0xe9170007);
return NULL;
}
THROWDBG(path_len < 4, 0xe9170006);
if (StrCmpIgnoreCase(path2 + path_len - 4, L".png"))
{
img = DecodePng(size, bin, &width, &height);
fmt = as_argb ? DXGI_FORMAT_R8G8B8A8_UNORM : DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
if (!IsPowerOf2(static_cast<U64>(width)) || !IsPowerOf2(static_cast<U64>(height)))
img = Draw::AdjustTexSize(static_cast<U8*>(img), &width, &height);
}
else if (StrCmpIgnoreCase(path2 + path_len - 4, L".jpg"))
{
img = DecodeJpg(size, bin, &width, &height);
fmt = as_argb ? DXGI_FORMAT_R8G8B8A8_UNORM : DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
if (!IsPowerOf2(static_cast<U64>(width)) || !IsPowerOf2(static_cast<U64>(height)))
img = Draw::AdjustTexSize(static_cast<U8*>(img), &width, &height);
}
else if (StrCmpIgnoreCase(path2 + path_len - 4, L".dds"))
{
img = DecodeBc(size, bin, &width, &height);
img_ref = True;
fmt = as_argb ? DXGI_FORMAT_BC3_UNORM : DXGI_FORMAT_BC3_UNORM_SRGB;
if (!IsPowerOf2(static_cast<U64>(width)) || !IsPowerOf2(static_cast<U64>(height)))
THROW(0xe9170008);
}
else
{
THROWDBG(True, 0xe9170006);
fmt = DXGI_FORMAT_UNKNOWN;
width = 0;
height = 0;
}
}
me2->Width = width;
me2->Height = height;
{
Bool success = False;
for (; ; )
{
{
D3D11_TEXTURE2D_DESC desc;
D3D11_SUBRESOURCE_DATA sub;
desc.Width = static_cast<UINT>(me2->Width);
desc.Height = static_cast<UINT>(me2->Height);
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = fmt;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_IMMUTABLE;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
sub.pSysMem = img;
sub.SysMemPitch = static_cast<UINT>(me2->Width * 4);
sub.SysMemSlicePitch = 0;
if (FAILED(Device->CreateTexture2D(&desc, &sub, &me2->Tex)))
break;
}
{
D3D11_SHADER_RESOURCE_VIEW_DESC desc;
memset(&desc, 0, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
desc.Format = fmt;
desc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D;
desc.Texture2D.MostDetailedMip = 0;
desc.Texture2D.MipLevels = 1;
if (FAILED(Device->CreateShaderResourceView(me2->Tex, &desc, &me2->View)))
break;
}
success = True;
break;
}
if (img != NULL && !img_ref)
FreeMem(img);
if (bin != NULL)
FreeMem(bin);
if (!success)
THROW(0xe9170009);
}
return me_;
}
} // namespace Draw
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment