'simple' gltf animation

This commit is contained in:
Zack Buhman 2026-01-01 18:42:54 -06:00
parent 03e76232d6
commit 532288906d
4 changed files with 140 additions and 80 deletions

13
gltf.h Normal file
View File

@ -0,0 +1,13 @@
union Accessor {
DWORD * dw;
float * f;
D3DXVECTOR3 * v3;
D3DXVECTOR4 * v4;
};
struct Mesh {
int position;
int normal;
int texcoord_0;
int indices;
};

151
main.cpp
View File

@ -45,6 +45,9 @@ struct SimpleVertex {
D3DXVECTOR2 Texture; D3DXVECTOR2 Texture;
}; };
#include "gltf.h"
#include "minimal.h"
struct WindowSize { struct WindowSize {
UINT Width; UINT Width;
UINT Height; UINT Height;
@ -68,16 +71,18 @@ void print(LPCSTR fmt, ...)
args); args);
va_end(args); va_end(args);
size_t length = end - &buf[0]; size_t length = end - &buf[0];
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE); #ifdef _DEBUG
WriteConsoleA(hOutput, buf, (DWORD)length, NULL, NULL); OutputDebugStringA(buf);
#endif
//HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
//WriteConsoleA(hOutput, buf, (DWORD)length, NULL, NULL);
} }
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{ {
FreeConsole(); //FreeConsole();
AllocConsole(); //AllocConsole();
AttachConsole(GetCurrentProcessId()); //AttachConsole(GetCurrentProcessId());
print("WinMain\n");
if (FAILED(InitWindow(hInstance, nCmdShow))) { if (FAILED(InitWindow(hInstance, nCmdShow))) {
print("InitWindow\n"); print("InitWindow\n");
return 0; return 0;
@ -85,7 +90,6 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLi
if (FAILED(InitDirect3DDevice())) { if (FAILED(InitDirect3DDevice())) {
print("InitDirect3DDevice\n"); print("InitDirect3DDevice\n");
system("pause");
return 0; return 0;
} }
@ -122,7 +126,6 @@ HRESULT InitWindow(HINSTANCE hInstance, int nCmdShow)
AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE); AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
UINT width = rc.right - rc.left; UINT width = rc.right - rc.left;
UINT height = rc.bottom - rc.top; UINT height = rc.bottom - rc.top;
print("width height %d %d\n", width, height);
g_hWnd = CreateWindow(L"d3d10wc", g_hWnd = CreateWindow(L"d3d10wc",
L"d3d10", WS_OVERLAPPEDWINDOW, L"d3d10", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
@ -272,7 +275,6 @@ HRESULT InitDirect3DDevice()
print("D3D10CreateDeviceAndSwapChain\n"); print("D3D10CreateDeviceAndSwapChain\n");
return hr; return hr;
} }
print("driverType %d\n", driverType);
InitDirect3DViews(); InitDirect3DViews();
@ -348,14 +350,13 @@ HRESULT InitDirect3DDevice()
// input layout // input layout
D3D10_INPUT_ELEMENT_DESC layout[] = { D3D10_INPUT_ELEMENT_DESC layout[] = {
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0 , D3D10_INPUT_PER_VERTEX_DATA, 0}, {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0 , D3D10_INPUT_PER_VERTEX_DATA, 0},
{"NORMAL" , 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0}, //{"NORMAL" , 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0},
{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D10_INPUT_PER_VERTEX_DATA, 0}, //{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D10_INPUT_PER_VERTEX_DATA, 0},
}; };
UINT numElements = (sizeof (layout)) / (sizeof (layout[0])); UINT numElements = (sizeof (layout)) / (sizeof (layout[0]));
D3D10_PASS_DESC passDesc; D3D10_PASS_DESC passDesc;
g_pTechniqueRender->GetPassByIndex(0)->GetDesc(&passDesc); g_pTechniqueRender->GetPassByIndex(0)->GetDesc(&passDesc);
print("pass desc: `%s`\n", passDesc.Name);
hr = g_pd3dDevice->CreateInputLayout(layout, numElements, hr = g_pd3dDevice->CreateInputLayout(layout, numElements,
passDesc.pIAInputSignature, passDesc.pIAInputSignature,
@ -372,81 +373,41 @@ HRESULT InitDirect3DDevice()
D3D10_BUFFER_DESC bd; D3D10_BUFFER_DESC bd;
D3D10_SUBRESOURCE_DATA initData; D3D10_SUBRESOURCE_DATA initData;
//////////////////////////////////////////////////////////////////////
// vertex buffer // vertex buffer
SimpleVertex vertices[] = { //////////////////////////////////////////////////////////////////////
{ D3DXVECTOR3(-1.0f, 1.0f, -1.0f), D3DXVECTOR3( 0.0f, 1.0f, 0.0f), D3DXVECTOR2(0.0f, 0.0f) }, #define VERTEX_ACCESSOR accessor_1
{ D3DXVECTOR3( 1.0f, 1.0f, -1.0f), D3DXVECTOR3( 0.0f, 1.0f, 0.0f), D3DXVECTOR2(1.0f, 0.0f) },
{ D3DXVECTOR3( 1.0f, 1.0f, 1.0f), D3DXVECTOR3( 0.0f, 1.0f, 0.0f), D3DXVECTOR2(1.0f, 1.0f) },
{ D3DXVECTOR3(-1.0f, 1.0f, 1.0f), D3DXVECTOR3( 0.0f, 1.0f, 0.0f), D3DXVECTOR2(0.0f, 1.0f) },
{ D3DXVECTOR3(-1.0f, -1.0f, -1.0f), D3DXVECTOR3( 0.0f, -1.0f, 0.0f), D3DXVECTOR2(0.0f, 0.0f) },
{ D3DXVECTOR3( 1.0f, -1.0f, -1.0f), D3DXVECTOR3( 0.0f, -1.0f, 0.0f), D3DXVECTOR2(1.0f, 0.0f) },
{ D3DXVECTOR3( 1.0f, -1.0f, 1.0f), D3DXVECTOR3( 0.0f, -1.0f, 0.0f), D3DXVECTOR2(1.0f, 1.0f) },
{ D3DXVECTOR3(-1.0f, -1.0f, 1.0f), D3DXVECTOR3( 0.0f, -1.0f, 0.0f), D3DXVECTOR2(0.0f, 1.0f) },
{ D3DXVECTOR3(-1.0f, -1.0f, 1.0f), D3DXVECTOR3(-1.0f, 0.0f, 0.0f), D3DXVECTOR2(0.0f, 0.0f) },
{ D3DXVECTOR3(-1.0f, -1.0f, -1.0f), D3DXVECTOR3(-1.0f, 0.0f, 0.0f), D3DXVECTOR2(1.0f, 0.0f) },
{ D3DXVECTOR3(-1.0f, 1.0f, -1.0f), D3DXVECTOR3(-1.0f, 0.0f, 0.0f), D3DXVECTOR2(1.0f, 1.0f) },
{ D3DXVECTOR3(-1.0f, 1.0f, 1.0f), D3DXVECTOR3(-1.0f, 0.0f, 0.0f), D3DXVECTOR2(0.0f, 1.0f) },
{ D3DXVECTOR3( 1.0f, -1.0f, 1.0f), D3DXVECTOR3( 1.0f, 0.0f, 0.0f), D3DXVECTOR2(0.0f, 0.0f) },
{ D3DXVECTOR3( 1.0f, -1.0f, -1.0f), D3DXVECTOR3( 1.0f, 0.0f, 0.0f), D3DXVECTOR2(1.0f, 0.0f) },
{ D3DXVECTOR3( 1.0f, 1.0f, -1.0f), D3DXVECTOR3( 1.0f, 0.0f, 0.0f), D3DXVECTOR2(1.0f, 1.0f) },
{ D3DXVECTOR3( 1.0f, 1.0f, 1.0f), D3DXVECTOR3( 1.0f, 0.0f, 0.0f), D3DXVECTOR2(0.0f, 1.0f) },
{ D3DXVECTOR3(-1.0f, -1.0f, -1.0f), D3DXVECTOR3( 0.0f, 0.0f, -1.0f), D3DXVECTOR2(0.0f, 0.0f) },
{ D3DXVECTOR3( 1.0f, -1.0f, -1.0f), D3DXVECTOR3( 0.0f, 0.0f, -1.0f), D3DXVECTOR2(1.0f, 0.0f) },
{ D3DXVECTOR3( 1.0f, 1.0f, -1.0f), D3DXVECTOR3( 0.0f, 0.0f, -1.0f), D3DXVECTOR2(1.0f, 1.0f) },
{ D3DXVECTOR3(-1.0f, 1.0f, -1.0f), D3DXVECTOR3( 0.0f, 0.0f, -1.0f), D3DXVECTOR2(0.0f, 1.0f) },
{ D3DXVECTOR3(-1.0f, -1.0f, 1.0f), D3DXVECTOR3( 0.0f, 0.0f, 1.0f), D3DXVECTOR2(0.0f, 0.0f) },
{ D3DXVECTOR3( 1.0f, -1.0f, 1.0f), D3DXVECTOR3( 0.0f, 0.0f, 1.0f), D3DXVECTOR2(1.0f, 0.0f) },
{ D3DXVECTOR3( 1.0f, 1.0f, 1.0f), D3DXVECTOR3( 0.0f, 0.0f, 1.0f), D3DXVECTOR2(1.0f, 1.0f) },
{ D3DXVECTOR3(-1.0f, 1.0f, 1.0f), D3DXVECTOR3( 0.0f, 0.0f, 1.0f), D3DXVECTOR2(0.0f, 1.0f) },
};
int vertices_length = (sizeof (vertices)) / (sizeof (vertices[0]));
bd.Usage = D3D10_USAGE_DEFAULT; bd.Usage = D3D10_USAGE_DEFAULT;
bd.ByteWidth = (sizeof (SimpleVertex)) * vertices_length; bd.ByteWidth = (sizeof (VERTEX_ACCESSOR));
//bd.ByteWidth = (sizeof (SimpleVertex)) * vertices_length;
bd.BindFlags = D3D10_BIND_VERTEX_BUFFER; bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0; bd.CPUAccessFlags = 0;
bd.MiscFlags = 0; bd.MiscFlags = 0;
initData.pSysMem = vertices; initData.pSysMem = VERTEX_ACCESSOR;
//initData.pSysMem = vertices;
hr = g_pd3dDevice->CreateBuffer(&bd, &initData, &g_pVertexBuffer); hr = g_pd3dDevice->CreateBuffer(&bd, &initData, &g_pVertexBuffer);
if (FAILED(hr)) { if (FAILED(hr)) {
print("CreateBuffer\n"); print("CreateBuffer\n");
return hr; return hr;
} }
UINT stride = (sizeof (SimpleVertex)); UINT stride = (sizeof (VERTEX_ACCESSOR[0]));
UINT offset = 0; UINT offset = 0;
g_pd3dDevice->IASetVertexBuffers(0, 1, &g_pVertexBuffer, &stride, &offset); g_pd3dDevice->IASetVertexBuffers(0, 1, &g_pVertexBuffer, &stride, &offset);
//////////////////////////////////////////////////////////////////////
// index buffer // index buffer
DWORD indices[] = { //////////////////////////////////////////////////////////////////////
3,1,0, #define INDEX_ACCESSOR accessor_0
2,1,3,
6,4,5,
7,4,6,
11,9,8,
10,9,11,
14,12,13,
15,12,14,
19,17,16,
18,17,19,
22,20,21,
23,20,22
};
int indices_length = (sizeof (indices)) / (sizeof (indices[0]));
bd.Usage = D3D10_USAGE_DEFAULT; bd.Usage = D3D10_USAGE_DEFAULT;
bd.ByteWidth = (sizeof (DWORD)) * indices_length; bd.ByteWidth = (sizeof (INDEX_ACCESSOR));
//bd.ByteWidth = (sizeof (DWORD)) * indices_length;
bd.BindFlags = D3D10_BIND_INDEX_BUFFER; bd.BindFlags = D3D10_BIND_INDEX_BUFFER;
bd.CPUAccessFlags = 0; bd.CPUAccessFlags = 0;
bd.MiscFlags = 0; bd.MiscFlags = 0;
initData.pSysMem = indices; initData.pSysMem = INDEX_ACCESSOR;
//initData.pSysMem = indices;
hr = g_pd3dDevice->CreateBuffer(&bd, &initData, &g_pIndexBuffer); hr = g_pd3dDevice->CreateBuffer(&bd, &initData, &g_pIndexBuffer);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
@ -459,8 +420,8 @@ HRESULT InitDirect3DDevice()
D3DXMatrixIdentity(&g_World1); D3DXMatrixIdentity(&g_World1);
D3DXMatrixIdentity(&g_World2); D3DXMatrixIdentity(&g_World2);
D3DXVECTOR3 Eye(0.0f, 2.0f, -5.0f); D3DXVECTOR3 Eye(0.0f, 0.0f, -2.0f);
D3DXVECTOR3 At(0.0f, 1.0f, 0.0f); D3DXVECTOR3 At(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 Up(0.0f, 1.0f, 0.0f); D3DXVECTOR3 Up(0.0f, 1.0f, 0.0f);
D3DXMatrixLookAtLH(&g_View, &Eye, &At, &Up); D3DXMatrixLookAtLH(&g_View, &Eye, &At, &Up);
@ -517,11 +478,48 @@ BOOL Resize()
return true; return true;
} }
void Animate(float t)
{
const float * frames = accessor_2;
const int frames_length = accessor_2_length;
while (t >= frames[frames_length - 1]) {
t -= frames[frames_length - 1];
}
// find frame
int prev_ix = -1;
for (int i = 0; i < frames_length - 1; i++) {
if (frames[i] <= t && frames[i+1] >= t) {
prev_ix = i;
break;
}
}
if (prev_ix == -1)
return;
int next_ix = prev_ix + 1;
if (next_ix >= frames_length)
return;
float lerp = (t - frames[prev_ix]) / (frames[next_ix] - frames[prev_ix]);
print("%f prev %d next %d lerp %f\n", t, prev_ix, next_ix, lerp);
const D3DXQUATERNION * animation = (D3DXQUATERNION *)accessor_3;
D3DXQUATERNION rotation;
D3DXQuaternionSlerp(&rotation,
&animation[prev_ix],
&animation[next_ix],
lerp);
D3DXMatrixRotationQuaternion(&g_World1, &rotation);
}
void Render() void Render()
{ {
static float t = 0.0f; static float t = 0.0f;
if (1) { if (1) {
t += (float)D3DX_PI * 0.0125f; t += (float)D3DX_PI * 0.0125f * 0.5;
} else { } else {
static DWORD dwTimeStart = 0; static DWORD dwTimeStart = 0;
DWORD dwTimeCur = GetTickCount(); DWORD dwTimeCur = GetTickCount();
@ -530,8 +528,10 @@ void Render()
t = (dwTimeCur - dwTimeStart) / 1000.0f; t = (dwTimeCur - dwTimeStart) / 1000.0f;
} }
Animate(t);
// first cube // first cube
D3DXMatrixRotationY(&g_World1, t); //D3DXMatrixRotationZ(&g_World1, t);
// lights // lights
D3DXVECTOR4 vLightDirs[2] = { D3DXVECTOR4 vLightDirs[2] = {
@ -563,6 +563,9 @@ void Render()
g_pWorldVariable->SetMatrix((float *)&g_World1); g_pWorldVariable->SetMatrix((float *)&g_World1);
g_pDiffuseVariable->SetResource(g_pTextureShaderResourceView); g_pDiffuseVariable->SetResource(g_pTextureShaderResourceView);
// color
g_pOutputColorVariable->SetFloatVector((float *)&vLightColors[0]);
// lights // lights
g_pLightDirVariable->SetFloatVectorArray((float *)vLightDirs, 0, 2); g_pLightDirVariable->SetFloatVectorArray((float *)vLightDirs, 0, 2);
g_pLightColorVariable->SetFloatVectorArray((float *)vLightColors, 0, 2); g_pLightColorVariable->SetFloatVectorArray((float *)vLightColors, 0, 2);
@ -572,10 +575,11 @@ void Render()
g_pTechniqueRender->GetDesc(&techDesc); g_pTechniqueRender->GetDesc(&techDesc);
for (UINT p = 0; p < techDesc.Passes; p++) { for (UINT p = 0; p < techDesc.Passes; p++) {
g_pTechniqueRender->GetPassByIndex(p)->Apply(0); g_pTechniqueRender->GetPassByIndex(p)->Apply(0);
g_pd3dDevice->DrawIndexed(36, 0, 0); g_pd3dDevice->DrawIndexed(3, 0, 0);
} }
// render the lights // render the lights
/*
for (int m = 0; m < 2; m++) { for (int m = 0; m < 2; m++) {
D3DXMATRIX mLight; D3DXMATRIX mLight;
D3DXMATRIX mLightScale; D3DXMATRIX mLightScale;
@ -590,9 +594,10 @@ void Render()
g_pTechniqueRenderLight->GetDesc( &techDesc ); g_pTechniqueRenderLight->GetDesc( &techDesc );
for (UINT p = 0; p < techDesc.Passes; p++) { for (UINT p = 0; p < techDesc.Passes; p++) {
g_pTechniqueRenderLight->GetPassByIndex(p)->Apply(0); g_pTechniqueRenderLight->GetPassByIndex(p)->Apply(0);
g_pd3dDevice->DrawIndexed(36, 0, 0); g_pd3dDevice->DrawIndexed(indices_length, 0, 0);
} }
} }
*/
// present // present
g_pSwapChain->Present(0, 0); g_pSwapChain->Present(0, 0);

17
main.fx
View File

@ -16,15 +16,15 @@ SamplerState samLinear {
struct VS_INPUT struct VS_INPUT
{ {
float4 Pos : POSITION; float4 Pos : POSITION;
float3 Normal : NORMAL; //float3 Normal : NORMAL;
float2 Tex : TEXCOORD; //float2 Tex : TEXCOORD;
}; };
struct PS_INPUT struct PS_INPUT
{ {
float4 Pos : SV_POSITION; float4 Pos : SV_POSITION;
float3 Normal : TEXCOORD0; //float3 Normal : TEXCOORD0;
float2 Tex : TEXCOORD1; //float2 Tex : TEXCOORD1;
}; };
PS_INPUT VS(VS_INPUT input) PS_INPUT VS(VS_INPUT input)
@ -33,11 +33,13 @@ PS_INPUT VS(VS_INPUT input)
output.Pos = mul(input.Pos, World); output.Pos = mul(input.Pos, World);
output.Pos = mul(output.Pos, View); output.Pos = mul(output.Pos, View);
output.Pos = mul(output.Pos, Projection); output.Pos = mul(output.Pos, Projection);
output.Normal = mul(input.Normal, World);
output.Tex = input.Tex; //output.Normal = mul(input.Normal, World);
//output.Tex = input.Tex;
return output; return output;
} }
/*
float4 PS(PS_INPUT input) : SV_Target float4 PS(PS_INPUT input) : SV_Target
{ {
float4 texColor = txDiffuse.Sample(samLinear, input.Tex); float4 texColor = txDiffuse.Sample(samLinear, input.Tex);
@ -50,6 +52,7 @@ float4 PS(PS_INPUT input) : SV_Target
return texColor * intensityColor; return texColor * intensityColor;
} }
*/
float4 PSSolid(PS_INPUT input) : SV_Target float4 PSSolid(PS_INPUT input) : SV_Target
{ {
@ -62,7 +65,7 @@ technique10 Render
{ {
SetVertexShader(CompileShader(vs_4_0, VS())); SetVertexShader(CompileShader(vs_4_0, VS()));
SetGeometryShader(NULL); SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_4_0, PS())); SetPixelShader(CompileShader(ps_4_0, PSSolid()));
} }
} }

39
minimal.h Normal file
View File

@ -0,0 +1,39 @@
const DWORD accessor_0[] = {
2,
1,
0,
};
const int accessor_0_length = (sizeof (accessor_0)) / (sizeof (accessor_0[0]));
const D3DXVECTOR3 accessor_1[] = {
D3DXVECTOR3( 0.000f, 0.000f, 0.000f),
D3DXVECTOR3( 1.000f, 0.000f, 0.000f),
D3DXVECTOR3( 0.000f, 1.000f, 0.000f),
};
const int accessor_1_length = (sizeof (accessor_1)) / (sizeof (accessor_1[0]));
const float accessor_2[] = {
0.0,
0.25,
0.5,
0.75,
1.0,
};
const int accessor_2_length = (sizeof (accessor_2)) / (sizeof (accessor_2[0]));
const D3DXVECTOR4 accessor_3[] = {
D3DXVECTOR4( 0.000f, 0.000f, 0.000f, 1.000f),
D3DXVECTOR4( 0.000f, 0.000f, 0.707f, 0.707f),
D3DXVECTOR4( 0.000f, 0.000f, 1.000f, 0.000f),
D3DXVECTOR4( 0.000f, 0.000f, 0.707f, -0.707f),
D3DXVECTOR4( 0.000f, 0.000f, 0.000f, 1.000f),
};
const int accessor_3_length = (sizeof (accessor_3)) / (sizeof (accessor_3[0]));
const Mesh mesh_0 = {
1, -1, -1, 0,
};