# [DirectX9 Bitmaps] Can someone help me out with a nullptr check?

## Recommended Posts

//page 120
#include <Windows.h>
#include <windef.h>
#include <winuser.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

//#pragma comment (lib,"d3dx9.lib")
//#pragma comment (lib,"dxguid.lib")
//#pragma comment (lib,"winmm.lib")	//システム時刻取得に必要　｜　マルチメディアライブラリ(Windows Multimedia Library)
//#pragma comment (lib,"dinput8.lib")

#define APPTITLE "CreateSurface"

#define KEY_DOWN(vk_code)((GetAsyncKeyState(vk_code)&0x8000)?1:0)
#define KEY_UP(vk_code)((GetAsyncKeyState(vk_code)&0x8000)?1:0)

#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480

//function prototypes
LRESULT WINAPI WinProc(HWND, UINT, WPARAM, LPARAM);
ATOM MyRegisterClass(HINSTANCE);
int GameInit(HWND);
void GameRun(HWND);
void GameEnd(HWND);

//Direct3D Objects
LPDIRECT3D9 d3d = NULL;
LPDIRECT3DDEVICE9 d3ddev = NULL;
LPDIRECT3DSURFACE9 surface = NULL;
LPDIRECT3DSURFACE9 backbuffer = NULL;

LRESULT WINAPI WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_QUIT:
GameEnd(hWnd);
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}

//helper function to set up windows properties
ATOM MyRegisterClass(HINSTANCE hInstance)
{
// create struucture
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);

//fill the structure with information
wc.style			= CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc		= (WNDPROC)WinProc;
wc.cbClsExtra		= 0;
wc.cbWndExtra		= 0;
wc.hInstance		= hInstance;
wc.hIcon			= NULL;
wc.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszClassName	= APPTITLE;
wc.hIconSm			= NULL;

//set up the window with the class info
return RegisterClassEx(&wc);
}

//Entry point for a windows program
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int    nCmdShow)
{
MSG msg;

MyRegisterClass(hInstance);

HWND hWnd;

hWnd = CreateWindow(
APPTITLE,
APPTITLE,
WS_EX_TOPMOST | WS_VISIBLE | WS_POPUP,
CW_USEDEFAULT,
CW_USEDEFAULT,
SCREEN_WIDTH, SCREEN_HEIGHT,
NULL, NULL,
hInstance,
NULL
);

if (!hWnd)
{
return FALSE;
}

ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

if (!GameInit(hWnd))
{
return 0;
}

//Main Message loop
int done = 0;

while (!done)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
done = 1;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
GameRun(hWnd);
}
}
return msg.wParam;
}

int GameInit(HWND hwnd)
{
HRESULT result;

//initialize Direct3D
d3d = Direct3DCreate9(D3D_SDK_VERSION);

if (d3d == NULL)
{
MessageBox(hwnd, "Error initializing Direct3D", "Error", MB_OK);
return 0;
}

//set Direct3D presentation parameters
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));

d3dpp.Windowed = TRUE;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.BackBufferCount = 1;
d3dpp.BackBufferWidth = SCREEN_WIDTH;
d3dpp.BackBufferHeight = SCREEN_HEIGHT;
d3dpp.hDeviceWindow = hwnd;

//create Direct3D device
d3d->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev);

if (d3ddev = NULL)
{
MessageBox(hwnd, "Error creating Direct3D device", "Error", MB_OK);
return 0;
}

//set random number seed
srand(time(NULL));

//Clear the backbuffer to black
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
//Create pointer to back buffer
d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);

//create surface
result = d3ddev->CreateOffscreenPlainSurface(
100, 100,
D3DFMT_X8R8G8B8,
D3DPOOL_DEFAULT,
&surface,
NULL);

if (result!=D3D_OK)
{
return 1;
}

surface,
NULL, NULL,
"char.jpg",
NULL,
D3DX_DEFAULT,
0, NULL);
//make sure file was loaded fine
if (result != D3D_OK)
{
return 1;
}

//draw surface to back buffer
d3ddev->StretchRect(surface, NULL, backbuffer, NULL, D3DTEXF_NONE);

//return okay
return 1;
}

void GameRun(HWND hwnd)
{
RECT rect;
int r, g, b;

if (d3ddev == NULL)
{
return;
}

if (d3ddev->BeginScene())
{
//Create pointer to the back buffer
d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);

//draw surface to the back buffer
d3ddev->StretchRect(surface, NULL, backbuffer, NULL, D3DTEXF_NONE);

//stop rendering
d3ddev->EndScene();
}
d3ddev->Present(NULL, NULL, NULL, NULL);

//check for escape key to exit program
if (KEY_DOWN(VK_ESCAPE))
{
PostMessage(hwnd, WM_DESTROY, 0, 0);
}
}

void GameEnd(HWND hwnd)
{
//free the surface
surface->Release();

if (d3ddev != NULL)
{
d3ddev->Release();
}

if (d3d != NULL)
{
d3d->Release();
}
}

So this is the code. I'm following a book and I checked If I made any mistakes. The picture shows what the error is. Can someone help?

Also, what is the default location for a file/bitmap/jpg in my case?

##### Share on other sites

Here goes one problem

if (d3ddev = NULL)
{
MessageBox(hwnd, "Error creating Direct3D device", "Error", MB_OK);
return 0;
}

Use '==' to test for equivalancy. Which explains why you make it to the exception being thrown. I'm guessing this call is failing here. Make sure the values you are passing to this function are valid

d3d->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev);

Edited by markypooch

##### Share on other sites
3 minutes ago, markypooch said:

Here goes one problem


if (d3ddev = NULL)
{
MessageBox(hwnd, "Error creating Direct3D device", "Error", MB_OK);
return 0;
}

Which explains why you make it to the exception being thrown.

I'm guessing this call is failing here. Make sure the values you are passing to this function are valid


d3d->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev);

Not sure if this is the problem, the book has the same code for device as mine. Is there anything that could possibly be wrong?

##### Share on other sites

Trust me on this one. All technical books have errata. In this case I'm very much assuming the technical editor missed this. Add the '==' to that if condition, and you should see that error message box popup telling you that device creation failed.

##### Share on other sites
4 minutes ago, Jamal Nasir said:

Not sure if this is the problem, the book has the same code for device as mine.

Then it must be a typo, consider the following:

struct Foobar {
int x;
void frobnicate() {
cout << this->x;
}
};

int main() {
Foobar* f = new Foobar {3};
return -1;
}

f->frobnicate(); // This will always crash
delete f;
}

##### Share on other sites
3 minutes ago, markypooch said:

Trust me on this one. All technical books have errata. In this case I'm very much assuming the technical editor missed this. Add the '==' to that if condition, and you should see that error message box popup telling you that device creation failed.

Oh awesome! It works now, thank you so much!

##### Share on other sites

Rather than testing for NULL after CreateDevice you really should be testing the HRESULT it returns, using the SUCCEEDED and FAILED macros, with failure HRESULTs giving you some more info on why it failed.

You also have a nasty memory leak in that code - you need a surface->Release for each GetBackBuffer call. In this case it won't destroy the backbuffer because GetBackBuffer will increment the reference count for it, so Release will just decrement it; it doesn't get destroyed until the reference count goes to 0.

##### Share on other sites
On 6/19/2017 at 0:14 PM, Smarkus said:

d3d = Direct3DCreate9(D3D_SDK_VERSION);

this creates a d3d device, and d3d points to it.

On 6/19/2017 at 0:14 PM, Smarkus said:

if (d3d = NULL)  {

and then this sets d3d to NULL, then checks to see if d3d is zero or non-zero,  and executes the code block if its non-zero. Since it was just set to NULL (ie zero), its never non-zero, so the code block never executes, and you are always NULL-ing out your d3d device pointer. A guaranteed show stopper there.

this is because evaluating expressions inside the condition statement has a higher precedence (IE gets done first).

In the end its simply a typo quite common to c/c++.

lesson learned: always double check those == statements. its a typo that syntax checking can't pick up, which leads to a logic error. it can only be found by code inspection or testing (or both ?).

##### Share on other sites

I'd also recommend turning on the compiler warning that will catch this, by increasing the warning level to 4 in Visual Studio.

You could even go as far as turning that warning into an error by doing:

#pragma warning(error : 4706)

##### Share on other sites

I'd also recommend turning on the compiler warning that will catch this, by increasing the warning level to 4 in Visual Studio.

You could even go as far as turning that warning into an error by doing:


#pragma warning(error : 4706)

What might not be obvious is that you can make this an error even without bumping your warning level to 4 (although you should be compiling with warning level 2 or 3 at least, as well as with warnings-as-errors, anyway).

## Create an account

Register a new account

• 12
• 10
• 10
• 11
• 18
• ### Similar Content

• Do YOU play Horror Games; if so WHAT is your favourite and WHY?
Hello! I want to develop a Horror Game for PC and Consoles, however, I need to understand WHY people enjoy playing Horror Games.
Here's a list of Questions:
What's your favourite Horror Game and Why? What environment scares YOU the most? What Creature/ Enemy scares YOU the most? Do YOU like Maze's/ Labyrinths?  Do you enjoy Puzzles/ Riddles? Thanks for taking the time out of your day to read this topic, I appreciate it!

• Back around 2006 I spent a good year or two reading books, articles on this site, and gobbling up everything game dev related I could. I started an engine in DX10 and got through basics. I eventually gave up, because I couldn't do the harder things.
Now, my C++ is 12 years stronger, my mind is trained better, and I am thinking of giving it another go.
Alot has changed. There is no more SDK, there is evidently a DX Toolkit, XNA died, all the sweet sites I used to go to are 404, and google searches all point to Unity and Unreal.
I plainly don't like Unity or Unreal, but might learn them for reference.
So, what is the current path? Does everyone pretty much use the DX Toolkit? Should I start there? I also read that DX12 is just expert level DX11, so I guess I am going DX 11.
Is there a current and up to date list of learning resources anywhere?  I am about tired of 404s..

• Hi all. My project is coming along wonderfully, and am starting to consider alpha deployment, and would like your advice.
My project need access to 10,000 small PNG image files at runtime, each is only a few kilobytes each, which during development I used to load in directly from a fixed path on my HDD whenever one was needed (obviously not a solution for go-live), using something like this:
img = new WriteableBitmap(new BitmapImage(new Uri(@screenshotsPath + filename)));
The image would then be blitted onto a buffer screen, etc. etc. At a time, a few dozen would be being used.
Now I'm thinking about deployment, and also when I produce an update to my app, there could be more images to add to the folders. So I'm considering the best way of a) deploying the images to the user as part of the project, and b) how to most easily handle updates to the app, whereby more images will be added.
I have just experimented with adding them all as a Resource (!). This inflated the exe from 10mb to 100mb (not a major problem), increased the compile time from 3 secs to 30 secs (annoying), increased RAM usage from 500mb to 1.5gb (not a major problem either), but means that it solves my fixed directory issue, distribution issue, and update issue, simply by having the files all stuck into the executable. Here's the new code I'm using:
img = BitmapFactory.FromResource("Shots/" + filename);
The next thing I was going to try was to mark them as Content > Copy if Newer. This would resolve the executable size and RAM usage (and also the directory issue as well), however it seems that I'd need to highlight them all, and move them from Resource to Content. As an up-front job this isn't too bad, but as I add new images to the project, I'll need to go in and do this every time, which gets annoying, as the VS2015 default is Resource. Also, I'm not sure how this would work in terms of updates. Would something like ClickOnce deployment recognise new PNGs and install them to the users?

I also have 3,000 ZIP files (~500kb each) which also need deploying and updating in the same way. These are currently read directly from my HDD until I can find a permanent solution for adding these to the project as well.
Can anyone thing of a better way of doing what I'm trying to achieve?
Thanks for any help folks.

• Hi
I have a procedurally generated tiled landscape, and want to apply 'regional' information to the tiles at runtime; so Forests, Roads - pretty much anything that could be defined as a 'region'. Up until now I've done this by creating a mesh defining the 'region' on the CPU and interrogating that mesh during the landscape tile generation; I then add regional information to the landscape tile via a series of Vertex boolean properties. For each landscape tile vertex I do a ray-mesh intersect into the 'region' mesh and get some value from that mesh.

For example my landscape vertex could be;
struct Vtx { Vector3 Position; bool IsForest; bool IsRoad; bool IsRiver; } I would then have a region mesh defining a forest, another defining rivers etc. When generating my landscape veretexes I do an intersect check on the various 'region' meshes to see what kind of landscape that vertex falls within.

My ray-mesh intersect code isn't particularly fast, and there may be many 'region' meshes to interrogate, and I want to see if I can move this work onto the GPU, so that when I create a set of tile vertexes I can call a compute/other shader and pass the region mesh to it, and interrogate that mesh inside the shader. The output would be a buffer where all the landscape vertex boolean values have been filled in.

The way I see this being done is to pass in two RWStucturedBuffer to a compute shader, one containing the landscape vertexes, and the other containing some definition of the region mesh, (possibly the region might consist of two buffers containing a set of positions and indexes). The compute shader would do a ray-mesh intersect check on each landscape vertex and would set the boolean flags on a corresponding output buffer.

In theory this is a parallelisable operation (no one landscape vertex relies on another for its values) but I've not seen any examples of a ray-mesh intersect being done in a compute shader; so I'm wondering if my approach is wrong, and the reason I've not seen any examples, is because no-one does it that way. If anyone can comment on;
Is this a really bad idea ? If no-one does it that way, does everyone use a Texture to define this kind of 'region' information ? If so - given I've only got a small number of possible types of region, what Texture Format would be appropriate, as 32bits seems really wasteful. Is there a common other approach to adding information to a basic height-mapped tile system that would perform well for runtime generated tiles ? Thanks
Phillip

• I'm searching a more high resolution GeoTiff of http://www.naturalearthdata.com/downloads/10m-raster-data/10m-natural-earth-1/ since these are not sufficient if you need to zoom in...does anybody know a good source (free/paid) ? Thanks.