Как сохранить объект всегда перед всем остальным в OpenGL? - PullRequest
6 голосов
/ 03 апреля 2011

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

Например, я нарисовал плоскую местность на земле, в плоскости XZ при Y = 0. Камера установлена ​​на Y = 1,75 (для имитации среднего роста человека). Если я смотрю вверх, он работает нормально, если я смотрю вниз, его обрезает плоскость земли.

Глядя вверх: http://i.stack.imgur.com/Q0i6g.png
Глядя вниз: http://i.stack.imgur.com/D5LIx.png

Функция, которую я вызываю для рисования системы осей в углу, такова:

void Axis3D::DrawCameraAxisSystem(float radius, float height, const Vector3D rotation) {
    if(vpHeight == 0) vpHeight = 1;

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glViewport(0, 0, vpWidth, vpHeight);
    gluPerspective(45.0f, 1.0 * vpWidth / vpHeight, 1.0f, 5.0f);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glTranslatef(0.0f, 0.0f, -3.0f);

    glRotatef(-rotation.x, 1.0f, 0.0f, 0.0f);
    glRotatef(-rotation.y, 0.0f, 1.0f, 0.0f);

    DrawAxisSystem(radius, height);
}

Теперь пара основных функций, которые, я думаю, имеют отношение к проблеме:

glutDisplayFunc(renderScene);
glutReshapeFunc(changeSize);

void changeSize(int width, int height) {
    if(height == 0) height = 1;

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    glViewport(0, 0, width, height);

    gluPerspective(60.0f, 1.0 * width / height, 1.0f, 1000.0f);

    glMatrixMode(GL_MODELVIEW);
}

void renderScene(void) {
    glClearColor(0.7f, 0.7f, 0.7f, 0.0f);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    changeSize(glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT));

    glLoadIdentity();

    SceneCamera.Move(CameraDirection, elapsedTime);
    SceneCamera.LookAt();

    SceneAxis.DrawCameraAxisSystem(0.03f, 0.8f, SceneCamera.GetRotationAngles());

    glutSwapBuffers();
}

Предложения

Ответы [ 5 ]

15 голосов
/ 03 апреля 2011

Вместо того, чтобы отключить тестирование глубины, вы можете просто glClear(GL_DEPTH_BUFFER_BIT);, прежде чем рендерить свое наложение. Тогда всякая информация о глубине исчезла, но все пиксели остались. Тем не менее, ваш оверлей по-прежнему будет отображаться соответствующим образом.

3 голосов
/ 03 марта 2015

Вы также можете зарезервировать чуть-чуть диапазона глубины для вашей трехмерной оси.И все остальное для вашей сцены.Как это:

// reserve 1% of the front depth range for the 3D axis
glDepthRange(0, 0.01);

Draw3DAxis();

// reserve 99% of the back depth range for the 3D axis
glDepthRange(0.01, 1.0);

DrawScene();

// restore depth range
glDepthRange(0, 1.0);
0 голосов
/ 25 марта 2015

`glGetBooleanv (GL_BLEND, & m_origin_blend);

glGetBooleanv (GL_DEPTH_TEST, & m_origin_depth);

glGetBooleanv (GL_CULL_FACE * 100 * 100)*

setDepthTest (false);

setCullFace (false);// по камню

// ваша ничья () ...

setAlphaBlending (m_origin_blend> 0? true: false);

setDepthTest (m_origin_depth> 0? true:false);

setCullFace (m_origin_cull> 0? true: false); `

0 голосов
/ 03 апреля 2011

Вы можете попробовать включить смешивание, а затем вручную установить альфа и цвет в фрагментном шейдере. Но это может быть излишним; -)

0 голосов
/ 03 апреля 2011

Вы хотите отключить тестирование глубины (чтобы оно не было обрезано ничем):

glDisable(GL_DEPTH_TEST);

и, если вы предварительно преобразовали точки (у вас их нет), установите види проекционные матрицы на единицу.

Редактировать:

Если вам нужно, чтобы бит оси оставался проверенным и в порядке, то вы, вероятно, захотите очистить буфер глубины.(glClear(GL_DEPTH_BUFFER_BIT)) между рендерингом и вашей главной сценой.Это приведет к сбросу буфера глубины, так что маркер будет отображаться (и будет отображаться спереди), но все равно будет правильно отбракован.

...