#include "data.h" #include "../3rdparty/usync.h" #include "shaders.h" #pragma code_seg(".setNullUAVSRV") __forceinline void setNullUAVSRV() { context->CSSetUnorderedAccessViews(0, 8, (ID3D11UnorderedAccessView* const *)zero, NULL); context->CSSetShaderResources(0, 8, (ID3D11ShaderResourceView* const *)zero); } #pragma code_seg(".createSRVUAVRTV") void createSRVUAVRTV(TEXTURE_2D_SRV_UAV_RTV* tex, int width, int height) { texDesc.Width = width; texDesc.Height = height; device->CreateTexture2D(&texDesc, NULL, &tex->TEX); device->CreateShaderResourceView(tex->TEX, NULL, &tex->SRV); device->CreateUnorderedAccessView(tex->TEX, NULL, &tex->UAV); device->CreateRenderTargetView(tex->TEX, NULL, &tex->RTV); } #ifndef SYNC_PLAYER static void pause(void *d, int flag) { Audio_Pause((bool)flag); } static void set_row(void *d, int row) { Audio_Seek(row); } static int is_playing(void *d) { return (int)Audio_IsPlaying(); } struct sync_cb usync_cb = { pause, set_row, is_playing }; void *usync_data = NULL; #endif #pragma code_seg(".main") int main() { #ifdef FULLSCREEN ShowCursor(0); hWnd = CreateWindowExA(0, (LPCSTR)ATOM_STATIC, 0, WS_POPUP | WS_VISIBLE | WS_MAXIMIZE, 0, 0, 0, 0, 0, 0, 0, 0); //ShowWindow(hWnd, SW_SHOW); #else #ifdef _DEBUG WNDCLASSEX wndclass; wndclass.cbSize = sizeof (wndclass); wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wndclass.lpfnWndProc = (WNDPROC)DefWindowProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = NULL; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = "BluFlame intro window class"; wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); RegisterClassEx(&wndclass); hWnd = CreateWindowExA(0, wndclass.lpszClassName, "Intro", WS_EX_APPWINDOW, GetSystemMetrics(SM_CXSCREEN) - WIDTH - 16, 0, WIDTH + 16, HEIGHT + 40, NULL, NULL, GetModuleHandle(NULL), NULL ); ShowWindow(hWnd, SW_NORMAL); SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); #else hWnd = CreateWindowExA(0, (LPCSTR)ATOM_STATIC, 0, WS_POPUP | WS_VISIBLE, 0, 0, WIDTH, HEIGHT, 0, 0, 0, 0); #endif #endif swapChainDesc.OutputWindow = hWnd; D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_DEBUG, NULL, 0, D3D11_SDK_VERSION, (DXGI_SWAP_CHAIN_DESC*)&swapChainDesc, &swapChain, &device, NULL, &context); #ifdef _DEBUG { ID3D11Debug* debug; device->QueryInterface(__uuidof(ID3D11Debug), (void**)&debug); ID3D11InfoQueue* infoQueue; device->QueryInterface(__uuidof(ID3D11InfoQueue), (void**)&infoQueue); infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true); infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true); infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_WARNING, true); infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_INFO, true); infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_MESSAGE, true); infoQueue->Release(); debug->Release(); } #endif swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferTexture); device->CreateUnorderedAccessView(backBufferTexture, NULL, &backBufferUAV); device->CreateTexture2D(&depthBufferDesc, NULL, &depthBuffer); device->CreateBuffer(&constantBufferDesc, NULL, &constantBuffer); device->CreateBuffer(&constantBuffer2Desc, NULL, &constantBuffer2); device->CreateBuffer(&constantBuffer2Desc, NULL, &constantBuffer3); device->CreateBuffer(&constantBufferTempDesc, NULL, &constantBufferTemp); device->CreateBuffer(&particleBufferDesc, NULL, &particleBuffer1); device->CreateUnorderedAccessView(particleBuffer1, &particleUavDesc, &particleBuffer1UAV); device->CreateShaderResourceView(particleBuffer1, &particleSrvDesc, &particleBuffer1SRV); device->CreateBuffer(&particleBufferDesc, NULL, &particleBuffer2); device->CreateUnorderedAccessView(particleBuffer2, &particleUavDesc, &particleBuffer2UAV); device->CreateShaderResourceView(particleBuffer2, &particleSrvDesc, &particleBuffer2SRV); device->CreateRenderTargetView(backBufferTexture, &backBufferRtvDesc, &backBufferRtv); device->CreateDepthStencilState(&depthStencilStateDesc, &depthStencilState); device->CreateDepthStencilView(depthBuffer, &depthStencilViewDesc, &depthStencilView); device->CreateBlendState(&alphaBlendDesc, &alphaBlendState); #ifndef _DEBUG CreateShaders(); #else #ifndef SHADER_DEBUG InitShader(); shaderCompileEvent = ::CreateEvent(NULL, FALSE, FALSE, TEXT("WriteEvent")); SetThreadPriority((HANDLE)CreateThread(0, 0, &filemon, 0, 0, 0), THREAD_PRIORITY_BELOW_NORMAL); #endif CreateShaders(); #endif //--- // Postprocessing setup //--- device->CreateSamplerState(&ppSamplerDesc, &ppSampler); device->CreateSamplerState(&texSamplerDesc, &texSampler); createSRVUAVRTV(&noiseTemp, 1024, 1024); createSRVUAVRTV(&noise, 1024, 1024); createSRVUAVRTV(&tex0, WIDTH, HEIGHT); createSRVUAVRTV(&pingPongTex1, WIDTH, HEIGHT); createSRVUAVRTV(&tmpTex1, WIDTH, HEIGHT); createSRVUAVRTV(&blurTex1, WIDTH, HEIGHT); createSRVUAVRTV(&lensDirt2, WIDTH / 2, HEIGHT / 2); createSRVUAVRTV(&ghostsTex4, WIDTH / 4, HEIGHT / 4); createSRVUAVRTV(&streaksTex4, WIDTH / 4, HEIGHT / 4); createSRVUAVRTV(&tmpTex8, WIDTH / 8, HEIGHT / 8); createSRVUAVRTV(&blurTex8, WIDTH / 8, HEIGHT / 8); createSRVUAVRTV(&tmpTex32, WIDTH / 32, HEIGHT / 32); createSRVUAVRTV(&blurTex32, WIDTH / 32, HEIGHT / 32); ID3D11UnorderedAccessView* uavs[] = { particleBuffer1UAV, particleBuffer2UAV }; ID3D11ShaderResourceView* srvs[] = { particleBuffer1SRV, particleBuffer2SRV }; ID3D11ShaderResourceView* mergeSRV[] = { tex0.SRV, blurTex1.SRV, blurTex8.SRV, blurTex32.SRV, streaksTex4.SRV, lensDirt2.SRV, ghostsTex4.SRV, NULL }; ::CreateThread(0, 0, (LPTHREAD_START_ROUTINE)_4klang_render, audio_buffer, 0, 0); ::Sleep(1024); if (usync_init() < 0) abort(); #ifndef SYNC_PLAYER /* HACK: prefetch tracks - not needed when actually editing */ usync_get_val(event); usync_get_val(emitter_PosX); usync_get_val(emitter_PosY); usync_get_val(emitter_PosZ); usync_get_val(emitter_VelX); usync_get_val(emitter_VelY); usync_get_val(emitter_VelZ); usync_get_val(emitter_DirX); usync_get_val(emitter_DirY); usync_get_val(emitter_DirZ); usync_get_val(emitter_Mass); usync_get_val(emitter_Radius); usync_get_val(emitter_Rate); usync_get_val(emitter_Chaos); usync_get_val(particle_Life); usync_get_val(particle_Mass); usync_get_val(color_Blend_R); usync_get_val(color_Blend_G); usync_get_val(color_Blend_B); usync_get_val(color_Blend_A); usync_get_val(camera_PosX); usync_get_val(camera_PosY); usync_get_val(camera_PosZ); usync_get_val(camera_At_X); usync_get_val(camera_At_Y); usync_get_val(camera_At_Z); usync_get_val(camera_Up_X); usync_get_val(camera_Up_Y); usync_get_val(camera_Up_Z); usync_get_val(smNoise_DirX); usync_get_val(smNoise_DirY); usync_get_val(smNoise_DirZ); usync_get_val(smNoise_ColorR); usync_get_val(smNoise_ColorG); usync_get_val(smNoise_ColorB); usync_get_val(smNoise_ColorA); usync_get_val(smNoise_Size); usync_get_val(gravity); usync_get_val(sdfBlendFactor); usync_get_val(distort); usync_update(0.0f); #endif context->CSSetSamplers(0, 1, &texSampler); context->CSSetUnorderedAccessViews(0, 1, &noiseTemp.UAV, NULL); context->CSSetShader(csNoise, NULL, 0); context->Dispatch(64, 64, 1); setNullUAVSRV(); context->GenerateMips(noiseTemp.SRV); context->CSSetUnorderedAccessViews(0, 1, &noise.UAV, NULL); context->CSSetShaderResources(0, 1, &noiseTemp.SRV); context->CSSetShader(csFbm, NULL, 0); context->Dispatch(64, 64, 1); setNullUAVSRV(); context->GenerateMips(noise.SRV); Audio_PlayBuffer(); context->VSSetConstantBuffers(0, 1, &constantBuffer); context->GSSetConstantBuffers(0, 1, &constantBuffer); context->CSSetConstantBuffers(0, 1, &constantBuffer); context->PSSetConstantBuffers(0, 1, &constantBuffer); context->PSSetSamplers(0, 1, &texSampler); context->CSSetSamplers(0, 1, &ppSampler); #ifdef SYNC_PLAYER context->ClearUnorderedAccessViewUint(uavs[1], (UINT*)zero); context->CSSetUnorderedAccessViews(0, 2, uavs, indices); context->CSSetShader(starInitShader, NULL, 0); context->Dispatch(128, 128, 1); #endif do { #ifdef _DEBUG MSG msg; while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } #endif demoTime = Audio_GetCurrentTime(); float deltaTime = demoTime - oldDemoTime; oldDemoTime = demoTime; usync_update(demoTime); // For postprocessing context->ClearRenderTargetView(tex0.RTV, zero); context->ClearRenderTargetView(backBufferRtv, zero); context->ClearDepthStencilView(depthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0); context->Map(constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); constantBufferData = (ConstantBufferType*)mappedResource.pData; constantBufferData->demoTime = demoTime * 0.1f; constantBufferData->deltaTime = deltaTime * 0.1f; constantBufferData->emitterPositionX = usync_get_val(emitter_PosX); constantBufferData->emitterPositionY = usync_get_val(emitter_PosY); constantBufferData->emitterPositionZ = usync_get_val(emitter_PosZ); constantBufferData->emitterVelocityX = usync_get_val(emitter_VelX); constantBufferData->emitterVelocityY = usync_get_val(emitter_VelY); constantBufferData->emitterVelocityZ = usync_get_val(emitter_VelZ); constantBufferData->emitterDirectionX = usync_get_val(emitter_DirX); constantBufferData->emitterDirectionY = usync_get_val(emitter_DirY); constantBufferData->emitterDirectionZ = usync_get_val(emitter_DirZ); constantBufferData->emitterMass = usync_get_val(emitter_Mass); constantBufferData->emitterRadius = usync_get_val(emitter_Radius); constantBufferData->emitRate = usync_get_val(emitter_Rate); constantBufferData->emitChaos = usync_get_val(emitter_Chaos); constantBufferData->lifeTime = usync_get_val(particle_Life); constantBufferData->particleMass = usync_get_val(particle_Mass); constantBufferData->colorBlendR = usync_get_val(color_Blend_R); constantBufferData->colorBlendG = usync_get_val(color_Blend_G); constantBufferData->colorBlendB = usync_get_val(color_Blend_B); constantBufferData->colorBlendA = usync_get_val(color_Blend_A); constantBufferData->cameraPositionX = usync_get_val(camera_PosX); constantBufferData->cameraPositionY = usync_get_val(camera_PosY); constantBufferData->cameraPositionZ = usync_get_val(camera_PosZ); constantBufferData->cameraLookatX = usync_get_val(camera_At_X); constantBufferData->cameraLookatY = usync_get_val(camera_At_Y); constantBufferData->cameraLookatZ = usync_get_val(camera_At_Z); constantBufferData->cameraUpX = usync_get_val(camera_Up_X); constantBufferData->cameraUpY = usync_get_val(camera_Up_Y); constantBufferData->cameraUpZ = usync_get_val(camera_Up_Z); constantBufferData->smoothNoiseDirectionX = usync_get_val(smNoise_DirX); constantBufferData->smoothNoiseDirectionY = usync_get_val(smNoise_DirY); constantBufferData->smoothNoiseDirectionZ = usync_get_val(smNoise_DirZ); constantBufferData->smoothNoiseColorR = usync_get_val(smNoise_ColorR); constantBufferData->smoothNoiseColorG = usync_get_val(smNoise_ColorG); constantBufferData->smoothNoiseColorB = usync_get_val(smNoise_ColorB); constantBufferData->smoothNoiseColorA = usync_get_val(smNoise_ColorA); constantBufferData->smoothNoiseSize = usync_get_val(smNoise_Size); constantBufferData->gravity = usync_get_val(gravity); constantBufferData->sdfBlendFactor = usync_get_val(sdfBlendFactor); constantBufferData->distort = usync_get_val(distort); auto idx = ((audio_MMTime.u.sample >> 8) << 5); constantBufferData->envelope1 = (&_4klang_envelope_buffer)[idx + 2*3]; constantBufferData->envelope2 = (&_4klang_envelope_buffer)[idx + 2*4]; constantBufferData->note = (&_4klang_note_buffer)[idx + 2*6] / 128.0f; context->Unmap(constantBuffer, 0); auto uavtemp = uavs[1]; uavs[1] = uavs[0]; uavs[0] = uavtemp; auto srvtemp = srvs[1]; srvs[1] = srvs[0]; srvs[0] = srvtemp; #ifndef SYNC_PLAYER bool bUpdate = deltaTime != 0 && demoTime != 0; if (audio_MMTime.u.sample == 0) { context->ClearUnorderedAccessViewUint(uavs[1], (UINT*)zero); context->CSSetUnorderedAccessViews(0, 2, uavs, indices); context->CSSetShader(starInitShader, NULL, 0); context->Dispatch(128, 128, 1); } else if (bUpdate) #endif { context->VSSetConstantBuffers(1, 2, (ID3D11Buffer* const *)zero); context->GSSetConstantBuffers(1, 2, (ID3D11Buffer* const *)zero); context->CSSetConstantBuffers(1, 2, (ID3D11Buffer* const *)zero); context->PSSetConstantBuffers(1, 2, (ID3D11Buffer* const *)zero); context->VSSetShader(constantBufferVertexShader, NULL, 0); context->GSSetShader(constantBufferGeometryShader, NULL, 0); context->SOSetTargets(1, &constantBufferTemp, (UINT*)zero); context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); context->Draw(1, 0); context->SOSetTargets(0, (ID3D11Buffer* const *)zero, (UINT*)zero); context->CopyResource(constantBuffer3, constantBuffer2); context->CopyResource(constantBuffer2, constantBufferTemp); context->VSSetConstantBuffers(1, 1, &constantBuffer3); context->GSSetConstantBuffers(1, 1, &constantBuffer3); context->CSSetConstantBuffers(1, 1, &constantBuffer3); context->PSSetConstantBuffers(1, 1, &constantBuffer3); context->VSSetConstantBuffers(2, 1, &constantBuffer2); context->GSSetConstantBuffers(2, 1, &constantBuffer2); context->CSSetConstantBuffers(2, 1, &constantBuffer2); context->PSSetConstantBuffers(2, 1, &constantBuffer2); float fEvent = usync_get_val(event); int iEvent = fEvent; ID3D11ComputeShader* localUpdateShader = updateShader; if (iEvent != oldEvent) { switch (iEvent) { case 1: // clear all particles localUpdateShader = event1Shader; break; case 2: // create one master emitter localUpdateShader = event2Shader; break; } } oldEvent = iEvent; context->ClearUnorderedAccessViewUint(uavs[1], (UINT*)zero); context->CSSetUnorderedAccessViews(0, 2, uavs, indices); context->CSSetShader(localUpdateShader, NULL, 0); context->Dispatch(1024, 1024, 1); } context->CSSetUnorderedAccessViews(0, 2, (ID3D11UnorderedAccessView* const *)zero, NULL); UINT strides[] = { 48 }; context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); context->VSSetConstantBuffers(0, 1, &constantBuffer); context->VSSetShader(particleVertexShader, NULL, 0); context->GSSetShader(particleGeometryShader, NULL, 0); context->PSSetShaderResources(0, 1, &noise.SRV); context->PSSetShader(particlePixelShader, NULL, 0); // For postprocessing context->OMSetRenderTargets(1, &tex0.RTV, NULL); context->OMSetBlendState(alphaBlendState, NULL, 0xffffffff); context->RSSetViewports(1, &swapChainViewport); context->VSSetShaderResources(0, 1, &srvs[1]); context->DrawInstanced(1024 * 1024, 1, 0, 0); context->VSSetShaderResources(0, 1, (ID3D11ShaderResourceView* const*)zero); context->OMSetRenderTargets(1, (ID3D11RenderTargetView* const *)zero, NULL); // tex0 is the input texture context->GenerateMips(tex0.SRV); setNullUAVSRV(); if (true) { // Distort Chroma context->CSSetUnorderedAccessViews(0, 1, &tmpTex1.UAV, NULL); context->CSSetShaderResources(0, 1, &tex0.SRV); context->CSSetShader(csDistortChroma, NULL, 0); context->Dispatch(WIDTH/16, HEIGHT/16, 1); setNullUAVSRV(); context->GenerateMips(tmpTex1.SRV); // Radial Blur context->CSSetUnorderedAccessViews(0, 1, &pingPongTex1.UAV, NULL); context->CSSetShaderResources(0, 1, &tmpTex1.SRV); context->CSSetShader(csRadialBlur, NULL, 0); context->Dispatch(WIDTH / 16, HEIGHT / 16, 1); setNullUAVSRV(); context->GenerateMips(pingPongTex1.SRV); // Circumferential Blur -> (MipMap) -> Streaks context->CSSetUnorderedAccessViews(0, 1, &tex0.UAV, NULL); context->CSSetShaderResources(0, 1, &pingPongTex1.SRV); context->CSSetShader(csCircumferentialBlur, NULL, 0); context->Dispatch(WIDTH / 16, HEIGHT / 16, 1); setNullUAVSRV(); context->GenerateMips(tex0.SRV); // Streaks context->CSSetUnorderedAccessViews(0, 1, &streaksTex4.UAV, NULL); context->CSSetShaderResources(0, 1, &tex0.SRV); context->CSSetShader(csStreaks, NULL, 0); context->Dispatch(WIDTH / 64 + 1, HEIGHT / 64 + 1, 1); // Lens dirt context->CSSetUnorderedAccessViews(0, 1, &lensDirt2.UAV, NULL); context->CSSetShader(csLensDirt, NULL, 0); context->Dispatch(WIDTH / 32 + 1, HEIGHT / 32 + 1, 1); // BlurV (1/1) context->CSSetUnorderedAccessViews(0, 1, &tmpTex1.UAV, NULL); context->CSSetShaderResources(0, 1, &tex0.SRV); context->CSSetShader(csBlurV, NULL, 0); context->Dispatch(WIDTH / 16, HEIGHT / 16, 1); // BlurH (1/1) -> blurTex1 context->CSSetUnorderedAccessViews(0, 1, &blurTex1.UAV, NULL); context->CSSetShaderResources(0, 1, &tmpTex1.SRV); context->CSSetShader(csBlurH, NULL, 0); context->Dispatch(WIDTH / 16, HEIGHT / 16, 1); context->GenerateMips(blurTex1.SRV); // BlurV (1/8) context->CSSetUnorderedAccessViews(0, 1, &tmpTex8.UAV, NULL); context->CSSetShaderResources(0, 1, &blurTex1.SRV); context->CSSetShader(csBlurV, NULL, 0); context->Dispatch(WIDTH / 128 + 1, HEIGHT / 128 + 1, 1); // BlurH (1/8) -> blurTex8 -> merge / ghosts context->CSSetUnorderedAccessViews(0, 1, &blurTex8.UAV, NULL); context->CSSetShaderResources(0, 1, &tmpTex8.SRV); context->CSSetShader(csBlurH, NULL, 0); context->Dispatch(WIDTH / 128 + 1, HEIGHT / 128 + 1, 1); context->GenerateMips(blurTex8.SRV); // BlurV (1/32) context->CSSetUnorderedAccessViews(0, 1, &tmpTex32.UAV, NULL); context->CSSetShaderResources(0, 1, &blurTex8.SRV); context->CSSetShader(csBlurV, NULL, 0); context->Dispatch(WIDTH / 512 + 1, HEIGHT / 512 + 1, 1); // BlurH (1/32) -> blurTex32 -> merge / lensDirt / smallDirt / ghosts context->CSSetUnorderedAccessViews(0, 1, &blurTex32.UAV, NULL); context->CSSetShaderResources(0, 1, &tmpTex32.SRV); context->CSSetShader(csBlurV, NULL, 0); context->Dispatch(WIDTH / 512 + 1, HEIGHT / 512 + 1, 1); context->GenerateMips(tex0.SRV); // Ghosts ID3D11ShaderResourceView* ghostsSRV[] = { blurTex1.SRV, blurTex8.SRV }; context->CSSetUnorderedAccessViews(0, 1, &ghostsTex4.UAV, NULL); context->CSSetShaderResources(0, 2, ghostsSRV); context->CSSetShader(csGhosts, NULL, 0); context->Dispatch(WIDTH / 64 + 1, HEIGHT / 64 + 1, 1); setNullUAVSRV(); } // Merge context->CSSetUnorderedAccessViews(0, 1, &backBufferUAV, NULL); context->CSSetShaderResources(0, 8, mergeSRV); context->CSSetShader(csMerge, NULL, 0); context->Dispatch(WIDTH / 16, HEIGHT / 16, 1); setNullUAVSRV(); swapChain->Present(1, 0); #ifdef _DEBUG #ifndef SHADER_DEBUG if (::WaitForSingleObject(shaderCompileEvent, 0) == WAIT_OBJECT_0) { ::Sleep(50); CreateShaders(); ::Sleep(50); } #endif #endif } while (!GetAsyncKeyState(VK_ESCAPE) && (audio_MMTime.u.sample < MAX_SAMPLES)); usync_export(); ExitProcess(EXIT_SUCCESS); return EXIT_SUCCESS; }