Tôi đang tự hỏi làm thế nào để vẽ hình học đơn giản với kết cấu có thể ăn quá nhiều hiệu suất (dưới 60 khung hình / giây)? Ngay cả card đồ họa tốt của tôi (GTX 960) cũng có thể "chỉ" vẽ tối đa 1000 họa tiết. Hoạ tiết tôi đang sử dụng là tất cả sức mạnh của 2 kết cấu và không vượt quá kích thước 512x512. Tôi thậm chí chỉ lọc với GL_NEAREST
.
Các sprite chính họ được tạo ngẫu nhiên trong kích thước. Vì vậy, không có 1000 quads toàn màn hình, sẽ không có trường hợp sử dụng thực sự.
Tôi đang vẽ các họa tiết của mình theo đợt, nghĩa là tôi có một bộ đệm đỉnh động và bộ đệm chỉ mục tĩnh. Tôi cập nhật bộ đệm đỉnh mỗi khung hình glBufferSubData
một lần và sau đó vẽ mọi thứ với `` glDrawElements`. Tôi có khoảng 5 kết cấu khác nhau mà tôi liên kết một lần trên mỗi khung hình dẫn đến 5 cuộc gọi rút thăm. Để kết xuất, tôi chỉ sử dụng một shader bị ràng buộc khi ứng dụng khởi động.
Vì vậy, tôi có 5 liên kết kết cấu, 5 cuộc gọi vẽ và một cập nhật bộ đệm đỉnh cho mỗi khung hình không thực sự nhiều.
Đây là một ví dụ với một kết cấu:
val shaderProgram = ShaderProgram("assets/default.vert", "assets/default.frag")
val texture = Texture("assets/logo.png")
val sprite = BufferSprite(texture)
val batch = BufferSpriteBatch()
val projView = Matrix4f().identity().ortho2D(0f, 640f, 0f, 480f)
fun setup() {
glEnable(GL_TEXTURE)
//glColorMask(true, true, true, true)
//glDepthMask(false)
glUseProgram(shaderProgram.program)
texture.bind()
batch.begin()
for(i in 1..1000)
batch.draw(sprite)
batch.update()
}
fun render() {
glClear(GL_COLOR_BUFFER_BIT)
stackPush().use { stack ->
val mat = stack.mallocFloat(16)
projView.get(mat)
val loc = glGetUniformLocation(shaderProgram.program, "u_projView")
glUniformMatrix4fv(loc, false, mat)
batch.flush()
}
}
Các batch.draw()
puts phương pháp sprites đỉnh dữ liệu trong một khía cạnh cpu đệm và batch.update()
cập nhật mọi thứ để các gpu với glBufferSubData
. Và thiết lập spritebatch trông như sau:
glBindBuffer(GL_ARRAY_BUFFER, tmpVbo)
glBufferData(GL_ARRAY_BUFFER, vertexData, GL_STATIC_DRAW)
glEnableVertexAttribArray(0)
glEnableVertexAttribArray(1)
glEnableVertexAttribArray(2)
glVertexAttribPointer(0, 2, GL_FLOAT, false, 24 * sizeof(Float), 0)
glVertexAttribPointer(1, 4, GL_FLOAT, false, 24 * sizeof(Float), 2.toLong() * sizeof(Float))
glVertexAttribPointer(2, 2, GL_FLOAT, false, 24 * sizeof(Float), 6.toLong() * sizeof(Float))
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tmpEbo)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices, GL_STATIC_DRAW)
Tôi đã định hình chương trình của mình trước, nhưng việc cập nhật bộ đệm đỉnh và tất cả các hình học chiếm khoảng 10% tổng thời gian trên mỗi khung. Nhưng việc hoán đổi bộ đệm chiếm phần còn lại của thời gian khung 90%.
Vì vậy, tôi đang hỏi, làm thế nào các trò chơi AAA lớn như vậy có thể hiển thị cảnh của chúng với hàng triệu đỉnh, nếu vẽ pixel là một nhiệm vụ tốn thời gian như vậy? Tôi biết rằng họ có rất nhiều tối ưu hóa trong mã, nhưng vẫn còn.