2013-11-15 35 views
6

我試圖在Scala中重現關於如何使用OpenGL ES 2.0的Java演示this JOGL demo。編譯成功,但嘗試執行這會產生以下輸出:當在Scala中重新創建Java OpenGL ES 2.0演示時出現奇數NullPointerException

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] 

它成功地渲染也許1或幾幀異常上升之前。當我從jswat調試器運行它時,並沒有出現預期。

我錯過了真正明顯的東西嗎?其他人是否遇到過與Scala和OpenGL ES 2.0類似的問題?

我正在使用Linux Mint 13和Ant來編譯和運行代碼。我的斯卡拉代碼是:

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

您確實需要添加一些日誌記錄來幫助縮小可能導致NPE的原因,而不是提供一段代碼。 – Vidya

回答

3

我想你需要首先進行DEBUG。 在gl.glcreateprogram後面使用'println',調試它的確切位置。

'NULL指針異常'可以比任何其他奇怪的錯誤找到更容易。 (只爲我!)

使用這種方式,並找到哪裏例外首先出現。