: DirectX 8 Programming Tutorial

2D Objects

2D Objects

A 2D object is really two textured triangles in a triangle strip that form a rectangle. The z value for each of the vertices is the same so that the 2D object faces the camera flat. I have created a class called CPanel which we will use as our 2D object.

CPanel is very similar to the objects we have already created. It has a vertex buffer which contains four vertices (one for each corner of the panel), and the panel is centred about the origin. The code for CPanel is shown below.

CPanel::CPanel(LPDIRECT3DDEVICE8 pD3DDevice, int nWidth, int nHeight, int nScreenWidth, int nScreenHeight, DWORD dwColour) {
m_pD3DDevice = pD3DDevice;
m_pVertexBuffer = NULL;
m_pTexture = NULL;
m_nWidth = nWidth;
m_nHeight = nHeight;
m_nScreenWidth = nScreenWidth;
m_nScreenHeight = nScreenHeight;
m_dwColour = dwColour;
//Initialize Vertex Buffer
if (CreateVertexBuffer()) {
if (UpdateVertices()) {
LogInfo("<li>Panel created OK");
LogError("<li>Panel failed to create");
CPanel::~CPanel() {
LogInfo("<li>Panel destroyed OK");
bool CPanel::CreateVertexBuffer() {
//Create the vertex buffer from our device.
if (FAILED(m_pD3DDevice->CreateVertexBuffer(4 * sizeof(PANEL_CUSTOMVERTEX), 0, PANEL_D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &m_pVertexBuffer))) {
LogError("<li>CPanel: Unable to create vertex buffer.");
return false;
return true;
bool CPanel::UpdateVertices() {
m_pVertexBuffer->Lock(0, 4 * sizeof(PANEL_CUSTOMVERTEX), (BYTE**)&pVertices, 0);
if (m_dwColour == 1) {
//No colour was set, so default to white
m_dwColour = D3DCOLOR_XRGB(255, 255, 255);
//Set all the vertices to selected colour
pVertices[0].colour = m_dwColour;
pVertices[1].colour = m_dwColour;
pVertices[2].colour = m_dwColour;
pVertices[3].colour = m_dwColour;
//Set the positions of the vertices
pVertices[0].x = (m_nWidth) / 2.0f;
pVertices[0].y = (m_nHeight) / 2.0f;
pVertices[1].x = (m_nWidth) / 2.0f;
pVertices[1].y = m_nHeight / 2.0f;
pVertices[2].x = (m_nWidth) / 2.0f;
pVertices[2].y = (m_nHeight) / 2.0f;
pVertices[3].x = (m_nWidth) / 2.0f;
pVertices[3].y = m_nHeight / 2.0f;
pVertices[0].z = 1.0f;
pVertices[1].z = 1.0f;
pVertices[2].z = 1.0f;
pVertices[3].z = 1.0f;
//Set the texture coordinates of the vertices
pVertices[0].u = 0.0f;
pVertices[0].v = 1.0f;
pVertices[1].u = 0.0f;
pVertices[1].v = 0.0f;
pVertices[2].u = 1.0f;
pVertices[2].v = 1.0f;
pVertices[3].u = 1.0f;
pVertices[3].v = 0.0f;
return true;
bool CPanel::SetTexture(const char *szTextureFilePath, DWORD dwKeyColour) {
if (FAILED(D3DXCreateTextureFromFileEx(m_pD3DDevice, szTextureFilePath, 0, 0, 0, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, dwKeyColour, NULL, NULL, &m_pTexture))) {
return false;
return true;
DWORD CPanel::Render() {
m_pD3DDevice->SetStreamSource(0, m_pVertexBuffer, sizeof(PANEL_CUSTOMVERTEX));
if (m_pTexture != NULL) {
m_pD3DDevice->SetTexture(0, m_pTexture);
m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
} else {
m_pD3DDevice->SetTexture(0, NULL);
m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
return 2; //Return the number of polygons rendered
void CPanel::MoveTo(int x, int y) {
//x and y specify the top left corner of the panel in screen coordinates
x = (m_nScreenWidth / 2) (m_nWidth / 2);
y = (m_nScreenHeight / 2) (m_nHeight / 2);
D3DXMatrixTranslation(&matMove, (float)x, (float)y, 0.0f);
m_pD3DDevice->SetTransform(D3DTS_WORLD, &matMove);

The only slight changes from usual are that the SetTexture and Render methods have changed to enable texture transparencies (we will look at this in a moment).

There is also a new function called MoveTo which will move the panel from the centre of the screen, to any position you specify. It takes two parameters x and y which are screen coordinates for the top left corner of the panel. We then use the normal matrix translation functions to move the panel. We can also rotate the panel by using the normal rotation matrices.

: 0.062. /Cache: 2 / 0