Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import org.joml.Matrix4f
- import org.joml.Vector3f
- import org.lwjgl.glfw.Callbacks.glfwFreeCallbacks
- import org.lwjgl.glfw.GLFW.*
- import org.lwjgl.glfw.GLFWErrorCallback
- import org.lwjgl.opengl.GL
- import org.lwjgl.opengl.GL11.*
- import org.lwjgl.opengl.GL15.*
- import org.lwjgl.opengl.GL20.*
- import org.lwjgl.opengl.GL30.*
- import org.lwjgl.opengl.GL31.glDrawElementsInstanced
- import org.lwjgl.opengl.GL33.glVertexAttribDivisor
- import org.lwjgl.system.MemoryStack.stackPush
- import org.lwjgl.system.MemoryUtil.NULL
- import java.io.BufferedReader
- import java.io.FileReader
- const val SHADER_PATH = "src/main/kotlin/"
- const val PER_INSTANCE_SIZE = 3 * FLOAT_SIZE
- const val PER_VERTEX_SIZE = 3 * FLOAT_SIZE + 3 * FLOAT_SIZE
- const val WINDOW_WIDTH = 800
- const val WINDOW_HEIGHT = 600
- const val SIZE = 2
- // X Y Z R G B
- val cube_vertices = floatArrayOf(
- -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f,
- 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f,
- 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f,
- 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f,
- -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f,
- -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f,
- -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f,
- 0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f,
- 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f,
- 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f,
- -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f,
- -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f,
- -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f,
- -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f,
- -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f,
- -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f,
- -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f,
- -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f,
- 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f,
- 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f,
- 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f,
- 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f,
- 0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f,
- 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f,
- -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f,
- 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f,
- 0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f,
- 0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f,
- -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f,
- -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f,
- -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f,
- 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f,
- 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f,
- 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f,
- -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f,
- -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f
- )
- class Game {
- var window = NULL
- fun run() {
- initWindow()
- loop()
- glfwFreeCallbacks(window)
- glfwDestroyWindow(window)
- glfwTerminate()
- glfwSetErrorCallback(null).free()
- }
- private fun initWindow() {
- GLFWErrorCallback.createPrint(System.err).set()
- if (!glfwInit()) throw IllegalStateException("Unable to initialize GLFW")
- glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE)
- glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE)
- window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "GraphicTest", NULL, NULL)
- if (window == NULL) throw RuntimeException("Failed to create GLFW window")
- glfwSetKeyCallback(window) { window, key, _, action, _ ->
- if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE)
- glfwSetWindowShouldClose(window, true) // We will detect this in the rendering loop
- }
- stackPush().use { stack ->
- val pWidth = stack.mallocInt(1)
- val pHeight = stack.mallocInt(1)
- // Get the window SIZE passed to glfwCreateWindow
- glfwGetWindowSize(window, pWidth, pHeight)
- // Get the resolution of the primary monitor
- val vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor())
- // Center the window
- glfwSetWindowPos(
- window,
- (vidmode.width() - pWidth.get(0)) / 2,
- (vidmode.height() - pHeight.get(0)) / 2
- )
- }
- glfwMakeContextCurrent(window)
- glfwSwapInterval(1)// Enable vSync
- glfwShowWindow(window)
- }
- private fun loop() {
- GL.createCapabilities()
- glEnable(GL_DEPTH_TEST)
- //OPEN SHADER PROGRAM
- val vertexShader = loadAndCompileShader(GL_VERTEX_SHADER, SHADER_PATH + "vertex_shader.vert")
- val fragShader = loadAndCompileShader(GL_FRAGMENT_SHADER, SHADER_PATH + "fragment_shader.frag")
- val shaderProgram = glCreateProgram()
- glAttachShader(shaderProgram, vertexShader)
- glAttachShader(shaderProgram, fragShader)
- glBindFragDataLocation(shaderProgram, 0, "outColor")
- glLinkProgram(shaderProgram)
- glUseProgram(shaderProgram)
- val vao = glGenVertexArrays()
- glBindVertexArray(vao)
- //ATTRIBUTES
- val perVertexVBO = glGenBuffers()
- glBindBuffer(GL_ARRAY_BUFFER, perVertexVBO)
- val inVertexAttrib = glGetAttribLocation(shaderProgram, "in_vertex")
- glEnableVertexAttribArray(inVertexAttrib)
- var offset: Long = 0
- glVertexAttribPointer(inVertexAttrib, 3, GL_FLOAT, false, PER_VERTEX_SIZE, offset)
- offset += 3 * FLOAT_SIZE
- val inNormalAttrib = glGetAttribLocation(shaderProgram, "color")
- glEnableVertexAttribArray(inNormalAttrib)
- glVertexAttribPointer(inNormalAttrib, 3, GL_FLOAT, false, PER_VERTEX_SIZE, offset)
- offset += 3 * FLOAT_SIZE
- val perInstanceVBO = glGenBuffers()
- glBindBuffer(GL_ARRAY_BUFFER, perInstanceVBO)
- val locAttrib = glGetAttribLocation(shaderProgram, "pos")
- glEnableVertexAttribArray(locAttrib)
- glVertexAttribPointer(locAttrib, 3, GL_FLOAT, false, PER_INSTANCE_SIZE, 0)
- glVertexAttribDivisor(locAttrib, 1)
- val view = Matrix4f().lookAt(
- Vector3f(1.2F, 4.2F, 1.0F),
- Vector3f(0.0F, 0.0F, 0.0F),
- Vector3f(0.0F, 0.0F, 1.0F)
- )
- stackPush().use { stack ->
- val buffer = stack.mallocFloat(4 * 4)
- view.get(buffer)
- val uniView = glGetUniformLocation(shaderProgram, "view")
- glUniformMatrix4fv(uniView, false, buffer)
- }
- val proj = Matrix4f().perspective(Math.toRadians(45.0).toFloat(), WINDOW_WIDTH.toFloat() / WINDOW_HEIGHT.toFloat(), 1.0F, 10.0F)
- stackPush().use { stack ->
- val buffer = stack.mallocFloat(4 * 4)
- proj.get(buffer)
- val uniProj = glGetUniformLocation(shaderProgram, "proj")
- glUniformMatrix4fv(uniProj, false, buffer)
- }
- glBindBuffer(GL_ARRAY_BUFFER, perVertexVBO)
- stackPush().use { stack ->
- val buffer = stack.mallocFloat(cube_vertices.size)
- buffer.put(cube_vertices)
- buffer.flip()
- glBufferData(GL_ARRAY_BUFFER, buffer, GL_DYNAMIC_DRAW)
- }
- while (!glfwWindowShouldClose(window)) {
- glClearColor(1.0f, 1.0f, 1.0f, 1.0f)
- glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)
- glBindVertexArray(vao)
- val positions = FloatArray(SIZE * SIZE * 3, { _ -> 0.0F })
- for (c in 0..SIZE) {
- for (d in 0..SIZE) {
- positions[c * SIZE + d + 0] = ((c * 3 - SIZE).toFloat())
- positions[c * SIZE + d + 1] = (-2 + 0.5 * Math.sin(Math.toRadians((c + d + 1) * glfwGetTime()))).toFloat()
- positions[c * SIZE + d + 2] = -d * 3.0F
- }
- }
- glBindBuffer(GL_ARRAY_BUFFER, perInstanceVBO)
- stackPush().use { stack ->
- val buffer = stack.mallocFloat(positions.size)
- buffer.put(positions)
- buffer.flip()
- glBufferData(GL_ARRAY_BUFFER, buffer, GL_DYNAMIC_DRAW)
- }
- glDrawElementsInstanced(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0, SIZE * SIZE)
- val trans = Matrix4f().rotate((glfwGetTime() * Math.toRadians(180.0)).toFloat(), Vector3f(0.0F, 0.0F, 1.0F))
- stackPush().use { stack ->
- val buffer = stack.mallocFloat(4 * 4)
- trans.get(buffer)
- val uniTrans = glGetUniformLocation(shaderProgram, "model")
- glUniformMatrix4fv(uniTrans, false, buffer)
- }
- glfwSwapBuffers(window)
- glfwPollEvents()
- }
- glDeleteProgram(shaderProgram)
- glDeleteShader(fragShader)
- glDeleteShader(vertexShader)
- glDeleteBuffers(intArrayOf(perInstanceVBO, perVertexVBO))
- glDeleteVertexArrays(vao)
- }
- private fun loadAndCompileShader(shaderType: Int, fileName: String): Int {
- val shader = glCreateShader(shaderType)
- glShaderSource(shader, loadFile(fileName))
- glCompileShader(shader)
- val status = glGetShaderi(shader, GL_COMPILE_STATUS)
- if (status != GL_TRUE) {
- throw RuntimeException(glGetShaderInfoLog(shader))
- }
- return shader
- }
- /**
- * Load a text file and return its content as a String.
- */
- private fun loadFile(fileName: String): String {
- val vertexCode = StringBuilder()
- try {
- val reader = BufferedReader(FileReader(fileName))
- var line = reader.readLine()
- while (line != null) {
- vertexCode.append(line)
- vertexCode.append('\n')
- line = reader.readLine()
- }
- } catch (e: Exception) {
- throw IllegalArgumentException("unable to load shader from file [$fileName]", e)
- }
- return vertexCode.toString()
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement