Reputation: 23
so I am learning DirectX 11 and I was making stuff and I came across a debugging error (trying to access 0x00000000 from the swap chain) and I thought the CreateDeviceAndSwapChain was supposed to fix that but it didnt. Here is my code:
#include <windows.h>
#include <d3d11.h>
#include <d3dx11.h>
#include <dxgi.h>
#include "types.h"
//globals
RECT dimensions;
HWND hwnd;
//width and height of the window
uint width;
uint height;
//create the driver types
D3D_DRIVER_TYPE dt[] = {
D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP, D3D_DRIVER_TYPE_SOFTWARE
};
//create the feature level
D3D_FEATURE_LEVEL fl[] = {
D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_10_1
};
//create the selected drivertype
D3D_DRIVER_TYPE selectedDT;
//create the selected feature level
D3D_FEATURE_LEVEL* selectedFL;
//create driver types and feature level uints
uint totalDTs = ARRAYSIZE(dt);
uint totalFLs = ARRAYSIZE(fl);
//create the swap chain description
DXGI_SWAP_CHAIN_DESC scd;
//create the swap chain
IDXGISwapChain* swapchain;
//create the device
ID3D11Device* dev;
//create the context
ID3D11DeviceContext* context;
//create the render target view
ID3D11RenderTargetView *rtv;
//functions
void init();
void initswapchaindesc();
void createDevice();
void close();
// the WindowProc function prototype
LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// window handler
HWND hwnd;
// this struct holds information for the window class
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(WNDCLASSEX));
// fill the struct
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszClassName = "WindowClass1";
// register the window class
RegisterClassEx(&wc);
hwnd = CreateWindowEx(NULL,
"WindowClass1", // name of the window class
"Our First Windowed Program", // title of the window
WS_OVERLAPPEDWINDOW, // window style
300, // x-position of the window
300, // y-position of the window
800, // width of the window
600, // height of the window
NULL, // we have no parent window, NULL
NULL, // we aren't using menus, NULL
hInstance, // application handle
NULL); // used with multiple windows, NULL
// display the window
ShowWindow(hwnd, nCmdShow);
// enter the main loop:
init();
close();
MessageBox(hwnd, "Success!", "A message for you", NULL);
// this struct holds Windows event messages
MSG msg;
// wait for the next message in the queue
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
// the quit message
case WM_DESTROY:
{
//quit
PostQuitMessage(0);
return 0;
}
break;
}
// def message
return DefWindowProc (hwnd, message, wParam, lParam);
}
void init() {
GetClientRect(hwnd, &dimensions);
width = dimensions.right - dimensions.left;
height = dimensions.bottom - dimensions.top;
//initialize the swap chain description
ZeroMemory(&scd, sizeof(scd));
scd.BufferCount = 1;
scd.BufferDesc.Width = width;
scd.BufferDesc.Height = height;
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
scd.BufferDesc.RefreshRate.Denominator = 60;
scd.BufferDesc.RefreshRate.Numerator = 1;
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
scd.OutputWindow = hwnd;
scd.Windowed = true;
scd.SampleDesc.Count = 1;
scd.SampleDesc.Quality = 0;
uint creationflags;
#ifdef _DEBUG
creationflags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
HRESULT devcreateres;
uint driver = 0;
for(driver = 0; driver < totalDTs; ++driver) {
devcreateres = D3D11CreateDeviceAndSwapChain(0, dt[driver], 0, creationflags, fl, totalFLs,
D3D11_SDK_VERSION, &scd, &swapchain, &dev,
selectedFL, &context);
if(SUCCEEDED(devcreateres)) {
selectedDT = dt[driver];
}
}
//create the back buffer image
ID3D11Texture2D* backbuffer;
//error here - line 175
swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backbuffer);
dev->CreateRenderTargetView(backbuffer, NULL, &rtv);
backbuffer->Release();
context->OMSetRenderTargets(1, &rtv, NULL);
// Set the viewport
D3D11_VIEWPORT viewport;
ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = 800;
viewport.Height = 600;
context->RSSetViewports(1, &viewport);
}
void close() {
if(swapchain)
swapchain->Release();
if(dev)
dev->Release();
if(context)
context->Release();
if(rtv)
rtv->Release();
}
(btw the data type uint is defined as unsigned int.)
Please help!
Upvotes: 1
Views: 1979
Reputation: 330
If still applicable, I noticed that close()
was placed before the start of the while
(main) loop. It gets placed afterwards. Here's your section of code:
// enter the main loop:
init();
close();
MessageBox(hwnd, "Success!", "A message for you", NULL);
// this struct holds Windows event messages
MSG msg;
// wait for the next message in the queue
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
You need close()
to happen after the loop is closed. Note that placing something "inside the loop" means placing something literally, inside the while loop. Here, you want it to TranslateMessage(&msg);
, then DispatchMessage(&msg);
while(GetMessage(&msg, NULL, 0, 0)
is true. Additionally you want to run you own functions to happen in this loop.
As the loop happens over and over again, you want to draw your frame each time. To do this you can add else
, an run the function inside.
i.e:
// enter the main loop:
init();
MessageBox(hwnd, "Success!", "A message for you", NULL);
// this struct holds Windows event messages
MSG msg;
// wait for the next message in the queue
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
render(); //Your render function.
}
close(); //If this is run, the while loop has closed. This is a good opportunity
//to run close() before the function returns msg.wParam
return msg.wParam;
}
You could be getting the violation because the COM objects were released before the loop was started.
Upvotes: 1