LWJGL和Scala,绘制一个对象

时间:2018-01-18 06:06:07

标签: scala opengl lwjgl glfw

我正在开发一个我在Scala中编写的项目,我正在使用LWJGL,并且我遇到了一些使对象出现在屏幕上的问题。我以前在java中使用过LWJGL,所以我尝试在scala中编写相同的代码。

这是我初始化窗口的主要类

import java.nio.FloatBuffer
import org.lwjgl.BufferUtils
import org.lwjgl.glfw.{GLFWErrorCallback, GLFWKeyCallback}
import org.lwjgl.glfw.GLFW._
import org.lwjgl.opengl.GL
import org.lwjgl.opengl.GL11._
import org.lwjgl.opengl.GL15._


object Main {
def main(args:Array[String]):Unit = {
    init()
    loop()
}
var window:Long = 0
val height = 720
val width = 1280
def init()= {
//Set up error callback to print to System.err
GLFWErrorCallback.createPrint(System.err).set()

//Init window
if (!glfwInit())
  throw new IllegalStateException("Unable to init GLFW")

glfwDefaultWindowHints()
glfwWindowHint(GLFW_VISIBLE,GLFW_FALSE)   //window stays hidden after 
creation
glfwWindowHint(GLFW_RESIZABLE,GLFW_TRUE)  //window will be resizable

//Create window
window = glfwCreateWindow(width,height,"Platformer",0,0)
if (window == 0) {
  throw new RuntimeException("Failed to create window")
}

glfwSetInputMode(window,GLFW_STICKY_KEYS,1)
//Set escape key callback to close window
glfwSetKeyCallback(window, (window: Long, key: Int, scancode: Int, action: Int, mods: Int) => {
  if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE) {
    glfwSetWindowShouldClose(window, true)
  }
})

//Make the context current
glfwMakeContextCurrent(window)

//Enable v-sync
glfwSwapInterval(1)

//Show window
glfwShowWindow(window)
//Allows gl calls
GL.createCapabilities()

//Set clear color and get ready for textures
glClearColor(0,0,0,0)
glEnable(GL_TEXTURE_2D)
glOrtho(0,1280,720,0,1, 0 - 1)
glMatrixMode(GL_MODELVIEW)

//Allows use of alpha values
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
}

def loop(): Unit ={
  val obj = new RenderObject()
  while (!glfwWindowShouldClose(window)){
      glfwPollEvents()
      glClear(GL_COLOR_BUFFER_BIT)
      obj.render()
      glfwSwapBuffers(window)
  }
}

//I tested this method and it works properly
def createBuffer(floats:Array[Float]):FloatBuffer = {
  var buffer = BufferUtils.createFloatBuffer(floats.length)
  buffer.put(floats)
  buffer.flip()
  buffer
 }
}

这是我的RenderObject

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

class RenderObject(){
  var vId: Int = glGenBuffers()
  protected var vertices:Array[Float] = Array(
    0,0,
    0,1000,
    1000,1000,
    0,1000
  )
init()
def init(): Unit ={
  glBindBuffer(GL_ARRAY_BUFFER,vId)
  glBufferData(GL_ARRAY_BUFFER,Main.createBuffer(vertices),GL_STATIC_DRAW)
  glBindBuffer(GL_ARRAY_BUFFER,0)
}

//Renders the object
def render(): Unit ={
  //Put this in to test the buffer data
  var floatArray:Array[Float] = new Array[Float](12)
  glGetBufferSubData(vId,0,floatArray)
  for (f <- floatArray) println(f+"")
  //Always prints out 0.0

  glColor3f(1,0,0)

  glEnableClientState(GL_VERTEX_ARRAY)

  glBindBuffer(GL_ARRAY_BUFFER, vId)
  glVertexPointer(2, GL_FLOAT, 0, 0)

  glDrawArrays(GL_QUADS, 0, 4)

  glBindBuffer(GL_ARRAY_BUFFER, 0)

  glDisableClientState(GL_VERTEX_ARRAY)

 }
}

我输入glGetBufferSubData来测试缓冲区是否有我的数据,它总是打印出0.0。这让我相信错误与RenderObject中的init函数有关。有没有人有我可以尝试的想法?

1 个答案:

答案 0 :(得分:1)

glGetBufferSubData的第一个参数是目标,而不是对象名称。你必须这样做:

var floatArray:Array[Float] = new Array[Float](8)
glBindBuffer(GL_ARRAY_BUFFER, vId)
glGetBufferSubData(GL_ARRAY_BUFFER, 0, floatArray)

但您也可以使用glGetNamedBufferSubData

glGetNamedBufferSubData(vId, 0, floatArray)


此外,顶点坐标不形成四边形。坐标(0,1000)是两次,但缺少坐标(1000,0)。像这样更改你的代码:

protected var vertices:Array[Float] = Array(
    0,    0,
    0,    1000,
    1000, 1000,
    1000, 0
)