Sign in to follow this  
SteveHatcher

DX11 Setting up DirectX issues...

Recommended Posts

SteveHatcher    1236

Hi Guys,
I have been working on some directX tutorials and am having trouble with one step. I am setting up separate functions for each step of my program, and Visual Studio crashes when it reaches my Render() function. Using the debugger I can see that my backBufferTarget_ has a value of 0x00000000. So even though I think I am initializing it in InitD3D(), it is not remembering or something. My code is below, if anyone has an advice that would be greatly appreciated. I am sure it is a simple thing I am missing.

#include<Windows.h> 
#include<memory>
#include<xnamath.h>
#include<d3d11.h>
#include<d3dx11.h>
#include<DxErr.h>

#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "d3dx11.lib")
#pragma comment(lib, "dxerr.lib")

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

HWND hwnd = NULL;
HINSTANCE hInstance = NULL;

ID3D11DeviceContext* d3dContext_ = NULL;
ID3D11Device* d3dDevice_ = NULL;
IDXGISwapChain* swapChain_ = NULL;
ID3D11RenderTargetView* backBufferTarget_ = NULL;

//********************
//Function prototypes*
//********************
void MessagePump(void);
bool GetFullScreen(void);
bool InitWindow(void);
void KillWindow(void);
bool InitD3D(void);
void Render(void);
bool InitScene(void);
bool InitObjects(void);

bool progFinished = FALSE;
bool progFullScreen = FALSE;

#define APP_NAME "Kenneth Game"

//************************
//Application entry point*
//************************
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPWSTR cmdLine, int cmdShow)
{

	if (!GetFullScreen())
	{
		OutputDebugString("User abort\n");
		exit(5);
	}

	InitWindow();

	InitD3D();

	InitScene();

	while (!progFinished)
	{
		
		MessagePump(); //Check for window messages

		Render(); //Draw our graphics
	}

	KillWindow(); //Unload resources

	return 0;
}

//****************************************************************************************
//Initialise a window (full-screen or otherwise) in which our graphics will be displayed.*
//****************************************************************************************
bool InitWindow(void) 
{

	//UNREFERENCED_PARAMETER(prevInstance);
	//UNREFERENCED_PARAMETER(cmdLine);

	WNDCLASSEX wndClass = { 0 };
	wndClass.cbSize = sizeof(WNDCLASSEX);
	wndClass.style = CS_HREDRAW | CS_VREDRAW;
	wndClass.lpfnWndProc = WndProc;
	wndClass.hInstance = hInstance;
	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
	wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wndClass.lpszMenuName = NULL;
	wndClass.lpszClassName = "DX11BookWindowClass";

	if (!RegisterClassEx(&wndClass))
		return false;

	RECT rc = { 0, 0, 640, 480 };
	AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);

	HWND hwnd = CreateWindowA("DX11BookWindowClass", "Blank Win32 Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance, NULL);

	if (!hwnd)
		return false;

	ShowWindow(hwnd, SW_SHOW);
	//UpdateWindow(hwnd);

	return true;
}

//*************************************************
//Terminate the window that was previously opened.*
//*************************************************
void KillWindow(void)
{
	MSG msg;

	while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
	{
		DispatchMessage(&msg);
	}

	//ghAppWindow = NULL;
	ShowCursor(true);
}

//***************************
//Windows message processor.*
//***************************
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT paintStruct;
	HDC hDC;

	switch (message)
	{
	case WM_PAINT:
		hDC = BeginPaint(hwnd, &paintStruct);
		EndPaint(hwnd, &paintStruct);
		break;

	case WM_DESTROY:
		progFinished = true;
		PostQuitMessage(0);
		break;

	default:
		return DefWindowProc(hwnd, message, wParam, lParam);
	}

	return 0;
}

//**********************************************
//Process any messages that Windows has sent us*
//**********************************************
void MessagePump(void)
{
	MSG msg;

	if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

}

//*************************************
//Prompt selection of full screen mode*
//*************************************
bool GetFullScreen(void)
{
	int iResult;
	bool bRet = true;

	iResult = MessageBox(NULL, "Run fullscreen?", APP_NAME, MB_YESNOCANCEL | MB_ICONQUESTION);
	switch (iResult)
	{
	case IDCANCEL:
		bRet = false;
		break;
	case IDNO:
		progFullScreen = false;
		break;
	case IDYES:
		progFullScreen = true;
		break;
	case 0:
		OutputDebugString("Couldn't open MessageBox, closing");
		exit(10);
		break;
	}

	return bRet;
}

//**************************************
//Creates a hardware device in Direct3D*
//**************************************
bool InitD3D(void)
{
	D3D_DRIVER_TYPE driverType_;
	D3D_FEATURE_LEVEL featureLevel_;
	RECT dimensions;
	GetClientRect(hwnd, &dimensions);

	unsigned int width = dimensions.right - dimensions.left;
	unsigned int height = dimensions.bottom - dimensions.top;

	D3D_DRIVER_TYPE driverTypes[] =
	{
		D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP,
		D3D_DRIVER_TYPE_REFERENCE, D3D_DRIVER_TYPE_SOFTWARE
	};

	unsigned int totalDriverTypes = ARRAYSIZE(driverTypes);

	D3D_FEATURE_LEVEL featureLevels[] =
	{
		D3D_FEATURE_LEVEL_11_0,
		D3D_FEATURE_LEVEL_10_1,
		D3D_FEATURE_LEVEL_10_0
	};

	unsigned int totalFeatureLevels = ARRAYSIZE(featureLevels);

	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.Windowed = true;
	swapChainDesc.SampleDesc.Count = 1;
	swapChainDesc.SampleDesc.Quality = 0;

	unsigned int creationFlags = 0;

#ifdef _DEBUG
	creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

	HRESULT result;
	unsigned int driver = 0;

	for (driver = 0; driver < totalDriverTypes; ++driver)
	{
		result = D3D11CreateDeviceAndSwapChain(0, driverTypes[driver], 0, creationFlags, featureLevels, totalFeatureLevels, D3D11_SDK_VERSION, &swapChainDesc, &swapChain_,
			&d3dDevice_, &featureLevel_, &d3dContext_);

		if (SUCCEEDED(result))
		{
			driverType_ = driverTypes[driver];
			break;
		}
	}

	if (FAILED(result))
	{
		DXTRACE_MSG("Failed to create the Direct3D device!");
		return false;
	}

	ID3D11Texture2D* backBufferTexture;

	result = swapChain_->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferTexture);

	if (FAILED(result))
	{
		DXTRACE_MSG("Failed to get the swap chain back buffer!");
		return false;
	}

	result = d3dDevice_->CreateRenderTargetView(backBufferTexture, 0, &backBufferTarget_);

	if (backBufferTexture)
		backBufferTexture->Release();

	if (FAILED(result))
	{
		DXTRACE_MSG("Failed to create the render target view!");
		return false;
	}

	d3dContext_->OMSetRenderTargets(1, &backBufferTarget_, 0);

	D3D11_VIEWPORT viewport;
	viewport.Width = static_cast<float>(width);
	viewport.Height = static_cast<float>(height);
	viewport.MinDepth = 0.0f;
	viewport.MaxDepth = 1.0f;
	viewport.TopLeftX = 0.0f;
	viewport.TopLeftY = 0.0f;

	d3dContext_->RSSetViewports(1, &viewport);

	return true;
}

//****************************************************
// Initialise DirectX ready for us to start rendering*
//****************************************************
bool InitScene(void)
{


	
	return true;
}

//*******************************************
//Initialise the 3d objects we will be using*
//*******************************************
bool InitObjects(void)
{




	return true;
}

void Render(void)
{

	float clearColor[4] = { 0.0f, 0.0f, 0.25f, 1.0f };
	d3dContext_->ClearRenderTargetView(backBufferTarget_, clearColor);

	swapChain_->Present(0, 0);

}

Share this post


Link to post
Share on other sites
satanir    1452

That's the problem:

 

 


HWND hwnd = CreateWindowA("DX11BookWindowClass", "Blank Win32 Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance, NULL);

You use a local variable to store the HWND, but then when you call D3D11CreateDeviceAndSwapChain(), you use a global variable with the same name. Since the global variable was never set correctly and is still NULL, D3D11CreateDeviceAndSwapChain() fails. When you run it in debug mode, it shows the failure in the debug log.

Change the line above to:

// Initialize the GLOBAL hwnd
hwnd = CreateWindowA("DX11BookWindowClass", "Blank Win32 Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance, NULL); 

To avoid confusing global and local variables, you need a better naming convention. Specifically for HWND - you don't need it as global variable, as it's required only for initialization. Same goes for other variables. The only ones you want to keep as globals are the device and the swap-chain.

Edited by N.I.B.

Share this post


Link to post
Share on other sites
SteveHatcher    1236

Oh dude, thank you SO MUCH - that fixed it. I was trying for hours last night heaps of stuff. Still wrapping my head around this extra laywer of complexity (after just finishing a C++ book).

 

Thanks!

Share this post


Link to post
Share on other sites
SteveHatcher    1236

Hi Again,
 
I come with more perils. I am now trying to add keyboard support, and like before, the program is crashing when it comes to the device I thought I have created. I am keeping my eye out for uninitiated global variables as you taught me before but cannot find the problem. The added code is:
 

//**********************
//DirectInput variables*
//**********************
#define KEYDOWN( name, key ) ( name[key] & 0x80 )
LPDIRECTINPUT8 directInput_ = NULL;
LPDIRECTINPUTDEVICE8 keyboardDevice_ = NULL;
char keyboardKeys_[256];
char prevKeyboardKeys_[256];

For the Initialization routine (which is called before Update() and Render():

bool InitInput(void)
{
    HRESULT result;

    ZeroMemory(keyboardKeys_, sizeof(keyboardKeys_));
    ZeroMemory(prevKeyboardKeys_, sizeof(prevKeyboardKeys_));

    result = DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&directInput_, 0); //Initialize DirectInput8

    if (FAILED(result))
    {
        return false;
    }

    result = directInput_->CreateDevice(GUID_SysKeyboard, &keyboardDevice_, 0);

    if (FAILED(result))
    {
        return false;
    }

    result = keyboardDevice_->SetDataFormat(&c_dfDIKeyboard);

    if (FAILED(result))
    {
        return false;
    }

    result = keyboardDevice_->SetCooperativeLevel(ghHwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);

    if (FAILED(result))
    {
        return false;
    }

    result = keyboardDevice_->Acquire();

    if (FAILED(result))
    {
        return false;
    }

    return true;
}

And for the Update() routine:

//******************************
//Get current state of Keyboard*
//******************************
void Update(void)
{
	float fElapsed;
	float rotZ = 0;
	float fY = 0.0f;

	keyboardDevice_->GetDeviceState(sizeof(keyboardKeys_), (LPVOID)&keyboardKeys_);

	if (GetAsyncKeyState(VK_ESCAPE))
	{
		PostQuitMessage(0);
	}

	// Button up event.
	if (KEYDOWN(prevKeyboardKeys_, DIK_DOWN) && !KEYDOWN(keyboardKeys_, DIK_DOWN))
	{
		fY -= 0.1f;
	}


	if (KEYDOWN(prevKeyboardKeys_, DIK_UP) && !KEYDOWN(keyboardKeys_, DIK_UP))
	{
		fY += 0.1f;
	}

	memcpy(prevKeyboardKeys_, keyboardKeys_, sizeof(keyboardKeys_));

	gfTimeScale = 0.001f;
	fElapsed = GetElapsedTime();
	rotZ += fElapsed;
}

 
It is crashing at keyboardDevice_->GetDeviceState(sizeof(keyboardKeys_), (LPVOID)&keyboardKeys_);

 

The debugger shows keyboardDevice_ becomes a 0x00000000 (similar to before). Again this is adapting code that works when it was done in the way the book shows.

 

Again any help is greatly appreciated.

 

Thanks

Edited by SteveHatcher

Share this post


Link to post
Share on other sites
Samith    2460

The debugger shows keyboardDevice_ becomes a 0x00000000 (similar to before). Again this is adapting code that works when it was done in the way the book shows.

After a quick glance at your code in not sure what's wrong, but I did notice one thing: you don't seem to ever check the result of your Init functions. In InitInput you return false if anything failed, but then you never check if InitInput returns true or not (I'm assuming, based on the code in the original post).

You should check the return values of your Init functions, and at the very least log something if they're false. It's possible that keyboardDevice_ never initialized properly (and thus was always NULL) but you won't catch that until you're update loop. You want to try and find errors as soon as possible! Crash early and crash often, as the saying goes.

EDIT: Looked at your code again. Looks like hInstance is uninitialized. You can get hInstance from WinMain. Edited by Samith

Share this post


Link to post
Share on other sites
SteveHatcher    1236

Thank you very much! In my main I changed it to:

	if (!InitInput())
	{
		OutputDebugString("  Input initialisation failed\n");
		exit(5);
	}

and could see it was failing here. You were spot on about hInstance. The way I got it was with

hInstance = GetModuleHandle(NULL); 

Do you think that's okay? Or is another better way to do it?

 

Thanks heaps!

Share this post


Link to post
Share on other sites
SteveHatcher    1236

Hi Guys..

 

Stuck yet again. This time I am simply trying to display my triangle slightly rotated.

 

I have added some vertices:

VertexPos gVertices[] = 
{
	XMFLOAT3(0.5f, 0.5f, 0.5f), 
	XMFLOAT3(0.5f, -0.5f, 0.5f),
	XMFLOAT3(-0.5f, -0.5f, 0.5f)
};

which come into play here in InitObjects(void)

	ZeroMemory(&resourceData, sizeof(resourceData));
	resourceData.pSysMem = gVertices;
	d3dResult = d3dDevice_->CreateBuffer(&vertexDesc, &resourceData, &vertexBuffer_);

	D3D11_BUFFER_DESC constDesc;
	ZeroMemory(&constDesc, sizeof(constDesc));
	constDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	constDesc.ByteWidth = sizeof(XMMATRIX);
	constDesc.Usage = D3D11_USAGE_DEFAULT;

	d3dResult = d3dDevice_->CreateBuffer(&constDesc, 0, &mvpCB_);

with the final Render() function as

void Render(void)
{
	if (d3dContext_ == 0) //Checks that the Direct3D context is valid. 
		return;


	float clearColor[4] = { 0.0f, 0.0f, 0.25f, 1.0f };
	d3dContext_->ClearRenderTargetView(backBufferTarget_, clearColor);
	unsigned int stride = sizeof(VertexPos);
	unsigned int offset = 0;

	//Setting up the input assembly
	d3dContext_->IASetInputLayout(inputLayout_); 
	d3dContext_->IASetVertexBuffers(0, 1, &vertexBuffer_, &stride, &offset); 
	d3dContext_->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); 
	d3dContext_->VSSetShader(solidColorVS_, 0, 0);
	d3dContext_->PSSetShader(solidColorPS_, 0, 0);


	XMMATRIX view = XMMatrixIdentity();
	XMMATRIX projection = XMMatrixOrthographicOffCenterLH(0.0f, 800.0f, 0.0f, 600.0f, 0.1f, 100.0f); //1a. Creates an orthographic projection matrix using LHS. Return value is a XMMATRIX structure where the resulting projection matrix is placed.
	XMMATRIX vpMatrix_ = XMMatrixMultiply(view, projection);

	XMMATRIX translation = XMMatrixTranslation(10.0f, 10.0f, 10.0f);
	XMMATRIX rotationZ = XMMatrixRotationZ(30.0f);
	XMMATRIX scale = XMMatrixScaling(0.0f, 0.0f, 0.0f);
	XMMATRIX TriangleWorld = translation * rotationZ;

	XMMATRIX mvp = TriangleWorld*vpMatrix_*translation;
	mvp = XMMatrixTranspose(mvp);

	d3dContext_->UpdateSubresource(mvpCB_, 0, 0, &mvp, 0, 0);
	d3dContext_->VSSetConstantBuffers(0, 1, &mvpCB_);

	d3dContext_->Draw(3, 0); 
	swapChain_->Present(0, 0);
}

No matter what I change in the XMMatrixRotationZ or XMMatrixTranslation, my triangle stays the same. Its as if since the buffer is created I am not altering it at all.

 

I have tried many combinations of matrix multiplication ways and large numbers to no avail. It is as if the mvp matrix is having no effect on the final image. Thank you for your time - I have spent many hours trying to figure this out and only come here as a last resort. I find the best way to learn is trying to figure out broken code...

Edited by SteveHatcher

Share this post


Link to post
Share on other sites
SteveHatcher    1236

Not 100% sure what you mean, but my vertex shader is created here:

bool InitObjects(void)
{
	
	DWORD shaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;

#if defined( DEBUG ) || defined( _DEBUG )
	shaderFlags |= D3DCOMPILE_DEBUG;
#endif

	ID3DBlob* errorBuffer = 0;
	ID3DBlob* vsBuffer = 0;

	//bool compileResult = CompileD3DShader("SolidGreenColor.fx", "VS_Main", "vs_4_0", &vsBuffer); //Loads vertex shader from the text file and compiles it into byte code. 
	//bool compileResult = D3DX11CompileFromFile("SolidGreenColor.fx", 0, 0, "VS_Main", "vs_4_0", shaderFlags, 0, 0, &vsBuffer, &errorBuffer, 0);

	HRESULT result;
	result =  D3DX11CompileFromFile("SolidGreenColor.fx", 0, 0, "VS_Main", "vs_4_0", shaderFlags, 0, 0, &vsBuffer, &errorBuffer, 0);

	if (FAILED(result))
	{
		if (errorBuffer != 0)
		{
			OutputDebugStringA((char*)errorBuffer->GetBufferPointer());
			errorBuffer->Release();
		}

		return false;
	}

	HRESULT d3dResult;

	d3dResult = d3dDevice_->CreateVertexShader(vsBuffer->GetBufferPointer(), vsBuffer->GetBufferSize(), 0, &solidColorVS_);

	if (FAILED(d3dResult))
	{
		if (vsBuffer)
			vsBuffer->Release();

		return false;
	}

	D3D11_INPUT_ELEMENT_DESC solidColorLayout[] = //Used to describe the vertex latout of a vertex streucture. (msdn). 
	{
		{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 } //3b
	};

	unsigned int totalLayoutElements = ARRAYSIZE(solidColorLayout);

	d3dResult = d3dDevice_->CreateInputLayout(solidColorLayout, totalLayoutElements, //3c The input layout uses the type of ID3D11InputLayout. Created with a call to the D3D device function CreateInputLayout. 
		vsBuffer->GetBufferPointer(), vsBuffer->GetBufferSize(), &inputLayout_);

	vsBuffer->Release();

	if (FAILED(d3dResult))
	{
		return false;
	}

	ID3DBlob* psBuffer = 0;

	result = D3DX11CompileFromFile("SolidGreenColor.fx", 0, 0, "PS_Main", "ps_4_0", shaderFlags, 0, 0, &psBuffer, &errorBuffer, 0);

	if (FAILED(result))
	{
		if (errorBuffer != 0)
		{
			OutputDebugStringA((char*)errorBuffer->GetBufferPointer());
			errorBuffer->Release();
		}

		return false;
	}

	d3dResult = d3dDevice_->CreatePixelShader(psBuffer->GetBufferPointer(), psBuffer->GetBufferSize(), 0, &solidColorPS_);

	psBuffer->Release();

	ZeroMemory(&vertexDesc, sizeof(vertexDesc));
	vertexDesc.Usage = D3D11_USAGE_DEFAULT;
	vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	vertexDesc.ByteWidth = sizeof(VertexPos)* 3;

	ZeroMemory(&resourceData, sizeof(resourceData));
	resourceData.pSysMem = gVertices;
	d3dResult = d3dDevice_->CreateBuffer(&vertexDesc, &resourceData, &vertexBuffer_);

	D3D11_BUFFER_DESC constDesc;
	ZeroMemory(&constDesc, sizeof(constDesc));
	constDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	constDesc.ByteWidth = sizeof(XMMATRIX);
	constDesc.Usage = D3D11_USAGE_DEFAULT;

	d3dResult = d3dDevice_->CreateBuffer(&constDesc, 0, &mvpCB_);

	if (FAILED(d3dResult))
	{
		return false;
	}

	return true;

}

My goal is to modify the triangle in world space so the rotation or translation matrices have an effect on it. Thanks for your time.

Edited by SteveHatcher

Share this post


Link to post
Share on other sites
SteveHatcher    1236

Oh Sorry, Im guessing you mean the .fx file that D3Dx11CompileFromFile is grabbing?

 

It is:

float4 VS_Main( float4 pos : POSITION ) : SV_POSITION
{
    return pos;
}


float4 PS_Main( float4 pos : SV_POSITION ) : SV_TARGET
{
    return float4( 0.0f, 1.0f, 0.0f, 1.0f );
}

A solid green shader as far as I am aware.

Share this post


Link to post
Share on other sites
unbird    8336
Precisely. Yeah, that's a pass-through vertex shader, the position doesn't change at all wink.png

It should look something like this:
 
cbuffer VSParameters : register(b0)  // deliberately assigning slot 0 !
{
	matrix WVP;
};

float4 VS_Main( float4 pos : POSITION ) : SV_POSITION
{
	return mul(position, WVP);
}
Also, you probably want to rotate (and/or scale) first, then translate. Order of multiplication matters with matrices:

XMMATRIX TriangleWorld = rotationZ * translation;

Share this post


Link to post
Share on other sites
SteveHatcher    1236

Okay, thanks guys. I am still slowly digging my way through the literature.

 

Is there a way to create a simple shader like this but entirely in a struct, or class of my definition so it does not need a separate .fx file? If so, what function do I use instead of the D3Dx11CompileFromFile?

 

I hope my question makes sense. Thanks. you guys are extremely helpful and awesome!

Share this post


Link to post
Share on other sites
unbird    8336
Not quite sure what you mean. You can have several shaders in the same file (like you already do for both vertex and pixel shader). And there are compile functions which take source code directly, without the detour of a file, e.g. D3DX11CompileFromMemory or alternatively the newer compile function D3DCompile.

Put your HLSL source as a static string in your cpp file and feed it to one of those functions.

(Alternatively one could even let the command line compiler fxc spit out compiled binaries as a hex array source code, with the option /Fh. This way no runtime compilation is needed)

Share this post


Link to post
Share on other sites


Is there a way to create a simple shader like this but entirely in a struct, or class of my definition so it does not need a separate .fx file? If so, what function do I use instead of the D3Dx11CompileFromFile?

No, that doesn't make much sense.

Of course you could include the source of your HLSL file as string constant in your code, but this is not very common.

If you don't want to compile your shaders at runtime, you can do it offline using the fxc.exe command line compiler. Take this:

http://msdn.microsoft.com/en-us/library/windows/desktop/bb509709%28v=vs.85%29.aspx

What I do is this: I let fxc.exe create an header file (command line option /Fh). This .h file contains a byte array with the compiled shader code that can be passed to e.g. ID3D11Device::CreateVertexShader.

Share this post


Link to post
Share on other sites
SteveHatcher    1236

Just out of interest, why do they have them in a separate file? I can't see the advantage of this as opposed to having them in a header file and just including it?

 

Thanks

Share this post


Link to post
Share on other sites
SteveHatcher    1236

I'm not sure if I get the idea behind your question. You have a project with mixed languages: C++ and HLSL. They have different compilers. Why would you mix the languages in a single file?

That answers my question, didn't click about it being a different language lol. Thanks

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  

  • Similar Content

    • By isu diss
      HRESULT FBXLoader::Open(HWND hWnd, char* Filename) { HRESULT hr = S_OK; if (FBXM) { FBXIOS = FbxIOSettings::Create(FBXM, IOSROOT); FBXM->SetIOSettings(FBXIOS); FBXI = FbxImporter::Create(FBXM, ""); if (!(FBXI->Initialize(Filename, -1, FBXIOS))) MessageBox(hWnd, (wchar_t*)FBXI->GetStatus().GetErrorString(), TEXT("ALM"), MB_OK); FBXS = FbxScene::Create(FBXM, "MCS"); if (!FBXS) MessageBox(hWnd, TEXT("Failed to create the scene"), TEXT("ALM"), MB_OK); if (!(FBXI->Import(FBXS))) MessageBox(hWnd, TEXT("Failed to import fbx file content into the scene"), TEXT("ALM"), MB_OK); if (FBXI) FBXI->Destroy(); FbxNode* MainNode = FBXS->GetRootNode(); int NumKids = MainNode->GetChildCount(); FbxNode* ChildNode = NULL; for (int i=0; i<NumKids; i++) { ChildNode = MainNode->GetChild(i); FbxNodeAttribute* NodeAttribute = ChildNode->GetNodeAttribute(); if (NodeAttribute->GetAttributeType() == FbxNodeAttribute::eMesh) { FbxMesh* Mesh = ChildNode->GetMesh(); NumVertices = Mesh->GetControlPointsCount();//number of vertices MyV = new FBXVTX[NumVertices]; for (DWORD j = 0; j < NumVertices; j++) { FbxVector4 Vertex = Mesh->GetControlPointAt(j);//Gets the control point at the specified index. MyV[j].Position = XMFLOAT3((float)Vertex.mData[0], (float)Vertex.mData[1], (float)Vertex.mData[2]); } NumIndices = Mesh->GetPolygonVertexCount();//number of indices; for cube 20 MyI = new DWORD[NumIndices]; MyI = (DWORD*)Mesh->GetPolygonVertices();//index array NumFaces = Mesh->GetPolygonCount(); MyF = new FBXFACEX[NumFaces]; for (int l=0;l<NumFaces;l++) { MyF[l].Vertices[0] = MyI[4*l]; MyF[l].Vertices[1] = MyI[4*l+1]; MyF[l].Vertices[2] = MyI[4*l+2]; MyF[l].Vertices[3] = MyI[4*l+3]; } UV = new XMFLOAT2[NumIndices]; for (int i = 0; i < Mesh->GetPolygonCount(); i++)//polygon(=mostly rectangle) count { FbxLayerElementArrayTemplate<FbxVector2>* uvVertices = NULL; Mesh->GetTextureUV(&uvVertices); for (int j = 0; j < Mesh->GetPolygonSize(i); j++)//retrieves number of vertices in a polygon { FbxVector2 uv = uvVertices->GetAt(Mesh->GetTextureUVIndex(i, j)); UV[4*i+j] = XMFLOAT2((float)uv.mData[0], (float)uv.mData[1]); } } } } } else MessageBox(hWnd, TEXT("Failed to create the FBX Manager"), TEXT("ALM"), MB_OK); return hr; } I've been trying to load fbx files(cube.fbx) into my programme. but I get this. Can someone pls help me?
       

    • By lonewolff
      Hi Guys,
      I am having a bit of a problem with a dynamic texture.
      It is creating without error and I am attempting to initialize the first pixel to white to make sure I am mapping correctly. But when I draw the texture to the quad it displays the whole quad white (instead of just one pixel).
      This is how I am creating, mapping, and setting the first pixel to white. But as mentioned, when I draw the quad, the entire quad is white.
       
      // Create dynamic texture D3D11_TEXTURE2D_DESC textureDesc = { 0 }; textureDesc.Width = 2048; textureDesc.Height = 2048; textureDesc.MipLevels = 1; textureDesc.ArraySize = 1; textureDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; textureDesc.SampleDesc.Count = 1; textureDesc.Usage = D3D11_USAGE_DYNAMIC; textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; textureDesc.MiscFlags = 0; HRESULT result = d3dDevice->CreateTexture2D(&textureDesc, NULL, &textureDynamic); if (FAILED(result)) return -1; result = d3dDevice->CreateShaderResourceView(textureDynamic, 0, &textureRV); if (FAILED(result)) return -2; D3D11_MAPPED_SUBRESOURCE resource; if (FAILED(d3dContext->Map(textureDynamic, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource))) return -1; memset(resource.pData, 255, 4); d3dContext->Unmap(textureDynamic, 0);  
      Hopefully I have just made an oversight somewhere.
      Any assistance would be greatly appreciated
      (If I change the 255 value to 128 the quad then turns grey, so the mapping is definitely doing something. Just can't work out why it is colouring the whole quad and not the first pixel)
    • By KaiserJohan
      Just a really quick question - is there any overhead to using DrawIndexedInstanced even for geometry you just render once vs using DrawIndexed? Or is the details obfuscated by the graphics driver?
      I would assume no but you never know  
    • By isu diss
       I'm trying to code Rayleigh part of Nishita's model (Display Method of the Sky Color Taking into Account Multiple Scattering). I get black screen no colors. Can anyone find the issue for me?
       
      #define InnerRadius 6320000 #define OutterRadius 6420000 #define PI 3.141592653 #define Isteps 20 #define Ksteps 10 static float3 RayleighCoeffs = float3(6.55e-6, 1.73e-5, 2.30e-5); RWTexture2D<float4> SkyColors : register (u0); cbuffer CSCONSTANTBUF : register( b0 ) { float fHeight; float3 vSunDir; } float Density(float Height) { return exp(-Height/8340); } float RaySphereIntersection(float3 RayOrigin, float3 RayDirection, float3 SphereOrigin, float Radius) { float t1, t0; float3 L = SphereOrigin - RayOrigin; float tCA = dot(L, RayDirection); if (tCA < 0) return -1; float lenL = length(L); float D2 = (lenL*lenL) - (tCA*tCA); float Radius2 = (Radius*Radius); if (D2<=Radius2) { float tHC = sqrt(Radius2 - D2); t0 = tCA-tHC; t1 = tCA+tHC; } else return -1; return t1; } float RayleighPhaseFunction(float cosTheta) { return ((3/(16*PI))*(1+cosTheta*cosTheta)); } float OpticalDepth(float3 StartPosition, float3 EndPosition) { float3 Direction = normalize(EndPosition - StartPosition); float RayLength = RaySphereIntersection(StartPosition, Direction, float3(0, 0, 0), OutterRadius); float SampleLength = RayLength / Isteps; float3 tmpPos = StartPosition + 0.5 * SampleLength * Direction; float tmp; for (int i=0; i<Isteps; i++) { tmp += Density(length(tmpPos)-InnerRadius); tmpPos += SampleLength * Direction; } return tmp*SampleLength; } static float fExposure = -2; float3 HDR( float3 LDR) { return 1.0f - exp( fExposure * LDR ); } [numthreads(32, 32, 1)] //disptach 8, 8, 1 it's 256 by 256 image void ComputeSky(uint3 DTID : SV_DispatchThreadID) { float X = ((2 * DTID.x) / 255) - 1; float Y = 1 - ((2 * DTID.y) / 255); float r = sqrt(((X*X)+(Y*Y))); float Theta = r * (PI); float Phi = atan2(Y, X); static float3 Eye = float3(0, 10, 0); float ViewOD = 0, SunOD = 0, tmpDensity = 0; float3 Attenuation = 0, tmp = 0, Irgb = 0; //if (r<=1) { float3 ViewDir = normalize(float3(sin(Theta)*cos(Phi), cos(Theta),sin(Theta)*sin(Phi) )); float ViewRayLength = RaySphereIntersection(Eye, ViewDir, float3(0, 0, 0), OutterRadius); float SampleLength = ViewRayLength / Ksteps; //vSunDir = normalize(vSunDir); float cosTheta = dot(normalize(vSunDir), ViewDir); float3 tmpPos = Eye + 0.5 * SampleLength * ViewDir; for(int k=0; k<Ksteps; k++) { float SunRayLength = RaySphereIntersection(tmpPos, vSunDir, float3(0, 0, 0), OutterRadius); float3 TopAtmosphere = tmpPos + SunRayLength*vSunDir; ViewOD = OpticalDepth(Eye, tmpPos); SunOD = OpticalDepth(tmpPos, TopAtmosphere); tmpDensity = Density(length(tmpPos)-InnerRadius); Attenuation = exp(-RayleighCoeffs*(ViewOD+SunOD)); tmp += tmpDensity*Attenuation; tmpPos += SampleLength * ViewDir; } Irgb = RayleighCoeffs*RayleighPhaseFunction(cosTheta)*tmp*SampleLength; SkyColors[DTID.xy] = float4(Irgb, 1); } }  
    • By Endurion
      I have a gaming framework with an renderer interface. Those support DX8, DX9 and latest, DX11. Both DX8 and DX9 use fixed function pipeline, while DX11 obviously uses shaders. I've got most of the parts working fine, as in I can switch renderers and notice almost no difference. The most advanced features are 2 directional lights with a single texture  
      My last problem is lighting; albeit there's documentation on the D3D lighting model I still can't get the behaviour right. My mistake shows most prominently in the dark side opposite the lights. I'm pretty sure the ambient calculation is off, but that one's supposed to be the most simple one and should be hard to get wrong.
      Interestingly I've been searching high and low, and have yet to find a resource that shows how to build a HLSL shader where diffuse, ambient and specular are used together with material properties. I've got various shaders for all the variations I'm supporting. I stepped through the shader with the graphics debugger, but the calculation seems to do what I want. I'm just not sure the formula is correct.
      This one should suffice though, it's doing two directional lights, texture modulated with vertex color and a normal. Maybe someone can spot one (or more mistakes). And yes, this is in the vertex shader and I'm aware lighting will be as "bad" as in fixed function; that's my goal currently.
      // A constant buffer that stores the three basic column-major matrices for composing geometry. cbuffer ModelViewProjectionConstantBuffer : register(b0) { matrix model; matrix view; matrix projection; matrix ortho2d; }; struct DirectionLight { float3 Direction; float PaddingL1; float4 Ambient; float4 Diffuse; float4 Specular; }; cbuffer LightsConstantBuffer : register( b1 ) { float4 Ambient; float3 EyePos; float PaddingLC1; DirectionLight Light[8]; }; struct Material { float4 MaterialEmissive; float4 MaterialAmbient; float4 MaterialDiffuse; float4 MaterialSpecular; float MaterialSpecularPower; float3 MaterialPadding; }; cbuffer MaterialConstantBuffer : register( b2 ) { Material _Material; }; // Per-vertex data used as input to the vertex shader. struct VertexShaderInput { float3 pos : POSITION; float3 normal : NORMAL; float4 color : COLOR0; float2 tex : TEXCOORD0; }; // Per-pixel color data passed through the pixel shader. struct PixelShaderInput { float4 pos : SV_POSITION; float2 tex : TEXCOORD0; float4 color : COLOR0; }; // Simple shader to do vertex processing on the GPU. PixelShaderInput main(VertexShaderInput input) { PixelShaderInput output; float4 pos = float4( input.pos, 1.0f ); // Transform the vertex position into projected space. pos = mul(pos, model); pos = mul(pos, view); pos = mul(pos, projection); output.pos = pos; // pass texture coords output.tex = input.tex; // Calculate the normal vector against the world matrix only. //set required lighting vectors for interpolation float3 normal = mul( input.normal, ( float3x3 )model ); normal = normalize( normal ); float4 ambientEffect = Ambient; float4 diffuseEffect = float4( 0, 0, 0, 0 ); float4 specularEffect = float4( 0, 0, 0, 0 ); for ( int i = 0; i < 2; ++i ) { // Invert the light direction for calculations. float3 lightDir = -Light[i].Direction; float lightFactor = max( dot( lightDir, input.normal ), 0 ); ambientEffect += Light[i].Ambient * _Material.MaterialAmbient; diffuseEffect += saturate( Light[i].Diffuse * dot( normal, lightDir ) );// * _Material.MaterialDiffuse; //specularEffect += Light[i].Specular * dot( normal, halfangletolight ) * _Material.MaterialSpecularPower; } specularEffect *= _Material.MaterialSpecular; //ambientEffect.w = 1.0; ambientEffect = normalize( ambientEffect ); /* Ambient effect: (L1.ambient + L2.ambient) * object ambient color Diffuse effect: (L1.diffuse * Dot(VertexNormal, Light1.Direction) + L2.diffuse * Dot(VertexNormal, Light2.Direction)) * object diffuse color Specular effect: (L1.specular * Dot(VertexNormal, HalfAngleToLight1) * Object specular reflection power + L2.specular * Dot(VertexNormal, HalfAngleToLight2) * Object specular reflection power ) * object specular color Resulting color = Ambient effect + diffuse effect + specular effect*/ float4 totalFactor = ambientEffect + diffuseEffect + specularEffect; totalFactor.w = 1.0; output.color = input.color * totalFactor; return output; }   Edit: This message editor is driving me nuts (Arrrr!) - I don't write code in Word.
  • Popular Now