Skip to content
Advertisement

LWJGL – OpenGL not rendering

The following LWJGL code is expected to render a blueish square in the center of the screen. Instead, I get a blank white screen. It’s like the rendering is not working at all, or that I am rendering outside of the screen.

I’m a complete noob in OpenGL and LWJGL, so I’m out of my depth. I went through everything but can’t seem to find anything that might be wrong with the code.

OpenGLTest.scala

package com.summerbulb.lwjgl

import game.graphics.VertexArray
import game.input.KeyboardInput
import org.lwjgl.glfw.GLFW._
import org.lwjgl.glfw.GLFWVidMode
import org.lwjgl.opengl.GL
import org.lwjgl.opengl.GL11._
import org.lwjgl.opengl.GL20._
import org.lwjgl.system.MemoryUtil.NULL

import scala.collection.mutable


class OpenGLTest() extends Runnable {
  val width: Int = 1280
  val height: Int = 720

  var isRunning = false

  var window: Long = 0L

  val vertices = Array[Float](
    -0.5f, -0.5f, -0.5f,
    -0.5f, 0.5f, -0.5f,
    0.5f, 0.5f, -0.5f,
    0.5f, -0.5f, -0.5f
  )

  val indices = Array[Byte](
    0, 1, 2,
    2, 3, 0

  )

  val textureCoordinates = Array[Float](
    0, 1,
    0, 0,
    1, 0,
    1, 1
  )

  val vertShader =
    "#version 400 coren" +
    "n" +
    "layout (location = 0) in vec4 position;n" +
    "layout (location = 1) in vec2 tc;n" +
    "n" +
//    "uniform mat4 pr_matrix;n" +
    "n" +
    "void main()n" +
    "{n" +
    "    gl_Position = position;n" +
    "}"

  val fragShader =
    "#version 400 coren" +
    "n" +
    "layout (location = 0) out vec4 color;n" +
    "n" +
    "void main()n" +
    "{n" +
    "    color = vec4(0.2, 0.3, 0.8, 1.0);n" +
    "}"

  lazy val background = new VertexArray(vertices, indices, textureCoordinates)
  lazy val shaderProgramId = createShaderProgram(vertShader, fragShader)

  val cache = mutable.Map[String, Int]()

  def getUniform(name: String) = {

    if (cache.contains(name))
      cache(name)
    else {

      val location = glGetUniformLocation(shaderProgramId, name)
      if (location == -1) {
        System.err.println("Could not find uniform variable '" + name + "'!")
      } else {
        cache.put(name, location)
      }
      location
    }
  }

  def start() = {
    isRunning = true
    val thread = new Thread(this, "OpenGlTest")
    thread.start()
  }

  def init(): Unit = {
    if (!glfwInit()) {
      throw new Exception("Unable to initialize GLFW")
    }

    glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE)
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3)
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3)
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE)

    window = glfwCreateWindow(width, height, "OpenGlTest", NULL, NULL)

    if (window == null) {
      throw new Exception("Could not create window.")
    }

    val vidMode = glfwGetVideoMode(glfwGetPrimaryMonitor())

    glfwSetWindowPos(window, (GLFWVidMode.WIDTH - width) / 2, (GLFWVidMode.HEIGHT - height) / 2)

    glfwSetKeyCallback(window, new KeyboardInput())

    glfwMakeContextCurrent(window)
    glfwShowWindow(window)
    GL.createCapabilities()


    glClearColor(1.0f, 1.0f, 1.0f, 1.0f)
    glEnable(GL_DEPTH_TEST | GL_DEPTH_BUFFER_BIT)
    println("OpenGL: " + glGetString(GL_VERSION))
  }

  override def run(): Unit = {
    init()
    while (isRunning) {
      update()
      render()

      if (glfwWindowShouldClose(window))
        isRunning = false
    }
  }

  def update(): Unit = {
    glfwPollEvents()


    // ESC closes the window
    if (KeyboardInput.keys(GLFW_KEY_ESCAPE)) {
      isRunning = false
    }
  }

  def render(): Unit = {
    glClear(GL_COLOR_BUFFER_BIT)

    glUseProgram(shaderProgramId)
    background.render()
    glUseProgram(0)

    glfwSwapBuffers(window)

  }

  def createShaderProgram(vert: String, frag: String): Int = {
    val program:Int = glCreateProgram()
    val vertID = glCreateShader(GL_VERTEX_SHADER)
    val fragID = glCreateShader(GL_FRAGMENT_SHADER)

    glShaderSource(vertID, vert)
    glShaderSource(fragID, frag)

    glCompileShader(vertID)
    if (glGetShaderi(vertID, GL_COMPILE_STATUS) != GL_TRUE) {
      val infoLog = glGetShaderInfoLog(vertID)
      throw new Exception("Failed to compile vertex shader.nDetails:n" + infoLog)
    }

    glCompileShader(fragID)
    if (glGetShaderi(fragID, GL_COMPILE_STATUS) != GL_TRUE) {
      val infoLog = glGetShaderInfoLog(fragID)
      throw new Exception("Failed to compile fragment shader.nDetails:n" + infoLog)
    }

    glAttachShader(program, vertID)
    glAttachShader(program, fragID)
    glLinkProgram(program)


    glValidateProgram(program)

    glDeleteShader(vertID)
    glDeleteShader(fragID)

    val error = glGetError()
    if (error != GL_NO_ERROR) {
      println(error)
      System.exit(200)
    }

    program
  }

}

object OpenGLTest {
  def main(args: Array[String]): Unit = {
    new OpenGLTest().start()
  }
}

VertexArray.scala

package game.graphics

import java.nio.{ByteBuffer, ByteOrder, FloatBuffer, IntBuffer}

import org.lwjgl.opengl.GL11._
import org.lwjgl.opengl.GL15._
import org.lwjgl.opengl.GL20._
import org.lwjgl.opengl.GL30._

class VertexArray(vertices: Array[Float], indices: Array[Byte], textureCoordinates: Array[Float]) {

  val count = indices.length

  val vao = glGenVertexArrays()
  glBindVertexArray(vao)

  val vbo = glGenBuffers()
  glBindBuffer(GL_ARRAY_BUFFER, vbo)
//  val verticesBuffer = BufferUtils.createFloatBuffer(vertices.length)
//  verticesBuffer.put(vertices).flip()
  glBufferData(GL_ARRAY_BUFFER, createFloatBuffer(vertices) , GL_STATIC_DRAW)
  glVertexAttribPointer(Shader.VERTEX_ATTRIB, 3, GL_FLOAT, false, 0, 0)
  glEnableVertexAttribArray(Shader.VERTEX_ATTRIB)


  val tbo = glGenBuffers()
  glBindBuffer(GL_ARRAY_BUFFER, tbo)
//  val texCoordBuffer = BufferUtils.createFloatBuffer(textureCoordinates.length)
//  texCoordBuffer.put(textureCoordinates).flip()
  glBufferData(GL_ARRAY_BUFFER, createFloatBuffer(textureCoordinates), GL_STATIC_DRAW)
  glVertexAttribPointer(Shader.TCOORD_ATTRIB , 2, GL_FLOAT, false, 0, 0)
  glEnableVertexAttribArray(Shader.TCOORD_ATTRIB)


  val ibo = glGenBuffers()
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo)
//  private val indicesBuffer: ByteBuffer = BufferUtils.createByteBuffer(indices.length)
//  indicesBuffer.put(indices).flip()
  glBufferData(GL_ELEMENT_ARRAY_BUFFER, createByteBuffer(indices), GL_STATIC_DRAW )

  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)
  glBindBuffer(GL_ARRAY_BUFFER, 0)
  glBindVertexArray(0)

  def bind() = {
    glBindVertexArray(vao)
    glEnableVertexAttribArray(Shader.VERTEX_ATTRIB)
    glEnableVertexAttribArray(Shader.TCOORD_ATTRIB)

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo)
  }

  def unbind() = {
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)
    glBindVertexArray(0)
  }

  def draw() = {
    glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_BYTE, 0)
  }


  def render() = {
    bind()
    draw()
  }


  def createByteBuffer(array: Array[Byte]): ByteBuffer = {
    val result = ByteBuffer.allocateDirect(array.length).order(ByteOrder.nativeOrder)
    result.put(array).flip
    result
  }

  def createFloatBuffer(array: Array[Float]): FloatBuffer = {
    val result = ByteBuffer.allocateDirect(array.length << 2).order(ByteOrder.nativeOrder).asFloatBuffer
    result.put(array).flip
    result
  }

  def createIntBuffer(array: Array[Int]): IntBuffer = {
    val result = ByteBuffer.allocateDirect(array.length << 2).order(ByteOrder.nativeOrder).asIntBuffer
    result.put(array).flip
    result
  }
}

Advertisement

Answer

The call of

glEnable(GL_DEPTH_TEST | GL_DEPTH_BUFFER_BIT)

will cause an INVALID_ENUM error. The parameter to glEnable has to be a single enumerator constant. The parameter is not a bit mask where, the values can be concatenated by |.

glClearColor(1.0f, 1.0f, 1.0f, 1.0f)
glEnable(GL_DEPTH_TEST)

If you want to clear the buffers, then you’ve to call glClear. The parameter of glClear is a bit mask that indicate the buffers to be cleared:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement