OpenGL: glLoadMatrix и буфер глубины

1

Другой вопрос с буфером глубины:

У меня матричная матрица - матричные компультации находятся на стороне OpenGL (glPushMatrix, вращение, получить матрицу из OpenGL, glPopMatrix), и при обновлении камеры я отправляю эти вычисленные элементы матрицы в OpenGL через glLoadMatrix. Все нормально (движение и вращение), но буфер глубины испорчен:

без glLoadMatrix (без движения/вращения):

Изображение 174551

с glLoadMatrix:

Изображение 174551

Я не понимаю, почему это происходит (если я перемещаю камеру по "классическим" тригонометрическим функциям, все в порядке).

public class Camera implements ICamera {
private final FloatBuffer matrix = BufferUtils.createFloatBuffer(16);

private final FloatBuffer buffer = BufferUtils.createFloatBuffer(16);

/**
 * absolutní pozice kamery v prostoru
 */
private final Vector3f position = new Vector3f();

/**
 * aktuální pohled kamery
 */
private final Vector3f look = new Vector3f();

/**
 * nastavení pozice kamery
 */
@Override
public void setPosition(Vector3f aPosition) {
    matrix.clear();
    matrix.put(0, 1.0f);
    matrix.put(5, 1.0f);
    matrix.put(10, -1.0f);
    matrix.put(15, 1.0f);
    matrix.put(12, aPosition.getX());
    matrix.put(13, aPosition.getY());
    matrix.put(14, aPosition.getZ());
    position.set(matrix.get(12), matrix.get(13), matrix.get(14));
}

/**
 * commonly called with move vector
 */
public void move(Vector3f aPosition) {
    matrix.clear();
    float x = aPosition.getX();
    float y = aPosition.getY();
    float z = aPosition.getZ();
    matrix.put(12, matrix.get(12) + x * matrix.get(0) + y * matrix.get(4) + z * matrix.get(8));
    matrix.put(13, matrix.get(13) + x * matrix.get(1) + y * matrix.get(5) + z * matrix.get(9));
    matrix.put(14, matrix.get(14) + x * matrix.get(2) + y * matrix.get(6) + z * matrix.get(10));
    position.set(matrix.get(12), matrix.get(13), matrix.get(14));
}

/**
 * nastaví směr pohledu na zadaný bod (slouží k otáčení kamery)
 */
public void look(Vector3f aTarget) {
    matrix.clear();
    // realne neovlivni scenu, pouze vyuziva OpenGL pro vypocty matic
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadMatrix(matrix);
    glRotatef(aTarget.getY(), 1, 0, 0);
    glGetFloat(GL_MODELVIEW_MATRIX, matrix);
    glRotatef(-aTarget.getX(), matrix.get(1), matrix.get(5), matrix.get(9));
    glGetFloat(GL_MODELVIEW_MATRIX, matrix);
    glPopMatrix();
    /**
     * - není potřeba normalizovat, poněvadž v matici už normalizovaný je
     * - 12, 13, 14 je pozice kamery, 8, 9, 10 je rotace kamery; výsledek dá absolutní vektor pohledu kamery
     */
    look.set(matrix.get(12) - matrix.get(8), matrix.get(13) - matrix.get(9), matrix.get(14) - matrix.get(10));
}

// this thing update camera rotation/position
@Override
public void tick(float aTick) {
    // nevypada to hezky, nicmene usetri to nejmene 1 volani navic
    float m00 = matrix.get(0);
    float m01 = matrix.get(1);
    float m02 = matrix.get(2);
    float m04 = matrix.get(4);
    float m05 = matrix.get(5);
    float m06 = matrix.get(6);
    float m08 = matrix.get(8);
    float m09 = matrix.get(9);
    float m10 = matrix.get(10);
    float m12 = matrix.get(12);
    float m13 = matrix.get(13);
    float m14 = matrix.get(14);
    buffer.put(0, m00);
    buffer.put(1, m04);
    buffer.put(2, m08);
    buffer.put(4, m01);
    buffer.put(5, m05);
    buffer.put(6, m09);
    buffer.put(8, m02);
    buffer.put(9, m06);
    buffer.put(10, m10);
    buffer.put(12, -(m00 * m12 + m01 * m13 + m02 * m14));
    buffer.put(13, -(m04 * m12 + m05 * m13 + m06 * m14));
    buffer.put(14, -(m08 * m12 + m09 * m13 + m10 * m14));
    buffer.rewind();
    glMatrixMode(GL_MODELVIEW);
    // this line is true devil: if I comment this out, it produce image [1], in this case produce image [2]
    glLoadMatrix(buffer);
    }
}
  • 0
    Почему вы пересчитываете часть матрицы в tick и почему не переносите всю матрицу?
  • 0
    Ой маан !! У тебя орлиный глаз! Я сделал небольшой тюнинг, и теперь все плохие призраки исчезли! Я положил buffer.put(matrix); после м14 и теперь все ок!
Теги:
lwjgl

1 ответ

1
Лучший ответ

Я изменил метод тика:

@Override
public void tick(float aTick) {
    float m01 = matrix.get(1);
    float m02 = matrix.get(2);
    float m04 = matrix.get(4);
    float m06 = matrix.get(6);
    float m08 = matrix.get(8);
    float m09 = matrix.get(9);
    float m12 = matrix.get(12);
    float m13 = matrix.get(13);
    float m14 = matrix.get(14);
    buffer.put(matrix);
    buffer.put(1, m04);
    buffer.put(2, m08);
    buffer.put(4, m01);
    buffer.put(6, m09);
    buffer.put(8, m02);
    buffer.put(9, m06);
    buffer.put(12, -(matrix.get(0) * m12 + m01 * m13 + m02 * m14));
    buffer.put(13, -(m04 * m12 + matrix.get(5) * m13 + m06 * m14));
    buffer.put(14, -(m08 * m12 + m09 * m13 + matrix.get(10) * m14));
    buffer.rewind();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glLoadMatrix(buffer);
}

Как указал Immibis - я не могу скопировать все значения matrix do buffer а плохим побочным эффектом были неправильные вычисления буфера глубины.

Сейчас все в порядке.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню