打开GL转换

时间:2012-02-09 21:56:11

标签: java opengl graphics transformation

我有一个小型的开放式GL应用程序,我正在使用JOGL编写Java。

我正试图找到应用转换的CURRENT方法,而不是靠墙试图

基本上我要做的就是让两个物体彼此相邻。基本上我创建对象(计算所有三角形的方法 - 我知道这是有效的,因为两个对象都显示出来,它们只是相互重叠),然后在显示中我将它们放在VBO中并调用drawElements。我的问题是我无法在网上找到任何不使用glTranslatef,glRotatef和glScalef的示例或教程,我已经被告知它已经过时并且曾经是旧开放GL的固定功能方面的一部分

编辑:(以前的代码已删除)

史诗失败代表我。当他说他的着色器代码时,我认为他是指加载和编译着色器的.java文件。它只是打击了我,他的意思是SHADER CODE,它是一个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 个答案:

答案 0 :(得分:1)

听起来你的教授希望你通过glLoadMatrix以及glTranslate等来调用你自己的矩阵。

答案 1 :(得分:0)

  

以下是当前着色器代码:

[… code example …] 

请不要在着色器中计算矩阵。如果它们是常量,编译器可能会将它们变成常量,但它仍然非常不灵活。正确的方法是计算主程序中的矩阵,然后只将它们作为统一传递给OpenGL。整个矩阵数学的东西很简单。对于C编码员,我在公共领域提供https://github.com/datenwolf/linmath.h。将它转换为Java应该很容易。

答案 2 :(得分:0)

在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);

转换从左到右发生(即首先转换,然后旋转,然后缩放)

无论如何,我希望这对任何人都有帮助!

感谢所有回复。