Здравствуйте. Помогите мне, пожалуйста, с одной проблемой – никак не получается вручную сгенерировать нужную мне сферу. Да-да казалось бы такая простая вещь как D3dxCreateSphere могла бы подойти, но мне нужна не обычная сфера, которая сжимает свои линии к полюсам, а сфера с равными сегментами.
Мне же нужно чтобы вы 1) помогли подкорректировать его так, чтобы код генерировал сферу без сжатия к полюсам с равными сегментами и 2) – помогли с индексным буфером(который как вы видите, соединяет только вершины сегмента, а не сегменты между собой).
Версию кода в несколько упрощенном виде я приведу здесь.
Это генерирует обыкновенную сферу. Если вы не поленитесь написать простой класс и вставить в него
_vb , _ib в качестве буферов и несколько несложных переменных типа unsigned int.
HRESULT PLANET::Init() {
UINT segmentary = 16, //общее кол-во сегментов columnsnum = segmentary, //кол-во колонок rowsnum = segmentary, //максимальное кол-во сегментов в колонке segmentsnum = segmentary*segmentary;//кол-во сегментов
_numrendprimitives = segmentsnum*2; //кол-во отрисовывающихся примитивов
_numvvertexes = segmentsnum*4; //кол-во вершин для vertex buffer _numivertexes = segmentsnum*6; //кол-во вершин для index buffer (*_pDev)->CreateVertexBuffer ( _numvvertexes *sizeof(PlanetVertex), D3DUSAGE_DYNAMIC, D3DFVF_XYZ | D3DFVF_TEX1, D3DPOOL_DEFAULT, &_vb, NULL ); PlanetVertex* pattern;
_vb->Lock(0,0,(void**)&pattern,0);
//ПРОЦЕДУРНАЯ ГЕНЕРАЦИЯ СФЕРЫ //переменные скругления сферы float lattitude = 0.0f; float longitude = 0.0f;
const float _lattitudelimit = 360.0f; const float _longitudelimit = 360.0f; float lattitudeshift = _lattitudelimit/(float)columnsnum; float longitudeshift = _longitudelimit/(float)rowsnum;
//вычисляемые значения(для каждой вершины в квадрате) float
x1,x2,x3,x4, y1,y2,y3,y4, z1,z2,z3,z4, //вычисляемые значения скругления
fx1, fy1, fz1, fx2, fy2, fz2, fx3, fy3, fz3, fx4, fy4, fz4; for (UINT i = 0, //главный индекс c = 0, //счетчик столбцов r = 0; //счетчик строк c < segmentary; c++, lattitude+=lattitudeshift ) { fx1 = cos(D3DXToRadian(lattitude)); fx2 = cos(D3DXToRadian(lattitude)); fx3 = cos(D3DXToRadian(lattitude+lattitudeshift)); fx4 = cos(D3DXToRadian(lattitude+lattitudeshift));
x1 = fx1; x2 = fx2; x3 = fx3; x4 = fx4;
for( r = 0; r < rowsnum; r++, i+=4, longitude+=longitudeshift ) {
fy1 = sin(D3DXToRadian(longitude))*sin(D3DXToRadian(lattitude)); fy2 = sin(D3DXToRadian(longitude+longitudeshift))*sin(D3DXToRadian(lattitude)); fy3 = sin(D3DXToRadian(longitude+longitudeshift))*sin(D3DXToRadian(lattitude+lattitudeshift)); fy4 = sin(D3DXToRadian(longitude))*sin(D3DXToRadian(lattitude+lattitudeshift));
fz1 = cos(D3DXToRadian(longitude))*sin(D3DXToRadian(lattitude)); fz2 = cos(D3DXToRadian(longitude+longitudeshift))*sin(D3DXToRadian(lattitude)); fz3 = cos(D3DXToRadian(longitude+longitudeshift))*sin(D3DXToRadian(lattitude+lattitudeshift)); fz4 = cos(D3DXToRadian(longitude))*sin(D3DXToRadian(lattitude+lattitudeshift));
y1 = fy1; y2 = fy2; y3 = fy3; y4 = fy4;
z1 = fz1; z2 = fz2; z3 = fz3; z4 = fz4; // x y z pattern[i] = PlanetVertex(x1, y1, z1 , 0.0f, 1.0f); pattern[i+1] = PlanetVertex(x2, y2, z2 , 0.0f, 0.0f); pattern[i+2] = PlanetVertex(x3, y3, z3 , 1.0f, 0.0f); pattern[i+3] = PlanetVertex(x4, y4, z4 , 1.0f, 1.0f);
}
} _vb->Unlock();
//создание индексного буффера (*_pDev)->CreateIndexBuffer ( _numivertexes * sizeof(WORD), D3DUSAGE_DYNAMIC, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &_ib, NULL );
WORD* i; _ib->Lock(0,0,(void**)&i,0);
for(UINT q = 0,//счетчик цикла rsi = 0,//индекс m = 0; //значение q < segmentsnum; q++, rsi+=6, m+=4) { i[rsi] = m; i[rsi+1] = m+1; i[rsi+2] = m+2; i[rsi+3] = m+3; i[rsi+4] = m; i[rsi+5] = m+2; } _ib->Unlock();
return S_OK; }
//код рендеринга VOID PLANET::Draw() { //...//
(*_pDev)->SetFVF(PLANET_FVF); (*_pDev)->SetStreamSource(0,_vb,0,sizeof(PlanetVertex)); (*_pDev)->SetIndices(_ib); (*_pDev)->DrawIndexedPrimitive ( D3DPT_TRIANGLELIST, 0,0, _numivertexes,0, _numrendprimitives );
}
Я пока не беру в расчет такие вещи как радиус, точное кол-во сегментов.
При этой генерации возникают проблемы связанные с несколько неправильной работой z-буффера(в cull режиме CCW) Я полагаю это связано с неправильным алгоритмом(пофиксите если найдете ок?)
Вопрос: А для чего мне такая сфера ?
Мне нужна сфера-планета как в старой RTS Populous:The beginning , кто играл, тот знает, кто не играл – советую ознакомиться – незаслуженно забытый шедевр.
Хочу сделать нечто похожее на фан-римейк ^_^
Кто хочет присоединиться – icq 227929521. Принимаю всех, кто хоть что-то умеет.
PS:
Разумеется вы можете использовать этот простой код для процедурных генераций всего чего угодно..
А если поэксперементировать с параметрами синуса и косинуса выходит все что угодно –
от ленты мёбиуса до молекул ДНК..
|