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); }