【发布时间】:2021-12-27 18:28:23
【问题描述】:
我试图用 LWJGL 在 kotlin 中制作三角形着色器,但由于某种原因它不起作用并且我没有收到任何错误。调试起来真的很难,因为即使我故意在着色器代码中写错了东西,我仍然没有收到任何错误,所以我什至无法判断这段代码有什么问题。
三角形类代码:
class Triangle {
private var vertexShaderCode: String = "" +
"attribute vec4 vPosition; \n" +
"void main() { \n" +
" gl_Position = vPosition; \n" +
"}"
private var fragmentShaderCode: String = "" +
"precision mediump float; \n" +
"uniform vec4 vColor; \n" +
"void main() { \n" +
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); \n" +
"}"
private lateinit var vertexBuffer: FloatBuffer
private val COORDS_PER_VERTEX: Int = 3
private val triangleCoords = floatArrayOf(
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
1.0f, 0.0f, 0.0f
)
private val color = floatArrayOf(1.0f, 0.0f, 0.0f, 1.0f)
private val mProgram: Int
var VBO: Int
var VAO: Int
init {
VBO = glGenBuffers()
VAO = glGenVertexArrays()
glBindVertexArray(0)
val vertexShader: Int = Engine().loadShader(GL_VERTEX_SHADER, vertexShaderCode)
val fragmentShader: Int = Engine().loadShader(GL_FRAGMENT_SHADER, fragmentShaderCode)
mProgram = glCreateProgram()
glAttachShader(mProgram, vertexShader)
glAttachShader(mProgram, fragmentShader)
glLinkProgram(mProgram)
}
fun draw() {
glUseProgram(mProgram)
VBO = glGenBuffers()
VAO = glGenVertexArrays()
glBindVertexArray(VAO)
glBindBuffer(GL_ARRAY_BUFFER, VBO)
GL15.glBufferData(GL_ARRAY_BUFFER, triangleCoords, GL_STATIC_DRAW)
GL20.glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0)
glBindVertexArray(VAO)
glDrawArrays(GL_TRIANGLES, 0, 3)
glDisableVertexAttribArray(0)
glBindVertexArray(0)
}
}
应用代码:
class Engine {
private var window: Long = 0
fun run() {
println("Hello LWJGL " + Version.getVersion() + "!")
init()
loop()
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)
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3)
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0)
window = glfwCreateWindow(600, 800, "Hello World!", NULL, NULL)
if(window==NULL)
throw RuntimeException("Failed to create the GLFW window!")
stackPush().use { stack ->
val pWidth = stack.mallocInt(1) // int*
val pHeight = stack.mallocInt(1) // int*
// 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[0]) / 2,
(vidmode.height() - pHeight[0]) / 2
)
}
glfwMakeContextCurrent(window)
glfwSwapInterval(1)
glfwShowWindow(window)
}
private fun loop(){
GL.createCapabilities()
var triangle = Triangle1()
glClearColor(1.0f, 1.0f, 1.0f, 1.0f)
while(!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)
triangle.draw()
glfwSwapBuffers(window)
glfwPollEvents()
}
}
fun loadShader(type: Int, shaderCode: String): Int {
val shader = glCreateShader(type)
glShaderSource(shader, shaderCode)
glCompileShader(shader)
return shader
}
}
【问题讨论】:
-
我不熟悉 kotlin,但我认为您每次绘制时都会创建一个新的 VAO/VBO(并且永远不要删除它们)。创建一次 VAO/VBO,然后仅在渲染期间使用它。并且您应该在着色器加载期间检查编译器和链接器错误。见khronos.org/opengl/wiki/…
-
在
draw函数中,您永远不会启用(默认禁用)通用顶点属性数组 0。实际上您只是禁用它,它已经是。