1
\$\begingroup\$

I saw Lazy Foo using OpenGL & GLSL in SDL, but I want to use DirectX 11 & HLSL in SDL.

Is there a way to do this, and how?

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

This old post but might help others.

After you initialize and create window with SDL successfully, get the HWND from SDL_SysWMinfo as shown below,

SDL_SysWMinfo wmInfo; SDL_VERSION(&wmInfo.version); SDL_GetWindowWMInfo(window, &wmInfo); HWND hwnd = wmInfo.info.win.window; 

After this you can proceed normally and on how you would create and initialize a D3D11 device and swap chain. When you fill in the DXGI_SWAP_CHAIN_DESC you can set the OutputWindow field to the HWND obtained above.

swapChainDesc.OutputWindow = hwnd; 

Below is a sample code that will create D3D11 device, swap chain and clears the background to a color.

//Using SDL and standard IO #include <SDL.h> #include <stdio.h> #include <SDL_syswm.h> #include<dxgi.h> #include<d3d11.h> #include<d3dcompiler.h> #pragma comment(lib, "dxgi") #pragma comment(lib, "d3d11") #pragma comment(lib, "D3DCompiler") //Screen dimension constants const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; int main(int argc, char* args[]) { //The window we'll be rendering to SDL_Window* window = NULL; //The surface contained by the window SDL_Surface* screenSurface = NULL; //D3D11 Stuff..... D3D_FEATURE_LEVEL featureLevelsRequested = D3D_FEATURE_LEVEL_11_0; D3D_FEATURE_LEVEL featureLevelsSupported; ID3D11Device* pD3D11Dev = NULL; ID3D11DeviceContext* pD3D11DevContext = NULL; IDXGISwapChain *pSwapChain = NULL; ID3D11Texture2D *pRenderTargetResource = NULL; ID3D11RenderTargetView *pBackBuffer = NULL; //Initialize SDL if (SDL_Init(SDL_INIT_VIDEO) < 0) { printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError()); } else { //Create window window = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (window == NULL) { printf("Window could not be created! SDL_Error: %s\n", SDL_GetError()); } else { // Get Window HWND SDL_SysWMinfo wmInfo; SDL_VERSION(&wmInfo.version); SDL_GetWindowWMInfo(window, &wmInfo); HWND hwnd = wmInfo.info.win.window; //Swap Chain Desc DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; swapChainDesc.BufferCount = 1; swapChainDesc.BufferDesc.Width = SCREEN_WIDTH; swapChainDesc.BufferDesc.Height = SCREEN_HEIGHT; swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.BufferDesc.RefreshRate.Numerator = 60; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.OutputWindow = hwnd; swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.Windowed = TRUE; //Create device and swap chain HRESULT d3dHR = D3D11CreateDeviceAndSwapChain( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_DEBUG, &featureLevelsRequested, 1, D3D11_SDK_VERSION, &swapChainDesc, &pSwapChain, &pD3D11Dev, &featureLevelsSupported, &pD3D11DevContext ); if (d3dHR != S_OK) { return 0; } // Create ID3D11Texture2D resource as a buffer to draw stuff on pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pRenderTargetResource); if (pRenderTargetResource != NULL) { pD3D11Dev->CreateRenderTargetView(pRenderTargetResource, NULL, &pBackBuffer); pRenderTargetResource->Release(); pD3D11DevContext->OMSetRenderTargets(1, &pBackBuffer, NULL); } //Viewport setup D3D11_VIEWPORT viewPort = {}; viewPort.TopLeftX = 0; viewPort.TopLeftY = 0; viewPort.Width = SCREEN_WIDTH; viewPort.Height = SCREEN_HEIGHT; pD3D11DevContext->RSSetViewports(1, &viewPort); //Get window surface screenSurface = SDL_GetWindowSurface(window); //Fill the surface white SDL_FillRect(screenSurface, NULL, SDL_MapRGB(screenSurface->format, 0xFF, 0xFF, 0xFF)); //Update the surface SDL_UpdateWindowSurface(window); //Hack to get window to stay up SDL_Event e; bool quit = false; while (quit == false) { //D3D Render stuff FLOAT backgroundColor[4] = { 0.0f, 0.2f, 0.2f, 1.0f }; pD3D11DevContext->ClearRenderTargetView(pBackBuffer, backgroundColor); pSwapChain->Present(1, 0); // Flip/Swap the back and front buffer while (SDL_PollEvent(&e)) { if (e.type == SDL_QUIT) { quit = true; } } } } } //D3D Cleanup pSwapChain->Release(); pBackBuffer->Release(); pD3D11Dev->Release(); pD3D11DevContext->Release(); //Destroy window SDL_DestroyWindow(window); //Quit SDL subsystems SDL_Quit(); return 0; } 
\$\endgroup\$
1
  • \$\begingroup\$ I'm not sure if neccesary manage manually DirectX 11 initialization: there is a SDL_render_d3d11.c file within the SDL sources, so probably if you simply start a renderer of that type all the DirectX 11 stuff is made inside SDL2 internally? \$\endgroup\$ Commented Oct 31, 2024 at 11:45

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.