Witam serdecznie, mam ciekawe zadanko do zrobienia, mianowicie chciałbym stworzyć figurę w stylu kostki rubika, z jednym małym szczegółem, mianowicie, by oddzielić każdy sześcian od siebie pewną odległością. Specjalistą nie jestem w programowaniu DirectX11, animacja na chwilę obecną wygląda tak:
lecz jak zrobić by kostka składała się z 27 sześcianów ?
czytelniejszy kod:KOD
#include <windows.h>
#include <d3d11.h>
#include <dxgi.h>
#include <DirectXMath.h>
using namespace DirectX;
#include "VertexShader.h"
#include "PixelShader.h"
#define APPNAME "Przykład 10.1"
float vertices[] = {
-1.0f,1.0f, -1.0f, 1.0f,1.0f,1.0f,1.0f,
-1.0f, 1.0f, 1.0f, 1.0f,1.0f,1.0f,1.0f,
1.0f, 1.0f, -1.0f, 1.0f,1.0f,1.0f,1.0f,
1.0f,1.0f, 1.0f, 1.0f,1.0f,1.0f,1.0f,
1.0f, 1.0f, -1.0f, 1.0f,1.0f,1.0f,1.0f,
-1.0f, 1.0f, 1.0f, 1.0f,1.0f,1.0f,1.0f,
-1.0f, -1.0f, -1.0f, 1.0f,1.0f,0.0f,1.0f,
1.0f, -1.0f, -1.0f, 1.0f,1.0f,0.0f,1.0f,
-1.0f, -1.0f, 1.0f, 1.0f,1.0f,0.0f,1.0f,
1.0f, -1.0f, 1.0f, 1.0f,1.0f,0.0f,1.0f,
1.0f, -1.0f, -1.0f, 1.0f,1.0f,0.0f,1.0f,
-1.0f, -1.0f, 1.0f, 1.0f,1.0f,0.0f,1.0f,
-1.0f, -1.0f, 1.0f, 0.0f,1.0f,0.0f,1.0f,
1.0f, -1.0f, 1.0f, 0.0f,1.0f,0.0f,1.0f,
-1.0f, 1.0f, 1.0f, 0.0f,1.0f,0.0f,1.0f,
1.0f, -1.0f, 1.0f, 0.0f,1.0f,0.0f,1.0f,
1.0f, 1.0f, 1.0f, 0.0f,1.0f,0.0f,1.0f,
-1.0f, 1.0f, 1.0f, 0.0f,1.0f,0.0f,1.0f,
-1.0f, -1.0f, -1.0f, 1.0f,0.0f,0.0f,1.0f,
-1.0f, -1.0f, 1.0f, 1.0f,0.0f,0.0f,1.0f,
-1.0f, 1.0f, -1.0f, 1.0f,0.0f,0.0f,1.0f,
-1.0f, 1.0f, 1.0f, 1.0f,0.0f,0.0f,1.0f,
-1.0f, -1.0f, 1.0f, 1.0f,0.0f,0.0f,1.0f,
-1.0f, 1.0f, -1.0f, 1.0f,0.0f,0.0f,1.0f,
1.0f, -1.0f, -1.0f, 0.0f,0.0f,1.0f,1.0f,
1.0f, 1.0f, -1.0f, 0.0f,0.0f,1.0f,1.0f,
-1.0f, 1.0f, -1.0f, 0.0f,0.0f,1.0f,1.0f,
1.0f, -1.0f, -1.0f, 0.0f,0.0f,1.0f,1.0f,
-1.0f, 1.0f, -1.0f, 0.0f,0.0f,1.0f,1.0f,
-1.0f, -1.0f, -1.0f, 0.0f,0.0f,1.0f,1.0f,
1.0f, 1.0f, 1.0f, 1.0f,0.271f,0.0f,1.0f,
1.0f, 1.0f, -1.0f, 1.0f,0.271f,0.0f,1.0f,
1.0f, -1.0f, 1.0f, 1.0f,0.271f,0.0f,1.0f,
1.0f, 1.0f, -1.0f, 1.0f,0.271f,0.0f,1.0f,
1.0f, -1.0f, -1.0f, 1.0f,0.271f,0.0f,1.0f,
1.0f, -1.0f, 1.0f, 1.0f,0.271f,0.0f,1.0f,
};
const float black[4] = { 0.0f,0.3f,0.8f,1.0f };
struct VS_CONSTANT_BUFFER
{
XMFLOAT4X4 matWorldViewProj;
};
LRESULT CALLBACK ProcOkna(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASS wndclass;
HWND hwnd;
MSG msg;
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wndclass.lpfnWndProc = ProcOkna;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = "Szkielet_D3D11";
if (!RegisterClass(&wndclass))
{
MessageBox(NULL, "Nie udalo sie zarejestrowac klasy okna!", APPNAME, MB_ICONERROR);
return 0;
}
hwnd = CreateWindow("Szkielet_D3D11", APPNAME, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, hInstance, NULL);
if (hwnd == NULL)
{
MessageBox(NULL, "Nie udalo sie utworzyc okna!", APPNAME, MB_ICONERROR);
UnregisterClass("Szkielet_D3D11", hInstance);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
UnregisterClass("Szkielet_D3D11", hInstance);
return msg.wParam;
}
LRESULT CALLBACK ProcOkna(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static ID3D11Device * pD3D11Device = NULL;
static ID3D11DeviceContext * pD3D11DeviceContext = NULL;
static IDXGISwapChain * pSwapChain = NULL;
static ID3D11Texture2D * pBackBuffer = NULL;
static ID3D11RenderTargetView *pRenderTargetView = NULL;
static D3D_FEATURE_LEVEL d3dFeatureLevel;
static DXGI_SWAP_CHAIN_DESC scDesc;
D3D11_BUFFER_DESC vbDesc;
D3D11_SUBRESOURCE_DATA vbInit;
ID3D11Buffer * pVertexBuffer = NULL;
UINT stride = 28;
UINT offset = 0;
D3D11_INPUT_ELEMENT_DESC ieDesc[2];
ID3D11InputLayout *pInputLayout = NULL;
ID3D11VertexShader * pVertexShader = NULL;
ID3D11PixelShader * pPixelShader = NULL;
D3D11_VIEWPORT sViewport;
static HRESULT hr;
static RECT client;
static VS_CONSTANT_BUFFER sVSCBuffer;
static D3D11_BUFFER_DESC cbDesc;
static D3D11_SUBRESOURCE_DATA cbInit;
static ID3D11Buffer *pVSCBuffer = NULL;
static D3D11_MAPPED_SUBRESOURCE sMappedResource;
static VS_CONSTANT_BUFFER *pCBuffer = NULL;
static double angle = 0.0;
static XMMATRIX wvpMatrix, vMatrix, wvMatrix, pomwvpMatrixX, pomwvpMatrixY, pomwvpMatrixZ, pomwvpMatrixX2, pomwvpMatrixY2, pomwvpMatrixZ2, pomwvpMatrixX3, pomwvpMatrixY3, pomwvpMatrixZ3;
static D3D11_RASTERIZER_DESC sRastDesc;
static ID3D11RasterizerState * pRasterState = NULL;
static D3D11_TEXTURE2D_DESC sDSDesc;
static ID3D11Texture2D * pDSBuffer = NULL;
static ID3D11DepthStencilView * pDSView = NULL;
switch (uMsg)
{
case WM_CREATE:
SetTimer(hwnd, 2001, 15, NULL);
GetClientRect(hwnd, &client);
ZeroMemory(&scDesc, sizeof(scDesc));
scDesc.BufferDesc.Width = client.right - client.left;
scDesc.BufferDesc.Height = client.bottom - client.top;
scDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
scDesc.BufferDesc.RefreshRate.Numerator = 60;
scDesc.BufferDesc.RefreshRate.Denominator = 1;
scDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
scDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
scDesc.SampleDesc.Count = 1;
scDesc.SampleDesc.Quality = 0;
scDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
scDesc.BufferCount = 1;
scDesc.OutputWindow = hwnd;
scDesc.Windowed = true;
scDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
scDesc.Flags = 0;
hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_SINGLETHREADED, NULL, 0, D3D11_SDK_VERSION, &scDesc, &pSwapChain, &pD3D11Device, &d3dFeatureLevel, &pD3D11DeviceContext);
if (hr != S_OK)
MessageBox(NULL, "Nie udalo sie wywolac funkcji D3D11CreateDeviceAndSwapChain!", APPNAME, MB_ICONERROR);
else
hr = pSwapChain->GetBuffer(0, __uuidof(pBackBuffer), reinterpret_cast<void**>(&pBackBuffer));
if (hr != S_OK)
MessageBox(NULL, "Nie udalo sie wywolac metody IDXGISwapChain::GetBuffer!", APPNAME, MB_ICONERROR);
else
hr = pD3D11Device->CreateRenderTargetView(pBackBuffer, NULL, &pRenderTargetView);
if (hr != S_OK)
MessageBox(NULL, "Nie udalo sie wywolac metody ID3D11Device::CreateRenderTargetView!", APPNAME, MB_ICONERROR);
else
{
vbDesc.ByteWidth = sizeof(vertices);
vbDesc.Usage = D3D11_USAGE_DEFAULT;
vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbDesc.CPUAccessFlags = 0;
vbDesc.MiscFlags = 0;
vbDesc.StructureByteStride = 0;
vbInit.pSysMem = vertices;
vbInit.SysMemPitch = 0;
vbInit.SysMemSlicePitch = 0;
pD3D11Device->CreateBuffer(&vbDesc, &vbInit, &pVertexBuffer);
ieDesc[0].SemanticName = "POSITION";
ieDesc[0].SemanticIndex = 0;
ieDesc[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
ieDesc[0].InputSlot = 0;
ieDesc[0].AlignedByteOffset = 0;
ieDesc[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
ieDesc[0].InstanceDataStepRate = 0;
ieDesc[1].SemanticName = "COLOR";
ieDesc[1].SemanticIndex = 0;
ieDesc[1].Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
ieDesc[1].InputSlot = 0;
ieDesc[1].AlignedByteOffset = 12;
ieDesc[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
ieDesc[1].InstanceDataStepRate = 0;
pD3D11Device->CreateInputLayout(ieDesc, 2, g_vs_main, sizeof(g_vs_main),
&pInputLayout);
pD3D11Device->CreateVertexShader(g_vs_main, sizeof(g_vs_main), NULL,
&pVertexShader);
pD3D11Device->CreatePixelShader(g_ps_main, sizeof(g_ps_main), NULL,
&pPixelShader);
sViewport.Width = static_cast<float>(client.right - client.left);
sViewport.Height = static_cast<float>(client.bottom - client.top);
sViewport.TopLeftX = 0.0f;
sViewport.TopLeftY = 0.0f;
sViewport.MinDepth = 0.0f;
sViewport.MaxDepth = 1.0f;
sRastDesc.FillMode = D3D11_FILL_SOLID;
sRastDesc.CullMode = D3D11_CULL_NONE;
sRastDesc.FrontCounterClockwise = false;
sRastDesc.DepthBias = 0;
sRastDesc.DepthBiasClamp = 0.0f;
sRastDesc.SlopeScaledDepthBias = 0.0f;
sRastDesc.DepthClipEnable = true;
sRastDesc.ScissorEnable = false;
sRastDesc.MultisampleEnable = false;
sRastDesc.AntialiasedLineEnable = false;
pD3D11Device->CreateRasterizerState(&sRastDesc, &pRasterState);
sDSDesc.Width = client.right - client.left;
sDSDesc.Height = client.bottom - client.top;
sDSDesc.MipLevels = 1;
sDSDesc.ArraySize = 1;
sDSDesc.Format = DXGI_FORMAT_D32_FLOAT;
sDSDesc.SampleDesc.Count = 1;
sDSDesc.SampleDesc.Quality = 0;
sDSDesc.Usage = D3D11_USAGE_DEFAULT;
sDSDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
sDSDesc.CPUAccessFlags = 0;
sDSDesc.MiscFlags = 0;
pD3D11Device->CreateTexture2D(&sDSDesc, 0, &pDSBuffer);
//Utworzenie widoku bufora glebokosci
pD3D11Device->CreateDepthStencilView(pDSBuffer, NULL, &pDSView);
XMStoreFloat4x4(&sVSCBuffer.matWorldViewProj, XMMatrixIdentity());
cbDesc.ByteWidth = sizeof(VS_CONSTANT_BUFFER);
cbDesc.Usage = D3D11_USAGE_DYNAMIC;
cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
cbDesc.MiscFlags = 0;
cbDesc.StructureByteStride = 0;
cbInit.pSysMem = &sVSCBuffer;
cbInit.SysMemPitch = 0;
cbInit.SysMemSlicePitch = 0;
pD3D11Device->CreateBuffer(&cbDesc, &cbInit, &pVSCBuffer);
pD3D11DeviceContext->IASetVertexBuffers(0, 1, &pVertexBuffer, &stride, &offset);
pD3D11DeviceContext->IASetInputLayout(pInputLayout);
pD3D11DeviceContext->IASetPrimitiveTopology(
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
pD3D11DeviceContext->VSSetShader(pVertexShader, NULL, 0);
pD3D11DeviceContext->VSSetConstantBuffers(0, 1, &pVSCBuffer);
pD3D11DeviceContext->RSSetViewports(1, &sViewport);
pD3D11DeviceContext->RSSetState(pRasterState);
pD3D11DeviceContext->PSSetShader(pPixelShader, NULL, 0);
pD3D11DeviceContext->OMSetRenderTargets(1, &pRenderTargetView, pDSView);
}
return 0;
case WM_TIMER:
angle += 0.025;
InvalidateRect(hwnd, NULL, false);
return 0;
case WM_PAINT:
if (hr == S_OK)
{
if (pVSCBuffer)
{
GetClientRect(hwnd, &client);
wvMatrix = XMMatrixMultiply(XMMatrixRotationY(1.0*angle), XMMatrixRotationX(3.1415*sin(angle) / 4.0)), XMMatrixTranslation;
vMatrix = XMMatrixTranslation(0.0f, 0.0f, 25.625f);
wvMatrix = XMMatrixMultiply(wvMatrix, vMatrix);
wvpMatrix = XMMatrixMultiply(wvMatrix, XMMatrixPerspectiveFovLH(45.0f, static_cast<float>(client.right - client.left) / (client.bottom - client.top), 1.0f, 100.0f));
wvMatrix = XMMatrixTranspose(wvMatrix);
vMatrix = XMMatrixTranspose(vMatrix);
wvpMatrix = XMMatrixTranspose(wvpMatrix);
pomwvpMatrixX = XMMatrixTranslation(2.5f, 0.0f, 0.0f);
pomwvpMatrixX = XMMatrixTranspose(pomwvpMatrixX);
pomwvpMatrixY = XMMatrixTranslation(0.0f, 2.5f, 0.0f);
pomwvpMatrixY = XMMatrixTranspose(pomwvpMatrixY);
pomwvpMatrixZ = XMMatrixTranslation(0.0f, 0.0f, 2.5f);
pomwvpMatrixZ = XMMatrixTranspose(pomwvpMatrixZ);
}
pD3D11DeviceContext->Map(pVSCBuffer, 0,
D3D11_MAP_WRITE_DISCARD, 0, &sMappedResource);
pCBuffer = reinterpret_cast<VS_CONSTANT_BUFFER *>(sMappedResource.pData);
XMStoreFloat4x4(&(pCBuffer->matWorldViewProj), wvpMatrix);
pD3D11DeviceContext->Unmap(pVSCBuffer, 0);
}
pD3D11DeviceContext->ClearRenderTargetView(pRenderTargetView, black);
pD3D11DeviceContext->ClearDepthStencilView(pDSView, D3D11_CLEAR_DEPTH, 1.0f, 0);
pD3D11DeviceContext->Draw(48, 0);
pD3D11DeviceContext->Map(pVSCBuffer, 0,D3D11_MAP_WRITE_DISCARD, 0, &sMappedResource);
pCBuffer = reinterpret_cast<VS_CONSTANT_BUFFER *>(sMappedResource.pData);
XMStoreFloat4x4(&(pCBuffer->matWorldViewProj), XMMatrixMultiply(wvpMatrix, pomwvpMatrixX));
XMMatrixTranspose(XMMatrixRotationZ(angle));
pD3D11DeviceContext->Unmap(pVSCBuffer, 0);
pD3D11DeviceContext->Draw(48, 0);
pD3D11DeviceContext->Map(pVSCBuffer, 0,
D3D11_MAP_WRITE_DISCARD, 0, &sMappedResource);
pCBuffer = reinterpret_cast<VS_CONSTANT_BUFFER *>(sMappedResource.pData);
XMStoreFloat4x4(&(pCBuffer->matWorldViewProj), XMMatrixMultiply(wvpMatrix, pomwvpMatrixX));
XMMatrixTranspose(XMMatrixRotationZ(angle));
pD3D11DeviceContext->Unmap(pVSCBuffer, 0);
pD3D11DeviceContext->Draw(48, 0);
pD3D11DeviceContext->Map(pVSCBuffer, 0,
D3D11_MAP_WRITE_DISCARD, 0, &sMappedResource);
pCBuffer = reinterpret_cast<VS_CONSTANT_BUFFER *>(sMappedResource.pData);
XMStoreFloat4x4(&(pCBuffer->matWorldViewProj), XMMatrixMultiply(wvpMatrix, pomwvpMatrixY));
XMMatrixTranspose(XMMatrixRotationZ(angle));
pD3D11DeviceContext->Unmap(pVSCBuffer, 0);
pD3D11DeviceContext->Draw(48, 0);
pD3D11DeviceContext->Map(pVSCBuffer, 0,
D3D11_MAP_WRITE_DISCARD, 0, &sMappedResource);
pCBuffer = reinterpret_cast<VS_CONSTANT_BUFFER *>(sMappedResource.pData);
XMStoreFloat4x4(&(pCBuffer->matWorldViewProj), XMMatrixMultiply(wvpMatrix, pomwvpMatrixZ));
XMMatrixTranspose(XMMatrixRotationZ(angle));
pD3D11DeviceContext->Unmap(pVSCBuffer, 0);
pD3D11DeviceContext->Draw(48, 0);
pSwapChain->Present(0, 0);
}
ValidateRect(hwnd, NULL);
return 0;
case WM_DESTROY:
KillTimer(hwnd, 2001);
if (pRasterState)
pRasterState->Release();
if (pDSBuffer)
pDSBuffer->Release();
if (pDSView)
pDSView->Release();
if (pVSCBuffer)
pVSCBuffer->Release();
if (pVertexBuffer)
pVertexBuffer->Release();
if (pInputLayout)
pInputLayout->Release();
if (pVertexShader)
pVertexShader->Release();
if (pPixelShader)
pPixelShader->Release();
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}