Открытые GL преобразования - PullRequest
0 голосов
/ 10 февраля 2012

У меня есть небольшое открытое приложение GL, которое я пишу на Java с использованием JOGL.

Я бьюсь головой о стену, пытаясь найти ТЕКУЩИЙ способ применения преобразований

По существуя пытаюсь сделать так, чтобы два объекта были рядом друг с другом.В основном я создаю объекты (методы, которые вычисляют все треугольники - я знаю, что это работает, потому что оба объекта обнаруживаются, они просто перекрывают друг друга), затем на экране я помещаю их в VBO и вызываю drawElements.Моя проблема в том, что я не могу найти в Интернете никаких примеров или учебных пособий, в которых НЕ используются glTranslatef, glRotatef и glScalef, которые, как мне сообщили, устарели и являются частью фиксированного аспекта функции старого открытого GL.

РЕДАКТИРОВАТЬ: (предыдущий код удален)

Epic fail от моего имени.Когда он сказал свой код шейдера, я подумал, что он имел в виду файл .java, который загружает и компилирует шейдер.Меня просто поразило, что он имел в виду КОД ШЕЙДЕРА, который был в файле glsl.Теперь я вижу, где у него есть 3 переменные mat4, которые содержат rx, ry и rz.Странно то, что даже если я настрою масштаб и переведу матрицу, мои фигуры больше не будут появляться.Матрицы вращения устанавливаются так, как можно было бы предположить, и последняя строка выглядит так: «glPosition = rz * ry * rx * vPosition;»Я также попытался объявить матрицы перевода и масштабирования, а затем выполнить «= s * t * rz * ry * rx * vPosition», но без кубиков.

Вот текущий код шейдера:

attribute vec4 vPosition;
uniform vec3 theta;
uniform vec3 trans;
uniform vec3 scale;

void main()
{
// Compute the sines and cosines of each rotation
// about each axis
vec3 angles = radians (theta);
vec3 c = cos (angles);
vec3 s = sin (angles);

// rotation matricies
mat4 rx = mat4 (1.0,  0.0,  0.0,  0.0, 
                0.0,  c.x,  s.x,  0.0,
                0.0, -s.x,  c.x,  0.0,
                0.0,  0.0,  0.0,  1.0);

mat4 ry = mat4 (c.y,  0.0, -s.y,  0.0, 
                0.0,  1.0,  0.0,  0.0,
                s.y,  0.0,  c.y,  0.0,
                0.0,  0.0,  0.0,  1.0);

mat4 rz = mat4 (c.z, -s.z,  0.0,  0.0, 
                s.z,  c.z,  0.0,  0.0,
                0.0,  0.0,  1.0,  0.0,
                0.0,  0.0,  0.0,  1.0);

//mat4 t = mat4 (1.0, 0.0, 0.0, trans.x, 
//               0.0, 1.0, 0.0, trans.y,
//               0.0, 0.0, 1.0, trans.z,
//               0.0, 0.0, 0.0, 1.0);

//mat4 s = mat4 (scale.x, 0.0, 0.0, 0.0, 
//               0.0, scale.y, 0.0, 0.0,
//               0.0, 0.0, scale.z, 0.0,
//               0.0, 0.0, 0.0, 1.0);

gl_Position = rz * ry * rx * vPosition;
//gl_Position = s * t * rz * ry * rx * vPosition;
}

По сути, если я раскомментирую две нижние матрицы, но оставлю оператор glPosition тем же, ничего не появится.Также закомментированный оператор glPosition не работал (хотя я не удивлен, я не слишком хорош в умножении матриц).Я также попытался сделать только s * vPosition, просто чтобы попробовать и только масштабировать, но опять ничего не видно.

Ответы [ 3 ]

1 голос
/ 10 февраля 2012

Похоже, ваш профессор хочет, чтобы вы использовали свою собственную матрицу через glLoadMatrix, а не через вызовы glTranslate и т. Д.

0 голосов
/ 10 февраля 2012

Между ссылкой datenwolf и несколькими другими ресурсами, которые я нашел, я смог написать (довольно скромный) класс матрицы для столбцов с мажорными столбцами для использования в моем назначении. Я публикую здесь источник на тот случай, если кто-нибудь еще посчитает его полезным.

import java.nio.FloatBuffer;

public class CGMatrix {

public CGMatrix() {
}

public static float[][] identity() {
    return new float[][]{{1.0f, 0, 0, 0}, 
            {0, 1.0f, 0, 0},
            {0, 0, 1.0f, 0},
            {0, 0, 0, 1.0f}};
}

public static float[][] rotateX(float angle) {
    double r = angle * (Math.PI / 180);
    float s = (float)Math.sin(r);
    float c = (float)Math.cos(r);
    return new float[][] {{1, 0, 0, 0},
                        {0, c, s, 0},
                        {0, -s, c, 0},
                        {0, 0, 0, 1}};
}

public static float[][] rotateY(float angle) {
    double r = angle * (Math.PI / 180);
    float s = (float)Math.sin(r);
    float c = (float)Math.cos(r);
    return new float[][] {{c, 0, s, 0},
                        {0, 1, 0, 0},
                        {-s, 0, c, 0},
                        {0, 0, 0, 1}};
}

public static float[][] rotateZ(float angle) {
    double r = angle * (Math.PI / 180);
    float s = (float)Math.sin(r);
    float c = (float)Math.cos(r);
    return new float[][] {{c, s, 0, 0},
                        {-s, c, 0, 0},
                        {0, 0, 1, 0},
                        {0, 0, 0, 1}};
}

public static float[][] scale(float sx, float sy, float sz) {
    float[][] m = identity();
    m[0][0] *= sx;
    m[1][1] *= sy;
    m[2][2] *= sz;
    return m;
}

public static float[][] translate(float tx, float ty, float tz) {
    float[][] m = identity();
    m[3][0] = tx;
    m[3][1] = ty;
    m[3][2] = tz;
    return m;
}

public static float[][] multiply(float [][] a, float[][] b) {
    float[][] m = identity();
    for(int j = 0; j < 4; ++j){
        for(int i = 0; i < 4; ++i) {
            m[i][j] = 0;
            for(int k = 0; k < 4; ++k) {
                m[i][j] += a[i][k]*b[k][j];
            }
        }
    }
    return m;
}

public static FloatBuffer buffer(float[][] m) {
    float[] n = new float[16];
    int k = 0;
    for(int j = 0; j < 4; ++j) {
        for(int i = 0; i < 4; ++i) {
            n[k] = m[j][i];
            k++;
        }
    }
    return FloatBuffer.wrap(n);

}

}

Поэтому в моем случае я настроил отдельные матрицы для перемещения, масштабирования и поворотов.

так что, если, например, я хотел перевести вдоль z, затем повернуть вдоль y, а затем масштабировать, я мог бы сделать:

    cgMatrix = gl2.glGetUniformLocation(shaderProgID, "cgMatrix");
    float[][] t = CGMatrix.translate(0, 0, 0.5f);
    float[][] s = CGMatrix.scale(1, 0.75f, 1);
    FloatBuffer m = CGMatrix.buffer(CGMatrix.multiply(t, CGMatrix.multiply(ry, s)));
    gl2.glUniformMatrix4fv(cgMatrix, 1, false, m);

Там, где преобразования происходят слева направо (т.е. сначала они переводятся, затем вращаются, затем масштабируются)

Во всяком случае, я надеюсь, что это может быть полезным для всех!

Спасибо за все ответы.

0 голосов
/ 10 февраля 2012

Вот текущий код шейдера:

[… code example …] 

Пожалуйста, не вычисляйте матрицы в шейдере.Если они являются константами, компилятор, вероятно, превратит их в константы, но это все еще очень негибко.Правильный способ сделать это - вычислить матрицы в вашей основной программе, а затем только передавать их в OpenGL как единообразные.Математика в целом очень проста.Для кодеров C я предоставляю https://github.com/datenwolf/linmath.h в свободном доступе.Это должно быть достаточно легко, чтобы перевести это на Java.

...