2013-11-15 17 views
6

Tôi đang cố gắng tái tạo this JOGL demo, bản trình diễn Java về cách sử dụng OpenGL ES 2.0, trong Scala. Biên dịch thành công, nhưng cố gắng thực hiện điều này sẽ cho ra kết quả sau:Odd NullPointerException khi tái tạo bản trình diễn Java OpenGL ES 2.0 trong Scala

Main() called 
libEGL warning: DRI2: failed to authenticate 
Chosen GL capabilities: GLCaps[glx vid 0xae, fbc 0x17a: rgba 8/8/8/8, 
trans-rgba 0xff/ff/ff/ff, accum-rgba 16/16/16/16, dp/st/ms 24/0/0, dbl, mono , hw,  
GLProfile[GL2ES2/GL3.hw], on-scr[.]] 
INIT GL IS: jogamp.opengl.gl4.GL4bcImpl 
GL_VENDOR: NVIDIA Corporation 
GL_RENDERER: GeForce GTX 260/PCIe/SSE2 
GL_VERSION: 3.3.0 NVIDIA 304.88 

vertex Shader successfully compiled! 
fragment Shader successfully compiled! 
Exception in thread "main-Display-.x11_:0.0-1-EDT-1" java.lang.NullPointerException 
at jogamp.newt.driver.x11.DisplayDriver.dispatchMessagesNative(DisplayDriver.java:103) 
at jogamp.newt.DisplayImpl.dispatchMessages(DisplayImpl.java:540) 
at jogamp.newt.DisplayImpl$5.run(DisplayImpl.java:463) 
at jogamp.newt.DefaultEDTUtil$NEDT.run(DefaultEDTUtil.java:326) 
X11Util.Display: Shutdown (JVM shutdown: true, open (no close attempt): 2/2, reusable 
(open, marked uncloseable): 0, pending (open in creation order): 2) 
X11Util: Open X11 Display Connections: 2 
X11Util: Open[0]: NamedX11Display[:0.0, 0x7da0cab0, refCount 1, unCloseable false] 
X11Util: Open[1]: NamedX11Display[:0.0, 0x7da1bea8, refCount 1, unCloseable false] 

Thành công có thể hiển thị 1 hoặc một vài khung trước khi ngoại lệ tăng lên. Và sự xuất hiện không xuất hiện khi tôi chạy nó từ trình gỡ lỗi jswat.

Tôi có thiếu thứ gì đó thực sự rõ ràng không? Có ai khác gặp phải vấn đề tương tự với Scala và OpenGL ES 2.0 không?

Tôi đang sử dụng Linux Mint 13 và Ant để biên dịch và chạy mã. Mã Scala của tôi là:

import javax.media.opengl.GL; 
import javax.media.opengl.GL2ES2; 
import javax.media.opengl.GLAutoDrawable; 
import javax.media.opengl.GLEventListener; 
import javax.media.opengl.GLProfile; 
import javax.media.opengl.GLCapabilities; 

import com.jogamp.newt.opengl.GLWindow; 
import com.jogamp.opengl.util._; 
import com.jogamp.common.nio.Buffers; 

import java.nio.FloatBuffer; 

// explicitly enabling postifx length operator: 
import scala.language.postfixOps; 

object RectangleDisplayer extends GLEventListener { 
    val vertexShaderCode : Array[String] = 
Array("#if __VERSION__ >= 130\n", 
" #define attribute in\n", 
" #define varying out\n", 
"#endif\n", 

"#ifdef GL_ES\n", 
"precision mediump float; \n", 
"precision mediump int; \n", 
"#endif \n", 

"uniform mat4 uniform_Projection; \n", 
"attribute vec4 attribute_Position;\n", 
"attribute vec4 attribute_Color;\n", 

"varying vec4 varying_Color;\n", 

"void main(void)\n", 
"{\n", 
" varying_Color = attribute_Color;\n", 
" gl_Position = uniform_Projection * attribute_Position;\n", 
"}\n") 

    val fragmentShaderCode : Array[String] = 
Array("#if __VERSION__ >= 130\n", 
" #define varying in\n", 
" out vec4 mgl_FragColor;\n", 
" #define texture2D texture\n", 
" #define gl_FragColor mgl_FragColor\n", 
"#endif\n", 

"#ifdef GL_ES\n", 
"precision mediump float;\n", 
"precision mediump int;\n", 
"#endif\n", 

"varying vec4 varying_Color; \n", 

"void main(void)\n", 
"{\n", 
" gl_FragColor = varying_Color;\n", 
"}\n") 

    var width : Int = 640 
    var height : Int = 480 

    // Scheinbar müssen in Scala alle Variablen zu Beginn initialisiert sein 
    var shaderProgram : Int = 0 
    var vertexShader : Int = 0 
    var fragmentShader : Int = 0 

    var vboHandles : Array[Int] = new Array[Int](2) 
    var vboVertices : Int = 0 
    var vboColors : Int = 0 

    var ModelViewProjectionMatrix_location : Int = 0 


    def compileShaderIntoProgram(gl : GL2ES2, theShader : Int, shaderCode : Array[String]):Unit = { 
    /*println("Shader code") 
    for (l <- shaderCode) { 
     print(l) 
    }*/ 
    val lengths = shaderCode map(_ length) 
    gl.glShaderSource(theShader, shaderCode.length, shaderCode, lengths, 0) 
    gl.glCompileShader(theShader) 
    } 

    def checkCompileStatus(gl : GL2ES2, theShader: Int, which : Int):Unit = { 
    var compiled : Array[Int] = Array(1) 
    gl.glGetShaderiv(theShader, GL2ES2.GL_COMPILE_STATUS, compiled, 0) 

    var shaderType : String = "vertex" 
    if (which == 1) { 
     shaderType = "fragment" 
    } 

    if (compiled(0) != 0) { 
     println(shaderType + " Shader successfully compiled!") 
    } else { 
     var logLength = new Array[Int](1) 
     var returnedLogLength = new Array[Int](1) 

     gl.glGetShaderiv(theShader, GL2ES2.GL_INFO_LOG_LENGTH, logLength, 0) 

     var log : Array[Byte] = new Array[Byte](logLength(0)) 
     gl.glGetShaderInfoLog(theShader, logLength(0), returnedLogLength, 0, log, 0) 

     println("Error compiling "+shaderType+" shader:") 
     println(new String(log)) 

     System.exit(1) 
    } 
    } 

    override def init(drawable : GLAutoDrawable):Unit = { 
    val gl : GL2ES2 = drawable.getGL().getGL2ES2() 

    println("Chosen GL capabilities: " + drawable.getChosenGLCapabilities()) 
    println("INIT GL IS: " + gl.getClass().getName()) 
    println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR)) 
    println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER)) 
    println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION)) 

    // create, compile and attach shaders 
    vertexShader = gl.glCreateShader(GL2ES2.GL_VERTEX_SHADER) 
    fragmentShader = gl.glCreateShader(GL2ES2.GL_FRAGMENT_SHADER) 

    compileShaderIntoProgram(gl, vertexShader, vertexShaderCode) 
    checkCompileStatus(gl, vertexShader, 0) 

    compileShaderIntoProgram(gl, fragmentShader, fragmentShaderCode) 
    checkCompileStatus(gl, fragmentShader, 1) 

    shaderProgram = gl.glCreateProgram() 
    gl.glAttachShader(shaderProgram, vertexShader) 
    gl.glAttachShader(shaderProgram, fragmentShader) 

    // Associate attribute ids with the attribute names inside the (vertex) shader 
    gl.glBindAttribLocation(shaderProgram, 0, "attribute_Position") 
    gl.glBindAttribLocation(shaderProgram, 1, "attribute_Color") 

    gl.glLinkProgram(shaderProgram) 

    ModelViewProjectionMatrix_location = gl.glGetUniformLocation(shaderProgram, "uniform_Projection") 

    // forward compatibility with ES 3 by creating and binding a "Vertex Buffer Object" 
    gl.glGenBuffers(2, vboHandles, 0) 
    vboColors = vboHandles(0) 
    vboVertices = vboHandles(1) 
    } 

    override def display(drawable : GLAutoDrawable):Unit = { 
    val gl : GL2ES2 = drawable.getGL().getGL2ES2() 

    gl.glClearColor(0.0f, 0.0f, 1.0f, 1.0f) 
    gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT) 

    gl.glUseProgram(shaderProgram) 

    // Define projection matrix 
    val model_view_projection : Array[Float] = 
     Array(1.0f, 0.0f, 0.0f, 0.0f, 
      0.0f, 1.0f, 0.0f, 0.0f, 
      0.0f, 0.0f, 1.0f, -1.0f, 
      0.0f, 0.0f, 0.0f, 1.0f) 

    gl.glUniformMatrix4fv(ModelViewProjectionMatrix_location, 1, false, model_view_projection, 0) 

    // Define Vertex buffer 
    val vertices : Array[Float] = Array(0.0f, 1.0f, 0.0f, 
             -1.0f, -1.0f, 0.0f, 
             1.0f, -1.0f, 0.0f) 

    var fbVertices : FloatBuffer = Buffers.newDirectFloatBuffer(vertices) 
    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboVertices) 

    var numBytes : Int = vertices.length*4 
    gl.glBufferData(GL.GL_ARRAY_BUFFER, numBytes, fbVertices, GL.GL_STATIC_DRAW) 
    fbVertices = null 

    // Associate vertex attribute 0 with the last bound VBO 
    gl.glVertexAttribPointer(0, // the vertex attribute 
           3, GL.GL_FLOAT, 
           false, // normalized? 
           0, // stride 
           0 // The bound VBO data offset 
          ) 
    gl.glEnableVertexAttribArray(0) 


    // Define color buffer 
    val colors : Array[Float] = Array(1.0f, 0.0f, 0.0f, 1.0f, 
             0.0f, 0.0f, 0.0f, 1.0f, 
             1.0f, 1.0f, 0.0f, 0.9f) 
    var fbColors : FloatBuffer = Buffers.newDirectFloatBuffer(colors) 
    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboColors) 
    numBytes = colors.length*4 
    gl.glBufferData(GL.GL_ARRAY_BUFFER, numBytes, fbColors, GL.GL_STATIC_DRAW) 
    fbColors = null 

    // Associate vertex attribute 1 with the last bound VBO 
    gl.glVertexAttribPointer(1, 4, // four positions used for each vertex 
          GL.GL_FLOAT, false, // normalized? 
          0, // stride 
          0 // the bound VBO data offset 
          ) 
    gl.glEnableVertexAttribArray(1) 

    gl.glDrawArrays(GL.GL_TRIANGLES, 0, 3) 

    gl.glDisableVertexAttribArray(0) 
    gl.glDisableVertexAttribArray(1) 

    gl.glDeleteBuffers(2, vboHandles, 0) 
    } 

    override def reshape(drawable : GLAutoDrawable, 
    x: Int, y: Int, z: Int, h: Int):Unit = { 
     width = z 
     height = h 

     val gl : GL2ES2 = drawable.getGL().getGL2ES2() 

     gl.glViewport(0, 0, width, height) 
    } 

    override def dispose(drawable : GLAutoDrawable):Unit = { 
    println("cleanup operations, disposing and detaching shaders") 
    val gl : GL2ES2 = drawable.getGL().getGL2ES2() 

    gl.glUseProgram(0) 
    gl.glDetachShader(shaderProgram, vertexShader) 
    gl.glDeleteShader(vertexShader) 
    gl.glDetachShader(shaderProgram, fragmentShader) 
    gl.glDeleteShader(fragmentShader) 

    gl.glDeleteProgram(shaderProgram) 
    System.exit(0) 
    } 

    def main(args: Array[String]): Unit = { 
    println("Main() called") 

    val caps : GLCapabilities = new GLCapabilities(GLProfile.get(GLProfile.GL2ES2)) 
    caps.setBackgroundOpaque(false) 
    var glWindow : GLWindow = GLWindow.create(caps) 

    // setup window parameters 
    glWindow.setTitle("Scala GL ES test") 
    glWindow.setSize(width, height) 
    glWindow.setUndecorated(false) 
    glWindow.setPointerVisible(true) 
    glWindow.setVisible(true) 

    // add this class as event listener to the window 
    glWindow.addGLEventListener(this) 
    var animator: Animator = new Animator() 
    animator.add(glWindow) 
    animator.start() 
    } 
} 
+0

Bạn thực sự cần phải thêm một số ghi nhật ký khác để giúp thu hẹp những gì có thể gây ra NPE thay vì cung cấp một bức tường mã. – Vidya

Trả lời

3

Tôi nghĩ bạn cần phải DEBUG trước. Sử dụng 'println' sau khi gl.glcreateprogram, gỡ lỗi chính xác nơi lỗi của bạn xuất phát.

'NULL Pointer Exception' có thể tìm thấy dễ dàng hơn bất kỳ lỗi lạ nào khác. (Chỉ dành cho tôi!)

Sử dụng cách đó và tìm nơi ngoại lệ xuất hiện trước.

Các vấn đề liên quan