I have been trying (futilly I might add) to learn DirectX. I thought I was
making progress today, but I can't figure this out. I have four images that
I want to draw on the back buffer. I know that they should be used as
sprites, but right now I just want to display them to the back buffer. I
have successfully displayed one to the back buffer, but when I altered the
code to dsplay the others too I started getting Access Violations. What is
an access violation anyway? I've been searching the internet all day trying
to find a simple definition of what causes it, but all I've found were very
specific cases. The code compiles and links correctly:
#include <windows.h>
#include <tchar.h>
#include <d3d10.h>
#include <d3dx10.h>
#include <windows.h>
HINSTANCE hInst;
HWND wndHandle;
int width = 640;
int height = 480;
ID3D10Device* pD3DDevice = NULL;
IDXGISwapChain* pSwapChain = NULL;
ID3D10RenderTargetView* pRenderTargetView = NULL;
bool InitWindow(HINSTANCE hInstance, int width, int height);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
bool InitDirect3D(HWND hWnd, int width, int height);
void Render();
void ShutdownDirect3D();
ID3D10Texture2D* GetTexture2DFromFile(LPCWSTR filename);
//My functions
void print(LPCWSTR message);
//My variables
ID3D10Texture2D* srcTexture[4];
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR
lpCmdLine, int nCmdShow)
{
if (!InitWindow(hInstance, width, height))
{
return false;
}
if (!InitDirect3D(wndHandle, width, height))
{
return 0;
}
MSG msg = {0};
while (WM_QUIT != msg.message)
{
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) == TRUE)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Render();
}
return (int) msg.wParam;
}
bool InitWindow(HINSTANCE hInstance, int width, int height)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC) WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = 0;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH) (COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = TEXT("DirectXExample");
wcex.hIconSm = 0;
RegisterClassEx(&wcex);
RECT rect = {0, 0, width, height};
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
wndHandle = CreateWindow(TEXT("DirectXExample"),
TEXT("DirectXExample"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
rect.right - rect.left,
rect.bottom - rect.top,
NULL,
NULL,
hInstance,
NULL);
if (!wndHandle)
{
return false;
}
ShowWindow(wndHandle, SW_SHOW);
UpdateWindow(wndHandle);
return true;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
switch (message)
{
case WM_KEYDOWN:
switch (wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
break;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
bool InitDirect3D(HWND hWnd, int width, int height)
{
DXGI_SWAP_CHAIN_DESC swapChainDesc;
ZeroMemory (&swapChainDesc, sizeof(swapChainDesc));
swapChainDesc.BufferCount = 1;
swapChainDesc.BufferDesc.Width = width;
swapChainDesc.BufferDesc.Height = 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;
HRESULT hr = D3D10CreateDeviceAndSwapChain(NULL,
D3D10_DRIVER_TYPE_REFERENCE,
NULL,
0,
D3D10_SDK_VERSION,
&swapChainDesc,
&pSwapChain,
&pD3DDevice);
if (hr != S_OK)
{
return false;
}
ID3D10Texture2D* pBackBuffer;
hr = pSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*)
&pBackBuffer);
if (hr != S_OK)
{
return false;
}
hr = pD3DDevice->CreateRenderTargetView(pBackBuffer, NULL,
&pRenderTargetView);
pBackBuffer->Release();
if (hr != S_OK)
{
return false;
}
pD3DDevice->OMSetRenderTargets(1, &pRenderTargetView, NULL);
D3D10_VIEWPORT viewPort;
viewPort.Width = width;
viewPort.Height = height;
viewPort.MinDepth = 0.0f;
viewPort.MaxDepth = 1.0f;
viewPort.TopLeftX = 0;
viewPort.TopLeftY = 0;
pD3DDevice->RSSetViewports(1, &viewPort);
srcTexture[1] = GetTexture2DFromFile(TEXT("./warrior.gif"));
srcTexture[2] = GetTexture2DFromFile(TEXT("./thief.gif"));
srcTexture[3] = GetTexture2DFromFile(TEXT("./whitemage.gif"));
srcTexture[4] = GetTexture2DFromFile(TEXT("./blackmage.gif"));
return true;
}
void Render()
{
if (pD3DDevice != NULL)
{
pD3DDevice->ClearRenderTargetView(pRenderTargetView, D3DXCOLOR(0.0f, 1.0f,
0.0f, 0.0f));
// Get a pointer to the back buffer texture
ID3D10Texture2D *pBackBuffer;
HRESULT hr = pSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D),
(LPVOID*)&pBackBuffer);
if(FAILED(hr))
{
return;
}
D3D10_TEXTURE2D_DESC desc[4];
D3D10_BOX sourceRegion[4];
for (int i = 0; i < 4; i++)
{
// fill a D3D10_TEXTURE2D_DESC with the texture details
srcTexture[1]->GetDesc(&desc[i]);
// create the source region using the width and height from the
// D3D10_TEXTURE2D_DESC structure
sourceRegion[i].left = 0;
sourceRegion[i].right = desc[i].Width;
sourceRegion[i].top = 0;
sourceRegion[i].bottom = desc[i].Height;
sourceRegion[i].front = 0;
sourceRegion[i].back = 1;
// Copy part of a texture resource to the back buffer texture
// The last parameter is a D3D10_BOX structure which defines the rectangle
to copy to the back
// buffer. Passing in 0 will copy the whole buffer.
pD3DDevice->CopySubresourceRegion(pBackBuffer, 0, 0, i * 100, 0,
srcTexture[i], 0, &sourceRegion[i]);
}
pSwapChain->Present(0, 0);
}
}
void ShutdownDirect3D()
{
if (pRenderTargetView)
{
pRenderTargetView->Release();
}
if (pSwapChain)
{
pSwapChain->Release();
}
if (pD3DDevice)
{
pD3DDevice->Release();
}
}
ID3D10Texture2D* GetTexture2DFromFile(LPCWSTR filename)
{
ID3D10Texture2D* texture2D = NULL;
ID3D10Resource* pD3D10Resource = NULL;
//Loads the texture into the temporary ID3D10Resource object
HRESULT hr = D3DX10CreateTextureFromFile(pD3DDevice,
filename,
NULL,
NULL,
&pD3D10Resource,
NULL);
//Make sure the texture was loaded in successfully
if (FAILED(hr))
{
return NULL;
}
//Translates the ID3D10Resource object into a ID3D10Texture2D object
pD3D10Resource->QueryInterface(__uuidof(ID3D10Texture2D),
(LPVOID*)&texture2D);
pD3D10Resource->Release();
//returns the ID3D10Texture2D object
return texture2D;
}
void print(LPCWSTR message)
{
MessageBox(NULL, message, TEXT("OurRPG"), MB_OK);
}
I think the access violation is taking place on the line that says
pD3DDevice->CopySubresourceRegion(pBackBuffer, 0, 0, i * 100, 0,
srcTexture[i], 0, &sourceRegion[i]);
when i = 0
The message I get is Unhandled exception at 0x00000000 in OurRPG.exe:
0xC0000005: Access violation.
No symbols are loaded for any call stack frame. The source code cannot be
displayed.
Is there a way I can turn on debugging symbols? I'm using Visual C++
Express 2008.:
[Non-text portions of this message have been removed]