I've successfully used LWJGL 2.9.3 in the past and am now giving LWJGL 3.15 a shot in Kotlin.
I had a quad rendering nicely but now I'm using shaders it seems that openGL isn't initialized and I'm not sure why. I look through others' example code and can't figure out why mine isn't working. I've called glfwInit() and GL.createCapabilities()
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffd4af32957, pid=14068, tid=0x00000000000026ec
# Problematic frame:
# C [lwjgl_opengl.dll+0x12957]
Register to memory mapping:
RAX=0x0000000071bd1d50 is an unknown value
RBX={method} {0x0000000016404640} 'glCreateShader' '(I)I' in 'org/lwjgl/opengl/GL20'
RCX=0x0000000000000000 is an unknown value
My best guess is that the problem lies somewhere in one of these two classes:
Main.kt
import org.lwjgl.glfw.*
import org.lwjgl.opengl.*
import org.lwjgl.glfw.Callbacks.*
import org.lwjgl.glfw.GLFW.*
import org.lwjgl.opengl.GL11.*
import org.lwjgl.system.MemoryStack.*
import org.lwjgl.system.MemoryUtil.*
import shaders.StaticShader
class Main : Thread(){
private var window: Long = 0
private val width = 800
private val height = 600
private val title = "Swan LWJGL"
private val loader = Loader()
private val renderer = Renderer()
private val shader = StaticShader()
override fun run() {
init()
val model = loader.loadToVAO(
floatArrayOf(
-0.5f, 0.5f, 0f,
-0.5f, -0.5f, 0f,
0.5f, -0.5f, 0f,
0.5f, 0.5f, 0f),
intArrayOf(
0,1,3,
3,1,2))
while (!glfwWindowShouldClose(window)) {
renderer.prepare()
shader.start()
renderer.render(model)
shader.stop()
glfwSwapBuffers(window)
glfwPollEvents()
}
loader.free()
shader.free()
glfwFreeCallbacks(window)
glfwDestroyWindow(window)
glfwTerminate()
glfwSetErrorCallback(null).free()
}
private fun init() {
GLFWErrorCallback.createPrint(System.err).set()
if (!glfwInit()) throw IllegalStateException("Unable to initialize GLFW")
glfwDefaultWindowHints()
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE)
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE)
window = glfwCreateWindow(width, height, title, NULL, NULL)
if (window == NULL) throw RuntimeException("Failed to create the GLFW window")
glfwSetKeyCallback(window) { window, key, _, action, _ ->
if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE)
glfwSetWindowShouldClose(window, true)
}
stackPush().use { stack ->
val pWidth = stack.mallocInt(1)
val pHeight = stack.mallocInt(1)
glfwGetWindowSize(window, pWidth, pHeight)
val videoMode = glfwGetVideoMode(glfwGetPrimaryMonitor())
glfwSetWindowPos(window,
(videoMode.width() - pWidth.get(0)) / 2,
(videoMode.height() - pHeight.get(0)) / 2)
}
GL.createCapabilities()
glfwMakeContextCurrent(window)
glfwSwapInterval(1)
glfwShowWindow(window)
glEnable(GL_DEPTH_TEST)
println(glGetString(GL_VERSION))
}
companion object {
@JvmStatic fun main(args: Array<String>) {
Main().start()
}
}
}
StaticShader.kt
package shaders
import org.lwjgl.opengl.GL11.*
import org.lwjgl.opengl.GL20.*
import java.io.BufferedReader
import java.io.FileReader
import java.io.IOException
abstract class Shader(vFile: String, fFile: String){
private var vID = loadShader(vFile, GL_VERTEX_SHADER)
private var fID = loadShader(fFile, GL_FRAGMENT_SHADER)
private var id = glCreateProgram()
init{
glAttachShader(id, vID)
glAttachShader(id, fID)
//bindAttributes()
glLinkProgram(id)
glValidateProgram(id)
}
fun start(){
glUseProgram(id)
}
fun stop(){
glUseProgram(0)
}
fun free(){
stop()
glDetachShader(id, vID)
glDetachShader(id, fID)
glDeleteShader(vID)
glDeleteShader(fID)
glDeleteProgram(id)
}
private fun loadShader(file: String, type: Int): Int{
val src = StringBuilder()
try{
BufferedReader(FileReader(file)).useLines { it.map{
line -> src.append(line).append("\n")
}}
}catch(e: IOException){
e.printStackTrace()
error("Error reading file")
}
val sID = glCreateShader(type)
glShaderSource(sID, src)
glCompileShader(sID)
if(glGetShaderi(sID, GL_COMPILE_STATUS) == GL_FALSE){
println(glGetShaderInfoLog(sID, 500))
error("Error compiling shader")
}
return sID
}
open fun bindAttributes(){}
open fun bindAttribute(attrib: Int, name: String){
glBindAttribLocation(id, attrib, name)
}
private fun error(msg: String){
System.err.println(msg)
System.exit(-1)
}
}