I am trying to texture a quad, with a character, that is within the glyph texture (obtained with D3DXFont::GetGlyphData).
Most of the characters are drawn correctly.
However characters such as: 'F', and 'A' are being drawn upside down.
None of the glyphs when saved to file seem to be upside down.
#include <Windows.h>
#include <d3d9.h>
#include <d3dx9.h>
// global declarations
LPDIRECT3D9 d3d; // the pointer to our Direct3D interface
LPDIRECT3DDEVICE9 d3ddev; // the pointer to the device class
ID3DXSprite* pSprite;
ID3DXFont* pFont;
void drawCharacter(const char c, int screenX, int screenY, D3DCOLOR color)
{
struct CUSTOMVERTEX
{
float x, y, z, rhw, tu, tv;
};
WORD glyphIndex;
IDirect3DTexture9* texture;
RECT rect;
POINT point;
D3DSURFACE_DESC desc;
if(GetGlyphIndices(pFont->GetDC(), &c, 1, &glyphIndex, GGI_MARK_NONEXISTING_GLYPHS) == GDI_ERROR)
return;
if(pFont->GetGlyphData(glyphIndex, &texture, &rect, &point) != S_OK)
return;
if(texture->GetLevelDesc(0, &desc) != D3D_OK)
return;
const float glyphWidth = static_cast<float>(desc.Width);
const float glyphHeight = static_cast<float>(desc.Height);
const float charWidth = static_cast<float>(rect.right - rect.left);
const float charHeight = static_cast<float>(rect.bottom - rect.top);
const float startX = static_cast<float>(screenY);
const float startY = static_cast<float>(screenY);
float u = (static_cast<float>(rect.left) + 0.5f) / glyphWidth;
float v = (static_cast<float>(rect.top) + 0.5f) / glyphHeight;
float u2 = u + (charWidth / glyphWidth);
float v2 = v + (charHeight / glyphHeight);
const CUSTOMVERTEX char_quad[4] =
{
// Bottom left vertex
{
startX, startY, 0.0f, 1.0f,
u, v2
},
// Bottom right vertex
{
startX + charWidth, startY, 0.0f, 1.0f,
u2, v2
},
// Top right vertex
{
startX + charWidth, startY + charHeight, 0.0f, 1.0f,
u2, v
},
// Top left vertex
{
startX, startY + charHeight, 0.0f, 1.0f,
u, v
}
};
// D3DXSaveTextureToFileA("glyph.dds", D3DXIFF_DDS, texture, 0);
d3ddev->SetTexture(0, texture);
d3ddev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, char_quad, sizeof(CUSTOMVERTEX));
}
// this is the function used to render a single frame
void render_frame()
{
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
d3ddev->BeginScene();
pSprite->Begin(D3DXSPRITE_ALPHABLEND);
// select which vertex format we are using
d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
drawCharacter('F', 100, 100, D3DCOLOR_XRGB(0, 255, 0));
pSprite->End();
d3ddev->EndScene();
d3ddev->Present(NULL, NULL, NULL, NULL);
}
// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
HWND hWnd;
WNDCLASSEX wc = {};
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = DefWindowProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszClassName = "WindowClass";
if(!RegisterClassEx(&wc))
{
return 0;
}
hWnd = CreateWindowEx(NULL,
"WindowClass",
"Our Direct3D Program",
WS_OVERLAPPEDWINDOW,
0, 0,
800, 600,
NULL,
NULL,
hInstance,
NULL);
if(!hWnd)
{
UnregisterClass(wc.lpszClassName, hInstance);
return 0;
}
ShowWindow(hWnd, nCmdShow);
// set up and initialize Direct3D
d3d = Direct3DCreate9(D3D_SDK_VERSION);
if(!d3d)
{
UnregisterClass(wc.lpszClassName, hInstance);
return 0;
}
D3DPRESENT_PARAMETERS d3dpp = {};
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hWnd;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.BackBufferWidth = 800;
d3dpp.BackBufferHeight = 600;
// create a device class using this information and the info from the d3dpp stuct
if(d3d->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&d3ddev) != D3D_OK)
{
d3d->Release();
UnregisterClass(wc.lpszClassName, hInstance);
return 0;
}
if(D3DXCreateSprite(d3ddev, &pSprite) != D3D_OK)
{
d3d->Release();
d3ddev->Release();
UnregisterClass(wc.lpszClassName, hInstance);
return 0;
}
if(D3D_OK != D3DXCreateFont(d3ddev,
14,
0,
FW_BOLD,
1,
FALSE,
DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS,
ANTIALIASED_QUALITY,
DEFAULT_PITCH | FF_DONTCARE,
"Georgia",
&pFont))
{
d3d->Release();
d3ddev->Release();
pSprite->Release();
UnregisterClass(wc.lpszClassName, hInstance);
return 0;
}
MSG msg;
while(TRUE)
{
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(msg.message == WM_QUIT)
break;
render_frame();
}
d3d->Release();
d3ddev->Release();
pSprite->Release();
pFont->Release();
UnregisterClass(wc.lpszClassName, hInstance);
return msg.wParam;
}
Edit: Updated to include a full example of my problem.
It's been a while since I did any DirextX stuff, but I think it may be to do with the quad texture coordinate ordering. I ran your code and tried this:
const CUSTOMVERTEX char_quad[4] =
{
// Top left vertex
{
startX, startY + charHeight, 0.0f, 1.0f,
u, v2
},
// Top right vertex
{
startX + charWidth, startY + charHeight, 0.0f, 1.0f,
u2, v2
},
// Bottom right vertex
{
startX + charWidth, startY, 0.0f, 1.0f,
u2, v
},
// Bottom left vertex
{
startX, startY, 0.0f, 1.0f,
u, v
}
};
which output the characters ABCDEF all Ok.
I can't exactly remember how to specify the custom vertex, so I guess I was probably lucky with the above hack :)
Had another look at this and I think the coords should be ordered to render the TRIANGLEFAN in Clockwise Winding Order (so it doesn't get backface culled). Reordering the coords makes more sense I think:
// TRIANGLEFAN coords:
// v1-----v2 clockwise winding order
// | / |
// | / |
// v0-----v3
//
const CUSTOMVERTEX char_quad[4] =
{
// Bottom left vertex
{
startX, startY, 0.0f, 1.0f,
u, v
},
// Top left vertex
{
startX, startY + charHeight, 0.0f, 1.0f,
u, v2
},
// Top right vertex
{
startX + charWidth, startY + charHeight, 0.0f, 1.0f,
u2, v2
},
// Bottom right vertex
{
startX + charWidth, startY, 0.0f, 1.0f,
u2, v
},
};
Related
I wanted to draw a 3D cube, but it doesn't display correctly. That is, the Z buffer (depth buffer) does not work.
The initialization of the depth buffer occurs in the InitDepthBuffer method, which I copied from the manual from Microsoft. The InitDepthBuffer method is called in the InitD3D method below.
Why "cube" is not displayed correctly and how to fix the program?
My Game.cpp
// include the basic windows header files and the Direct3D header files
#include <windows.h>
#include <windowsx.h>
#include <d3d11.h>
#include <d3dx11.h>
#include <d3dx10.h>
#include <xnamath.h>
// include the Direct3D Library file
#pragma comment (lib, "d3d11.lib")
#pragma comment (lib, "d3dx11.lib")
#pragma comment (lib, "d3dx10.lib")
// define the screen resolution
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
// global declarations
IDXGISwapChain* swapchain; // the pointer to the swap chain interface
ID3D11Device* dev; // the pointer to our Direct3D device interface
ID3D11DeviceContext* devcon; // the pointer to our Direct3D device context
ID3D11RenderTargetView* backbuffer; // the pointer to our back buffer
ID3D11InputLayout* pLayout; // the pointer to the input layout
ID3D11VertexShader* pVS; // the pointer to the vertex shader
ID3D11PixelShader* pPS; // the pointer to the pixel shader
ID3D11Buffer* pVBuffer; // the pointer to the vertex buffer
ID3D11Buffer* pIBuffer;
ID3D11Buffer* wvpConstBuffer;
ID3D11ShaderResourceView* pTexture; // the texture
ID3D11SamplerState* pSamplerState;
ID3D11RasterizerState* pRasterState;
ID3D11Texture2D* pDepthStencil = NULL;
ID3D11DepthStencilState* pDSState;
ID3D11DepthStencilView* pDSV;
// a struct to define a single vertex
struct VERTEX { FLOAT X, Y, Z, texX, texY; };
struct ConstantBuffer
{
XMMATRIX mWorld;
XMMATRIX mView;
XMMATRIX mProjection;
};
XMMATRIX g_World;
XMMATRIX g_View;
XMMATRIX g_Projection;
// function prototypes
void InitD3D(HWND hWnd); // sets up and initializes Direct3D
void RenderFrame(void); // renders a single frame
void CleanD3D(void); // closes Direct3D and releases memory
void InitGraphics(void); // creates the shape to render
void InitPipeline(void); // loads and prepares the shaders
// the WindowProc function prototype
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
HWND hWnd;
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(WNDCLASSEX));
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszClassName = L"WindowClass";
RegisterClassEx(&wc);
RECT wr = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT };
AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);
hWnd = CreateWindowEx(NULL,
L"WindowClass",
L"My Game",
WS_OVERLAPPEDWINDOW,
300,
300,
wr.right - wr.left,
wr.bottom - wr.top,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hWnd, nCmdShow);
// set up and initialize Direct3D
InitD3D(hWnd);
// enter the main loop:
MSG msg;
while (TRUE)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
if (msg.message == WM_QUIT)
break;
}
RenderFrame();
}
// clean up DirectX and COM
CleanD3D();
return msg.wParam;
}
// this is the main message handler for the program
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
} break;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
void InitDepthBuffer()
{
D3D11_TEXTURE2D_DESC descDepth;
descDepth.Width = SCREEN_WIDTH;
descDepth.Height = SCREEN_HEIGHT;
descDepth.MipLevels = 1;
descDepth.ArraySize = 1;
descDepth.Format = DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
descDepth.SampleDesc.Count = 1;
descDepth.SampleDesc.Quality = 0;
descDepth.Usage = D3D11_USAGE_DEFAULT;
descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
descDepth.CPUAccessFlags = 0;
descDepth.MiscFlags = 0;
dev->CreateTexture2D(&descDepth, NULL, &pDepthStencil);
D3D11_DEPTH_STENCIL_DESC dsDesc;
// Depth test parameters
dsDesc.DepthEnable = true;
dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
dsDesc.DepthFunc = D3D11_COMPARISON_LESS;
// Stencil test parameters
dsDesc.StencilEnable = true;
dsDesc.StencilReadMask = 0xFF;
dsDesc.StencilWriteMask = 0xFF;
// Stencil operations if pixel is front-facing
dsDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
dsDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
// Stencil operations if pixel is back-facing
dsDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
dsDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
dev->CreateDepthStencilState(&dsDesc, &pDSState);
D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;
descDSV.Format = DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
descDSV.Texture2D.MipSlice = 0;
dev->CreateDepthStencilView(pDepthStencil, // Depth stencil texture
&descDSV, // Depth stencil desc
&pDSV); // [out] Depth stencil view
}
// this function initializes and prepares Direct3D for use
void InitD3D(HWND hWnd)
{
// create a struct to hold information about the swap chain
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 = SCREEN_WIDTH; // set the back buffer width
scd.BufferDesc.Height = SCREEN_HEIGHT; // set the back buffer height
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // how swap chain is to be used
scd.OutputWindow = 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; // allow full-screen switching
// 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,
&swapchain,
&dev,
NULL,
&devcon);
// get the address of the back buffer
ID3D11Texture2D* pBackBuffer;
swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
// use the back buffer address to create the render target
dev->CreateRenderTargetView(pBackBuffer, NULL, &backbuffer);
pBackBuffer->Release();
InitDepthBuffer();
// set the render target as the back buffer
devcon->OMSetRenderTargets(1, &backbuffer, pDSV);
devcon->OMSetDepthStencilState(pDSState, 1);
// Set the viewport
D3D11_VIEWPORT viewport;
ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = SCREEN_WIDTH;
viewport.Height = SCREEN_HEIGHT;
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
devcon->RSSetViewports(1, &viewport);
InitPipeline();
InitGraphics();
}
// this is the function used to render a single frame
void RenderFrame(void)
{
// update WVP matrices
ConstantBuffer cb;
cb.mWorld = XMMatrixTranspose(g_World);
cb.mView = XMMatrixTranspose(g_View);
cb.mProjection = XMMatrixTranspose(g_Projection);
devcon->UpdateSubresource(wvpConstBuffer, 0, NULL, &cb, 0, 0);
// clear the back buffer to a deep blue and the depth buffer
devcon->ClearRenderTargetView(backbuffer, D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f));
devcon->ClearDepthStencilView(pDSV, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
// select which vertex buffer to display
UINT stride = sizeof(VERTEX);
UINT offset = 0;
devcon->IASetVertexBuffers(0, 1, &pVBuffer, &stride, &offset);
devcon->IASetIndexBuffer(pIBuffer, DXGI_FORMAT_R32_UINT, 0);
devcon->VSSetConstantBuffers(0, 1, &wvpConstBuffer);
// select which primtive type we are using
devcon->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
// draw the vertex buffer to the back buffer
devcon->DrawIndexed(24, 0, 0);
// switch the back buffer and the front buffer
swapchain->Present(0, 0);
g_World *= XMMatrixRotationY(XM_PI / 12);
Sleep(100);
}
// this is the function that cleans up Direct3D and COM
void CleanD3D(void)
{
swapchain->SetFullscreenState(FALSE, NULL); // switch to windowed mode
// close and release all existing COM objects
pLayout->Release();
pVS->Release();
pPS->Release();
pVBuffer->Release();
swapchain->Release();
backbuffer->Release();
dev->Release();
devcon->Release();
}
void InitTextures()
{
D3DX11CreateShaderResourceViewFromFile(dev, L"texture.png", NULL, NULL, &pTexture, NULL);
D3D11_SAMPLER_DESC sampDesc;
ZeroMemory(&sampDesc, sizeof(D3D11_SAMPLER_DESC));
sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
sampDesc.MinLOD = 0;
sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
dev->CreateSamplerState(&sampDesc, &pSamplerState);
}
// this is the function that creates the shape to render
void InitGraphics()
{
// create a triangle using the VERTEX struct
VERTEX OurVertices[] =
{ // CUBE
{-0.5f, 0.5f, 0.5f, 0.0f, 0.0f}, // Front
{0.5f, 0.5f, 0.5f, 1.0f, 0.0f},
{0.5f, -0.5f, 0.5f, 1.0f, 1.0f},
{-0.5f, -0.5f, 0.5f, 0.0f, 1.0f},
{-0.5f, 0.5f, -0.5f, 1.0f, 0.0f}, // Back
{0.5f, 0.5f, -0.5f, 0.0f, 0.0f},
{0.5f, -0.5f, -0.5f, 0.0f, 1.0f},
{-0.5f, -0.5f, -0.5f, 1.0f, 1.0f},
};
// create the vertex buffer
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DYNAMIC; // write access access by CPU and GPU
bd.ByteWidth = sizeof(OurVertices); // 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
dev->CreateBuffer(&bd, NULL, &pVBuffer); // create the buffer
// copy the vertices into the buffer
D3D11_MAPPED_SUBRESOURCE ms;
devcon->Map(pVBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &ms); // map the buffer
memcpy(ms.pData, OurVertices, sizeof(OurVertices)); // copy the data
devcon->Unmap(pVBuffer, NULL); // unmap the buffer
unsigned int indices[] =
{
0, 1, 2, // front
0, 2, 3,
4, 0, 3, // left
4, 3, 7,
//4, 5, 6, // back
//4, 6, 7,
6, 5, 1, // right
6, 1, 2,
};
// indices
D3D11_BUFFER_DESC bdIndices;
bdIndices.Usage = D3D11_USAGE_DEFAULT;
bdIndices.ByteWidth = sizeof(indices);
bdIndices.BindFlags = D3D11_BIND_INDEX_BUFFER;
bdIndices.CPUAccessFlags = 0;
bdIndices.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA InitData;
InitData.pSysMem = indices;
InitData.SysMemPitch = 0;
InitData.SysMemSlicePitch = 0;
dev->CreateBuffer(&bdIndices, &InitData, &pIBuffer);
D3D11_BUFFER_DESC bdWVP;
ZeroMemory(&bdWVP, sizeof(D3D11_BUFFER_DESC));
bdWVP.Usage = D3D11_USAGE_DEFAULT;
bdWVP.ByteWidth = sizeof(ConstantBuffer);
bdWVP.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bdWVP.CPUAccessFlags = 0;
dev->CreateBuffer(&bdWVP, NULL, &wvpConstBuffer);
g_World = XMMatrixIdentity();
XMVECTOR Eye = XMVectorSet(0.0f, 1.0f, -3.0f, 0.0f);
XMVECTOR At = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
XMVECTOR Up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
g_View = XMMatrixLookAtLH(Eye, At, Up);
g_Projection = XMMatrixPerspectiveFovLH(XM_PIDIV2, SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT, 0.01f, 100.0f);
}
void InitRasterizer()
{
D3D11_RASTERIZER_DESC raster_desc;
raster_desc.FillMode = D3D11_FILL_SOLID;
raster_desc.CullMode = D3D11_CULL_NONE;
raster_desc.FrontCounterClockwise = false;
raster_desc.DepthBias = 0;
raster_desc.DepthBiasClamp = 0.0f;
raster_desc.SlopeScaledDepthBias = 0.0f;
raster_desc.DepthClipEnable = true;
raster_desc.ScissorEnable = false;
raster_desc.MultisampleEnable = false;
raster_desc.AntialiasedLineEnable = false;
dev->CreateRasterizerState(&raster_desc, &pRasterState);
}
// this function loads and prepares the shaders
void InitPipeline()
{
InitRasterizer();
InitTextures();
// load and compile the two shaders
ID3D10Blob* VS, * PS;
D3DX11CompileFromFile(L"shaders.shader", 0, 0, "VShader", "vs_4_0", 0, 0, 0, &VS, 0, 0);
D3DX11CompileFromFile(L"shaders.shader", 0, 0, "PShader", "ps_4_0", 0, 0, 0, &PS, 0, 0);
// encapsulate both shaders into shader objects
dev->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &pVS);
dev->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &pPS);
// set the shader objects
devcon->VSSetShader(pVS, 0, 0);
devcon->PSSetShader(pPS, 0, 0);
// set the texture
devcon->PSSetShaderResources(0, 1, &pTexture);
devcon->PSSetSamplers(0, 1, &pSamplerState);
// off cull mode
devcon->RSSetState(pRasterState);
// 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},
};
dev->CreateInputLayout(ied, 2, VS->GetBufferPointer(), VS->GetBufferSize(), &pLayout);
devcon->IASetInputLayout(pLayout);
}
shaders.shader
cbuffer ConstantBuffer : register(b0)
{
matrix World;
matrix View;
matrix Projection;
}
Texture2D ObjTexture;
SamplerState ObjSamplerState;
struct VS_OUTPUT
{
float4 Pos : SV_POSITION;
float2 TexCoord : TEXCOORD;
};
VS_OUTPUT VShader(float4 Pos : POSITION, float4 inTexCoord : TEXCOORD)
{
VS_OUTPUT output = (VS_OUTPUT)0;
output.Pos = mul(Pos, World);
output.Pos = mul(output.Pos, View);
output.Pos = mul(output.Pos, Projection);
output.TexCoord = inTexCoord;
return output;
}
float4 PShader(VS_OUTPUT input) : SV_Target
{
return ObjTexture.Sample(ObjSamplerState, input.TexCoord);
}
the "cube"
I've looked all over but couldn't solve the problem.
With a fresh eye today i've noticed that besides things i've mentioned earlier render target view and depth stencil view are using different multisampling settings: render target use 4 samples while depth stencil only 1. In order for them to work together their dimensions and multisampling settings must be exactly the same.
I'm using the SpriteFont/SpriteBatch classes to render text onto my game because quite frankly, i am tired of using Direct2D and DirectWrite... But everytime I draw text using SpriteFont, I get the text written on the screen, but it is written on a black background... The black background blocks the entire scene of my game.. is there any way to remove the black background and only keep the text?
Down below is my implementation of SpriteFont..
void RenderText(int FPS)
{
std::unique_ptr<DirectX::SpriteFont> Sprite_Font(new DirectX::SpriteFont(device, L"myfile.spritefont"));
std::unique_ptr<DirectX::SpriteBatch> Sprite_Batch(new DirectX::SpriteBatch(DevContext));
Sprite_Batch->Begin();
Sprite_Font->DrawString(Sprite_Batch.get(), L"FPS: ", DirectX::XMFLOAT2(200,200));
Sprite_Batch->End();
}
It seems to me that the black background is drawn because of the values that I specified in the function ClearRenderTargetView().
float BackgroundColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
DevContext->ClearRenderTargetView(RenderTarget, BackgroundColor); //This is where the black background gets drawn over my entire scene
Everytime i change BackgroundColor[4] to different values, the background color changes as well, respectably. How can I remove the black background from my game and only include the text?
Here is my entire code.
#include <Windows.h>
#include <SpriteFont.h>
#include <SpriteBatch.h>
#include <d3dcompiler.h>
#include <SimpleMath.h>
#pragma comment (lib, "dinput8.lib")
#pragma comment (lib, "D3D11.lib")
#pragma comment (lib, "d3dcompiler.lib")
LRESULT CALLBACK WindowProcedure(HWND, unsigned int, WPARAM, LPARAM);
void Create_Window(HINSTANCE&);
void Initialize_Direct3D11(HINSTANCE);
void Initialize_Rendering_Pipeline();
void Initialize_Sprites();
void Render_Frame();
void Render_Text();
void Create_Vertex_Buffer_for_triangle();
HWND MainWindow;
IDXGISwapChain * SwapChain;
ID3D11Device * device;
ID3D11DeviceContext * DevContext;
ID3D11RenderTargetView * RenderTarget;
ID3D11Buffer * VertexBuffer;
ID3D10Blob * VertexShader;
ID3D10Blob * PixelShader;
ID3D11VertexShader * VS;
ID3D11PixelShader * PS;
ID3D11InputLayout * inputLayout;
std::unique_ptr<DirectX::SpriteFont> Sprite_Font;
std::unique_ptr<DirectX::SpriteBatch> Sprite_Batch;
DirectX::SimpleMath::Vector2 m_fontPos;
const wchar_t* output = L"Hello World";
struct Vertex_Buffer
{
float Positions[3];
Vertex_Buffer(float x, float y, float z)
{
Positions[0] = x;
Positions[1] = y;
Positions[2] = z;
};
};
int WINAPI WinMain(HINSTANCE CurrentInstance, HINSTANCE PrevInstance, LPSTR ignore, int WindowShow)
{
MSG message;
HRESULT status;
Create_Window(CurrentInstance);
Initialize_Direct3D11(CurrentInstance);
Initialize_Sprites();
Initialize_Rendering_Pipeline();
Create_Vertex_Buffer_for_triangle();
while (true)
{
if (PeekMessage(&message, MainWindow, 0, 0, PM_REMOVE))
{
TranslateMessage(&message);
DispatchMessage(&message);
}
else
{
Render_Frame();
Render_Text();
SwapChain->Present(0, 0);
}
}
}
void Initialize_Sprites()
{
Sprite_Font.reset(new DirectX::SpriteFont(device, L"myfile.spritefont"));
Sprite_Batch.reset(new DirectX::SpriteBatch(DevContext));
m_fontPos.x = 200;
m_fontPos.y = 200;
}
void Create_Window(HINSTANCE &CurrentInstance)
{
WNDCLASSEX windowclass;
ZeroMemory(&windowclass, sizeof(WNDCLASSEX));
windowclass.cbSize = sizeof(WNDCLASSEX);
windowclass.lpszClassName = L"Window Class";
windowclass.hInstance = CurrentInstance;
windowclass.lpfnWndProc = WindowProcedure;
windowclass.hIcon = LoadIcon(NULL, IDI_WINLOGO);
windowclass.hCursor = LoadCursor(NULL, IDC_ARROW);
RegisterClassEx(&windowclass);
MainWindow = CreateWindowEx(
0,
L"Window Class",
L"The Empire of Anatoria",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
800,
600,
NULL,
NULL,
CurrentInstance,
NULL
);
ShowWindow(MainWindow, SW_SHOW);
}
void Render_Text()
{
DirectX::SimpleMath::Vector2 origin = Sprite_Font->MeasureString(output);
Sprite_Batch->Begin();
Sprite_Font->DrawString(Sprite_Batch.get(), output,
m_fontPos, DirectX::Colors::White, 0.f, origin);
Sprite_Batch->End();
}
void Initialize_Direct3D11(HINSTANCE instance)
{
DXGI_MODE_DESC BackBufferDesc;
DXGI_SWAP_CHAIN_DESC SwapChainDesc;
ZeroMemory(&BackBufferDesc, sizeof(DXGI_MODE_DESC));
BackBufferDesc.Width = 400;
BackBufferDesc.Height = 400;
BackBufferDesc.RefreshRate.Numerator = 60;
BackBufferDesc.RefreshRate.Denominator = 1;
BackBufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
ZeroMemory(&SwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
SwapChainDesc.BufferDesc = BackBufferDesc;
SwapChainDesc.BufferCount = 1;
SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
SwapChainDesc.SampleDesc.Count = 1;
SwapChainDesc.SampleDesc.Quality = 0;
SwapChainDesc.OutputWindow = MainWindow;
SwapChainDesc.Windowed = TRUE;
SwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
D3D11CreateDeviceAndSwapChain(NULL,
D3D_DRIVER_TYPE_HARDWARE,
NULL,
NULL,
NULL,
NULL,
D3D11_SDK_VERSION,
&SwapChainDesc,
&SwapChain,
&device,
NULL,
&DevContext
);
ID3D11Texture2D * BackBuffer;
SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&BackBuffer);
device->CreateRenderTargetView(BackBuffer, NULL, &RenderTarget);
DevContext->OMSetRenderTargets(
1,
&RenderTarget,
NULL
);
BackBuffer->Release();
DevContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
}
void Initialize_Rendering_Pipeline()
{
D3DCompileFromFile(L"VertexShader.hlsl", 0, 0, "main", "vs_5_0", 0, 0, &VertexShader, 0);
D3DCompileFromFile(L"VertexShader.hlsl", 0, 0, "Pixel_Shader", "ps_5_0", 0, 0, &PixelShader, 0);
device->CreateVertexShader(VertexShader->GetBufferPointer(), VertexShader->GetBufferSize(), NULL, &VS);
device->CreatePixelShader(PixelShader->GetBufferPointer(), PixelShader->GetBufferSize(), NULL, &PS);
DevContext->VSSetShader(VS, 0, 0);
DevContext->PSSetShader(PS, 0, 0);
D3D11_VIEWPORT Raster;
ZeroMemory(&Raster, sizeof(D3D11_VIEWPORT));
Raster.MinDepth = 0.0f;
Raster.MaxDepth = 1.0f;
Raster.Width = 400;
Raster.Height = 400;
DevContext->RSSetViewports(1, &Raster);
D3D11_INPUT_ELEMENT_DESC InputLayout[1];
ZeroMemory(&InputLayout[0], sizeof(D3D11_INPUT_ELEMENT_DESC));
InputLayout[0].SemanticName = "POSITION";
InputLayout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
InputLayout[0].InputSlot = 0;
InputLayout[0].AlignedByteOffset = 0;
InputLayout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
device->CreateInputLayout(
InputLayout,
1,
VertexShader->GetBufferPointer(),
VertexShader->GetBufferSize(),
&inputLayout
);
DevContext->IASetInputLayout(inputLayout);
}
void Render_Frame()
{
float BackgroundColor[4] = {0.0f, 0.0f, 0.0f, 1.0f};
DevContext->ClearRenderTargetView(RenderTarget, BackgroundColor);
DevContext->Draw(3, 0);
}
void Create_Vertex_Buffer_for_triangle()
{
D3D11_BUFFER_DESC VertexBufferDesc;
D3D11_SUBRESOURCE_DATA VertexData;
UINT stride = sizeof(Vertex_Buffer);
UINT offset = 0;
ZeroMemory(&VertexBufferDesc, sizeof(D3D11_BUFFER_DESC));
VertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
VertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
VertexBufferDesc.CPUAccessFlags = 0;
VertexBufferDesc.ByteWidth = sizeof(Vertex_Buffer) * 3;
Vertex_Buffer VerticesData[] =
{
Vertex_Buffer(0.0f, 0.5f, 0.5f),
Vertex_Buffer(0.5f, -0.5f, 0.5f),
Vertex_Buffer(-0.5f, -0.5f, 0.5f)
};
ZeroMemory(&VertexData, sizeof(D3D11_SUBRESOURCE_DATA));
VertexData.pSysMem = VerticesData;
device->CreateBuffer(
&VertexBufferDesc,
&VertexData,
&VertexBuffer);
DevContext->IASetVertexBuffers(
0,
1,
&VertexBuffer,
&stride,
&offset
);
}
LRESULT CALLBACK WindowProcedure(HWND handle, unsigned int message, WPARAM ignore1, LPARAM ignore2)
{
switch (message)
{
case WM_CREATE:
return 0;
case WM_CLOSE:
DestroyWindow(handle);
return 0;
default:
return DefWindowProc(handle, message, ignore1, ignore2);
}
}
Here is the VertexShader.hlsl file
float4 main( float4 pos : POSITION ) : SV_POSITION
{
return pos;
}
float4 Pixel_Shader() : SV_TARGET
{
return float4(1.0f, 0.0f, 0.0f, 1.0f);
}
First, if your code snippet is accurate, you should not be creating the SpriteFont and SpriteBatch instance every frame. You only have to create them when the device changes.
By default, SpriteFont is drawing using pre-multiplied alpha blending modes, so if you are getting a fully "background color" image then something else is amiss in your pipeline state. It is likely that you are leaving some state in effect in the rendering between the clear and RenderText that is affecting the SpriteBatch renderer that you should reset.
It might also be the color you are using for the background clear which has the alpha set to 0 rather than 1. Try using:
float BackgroundColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
Try working through a few of the DirectX Tool Kit tutorials to make sure things are working in isolation and so you understand how the classes work, specifically Drawing text.
You and me have the same problem with SpriteFont. We forgot to reset the VertexBuffers and all other rendering states after the call to SpriteFont. See my post and the solution from Chuck Walbourn: DirectX::SpriteFont/SpriteBatch prevents 3D scene from drawing.
To quote Chuck:
You set the render state up for your scene in InitScene, but drawing anything else changes the state which is exactly what SpriteBatch does. I document which render states each object in DirectX Toolkit manipulates on the wiki. You need to set all the state your Draw requires each frame, not assume it is set forever, if you do more than a single draw.
See my question for additional links providing more information.
I have just begun my directx c++ tutorial and I finally drew triangle, but whenever I try to transform it, by any matrix, that never works although I followed the tutorial step by step and I also looked for it in the MSDN tutorial, but I didn't figure out the problem, here's the full code:
main.cpp:
#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#include "define.h"
LRESULT WINAPI WndProc( HWND, UINT, WPARAM, LPARAM );
int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow )
{
HICON icon;
icon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_APP_ICON));
WNDCLASS wc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)NULL;
wc.hCursor = LoadCursor(hInst, IDC_ARROW);
wc.hIcon = icon;
wc.hInstance = hInst;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = "Window Class";
wc.lpszMenuName = NULL;
wc.style = CS_VREDRAW | CS_HREDRAW;
RegisterClass( &wc );
HWND hWnd = CreateWindow("Window Class", "D3D Tutorial 01: CreateDevice",
WS_OVERLAPPEDWINDOW, 0, 0, 1440, 900,
NULL, NULL, hInst, NULL );
ShowWindow( hWnd, SW_NORMAL);
initD3D(hWnd);
initGraphics();
Render();
MSG msg;
// Check to see if any messages are waiting in the queue
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT WINAPI WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch( msg )
{
case WM_KEYDOWN:
{
if(wParam == 0x51)
PostQuitMessage(1);
return 0;
break;
}
case WM_DESTROY:
{
PostQuitMessage(0);
clearD3D();
return 1;
break;
}
default:
{
return DefWindowProc( hWnd, msg, wParam, lParam );
}
}
}
void initD3D(HWND hwnd)
{
d3d = Direct3DCreate9(D3D_SDK_VERSION);
D3DPRESENT_PARAMETERS d3dparams;
ZeroMemory(&d3dparams, sizeof(D3DPRESENT_PARAMETERS));
d3dparams.hDeviceWindow = hwnd;
d3dparams.Windowed = FALSE;
d3dparams.BackBufferFormat = D3DFMT_A8R8G8B8;
d3dparams.BackBufferHeight = 900;
d3dparams.BackBufferWidth = 1440;
d3dparams.SwapEffect = D3DSWAPEFFECT_FLIP;
d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_NOWINDOWCHANGES, &d3dparams, &d3ddevice);
d3ddevice->SetRenderState(D3DRS_LIGHTING, FALSE);
}
void Render()
{
// clear the window to a deep blue
d3ddevice->Clear(NULL, 0, D3DCLEAR_TARGET, D3DCOLOR_ARGB(255, 20, 40, 100), 1.0f, 0);
d3ddevice->BeginScene(); // begins the 3D scene
// do 3D rendering on the back buffer here
d3ddevice->SetFVF(FVFcode);
D3DXMatrixIdentity(&matrix);
D3DXMatrixTranslation(&matrix, 900, 0, 0);
d3ddevice->SetTransform(D3DTS_WORLD, &matrix);
D3DXMATRIX out;
D3DXVECTOR3 eye(2,3,3);
D3DXVECTOR3 Lat(0,0,0);
D3DXVECTOR3 up(0,1,0);
D3DXMatrixLookAtLH(&out, &eye, &Lat, &up);
d3ddevice->SetTransform(D3DTS_VIEW, &out);
D3DXMATRIX pro;
D3DXMatrixPerspectiveFovLH(&pro,
D3DXToRadian(45), // the horizontal field of view
(FLOAT)1440 / (FLOAT)900, // aspect ratio
1.0f, // the near view-plane
100.0f); // the far view-plane
d3ddevice->SetTransform(D3DTS_PROJECTION, &pro);
d3ddevice->SetStreamSource(0, v_buffer, 0, sizeof(vertex));
d3ddevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
d3ddevice->EndScene(); // ends the 3D scene
d3ddevice->Present(NULL, NULL, NULL, NULL); // displays the created frame on the screen
}
void initGraphics()
{
vertex v [] =
{{320.0f, 50.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(0, 0, 255)},
{520.0f, 400.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(0, 255, 0)},
{120.0f, 400.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(255, 0, 0)},
};
d3ddevice->CreateVertexBuffer( 3*sizeof(vertex), 0, FVFcode, D3DPOOL_DEFAULT, &v_buffer, NULL );
VOID* pVoid;
v_buffer->Lock(0, 0, (void**)&pVoid, 0);
CopyMemory(pVoid, v, sizeof(v));
v_buffer->Unlock();
}
define.h:
#ifndef DEFINE_H_INCLUDED
#define DEFINE_H_INCLUDED
#define IDI_APP_ICON 1
#define FVFcode (D3DFVF_DIFFUSE | D3DFVF_XYZRHW)
//all the declarations and prototypes:
//Dx functions:
void initD3D (HWND);
void clearD3D (void);
void Render(void);
void initGraphics(void);
//constants:
LPDIRECT3D9 d3d;
D3DXMATRIX matrix;
LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL;
LPDIRECT3DDEVICE9 d3ddevice;
//Vertices Structure:
struct vertex
{
float x, y,z, rhw;
DWORD color;
};
void clearD3D ()
{
d3d->Release();
d3ddevice->Release();
v_buffer->Release();
}
#endif // DEFINE_H_INCLUDED
and I just have another resource file where I just imported the app icon, I know the code is so long and will take time to read, but I am so sorry I can't find any other solution for this. I also have another question, do I have to set the three matrices, world view and projection, to be able to make an effect like changing the triangles place using world matrix, do I have to set the other two matrices, to change it or only world?? Lastly, thanks for any replier so much, thanks fr his effort and time.
EDIT
The relevant parts/ parts related to transforms from the whole code -coz it is too long- are:
d3ddevice->BeginScene(); // begins the 3D scene
// do 3D rendering on the back buffer here
d3ddevice->SetFVF(FVFcode);
D3DXMATRIX matrix;
D3DXMatrixIdentity(&matrix);
D3DXMatrixTranslation(&matrix, 900, 0, 0);
d3ddevice->SetTransform(D3DTS_WORLD, &matrix);
D3DXMATRIX out;
D3DXVECTOR3 eye(2,3,3);
D3DXVECTOR3 Lat(0,0,0);
D3DXVECTOR3 up(0,1,0);
D3DXMatrixLookAtLH(&out, &eye, &Lat, &up);
d3ddevice->SetTransform(D3DTS_VIEW, &out);
D3DXMATRIX pro;
D3DXMatrixPerspectiveFovLH(&pro,
D3DXToRadian(45), // the horizontal field of view
(FLOAT)1440 / (FLOAT)900, // aspect ratio
1.0f, // the near view-plane
100.0f); // the far view-plane
d3ddevice->SetTransform(D3DTS_PROJECTION, &pro);
d3ddevice->SetStreamSource(0, v_buffer, 0, sizeof(vertex));
d3ddevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
d3ddevice->EndScene(); // ends the 3D scene
So lets start with the basics:
The world matrix
Defined here
D3DXMATRIX matrix;
D3DXMatrixIdentity(&matrix);
D3DXMatrixTranslation(&matrix, 900, 0, 0);
d3ddevice->SetTransform(D3DTS_WORLD, &matrix);
This matrix defines the transformation from the origin that the vertices will have. In this case, you are translating the vertices 900 units to the positive X axis. I.e, if you render its position as (0,0,0), it will be actually at (900,0,0).
This matrix is used when you need to efficiently transform a static mesh, so you don't have to mess with the vertex buffer, only with a single matrix, which is much more efficent. This is the matrix that you should be look at in order to translate, rotate and skew.
The view matrix
Defined here:
D3DXMATRIX out;
D3DXVECTOR3 eye(2,3,3);
D3DXVECTOR3 Lat(0,0,0);
D3DXVECTOR3 up(0,1,0);
D3DXMatrixLookAtLH(&out, &eye, &Lat, &up);
d3ddevice->SetTransform(D3DTS_VIEW, &out);
This matrix defines the transformation that will take place in order to transform the vertex from world space into view space. That is, the relative position of the vertex to the camera. If all you want is rotate or translate the camera, this is where you should change.
The projection matrix
D3DXMATRIX pro;
D3DXMatrixPerspectiveFovLH(&pro,
D3DXToRadian(45), // the horizontal field of view
(FLOAT)1440 / (FLOAT)900, // aspect ratio
1.0f, // the near view-plane
100.0f); // the far view-plane
d3ddevice->SetTransform(D3DTS_PROJECTION, &pro);
This matrix defines how the vertices will be projected to screen space. Look at this image:
Objects closer to the camera than the near view plane or farther than the far view plane will not be shown. In the image, the green sphere will not be shown, since it is out of bounds.
The FOV angle in practice, means a "zoom" (not quite, but you can think like that).
This matrix is changed when you need some artifacts, like zooming, PIP and such.
In your case, it seems that you want to change just the world matrix. A good start would be using the D3DXMatrixTransformation function.
The basic problem is here:
#define FVFcode (D3DFVF_DIFFUSE | D3DFVF_XYZRHW)
D3DFVF_XYZRHW indicates the vertex has transformed positions and therefore the world, view and projection transforms should not be applied.
To fix, you'll need to change that D3DFVF_XYZRHW to D3DFVF_XYZ. Then the vertex structure needs the rhw dropped:
struct vertex
{
float x, y, z;
DWORD color;
};
and the initialization of v must be altered:
vertex v [] =
{{320.0f, 50.0f, 1.0f, D3DCOLOR_XRGB(0, 0, 255)},
{520.0f, 400.0f, 1.0f, D3DCOLOR_XRGB(0, 255, 0)},
{120.0f, 400.0f, 1.0f, D3DCOLOR_XRGB(255, 0, 0)},
};
That should get DirectX to apply the transformations. I haven't checked to see if there are additional problems with the math of the transformations.
I'm learning DirectX 11 and I'm trying to render a simple cube, unfortunately my code doesn't work, it simply doesn't render nothing... no errors, no warnings... The only thing displayed is the window with the specified clear color. I'm also very sure that the code is executed entirely.
This is the header of my specialized class:
#pragma once
#include "DirectxApp.h"
#include <DirectXMath.h>
#include "DirectxUtils.h"
struct Vertex
{
DirectX::XMFLOAT3 Position;
DirectX::XMFLOAT4 Color;
};
struct TransformationMatrix
{
DirectX::XMMATRIX worldViewProjMatrix;
};
class MyDirectxApp : public DirectxApp
{
private:
ID3D11Buffer* m_vertexBuffer;
ID3D11Buffer* m_indexBuffer;
ID3D11Buffer* m_worldViewProjBuffer;
ID3D11RasterizerState* m_rasterizerState;
ID3D11InputLayout* m_inputLayout;
ID3D11VertexShader* m_vertexShader;
ID3D11PixelShader* m_pixelShader;
DirectX::XMMATRIX m_worldMatrix;
DirectX::XMMATRIX m_viewMatrix;
DirectX::XMMATRIX m_projMatrix;
TransformationMatrix m_transformationMatrix;
float m_theta;
float m_phi;
float m_radius;
public:
MyDirectxApp(HINSTANCE hInstance,
int width,
int height,
LPWSTR windowName = L"",
bool enable4xMsaa = true,
int xCoord = CW_USEDEFAULT,
int yCoord = CW_USEDEFAULT
);
virtual bool Init();
virtual void OnFrame();
virtual ~MyDirectxApp(void);
};
And this is the cpp (the init method of the super class initializes the window and the basic components of DirectX, see later):
#include "MyDirectxApp.h"
using namespace DirectX;
MyDirectxApp::MyDirectxApp(HINSTANCE hInstance,
int width,
int height,
LPWSTR windowName,
bool enable4xMsaa,
int xCoord,
int yCoord
) : DirectxApp(hInstance, width, height, windowName, enable4xMsaa, xCoord, yCoord)
{
m_vertexBuffer = 0;
m_indexBuffer = 0;
m_inputLayout = 0;
m_rasterizerState = 0;
m_vertexShader = 0;
m_pixelShader = 0;
m_worldViewProjBuffer = 0;
XMMATRIX matrixIdentity = XMMatrixIdentity();
m_worldMatrix = matrixIdentity;
m_viewMatrix = matrixIdentity;
m_projMatrix = matrixIdentity;
m_transformationMatrix.worldViewProjMatrix = matrixIdentity;
m_theta = 1.5f * DirectX::XM_PI;
m_phi = 0.25f* DirectX::XM_PI;
m_radius = 5.0f;
}
bool MyDirectxApp::Init()
{
if(!DirectxApp::Init())
{
return false;
}
HRESULT hResult;
//////////////////////////////////////
// CreateVertexBuffer
//////////////////////////////////////
Vertex cubeVertexArray[] = {
// Position Color
{XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, //white
{XMFLOAT3(-1.0f, +1.0f, -1.0f), XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f)}, //black
{XMFLOAT3(+1.0f, +1.0f, -1.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f)}, //red
{XMFLOAT3(+1.0f, -1.0f, -1.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f)}, //green
{XMFLOAT3(-1.0f, -1.0f, +1.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f)}, //blue
{XMFLOAT3(-1.0f, +1.0f, +1.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f)}, //yellow
{XMFLOAT3(+1.0f, +1.0f, +1.0f), XMFLOAT4(0.0f, 1.0f, 1.0f, 1.0f)}, //cyan
{XMFLOAT3(+1.0f, -1.0f, +1.0f), XMFLOAT4(1.0f, 0.0f, 1.0f, 1.0f)} //magenta
};
hResult = DirectxUtils::CreateVertexBuffer(m_d3dDevice, &cubeVertexArray, sizeof(cubeVertexArray), &m_vertexBuffer);
if (FAILED(hResult))
{
MessageBox(0, L"CreateVertexBuffer FAILED", 0, 0);
return false;
}
//////////////////////////////////////
// CreateIndexBuffer
//////////////////////////////////////
UINT indices[] = {
0, 1, 2, // front face
0, 2, 3,
4, 6, 5, // back face
4, 7, 6,
4, 5, 1, // left face
4, 1, 0,
3, 2, 6, // right face
3, 6, 7,
1, 5, 6, // top face
1, 6, 2,
4, 0, 3, // bottom face
4, 3, 7
};
hResult = DirectxUtils::CreateIndexBuffer(m_d3dDevice, &indices, sizeof(indices), &m_indexBuffer);
if (FAILED(hResult))
{
MessageBox(0, L"CreateIndexBuffer FAILED", 0, 0);
return false;
}
//////////////////////////////////////
// CreateVertexShader
//////////////////////////////////////
D3D11_INPUT_ELEMENT_DESC inputLayoutDesc[] = {
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT , 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"COLOR" , 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
};
hResult = DirectxUtils::CreateVertexShader(m_d3dDevice, L"VertexShader.hlsl", "main", inputLayoutDesc, 2, &m_vertexShader, &m_inputLayout);
if (FAILED(hResult))
{
MessageBox(0, L"CreateVertexShader FAILED", 0, 0);
return false;
}
//////////////////////////////////////
// CreatePixelShader
//////////////////////////////////////
hResult = DirectxUtils::CreatePixelShader(m_d3dDevice, L"PixelShader.hlsl", "main", &m_pixelShader);
if (FAILED(hResult))
{
MessageBox(0, L"CreatePixelShader FAILED", 0, 0);
return false;
}
//////////////////////////////////////
// create world\view\proj matrix
//////////////////////////////////////
XMVECTOR cameraPos = XMVectorSet(0.0f, 3.0f, -5.0f, 1.0f);
XMVECTOR cameraTarget = XMVectorZero();
XMVECTOR cameraUp = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
m_worldMatrix = XMMatrixIdentity();
m_projMatrix = XMMatrixPerspectiveFovLH(XMConvertToRadians(45.0f), AspectRatio(), 0.1f, 100.0f);
m_viewMatrix = XMMatrixLookAtLH(cameraPos, cameraTarget, cameraUp);
hResult = DirectxUtils::CreateConstantBuffer(m_d3dDevice, sizeof(TransformationMatrix), &m_worldViewProjBuffer);
if (FAILED(hResult))
{
MessageBox(0, L"CreateConstantBuffer FAILED", 0, 0);
return false;
}
//////////////////////////////////////
// CreateRasterizerState
//////////////////////////////////////
D3D11_RASTERIZER_DESC rasterizerDesc;
rasterizerDesc.FillMode = D3D11_FILL_SOLID;
rasterizerDesc.CullMode = D3D11_CULL_BACK;
rasterizerDesc.FrontCounterClockwise = false;
rasterizerDesc.DepthClipEnable = true;
hResult = m_d3dDevice->CreateRasterizerState(&rasterizerDesc, &m_rasterizerState);
if (FAILED(hResult))
{
MessageBox(0, L"CreateRasterizerState FAILED", 0, 0);
return false;
}
return true;
}
void MyDirectxApp::OnFrame()
{
///////////////////////////////////
// update worldViewProj matrix
///////////////////////////////////
XMVECTOR cameraPos = XMVectorSet(0.0f, 3.0f, -5.0f, 1.0f);
XMVECTOR cameraTarget = XMVectorZero();
XMVECTOR cameraUp = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
m_viewMatrix = XMMatrixLookAtLH(cameraPos, cameraTarget, cameraUp);
m_transformationMatrix.worldViewProjMatrix = m_worldMatrix * m_viewMatrix * m_projMatrix;
///////////////////////////////////
// drawing
///////////////////////////////////
static const FLOAT clearColor[4] = {0.0f, 0.0f, 0.0f, 0.0f};
m_d3dDeviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilBufferView);
m_d3dDeviceContext->ClearRenderTargetView(m_renderTargetView, clearColor);
m_d3dDeviceContext->ClearDepthStencilView(m_depthStencilBufferView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
m_d3dDeviceContext->IASetInputLayout(m_inputLayout);
m_d3dDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
UINT stride = sizeof(Vertex);
UINT offset = 0;
m_d3dDeviceContext->IASetVertexBuffers(0, 1, &m_vertexBuffer, &stride, &offset);
m_d3dDeviceContext->IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R32_UINT, 0);
m_d3dDeviceContext->VSSetShader(m_vertexShader, nullptr, 0);
m_d3dDeviceContext->PSSetShader(m_pixelShader, nullptr, 0);
m_d3dDeviceContext->RSSetState(m_rasterizerState);
m_d3dDeviceContext->UpdateSubresource(m_worldViewProjBuffer, 0, nullptr, &m_transformationMatrix, 0, 0);
m_d3dDeviceContext->VSSetConstantBuffers(0, 1, &m_worldViewProjBuffer);
m_d3dDeviceContext->DrawIndexed(36, 0, 0);
m_swapChain->Present(0, 0);
}
MyDirectxApp::~MyDirectxApp(void)
{
m_vertexBuffer->Release();
m_indexBuffer->Release();
m_inputLayout->Release();
m_rasterizerState->Release();
m_vertexShader->Release();
m_pixelShader->Release();
m_worldViewProjBuffer->Release();
}
The VertexShader is really simple, it only does the world-view-projection transformation:
cbuffer cbPerObject
{
float4x4 worldViewProjection;
};
//input data structure
struct VertexInput
{
float3 iPosition : POSITION;
float4 iColor : COLOR;
};
//output data
struct VertexOutput
{
float4 oPosition : SV_POSITION; //system-value-position is a special semantic name
float4 oColor : COLOR;
};
VertexOutput main(VertexInput vertexInput)
{
VertexOutput vertexOutput;
//transform world-view-projection
vertexOutput.oPosition = mul(float4(vertexInput.iPosition, 1.0f), worldViewProjection);
vertexOutput.oColor = vertexInput.iColor;
return vertexOutput;
}
The PixelShader is even simpler:
//input data structure
//must match the vertexShader output
struct PixelShaderInput
{
float4 iPosition : SV_POSITION;
float4 iColor : COLOR;
};
float4 main(PixelShaderInput pixelShaderInput) : SV_TARGET //system-value-target means the output must match the renderTarget format
{
return pixelShaderInput.iColor;
}
As mentioned above the basic components of Directx are created by the super class (DirectxApp), here's the code:
bool DirectxApp::InitDirectx()
{
//////////////////////////////////////
// device creation
//////////////////////////////////////
UINT creationDeviceFlags = 0;
#if defined(DEBUG)
creationDeviceFlags = D3D11_CREATE_DEVICE_DEBUG;
#endif
D3D_FEATURE_LEVEL featureLevel;
HRESULT hResult = D3D11CreateDevice(0, //display adapter
D3D_DRIVER_TYPE_HARDWARE, //drier type
0, //software driver
creationDeviceFlags, //device flag
0, //array of feature levels (NULL means choose the greatest)
0, //number of feature levels
D3D11_SDK_VERSION, //sdk version
&m_d3dDevice,
&featureLevel,
&m_d3dDeviceContext);
if (FAILED(hResult))
{
MessageBox(0, L"D3D11CreateDevice FAILED", 0, 0);
return false;
}
if (featureLevel != D3D_FEATURE_LEVEL_11_0)
{
MessageBox(0, L"D3D_FEATURE_LEVEL_11_0 not supported", 0, 0);
return false;
}
//////////////////////////////////////
// check 4xMSAA
//////////////////////////////////////
UINT m4xMsaaQuality;
m_d3dDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, 4, &m4xMsaaQuality);
assert(m4xMsaaQuality > 0); //m4xMsaaQuality is always > 0
//////////////////////////////////////
// swap chain creation
//////////////////////////////////////
DXGI_SWAP_CHAIN_DESC swapChainDesc;
swapChainDesc.BufferDesc.Width = m_windowWidth;
swapChainDesc.BufferDesc.Height = m_windowHeight;
swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
if (m_enable4xMsaa)
{
swapChainDesc.SampleDesc.Count = 4;
swapChainDesc.SampleDesc.Quality = m4xMsaaQuality -1;
}
else
{
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
}
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = 1; //means double buffering
swapChainDesc.OutputWindow = m_mainWindow;
swapChainDesc.Windowed = true;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
swapChainDesc.Flags = 0;
IDXGIDevice* dxgiDevice = 0;
m_d3dDevice->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice));
IDXGIAdapter* dxgiAdapter = 0;
dxgiDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&dxgiAdapter));
IDXGIFactory* dxgiFactory = 0;
dxgiAdapter->GetParent(__uuidof(IDXGIFactory), reinterpret_cast<void**>(&dxgiFactory));
HRESULT hResultSwapChain = dxgiFactory->CreateSwapChain(m_d3dDevice, &swapChainDesc, &m_swapChain);
dxgiDevice->Release();
dxgiAdapter->Release();
dxgiFactory->Release();
if (FAILED(hResultSwapChain))
{
MessageBox(0, L"CreateSwapChain FAILED", 0, 0);
return false;
}
//////////////////////////////////////
// render target creation
//////////////////////////////////////
ID3D11Texture2D* backBufferTexture2D = 0;
m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&backBufferTexture2D));
HRESULT hResultRenderTarget = m_d3dDevice->CreateRenderTargetView(backBufferTexture2D, 0, &m_renderTargetView);
backBufferTexture2D->Release();
if (FAILED(hResultRenderTarget))
{
MessageBox(0, L"CreateRenderTargetView FAILED", 0, 0);
return false;
}
//////////////////////////////////////
// depth-stencil buffer creation
//////////////////////////////////////
D3D11_TEXTURE2D_DESC depthStencilBufferTexture2D;
depthStencilBufferTexture2D.Width = m_windowWidth;
depthStencilBufferTexture2D.Height = m_windowHeight;
depthStencilBufferTexture2D.MipLevels = 1;
depthStencilBufferTexture2D.ArraySize = 1;
depthStencilBufferTexture2D.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
if (m_enable4xMsaa)
{
depthStencilBufferTexture2D.SampleDesc.Count = 4;
depthStencilBufferTexture2D.SampleDesc.Quality = m4xMsaaQuality -1;
}
else
{
depthStencilBufferTexture2D.SampleDesc.Count = 1;
depthStencilBufferTexture2D.SampleDesc.Quality = 0;
}
depthStencilBufferTexture2D.Usage = D3D11_USAGE_DEFAULT;
depthStencilBufferTexture2D.BindFlags = D3D11_BIND_DEPTH_STENCIL;
depthStencilBufferTexture2D.CPUAccessFlags = 0;
depthStencilBufferTexture2D.MiscFlags = 0;
HRESULT hResultDepthStencil = m_d3dDevice->CreateTexture2D(&depthStencilBufferTexture2D, 0, &m_depthStencilBufferTexture2D);
if (FAILED(hResultDepthStencil))
{
MessageBox(0, L"CreateTexture2D depthStencil FAILED", 0, 0);
return false;
}
HRESULT hResultDepthStencilView = m_d3dDevice->CreateDepthStencilView(m_depthStencilBufferTexture2D, 0, &m_depthStencilBufferView);
if (FAILED(hResultDepthStencilView))
{
MessageBox(0, L"CreateDepthStencilView FAILED", 0, 0);
return false;
}
//////////////////////////////////////
// viewport creation
//////////////////////////////////////
D3D11_VIEWPORT viewport;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = float(m_windowWidth);
viewport.Height = float(m_windowHeight);
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
m_d3dDeviceContext->RSSetViewports(1, &viewport);
return true;
}
I appreciate any hint to solve this problem!
Thanks in advance
EDIT
To the rendering pipeline arrives only one triangle, the VertexShader is executed but not the PixelShader, and then dies...
It may not be the only problem, but you should transpose the matrices before sending them to the shader. You can do that by calling XMMatrixTranspose( matrix ).
(I see now that someone already mentioned it)
I'm pretty new to this structure and the book I'm learning it from is absurdly unintuitive to me. I triple checked the code but I can't figure out why I can't get an image to pop up. The background is white and the HUD is there but the cube won't show up. It was the same when i tried to make it in colour.
#include <windows.h>
#include <windowsx.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <d3dx9core.h>
#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")
LPDIRECT3D9 d3d;
LPDIRECT3DDEVICE9 d3ddev;
//LPDIRECT3DTEXTURE9 quadTexture;
LPD3DXFONT m_font;
D3DCOLOR fontColor;
LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL;
LPDIRECT3DINDEXBUFFER9 i_buffer = NULL;
struct ColorVertex{
D3DXVECTOR3 pos;
ColorVertex(FLOAT X, FLOAT Y, FLOAT Z):pos(X, Y, Z){}
static IDirect3DVertexDeclaration9* Decl;
};
IDirect3DVertexDeclaration9* ColorVertex::Decl = 0;
void initD3D(HWND hWnd);
void render_frame(void);
void cleanD3D(void);
void setVertices(void);
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
#define SCREEN_WIDTH GetSystemMetrics(SM_CXSCREEN)
#define SCREEN_HEIGHT GetSystemMetrics(SM_CYSCREEN)
HWND hWnd;
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(WNDCLASSEX));
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszClassName = L"WindowClass";
RegisterClassEx(&wc);
hWnd = CreateWindowEx(NULL,
L"WindowClass",
L"v2",
WS_EX_TOPMOST | WS_POPUP,
0, 0,
SCREEN_WIDTH, SCREEN_HEIGHT,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hWnd, nCmdShow);
initD3D(hWnd);
setVertices();
D3DXCreateFont( d3ddev, 20, 0, FW_BOLD, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("Arial"), &m_font );
D3DVERTEXELEMENT9 Elements[] = {
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
D3DDECL_END()
};
d3ddev->CreateVertexDeclaration(Elements, &ColorVertex::Decl);
MSG msg;
while(TRUE){
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(msg.message == WM_QUIT) break;
render_frame();
}
cleanD3D();
return msg.wParam;
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){
switch(message){
case WM_DESTROY:{
PostQuitMessage(0);
return 0;
}break;
}
return DefWindowProc (hWnd, message, wParam, lParam);
}
void initD3D(HWND hWnd){
d3d = Direct3DCreate9(D3D_SDK_VERSION);
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = FALSE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hWnd;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.BackBufferWidth = SCREEN_WIDTH;
d3dpp.BackBufferHeight = SCREEN_HEIGHT;
d3d->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&d3ddev);
d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE);
d3ddev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
d3ddev->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
}
void setVertices(void){
d3ddev->CreateVertexBuffer(8*sizeof(ColorVertex),
0,
0,
D3DPOOL_MANAGED,
&v_buffer,
NULL);
ColorVertex* cube = 0;
v_buffer->Lock(0, 0, (void**)&cube, 0);
cube[0] = ColorVertex(-1.0f, -1.0f, -1.0f);
cube[1] = ColorVertex(-1.0f, 1.0f, -1.0f);
cube[2] = ColorVertex( 1.0f, 1.0f, -1.0f);
cube[3] = ColorVertex( 1.0f, -1.0f, -1.0f);
cube[4] = ColorVertex(-1.0f, -1.0f, 1.0f);
cube[5] = ColorVertex(-1.0f, 1.0f, 1.0f);
cube[6] = ColorVertex( 1.0f, 1.0f, 1.0f);
cube[7] = ColorVertex( 1.0f, -1.0f, 1.0f);
v_buffer->Unlock();
d3ddev->CreateIndexBuffer(12*3*sizeof(WORD),
0,
D3DFMT_INDEX16,
D3DPOOL_MANAGED,
&i_buffer,
NULL);
WORD* k = 0;
i_buffer->Lock(0, 0, (void**)&k, 0);
k[0] = 0; k[1] = 1; k[2] = 2;
k[3] = 0; k[4] = 2; k[5] = 3;
// Back face.
k[6] = 4; k[7] = 6; k[8] = 5;
k[9] = 4; k[10] = 7; k[11] = 6;
// Left face.
k[12] = 4; k[13] = 5; k[14] = 1;
k[15] = 4; k[16] = 1; k[17] = 0;
// Right face.
k[18] = 3; k[19] = 2; k[20] = 6;
k[21] = 3; k[22] = 6; k[23] = 7;
// Top face.
k[24] = 1; k[25] = 5; k[26] = 6;
k[27] = 1; k[28] = 6; k[29] = 2;
// Bottom face.
k[30] = 4; k[31] = 0; k[32] = 3;
k[33] = 4; k[34] = 3; k[35] = 7;
i_buffer->Unlock();
}
void render_frame(void){
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255, 255, 255), 1.0f, 0);
d3ddev->BeginScene();
d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(ColorVertex));
d3ddev->SetIndices(i_buffer);
D3DXMATRIX matView;
D3DXMatrixLookAtLH(&matView,
&D3DXVECTOR3 (0.0f, 5.0f, -5.0f),// the camera position
&D3DXVECTOR3 (0.0f, 0.0f, 0.0f), // the look-at position
&D3DXVECTOR3 (0.0f, 1.0f, 0.0f));// the up direction
d3ddev->SetTransform(D3DTS_VIEW, &matView);
D3DXMATRIX matProjection;
D3DXMatrixPerspectiveFovLH(&matProjection,
D3DXToRadian(90),
(FLOAT)SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT,
1.0f,// the near view-plane
5000.0f);// the far view-plane
d3ddev->SetVertexDeclaration(ColorVertex::Decl);
d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12);
fontColor = D3DCOLOR_ARGB(255,0,0,255);
RECT rct;
rct.left=10;
rct.right=SCREEN_WIDTH-10;
rct.top=10;
rct.bottom=rct.top+20;
//WCHAR lookAtPos [32000];
//swprintf_s(lookAtPos, 32000, L"X=%f, Z=%f, Y=%f", camDirX, camDirZ, camDirY);
m_font->DrawText(NULL, L"Hello World", -1, &rct, 0, fontColor );
d3ddev->EndScene();
d3ddev->Present(NULL, NULL, NULL, NULL);
}
void cleanD3D(void){
d3ddev->Release();
d3d->Release();
i_buffer->Release();
v_buffer->Release();
ColorVertex::Decl->Release();
}
I'm a friggin idiot. I set the world projection matrix and then didn't use it. Sorry for bothering you guys.