Sign Up NOW to get 100 free credits, used to download 3D Models, Textures, Sound Effects and Music!

Lesson 3: Direct3D 11 Initialization

We have one more thing to do to start displaying our crazy minds using DirectX. And that is to Initialize Direct3D. By the end of this lesson, you should have a nice little window with a blue background.We will initialize direct3d here. After we initialize direct3d, all the boring preparation stuff will be over, and we can start drawing things onto the screen! You will need to download the directx sdk from microsofts website. here. Ok, lets get on this thing.



We start this lesson by including the necessary headers, and linking to the necessary libraries. As you can see, we have included the and linked to the d3dx10 library and header file. This is in case we want to use some of the functions types or structures they contain, as direct3d 11 is only an "extension" of direct3d 10. We include xnamath.h because the D3DX math library has been "depricated" for the new xna math library. An example is we will not use D3DXVECTOR3 for a variable containing 3 float values. Instead, we will use the XMFLOAT3.


#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "d3dx11.lib")
#pragma comment(lib, "d3dx10.lib")

#include <windows.h>
#include <d3d11.h>
#include <d3dx11.h>
#include <d3dx10.h>
#include <xnamath.h>

Here we declare our globals. The first declaration is a COM Interface object. This is our SwapChain, which is used to change the backbuffer to the front buffer, and the front buffer to the back buffer. This is called double buffering. When we render our scene, we are rendering to the backbuffer, so by the time we present the back buffer to the monitor, it will be fully drawn. Otherwise, we will get scanlines, which is when we can see our program drawing our scene to the screen, from the top down usually. The next is an Interface we will use to represent our hardware device (GPU). Now, the line after that, is a new interface that came with directx 11. The ID3D11Device interface was split into two, to help support the new multi-threading features. We will use our ID3D11Device interface object to call all the rendering method, while ID3D11Device will be used to call the rest of the methods that don't have to do with rendering.

I will better explain the reason behind splitting the ID3D11Device into two. DirectX 11 has new multi-threading features, used to speed up the applications. When you are loading something into memory, such as a model, or creating an object, you will call the ID3D11Device object. While the object or model is loading or creating, you can call the ID3D11DeviceContext interface object to continue rendering your scene. This will take away from performance hits when loading models, creating objects, or anything like that. Its not a difficult idea to understand, so i hope you follow what i'm saying.

So, after that, we have another interface object, which is the render target view. Basically, we do not write directly to the screen, but instead write to the render target view, which is a 2d texture (our backbuffer). Then this texture is sent to the output merger stage of the pipeline as our render target, which will then be rendered to the screen.

The next 6 lines are used to change the color of the background, not important to the lesson.


IDXGISwapChain* SwapChain;
ID3D11Device* d3d11Device;
ID3D11DeviceContext* d3d11DevCon;
ID3D11RenderTargetView* renderTargetView;

float red = 0.0f;
float green = 0.0f;
float blue = 0.0f;
int colormodr = 1;
int colormodg = 1;
int colormodb = 1;

Next we declare our function prototypes. The first function is used to initialize direct3d. The second one is to release the objects we don't need to prevent memory leaks. InitScene is used to set up or scene. Update scene is used to change our scene on a per-frame basis, then the draw scene is used to draw our scene to the screen, and is updated every frame too.


bool InitializeDirect3d11App(HINSTANCE hInstance);
void ReleaseObjects();
bool InitScene();
void UpdateScene();
void DrawScene();

In our winMain function, we will call InitializeDirect3d11App, then InitScene. After that we will call our messageloop, and when our message loop is done, we release our objects, then end the program.


	if(!InitializeDirect3d11App(hInstance))	//Initialize Direct3D
	{
		MessageBox(0, L"Direct3D Initialization - Failed",
			L"Error", MB_OK);
		return 0;
	}

	if(!InitScene())	//Initialize our scene
	{
		MessageBox(0, L"Scene Initialization - Failed",
			L"Error", MB_OK);
		return 0;
	}
    
	messageloop();

	ReleaseObjects();    

Initializing Direct3D 11

This is our function which will initialize direct3d. It takes one parameter, which is the handle to our applications instance. I will go through it part by part.


bool InitializeDirect3dApp(HINSTANCE hInstance)
{
	HRESULT hr;
    
	//Describe our Buffer
	DXGI_MODE_DESC bufferDesc;

	ZeroMemory(&bufferDesc, sizeof(DXGI_MODE_DESC));

	bufferDesc.Width = Width;
	bufferDesc.Height = Height;
	bufferDesc.RefreshRate.Numerator = 60;
	bufferDesc.RefreshRate.Denominator = 1;
	bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
	bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
	
	//Describe our SwapChain
	DXGI_SWAP_CHAIN_DESC swapChainDesc; 
		
	ZeroMemory(&swapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));

	swapChainDesc.BufferDesc = bufferDesc;
	swapChainDesc.SampleDesc.Count = 1;
	swapChainDesc.SampleDesc.Quality = 0;
	swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	swapChainDesc.BufferCount = 1;
	swapChainDesc.OutputWindow = hwnd; 
	swapChainDesc.Windowed = TRUE; 
	swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;


	//Create our SwapChain
	hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, NULL, NULL, NULL,
		D3D11_SDK_VERSION, &swapChainDesc, &SwapChain, &d3d11Device, NULL, &d3d11DevCon);

	//Create our BackBuffer
	ID3D11Texture2D* BackBuffer;
	hr = SwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), (void**)&BackBuffer );

	//Create our Render Target
	hr = d3d11Device->CreateRenderTargetView( BackBuffer, NULL, &renderTargetView );
	BackBuffer->Release();

	//Set our Render Target
	d3d11DevCon->OMSetRenderTargets( 1, &renderTargetView, NULL );

	return true;
}

First we create an HRESULT object called hr to use for error checking. I have not included error checking in order to keep the code more clear and condensed, but I will explain at the end of this lesson how you can impliment error checking.


	HRESULT hr;

Describing the BackBuffer
( DXGI_MODE_DESC )

The first thing we do in this function is describe our backbuffer. We create a DXGI_MODE_DESC object called bufferDesc. Then we call ZeroMemory to make sure the object is completely cleaned out (in case we don't set all the parameters, and a parameter already has a value in it). Then we fill out our backbuffer description. The DXGI_MODE_DESC structure:


typedef struct DXGI_MODE_DESC {
  UINT                     Width;
  UINT                     Height;
  DXGI_RATIONAL            RefreshRate;
  DXGI_FORMAT              Format;
  DXGI_MODE_SCANLINE_ORDER ScanlineOrdering;
  DXGI_MODE_SCALING        Scaling;
} DXGI_MODE_DESC, *LPDXGI_MODE_DESC;

Where each member is described below:

Width
- This is the Width of the resolution we are going to use.

Height
- This is the Height of the resolution we are going to use.

RefreshRate
- This is a DXGI_RATIONAL type, describing the refresh rate in hertz. We set ours to 60/1, or 60hz.

Format
- This is a DXGI_FORMAT enumerated type, describing the format of our display. We can use DXGI_FORMAT_R8G8B8A8_UNORM, which is a 32-bit unsigned integer, taking 8 bits for Red, Green, Blue, and Alpha each.

ScanlineOrdering - A DXGI_MODE_SCANLINE_ORDER enumerated type, describing the manner in which the rasterizer will render onto a surface. As we use double buffering, this will not usually be seen, so we can set it to DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED, meaning the order in which the render takes place on a surface does not matter.

Scaling - This is another enumerated type. The DXGI_MODE_SCALING, explaining how an image is stretched to fit a monitors resolution. We can use one of three: DXGI_MODE_SCALING_UNSPECIFIED, which means it is not specified, DXGI_MODE_SCALING_CENTERED, meaning the image is centered on the screen, and no scaling and stretching is done at all, and DXGI_MODE_SCALING_STRETCHED, which will stretch the image to the monitors resolution.


	DXGI_MODE_DESC bufferDesc;

	ZeroMemory(&bufferDesc, sizeof(DXGI_MODE_DESC));

	bufferDesc.Width = Width;
	bufferDesc.Height = Height;
	bufferDesc.RefreshRate.Numerator = 60;
	bufferDesc.RefreshRate.Denominator = 1;
	bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
	bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;

Describing the SwapChain
( DXGI_SWAP_CHAIN_DESC )

Now that we have our back buffer description filled out, we can move on to describing our SwapChain. We create a DXGI_SWAP_CHAIN_DESC called swapChainDesc, Then we clear it out by calling the ZeroMemory function. After that, we can fill out the description. The structure looks like this:


typedef struct DXGI_SWAP_CHAIN_DESC {
  DXGI_MODE_DESC   BufferDesc;
  DXGI_SAMPLE_DESC SampleDesc;
  DXGI_USAGE       BufferUsage;
  UINT             BufferCount;
  HWND             OutputWindow;
  BOOL             Windowed;
  DXGI_SWAP_EFFECT SwapEffect;
  UINT             Flags;
} DXGI_SWAP_CHAIN_DESC;

Where each member is described below:

BufferDesc
- This is a DXGI_MODE_DESC structure, which describes the back buffer. We will put the bufferDesc object we just filled out here.

SampleDesc
- This is a DXGI_SAMPLE_DESC structure, which describes the multisampling. If you don't know, multisampling is used to "smooth" out the choppiness in lines and edges, created because pixels on the monitor are not infinetly small. Since pixels are like little blocks, you can see "choppiness" in diagonal lines and edges on a computer screen.

BufferUsage
- A DXGI_USAGE enumerated type describing the access the cpu has to the surface of the back buffer. We specify DXGI_USAGE_RENDER_TARGET_OUTPUT since we will render to it.

BufferCount
- This is the number of back buffers we will use. We set 1 for double buffering, but you can set 2 for triple buffering, or even more if you wanted.

OutputWindow
- This is the handle to our window, hwnd.

Windowed
- This either true or false depending on if we want windowed or full-screen. Set true for windowed, and false for full-screen. (Be carefull exiting out of full-screen. It might freeze your program. A way around this is to set the application to windowed just before you actually exit out of the program)

SwapEffect
- This is a DXGI_SWAP_EFFECT enumerated type, describing what the display driver should do with the front buffer after swapping it to the back buffer. we set DXGI_SWAP_EFFECT_DISCARD to let the display driver decide what the most efficient thing to do with it is.

Flags
- A DXGI_SWAP_CHAIN_FLAG enumerated type. This is an extra flag describing the behavior of the swap chain. The only one that might be usefull right now is DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH, which changes the monitors resolution when swapping between windowed and fullscreen.


	DXGI_SWAP_CHAIN_DESC swapChainDesc; 
		
	ZeroMemory(&swapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));

	swapChainDesc.BufferDesc = bufferDesc;
	swapChainDesc.SampleDesc.Count = 1;
	swapChainDesc.SampleDesc.Quality = 0;
	swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	swapChainDesc.BufferCount = 1;
	swapChainDesc.OutputWindow = hwnd; 
	swapChainDesc.Windowed = TRUE; 
	swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

Creating the Device and SwapChain
( D3D11CreateDeviceAndSwapChain() )

Next we create the direct3d device, device context, and Swap Chain by calling the direct3d core function D3D11CreateDeviceAndSwapChain(). The functions parameters look like this:


HRESULT D3D11CreateDeviceAndSwapChain(
  __in   IDXGIAdapter *pAdapter,
  __in   D3D_DRIVER_TYPE DriverType,
  __in   HMODULE Software,
  __in   UINT Flags,
  __in   const D3D_FEATURE_LEVEL *pFeatureLevels,
  __in   UINT FeatureLevels,
  __in   UINT SDKVersion,
  __in   const DXGI_SWAP_CHAIN_DESC *pSwapChainDesc,
  __out  IDXGISwapChain **ppSwapChain,
  __out  ID3D11Device **ppDevice,
  __out  D3D_FEATURE_LEVEL *pFeatureLevel,
  __out  ID3D11DeviceContext **ppImmediateContext
);

Where each parameter is described below:

pAdapter
- This is a pointer to the video adapter to use. We can set NULL to use the default one.

DriverType
- A D3D_DRIVER_TYPE enumerated type. This says how direct3d will be implimented. We use D3D_DRIVER_TYPE_HARDWARE to say that direct3d will be implimented by the GPU (graphics card).

Software
- This is an HMODULE handle to a DLL that will be used to impliment software rasterizing.

Flags
- This is one or more D3D11_CREATE_DEVICE_FLAG types or'ed together.

pFeatureLevels
- This is a pointer to an array of D3D_FEATURE_LEVEL enumerated types that say what version of directx features to use. Set NULL to use the highest features available.

FeatureLevels
- This is the number of elements in the pFeatureLevels array. set to NULL.

SDKVersion
- The version of the DirectX SDK. Use D3D11_SDK_VERSION.

pSwapChainDesc
- A pointer to the created DXGI_SWAP_CHAIN_DESC structure, which we created above.

ppSwapChain
- A pointer to an IDXGISwapChain interface to recieve the created SwapChain.

ppDevice
- A pointer to our direct3d device.

pFeatureLevel
- This is a pointer to a D3D_FEATURE_LEVEL which will hold the highest feature level available. (Feature levels are used for backwards compatibility)

ppImmediateContext
- This is a pointer to our ID3D11DeviceContext (device context). Remember the device context will be used for the rendering methods of the device, to support multi-threading and boost performance.


	hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, NULL, NULL, NULL,
		D3D11_SDK_VERSION, &swapChainDesc, &SwapChain, &d3d11Device, NULL, &d3d11DevCon);

Creating the BackBuffer
( GetBuffer() )

Next we create our backbuffer which will be used to create our render target view. We call the GetBuffer method of the SwapChain interface:


HRESULT GetBuffer(
  [in]       UINT Buffer,
  [in]       REFIID riid,
  [in, out]  void **ppSurface
);

Where each parameter is described below:

Buffer
- Since we set swapChainDesc.SwapEffect to DXGI_SWAP_EFFECT_DISCARD, we only have access to the first buffer, so we set to 0.

riid
- This is a reference ID to the type of interface to change the back buffer. We use a 2d texture (ID3D11Texture2D).

ppSurface
- This is a pointer to the BackBuffer we created above, which is the surface we will render to.


	ID3D11Texture2D* BackBuffer;
	hr = SwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), (void**)&BackBuffer );

Creating the Render Target
( ID3D11Device::CreateRenderTargetView() )

Now we create our render target view, which we will send to the output merger stage of the pipeline. We can create our render target view by calling CreateRenderTargetView of our device interface:


HRESULT CreateRenderTargetView(
  [in]   ID3D11Resource *pResource,
  [in]   const D3D11_RENDER_TARGET_VIEW_DESC *pDesc,
  [out]  ID3D11RenderTargetView **ppRTView
);

Where each parameter is described below:

pResource
- This is our backbuffer.

pDesc
- A pointer to a D3D11_RENDER_TARGET_VIEW_DESC structure. We set NULL to create a view that accesses all of the subresources in mipmap level 0.

ppRTView
- This is a pointer to our ID3D11RenderTargetView interface, renderTargetView.


Now that we don't need the backbuffer anymore, we can release it.

	
	hr = d3d11Device->CreateRenderTargetView( BackBuffer, NULL, &renderTargetView );
	BackBuffer->Release();

Set the Render Targets
( ID3D11DeviceContext::OMSetRenderTargets() )

And the last thing we do while initializing, is bind the render target view to the output merger stage of the pipeline. This function will also bind our depth/stencil buffer as well, but we have not created one yet, so we set that parameter to NULL.


void OMSetRenderTargets(
  [in]  UINT NumViews,
  [in]  ID3D11RenderTargetView *const **ppRenderTargetViews,
  [in]  ID3D11DepthStencilView *pDepthStencilView
);

Where each parameter is described below:

NumViews
- This is the number of render targets to bind. We only have one.

ppRenderTargetViews
- This is an array of render target views to bind.

pDepthStencilView
- This is a pointer to the depth stencil buffer. We do not have one yet, so we set this one to NULL.


Thats all for the basic initializing of direct3d 11.


	d3d11DevCon->OMSetRenderTargets( 1, &renderTargetView, NULL );

Clean Up

Next we have the other new functions. The first one, ReleaseObjects(), will release all the COM objects we created. Don't forget to do this or you will create a memory leak.


void ReleaseObjects()
{
	//Release the COM Objects we created
	SwapChain->Release();
	d3d11Device->Release();
	d3dDevCon->Release();
}

Initialize Scene

The InitScene() function will be used to initialize our scene. In a video game, you will probably have many different scenes, so you will probably want to rename them from InitScene(). We will place our objects, load our models, textures, sounds, all that must be done to start off that specific scene.


bool InitScene()
{

	return true;
}

Update Scene

Next we have our UpdateScene() function. We will use this function to do all the updating of our scene, like changing objects locations, changing values, anything that changes in our scene will be done here. In this lesson, we will just change the color of our background, so in the update scene function, we will just change the color.


void UpdateScene()
{
	//Update the colors of our scene
	red += colormodr * 0.00005f;
	green += colormodg * 0.00002f;
	blue += colormodb * 0.00001f;

	if(red >= 1.0f || red <= 0.0f)
		colormodr *= -1;
	if(green >= 1.0f || green <= 0.0f)
		colormodg *= -1;
	if(blue >= 1.0f || blue <= 0.0f)
		colormodb *= -1;
}

Render Scene

Now we have our DrawScene() function. This is where we will simply render our scene. We should avoid doing any updating in this scene, and keep this function only for drawing our scene. This is where we will change the color of our background. Remember, if you have come from an earlier version of DirectX, like directx 10, all the rendering methods have been moved to the device context interface, so instead of calling d3dDevice like we would have in directx 10, we will call our d3dDeviceContext object to get the ClearRenderTargetView method, since this is a rendering method. We will call d3dDevice for other things that have to do with the GPU, other than rendering. Finally, we present the scene by calling the Present method of our swapchain interface. What this does is swap the front buffer with the back buffer. In the drawscene function, we will render to the backbuffer, then the back buffer is presented when call the Present method.


void DrawScene()
{
	//Clear our backbuffer to the updated color
	D3DXCOLOR bgColor( red, green, blue, 1.0f );

	d3d11DevCon->ClearRenderTargetView(renderTargetView, bgColor);

	//Present the backbuffer to the screen
	SwapChain->Present(0, 0);
}

This is our messageloop() function. Its pretty much the same as when we created our window in the last lesson, but now when there are no messages to be checked, we will first call our UpdateScene() function, to update our scene, then call the DrawScene() function, to draw our scene to the backbuffer and present the backbuffer to the screen.


int messageloop(){
	MSG msg;
	ZeroMemory(&msg, sizeof(MSG));
	while(true)
	{
		BOOL PeekMessageL( 
			LPMSG lpMsg,
			HWND hWnd,
			UINT wMsgFilterMin,
			UINT wMsgFilterMax,
			UINT wRemoveMsg
			);

		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			if (msg.message == WM_QUIT)
				break;
			TranslateMessage(&msg);	
			DispatchMessage(&msg);
		}
		else{
///////////////**************new**************////////////////////
			// run game code
            
			UpdateScene();
			DrawScene();
            
///////////////**************new**************////////////////////
		}
	}
	return msg.wParam;
}

Error Checking:

It will save you time checking for errors in your code when calling functions, as the application may continue running even though a function was not successful. When a function returns, you can check the value of the HRESULT to see how to continue your code. These are the return values of an HRESULT:

S_OK
The function was successful.

E_NOTIMPL
The function was not implimented.

E_NOINTERFACE
The interface is not supported.

E_ABORT
The function aborted.

E_FAIL
The function failed.

E_INVALIDARG
One or more arguments are invalid.

You can display the exact error that was returned by calling the DXGetErrorDescription(HRESULT hResult) function. You will need to link to the "DXErr.lib" library and include the "DXErr.h" header If you want to use this function.

The following is our InitializeDirect3d11App() function with error checking: (You will want to make sure you are NOT in full-screen when the error box pops up. You can do this by going to window mode right before you display the message.)


#pragma comment (lib, "DXErr.lib")
#include <DXErr.h>

...

bool InitializeDirect3d11App(HINSTANCE hInstance)
{
	HRESULT hr;

	//Describe our Buffer
	DXGI_MODE_DESC bufferDesc;

	ZeroMemory(&bufferDesc, sizeof(DXGI_MODE_DESC));

	bufferDesc.Width = Width;
	bufferDesc.Height = Height;
	bufferDesc.RefreshRate.Numerator = 60;
	bufferDesc.RefreshRate.Denominator = 1;
	bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
	bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
	
	//Describe our SwapChain
	DXGI_SWAP_CHAIN_DESC swapChainDesc; 
		
	ZeroMemory(&swapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));

	swapChainDesc.BufferDesc = bufferDesc;
	swapChainDesc.SampleDesc.Count = 1;
	swapChainDesc.SampleDesc.Quality = 0;
	swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	swapChainDesc.BufferCount = 1;
	swapChainDesc.OutputWindow = hwnd; 
	swapChainDesc.Windowed = TRUE; 
	swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;


	//Create our SwapChain
	hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, NULL, NULL, NULL,
		D3D11_SDK_VERSION, &swapChainDesc, &SwapChain, &d3d11Device, NULL, &d3d11DevCon);
	if(FAILED(hr))
	{	
		MessageBox(NULL, DXGetErrorDescription(hr),
			TEXT(" D3D11CreateDeviceAndSwapChain"), MB_OK);	
		return 0;	
	}	

	//Create our BackBuffer
	ID3D11Texture2D* BackBuffer;
	hr = SwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), (void**)&BackBuffer );
	if(FAILED(hr))
	{	
		MessageBox(NULL, DXGetErrorDescription(hr),
			TEXT("SwapChain->GetBuffer"), MB_OK);	
		return 0;	
	}	

	//Create our Render Target
	hr = d3d11Device->CreateRenderTargetView( BackBuffer, NULL, &renderTargetView );
	BackBuffer->Release();
	if(FAILED(hr))
	{	
		MessageBox(NULL, DXGetErrorDescription(hr),
			TEXT("d3d11Device->CreateRenderTargetView"), MB_OK);	
		return 0;	
	}	

	//Set our Render Target
	d3d11DevCon->OMSetRenderTargets( 1, &renderTargetView, NULL );

	return true;
}

Exercise:

1. In this lesson we have created a double buffer. Your exercise is to create a tripple buffer!

>> Download Source Code <<
<<-- Creating a Window
Begin Drawing! -->>



- Comments will not be seen by public -

- Please be sure to put your email in the message if you'd like a response -

10 + 1:
Name:
Message: