当前位置: 首页 > 知识库问答 >
问题:

LWJGL - OpenGL 未渲染

罗昕
2023-03-14

下面的LWJGL代码将在屏幕中心呈现一个蓝色正方形。相反,我得到了一个空白的白色屏幕。就像渲染根本不工作,或者我在屏幕外渲染。

我是OpenGL和LWJGL的新手,所以我力不从心。我浏览了所有内容,但似乎找不到任何可能与代码有关的问题。

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 core\n" +
    "\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 core\n" +
    "\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
  }
}

共有1个答案

陶星渊
2023-03-14

的呼唤

glEnable(GL_DEPTH_TEST | GL_DEPTH_BUFFER_BIT)

将导致<code>INVALID_ENUM<code>错误。glEnable的参数必须是单个枚举数常量。参数不是位掩码,其中,值可以通过<code>|

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

如果要清除缓冲区,则必须调用glClearglClear的参数是一个位掩码,指示要清除的缓冲区:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
 类似资料:
  • 我试图使用opengl在lwjgl显示器上显示自定义字体的文本。目前,我正在使用自定义位图字体类从png文件加载字体,并以与tileset相同的方式显示它们。它工作正常,但当我将文本绘制到屏幕上时,字符之间的间距完全不同,因为字母M比字母i宽得多,并且所有字符的宽度都不同。有没有办法检测每个字符的宽度?或者是否有任何特定于lwjgl字体的库?有一种方法可以使用slick2d来实现,但加载整个库只是

  • 我有两个VBO,我试图渲染,它们在屏幕上应该有两个不同的位置。当我试图修改其中一个VBO的位置时,它会被转移到另一个VBOs。 示例-我更改了对象2的y位置,对象1和对象2现在都存在于该y位置。 我用于转换VBO的代码: 请注意位置,旋转,缩放都是Vector3fs,modelMatrix是well,模型矩阵。 此外,这是一个工具包。degToRad类似于数学。toRadians()类型的方法。

  • 使用LWJGL的OpenGL版本1.1和2D纹理,我发现自己卡住了... 出于某种原因,LWJGL引擎不会在2D图层上渲染加载的纹理...相反,我得到了一个白色正方形... 我假设我很有可能在代码的某个地方遗漏了什么..以下是与此类事件相关的全部代码.. 加载OpenGL环境: 进入2D绘图模式(用于绘制纯色正方形的功能-通过glcolor函数进行测试,然后通过glvertex调用尺寸): 加载映

  • 每当我运行这个,窗口就会弹出,我看到这个。(当我运行游戏时,我看到了这一点) 如果您简单地创建一个新的Java项目,导入OpenGL、GLFW和LWJGL以及本机,然后复制代码,就可以重新创建它(删除包)

  • 注意:很抱歉链接/图片只不过是文本-作为一个新用户,我不能张贴图片,也不能张贴 所以我一直在使用被弃用的OpenGL,并在几周前决定最终转向更现代的方法。我使用Open.gl作为资源(我发现LWJGL教程是不一致和稀疏的),并且能够渲染到本教程的最后一幅图像。然而,我在下一页遇到了一些严重的问题(渲染一个立方体)。 我在这个问题上做了很多研究,并多次改进/重新组织我的代码,以便完全理解每个组件的用

  • 我已经试着让这段代码工作了一段时间,但我仍然不知道我做错了什么。(LWJGL-Java) 我曾尝试在网上查看其他人的代码,但我找不到任何重大区别。事实上,我学会了将OpenGL与C结合使用,所以我的大脑可能会被它卡住,这可能就是我找不到错误的原因。 这是init(调用一次) 这是渲染函数: 着色器: 顶点: Framgent公司: