• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
RoundPotato

Direct3D11 dev->CreateVertexShader() crashes the program.

15 posts in this topic

Hello there,

 

I've pinned the crash down to its position and it turned out to be:

dev->CreateVertexShader(vBlob->GetBufferPointer(),vBlob->GetBufferSize(),NULL,&vs);

 

It is inside "void initPipeline()"...

 

From:

#include <windows.h>
#include <windowsx.h>
#include <d3d11.h>
#include <d3dcompiler.h>

#pragma comment(lib,"d3d11.lib")
#pragma comment(lib,"d3dcompiler.lib")

#define SCREEN_WIDTH 1366
#define SCREEN_HEIGHT 786

// COM pointers
ID3D11Device *dev;
ID3D11DeviceContext *devCon;
IDXGISwapChain *sc;
ID3D11RenderTargetView *backBuffer;
ID3D11VertexShader *vs;
ID3D11PixelShader *ps;
ID3D11Buffer *vBuffer;
ID3D11InputLayout *il;

// VERTEX struct
struct VERTEX
{
	FLOAT x,y,z;
	FLOAT color[4];
};

void renderFrame()
{
	float color[4] = {0.0,0.2,0.4,1.0};
	devCon->ClearRenderTargetView(backBuffer,color);
	/*
	// set Vertex buffers
	UINT size = sizeof(VERTEX);
	UINT offset = 0;
	devCon->IASetVertexBuffers(0,1,&vBuffer,&size,&offset);
	
	// set primitives rendering style
	devCon->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

	// draw vertex onto back buffer
	devCon->Draw(3,0);
	*/
	// swap buffers
	sc->Present(0,0);
}

void initPipeline()
{
	// load Shaders
	ID3D10Blob *vBlob,*pBlob;
	D3DCompileFromFile(L"Shaders.hlsl",NULL,NULL,"PShader","ps_5_0",NULL,NULL,&pBlob,NULL);
	D3DCompileFromFile(L"Shaders.hlsl",NULL,NULL,"VShader","vs_5_0",NULL,NULL,&vBlob,NULL);
	
	// create Shader objects
	//dev->CreatePixelShader(pBlob->GetBufferPointer(),pBlob->GetBufferSize(),NULL,&ps);
	//dev->CreatePixelShader(pBlob->GetBufferPointer(),pBlob->GetBufferSize(),NULL,&ps);
	dev->CreateVertexShader(vBlob->GetBufferPointer(),vBlob->GetBufferSize(),NULL,&vs);
	/*
	// set Shaders
	devCon->VSSetShader(vs,NULL,NULL);
	devCon->PSSetShader(ps,NULL,NULL);
	*/
	/*
	// Describe Input Layout
	D3D11_INPUT_ELEMENT_DESC ied[] = 
	{
		{"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0},
		{"COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,D3D11_APPEND_ALIGNED_ELEMENT,D3D11_INPUT_PER_VERTEX_DATA,0}
	};

	// Create Input Layout
	dev->CreateInputLayout(ied,2,vBlob->GetBufferPointer(),vBlob->GetBufferSize(),&il);

	// set Input Layout
	devCon->IASetInputLayout(il);
	*/
}

void initGraphics()
{
	// create a triangle using the VERTEX struct
	VERTEX verts[] =
	{
		{0.0f, 0.5f, 0.0f, (1.0f, 0.0f, 0.0f, 1.0f)},
		{0.45f, -0.5, 0.0f, (0.0f, 1.0f, 0.0f, 1.0f)},
		{-0.45f, -0.5f, 0.0f, (0.0f, 0.0f, 1.0f, 1.0f)}
	};

	// create buffer
	D3D11_BUFFER_DESC bd;
	ZeroMemory(&bd,sizeof(D3D11_BUFFER_DESC));

	bd.Usage = D3D11_USAGE_DYNAMIC;
	bd.ByteWidth = sizeof(VERTEX)*3;
	bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
	bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;

	dev->CreateBuffer(&bd,NULL,&vBuffer);

	D3D11_MAPPED_SUBRESOURCE msr;
	devCon->Map(vBuffer,NULL,D3D11_MAP_WRITE_DISCARD,NULL,&msr);
	memcpy(msr.pData,verts,sizeof(verts));
	devCon->Unmap(vBuffer,NULL);
}

void initD3D(HWND hWnd)
{
	DXGI_SWAP_CHAIN_DESC scd;
	ZeroMemory(&scd,sizeof(DXGI_SWAP_CHAIN_DESC));

	scd.BufferCount = 1;
	scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	scd.BufferDesc.Width = SCREEN_WIDTH;
	scd.BufferDesc.Height = SCREEN_HEIGHT;
	scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	scd.OutputWindow = hWnd;
	scd.SampleDesc.Count = 4;
	scd.Windowed = TRUE;
	scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;

	D3D11CreateDeviceAndSwapChain(NULL,D3D_DRIVER_TYPE_HARDWARE,NULL,NULL,NULL,NULL,D3D11_SDK_VERSION,&scd,&sc,&dev,NULL,&devCon);

	ID3D11Texture2D *t2D;
	sc->GetBuffer(0,__uuidof(ID3D11Texture2D),(LPVOID*)&t2D);
	dev->CreateRenderTargetView(t2D,NULL,&backBuffer);
	t2D->Release();
	devCon->OMSetRenderTargets(1,&backBuffer,NULL);

	/* crappy viewport
	D3D11_VIEWPORT vp;
	ZeroMemory(&vp,sizeof(D3D11_VIEWPORT));

	vp.TopLeftX = 0;
	vp.TopLeftY = 0;
	vp.Width = SCREEN_WIDTH;
	vp.Height = SCREEN_HEIGHT;
	devCon->RSSetViewports(1,&vp);
	*/
}

void cleanD3D()
{
	// turn off FullScreen
	sc->SetFullscreenState(FALSE,NULL);

	// release COM objects' resources
	il->Release();
	vBuffer->Release();
	vs->Release();
	ps->Release();
	dev->Release();
	devCon->Release();
	backBuffer->Release();
	sc->Release();
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
	switch(msg)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}

	// return default-managed values
	return DefWindowProc(hWnd,msg,wParam,lParam);
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lCmdLIne,int nCmdShow)
{
	WNDCLASSEX wc;
	ZeroMemory(&wc,sizeof(WNDCLASSEX));

	wc.cbSize = sizeof(WNDCLASSEX);
	wc.hInstance = hInstance;
	wc.lpfnWndProc = WndProc;
	wc.style = CS_HREDRAW | CS_VREDRAW;
	//wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
	wc.hCursor = LoadCursor(NULL,IDC_ARROW);
	wc.lpszClassName = L"WindowClass1";

	RegisterClassEx(&wc);

	RECT wRect = {0,0,SCREEN_WIDTH,SCREEN_HEIGHT};
	AdjustWindowRect(&wRect,WS_OVERLAPPEDWINDOW,FALSE);
	HWND hWnd = CreateWindowEx(NULL,L"WindowClass1",L"MY MEGA WINDOW",WS_OVERLAPPEDWINDOW,0,0,wRect.right - wRect.left,wRect.bottom - wRect.top,NULL,NULL,hInstance,NULL);
	ShowWindow(hWnd,SW_SHOWMAXIMIZED);

	initD3D(hWnd);
	initPipeline();
	//initGraphics();

	MSG msg = {0};

	while(true)
	{
		if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
			if(msg.message == WM_QUIT) break;
		}
		else
		{
			renderFrame();
			// 50 FPS  (1000/20)
			Sleep(20);
		}
	}

	cleanD3D();

	return msg.wParam;
}

 

 

Both Pixel and Vertex Shader creation crashed the program, I don't even know what to think. Anyone has any ideas ? sad.png

0

Share this post


Link to post
Share on other sites
First read here!

And yeah, like I said earlier, directxtutorial.com lacks error checking. Check the HRESULT from the compile call with the check macros (e.g. SUCCEEDED).

Also: Make sure the shader file is where your app is looking for. The working directory of Visual Studio is usually not where your exe is.
0

Share this post


Link to post
Share on other sites

[attachment=15502:Desktop.zip][attachment=15502:Desktop.zip]I don't know what do you mean by Shaders compiling, but the statements where there are "compiled into blobs" is fine, it is the very creation I mentioned.

 

Yes the shader file is in the projects and I have copied over the necessary x86 .dll to where the .exe is (will probably ask how to get rid of it later).

 

I don't know how to check for those error codes you mentioned, I don't think it will be useful if it just returns true or false since it crashes on that statement anyway.

 

Please see attached videos of the crash and debug.

0

Share this post


Link to post
Share on other sites

Those videos show nothing we could use. it would crash only if shader didn't compile successfully (assuming your code is like the one you posted - without error checking).

0

Share this post


Link to post
Share on other sites

Try 

ID3D10Blob *VS, *PS;
D3DCompileFromFile(L"shaders.hlsl", 0, 0, "VShader", "vs_5_0", 0, 0, &VS, 0);
D3DCompileFromFile(L"shaders.hlsl", 0, 0, "PShader", "ps_5_0", 0, 0, &PS, 0);

Instead of your 

ID3D10Blob *vBlob,*pBlob;
D3DCompileFromFile(L"Shaders.hlsl",NULL,NULL,"PShader","ps_5_0",NULL,NULL,&pBlob,NULL);
D3DCompileFromFile(L"Shaders.hlsl",NULL,NULL,"VShader","vs_5_0",NULL,NULL,&vBlob,NULL);

See if that works.

?Actually nevermind that just retried your code and it worked fine for me, although it didn't first time around and as of yet i can't see why.

Edited by RyanMm
0

Share this post


Link to post
Share on other sites

Ugh... I read about the "macros" and put that shader compilation call into:

	if( SUCCEEDED( dev->CreateVertexShader(vBlob->GetBufferPointer(),vBlob->GetBufferSize(),NULL,&vs) ) )
		MessageBox(NULL,L"Vertex Shader Compiled!",L"Shader Compilation Result",MB_OK | MB_ICONEXCLAMATION);
	else
		MessageBox(NULL,L"Vertex SHader FAILED!",L"Shader Compilation Result",MB_OK | MB_ICONEXCLAMATION);

 

Still crashes the same way, which I assumed the checking is useless since the call itself crashes for no reason...

Any more ideas ?

0

Share this post


Link to post
Share on other sites

Good. But you don't check the shader compilation actually. Check that too. If the compilation fails, vBlob is NULL. Is it ? Because, if so, it's not even the CreateVertexShader that crashes, but dereferencing the NULL pointer with GetBufferPointer().

 

Also: Do you know how to use the interactive debugger ?

1

Share this post


Link to post
Share on other sites

Good. But you don't check the shader compilation actually. Check that too. If the compilation fails, vBlob is NULL. Is it ? Because, if so, it's not even the CreateVertexShader that crashes, but dereferencing the NULL pointer with GetBufferPointer().

 

I can't really check it if it's NULL or not with a "==" operator. And yes you are correct, It crashes on 

vBlob->GetBufferPointer();

 

 

Also: Do you know how to use the interactive debugger ?

 

No sad.png

0

Share this post


Link to post
Share on other sites
Hmmm, now I realize that there's even more to it, since you dont initialize your pointers to anything. Always do that IMO:
    ID3D10Blob *vBlob = NULL;
Or [tt]nullptr[/tt] if you're in for modern C++.

Anyway, if not it could be anything. In debug mode they get initialized to the magic number 0xCCCCCCCC (see here).

Checking for NULL should work with
    if(vBlob == NULL)
or even (Edit: corrected)
    if(!vBlob)
Why does it not work for you ?

Sooo, the why is it NULL (because I think it is) ? If the shader compilation fails, it will be set so (Note: I don't use VS 2012 but 2010, but I can reproduce that with the old D3DX function here).

Checking for the compilation works something like this (careful, I can't really check this, I just transliterated it for you):
ID3D10Blob *vBlob = NULL;
ID3D10Blob *errors = NULL;
HRESULT hr;
hr = D3DCompileFromFile(L"Shaders.hlsl",NULL,NULL,"VShader","vs_5_0",0,0,&vBlob,&errors);
if(FAILED(hr))
{
    if(errors)
    {			
        MessageBoxA(0, (LPCSTR)errors->GetBufferPointer(), "Error", 0);
        errors->Release();
    }
    else
    {
        MessageBoxA(0, "Compilation failed. Is the file where it should be ?", "Error", 0);
    }
    exit (EXIT_FAILURE);
}
If that code does not work, maybe someone else is so kind to correct it (Edit:Found already a typo, vBlob, not pBlob. Corrected)

So either your app cannot find your shader file, or there's an error in there.

Interactive debugging. Well, you could hit the 'Break' button when the crash occurs, you should be on the exact line where it happens. Move your mouse over the variables and be amazed (Hint: vBlob). Edited by unbird
2

Share this post


Link to post
Share on other sites

Thanks unbird.

It turns out to be the Shaders.hlsl file needed to be in the same directory as the "whatever.exe" and when I think about it from what you said earlier it does make sense since compilation is on runtime, right ?

 

But it's damn stupid, It crashed without the file at all, when I put it in the project source files (see videos) it compiled fine and even produced somekind of "Shaders.cso" file inthe directory of the "whatever.exe" yet crashed. How on earth was I supposed to know about this madness happening in a correct way even those something as being compiled angry.png

 

So yeah the problem is solved with moving "Shaders.hlsl" file. Thanks again.

 

By the way, I believe you over-thought(or forgot how C++ works) a bit when saying to check the Blob for NULL since you posted: 

 if(vBlob == NULL)

 

Which compares the address of the pointer to NULL since we do no deference and I can't imagine the address itself ever being NULL from a typical pointer declaration when the pointer get's created under some address upon declaration and simply using it's name refers to that address.

0

Share this post


Link to post
Share on other sites

Thanks unbird.

It turns out to be the Shaders.hlsl file needed to be in the same directory as the "whatever.exe" and when I think about it from what you said earlier it does make sense since compilation is on runtime, right ?

 

But it's damn stupid, It crashed without the file at all, when I put it in the project source files (see videos) it compiled fine and even produced somekind of "Shaders.cso" file inthe directory of the "whatever.exe" yet crashed. How on earth was I supposed to know about this madness happening in a correct way even those something as being compiled angry.png

 

So yeah the problem is solved with moving "Shaders.hlsl" file. Thanks again.

 

By the way, I believe you over-thought(or forgot how C++ works) a bit when saying to check the Blob for NULL since you posted: 

 if(vBlob == NULL)

 

Which compares the address of the pointer to NULL since we do no deference and I can't imagine the address itself ever being NULL from a typical pointer declaration when the pointer get's created under some address upon declaration and simply using it's name refers to that address.

 

His point is that you should set a pointer to NULL when you initialize it(unless it's a class member then use the initialization list.) If you check it for NULL then later, that tells you if it was ever allocated to something else. Using something like new on a pointer allocates new memory and sets it to point to that, so it would no longer be null.

 

If it's still set to NULL then obviously whatever call you used to allocate it earlier in the program never happened. You could also use an assert technically if it SHOULDN'T be null at that point.

 

That said if you don't initialize all your pointers to NULL then they're going to contain some crap value that will be interpreted as an intentional address and thus NULL will never trigger.

Edited by Satharis
1

Share this post


Link to post
Share on other sites
Precisely. Admittedly, I made a mistake earlier, the statements are not equivalent, it should be [tt]if(!vBlob)[/tt]. Corrected.

Fun fact: The Visual Studio debugger will complain when using an unitialized/unused pointer (it likely checks for that that magic number). Also: It was really meant as a question or suggestion to try out yourself (because asserts or - as in this case - proper error checking are the way to go). If you want us to help you give us feedback and try our approaches. Remote debugging through a forum is not simple. Making a video is overkill, and Zaoshi Kaba was right: The video did not show more than what we already knew and suggested approaches.

Which brings me back to the other question: You really need to learn to use the interactive debugger. I already started fabricating a screenshot but heck, we're in the age of youtube
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0