0
\$\begingroup\$

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)
}

}
\$\endgroup\$
  • \$\begingroup\$ How about you tell us what graphics hardware you have? \$\endgroup\$ – Maximus Minimus Jan 14 '18 at 12:45
  • \$\begingroup\$ I've got a Lenovo IdeaPad v310 running a Radeon R5 M430. (Yes I'm overseas without my good computer) I solved my problem :) I appreciate you taking the time to respond, though. \$\endgroup\$ – Alex Jan 14 '18 at 19:08
1
\$\begingroup\$

Switch the statements glfwMakeContextCurrent() and GL.createCapabilities()

glfwMakeContextCurrent() creates the context, which needs to happen first. GL.createCapabilities() then retrieves function pointers and checks available extensions, but this needs an active context first.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

I figured it out. It's throwing an exception because by constructing the StaticShader class when I declare it in my Main class variables, gl functions are being called by StaticShader's constructor before OpenGL has been initialized in the init() function of my Main class. I moved the initialization of StaticShader until after I'd initialized OpenGL and now it works fine.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.