Я работаю над созданием коробки, которую пользователь смотрит изнутри, коробки неба или чего-то в этом роде. Я делаю это, беря 6 квадратов и создавая куб с ними, а затем помещая теоретическую камеру в куб и текстурируя куб с помощью изображения. Пользователь может осмотреться с помощью мыши, и куб вращается, создавая впечатление, будто кто-то двигает головой. я столкнулся с проблемой появления белой линии на пересечении двух сторон, я попытался вытянуть четырехугольники, сохраняя размер фактических четырехугольников одинаковым. Я позаботился о том, чтобы чистый цвет был черным, и я все еще получаю белую линию.
Вот атрибуты, которые я установил:
glClearColor(0.0, 0.0, 0.0, 0.0);
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT);
glClearDepth(1);
//S is the side length of the cube
float s = 5;
glShadeModel(GL_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glHint(GL_POLYGON_SMOOTH, GL_NICEST);
glEnable(GL_POLYGON_SMOOTH);
glDisable(GL_COLOR_MATERIAL);
glDisable(GL_LIGHTING);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
Вот код, который создает куб:
float s = 5; //S is the side length of each quad
glNewList(m_cube, GL_COMPILE);
{
glPushMatrix();
{
glEnable(GL_TEXTURE_2D);
glPushMatrix();
{
glBegin(GL_QUADS);
{
//front
{
glTexCoord2f(0.5f, (1.0f / 3.0f));
// glColor3f(1, 0, 0);
glVertex3f(((s / 2.0f)), ((s / 2.0f)),
-((s / 2.0f))); //1
glTexCoord2f(0.25f, (1.0f / 3.0f));
// glColor3f(1, 1, 0);
glVertex3f(-((s / 2.0f)), ((s / 2.0f)),
-((s / 2.0f))); //2
glTexCoord2f(0.25f, (2.0f / 3.0f));
// glColor3f(1, 0, 1);
glVertex3f(-((s / 2.0f)), -((s / 2.0f)),
-((s / 2.0f))); //3
glTexCoord2f(0.5f, (2.0f / 3.0f));
// glColor3f(1, 1, 1);
glVertex3f(((s / 2.0f)), -((s / 2.0f)),
-((s / 2.0f))); //4
}
//left
{
glTexCoord2f(0.25f, (1.0f / 3.0f));
// glColor3f(1, 0, 0);
glVertex3f(-((s / 2.0f)), ((s / 2.0f)),
-((s / 2.0f))); //2
glTexCoord2f(0.0f, (1.0f / 3.0f));
// glColor3f(1, 1, 0);
glVertex3f(-((s / 2.0f)), ((s / 2.0f)),
((s / 2.0f))); //5
glTexCoord2f(0.0f, (2.0f / 3.0f));
// glColor3f(1, 0, 1);
glVertex3f(-((s / 2.0f)), -((s / 2.0f)),
((s / 2.0f))); //6
glTexCoord2f(0.25f, (2.0f / 3.0f));
// glColor3f(1, 1, 1);
glVertex3f(-((s / 2.0f)), -((s / 2.0f)),
-((s / 2.0f))); //3
}
//right
{
glTexCoord2f(0.75f, (1.0f / 3.0f));
// glColor3f(1, 0, 0);
glVertex3f(((s / 2.0f)), ((s / 2.0f)),
((s / 2.0f))); //7
glTexCoord2f(0.5f, (1.0f / 3.0f));
// glColor3f(1, 1, 0);
glVertex3f(((s / 2.0f)), ((s / 2.0f)),
-((s / 2.0f))); //1
glTexCoord2f(0.5f, (2.0f / 3.0f));
// glColor3f(1, 0, 1);
glVertex3f(((s / 2.0f)), -((s / 2.0f)),
-((s / 2.0f))); //4
glTexCoord2f(0.75f, (2.0f / 3.0f));
// glColor3f(1, 1, 1);
glVertex3f(((s / 2.0f)), -((s / 2.0f)),
((s / 2.0f))); //8
}
//back
{
glTexCoord2f(1.0f, (1.0f / 3.0f));
// glColor3f(1, 0, 0);
glVertex3f(-((s / 2.0f)), ((s / 2.0f)),
((s / 2.0f))); //5
glTexCoord2f(0.75f, (1.0f / 3.0f));
// glColor3f(1, 1, 0);
glVertex3f(((s / 2.0f)), ((s / 2.0f)),
((s / 2.0f))); //7
glTexCoord2f(0.75f, (2.0f / 3.0f));
// glColor3f(1, 0, 1);
glVertex3f(((s / 2.0f)), -((s / 2.0f)),
((s / 2.0f))); //8
glTexCoord2f(1.0f, (2.0f / 3.0f));
// glColor3f(1, 1, 1);
glVertex3f(-((s / 2.0f)), -((s / 2.0f)),
((s / 2.0f))); //6
}
//top
{
glTexCoord2f(.5f, 1.0f);
// glColor3f(1, 0, 0);
glVertex3f(((s / 2.0f)), -((s / 2.0f)),
((s / 2.0f))); //7
glTexCoord2f(0.25f, 1.0f);
// glColor3f(1, 1, 0);
glVertex3f(-((s / 2.0f)), -((s / 2.0f)),
((s / 2.0f))); //5
glTexCoord2f(0.25f, (2.0f / 3.0f));
// glColor3f(1, 0, 1);
glVertex3f(-((s / 2.0f)), -((s / 2.0f)),
-((s / 2.0f))); //2
glTexCoord2f(.5f, (2.0f / 3.0f));
// glColor3f(1, 1, 1);
glVertex3f(((s / 2.0f)), -((s / 2.0f)),
-((s / 2.0f))); //1
}
//bottom
{
glTexCoord2f(.5f, (1.0f / 3.0f));
// glColor3f(1, 0, 0);
glVertex3f(((s / 2.0f)), ((s / 2.0f)),
-((s / 2.0f))); //4
glTexCoord2f(0.25f, (1.0f / 3.0f));
// glColor3f(1, 1, 0);
glVertex3f(-((s / 2.0f)), ((s / 2.0f)),
-((s / 2.0f))); //3
glTexCoord2f(0.25f, 0.0f);
// glColor3f(1, 0, 1);
glVertex3f(-((s / 2.0f)), ((s / 2.0f)),
((s / 2.0f))); //6
glTexCoord2f(.5f, 0.0f);
// glColor3f(1, 1, 1);
glVertex3f(((s / 2.0f)), ((s / 2.0f)),
((s / 2.0f))); //8
}
}
glEnd();
}
glPopMatrix();
glDisable(GL_TEXTURE_2D);
}
glPopMatrix();
}
glEndList();
Вот код, который устанавливает камару:
float near_ = 1f;
float far_ = 10.0f;
float halfHeight = near_ * (Radian(m_fov)) / 2.0f;
float halfWidth = (static_cast<float>((m_width)) / static_cast<float>((m_height))) * halfHeight;
glViewport(0, 0, m_width, m_height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-halfWidth, halfWidth, -halfHeight, halfHeight, near_, far_);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Вот код, который отображается на экране:
void VideoStreamer::render()
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
float pitch = clamp(Degree(m_pitch), Degree(-(80.f)), Degree(80.f));
float yaw = wrap(m_yaw, Degree(0), Degree(360));
float roll = wrap(m_roll, Degree(0), Degree(360));
glPushMatrix();
{
glLineWidth(5);
glPushMatrix();
{
if (1)
{
glRotatef(pitch, 1.0, 0.0, 0.0);
glRotatef(yaw, 0.0, 1.0, 0.0);
glRotatef(roll, 0.0, 0.0, 1.0);
}
glCallList((m_cube));
}
glPopMatrix();
}
glPopMatrix();
SDL_GL_SwapBuffers();
}//end render
И вот снимок экрана с происходящим, обратите внимание на белую линию между синим и черным квадратами:
Вот текстура, которую я использую, с разрешением 600×450, но линия происходит в нескольких разрешениях:
Мой вопрос: как мне избавиться от этой белой линии?
РЕДАКТИРОВАТЬ: белые линии появляются только там, где верх и низ встречаются слева и справа
РЕДАКТИРОВАТЬ: обновленный код для отражения предложений
То, что вы видите, это просто то, что у вас действительно есть белый цвет в вашей текстуре. Таким образом, фрагменты, которые находятся на границе лица, в конечном итоге извлекаются из белой части (вы увидите это более четко, если вы включите линейный тип фильтра для вашей текстуры).
Что вы можете сделать, чтобы это исправить:
Я не могу дать вам эту картинку в комментариях, так что вы можете увеличить длину квадратов, оставив их на той же плоской высоте, как на этой картинке?
Какова была точность с плавающей точкой в вашем GPU?
float near_ = 0.00000001f;
Итак, вы уже попробовали:
Какие метод разделения экрана на подпространство ты используешь?
Предположение: ваша пунктирная линия может быть получена из Z-спасательное
Z-спасательное это явление в 3D-рендеринге, которое возникает, когда два или более примитива имеют одинаковые значения в z-буфере. Это особенно распространено в копланарных многоугольниках, где две грани занимают, по существу, одно и то же пространство, и ни одна впереди. Затронутые пиксели отображаются произвольно с фрагментами из одного или другого полигона способом, определяемым точностью Z-буфер. Это также может варьироваться по мере изменения сцены или камеры, в результате чего один полигон «выиграл» тест z, потом еще и тд. Общий эффект мерцающая, шумная растеризация двух полигонов, которые «борются» за цвета пикселей экрана. Эта проблема обычно вызвана ограниченным субпиксельная точность и с плавающей точкой и ошибки округления с фиксированной запятой.
Это похоже на сцинтилляцию, которая почти всегда вызвана ошибками округления. Размеры ваших квадроциклов выглядят вполне разумно, но ценность вашего ближнего самолета довольно мала. Это, вероятно, вызывает большие ошибки округления, когда вы умножаете вершины на матрицу MVP. Попробуйте установить ближний самолет к .1f
,
РЕДАКТИРОВАТЬ В противном случае проверьте код создания вершины на предмет возможной ошибки. Мне было немного трудно следовать — например, верхняя грань рассчитывается с использованием -((s / 2.0f)-.1),
— Почему вы вычитаете .1?
Возможно, написание новой функции для создания вершин и жесткого кодирования в значениях будет быстрым способом проверить, является ли это проблемой или нет.
Проблема заключалась в том, что у текстуры была утечка текстуры, которая получала цвета границ между сторонами. Моя математика была права по бокам и поместил текстуру текселей, но есть ошибки с плавающей точкой, которые я могу исправить.