Рекламные щиты OpenGL с фиксированным положением

#opengl #3d

#opengl #3D

Вопрос:

Я создаю дерево в opengl, и оно работает нормально..По сути, это 2d-дерево, поэтому я добавляю рекламные щиты… Я получаю проблему смещения, когда я перемещаю свою камеру, дерево перемещается со своего места на другую камеру.. Я пытаюсь сделать все, что знаю, чтобы исправить это, но безуспешно… Помогающий код из http://lighthouse3d.com/opengl/billboarding/billboardingtut.pdf

Можете ли вы мне помочь с этим?

Вот код рекламного щита

 void billboardCheatCylindricalBegin() {

    float modelview[16];
    int i, j;

    // save the current modelview matrix
    glPushMatrix();

    // get the current modelview matrix
    glGetFloatv(GL_MODELVIEW_MATRIX, modelview);

    for (i = 0; i < 3; i  = 2)
        for (j = 0; j < 3; j  ) {
            if (i == j)
                modelview[i * 4   j] = 1.0;
            else
                modelview[i * 4   j] = 0.0;
        }

    // set the modelview matrix
    glLoadMatrixf(modelview);
}

Tree(); //my tree call which works fine without billboard in 2d but moves with camera while using Billboard

void billboardEnd() {

    // restore the previously 
    // stored modelview matrix
    glPopMatrix();
}
  

Ответ №1:

Вам нужно изменить верхний левый 3×3 матрицы представления модели на идентификационную матрицу. Выполните итерацию i и j от 0 до < 3 и вычислите индекс поля by i * 4 j .
Вы неправильно увеличиваете i на 2 вместо 1 :

for (i = 0; i < 3; i = 2)

 for (i = 0; i < 3; i   )
  

Полный алгоритм

 glGetFloatv(GL_MODELVIEW_MATRIX, modelview);

for (i = 0; i < 3; i  )
{
    for (j = 0; j < 3; j  )
        modelview[i*4   j] = i == j ? 1.0f : 0.0f;
}

glLoadMatrixf(modelview);
  

Если матрица имеет компонент масштабирования, вам необходимо рассчитать коэффициенты масштабирования и задать диагональ с помощью коэффициентов масштабирования:

 float *m = modelview;
float scaleX = sqrt(m[0]*m[0]   m[1]*m[1]   m[2]*m[2]); 
float scaleY = sqrt(m[4]*m[4]   m[5]*m[5]   m[6]*m[6]);
float scaleZ = sqrt(m[8]*m[8]   m[9]*m[9]   m[10]*m[10]);

for (i = 0; i < 3; i  )
{
    for (j = 0; j < 3; j  )
        modelview[i*4   j] = 0.0f;
}

modelview[0] = scaleX;
modelview[5] = scaleY;
modelview[10] = scaleZ;
  

Комментарии:

1. @Struggler Что вы подразумеваете под «все еще идет смещение»? У вас есть масштабная матрица?

2. Я имею в виду, что это ни на что не влияет (все еще перемещается вдоль камеры)… Да, я масштабирую его с помощью glScalef, потому что после использования вашего кода он ложится на поверхность и такой тонкий..

3. @Struggler Убедитесь, что матрица проекции установлена на текущую GL_PROJECTION матрицу, а все остальные преобразования установлены на текущую GL_MODELVIEW матрицу (см. glMatrixMode ). Кроме того, вы должны учитывать масштаб — см. Ответ.

4. @Struggler Вы вызываете billboardCheatCylindricalBegin прямо перед glBegin и billboardEnd сразу после glEnd , не так ли?

5. Исправлено с помощью вашего кода, спасибо… Просто неправильное расположение glTranslatef на моем конце