Weird tearing lines on textured rotating cube, in windowed mode

Started by
8 comments, last by Zaoshi Kaba 8 years, 9 months ago

Hello, I have just started with directx programming, and made my first textured cube. The thing is that in windowed mode there´s some wierd tearing lines, both verticly and horizontally. Have a video on it here (recorded with ShadowPlay): https://www.dropbox.com/s/xk0st42hirmnk32/Desktop%202015.06.12%20-%2022.11.36.13.mp4?dl=0

Becuase of the fact that it shows up on the recordning I don´t think it´s something with vsync, becuase if I have understood correctly normal screentearing is when the GPU renders more frames than the Monitor can show.

Does anyone have any idea what can be the problem?

I have tried to set VSYNC on and it didn´t fix it. I have googled similar problems but didn´t get anything out of it. I tested to put an "if-statement" after the "AdjustWindowRec"-function, were I wanted to see if the screenwidth were equal to clientRectangle.right - clientRectangle.left, and it was. Could this be it? And if it is I have no idea why this would be the problem. If I have understood things proberly there can be some tearing in windowed mode when the window is smaller than the swapchain.

Here´s my code:


#include <Windows.h>
#include <d3d11.h>
#include <d3dx11.h>
#include <d3dx10.h>

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

#define COLOR D3DXCOLOR
#define MATRIX D3DXMATRIX
#define VECTOR3 D3DXVECTOR3
#define VECTOR4 D3DXVECTOR4
#define wTrue while(true)
#define SZeroMem RtlSecureZeroMemory

struct Vertex
{
	float x;
	float y;
	float z;
	VECTOR3 vertexNormal;
	float u;
	float v;
};

struct ConstantBuffer
{
	MATRIX resultMatrix;
	MATRIX rotationMatrix;
	VECTOR4 lightVector;
	COLOR lightColor;
	COLOR ambientLightColor;
};

Vertex vertecies[] =
{
	{ -1.0f, -1.0f, 1.0f, D3DXVECTOR3(0.0f, 0.0f, 1.0f), 0.0f, 0.0f },
	{ 1.0f, -1.0f, 1.0f, D3DXVECTOR3(0.0f, 0.0f, 1.0f), 0.0f, 1.0f },
	{ -1.0f, 1.0f, 1.0f, D3DXVECTOR3(0.0f, 0.0f, 1.0f), 1.0f, 0.0f },
	{ 1.0f, 1.0f, 1.0f, D3DXVECTOR3(0.0f, 0.0f, 1.0f), 1.0f, 1.0f },

	{ -1.0f, -1.0f, -1.0f, D3DXVECTOR3(0.0f, 0.0f, -1.0f), 0.0f, 0.0f },
	{ -1.0f, 1.0f, -1.0f, D3DXVECTOR3(0.0f, 0.0f, -1.0f), 0.0f, 1.0f },
	{ 1.0f, -1.0f, -1.0f, D3DXVECTOR3(0.0f, 0.0f, -1.0f), 1.0f, 0.0f },
	{ 1.0f, 1.0f, -1.0f, D3DXVECTOR3(0.0f, 0.0f, -1.0f), 1.0f, 1.0f },

	{ -1.0f, 1.0f, -1.0f, D3DXVECTOR3(0.0f, 1.0f, 0.0f), 0.0f, 0.0f },
	{ -1.0f, 1.0f, 1.0f, D3DXVECTOR3(0.0f, 1.0f, 0.0f), 0.0f, 1.0f },
	{ 1.0f, 1.0f, -1.0f, D3DXVECTOR3(0.0f, 1.0f, 0.0f), 1.0f, 0.0f },
	{ 1.0f, 1.0f, 1.0f, D3DXVECTOR3(0.0f, 1.0f, 0.0f), 1.0f, 1.0f },

	{ -1.0f, -1.0f, -1.0f, D3DXVECTOR3(0.0f, -1.0f, 0.0f), 0.0f, 0.0f },
	{ 1.0f, -1.0f, -1.0f, D3DXVECTOR3(0.0f, -1.0f, 0.0f), 0.0f, 1.0f },
	{ -1.0f, -1.0f, 1.0f, D3DXVECTOR3(0.0f, -1.0f, 0.0f), 1.0f, 0.0f },
	{ 1.0f, -1.0f, 1.0f, D3DXVECTOR3(0.0f, -1.0f, 0.0f), 1.0f, 1.0f },

	{ 1.0f, -1.0f, -1.0f, D3DXVECTOR3(1.0f, 0.0f, 0.0f), 0.0f, 0.0f },
	{ 1.0f, 1.0f, -1.0f, D3DXVECTOR3(1.0f, 0.0f, 0.0f), 0.0f, 1.0f },
	{ 1.0f, -1.0f, 1.0f, D3DXVECTOR3(1.0f, 0.0f, 0.0f), 1.0f, 0.0f },
	{ 1.0f, 1.0f, 1.0f, D3DXVECTOR3(1.0f, 0.0f, 0.0f), 1.0f, 1.0f },

	{ -1.0f, -1.0f, -1.0f, D3DXVECTOR3(-1.0f, 0.0f, 0.0f), 0.0f, 0.0f },
	{ -1.0f, -1.0f, 1.0f, D3DXVECTOR3(-1.0f, 0.0f, 0.0f), 0.0f, 1.0f },
	{ -1.0f, 1.0f, -1.0f, D3DXVECTOR3(-1.0f, 0.0f, 0.0f), 1.0f, 0.0f },
	{ -1.0f, 1.0f, 1.0f, D3DXVECTOR3(-1.0f, 0.0f, 0.0f), 1.0f, 1.0f },
};

DWORD indicies[] =
{
	0, 1, 2,
	2, 1, 3,
	4, 5, 6,
	6, 5, 7,
	8, 9, 10,
	10, 9, 11,
	12, 13, 14,
	14, 13, 15,
	16, 17, 18,
	18, 17, 19,
	20, 21, 22,
	22, 21, 23,
};

HRESULT CALLBACK handleMessage(HWND windowHandle, unsigned int message, WPARAM wParam, LPARAM lParam);

void initializeDirect3D();
void initializePipeline();
void initializeGraphics();
void updateCamera();
void render();
void releaseApplicationComponents();

int screenWidth = 1920;
int screenHeight = 1080;

float sampleDescCount = 8.0f;
float sampleDescQuality = 32.0f;
float anisotropicFilterQuality = 16.0f;

float blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };

bool renderWireFrame = false;
bool renderBackFace = false;
bool renderBothFaceSides = false;
bool allowAntiAlisingOnLines = false;
bool multisampleLines = true;
bool debug = false;

LPWSTR windowClassName = L"WndClass";
LPWSTR shaderFilePath = L"../debug/Shaders/Shaders.fx";
LPWSTR textureFilePath = L"../debug/Textures/Texture_lava.png";

HWND windowHandle;

IDXGISwapChain* swapChain = nullptr;
ID3D11Device* device = nullptr;
ID3D11DeviceContext* deviceContext = nullptr;

//shaders
ID3D11VertexShader* vertexShader = nullptr;
ID3D11PixelShader* pixelShader = nullptr;

ID3D11ShaderResourceView* texture = nullptr;

//Buffers
ID3D11Buffer* vertexBuffer = nullptr;
ID3D11Buffer* indexBuffer = nullptr;
ID3D11Buffer* constantBuffer = nullptr;

ID3D11RenderTargetView* backBuffer = nullptr;
ID3D11DepthStencilView* depthBuffer = nullptr;

//texturebuffers
ID3D11Texture2D* backBufferPointer = nullptr;
ID3D11Texture2D* depthBufferPointer = nullptr;

ID3D11InputLayout* inputLayout = nullptr;

//databuffers
ID3D10Blob* vertexShaderBlob = nullptr;
ID3D10Blob* pixelShaderBlob = nullptr;
ID3D10Blob* errorMessageBlob = nullptr;

//States
ID3D11RasterizerState* defaultRazterizerState = nullptr;
ID3D11SamplerState* defaultSamplerState = nullptr;
ID3D11BlendState* defaultBlendState = nullptr;

MATRIX translationMatrix;
MATRIX rotationXMatrix;
MATRIX rotationYMatrix;
MATRIX rotationZMatrix;
MATRIX totalRotationMatrix;
MATRIX scaleMatrix;
MATRIX worldMatrix;
MATRIX viewMatrix;
MATRIX projectionMatrix;
MATRIX resultMatrix;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE previousHInstance, LPSTR cmdLine, int cmdShow)
{
	WNDCLASSEX windowClass;
	SZeroMem(&windowClass, sizeof(WNDCLASSEX));
	
	windowClass.cbClsExtra = 0;
	windowClass.cbSize = sizeof(WNDCLASSEX);
	windowClass.cbWndExtra = 0;
	windowClass.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH);
	windowClass.hCursor = LoadCursor(0, IDC_ARROW);
	windowClass.hIcon = LoadIcon(0, IDI_APPLICATION);
	windowClass.hIconSm = 0;
	windowClass.hInstance = hInstance;
	windowClass.lpfnWndProc = handleMessage;
	windowClass.lpszClassName = windowClassName;
	windowClass.lpszMenuName = 0;
	windowClass.style = CS_HREDRAW | CS_VREDRAW;

	RegisterClassEx(&windowClass);

	DWORD windowStyle = WS_SYSMENU | WS_MINIMIZEBOX | WS_OVERLAPPED;

	RECT clientRectangle = { 0, 0, screenWidth, screenHeight };
	AdjustWindowRect(&clientRectangle, windowStyle, false);

	windowHandle = CreateWindowExW(0, windowClassName, L"DX11 Application", windowStyle,
		100, 100, clientRectangle.right - clientRectangle.left, clientRectangle.bottom - clientRectangle.top, 0, 0, hInstance, 0);

	initializeDirect3D();

	ShowWindow(windowHandle, cmdShow);

	MSG message;

	wTrue
	{
		if (PeekMessage(&message, 0, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&message);

			DispatchMessage(&message);

			if (message.message == WM_QUIT)
			{
				break;
			}
		}
		else
		{
			render();
		}
	}

	releaseApplicationComponents();

	return message.wParam;
}

HRESULT CALLBACK handleMessage(HWND windowHandle, unsigned int message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	case WM_PAINT:
		render();
		break;
	}

	return DefWindowProc(windowHandle, message, wParam, lParam);
}

void render()
{
	ConstantBuffer cBuffer;

	cBuffer.lightVector = VECTOR4(1.0f, 1.0f, 1.0f, 0.0f);
	cBuffer.lightColor = COLOR(0.6f, 0.8f, 0.8f, 1.0f);
	cBuffer.ambientLightColor = COLOR(0.1f, 0.1f, 0.1f, 1.0f);

	updateCamera();

	cBuffer.resultMatrix = resultMatrix;
	cBuffer.rotationMatrix = totalRotationMatrix;

	deviceContext->RSSetState(defaultRazterizerState);
	deviceContext->PSSetSamplers(0, 1, &defaultSamplerState);
	deviceContext->OMSetBlendState(defaultBlendState, blendFactor, 0xffffffff);

	deviceContext->ClearRenderTargetView(backBuffer, COLOR(0.0f, 0.5f, 0.9f, 1.0f));
	deviceContext->ClearDepthStencilView(depthBuffer, D3D11_CLEAR_DEPTH, 1.0f, 0);

	unsigned int stride = sizeof(Vertex);
	unsigned int offset = 0;
	deviceContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
	deviceContext->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R32_UINT, 0);

	deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

	deviceContext->UpdateSubresource(constantBuffer, 0, 0, &cBuffer, 0, 0);
	deviceContext->PSSetShaderResources(0, 1, &texture);
	deviceContext->DrawIndexed(36, 0, 0);

	swapChain->Present(0, 0);
}

void initializeDirect3D()
{
	DXGI_SWAP_CHAIN_DESC swapChainDescription;
	SZeroMem(&swapChainDescription, sizeof(DXGI_SWAP_CHAIN_DESC));

	swapChainDescription.BufferCount = 1;
	swapChainDescription.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	swapChainDescription.BufferDesc.Height = screenHeight;
	swapChainDescription.BufferDesc.Width = screenWidth;
	swapChainDescription.BufferDesc.RefreshRate.Denominator = 1;
	swapChainDescription.BufferDesc.RefreshRate.Numerator = 0;
	swapChainDescription.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
	swapChainDescription.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
	swapChainDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	swapChainDescription.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
	swapChainDescription.OutputWindow = windowHandle;
	swapChainDescription.SampleDesc.Count = sampleDescCount;
	swapChainDescription.SampleDesc.Quality = sampleDescQuality;
	swapChainDescription.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
	swapChainDescription.Windowed = true;

	if (debug)
	{
		D3D11CreateDeviceAndSwapChain(0, D3D_DRIVER_TYPE_HARDWARE, 0, D3D11_CREATE_DEVICE_DEBUG, 0, 0, D3D11_SDK_VERSION,
			&swapChainDescription, &swapChain, &device, 0, &deviceContext);
	}
	else
	{
		D3D11CreateDeviceAndSwapChain(0, D3D_DRIVER_TYPE_HARDWARE, 0, 0, 0, 0, D3D11_SDK_VERSION,
			&swapChainDescription, &swapChain, &device, 0, &deviceContext);
	}

	D3D11_TEXTURE2D_DESC depthBufferTextureDescription;
	SZeroMem(&depthBufferTextureDescription, sizeof(D3D11_TEXTURE2D_DESC));

	depthBufferTextureDescription.ArraySize = 1;
	depthBufferTextureDescription.BindFlags = D3D11_BIND_DEPTH_STENCIL;
	//depthBufferTextureDescription.CPUAccessFlags = 0;
	depthBufferTextureDescription.Format = DXGI_FORMAT_D32_FLOAT;
	depthBufferTextureDescription.Height = screenHeight;
	depthBufferTextureDescription.Width = screenWidth;
	depthBufferTextureDescription.MipLevels = 1;
	//depthBufferTextureDescription.MiscFlags = 0;
	depthBufferTextureDescription.SampleDesc.Count = sampleDescCount;
	depthBufferTextureDescription.SampleDesc.Quality = sampleDescQuality;
	depthBufferTextureDescription.Usage = D3D11_USAGE_DEFAULT;

	device->CreateTexture2D(&depthBufferTextureDescription, 0, &depthBufferPointer);

	D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDescription;
	SZeroMem(&depthStencilViewDescription, sizeof(D3D11_DEPTH_STENCIL_VIEW_DESC));

	depthStencilViewDescription.Format = DXGI_FORMAT_D32_FLOAT;
	depthStencilViewDescription.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;

	device->CreateDepthStencilView(depthBufferPointer, &depthStencilViewDescription, &depthBuffer);
	depthBufferPointer->Release();
	depthBufferPointer = nullptr;

	if (swapChain)
	{
		swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&backBufferPointer);
	}

	if (device)
	{
		device->CreateRenderTargetView(backBufferPointer, 0, &backBuffer);
		backBufferPointer->Release();
		backBufferPointer = nullptr;
	}

	if (deviceContext)
	{
		deviceContext->OMSetRenderTargets(1, &backBuffer, depthBuffer);
	}

	D3D11_VIEWPORT viewport;
	SZeroMem(&viewport, sizeof(D3D11_VIEWPORT));

	viewport.Height = screenHeight;
	viewport.Width = screenWidth;
	viewport.MaxDepth = 1.0f;
	viewport.MinDepth = 0.0f;
	viewport.TopLeftX = 0.0f;
	viewport.TopLeftY = 0.0f;

	if (deviceContext)
	{
		deviceContext->RSSetViewports(1, &viewport);
	}

	initializePipeline();
	initializeGraphics();
}

void initializePipeline()
{
	D3DX11CompileFromFile(shaderFilePath, 0, 0, "vertexShader", "vs_4_0", D3D10_SHADER_OPTIMIZATION_LEVEL3, 0, 0, &vertexShaderBlob, &errorMessageBlob, 0);

	if (errorMessageBlob)
	{
		OutputDebugStringA((char*)errorMessageBlob->GetBufferPointer());
	}

	D3DX11CompileFromFile(shaderFilePath, 0, 0, "pixelShader", "ps_4_0", D3D10_SHADER_OPTIMIZATION_LEVEL3, 0, 0, &pixelShaderBlob, &errorMessageBlob, 0);

	if (errorMessageBlob)
	{
		OutputDebugStringA((char*)errorMessageBlob->GetBufferPointer());
	}

	device->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), 0, &vertexShader);
	device->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), 0, &pixelShader);

	deviceContext->VSSetShader(vertexShader, 0, 0);
	deviceContext->PSSetShader(pixelShader, 0, 0);

	D3D11_INPUT_ELEMENT_DESC inputElementDescription[] = 
	{
		{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
	};

	device->CreateInputLayout(inputElementDescription, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &inputLayout);
	deviceContext->IASetInputLayout(inputLayout);

	D3D11_BUFFER_DESC constantBufferDescription;
	SZeroMem(&constantBufferDescription, sizeof(D3D11_BUFFER_DESC));

	constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	constantBufferDescription.ByteWidth = 176;
	constantBufferDescription.CPUAccessFlags = 0;
	constantBufferDescription.MiscFlags = 0;
	constantBufferDescription.StructureByteStride = 0;
	constantBufferDescription.Usage = D3D11_USAGE_DEFAULT;

	device->CreateBuffer(&constantBufferDescription, 0, &constantBuffer);
	deviceContext->VSSetConstantBuffers(0, 1, &constantBuffer);

	D3D11_RASTERIZER_DESC rasterizerStateDescription;
	SZeroMem(&rasterizerStateDescription, sizeof(D3D11_RASTERIZER_DESC));

	rasterizerStateDescription.AntialiasedLineEnable = false;
	rasterizerStateDescription.CullMode = D3D11_CULL_BACK;
	rasterizerStateDescription.DepthBias = 0.0f;
	rasterizerStateDescription.DepthBiasClamp = 0.0f;
	rasterizerStateDescription.DepthClipEnable = false;
	rasterizerStateDescription.FillMode = D3D11_FILL_SOLID;
	rasterizerStateDescription.FrontCounterClockwise = false;
	rasterizerStateDescription.MultisampleEnable = false;
	rasterizerStateDescription.ScissorEnable = false;
	rasterizerStateDescription.SlopeScaledDepthBias = 0.0f;

	if (renderWireFrame)
	{
		rasterizerStateDescription.FillMode = D3D11_FILL_WIREFRAME;
	}

	if (renderBackFace)
	{
		rasterizerStateDescription.CullMode = D3D11_CULL_FRONT;
	}

	if (renderBothFaceSides)
	{
		rasterizerStateDescription.CullMode = D3D11_CULL_NONE;
	}

	if (multisampleLines)
	{
		rasterizerStateDescription.MultisampleEnable = true;
		rasterizerStateDescription.AntialiasedLineEnable = false;
	}

	if (allowAntiAlisingOnLines)
	{
		rasterizerStateDescription.AntialiasedLineEnable = true;
		rasterizerStateDescription.MultisampleEnable = false;
	}

	device->CreateRasterizerState(&rasterizerStateDescription, &defaultRazterizerState);

	D3D11_SAMPLER_DESC samplerStateDescription;
	SZeroMem(&samplerStateDescription, sizeof(D3D11_SAMPLER_DESC));

	samplerStateDescription.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
	samplerStateDescription.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
	samplerStateDescription.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
	samplerStateDescription.BorderColor[0] = 1.0f;
	samplerStateDescription.BorderColor[1] = 1.0f;
	samplerStateDescription.BorderColor[2] = 1.0f;
	samplerStateDescription.BorderColor[3] = 1.0f;
	samplerStateDescription.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
	samplerStateDescription.Filter = D3D11_FILTER::D3D11_FILTER_ANISOTROPIC;
	samplerStateDescription.MaxAnisotropy = anisotropicFilterQuality;
	samplerStateDescription.MaxLOD = FLT_MAX;
	samplerStateDescription.MinLOD = 0.0f;
	samplerStateDescription.MipLODBias = 0.0f;

	device->CreateSamplerState(&samplerStateDescription, &defaultSamplerState);

	D3D11_BLEND_DESC blendStateDescription;
	SZeroMem(&blendStateDescription, sizeof(D3D11_BLEND_DESC));

	blendStateDescription.RenderTarget[0].BlendEnable = true;
	blendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
	blendStateDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
	blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
	blendStateDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
	blendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
	blendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
	blendStateDescription.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
	blendStateDescription.AlphaToCoverageEnable = true;
	blendStateDescription.IndependentBlendEnable = false;

	device->CreateBlendState(&blendStateDescription, &defaultBlendState);
}

void initializeGraphics()
{
	D3D11_BUFFER_DESC bufferDescription;
	SZeroMem(&bufferDescription, sizeof(D3D11_BUFFER_DESC));

	bufferDescription.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	bufferDescription.ByteWidth = sizeof(Vertex) * 24;
	bufferDescription.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
	bufferDescription.MiscFlags = 0;
	bufferDescription.StructureByteStride = 0;
	bufferDescription.Usage = D3D11_USAGE_DYNAMIC;

	device->CreateBuffer(&bufferDescription, 0, &vertexBuffer);

	D3D11_MAPPED_SUBRESOURCE mappedSubresource;
	SZeroMem(&mappedSubresource, sizeof(D3D11_MAPPED_SUBRESOURCE));

	deviceContext->Map(vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedSubresource);
	memcpy(mappedSubresource.pData, vertecies, sizeof(vertecies));
	deviceContext->Unmap(vertexBuffer, 0);

	SZeroMem(&bufferDescription, sizeof(D3D11_BUFFER_DESC));

	bufferDescription.BindFlags = D3D11_BIND_INDEX_BUFFER;
	bufferDescription.ByteWidth = sizeof(DWORD) * 36;
	bufferDescription.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
	bufferDescription.MiscFlags = 0;
	bufferDescription.StructureByteStride = 0;
	bufferDescription.Usage = D3D11_USAGE_DYNAMIC;

	device->CreateBuffer(&bufferDescription, 0, &indexBuffer);

	SZeroMem(&mappedSubresource, sizeof(D3D11_MAPPED_SUBRESOURCE));

	deviceContext->Map(indexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedSubresource);
	memcpy(mappedSubresource.pData, indicies, sizeof(indicies));
	deviceContext->Unmap(indexBuffer, 0);

	D3DX11CreateShaderResourceViewFromFile(device, textureFilePath, 0, 0, &texture, 0);
}

void updateCamera()
{
	static float rotationX = 0.0f;
	static float rotationY = 0.0f;
	static float rotationZ = 0.0f;

	rotationX += 0.00005f;
	rotationY += 0.00005f;
	rotationZ -= 0.00005f;

	D3DXMatrixTranslation(&translationMatrix, 0.0f, 0.0f, 0.0f);
	D3DXMatrixRotationX(&rotationXMatrix, rotationX);
	D3DXMatrixRotationY(&rotationYMatrix, rotationY);
	D3DXMatrixRotationZ(&rotationZMatrix, rotationZ);
	D3DXMatrixScaling(&scaleMatrix, 1.0f, 1.0f, 1.0f);

	totalRotationMatrix = rotationXMatrix * rotationYMatrix * rotationZMatrix;

	worldMatrix = totalRotationMatrix * scaleMatrix * translationMatrix;

	D3DXMatrixLookAtLH(&viewMatrix, &VECTOR3(0.0f, 2.5, 1.5f), &VECTOR3(0.0f, 0.0f, 0.0f), &VECTOR3(0.0f, 1.0f, 0.0f));

	D3DXMatrixPerspectiveFovLH(&projectionMatrix, (float)D3DXToRadian(120), (float)screenWidth / (float)screenHeight, 1.0f, 100.0f);

	resultMatrix = worldMatrix * viewMatrix * projectionMatrix;
}

void releaseApplicationComponents()
{
	if (swapChain)
	{
		swapChain->SetFullscreenState(false, 0);

		swapChain->Release();
		swapChain = nullptr;
	}

	if (device)
	{
		device->Release();
		device = nullptr;
	}

	if (deviceContext)
	{
		deviceContext->Release();
		deviceContext = nullptr;
	}

	if (backBuffer)
	{
		backBuffer->Release();
		backBuffer = nullptr;
	}

	if (depthBuffer)
	{
		depthBuffer->Release();
		depthBuffer = nullptr;
	}

	if (vertexShaderBlob)
	{
		vertexShaderBlob->Release();
		vertexShaderBlob = nullptr;
	}

	if (pixelShaderBlob)
	{
		pixelShaderBlob->Release();
		pixelShaderBlob = nullptr;
	}

	if (errorMessageBlob)
	{
		errorMessageBlob->Release();
		errorMessageBlob = nullptr;
	}

	if (vertexShader)
	{
		vertexShader->Release();
		vertexShader = nullptr;
	}

	if (pixelShader)
	{
		pixelShader->Release();
		pixelShader = nullptr;
	}

	if (vertexBuffer)
	{
		vertexBuffer->Release();
		vertexBuffer = nullptr;
	}

	if (indexBuffer)
	{
		indexBuffer->Release();
		indexBuffer = nullptr;
	}

	if (constantBuffer)
	{
		constantBuffer->Release();
		constantBuffer = nullptr;
	}

	if (inputLayout)
	{
		inputLayout->Release();
		inputLayout = nullptr;
	}

	if (backBufferPointer)
	{
		backBufferPointer->Release();
		backBufferPointer = nullptr;
	}

	if (depthBufferPointer)
	{
		depthBufferPointer->Release();
		depthBufferPointer = nullptr;
	}

	if (texture)
	{
		texture->Release();
		texture = nullptr;
	}

	if (defaultRazterizerState)
	{
		defaultRazterizerState->Release();
		defaultRazterizerState = nullptr;
	}

	if (defaultSamplerState)
	{
		defaultSamplerState->Release();
		defaultSamplerState = nullptr;
	}
}

Would be nice if someone could help. Also would love some feedback on my code, what I should think about and how I can improve.

Advertisement

Added the link in the first post, don´t know why it didn´t show up before. Also added some text I thought I had added when I posted. Were really tired when I wrote this.

You have quite a few coding practices that make it very difficult to examine your code, and which may cause problems that are difficult to debug.

However, Very First Step: enable debugging output in your debug build, and see what messages you get in the debug output window. You have a global variable debug = false. Change occurrences in your code where you make a decision regarding the current build mode to:


#ifdef _DEBUG
    function_or_parameter_for_debug_build - ...;
#else
    function_or_parameter_for_release_build - ...;
#endif


Second: Check for runtime errors. Just about every API call (Windows, DirectX, etc.) provides some indication of success or failure. Check ALL error indications and handle them properly. Particularly in your debug build, you should also provide the user with some sort of announcement of the error - console output, debug window output, screen message, etc.

In particular, check the documentation for every API call you make - device->Createxxx, context->xxx, etc., etc. If the documentation states that the return value or a parameter provides error indication, check those indications.

EDIT: For instance,


HRESULT hr;
hr = device->CreateSomething( ... );
if( FAILED( hr ) ) handle-the-error


Third: Your coding style - eliminate all the #define's such as #define vTrue while(true), #define VECTOR4, etc. Such defines make it difficult just to examine your code. In addition, compiling and linking errors can be difficult to diagnose as error messages will refer to preprocessed code.

Etc.

- Enable vsync unless you have a technical reason not to. Do you have such a reason?

- Do NOT call render() in the message procedure. Your app should be controlling the presentation, not the OS. Instead, in your message procedure:


HDC hdr;
PAINTSTRUCT ps;

switch( message )
{
...
    case WM_PAINT:
        if(GetUpdateRect(hWnd, NULL, false))
        {
           hdc = BeginPaint( hWnd, &ps );
           EndPaint( hWnd, &ps );
        }
        return 0;


EDIT2: It's important to process the WM_PAINT command correctly. The message WM_PAINT is sent to the window when all or a portion of the window has been invalidated. The code shown above tells the operating system that your app has received and processed the message. If WM_PAINT isn't processed correctly, the OS will keep sending the WM_PAINT message over and over again, wasting time and resources.

As mentioned, you use coding practices that, in general, are not good - global variables, all code in one file, including headers and libraries that may not be needed, etc. For the purpose of determining your current problem, revising those things now will probably just result in more difficulties. biggrin.png

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

The video has way too low resolution to see exactly what's happening there but... couldn't it just be from backbuffer scaling? I noticed that you're using screen size for backbuffer size, but window client area size is different*. Try making backbuffer size equal to window client area size at all times, see if that fixes the issue.

*Note that AdjustWindowRect calculates window size including the borders from client rectangle, which is the window size without the borders, so it's quite pointless in this case to compare that to screen size or to backbuffer size.

You have quite a few coding practices that make it very difficult to examine your code, and which may cause problems that are difficult to debug.

No, it's not difficult to read the code. And that wall of text isn't really relevant. Clearly this issue is not about API errors or conditional compilation.

Thank you both for your answers.

I haven´t really checked for errors when calling "createdevice" etc. just because I were lazy :D, I know you should so that but simply didn´t because I wanted to make cube quickly. You could say I were a bit excited to get to the cube. But yeah it could help me with problems in the future. Right know I don´t have any updates on the problem, but I think it is as snake5 said, that the sizes on the client-area and backbuffer isn´t the same. I know that you shouldn´t use only one .cpp file, but as mentioned before I just wanted to make a cube, and learn how to do that. The plan is to start build an engine or something this summer. I wanna learn that before I start university :D

About that what snake5 said. I checked like this:


if (screenWidth == clientRectangle.right - clientRectangle.left)
{
  OutputDebugString(L"They are equal");
}

I know that AdjustWindowRect() includes the borders etc of the window, witch means that if my argument in the if-statement is true, the backbuffer and window will not have the same size. And isn´t that weird if i have used AjustWindowRect()?

And the movie is in 1080p, 60fps so I doubt the quiality is bad, maybe the dropbox player doesn´t show full quality. Have you tried download it?

And some other questions:

1. Why is global variables bad? I can understand what you´re saying about #define´s, that it can be harder to know what I acually mean but gloabl variables?

2. What´s the difference between D3DX11_SDK_VERSION and D3D11_SDK_VERSION, except that they are define´s for different number?

3. Do you have any tips for me what I should think about when moving forward?

3. Do you have any tips for me what I should think about when moving forward?

As was already mentioned, use ::AjustWindowRect().
Because you did not use it, your back buffer is too large and is being shrunken to fit the actual client rectangle.

I know that AdjustWindowRect() includes the borders etc of the window, witch means that if my argument in the if-statement is true, the backbuffer and window will not have the same size. And isn´t that weird if i have used AjustWindowRect()?

#1: ::AjustWindowRect() accounts for the borders and menus to make sure you have a client rectangle that is the requested size (by increasing the size of the window).
#2: It doesn’t matter if the window is the same size, it matters if the client rectangle of the window is the same size.
#3: Why would it be weird? It is exactly your problem. Use ::AjustWindowRect() and be done with it.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

I´m already using AdjustWindowRect()


	WNDCLASSEX windowClass;
	SZeroMem(&windowClass, sizeof(WNDCLASSEX));
	
	windowClass.cbClsExtra = 0;
	windowClass.cbSize = sizeof(WNDCLASSEX);
	windowClass.cbWndExtra = 0;
	windowClass.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH);
	windowClass.hCursor = LoadCursor(0, IDC_ARROW);
	windowClass.hIcon = LoadIcon(0, IDI_APPLICATION);
	windowClass.hIconSm = 0;
	windowClass.hInstance = hInstance;
	windowClass.lpfnWndProc = handleMessage;
	windowClass.lpszClassName = windowClassName;
	windowClass.lpszMenuName = 0;
	windowClass.style = CS_HREDRAW | CS_VREDRAW;
 
	RegisterClassEx(&windowClass);
 
	DWORD windowStyle = WS_SYSMENU | WS_MINIMIZEBOX | WS_OVERLAPPED;
 
	RECT clientRectangle = { 0, 0, screenWidth, screenHeight };
	AdjustWindowRect(&clientRectangle, windowStyle, false);

That's why I found i strange


About that what snake5 said. I checked like this:

if (screenWidth == clientRectangle.right - clientRectangle.left)
{
OutputDebugString(L"They are equal");
}

I know that AdjustWindowRect() includes the borders etc of the window, witch means that if my argument in the if-statement is true, the backbuffer and window will not have the same size. And isn´t that weird if i have used AjustWindowRect()?

Your logic is faulty. What you call "clientRectangle" is not the client rectangle after you call AdjustWindowRect. You initialize clientRect (correctly) to { 0, 0, screenWidth, screenHeight }, but then you call AdjustWindowRect(&clientRectangle ... ) which (read the docs) changes clientRectangle to the required window size - at that point, it's no longer the size of the client rectangle.

If you really want to compare the client rect to the backbuffer, and know that's it valid when the code is executed:


RECT rect;
GetClientRect( hWnd, &rect );
ID3D11Texture2D* pTexture;
hr = g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&pTexture);
if (FAILED(hr))
{
     OutputDebugString("Failed to grab backbuffer\n");
}
D3D11_TEXTURE2D_DESC td = {};
pTexture->GetDesc( &td );
pTexture->Release();

if( (rect.right - rect.left) == td.Width )
{
   // the backbuffer is "correct" - i.e., the backbuffer is the same size as the client area
}

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Sorry, call me retard if you want, but I can´t see how my locigc is wrong. Yes, my naming should be better for the rectangle. Maybe call it windowRectangle instead of clientRectangle, because that is what it is.

But when I checked with my if -statement, i checked if the argument I passed in as the width were equal to the screenWidth. If it was true and they were equal, then the backbuffer would NOT be the same as the clientarea. I never wanted them to be equal because that would mean that the clientarea would become smaller than intended. Understand?

I have also noticed that if I have WS_OVERLAPPEDWINDOW as windowstyle and lower the resolution to 720p, the problem disappears. I can not see any reasons for this. Especially with the windowstyle.

I might be mistaken but Windows doesn't allow window to be higher dimensions than your resolution.

If you try to use 1080p in windowed mode then window becomes bigger than 1080p (your resolution) and Windows forces it into smaller size causing size mismatch.

This topic is closed to new replies.

Advertisement