Direct 2d 1.1 access violation Need help
I am making a program in direct2D 1.1. I keep getting a access violation error when it reaches code
dxgiDevice->GetAdapter(&dxgiAdapter);
here is my header file
Code:
#pragma once
#pragma once
// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef WINVER // Allow use of features specific to Windows 7 or later.
#define WINVER 0x0700 // Change this to the appropriate value to target other versions of Windows.
#endif
#ifndef _WIN32_WINNT // Allow use of features specific to Windows 7 or later.
#define _WIN32_WINNT 0x0700 // Change this to the appropriate value to target other versions of Windows.
#endif
#ifndef UNICODE
#define UNICODE
#endif
// Exclude rarely-used items from Windows headers.
#define WIN32_LEAN_AND_MEAN
// Windows Header Files:
#include <windows.h>
// C RunTime Header Files:
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <wchar.h>
#include <math.h>
#include <d2d1.h>
#include <d2d1helper.h>
#include <d2d1_1.h>
#include <d2d1_1helper.h>
#include <dwrite.h>
#include <wincodec.h>
#include <d3d11_1.h>
#include <d2d1effects.h>
#include <d2d1effecthelpers.h>
#include <dwrite.h>
#include <dwrite_1.h>
/******************************************************************
* *
* Macros *
* *
******************************************************************/
template<class Interface>
inline void SafeRelease(
Interface **ppInterfaceToRelease
)
{
if (*ppInterfaceToRelease != NULL)
{
(*ppInterfaceToRelease)->Release();
(*ppInterfaceToRelease) = NULL;
}
}
#ifndef Assert
#if defined( DEBUG ) || defined( _DEBUG )
#define Assert(b) do {if (!(b)) {OutputDebugStringA("Assert: " #b "\n");}} while(0)
#else
#define Assert(b)
#endif //DEBUG || _DEBUG
#endif
#ifndef HINST_THISCOMPONENT
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)
#endif
//
// DemoApp class declaration
//
class DemoApp
{
public:
DemoApp();
~DemoApp();
// Register the window class and call methods for instantiating drawing resources
HRESULT Initialize();
// Process and dispatch messages
void RunMessageLoop();
void OpenFilePicker();
void OpenFile();
private:
// Initialize device-independent resources.
HRESULT CreateDeviceIndependentResources();
// Initialize device-dependent resources.
HRESULT CreateDeviceResources();
// Release device-dependent resource.
void DiscardDeviceResources();
// Draw content.
HRESULT OnRender();
// Resize the render target.
void OnResize(
UINT width,
UINT height
);
// The windows procedure.
static LRESULT CALLBACK WndProc(
HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam
);
private:
HWND m_hwnd;
ID2D1Factory1* Direct2DFactory;
ID2D1DeviceContext* m_pRenderTarget;
ID2D1SolidColorBrush* m_pLightSlateGrayBrush;
ID2D1SolidColorBrush* m_pCornflowerBlueBrush;
ID3D11Device1* Direct3DDevice;
ID3D11DeviceContext1* Direct3dContext;
ID2D1Device* Direct2DDevice;
IDXGISwapChain1* DXGISwapChain;
ID2D1Bitmap1* Direct2DBackBuffer;
ID2D1DeviceContext *Screen;
IDXGIDevice *dxgiDevice;
IDXGIAdapter *dxgiAdapter;
IDXGIFactory2 *dxgiFactory;
};
and here is my implementation file
Code:
#include "DemoApp.h"
#include<wrl.h>
// Provides the application entry point.
int WINAPI WinMain(
HINSTANCE /* hInstance */,
HINSTANCE /* hPrevInstance */,
LPSTR /* lpCmdLine */,
int /* nCmdShow */
)
{
// Use HeapSetInformation to specify that the process should
// terminate if the heap manager detects an error in any heap used
// by the process.
// The return value is ignored, because we want to continue running in the
// unlikely event that HeapSetInformation fails.
HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
if (SUCCEEDED(CoInitialize(NULL)))
{
{
DemoApp app;
if (SUCCEEDED(app.Initialize()))
{
app.RunMessageLoop();
}
}
CoUninitialize();
}
return 0;
}
// DemoApp constructor
DemoApp::DemoApp() :
m_hwnd(NULL),
Direct2DFactory(NULL),
m_pRenderTarget(NULL),
m_pLightSlateGrayBrush(NULL),
m_pCornflowerBlueBrush(NULL),
dxgiDevice(NULL),
dxgiAdapter(NULL),
dxgiFactory(NULL),
Direct3DDevice(NULL),
Direct3dContext(NULL),
Direct2DDevice(NULL),
DXGISwapChain(NULL),
Direct2DBackBuffer(NULL),
Screen(NULL)
{
}
// DemoApp destructor
// Releases the application's resources.
DemoApp::~DemoApp()
{
SafeRelease(&Direct2DFactory);
SafeRelease(&m_pRenderTarget);
SafeRelease(&m_pLightSlateGrayBrush);
SafeRelease(&m_pCornflowerBlueBrush);
}
// Creates the application window and device-independent
// resources.
HRESULT DemoApp::Initialize()
{
HRESULT hr;
// Initialize device-indpendent resources, such
// as the Direct2D factory.
hr = CreateDeviceIndependentResources();
if (SUCCEEDED(hr))
{
// Register the window class.
WNDCLASSEX wcex = { sizeof(WNDCLASSEX) };
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = DemoApp::WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = sizeof(LONG_PTR);
wcex.hInstance = HINST_THISCOMPONENT;
wcex.hbrBackground = NULL;
wcex.lpszMenuName = NULL;
wcex.hCursor = LoadCursor(NULL, IDI_APPLICATION);
wcex.lpszClassName = L"D2DDemoApp";
RegisterClassEx(&wcex);
dxgiDevice->GetAdapter(&dxgiAdapter);
dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory));
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
swapChainDesc.Width = 0;
swapChainDesc.Height = 0;
swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
swapChainDesc.Stereo = false;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 1;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = 2;
swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
swapChainDesc.Flags = 0;
dxgiFactory->CreateSwapChainForHwnd(Direct3DDevice, m_hwnd, &swapChainDesc, nullptr, nullptr, &DXGISwapChain);
IDXGISurface *dxgiBackBuffer;
DXGISwapChain->GetBuffer(0, IID_PPV_ARGS(&dxgiBackBuffer));
// Because the CreateWindow function takes its size in pixels,
// obtain the system DPI and use it to scale the window size.
FLOAT dpiX, dpiY;
// The factory returns the current system DPI. This is also the value it will use
// to create its own windows.
Direct2DFactory->GetDesktopDpi(&dpiX, &dpiY);
D2D1_BITMAP_PROPERTIES1 bitmapProperties =
D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE), dpiX, dpiY);
Screen->CreateBitmapFromDxgiSurface(dxgiBackBuffer, &bitmapProperties, &Direct2DBackBuffer);
Screen->SetTarget(Direct2DBackBuffer);
// Create the window.
m_hwnd = CreateWindow(
L"D2DDemoApp",
L"Direct2D Demo App",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
static_cast<UINT>(ceil(640.f * dpiX / 96.f)),
static_cast<UINT>(ceil(480.f * dpiY / 96.f)),
NULL,
NULL,
HINST_THISCOMPONENT,
this
);
hr = m_hwnd ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
ShowWindow(m_hwnd, SW_SHOWNORMAL);
UpdateWindow(m_hwnd);
}
}
return hr;
}
// Creates resources that are not bound to a particular device.
// Their lifetime effectively extends for the duration of the
// application.
HRESULT DemoApp::CreateDeviceIndependentResources()
{
HRESULT hr = S_OK;
D2D1_FACTORY_OPTIONS options;
ZeroMemory(&options, sizeof(D2D1_FACTORY_OPTIONS));
// Create a Direct2D factory.
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory1), &options, reinterpret_cast<void **>(&Direct2DFactory));
return hr;
}
// Creates resources that are bound to a particular
// Direct3D device. These resources need to be recreated
// if the Direct3D device dissapears, such as when the display
// changes, the window is remoted, etc.
HRESULT DemoApp::CreateDeviceResources()
{
HRESULT hr = S_OK;
if (!m_pRenderTarget)
{
RECT rc;
GetClientRect(m_hwnd, &rc);
D2D1_SIZE_U size = D2D1::SizeU(
rc.right - rc.left,
rc.bottom - rc.top
);
// Create a Direct2D render target.
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_3,
D3D_FEATURE_LEVEL_9_2,
D3D_FEATURE_LEVEL_9_1
};
UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
ID3D11Device *device;
ID3D11DeviceContext *context;
D3D_FEATURE_LEVEL returnedFeatureLevel;
D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, 0, creationFlags, featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION,
&device, &returnedFeatureLevel, &context);
device->QueryInterface(__uuidof(ID3D11Device1), (void **)&Direct3DDevice);
context->QueryInterface(__uuidof(ID3D11DeviceContext1), (void **)&Direct3dContext);
Direct3DDevice->QueryInterface(__uuidof(IDXGIDevice), (void **)&dxgiDevice);
Direct2DFactory->CreateDevice(dxgiDevice, &Direct2DDevice);
Direct2DDevice->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &Screen);
if (SUCCEEDED(hr))
{
// Create a gray brush.
hr = m_pRenderTarget->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::LightSlateGray),
&m_pLightSlateGrayBrush
);
}
if (SUCCEEDED(hr))
{
// Create a blue brush.
hr = m_pRenderTarget->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::CornflowerBlue),
&m_pCornflowerBlueBrush
);
}
}
return hr;
}
// Discards device-dependent resources. These resources must be
// recreated when the Direct3D device is lost.
void DemoApp::DiscardDeviceResources()
{
SafeRelease(&m_pRenderTarget);
SafeRelease(&m_pLightSlateGrayBrush);
SafeRelease(&m_pCornflowerBlueBrush);
SafeRelease(&Direct2DBackBuffer);
SafeRelease(&DXGISwapChain);
SafeRelease(&Screen);
SafeRelease(&Direct2DDevice);
SafeRelease(&Direct3dContext);
SafeRelease(&Direct3DDevice);
}
// Runs the main window message loop.
void DemoApp::RunMessageLoop()
{
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
// This method discards device-specific
// resources if the Direct3D device dissapears during execution and
// recreates the resources the next time it's invoked.
HRESULT DemoApp::OnRender()
{
HRESULT hr = S_OK;
hr = CreateDeviceResources();
if (SUCCEEDED(hr))
{
m_pRenderTarget->BeginDraw();
m_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));
D2D1_SIZE_F rtSize = m_pRenderTarget->GetSize();
// Draw a grid background.
int width = static_cast<int>(rtSize.width);
int height = static_cast<int>(rtSize.height);
for (int x = 0; x < width; x += 10)
{
m_pRenderTarget->DrawLine(
D2D1::Point2F(static_cast<FLOAT>(x), 0.0f),
D2D1::Point2F(static_cast<FLOAT>(x), rtSize.height),
m_pLightSlateGrayBrush,
0.5f
);
}
for (int y = 0; y < height; y += 10)
{
m_pRenderTarget->DrawLine(
D2D1::Point2F(0.0f, static_cast<FLOAT>(y)),
D2D1::Point2F(rtSize.width, static_cast<FLOAT>(y)),
m_pLightSlateGrayBrush,
0.5f
);
}
// Draw two rectangles.
D2D1_RECT_F rectangle1 = D2D1::RectF(
rtSize.width/2 - 50.0f,
rtSize.height/2 - 50.0f,
rtSize.width/2 + 50.0f,
rtSize.height/2 + 50.0f
);
D2D1_RECT_F rectangle2 = D2D1::RectF(
rtSize.width/2 - 100.0f,
rtSize.height/2 - 100.0f,
rtSize.width/2 + 100.0f,
rtSize.height/2 + 100.0f
);
// Draw a filled rectangle.
m_pRenderTarget->FillRectangle(&rectangle1, m_pLightSlateGrayBrush);
// Draw the outline of a rectangle.
m_pRenderTarget->DrawRectangle(&rectangle2, m_pCornflowerBlueBrush);
hr = m_pRenderTarget->EndDraw();
DXGI_PRESENT_PARAMETERS parameters = { 0 };
parameters.DirtyRectsCount = 0;
parameters.pDirtyRects = nullptr;
parameters.pScrollRect = nullptr;
parameters.pScrollOffset = nullptr;
hr = DXGISwapChain->Present1(1, 0, ¶meters);
}
if (hr == D2DERR_RECREATE_TARGET)
{
hr = S_OK;
DiscardDeviceResources();
}
return hr;
}
// If the application receives a WM_SIZE message, this method
// resizes the render target appropriately.
void DemoApp::OnResize(UINT width, UINT height)
{
if (m_pRenderTarget)
{
// Note: This method can fail, but it's okay to ignore the
// error here, because the error will be returned again
// the next time EndDraw is called.
}
}
// Handles window messages.
LRESULT CALLBACK DemoApp::WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
LRESULT result = 0;
if (message == WM_CREATE)
{
LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam;
DemoApp *pDemoApp = (DemoApp *)pcs->lpCreateParams;
::SetWindowLongPtrW(
hwnd,
GWLP_USERDATA,
PtrToUlong(pDemoApp)
);
result = 1;
}
else
{
DemoApp *pDemoApp = reinterpret_cast<DemoApp *>(static_cast<LONG_PTR>(
::GetWindowLongPtrW(
hwnd,
GWLP_USERDATA
)));
bool wasHandled = false;
if (pDemoApp)
{
switch (message)
{
case WM_SIZE:
{
UINT width = LOWORD(lParam);
UINT height = HIWORD(lParam);
}
result = 0;
wasHandled = true;
break;
case WM_DISPLAYCHANGE:
{
InvalidateRect(hwnd, NULL, FALSE);
}
result = 0;
wasHandled = true;
break;
case WM_PAINT:
{
pDemoApp->OnRender();
ValidateRect(hwnd, NULL);
}
result = 0;
wasHandled = true;
break;
case WM_DESTROY:
{
PostQuitMessage(0);
}
result = 1;
wasHandled = true;
break;
}
}
if (!wasHandled)
{
result = DefWindowProc(hwnd, message, wParam, lParam);
}
}
return result;
}
I don't know if any of the code for the swapchain are in the correct spots though. Hope someone can help.
Re: Direct 2d 1.1 access violation Need help
Quote:
Originally Posted by
william3711
I am making a program in direct2D 1.1. I keep getting a access violation error when it reaches code
dxgiDevice->GetAdapter(&dxgiAdapter);
What is the dxgiDevice? Where and how do you define it? What is its value while an access violation happens?
Re: Direct 2d 1.1 access violation Need help
Looking at the code, I understand that dxgiAdapter is initialised in CreateDeviceResources, which is called from OnRender, which is called from the WM_PAINT message once the message loop has been established. However, you are referring to dxgiAdapter in Initialize before you have created the window and before you start the message loop. Hence dxgiAdapter has not been set before it is used.