return false;
}
return true;
}
bool CPaneclass="underline" :UpdateVertices() {
PANEL_CUSTOMVERTEX* pVertices = NULL;
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;
m_pVertexBuffer->Unlock();
return true;
}
bool CPaneclass="underline" :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 CPaneclass="underline" :Render() {
m_pD3DDevice->SetStreamSource(0, m_pVertexBuffer, sizeof(PANEL_CUSTOMVERTEX));
m_pD3DDevice->SetVertexShader(PANEL_D3DFVF_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 CPaneclass="underline" :MoveTo(int x, int y) {
//x and y specify the top left corner of the panel in screen coordinates
D3DXMATRIX matMove;
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.
The first thing to do is to enable alpha blending so that we can use transparent textures. We do this with a few calls to SetRenderState, the code to enable alpha blending is shown below:
//Enable alpha blending so we can use transparent textures
m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
//Set how the texture should be blended (use alpha)
m_pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
m_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
There are two further changes to make. The first is the way we load the textures. We need to use the D3DXCreateTextureFromFileEx function, this will enable us to specify a key colour. This means that any pixel in the texture that is the same colour as the key colour will be made transparent. Fig 11.1, 11.2 and 11.3 below show the three textures that I have used for this tutorial. I have specified that the black pixels should be transparent.
D3DXCreateTextureFromFileEx(m_pD3DDevice, szTextureFilePath, 0, 0, 0, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, dwKeyColour, NULL, NULL, &m_pTexture);
Fig 11.1
Fig 11.2
Fig 11.3
The second change is how the texture should be rendered. The SetTextureStageState function has been changed in the Render method of CPanel to render the texture using transparencies.
m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
From the last tutorial we have three rotating spaceships. We've added some 2D elements to the scene, each with some transparency in the texture. The final scene when rendered will look something like the screenshot below:
Now, we have completed the basics to rendering graphics in DirectX. There is lots more advanced topics in DirectX Graphics which we will cover in future tutorials. In the next tutorial we will see how to add some user interaction with the keyboard and mouse using DirectInput, vital to any game.
DirectX Tutorial 12: Keyboard and Mouse Input
In this tutorial we will create a simple Earth object that the user can control. The user will be able to use the mouse to change the Earth's position. The user will also be able to change the Earth's scale and rotation by using the keyboard. You can download the full source code by clicking the "Download Source" link above.
So far we have been using Direct3D to draw 3D objects. Now we want to add some user interaction to our application. We can do this by using DirectInput. DirectInput allows us to get data from any input device: mouse, keyboard or joystick. We can then use this data to change elements in our scene. In this tutorial we will be looking at the mouse and keyboard only, we'll take a look at joysticks in a future tutorial.
In our application, we will need to do the following steps to add user interaction.
· Initialise DirectInput
· Setup the keyboard
· Setup the mouse
· For each frame, get the state of the keyboard and mouse and use it to modify the scene
· Once finished, clean up DirectInput