Панель инструментов сама по себе выглядит великолепно, но окончательный блеск ей придают отображаемые на ней блоки. В области выбора блоков одновременно может отображаться до 21 блока. Если у вас больше 21 блока, для доступа к дополнительным блокам используются кнопки навигации. Чтобы отобразить 21 блок я визуализирую их в пустом буфере, а затем копирую полученный результат на панель инструментов. Код для этого содержится в следующей функции:
void vRenderTileSet(void)
{
RECT rectDest;
RECT rectSrc;
int iX;
int iY;
int iTile;
// Включаем рассеянное освещение
g_pd3dDevice->SetRenderState(D3DRS_AMBIENT, 0x00606060);
// Очищаем вторичный буфер и z-буфер
g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET,
D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
// Начинаем визуализацию
g_pd3dDevice->BeginScene();
// Задаем состояние альфа-смешивания
// Это необходимо для реализации прозрачности/полупрозрачности
g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
// Отображение активных блоков
for(iY = 0; iY < 7; iY++) {
for(iX = 0; iX < 3; iX++) {
// Вычисляем отображаемый блок
iTile = (g_iCurTileSet * 21) + (iX + (iY * 3));
// Отображаем, если это существующий блок
if(iTile < g_iTotalTiles) {
vDrawInterfaceObject(
iX * g_iTileSize,
iY * g_iTileSize,
(float)g_iTileSize,
(float)g_iTileSize,
iTile);
}
// Рисуем рамку поверх текущего блока
if(iTile == g_iCurTile) {
vDrawInterfaceObject(
iX * g_iTileSize,
iY * g_iTileSize,
(float)g_iTileSize,
(float)g_iTileSize,
18);
}
}
}
// Отображаем текущий блок
vDrawInterfaceObject(
32,
32 * 7,
(float)g_iTileSize,
(float)g_iTileSize,
g_iCurTile);
// Завершаем визуализацию
g_pd3dDevice->EndScene();
// Исходный прямоугольник
rectSrc.top = 0;
rectSrc.bottom = g_iTileSize * 8;
rectSrc.left = 0;
rectSrc.right = g_iTileSize * 3;
// Целевой прямоугольник
rectDest.top = 2;
rectDest.bottom = (g_iTileSize * 8) + 2;
rectDest.left = 0;
rectDest.right = (g_iTileSize * 3);
g_pd3dDevice->Present(&rectSrc, &rectDest, hWndToolBar, NULL);
}
Первая часть логики визуализации содержит код, который очищает буфер, включает рассеянное освещение и активизирует альфа-смешивание. Главное удовольствие начинается в идущих следом циклах визуализации. В основном цикле программа перебирает в цикле ряды из трех блоков и визуализирует каждый блок в экранном буфере. Код продолжает работать таким образом, пока не будут отображены все семь рядов блоков.
Чтобы помочь пользователю понять, какой именно блок активен в данный момент времени, код изображает вокруг выбранного блока красный квадрат. В цикле визуализации для каждого блока проверяется не является ли он активным в данный момент, и, если да, то к его изображению добавляется красный квадрат.
После того, как визуализация набора блоков завершена, копия выбранного в данный момент блока отображается в нижней части экрана. Это еще один полезный индикатор текущего блока.
Теперь, когда выполнена визуализация всех блоков, надо поместить их на панель инструментов. Это выполняется путем задания исходной и целевой областей и вызова функции Present(). Как видите, в качестве параметров этой функции передаются исходная прямоугольная область и прямоугольная область места назначения. Сама функция сообщает системе визуализации, что необходимо взять изображение из одной области и скопировать его в другую. В этом случае вы можете визуализировать блоки в буфере трехмерной графики, а затем скопировать их на панель инструментов для показа. Посмотрите на код, и вы увидите как я копирую исходную область и перемещаю ее на панель инструментов.