I'm trying to reproduce this JOGL demo, a Java demo on how to use OpenGL ES 2.0, in Scala. Compiling succeeds, but trying to execute this yields the following output:
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]
It succeeds in rendering perhaps 1 or a few frames before the exception rises. And the expection doesn't appear when I run it from the jswat debugger.
Am I missing something really obvious? Has anyone else experienced a similar problem with Scala and OpenGL ES 2.0?
I am using Linux Mint 13 and Ant to compile and run the code. My Scala code is:
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()
}
}