JOGL应用正射投影问题

时间:2018-07-07 16:07:56

标签: java jogl opengl-3

我绘制了一个彩色的四边形,但是当我尝试应用正交投影时,我看不到它(我只看到空的绿色屏幕,仅使用模型矩阵就可以了)屏幕尺寸为500x500。类似的问题并没有帮助我找出解决方案(调整线的大小,替换四边形的顶点等)

public class BaseFrame implements GLEventListener
{
private int screenWidth;
private int screenHeight;
private Shader shader;
private OpenGlObject myObj;

public BaseFrame(Dimension dim){
    this.screenWidth = dim.width;
    this.screenHeight = dim.height;
}

public void init(GLAutoDrawable glAutoDrawable) {
    GL3 gl = glAutoDrawable.getGL().getGL3();

    //-----------------------SHADER TEST------------------------
    String[] vertexShaderSource = new String[1];
    vertexShaderSource[0] = "#version 330\n" +
            "layout(location=0) in vec2 position;\n" +
            "layout(location=1) in vec3 color;\n" +
            "out vec4 vColor;\n" +
            "uniform mat4 model;" +
            "uniform mat4 projection;" +
            "void main(void)\n" +
            "{\n" +
            "gl_Position = projection * model * vec4(position, 0.0, 1.0);\n" +
            "vColor = vec4(color, 1.0);\n" +
            "}\n";
    String[] fragmentShaderSource = new String[1];
    fragmentShaderSource[0] = "#version 330\n" +
            "in vec4 vColor;\n" +
            "out vec4 fColor;\n" +
            "void main(void)\n" +
            "{\n" +
            "fColor = vColor;\n" +
            "}\n";

    shader = new Shader(gl);
    shader.compile(vertexShaderSource,fragmentShaderSource,null);
    Mat4 projection = Matrices.ortho(0.0f, (float)screenWidth, (float)screenHeight,
            0.0f, -1.0f, 1.0f);
    System.out.println(projection.toString());
    shader.setMatrix4f("projection", projection, false);
    //--------------------------------------------------------

    gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
    gl.glClearColor(0.0f, 1.0f, 0.0f, 0.0f);

    myObj = new OpenGlObject( 2, 6, gl);
    myObj.initRenderData(new float[]{0.0f, 100f,
                                100f, 0.0f,
                                0.0f, 0.0f,
                                0.0f, 100f,
                                100f, 100f,
                                100f, 100f},
                        new float[]{0.1f, 0.2f, 0.3f,
                                0.6f, 0.5f, 0.4f,
                                0.0f, 0.0f, 0.0f,
                                2.0f, 1.0f, 3.0f,
                                0.0f, 0.0f, 0.0f,
                                0.7f, 0.8f, 0.9f});

    System.out.println(gl.glGetError() + " init end");
}

public void dispose(GLAutoDrawable glAutoDrawable) {

}

public void display(GLAutoDrawable glAutoDrawable) {
    GL3 gl = glAutoDrawable.getGL().getGL3();
    gl.glClear(GL3.GL_DEPTH_BUFFER_BIT | GL3.GL_COLOR_BUFFER_BIT);
    System.out.println(gl.glGetError() + " display0");

    System.out.println(gl.glGetError() + " display1");

    myObj.draw(0.0f, 0.0f, shader);
    System.out.println(gl.glGetError() + " display2");
}

public void reshape(GLAutoDrawable glAutoDrawable, int i, int i1, int i2, int i3) {

}
}

OpenGLObject

public class OpenGlObject {

private final GL3 gl;

private int buffersFilled;
private int buffersCount;
private int verticesCount;
private IntBuffer buffers;
private IntBuffer vertexArray;

private ArrayList<Integer> paramsCount;

//BufferParamsCount states for number of buffers the object will have (i.e. vertices, colors and etc.)
public OpenGlObject(int bufferParamsCount, int verticesCount, GL3 gl) {
    this.gl = gl;

    this.buffersFilled = 0;
    this.buffersCount = bufferParamsCount;
    this.verticesCount = verticesCount;
    this.buffers = IntBuffer.allocate(buffersCount);
    this.vertexArray = IntBuffer.allocate(1);

    this.paramsCount = new ArrayList<>();
}

public void initRenderData(float[]... dataArrays){
    addBuffers(dataArrays);
    genVertexArray();
}

public void addBuffers(float[]... dataArrays){
    gl.glGenBuffers(buffersCount,buffers);
    for(float[] fData : dataArrays) {
        FloatBuffer floatBuffer = FloatBuffer.wrap(fData);
        gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, this.buffers.get(buffersFilled++));
        gl.glBufferData(GL3.GL_ARRAY_BUFFER, 4 * fData.length, floatBuffer, GL3.GL_STATIC_DRAW);

        paramsCount.add(fData.length / this.verticesCount);
    }
    System.out.println(gl.glGetError() + " addBuffers");
}

private void genVertexArray(){
    gl.glGenVertexArrays(1, this.vertexArray);
    gl.glBindVertexArray(this.vertexArray.get(0));

    for(int i = 0; i < this.buffersFilled; i++){
        gl.glEnableVertexAttribArray(i);
        gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, buffers.get(i));
        gl.glVertexAttribPointer(i, this.paramsCount.get(i), GL.GL_FLOAT, false, 0, 0);
    }

    System.out.println(gl.glGetError() + " genVertexArray");
}

public void draw(float x, float y, Shader shader){
    shader.use();

    Mat4 model = Mat4.MAT4_IDENTITY;

    model = model.translate(new Vec3(x,y,0.0f));

    shader.setMatrix4f("model", model, false);
    System.out.println(gl.glGetError() + " draw0");

    gl.glBindVertexArray(this.vertexArray.get(0));
    gl.glDrawArrays(GL.GL_TRIANGLES, 0, this.verticesCount);
    System.out.println(gl.glGetError() + " draw1");
}

}

正交矩阵实现

public static final Mat4 ortho(float left, float right, float bottom, float top, float zNear, float zFar) {
    float m00 = 2.0F / (right - left);
    float m11 = 2.0F / (top - bottom);
    float m22 = -2.0F / (zFar - zNear);
    float m30 = -(right + left) / (right - left);
    float m31 = -(top + bottom) / (top - bottom);
    float m32 = -(zFar + zNear) / (zFar - zNear);
    return new Mat4(m00, 0.0F, 0.0F, 0.0F, 0.0F, m11, 0.0F, 0.0F, 0.0F, 0.0F, m22, 0.0F, m30, m31, m32, 1.0F);
}

1 个答案:

答案 0 :(得分:0)

问题是我在初始化函数的范围内声明了Mat4 projection。正确的做法是在绘制之前(在display函数中)将矩阵传递给着色器。

public void display(GLAutoDrawable glAutoDrawable) {
    GL3 gl = glAutoDrawable.getGL().getGL3();
    gl.glClear(GL3.GL_DEPTH_BUFFER_BIT | GL3.GL_COLOR_BUFFER_BIT);

    Mat4 projection = Matrices.ortho(0.0f, (float)screenWidth, (float)screenHeight,
            0.0f, 0.0f, 1.0f);
    shader.setMatrix4f("projection", projection, false);

    myObj.draw(5.0f, 5.0f, 100f, 100f, 0.0f, shader);
}

OpenGLObject的绘制函数也进行了更改,以便能够进行大小调整和旋转

public void draw(float x, float y, float xSize, float ySize, float rotationAngle, Shader shader){
    shader.use();

    Mat4 model = Mat4.MAT4_IDENTITY;
    Mat4 rotation = Matrices.rotate(rotationAngle, new Vec3(0.0f,0.0f,1.0f));
    Mat4 scale = new Mat4(xSize, 0.0f, 0.0f, 0.0f,
            0.0f, ySize, 0.0f, 0.0f,
            0.0f, 0.0f, 1.0f, 0.0f,
            0.0f, 0.0f, 0.0f, 1.0f);


    model = model.translate(new Vec3(x,y,0.0f));
    model = model.translate(new Vec3(0.5f * xSize, 0.5f * ySize, 0.0f));
    model = model.multiply(rotation);
    model = model.translate(new Vec3(-0.5f * xSize, -0.5f * ySize, 0.0f));

    model = model.multiply(scale);

    shader.setMatrix4f("model", model, false);
    System.out.println(gl.glGetError() + " draw0");

    gl.glBindVertexArray(this.vertexArray.get(0));
    gl.glDrawArrays(GL.GL_TRIANGLES, 0, this.verticesCount);
    System.out.println(gl.glGetError() + " draw1");
}