Линии произвольной толщины. Как?
От: CFA Россия  
Дата: 01.06.02 17:17
Оценка:
Собственно у меня такой трабл:
Надо через DirectX нарисовать линию заданной толщины. Всякие трюки типа GetDC не подходят.
Нужен алгоритм (или идея) как это сделать с нуля.
Вот
Я пишу — по ночам больше тем.
Re: Линии произвольной толщины. Как?
От: CFA Россия  
Дата: 04.06.02 14:48
Оценка:
Мне, типа, кто-нибудь поможет?
Я пишу — по ночам больше тем.
Re: Линии произвольной толщины. Как?
От: SiGMan / iO UpG Южная Корея www.ioupg.com
Дата: 04.06.02 23:09
Оценка: 4 (1)
Здравствуйте CFA, Вы писали:
Надо через DirectX нарисовать линию заданной толщины

Очень часто встречаемый вопрос, особенно среди пересаживыющихся с ОГЛ на ДХ :)
Итак... линии рисовать напрямую можно только стандартные — т.е. однопискельные...
Ну и еще железо должно держать линию как примитив, хотя современное вроде такой болезью и не страдает,
но иногда все же native примитив тормозит, по сравнению с теми же треугольниками.
Вывод: заменять рендеринг ( громко сказано :) линии двумя треугольниками, образующими полосу заданной ширины.
Фрагмент кода...


//////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 * Computes a screen quad aligned with a world segment.
 * \param  inverseview  [in] inverse view matrix
 * \param  view   [in] view matrix
 * \param  proj   [in] projection matrix
 * \param  verts   [out] 4 quad vertices in world space (forming a tri-strip)
 * \param  uvs    [out] 4 quad uvs
 * \param  stride   [in] size of vertex (FVF stride)
 * \param  p0    [in] segment's first point in world space
 * \param  p1    [in] segment's second point in world space
 * \param  size   [in] size of segment/quad
 * \param  constantsize [in] true to keep the quad's screen size constant (e.g. needed to emulate glLineWidth)
 */
//////////////////////////////////////////////////////////////////////////////////////////////////////////
void Renderer::ComputeScreenQuad(const ViewMatrix& inverseview, const ViewMatrix& view, const ProjMatrix& proj,
ubyte* verts, ubyte* uvs, udword stride, const Point& p0, const Point& p1, float size, bool constantsize)
{
 // Compute delta in camera space
 Point Delta; TransformPoint3x3(Delta, p1-p0, view);

 // Compute size factors
 float SizeP0 = size;
 float SizeP1 = size;

 if(constantsize)
 {
  // Compute scales so that screen-size is constant
  SizeP0 *= ComputeConstantScale(p0, view, proj);
  SizeP1 *= ComputeConstantScale(p1, view, proj);
 }

 // Compute quad vertices
 float Theta0 = atan2f(-Delta.x, -Delta.y);
 float c0 = SizeP0 * cosf(Theta0);
 float s0 = SizeP0 * sinf(Theta0);
 ComputePoint(*((Point*)verts),  c0, -s0, inverseview, p0); verts+=stride;
 ComputePoint(*((Point*)verts),  -c0, s0, inverseview, p0); verts+=stride;

 float Theta1 = atan2f(Delta.x, Delta.y);
 float c1 = SizeP1 * cosf(Theta1);
 float s1 = SizeP1 * sinf(Theta1);
 ComputePoint(*((Point*)verts),  -c1, s1, inverseview, p1); verts+=stride;
 ComputePoint(*((Point*)verts),  c1, -s1, inverseview, p1); verts+=stride;

 // Output uvs if needed
 if(uvs)
 {
  *((float*)uvs) = 0.0f; *((float*)(uvs+4)) = 1.0f; uvs+=stride;
  *((float*)uvs) = 0.0f; *((float*)(uvs+4)) = 0.0f; uvs+=stride;
  *((float*)uvs) = 1.0f; *((float*)(uvs+4)) = 1.0f; uvs+=stride;
  *((float*)uvs) = 1.0f; *((float*)(uvs+4)) = 0.0f; uvs+=stride;
 }
}

inline void ComputePoint(Point& dest, float x, float y, const Matrix4x4& rot, const Point& trans)
{
 dest.x = trans.x + x * rot.m[0][0] + y * rot.m[1][0];
 dest.y = trans.y + x * rot.m[0][1] + y * rot.m[1][1];
 dest.z = trans.z + x * rot.m[0][2] + y * rot.m[1][2];
}


And extra used functions:

// Quickly rotates a vector, using the 3x3 part of a 4x4 matrix
inline void TransformPoint3x3(Point& dest, const Point& source, const Matrix4x4& rot)
{
 dest.x = source.x * rot.m[0][0] + source.y * rot.m[1][0] + source.z * rot.m[2][0];
 dest.y = source.x * rot.m[0][1] + source.y * rot.m[1][1] + source.z * rot.m[2][1];
 dest.z = source.x * rot.m[0][2] + source.y * rot.m[1][2] + source.z * rot.m[2][2];
}

float Renderer::ComputeConstantScale(const Point& pos, const ViewMatrix& view, const ProjMatrix& proj)
{
 Point ppcam0 = pos * view;
 Point ppcam1 = ppcam0;
 ppcam1.x += 1.0f;

 float l1 = 1.0f/(ppcam0.x*proj.m[0][3] + ppcam0.y*proj.m[1][3] + ppcam0.z*proj.m[2][3] + proj.m[3][3]);
 float c1 =  (ppcam0.x*proj.m[0][0] + ppcam0.y*proj.m[1][0] + ppcam0.z*proj.m[2][0] + proj.m[3][0])*l1;
 float l2 = 1.0f/(ppcam1.x*proj.m[0][3] + ppcam1.y*proj.m[1][3] + ppcam1.z*proj.m[2][3] + proj.m[3][3]);
 float c2 =  (ppcam1.x*proj.m[0][0] + ppcam1.y*proj.m[1][0] + ppcam1.z*proj.m[2][0] + proj.m[3][0])*l2;
 float CorrectScale = 1.0f/(c2 - c1);
 return CorrectScale / float(mRenderWidth);
}
io /l、 
゙(゚、 。 7
 l、゙ ~ヽ
 じしf_, )ノ
Re[2]: Линии произвольной толщины. Как?
От: CFA Россия  
Дата: 06.06.02 11:25
Оценка:
Здравствуйте SiGMan / iO UpG, Вы писали:

S/IU>Вывод: заменять рендеринг ( громко сказано линии двумя треугольниками, образующими полосу заданной ширины.

Спасибо, но ситуация не совсем такая
Я использую библиотеку CDX и работаю с DirectDraw. Мне нужен адаптировать алгоритм построения по точкам для для рисования линии произвольной толщины.
В принципе я пришел к томуже выводу и написал ф-ю FillPoly(CPoint *points, int cnt) и рисуя закрашенный четерех угольник, но есть проблемы в местах стыковки отрезков.
Интересно есть другое решение проблемы?
Я пишу — по ночам больше тем.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.