@@ -21,20 +21,44 @@ import com.lambda.graphics.texture.TextureUtils.bindTexture
2121import com.lambda.graphics.texture.TextureUtils.readImage
2222import com.lambda.graphics.texture.TextureUtils.setupTexture
2323import com.lambda.module.modules.client.RenderSettings
24+ import org.lwjgl.opengl.GL11C
2425import org.lwjgl.opengl.GL45C.*
2526import java.awt.image.BufferedImage
2627
28+ /* *
29+ * Represents a texture that can be uploaded and bound to the graphics pipeline.
30+ * Supports mipmap generation and LOD (Level of Detail) configuration
31+ *
32+ * @param image Optional initial image to upload to the texture
33+ * @param levels Number of mipmap levels to generate for the texture
34+ * @param forceConsistency Flag to enforce consistency when updating the texture. If true, attempts to update
35+ * the texture after initialization will throw an exception
36+ */
2737open class Texture (
2838 image : BufferedImage ? ,
2939 private val levels : Int = 4 ,
40+ private val forceConsistency : Boolean = false ,
3041) {
42+ /* *
43+ * Indicates whether there is an initial texture or not
44+ */
45+ var initialized: Boolean = false ; private set
3146 val id = glGenTextures()
3247
48+ /* *
49+ * Binds the texture to a specific slot in the graphics pipeline.
50+ */
3351 open fun bind (slot : Int = 0) {
3452 bindTexture(id, slot)
3553 glTexParameterf(GL_TEXTURE_2D , GL_TEXTURE_LOD_BIAS , RenderSettings .lodBias)
3654 }
3755
56+ /* *
57+ * Uploads an image to the texture and generates mipmaps for the texture if applicable.
58+ *
59+ * @param image The image to upload to the texture
60+ * @param offset The mipmap level to upload the image to
61+ */
3862 open fun upload (image : BufferedImage , offset : Int = 0) {
3963 // Store level_base +1 through `level` images and generate
4064 // mipmaps from them
@@ -43,13 +67,24 @@ open class Texture(
4367 val width = image.width
4468 val height = image.height
4569
46- // Set this mipmap to 0 to define the original texture
47- glTexImage2D(GL_TEXTURE_2D , 0 , GL_RGBA , width, height, 0 , GL_RGBA , GL_UNSIGNED_BYTE , readImage(image))
70+ // Set this mipmap to `offset` to define the original texture
71+ glTexImage2D(GL_TEXTURE_2D , offset , GL_RGBA , width, height, 0 , GL_RGBA , GL_UNSIGNED_BYTE , readImage(image))
4872 glGenerateMipmap(GL_TEXTURE_2D ) // This take the derived values GL_TEXTURE_BASE_LEVEL and GL_TEXTURE_MAX_LEVEL to generate the stack
4973
5074 setupTexture(GL_LINEAR_MIPMAP_LINEAR , GL_LINEAR )
5175 }
5276
77+ open fun update (image : BufferedImage , offset : Int = 0) {
78+ if (forceConsistency && initialized)
79+ throw IllegalStateException (" Client tried to update a texture, but the enforce consistency flag was present" )
80+
81+ val width = image.width
82+ val height = image.height
83+
84+ // Can we rebuild LOD ?
85+ glTexSubImage2D(GL_TEXTURE_2D , offset, 0 , 0 , width, height, GL_RGBA , GL_UNSIGNED_BYTE , readImage(image))
86+ }
87+
5388 private fun setupLOD (levels : Int ) {
5489 // When you call glTextureStorage, you're specifying the total number of levels, including level 0
5590 // This is a 0-based index system, which means that the maximum mipmap level is n-1
@@ -66,6 +101,8 @@ open class Texture(
66101 image?.let {
67102 bind()
68103 upload(it)
104+
105+ initialized = true
69106 }
70107 }
71108}
0 commit comments