Matrix Effect
user_6919294
c_cpp
a year ago
8.6 kB
6
No Index
/* Ireneusz A. Matrix Effect
Ten kod tworzy podstawową strukturę aplikacji DirectX 11 w C++, która może być użyta do stworzenia efektu Matrixa. Oto kilka kluczowych punktów:
Używamy DirectX 11 do renderowania.
Tworzymy system cząstek, gdzie każda cząstka reprezentuje spadający znak.
W funkcji Update() aktualizujemy pozycje i stany cząstek.
Funkcja Render() jest odpowiedzialna za rysowanie cząstek na ekranie.
Aby użyć tego kodu:
- Utwórz nowy projekt Win32 w Visual Studio.
- Zastąp zawartość głównego pliku źródłowego powyższym kodem.
- Upewnij się, że masz zainstalowane DirectX SDK i że ścieżki do plików nagłówkowych i bibliotek są poprawnie ustawione w projekcie.
- Skompiluj i uruchom program.
Pamiętaj, że ten kod jest szkieletem i wymaga dodatkowej pracy:
- Musisz dodać shadery (vertex i pixel shader).
- Należy zaimplementować faktyczne renderowanie cząstek w funkcji Render().
- Warto dodać teksturę dla znaków, aby uzyskać lepszy efekt wizualny. */
#include <windows.h>
#include <d3d11.h>
#include <d3dx11.h>
#include <d3dcompiler.h>
#include <xnamath.h>
#include <vector>
#include <random>
#pragma comment (lib, "d3d11.lib")
#pragma comment (lib, "d3dx11.lib")
#pragma comment (lib, "d3dcompiler.lib")
// Struktury
struct SimpleVertex
{
XMFLOAT3 Pos;
XMFLOAT2 Tex;
};
struct ConstantBuffer
{
XMMATRIX mWorld;
XMMATRIX mView;
XMMATRIX mProjection;
};
struct Particle
{
XMFLOAT3 position;
XMFLOAT3 velocity;
XMFLOAT4 color;
float size;
float life;
};
// Globalne zmienne
IDXGISwapChain* g_pSwapChain = nullptr;
ID3D11Device* g_pd3dDevice = nullptr;
ID3D11DeviceContext* g_pImmediateContext = nullptr;
ID3D11RenderTargetView* g_pRenderTargetView = nullptr;
ID3D11VertexShader* g_pVertexShader = nullptr;
ID3D11PixelShader* g_pPixelShader = nullptr;
ID3D11InputLayout* g_pVertexLayout = nullptr;
ID3D11Buffer* g_pVertexBuffer = nullptr;
ID3D11Buffer* g_pIndexBuffer = nullptr;
ID3D11Buffer* g_pConstantBuffer = nullptr;
ID3D11ShaderResourceView* g_pTextureRV = nullptr;
ID3D11SamplerState* g_pSamplerLinear = nullptr;
XMMATRIX g_World;
XMMATRIX g_View;
XMMATRIX g_Projection;
std::vector<Particle> g_Particles;
// Funkcje
HRESULT InitDevice(HWND hWnd);
void CleanupDevice();
void Render();
void Update();
// Główna funkcja okna
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
// Funkcja główna
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wcex = { sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW, WndProc, 0, 0, hInstance, nullptr, nullptr, nullptr, nullptr, L"MatrixEffect", nullptr };
RegisterClassEx(&wcex);
RECT rc = { 0, 0, 800, 600 };
AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
HWND hWnd = CreateWindow(L"MatrixEffect", L"Matrix Effect", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, nullptr, nullptr, hInstance, nullptr);
if (FAILED(InitDevice(hWnd)))
{
CleanupDevice();
return 0;
}
ShowWindow(hWnd, nCmdShow);
MSG msg = { 0 };
while (WM_QUIT != msg.message)
{
if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
Update();
Render();
}
}
CleanupDevice();
return (int)msg.wParam;
}
// Inicjalizacja urządzenia DirectX
HRESULT InitDevice(HWND hWnd)
{
HRESULT hr = S_OK;
RECT rc;
GetClientRect(hWnd, &rc);
UINT width = rc.right - rc.left;
UINT height = rc.bottom - rc.top;
UINT createDeviceFlags = 0;
#ifdef _DEBUG
createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
D3D_DRIVER_TYPE driverTypes[] =
{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE,
};
UINT numDriverTypes = ARRAYSIZE(driverTypes);
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
};
UINT numFeatureLevels = ARRAYSIZE(featureLevels);
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = 1;
sd.BufferDesc.Width = width;
sd.BufferDesc.Height = height;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = hWnd;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed = TRUE;
for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++)
{
D3D_DRIVER_TYPE driverType = driverTypes[driverTypeIndex];
hr = D3D11CreateDeviceAndSwapChain(nullptr, driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels,
D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, nullptr, &g_pImmediateContext);
if (SUCCEEDED(hr))
break;
}
if (FAILED(hr))
return hr;
// Tworzenie render target view
ID3D11Texture2D* pBackBuffer = nullptr;
hr = g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
if (FAILED(hr))
return hr;
hr = g_pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &g_pRenderTargetView);
pBackBuffer->Release();
if (FAILED(hr))
return hr;
g_pImmediateContext->OMSetRenderTargets(1, &g_pRenderTargetView, nullptr);
// Setup the viewport
D3D11_VIEWPORT vp;
vp.Width = (FLOAT)width;
vp.Height = (FLOAT)height;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
g_pImmediateContext->RSSetViewports(1, &vp);
// Inicjalizacja cząstek
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<> dis(0.0, 1.0);
for (int i = 0; i < 1000; i++)
{
Particle p;
p.position = XMFLOAT3(dis(gen) * width, dis(gen) * height, 0.0f);
p.velocity = XMFLOAT3(0.0f, 50.0f + dis(gen) * 50.0f, 0.0f);
p.color = XMFLOAT4(0.0f, 0.5f + dis(gen) * 0.5f, 0.0f, 1.0f);
p.size = 5.0f + dis(gen) * 10.0f;
p.life = 1.0f + dis(gen) * 4.0f;
g_Particles.push_back(p);
}
// Kompilacja shaderów, tworzenie bufora wierzchołków, itp. (pominięte dla zwięzłości)
return S_OK;
}
// Czyszczenie zasobów
void CleanupDevice()
{
if (g_pImmediateContext) g_pImmediateContext->ClearState();
if (g_pConstantBuffer) g_pConstantBuffer->Release();
if (g_pVertexBuffer) g_pVertexBuffer->Release();
if (g_pIndexBuffer) g_pIndexBuffer->Release();
if (g_pVertexLayout) g_pVertexLayout->Release();
if (g_pVertexShader) g_pVertexShader->Release();
if (g_pPixelShader) g_pPixelShader->Release();
if (g_pRenderTargetView) g_pRenderTargetView->Release();
if (g_pSwapChain) g_pSwapChain->Release();
if (g_pImmediateContext) g_pImmediateContext->Release();
if (g_pd3dDevice) g_pd3dDevice->Release();
}
// Aktualizacja cząstek
void Update()
{
static float t = 0.0f;
static DWORD dwTimeStart = 0;
DWORD dwTimeCur = GetTickCount();
if (dwTimeStart == 0)
dwTimeStart = dwTimeCur;
t = (dwTimeCur - dwTimeStart) / 1000.0f;
for (auto& particle : g_Particles)
{
particle.position.x += particle.velocity.x * 0.016f;
particle.position.y += particle.velocity.y * 0.016f;
particle.life -= 0.016f;
if (particle.life <= 0.0f || particle.position.y > 600.0f)
{
particle.position = XMFLOAT3((float)(rand() % 800), 0.0f, 0.0f);
particle.velocity = XMFLOAT3(0.0f, 50.0f + (float)(rand() % 50), 0.0f);
particle.color = XMFLOAT4(0.0f, 0.5f + (float)(rand() % 50) / 100.0f, 0.0f, 1.0f);
particle.size = 5.0f + (float)(rand() % 10);
particle.life = 1.0f + (float)(rand() % 4);
}
}
}
// Renderowanie
void Render()
{
// Czyszczenie widoku
float ClearColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
g_pImmediateContext->ClearRenderTargetView(g_pRenderTargetView, ClearColor);
// Renderowanie cząstek (uproszczone)
for (const auto& particle : g_Particles)
{
// Tu powinno być renderowanie każdej cząstki
}
// Prezentacja widoku
g_pSwapChain->Present(0, 0);
}Editor is loading...
Leave a Comment