Как правильно расположить камеру скайбокса с помощью openGL

Я создал скайбокс для своего проекта, и он выглядит так, как я хотел; Тем не менее, есть несколько проблем, которые я не могу понять, как исправить, и я прочитал некоторые учебники по этой теме, но я не смог найти то, что мне помогло бы.
Первая проблема заключается в том, что я не знаю, как заставить коробку всегда двигаться с моей камерой. На изображении ниже вы можете видеть, что я могу уменьшать и видеть всю коробку, вместо того, чтобы только увеличивать / уменьшать солнечную систему и всегда иметь звезды на заднем плане.

введите описание изображения здесь

Другая проблема, с которой я столкнулся, заключается в том, что когда я увеличиваю изображение слишком близко, мой фон исчезает.
введите описание изображения здесь

Я знаю, что если я смогу заставить камеру работать должным образом, я смогу это исправить, но это возвращает к моей первой проблеме. Я не знаю, как получить доступ к информации о камере.

Я считаю, что мне придется изменить glTranslatef() а также glScalef() в моем коде от фиксированного числа до числа, которое меняется в зависимости от положения камеры.
Вот мой код:

void Skybox::displaySkybox()
{

Images::RGBImage test[6]; //6 pictures for 6 sides
test[0]=Images::readImageFile(fileName); //Top
//test[1]=Images::readImageFile(fileName);//Back
//test[2]=Images::readImageFile(fileName);//Bottom
//test[3]=Images::readImageFile(fileName);//Right
//test[4]=Images::readImageFile(fileName); //Left
//test[5]=Images::readImageFile(fileName);  //Front

glEnable(GL_TEXTURE_2D);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
test[0].glTexImage2D(GL_TEXTURE_2D,0,GL_RGB);

// Save Current Matrix
glPushMatrix();

// Second Move the render space to the correct position (Translate)
glTranslatef(0,0,0);

// First apply scale matrix
glScalef(10000,10000,10000);

static const GLint faces[6][4] =
{
{5, 1, 2, 6}, // back
{5, 4, 0, 1}, // bottom
{0, 4, 7, 3}, // front
{4, 5, 6, 7}, // right ( 'left' in crinity's labeling )
{1, 0, 3, 2}, // left  ( 'right' in crinity's labeling )
{2, 3, 7, 6}  // top*/
};
GLfloat v[8][3];
GLint i;

v[0][0] = v[1][0] = v[2][0] = v[3][0] = -1;  // min x
v[4][0] = v[5][0] = v[6][0] = v[7][0] =  1;  // max x
v[0][1] = v[1][1] = v[4][1] = v[5][1] = -1;  // min y
v[2][1] = v[3][1] = v[6][1] = v[7][1] =  1;  // max y
v[0][2] = v[3][2] = v[4][2] = v[7][2] = -1;  // min z
v[1][2] = v[2][2] = v[5][2] = v[6][2] =  1;  // max z

for (i = 0; i < 7; i++)
{
//
glBegin(GL_QUADS);

glTexCoord2f(0,1);  glVertex3fv(&v[faces[i][0]][0]);
glTexCoord2f(1,1);  glVertex3fv(&v[faces[i][1]][0]);
glTexCoord2f(1,0);  glVertex3fv(&v[faces[i][2]][0]);
glTexCoord2f(0,0);  glVertex3fv(&v[faces[i][3]][0]);

glEnd();
}
// Load Saved Matrix
glPopMatrix();

}

Как я могу получить доступ к этим переменным? Есть ли в openGL функция, которая позаботится об этом?

2

Решение

Я считаю, что мне придется изменить glTranslatef () и glScalef () в моем коде с фиксированного числа на число, которое меняется в зависимости от положения камеры.

Вы близки, но есть более простое решение:

  1. Нарисуйте скайбокс сначала, прежде чем переводить камеру, чтобы вам не пришлось переводить коробку. Не забудьте очистить буфер глубины для каждого нового кадра (вы поймете, почему через секунду).

  2. Отключить запись в буфер глубины (вызов glDepthMask(GL_FALSE)). Это приведет к тому, что каждый объект, который вы рендерит, будет рисовать поверх него, заставляя его всегда появляться «позади» всего остального.

  3. Предполагая, что ваши матрицы преобразования были сброшены в начале кадра, примените только вращение камеры. Таким образом, камера всегда будет «центрирована» внутри коробки.

  4. Нарисуйте скайбокс. Поскольку запись в буфер глубины отключена, не имеет значения, насколько она мала, если она больше, чем ближняя плоскость клипа вашей камеры.

  5. Повторно включить запись в буфер глубины (вызов glDepthMask(GL_TRUE))

  6. Рендеринг вашей сцены нормально.

9

Другие решения

Я раньше не работал со скайбоксами, но было бы разумно, чтобы камера всегда была в центре коробки. Поэтому начните с перевода поля в центр вокруг координат камеры, что-то вроде glTranslate(camera.x, camera.y, camera.z);
Тогда я думаю, что поле должно оставаться бесконечно удаленным, поэтому, возможно, установите для вершин значение INT_MAX или что-то невероятно большое.

v[0][0] = v[1][0] = v[2][0] = v[3][0] = -INT_MAX;  // min x
v[4][0] = v[5][0] = v[6][0] = v[7][0] =  INT_MAX;  // max x ...etc

Тогда, вероятно, избавиться от вызова glScalef (). Попробуйте это

-2

По вопросам рекламы [email protected]