11package com.lambda.graphics.buffer.pbo
22
33import com.lambda.graphics.buffer.BufferUsage
4- import com.lambda.graphics.texture.TextureUtils.setupTexture
54import org.lwjgl.opengl.GL45C.*
65import java.nio.ByteBuffer
7- import kotlin.system.measureNanoTime
86
97class PixelBuffer (
108 private val width : Int ,
@@ -16,62 +14,58 @@ class PixelBuffer(
1614 private var writeIdx = 0 // Used to copy pixels from the PBO to the texture
1715 private var uploadIdx = 0 // Used to upload data to the PBO
1816
19- fun mapTexture (id : Int , buffer : ByteBuffer ) {
20- val time = measureNanoTime {
21- upload(buffer) { allocate ->
22- // Bind the texture
23- glBindTexture(GL_TEXTURE_2D , id)
24-
25- if (allocate) {
26- glTexParameteri(GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR )
27- glTexParameteri(GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR )
28-
29- // Allocate the texture memory
30- glTexImage2D(GL_TEXTURE_2D , 0 , GL_RGBA , width, height, 0 , GL_RGBA , GL_UNSIGNED_BYTE , 0 )
31- }
32- else {
33- // Update the texture
34- glTextureSubImage2D(GL_TEXTURE_2D , 0 , 0 , 0 , width, height, GL_RGBA , GL_UNSIGNED_BYTE , 0 )
35- }
36- }
17+ private val queryId = glGenQueries() // Used to measure the time taken to upload data to the PBO
18+ val uploadTime get() = IntArray (1 ).also { glGetQueryObjectiv(queryId, GL_QUERY_RESULT , it) }[0 ]
19+
20+ fun mapTexture (id : Int , buffer : ByteBuffer ) =
21+ upload(buffer) {
22+ // Bind the texture
23+ glBindTexture(GL_TEXTURE_2D , id)
24+
25+ // Perform the actual data transfer to the GPU
26+ glTextureSubImage2D(GL_TEXTURE_2D , 0 , 0 , 0 , width, height, GL_RGBA , GL_UNSIGNED_BYTE , 0 )
3727 }
3828
39- println (" PBO => texture $id took $time nanoseconds" )
40- }
29+ fun upload (data : ByteBuffer , process : () -> Unit ) =
30+ recordTransfer {
31+ uploadIdx = (writeIdx + 1 ) % buffers
4132
42- fun upload ( data : ByteBuffer , process : ( Boolean ) -> Unit ) {
43- uploadIdx = (writeIdx + 1 ) % buffers
33+ // Bind the next PBO to update pixel values
34+ glBindBuffer( GL_PIXEL_UNPACK_BUFFER , pboIds[writeIdx])
4435
45- // Bind the next PBO to update pixel values
46- glBindBuffer(GL_PIXEL_UNPACK_BUFFER , pboIds[uploadIdx])
36+ // Map the buffer into the memory
37+ val bufferData = glMapBuffer(GL_PIXEL_UNPACK_BUFFER , GL_WRITE_ONLY )
38+ if (bufferData != null ) {
39+ bufferData.put(data)
4740
48- // Allocate the memory for the buffer
49- process(true )
41+ // Release the buffer
42+ glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER )
43+ } else {
44+ println (" Failed to map the PBO" )
45+ }
5046
51- // Map the buffer into the memory
52- val bufferData = glMapBuffer(GL_PIXEL_UNPACK_BUFFER , GL_WRITE_ONLY )
53- if (bufferData != null ) {
54- bufferData.put(data)
47+ // Bind the current PBO for writing
48+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER , pboIds[uploadIdx])
5549
56- // Release the buffer
57- glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER )
58- } else {
59- println (" Failed to map the PBO" )
60- }
50+ // Copy the pixel values from the PBO to the texture
51+ process()
6152
62- // Bind the current PBO for writing
63- glBindBuffer(GL_PIXEL_UNPACK_BUFFER , pboIds[writeIdx] )
53+ // Unbind the PBO
54+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER , 0 )
6455
65- // Copy the pixel values from the PBO to the texture
66- process(false )
56+ // Swap the indices
57+ writeIdx = uploadIdx
58+ }
6759
68- // Unbind the PBO
69- glBindBuffer(GL_PIXEL_UNPACK_BUFFER , 0 )
60+ private fun recordTransfer (block : () -> Unit ) {
61+ // Start the timer
62+ glBeginQuery(GL_TIME_ELAPSED , queryId)
7063
71- println (" Uploaded data to PBO $uploadIdx at $bufferData " )
64+ // Perform the transfer
65+ block()
7266
73- // Swap the indices
74- writeIdx = uploadIdx
67+ // Stop the timer
68+ glEndQuery( GL_TIME_ELAPSED )
7569 }
7670
7771 // Called when no references to the object exist
@@ -89,7 +83,7 @@ class PixelBuffer(
8983 // Fill the buffers with null data to allocate the memory spaces
9084 repeat(buffers) {
9185 glBindBuffer(GL_PIXEL_UNPACK_BUFFER , pboIds[it])
92- glBufferData(GL_PIXEL_UNPACK_BUFFER , width * height * 4L , GL_STREAM_DRAW )
86+ glBufferData(GL_PIXEL_UNPACK_BUFFER , width * height * 4L , bufferUsage.gl )
9387 }
9488
9589 glBindBuffer(GL_PIXEL_UNPACK_BUFFER , 0 ) // Unbind the buffer
0 commit comments