The only problem is that the pixel shader always receive (0.0f, 0.0f) as texture coordinates. the vertex shader gets the right one.
I have no idea of what can cause that.
And another problem with my code is that the far-plane is too close, around 1.5f and I can't change it, I tried changing all the values that have something to do with the z buffer or the view matrix but still.
The partial code is here:
Obs: CStaticModel is not the problem, it was working before I start using DirectX 11
#pragma once
#include <Windows.h>
#include <d3d11.h>
#include <d3dx11.h>
#include <d3dx10.h>
#include "StaticModel.h"
#define DIRECTX_WINDOW_CLASSNAME "Such DirectX class Name"
#define DIRECTX_WINDOW_CAPTION "Such DirectX caption"
struct VERTEX
{
FLOAT X, Y, Z; // position
FLOAT U, V;
};
struct CONSTANT_BUFFER
{
D3DXMATRIX finalMatrix;
};
class CSDirectX
{
protected:
//WIN32 Initialization and management
HWND m_hWnd;
HINSTANCE m_hInstance;
UINT m_screenWidth;
UINT m_screenHeight;
void createWindow(const char* caption, HINSTANCE hInstance);
bool registerClass(const char* className)
{
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(WNDCLASSEX));
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = staticProc;
wc.hInstance = m_hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszClassName = className;
return RegisterClassEx(&wc) != 0;
}
void showWindow(bool show)
{
if(show)
ShowWindow(m_hWnd, SW_SHOW);
else
ShowWindow(m_hWnd, SW_HIDE);
}
static LRESULT CALLBACK staticProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
} break;
}
return DefWindowProc (hWnd, message, wParam, lParam);
return 0;
}
//DirectX initialization and management
ID3D11Device* m_device;
IDXGISwapChain* m_swapChain;
ID3D11DeviceContext* m_deviceContext;
ID3D11RenderTargetView* m_backBuffer;
ID3D11DepthStencilView* m_zBuffer;
D3DXCOLOR m_backgroundColor;
ID3D11VertexShader* m_vertexShader;
ID3D11PixelShader* m_pixelShader;
ID3D11Buffer* m_vertexBuffer;
ID3D11InputLayout* m_inputLayout;
ID3D11Buffer* m_constantBuffer;
ID3D11ShaderResourceView* textureTest;
CStaticModel teste;
D3DXMATRIX m_cameraPosition;
D3DXMATRIX m_projectionMatrix;
void init3D();
void clean3D();
void initPipeline();
void initGraphics();
void setCameraPosition(D3DXVECTOR3* position, D3DXVECTOR3* lookAt, D3DXVECTOR3* upDirection = &D3DXVECTOR3(0.0f, 1.0f, 0.0f));
public:
void init(HINSTANCE hInstance)
{
createWindow(DIRECTX_WINDOW_CAPTION, hInstance);
init3D();
}
void setBackgroundColor(D3DXCOLOR color){m_backgroundColor = color;}
void setFullscreen(BOOL fullscreen=true){m_swapChain->SetFullscreenState(fullscreen, NULL);}
void renderLoop()
{
m_deviceContext->ClearRenderTargetView(m_backBuffer, m_backgroundColor);
m_deviceContext->ClearDepthStencilView(m_zBuffer, D3D11_CLEAR_DEPTH, 1.0f, 0);
D3DXMATRIX rotation;
D3DXMATRIX translation;
static float a = 0.0f;a += 0.0001f;
D3DXMatrixRotationY(&rotation, a);
D3DXMATRIX final = rotation*m_cameraPosition*m_projectionMatrix*translation;
UINT stride = sizeof(VERTEX);
UINT offset = 0;
m_deviceContext->IASetVertexBuffers(0, 1, &m_vertexBuffer, &stride, &offset);
// select which primtive type we are using
m_deviceContext->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
// draw the vertex buffer to the back buffer
D3DXMatrixScaling(&translation, 0.5f, 0.5f, 0.5f);
final = rotation*m_cameraPosition*m_projectionMatrix*translation;
m_deviceContext->UpdateSubresource(m_constantBuffer, 0, 0, &final, 0, 0);
m_deviceContext->PSSetShaderResources(0, 1, &textureTest);
teste.draw(this);
m_swapChain->Present(0, 0);
}
void createVertexBuffer(ID3D11Buffer** pBuffer, size_t size);
void createIndexBuffer(ID3D11Buffer** pBuffer, size_t size);
void createConstantBuffer(ID3D11Buffer** pBuffer, size_t size);
ID3D11DeviceContext* context()
{
return m_deviceContext;
}
CSDirectX(void);
~CSDirectX(void);
};
#include "SDirectX.h"
#pragma comment (lib, "d3d11.lib")
#pragma comment (lib, "d3dx11.lib")
#pragma comment (lib, "d3dx10.lib")
CSDirectX::CSDirectX(void)
{
m_hWnd = 0;
m_hInstance = 0;
m_screenWidth = 800;
m_screenHeight = 600;
m_swapChain = 0;
m_device = 0;
m_deviceContext = 0;
m_backBuffer = 0;
m_vertexShader = 0;
m_pixelShader = 0;
m_constantBuffer = 0;
m_zBuffer = 0;
m_backgroundColor = D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f);
}
CSDirectX::~CSDirectX(void)
{
textureTest->Release();
clean3D();
}
void CSDirectX::init3D()
{
DXGI_SWAP_CHAIN_DESC scd;
// clear out the struct for use
ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));
// fill the swap chain description struct
scd.BufferCount = 1; // one back buffer
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // use 32-bit color
scd.BufferDesc.Width = m_screenWidth;
scd.BufferDesc.Height = m_screenHeight;
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // how swap chain is to be used
scd.OutputWindow = m_hWnd; // the window to be used
scd.SampleDesc.Count = 4; // how many multisamples
scd.Windowed = TRUE; // windowed/full-screen mode
scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
// create a device, device context and swap chain using the information in the scd struct
D3D11CreateDeviceAndSwapChain(NULL,
D3D_DRIVER_TYPE_HARDWARE,
NULL,
NULL,
NULL,
NULL,
D3D11_SDK_VERSION,
&scd,
&m_swapChain,
&m_device,
NULL,
&m_deviceContext);
ID3D11Texture2D *pBackBuffer;
m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
// use the back buffer address to create the render target
m_device->CreateRenderTargetView(pBackBuffer, NULL, &m_backBuffer);
pBackBuffer->Release();
D3D11_TEXTURE2D_DESC texd;
ZeroMemory(&texd, sizeof(texd));
texd.Width = m_screenWidth;
texd.Height = m_screenHeight;
texd.ArraySize = 1;
texd.MipLevels = 1;
texd.SampleDesc.Count = 4;
texd.Format = DXGI_FORMAT_D32_FLOAT;
texd.BindFlags = D3D11_BIND_DEPTH_STENCIL;
ID3D11Texture2D* depthBuffer;
m_device->CreateTexture2D(&texd, NULL, &depthBuffer);
D3D11_DEPTH_STENCIL_VIEW_DESC dsvd;
ZeroMemory(&dsvd, sizeof(dsvd));
dsvd.Format = DXGI_FORMAT_D32_FLOAT;
dsvd.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
m_device->CreateDepthStencilView(depthBuffer, &dsvd, &m_zBuffer);
depthBuffer->Release();
m_deviceContext->OMSetRenderTargets(1, &m_backBuffer, m_zBuffer);
D3D11_VIEWPORT viewport;
ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = (float)m_screenWidth;
viewport.Height = (float)m_screenHeight;
viewport.MinDepth = 0.0f; // the closest an object can be on the depth buffer is 0.0
viewport.MaxDepth = 1.0f; // the farthest an object can be on the depth buffer is 1.0
m_deviceContext->RSSetViewports(1, &viewport);
teste.generateCube(0.5f, 0);
teste.loadBuffers(this);
initPipeline();
initGraphics();
}
void CSDirectX::clean3D()
{
m_swapChain->SetFullscreenState(FALSE, NULL);
if(m_swapChain)
m_swapChain->Release();
if(m_device)
m_device->Release();
if(m_deviceContext)
m_deviceContext->Release();
if(m_backBuffer)
m_backBuffer->Release();
if(m_vertexShader)
m_vertexShader->Release();
if(m_pixelShader)
m_pixelShader->Release();
if(m_constantBuffer)
m_constantBuffer->Release();
if(m_zBuffer)
m_zBuffer->Release();
m_swapChain = 0;
m_device = 0;
m_deviceContext = 0;
m_backBuffer = 0;
m_zBuffer = 0;
m_vertexShader = 0;
m_pixelShader = 0;
m_constantBuffer = 0;
}
void CSDirectX::initPipeline()
{
ID3D10Blob *VS, *PS;
D3DX11CompileFromFile("shaders.hlsl", 0, 0, "VShader", "vs_5_0", 0, 0, 0, &VS, 0, 0);
D3DX11CompileFromFile("shaders.hlsl", 0, 0, "PShader", "ps_5_0", 0, 0, 0, &PS, 0, 0);
m_device->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &m_vertexShader);
m_device->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &m_pixelShader);
m_deviceContext->VSSetShader(m_vertexShader, 0, 0);
m_deviceContext->PSSetShader(m_pixelShader, 0, 0);
createConstantBuffer(&m_constantBuffer, 64);//Multiple of 16
m_deviceContext->VSSetConstantBuffers(0, 1, &m_constantBuffer);
// create the input layout object
D3D11_INPUT_ELEMENT_DESC ied[] =
{
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
//{"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
};
m_device->CreateInputLayout(ied, 2, VS->GetBufferPointer(), VS->GetBufferSize(), &m_inputLayout);
m_deviceContext->IASetInputLayout(m_inputLayout);
}
void CSDirectX::initGraphics()
{
createVertexBuffer(&m_vertexBuffer, sizeof(VERTEX)*3);
VERTEX OurVertices[] =
{
{0.0f, 0.5f, 0.0f, D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f)},
{0.45f, -0.5, 0.0f, D3DXCOLOR(0.0f, 1.0f, 0.0f, 1.0f)},
{-0.45f, -0.5f, 0.0f, D3DXCOLOR(0.0f, 0.0f, 1.0f, 1.0f)}
};
D3D11_MAPPED_SUBRESOURCE ms;
m_deviceContext->Map(m_vertexBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &ms); // map the buffer
memcpy(ms.pData, OurVertices, sizeof(OurVertices)); // copy the data
m_deviceContext->Unmap(m_vertexBuffer, NULL);
D3DXMatrixPerspectiveFovLH(&m_projectionMatrix,
D3DXToRadian(45), // the horizontal field of view
(FLOAT)m_screenWidth / (FLOAT)m_screenHeight, // aspect ratio
0.1f, // the near view-plane
100.0f); // the far view-plane
setCameraPosition(&D3DXVECTOR3(0.0f, 1.0f, 1.5f), &D3DXVECTOR3(0.0f, 0.0f, 0.0f));
D3DX11CreateShaderResourceViewFromFile(m_device, // the Direct3D device
"Wood1.png", // load Wood.png in the local folder
NULL, // no additional information
NULL, // no multithreading
&textureTest, // address of the shader-resource-view
NULL); // no multithreading
}
void CSDirectX::createVertexBuffer(ID3D11Buffer** pBuffer, size_t size)
{
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DYNAMIC; // write access access by CPU and GPU
bd.ByteWidth = size; // size is the VERTEX struct * 3
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; // use as a vertex buffer
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; // allow CPU to write in buffer
m_device->CreateBuffer(&bd, NULL, pBuffer); // create the buffer
}
void CSDirectX::createIndexBuffer(ID3D11Buffer** pBuffer, size_t size)
{
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DYNAMIC;
bd.ByteWidth = size;
bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
m_device->CreateBuffer(&bd, NULL, pBuffer);
}
void CSDirectX::createConstantBuffer(ID3D11Buffer** pBuffer, size_t size)
{
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = size;
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
m_device->CreateBuffer(&bd, NULL, pBuffer);
}
void CSDirectX::setCameraPosition(D3DXVECTOR3* position, D3DXVECTOR3* lookAt, D3DXVECTOR3* upDirection)
{
D3DXMatrixLookAtLH(&m_cameraPosition,
position,
lookAt,
upDirection);
}
void CSDirectX::createWindow(const char* caption, HINSTANCE hInstance)
{
m_hInstance = hInstance;
registerClass(DIRECTX_WINDOW_CLASSNAME);
m_hWnd = CreateWindow(DIRECTX_WINDOW_CLASSNAME, caption, WS_OVERLAPPEDWINDOW|WS_VISIBLE, 300, 300, m_screenWidth, m_screenHeight, NULL, NULL, hInstance, NULL);
}