使用Buffer显示JOGL

时间:2015-12-01 20:21:40

标签: java opengl jogl

我有3个FloatBuffers - 顶点,法线和颜色,其中包含了名称所暗示的内容。我还有一个IntBuffer来跟踪索引。

数据看起来正确,但我在显示时遇到问题。我只看到一块空白画布。我不确定我做错了什么。我在init()display()reshape()dispose()中猜测某些内容被忽略了。任何人都可以告诉我,如果你在下面的代码中发现了一些明显的错误,为什么你认为什么都没有显示?

  @Override
  public void init(GLAutoDrawable drawable) {
    GL2 gl = drawable.getGL().getGL2();
    gl.glClearColor(.0f, .0f, .2f, 0.9f);
    gl.glEnable(GL2.GL_DEPTH_TEST);
    gl.glDepthFunc(GL2.GL_LESS);
    gl.glEnable(GL2.GL_CULL_FACE);
    gl.glEnable(GL2.GL_LIGHTING);
    gl.glEnable(GL2.GL_LIGHT0);
    gl.glEnable(GL2.GL_AUTO_NORMAL);
    gl.glEnable(GL2.GL_NORMALIZE);
    gl.glFrontFace(GL2.GL_CCW);
    gl.glCullFace(GL2.GL_BACK);
    gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST);
    gl.glShadeModel(GL2.GL_SMOOTH);
    if (viewMesh) {
        gl.glPolygonMode(GL2.GL_FRONT_AND_BACK, GL2.GL_LINE);
    } else {
        gl.glPolygonMode(GL2.GL_FRONT_AND_BACK, GL2.GL_FILL);
    }

    glu = new GLU();

    // Build the VBOs
    VBO = IntBuffer.allocate(4);
    gl.glGenBuffers(4, VBO);
    vertVBOID = VBO.get(0);
    normalVBOID = VBO.get(1);
    colorVBOID = VBO.get(2);
    indexVBOID = VBO.get(3);

    // vertices
    int vsize = sd.verts.capacity() * BufferUtil.SIZEOF_FLOAT;
    gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, vertVBOID); // get a valid name
    gl.glBufferData(GL2.GL_ARRAY_BUFFER, vsize, sd.verts, GL2.GL_STATIC_DRAW);
    gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0); // reset

    // normals
    int nsize = sd.normals.capacity() * BufferUtil.SIZEOF_FLOAT;
    gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, normalVBOID);
    gl.glBufferData(GL2.GL_ARRAY_BUFFER, nsize, sd.normals, GL2.GL_STATIC_DRAW);
    gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0);

    // colors
    int csize = sd.colors.capacity() * BufferUtil.SIZEOF_FLOAT;
    gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, colorVBOID);
    gl.glBufferData(GL2.GL_ARRAY_BUFFER, csize, sd.colors, GL2.GL_STATIC_DRAW);
    gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0);

    int isize = sd.indices.capacity() * BufferUtil.SIZEOF_INT;
    gl.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, indexVBOID);
    gl.glBufferData(GL2.GL_ELEMENT_ARRAY_BUFFER, isize, sd.indices, GL2.GL_STATIC_DRAW);
    gl.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, 0);

    // sd.verts = null; // copy of data is no longer necessary, it is in the graphics card now.
    // sd.colors = null;
    // sd.normals = null;
    // sd.indices = null;
} 

@Override
public void display(GLAutoDrawable drawable) {
    GL2 gl = drawable.getGL().getGL2();
    gl.glMatrixMode(GL2.GL_MODELVIEW);
    gl.glLoadIdentity();
    glu.gluLookAt(45, 0, 0, 0, 0, 0, 0.0, 1.0, 0.0);

    gl.glScalef(scale, scale, scale);
    gl.glRotatef(rot, 0, 1, 0);
    gl.glTranslatef(-sd.tr_x, -sd.tr_y, -sd.tr_z);

        gl.glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
    gl.glEnableClientState(GLPointerFunc.GL_NORMAL_ARRAY);
    gl.glEnableClientState(GLPointerFunc.GL_COLOR_ARRAY);

    gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, normalVBOID);
    gl.glNormalPointer(GL2.GL_FLOAT, 0, 0);
    gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, colorVBOID);
    gl.glColorPointer(3, GL2.GL_FLOAT, 0, 0);
    gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, vertVBOID);
    gl.glVertexPointer(3, GL2.GL_FLOAT, 0, 0);

    gl.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, indexVBOID);
    gl.glDrawElements(GL2.GL_TRIANGLES, sd.indices.capacity(), GL2.GL_INT, 0);
    gl.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, 0); // unbind it

    gl.glDisableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
    gl.glDisableClientState(GLPointerFunc.GL_NORMAL_ARRAY);
    gl.glDisableClientState(GLPointerFunc.GL_COLOR_ARRAY);

}   

    @Override
public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) {
    GL2 gl = drawable.getGL().getGL2();
    double fov = (Math.PI / 4.0);
    double zmm = Math.abs(sd.min_z - sd.max_z);
    camdist = (zmm / 2.0) / Math.tan(fov / 2.0);

    h = (h == 0) ? 1 : h;

    gl.glViewport(0, 0, w, h);
    gl.glMatrixMode(GL2.GL_PROJECTION);
    gl.glLoadIdentity();
    glu.gluPerspective(camdist, w / (float) h, 0.1f, 1000.0);
}




    /**
 * Initilaize graphics
 */
public void initOGL() {
    profile = GLProfile.get(GLProfile.GL2);
    caps = new GLCapabilities(profile);
    caps.setHardwareAccelerated(true);
    canvas = new GLCanvas(caps);
    canvas.addGLEventListener(this);
    canvas.requestFocusInWindow();
    getContentPane().add(canvas); // add to the frame
}


    @Override
public void dispose(GLAutoDrawable drawable) {
}

1 个答案:

答案 0 :(得分:2)

一个明显的问题在于平局调用:

gl.glDrawElements(GL2.GL_TRIANGLES, sd.indices.capacity(), GL2.GL_INT, 0);

GL_INTglDrawElements()类型参数无效。唯一有效的值为GL_UNSIGNED_BYTEGL_UNSIGNED_SHORTGL_UNSIGNED_INT。所以电话需要是:

gl.glDrawElements(GL2.GL_TRIANGLES, sd.indices.capacity(), GL2.GL_UNSIGNED_INT, 0);

如果您遇到OpenGL代码无法正常工作的问题,请务必致电glGetError()。通过代码调用,您应立即收到GL_INVALID_ENUM错误。

此外,您的透视设置代码看起来有点可疑。我不完全明白你在那里做的是什么,但即使只是命名也暗示了一个可能的误解:

glu.gluPerspective(camdist, w / (float) h, 0.1f, 1000.0);

gluPerspective()的第一个参数是视野角度(以度为单位),而不是距离。