Jump to content

  • Log In with Google      Sign In   
  • Create Account


Linkandzelda

Member Since 19 Oct 2013
Offline Last Active Nov 01 2013 12:13 PM

Topics I've Started

Lighting messed up after creating Model class

24 October 2013 - 06:21 PM

A few days ago I setup lighting (2 directional lights, an ambient light and a point light) on a project within the main.cpp. Here's the piece of code in the main that handles the lighting setup after setting all the vector values.

XMMATRIX view = XMMatrixIdentity();
XMMATRIX world;

// Assign view to camera
view *= player_camera->getViewMatrix();

// Transform model world space
world = XMMatrixRotationX(XMConvertToRadians(x_degrees));
world *= XMMatrixRotationY(XMConvertToRadians(y_degrees));
world *= XMMatrixRotationZ(XMConvertToRadians(z_degrees));
world *= XMMatrixTranslation(noOf2 + -5.0f, noOf3 * -1.3f, noOf * 5.0f);

// Create transpose of model's world space
transpose = XMMatrixTranspose(world); // model world matrix

// Set constant buffer lighting values
cb0_values.directional_light_colour = g_directional_light_colour;
cb0_values.directional_light_colour_2 = g_directional_light_colour_2;
cb0_values.ambient_light_colour = g_ambient_light_colour;

// Transpose directional light
cb0_values.directional_light_vector = XMVector3Transform(g_directional_light_shines_from, transpose);
cb0_values.directional_light_vector = XMVector3Normalize( cb0_values.directional_light_vector );

// Second directional light
transpose = XMMatrixTranspose(world); // model world matrix
cb0_values.directional_light_vector_2 = XMVector3Transform(g_directional_light_shines_from_2, transpose);
cb0_values.directional_light_vector_2 = XMVector3Normalize( cb0_values.directional_light_vector_2 );

// Inverse for point light
inverse = XMMatrixInverse(&determinant, world);
cb0_values.point_light_vector = XMVector3Transform(point_light0_position, inverse);

// WVP into constant buffer
cb0_values.WorldViewProjection = world * view * projection;

// upload the new values for the constant buffer
g_pImmediateContext->UpdateSubresource(g_pConstantBuffer0, 0.1f, 0, &cb0_values, 0, 0);

// Load texture and sampler into resource
g_pImmediateContext->PSSetSamplers(0, 1, &g_pSampler0);
g_pImmediateContext->PSSetShaderResources(0, 1, &g_pTexture0);
g_pImmediateContext->PSSetShaderResources(1, 1, &g_pTexture1);

// Draw the vertex buffer to the back buffer
g_pImmediateContext->Draw(sizeof(vertices), 0);

Below is my Vertex shader code working along side this.

VOut output;

// calculate point light
float4 lightvector = point_light_vector - position;
float point_amount = dot(normalize(lightvector), normal); 				
point_amount =  saturate(point_amount);

// Assign position of vertex
output.position = mul(WVPMatrix, position);

// calculate first directional light
float diffuse_amount = dot(directional_light_vector, normal);
diffuse_amount =  saturate(diffuse_amount);

// second dir light
float diffuse_amount_2 = dot(directional_light_vector_2, normal);
diffuse_amount_2 =  saturate(diffuse_amount_2);

// add all the lights together
output.color = ambient_light_colour + ((directional_light_colour * diffuse_amount) + (directional_light_colour_2 * diffuse_amount_2)) + (point_amount * point_light_colour);

output.texcoord = texcoord;
output.normal = normal;

return output;

The above works 100% and I was rendering multiple of them using a for loop and moving the light sources throughout the world while rotating each model.

 

Then comes my problem, I adapted the above code into a model class that lets me set and update all the values like you would do with a model class. It also has its own vertex buffer and constant buffer per object, and I copied the code I had inside my main.cpp to handle that. Here's the Draw() function of the model class.

void model::Draw(XMMATRIX *view, XMMATRIX *projection) {
	XMMATRIX world, inverse, transpose;
	XMVECTOR determinant;
	MODEL_CONSTANT_BUFFER model_cb_values;

	world = XMMatrixRotationX(XMConvertToRadians(m_xangle));
	world *= XMMatrixRotationY(XMConvertToRadians(m_yangle));
	world *= XMMatrixRotationZ(XMConvertToRadians(m_zangle));
	world *= XMMatrixTranslation(m_x, m_y, m_z);
	world *= XMMatrixScaling(m_scale, m_scale, m_scale);

	model_cb_values.directional_light_vector =  XMVectorSet(m_dl_x, m_dl_y, m_dl_z, 0.0f);
	model_cb_values.directional_light_colour = XMVectorSet(m_dl_r, m_dl_g, m_dl_b, 0.0f);

	transpose = XMMatrixTranspose(world);
	model_cb_values.directional_light_vector = XMVector3Transform(model_cb_values.directional_light_vector, transpose);
	model_cb_values.directional_light_vector = XMVector3Normalize(model_cb_values.directional_light_vector);

	inverse = XMMatrixInverse(&determinant, world);
	model_cb_values.point_light_vector = XMVector3Transform(XMVectorSet(m_pl_x, m_pl_y, m_pl_z, 0.0f), inverse);

	model_cb_values.ambient_light_colour = XMVectorSet(m_al_r, m_al_g, m_al_b, 0.0f);
	model_cb_values.point_light_colour = XMVectorSet(m_pl_r, m_pl_g, m_pl_b, 0.0f);

	model_cb_values.WorldViewProjection = world*(*view)*(*projection);

	// Set the shader objects as active
    m_pImmediateContext->VSSetShader(m_pVShader, 0, 0);
    m_pImmediateContext->PSSetShader(m_pPShader, 0, 0);
	m_pImmediateContext->VSSetConstantBuffers(0, 1, &m_pConstantBuffer);

	// Load texture and sampler into resource
	m_pImmediateContext->PSSetSamplers(0, 1, &m_pSampler);
	m_pImmediateContext->PSSetShaderResources(0, 1, &m_pTexture);

	m_pImmediateContext->UpdateSubresource(m_pConstantBuffer, 0, 0, &model_cb_values, 0, 0);

	m_pObject->Draw();
}

It takes pointers of view and projection which is calculated before drawing and passed in. This is the updated shader code, which is pretty much identical as models were adapted to use a new shader.

cbuffer CB0
{
	matrix WVPMatrix;	// 64 bytes
	float4 directional_light_vector;	// 16 bytes
	float4 directional_light_colour;	// 16 bytes
	float4 ambient_light_colour;	// 16 bytes
	float4 point_light_vector;	// 16 bytes
	float4 point_light_colour;	// 16 bytes
	float4 packing; // 16 bytes
} // TOTAL SIZE = 112 bytes

Texture2D texture0;
SamplerState sampler0;

struct VOut
{
	float4 position : SV_POSITION;
	float4 color : COLOR;
	float2 texcoord :TEXCOORD;
};

VOut ModelVS(float4 position : POSITION,  float2 texcoord : TEXCOORD, float3 normal : NORMAL)
{
	VOut output;

	float4 default_color = {1.0f, 1.0f, 1.0f, 1.0f };

	float4 lightvector = point_light_vector - position;
	float point_amount = dot(normalize(lightvector), normal); 						
	point_amount =  saturate(point_amount);

	output.position = mul(WVPMatrix, position);

	output.texcoord = texcoord;

	float diffuse_amount = dot(directional_light_vector, normal);
	diffuse_amount =  saturate(diffuse_amount);

	output.color = ambient_light_colour + (directional_light_colour * diffuse_amount) + (point_amount * point_light_colour);
	
	return output;
}

float4 ModelPS(float4 position : SV_POSITION, float4 color : COLOR, float2 texcoord : TEXCOORD) : SV_TARGET 
{
	return texture0.Sample(sampler0, texcoord) * color;
}

Then I updated my main.cpp and set all the respective values identical to the ones from when it was running in the main like so.

Model1->setDirLight(-2.0f, 0.0f, -5.0f, lighting0_colour[0], lighting0_colour[1], lighting0_colour[2]);
Model1->setPtLight(3, 3, 0, 0.0f, 0.0f, 2.0f);
Model1->setAmbLight(0.1f, 0.1f, 0.1f);
				
Model1->setXPos(0.0);
Model1->setYPos(0.0);
Model1->setZPos(2.0);

Model1->setXAng(x_degrees);
Model1->setYAng(y_degrees);
Model1->setZAng(z_degrees);

Model1->setScale(0.5f);

Model1->Draw(&view, &projection);

The above results in the video here: https://dl.dropboxusercontent.com/u/2873587/LightingScrewed.mp4

 

You can see when I'm setting up the light positions that there's a directional light in the front left, (which I set to white), and a point light on 3,3,0 which is the right side of the object, and its set to blue. As soon as the video starts the object is in position 0 0 0 and no rotation, so everything looks fine. Then I begin to rotate the object and the lighting goes completely screwed and inverted and all sorts else. In the main.cpp version I was able to move the point light around the object (without doing any rotations) and the effects were what you expect. I mapped the point light in the model example (not in the video) and the results are not what you would expect at all, so something is off.

 

Is there anything I could have missed out to cause this? I've made this adaptation from main.cpp to model.cpp 3 times and the results are the same so I don't think I'm missing any code. If needed I can supply more code.

 

Thanks in advance, this was a long post with lots of code.

-Kris


Depth Buffer rendering nothing

19 October 2013 - 08:51 PM

Hello, I'm completely new to Directx 11 and I'm trying to implement a depth buffer in my program. Currently this is the result I'm getting when trying to render:

 

https://dl.dropboxusercontent.com/u/2873587/ZBufferFail.mp4

 

I've followed 2 different tutorials for depth buffer and it results in the same thing, so I'm starting to think the issue is related to something elsewhere in the code. Problem is, I don't have enough experience to know where to look or where to begin, so attached is my complete main.cpp file and shaders.hlsl.

 

main.cpp

#include <windows.h>
#include <d3d11.h>
#include <d3dx11.h>
#include <dxerr.h>

#define _XM_NO_INTRINSICS_
#define XM_NO_ALIGNMENT
#include <xnamath.h>

#include <windows.h>
#include <string>
#include <iostream>
#include <cstring>
using namespace std;;

//////////////////////////////////////////////////////////////////////////////////////
//	Global Variables
//////////////////////////////////////////////////////////////////////////////////////
HINSTANCE	g_hInst = NULL;
HWND		g_hWnd = NULL;

ID3D11Buffer*			g_pVertexBuffer;                
ID3D11VertexShader*		g_pVertexShader;         
ID3D11PixelShader*		g_pPixelShader;          
ID3D11InputLayout*		g_pInputLayout; 

ID3D11DepthStencilView* depthStencilView;
ID3D11Texture2D* depthStencilBuffer;

// Define vertex structure
struct POS_COL_VERTEX
{
	XMFLOAT3 Pos;
	XMFLOAT4 Col;
};

// Define vertices of a triangle - screen coordinates -1.0 to +1.0
    POS_COL_VERTEX vertices[] =
    {
         {XMFLOAT3(0.0f, 0.5f, 0.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f)},
		 {XMFLOAT3(0.5f, -0.5f, -0.5f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f)},
         {XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f)},

		 {XMFLOAT3(0.0f, 0.5f, 0.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f)},
         {XMFLOAT3(0.5f, -0.5f, 0.5f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f)},
         {XMFLOAT3(0.5f, -0.5f, -0.5f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f)},

		 {XMFLOAT3(0.0f, 0.5f, 0.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f)},
         {XMFLOAT3(-0.5f, -0.5f, 0.5f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f)},
		 {XMFLOAT3(0.5f, -0.5f, 0.5f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f)},

		 {XMFLOAT3(0.0f, 0.5f, 0.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)},
		 {XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)},
		 {XMFLOAT3(-0.5f, -0.5f, 0.5f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)},

		 {XMFLOAT3(0.5f, -0.5f, -0.5f), XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f)},
         {XMFLOAT3(0.5f, -0.5f, 0.5f), XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f)},
		 {XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f)},

		 {XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f)},
         {XMFLOAT3(0.5f, -0.5f, 0.5f), XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f)},
		 {XMFLOAT3(-0.5f, -0.5f, 0.5f), XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f)}
         
    };

// Rename for each tutorial
char		g_TutorialName[100] = "SWD304 - Tutorial 06 Exercise 01\0";

D3D_DRIVER_TYPE         g_driverType = D3D_DRIVER_TYPE_NULL;
D3D_FEATURE_LEVEL       g_featureLevel = D3D_FEATURE_LEVEL_11_0;
ID3D11Device*           g_pD3DDevice = NULL;
ID3D11DeviceContext*    g_pImmediateContext = NULL;
IDXGISwapChain*         g_pSwapChain = NULL;

ID3D11RenderTargetView* g_pBackBufferRTView = NULL;

float g_clear_colour[4] = {0.8f, 0.8f, 0.8f, 1.0f};

int screen_res[] = {640, 480};

ID3D11Buffer*			g_pConstantBuffer0; 

float redUpdate = 0.0f;
float scaleUpdate = 1.0f;
float xMod = 0.0f;
float yMod = 0.0f;

// Const buffer structs. Pack to 16 bytes. Don't let any single element cross a 16 byte boundary
struct CONSTANT_BUFFER0 
{
	float RedAmount;  	// 4 bytes
	float ScaleAmount; // 4 bytes
	float xModAmount; // 4 bytes
	float yModAmount; // 4 bytes
	XMMATRIX WorldViewProjection; // 64 bytes
	// Total 80
};

int buffer0_size = 80;

// World vars
float world_z = 2.00f;
float world_x = 0.00f;
float world_y = 0.00f;

float world_fieldOfView = 45.00f;
float world_z_min = 0.00f;
float world_z_max = 100.00f;

float x_degrees = 00.00f;
float y_degrees = 00.00f;
float z_degrees = 00.00f;

//////////////////////////////////////////////////////////////////////////////////////
//	Forward declarations
//////////////////////////////////////////////////////////////////////////////////////
HRESULT InitialiseWindow(HINSTANCE hInstance, int nCmdShow);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

HRESULT InitialiseD3D();
void ShutdownD3D();
void RenderFrame(void);
static void Draw();

HRESULT InitialiseGraphics(void);

//////////////////////////////////////////////////////////////////////////////////////
// Entry point to the program. Initializes everything and goes into a message processing 
// loop. Idle time is used to render the scene.
//////////////////////////////////////////////////////////////////////////////////////
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

	if(FAILED(InitialiseWindow(hInstance, nCmdShow)))
	{
		DXTRACE_MSG("Failed to create Window");
		return 0;
	}

	if(FAILED(InitialiseD3D()))
    {
 		DXTRACE_MSG("Failed to create Device");
		return 0;
    }

	if(FAILED(InitialiseGraphics())) 
	{
		DXTRACE_MSG( "Failed to initialise graphics" );
		return 0;
	}


	// Main message loop
	MSG msg = {0};

	while(msg.message != WM_QUIT)
	{
		if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
		{
			RenderFrame();
		}
	}

	ShutdownD3D();

	return (int) msg.wParam;
}


//////////////////////////////////////////////////////////////////////////////////////
// Register class and create window
//////////////////////////////////////////////////////////////////////////////////////
HRESULT InitialiseWindow(HINSTANCE hInstance, int nCmdShow)
{
	// Give your app window your own name
	char Name[100] = "Kristian Thomson\0";

	// Register class
	WNDCLASSEX wcex={0};
	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = WndProc;
	wcex.hInstance = hInstance;
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
//   wcex.hbrBackground = (HBRUSH )( COLOR_WINDOW + 1); // Needed for non-D3D apps
	wcex.lpszClassName = Name;

	if(!RegisterClassEx(&wcex)) return E_FAIL;

	// Create window
	g_hInst = hInstance;
	RECT rc = {0, 0, screen_res[0], screen_res[1]}; 
	AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
	g_hWnd = CreateWindow(	Name, g_TutorialName, WS_OVERLAPPEDWINDOW,
				CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, 
				rc.bottom - rc.top, NULL, NULL, hInstance, NULL);
	if(!g_hWnd)
		return E_FAIL;

	ShowWindow(g_hWnd, nCmdShow);

	return S_OK;
}

//////////////////////////////////////////////////////////////////////////////////////
// Called every time the application receives a message
//////////////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT ps;
	HDC hdc;

	int mouse_x = LOWORD(lParam);
	int mouse_y = HIWORD(lParam);

	float pointX = ((2.0f * (float)mouse_x) / (float) screen_res[0]) - 1.0f;
	float pointY = (((2.0f * (float)mouse_y) / (float) screen_res[1]) - 1.0f) * -1.0f;

	switch(message)
	{
		case WM_PAINT:
			hdc = BeginPaint(hWnd, &ps);
			EndPaint(hWnd, &ps);
			break;

		case WM_DESTROY:
			PostQuitMessage(0);
			break;

		case WM_LBUTTONDOWN:
			vertices[0].Pos.z -= 0.05f;
			vertices[1].Pos.z -= 0.05f;
			vertices[2].Pos.z -= 0.05f;

			//redUpdate += 0.05f;
			//scaleUpdate += 0.05f;
			
			break;

		case WM_RBUTTONDOWN:
			vertices[0].Pos.z += 0.05f;
			vertices[1].Pos.z += 0.05f;
			vertices[2].Pos.z += 0.05f;

			//redUpdate -= 0.05f;
			//scaleUpdate -= 0.05f;
			break;
		
		case WM_MOUSEMOVE:
			//g_clear_colour[0] = pointX;
			//g_clear_colour[1] = pointY;
			//g_clear_colour[2] = (mouse_x/mouse_y)/2;

			//vertices[0].Pos.x = pointX;
			//vertices[0].Pos.y = pointY;

			//vertices[3].Pos.x = pointX;
			//vertices[3].Pos.y = pointY;

			/*if (pointX > 0.0f && pointY > 0.0f) {
				vertices[1].Pos.x = pointX + -0.5f;
				vertices[1].Pos.y = pointY + -0.5f;
			}
			else {
				vertices[1].Pos.x = pointX + 0.5f;
				vertices[1].Pos.y = pointY + 0.5f;
			}*/

			//float xxx = vertices[3].Pos.x;
			break;

		case WM_KEYDOWN: 
			if(wParam == VK_ESCAPE) {
				DestroyWindow(g_hWnd);
				return 0;
			}
			if(wParam == VK_DOWN) {
				yMod -= 0.05f;
				world_z += 0.05f;
				break;
			}
			if(wParam == VK_UP) {
				yMod += 0.05f;
				world_z -= 0.05f;
				break;
			}
			if(wParam == VK_LEFT) {
				xMod -= 0.05f;
				world_x += 0.05f;
				break;
			}
			if(wParam == VK_RIGHT) {
				xMod += 0.05f;
				world_x -= 0.05f;
				break;
			}

			if(wParam == 0x54) {
				xMod += 0.05f;
				x_degrees -= 1.50f;
				break;
			}

			if(wParam == 0x59) {
				xMod += 0.05f;
				x_degrees += 1.50f;
				break;
			}
			if(wParam == 0x47) {
				xMod += 0.05f;
				y_degrees -= 1.50f;
				break;
			}

			if(wParam == 0x48) {
				xMod += 0.05f;
				y_degrees += 1.50f;
				break;
			}
			if(wParam == 0x42) {
				xMod += 0.05f;
				z_degrees -= 1.50f;
				break;
			}

			if(wParam == 0x4E) {
				xMod += 0.05f;
				z_degrees += 1.50f;
				break;
			}
            break;    		
             
		case WM_SIZE:
        if (g_pSwapChain)
        {
            g_pImmediateContext->OMSetRenderTargets(0, 0, 0);

            // Release all outstanding references to the swap chain's buffers.
            g_pBackBufferRTView->Release();

            HRESULT hr;
            // Preserve the existing buffer count and format.
            // Automatically choose the width and height to match the client rect for HWNDs.
            hr = g_pSwapChain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
                                            
            // Perform error handling here!

            // Get buffer and create a render-target-view.
            ID3D11Texture2D* pBuffer;
            hr = g_pSwapChain->GetBuffer(0, __uuidof( ID3D11Texture2D),
                                         (void**) &pBuffer );
            // Perform error handling here!

            hr = g_pD3DDevice->CreateRenderTargetView(pBuffer, NULL,
                                                     &g_pBackBufferRTView);
            // Perform error handling here!
            pBuffer->Release();

            g_pImmediateContext->OMSetRenderTargets(1, &g_pBackBufferRTView, NULL );

            // Set up the viewport.
			//RECT rc;
			//UINT width = rc.right - rc.left;
			//UINT height = rc.bottom - rc.top;

            D3D11_VIEWPORT vp;
            vp.Width = mouse_x;
            vp.Height = mouse_y;
            vp.MinDepth = 0.0f;
            vp.MaxDepth = 1.0f;
            vp.TopLeftX = 0;
            vp.TopLeftY = 0;
            g_pImmediateContext->RSSetViewports( 1, &vp );
        }
		break;

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

	return 0;
}

//////////////////////////////////////////////////////////////////////////////////////
// Create D3D device and swap chain
//////////////////////////////////////////////////////////////////////////////////////
HRESULT InitialiseD3D()
{
	HRESULT hr = S_OK;

	RECT rc;
	GetClientRect(g_hWnd, &rc);
	UINT width = rc.right - rc.left;
	UINT height = rc.bottom - rc.top;

	UINT createDeviceFlags = 0;

#ifdef _DEBUG
	createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

	D3D_DRIVER_TYPE driverTypes[] =
	{
		D3D_DRIVER_TYPE_HARDWARE, // comment out this line if you need to test D3D 11.0 functionality on hardware that doesn't support it
		D3D_DRIVER_TYPE_WARP, // comment this out also to use reference device
		D3D_DRIVER_TYPE_REFERENCE,
	};
	UINT numDriverTypes = ARRAYSIZE(driverTypes);

	D3D_FEATURE_LEVEL featureLevels[] =
	{
		D3D_FEATURE_LEVEL_11_0,
		D3D_FEATURE_LEVEL_10_1,
		D3D_FEATURE_LEVEL_10_0,
	};
	UINT numFeatureLevels = ARRAYSIZE(featureLevels);

	DXGI_SWAP_CHAIN_DESC sd;
	ZeroMemory(&sd, sizeof(sd));
	sd.BufferCount = 1;
	sd.BufferDesc.Width = width;
	sd.BufferDesc.Height = height;
	sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	sd.BufferDesc.RefreshRate.Numerator = 60;
	sd.BufferDesc.RefreshRate.Denominator = 1;
	sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	sd.OutputWindow = g_hWnd;
	sd.SampleDesc.Count = 1;
	sd.SampleDesc.Quality = 0;
	sd.Windowed = true;
	sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

	for(UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++)
	{
		g_driverType = driverTypes[driverTypeIndex];
		hr = D3D11CreateDeviceAndSwapChain(NULL, g_driverType, NULL, 
			createDeviceFlags, featureLevels, numFeatureLevels, 
			D3D11_SDK_VERSION, &sd, &g_pSwapChain, 
			&g_pD3DDevice, &g_featureLevel, &g_pImmediateContext);
		if(SUCCEEDED(hr))
			break;
	}

	if(FAILED(hr))
		return hr;

	// Get pointer to back buffer texture
	ID3D11Texture2D *pBackBufferTexture;
	hr = g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D),
                                      (LPVOID*)&pBackBufferTexture);

	if(FAILED(hr)) return hr;
	
	// Use the back buffer texture pointer to create the render target view
	hr = g_pD3DDevice->CreateRenderTargetView(pBackBufferTexture, NULL,
                                                    &g_pBackBufferRTView);
	pBackBufferTexture->Release();

	if(FAILED(hr)) return hr;

	//Describe our Depth/Stencil Buffer
	D3D11_TEXTURE2D_DESC depthStencilDesc;

	depthStencilDesc.Width     = width;
	depthStencilDesc.Height    = height;
	depthStencilDesc.MipLevels = 1;
	depthStencilDesc.ArraySize = 1;
	depthStencilDesc.Format    = DXGI_FORMAT_D24_UNORM_S8_UINT;
	depthStencilDesc.SampleDesc.Count   = 1;
	depthStencilDesc.SampleDesc.Quality = 0;
	depthStencilDesc.Usage          = D3D11_USAGE_DEFAULT;
	depthStencilDesc.BindFlags      = D3D11_BIND_DEPTH_STENCIL;
	depthStencilDesc.CPUAccessFlags = 0; 
	depthStencilDesc.MiscFlags      = 0;

	g_pD3DDevice->CreateTexture2D(&depthStencilDesc, NULL, &depthStencilBuffer);
	g_pD3DDevice->CreateDepthStencilView(depthStencilBuffer, NULL, &depthStencilView);

	// Set the render target view
	g_pImmediateContext->OMSetRenderTargets(1, &g_pBackBufferRTView, depthStencilView);

	// Set the viewport
	D3D11_VIEWPORT viewport;

	viewport.TopLeftX = 0;
	viewport.TopLeftY = 0;
	viewport.Width = width;
	viewport.Height = height;
	viewport.MinDepth = 0.0f;
	viewport.MaxDepth = 1.0f;

	g_pImmediateContext->RSSetViewports(1, &viewport);


	return S_OK;
}

//////////////////////////////////////////////////////////////////////////////////////
// Clean up D3D objects
//////////////////////////////////////////////////////////////////////////////////////
void ShutdownD3D()
{
	if(g_pVertexBuffer) g_pVertexBuffer->Release();
	if(g_pInputLayout) g_pInputLayout->Release();
	if(g_pVertexShader) g_pVertexShader->Release();
	if(g_pPixelShader) g_pPixelShader->Release();
	
	if(g_pSwapChain) g_pSwapChain->Release();
	if(g_pImmediateContext) g_pImmediateContext->Release();
	if(g_pD3DDevice) g_pD3DDevice->Release();

	if(g_pBackBufferRTView) g_pBackBufferRTView->Release();

	if(g_pConstantBuffer0) g_pConstantBuffer0->Release();

	if(depthStencilView) depthStencilView->Release();
	if(depthStencilBuffer) depthStencilBuffer->Release();
}

// Render frame
void RenderFrame(void)
{
	g_pImmediateContext->ClearRenderTargetView(g_pBackBufferRTView, g_clear_colour);

	g_pImmediateContext->ClearDepthStencilView(depthStencilView, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, 1.0f, 0);

	CONSTANT_BUFFER0 cb0_values;

	// Update world view projection
	XMMATRIX projection, world, view;
	XMMATRIX world2;

	world = XMMatrixRotationX(XMConvertToRadians(45));
	world *= XMMatrixRotationY(XMConvertToRadians(45));
	world *= XMMatrixRotationZ(XMConvertToRadians(45));
	world *= XMMatrixTranslation(0, 0 , 5);

	projection = XMMatrixPerspectiveFovLH(XMConvertToRadians(world_fieldOfView), (float)screen_res[0]/(float)screen_res[1], world_z_min, world_z_max);
	view = XMMatrixIdentity();
	view *= XMMatrixTranslation(world_x, world_y , 0);
	cb0_values.WorldViewProjection = world * view * projection;

	// Set vertex buffer 
	UINT stride = sizeof(POS_COL_VERTEX);
	UINT offset = 0;
	g_pImmediateContext->IASetVertexBuffers(0, 1, &g_pVertexBuffer, &stride, &offset);

	// Select which primtive type to use
	g_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

	// Draw the vertex buffer to the back buffer
	g_pImmediateContext->Draw(sizeof(vertices), 0);

	// upload the new values for the constant buffer
	g_pImmediateContext->UpdateSubresource(g_pConstantBuffer0, 0, 0, &cb0_values, 0, 0);

	world2 = XMMatrixRotationX(XMConvertToRadians(x_degrees));
	world2 *= XMMatrixRotationY(XMConvertToRadians(y_degrees));
	world2 *= XMMatrixRotationZ(XMConvertToRadians(z_degrees));
	world2 *= XMMatrixTranslation(0, 0.3f, world_z);

	cb0_values.WorldViewProjection = world2 * view * projection;

	g_pImmediateContext->UpdateSubresource(g_pConstantBuffer0, 0, 0, &cb0_values, 0, 0);

	// Draw the vertex buffer to the back buffer
	g_pImmediateContext->Draw(sizeof(vertices), 0);

	// Display what has just been rendered
	g_pSwapChain->Present(0, 0);

	Draw();
}

static void Draw() {
	D3D11_MAPPED_SUBRESOURCE ms;
	g_pImmediateContext->Map(g_pVertexBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &ms);	// Lock the buffer to allow writing
	memcpy(ms.pData, vertices, sizeof(vertices)); // Copy the data
	g_pImmediateContext->Unmap(g_pVertexBuffer, NULL);	// Unlock the buffer
}

HRESULT InitialiseGraphics()
{
    HRESULT hr = S_OK;

    // Set up and create vertex buffer
    D3D11_BUFFER_DESC bufferDesc;
    ZeroMemory(&bufferDesc, sizeof(bufferDesc));
    bufferDesc.Usage = D3D11_USAGE_DYNAMIC;		// Used by CPU and GPU
    bufferDesc.ByteWidth = sizeof(POS_COL_VERTEX) * sizeof(vertices);	// Total size of buffer, 3 vertices
    bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;	// Use as a vertex buffer
    bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;// Allow CPU access
    hr = g_pD3DDevice->CreateBuffer(&bufferDesc, NULL, &g_pVertexBuffer);//Create the buffer

    if(FAILED(hr)) // return error code on failure
    {
         return hr;
    }
	

	// Create constant buffer
	D3D11_BUFFER_DESC constant_buffer_desc;
	ZeroMemory(&constant_buffer_desc, sizeof(constant_buffer_desc));

	constant_buffer_desc.Usage = D3D11_USAGE_DEFAULT;	// Can use UpdateSubresource() to update
	constant_buffer_desc.ByteWidth = buffer0_size;	// MUST be a multiple of 16, calculate from CB struct
	constant_buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;// Use as a constant buffer

	hr = g_pD3DDevice->CreateBuffer(&constant_buffer_desc, NULL, &g_pConstantBuffer0);

	if(FAILED(hr)) return hr;

    // Copy the vertices into the buffer
    Draw();

    // Load and compile pixel and vertex shaders - use vs_5_0 to target DX11 hardware only
    ID3DBlob *VS, *PS, *error;
    hr = D3DX11CompileFromFile("shaders.hlsl", 0, 0, "VShader", "vs_4_0", 0, 0, 0, &VS, &error, 0);

    if(error != 0) // check for shader compilation error
    {
        OutputDebugStringA((char*)error->GetBufferPointer());
        error->Release();
        if(FAILED(hr)) // don't fail if error is just a warning
        {
            return hr;
        };
    }


    hr = D3DX11CompileFromFile("shaders.hlsl", 0, 0, "PShader", "ps_4_0", 0, 0, 0, &PS, &error, 0);

    if(error != 0)// check for shader compilation error
    {
        OutputDebugStringA((char*)error->GetBufferPointer());
        error->Release();
        if(FAILED(hr))// don't fail if error is just a warning
        {
            return hr;
        };
    }


    // Create shader objects
    hr = g_pD3DDevice->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &g_pVertexShader);

    if(FAILED(hr))
    {
        return hr;
    }
    
    hr = g_pD3DDevice->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &g_pPixelShader);

    if(FAILED(hr))
    {
        return hr;
    }

    // Set the shader objects as active
    g_pImmediateContext->VSSetShader(g_pVertexShader, 0, 0);
    g_pImmediateContext->PSSetShader(g_pPixelShader, 0, 0);
	g_pImmediateContext->VSSetConstantBuffers(0, 1, &g_pConstantBuffer0);

    // Create and set the input layout object
    D3D11_INPUT_ELEMENT_DESC iedesc[] =
    {
      {"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},
    };

    hr = g_pD3DDevice->CreateInputLayout(iedesc, 2, VS->GetBufferPointer(), VS->GetBufferSize(), &g_pInputLayout);

    if(FAILED(hr))
    {
        return hr;
    }

    g_pImmediateContext->IASetInputLayout(g_pInputLayout);

    return S_OK;
 }

Shaders

cbuffer CBuffer0
{
	float red_fraction; // 4 bytes
	float scale_fraction; // 4 bytes
	float xmod_fraction; // 4 bytes
	float ymod_fraction; // 4 bytes
	matrix WVPMatrix;	// 64 bytes
}


struct VOut
 {
     float4 position : SV_POSITION;
     float4 color : COLOR;
 };

 VOut VShader(float4 position : POSITION, float4 color : COLOR)
 {
     VOut output;

	 //color.r *= red_fraction;
	 //position.x *= scale_fraction;
	 //position.y *= scale_fraction;

	 //position.x += xmod_fraction;
	 //position.y += ymod_fraction;

     //output.position = position;
     output.color = color;

	 //output.color.g = output.position.y;
	 //output.color.b = output.position.x;

	 output.position = mul(WVPMatrix, position);

     return output;
 }


 float4 PShader(float4 position : SV_POSITION, float4 color : COLOR) : SV_TARGET
 {
	 //color.g = position.x;
	 //color.r = position.y;
	 
	 return color;
 }

Thank you very much in advance, I've been stuck on this all day and I have no idea what else to do to fix it.


PARTNERS