Skip to content

Commit f354999

Browse files
committed
ref: texture class
1 parent 662dd8b commit f354999

File tree

5 files changed

+45
-76
lines changed

5 files changed

+45
-76
lines changed

common/src/main/kotlin/com/lambda/graphics/renderer/gui/TextureRenderer.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ object TextureRenderer {
3838
shader.use()
3939

4040
drawInternal(rect)
41-
texture.unbind()
4241
}
4342

4443
fun drawTextureShaded(texture: Texture, rect: Rect) {

common/src/main/kotlin/com/lambda/graphics/texture/AnimatedTexture.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import org.lwjgl.stb.STBImage
2626
import java.nio.ByteBuffer
2727

2828

29-
class AnimatedTexture(path: LambdaResource) : Texture(image = null, forceConsistency = false) {
29+
class AnimatedTexture(path: LambdaResource) : Texture(image = null) {
3030
private val pbo: PixelBuffer
3131
private val gif: ByteBuffer // Do NOT free this pointer
3232
private val frameDurations: IntArray

common/src/main/kotlin/com/lambda/graphics/texture/Texture.kt

Lines changed: 42 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -17,45 +17,34 @@
1717

1818
package com.lambda.graphics.texture
1919

20-
import com.lambda.graphics.renderer.gui.TextureRenderer
2120
import com.lambda.graphics.texture.TextureUtils.bindTexture
2221
import com.lambda.graphics.texture.TextureUtils.readImage
2322
import com.lambda.graphics.texture.TextureUtils.setupTexture
24-
import com.lambda.util.math.Rect.Companion.basedOn
25-
import com.lambda.util.math.Vec2d
2623
import net.minecraft.client.texture.NativeImage
2724
import org.lwjgl.opengl.GL45C.*
2825
import java.awt.image.BufferedImage
29-
import java.lang.IllegalStateException
26+
import java.awt.image.BufferedImage.*
3027
import java.nio.ByteBuffer
28+
import kotlin.IllegalStateException
3129

3230
/**
3331
* Represents a texture that can be uploaded and bound to the graphics pipeline
3432
* Supports mipmap generation and LOD (Level of Detail) configuration
3533
*/
3634
open class Texture {
37-
val internalFormat: Int
3835
val format: Int
3936
private val levels: Int
40-
private val forceConsistency: Boolean
37+
private val nativeFormat: NativeImage.Format // For mojang native images
4138

4239
/**
4340
* @param image Optional initial image to upload to the texture
44-
* @param format The format of the image passed in
41+
* @param format The format of the image passed in, if the [image] is null, then you must pass the appropriate format
4542
* @param levels Number of mipmap levels to generate for the texture
46-
* @param forceConsistency Flag to enforce consistency when updating the texture. If true, attempts to update
47-
* the texture after initialization will throw an exception
4843
*/
49-
constructor(image: BufferedImage?,
50-
internalFormat: Int = GL_RGBA,
51-
format: Int = GL_RGBA,
52-
levels: Int = 4,
53-
forceConsistency: Boolean = false)
54-
{
55-
this.internalFormat = internalFormat
56-
this.format = format
44+
constructor(image: BufferedImage?, format: Int = GL_RGBA, levels: Int = 4) {
45+
this.format = image?.type?.let { bufferedMapping[it] } ?: format
5746
this.levels = levels
58-
this.forceConsistency = forceConsistency
47+
this.nativeFormat = nativeMapping.getOrDefault(format, NativeImage.Format.RGBA)
5948

6049
image?.let { bindTexture(id); upload(it) }
6150
}
@@ -64,23 +53,13 @@ open class Texture {
6453
* @param buffer The image buffer
6554
* @param width The width of the image
6655
* @param height The height of the image
67-
* @param format The format of the image passed in
56+
* @param format The format of the image passed in, must be specified
6857
* @param levels Number of mipmap levels to generate for the texture
69-
* @param forceConsistency Flag to enforce consistency when updating the texture. If true, attempts to update
70-
* the texture after initialization will throw an exception
7158
*/
72-
constructor(buffer: ByteBuffer,
73-
width: Int,
74-
height: Int,
75-
internalFormat: Int = GL_RGBA,
76-
format: Int = GL_RGBA,
77-
levels: Int = 4,
78-
forceConsistency: Boolean = false)
79-
{
80-
this.internalFormat = internalFormat
59+
constructor(buffer: ByteBuffer, width: Int, height: Int, format: Int, levels: Int = 4) {
8160
this.format = format
8261
this.levels = levels
83-
this.forceConsistency = forceConsistency
62+
this.nativeFormat = nativeMapping.getOrDefault(format, NativeImage.Format.RGBA)
8463

8564
bindTexture(id)
8665
upload(buffer, width, height)
@@ -117,20 +96,18 @@ open class Texture {
11796
* @param offset The mipmap level to upload the image to
11897
*/
11998
fun upload(image: BufferedImage, offset: Int = 0) {
120-
if (forceConsistency && initialized) throw IllegalStateException("Client tried to update a texture, but the enforce consistency flag was present")
121-
12299
// Store level_base +1 through `level` images and generate
123100
// mipmaps from them
124-
setupLOD(levels = levels)
101+
setupLOD(levels)
125102

126103
width = image.width
127104
height = image.height
128105
initialized = true
129106

130107
// Set this mipmap to `offset` to define the original texture
131108
setupTexture(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR)
132-
glTexImage2D(GL_TEXTURE_2D, offset, internalFormat, width, height, 0, format, GL_UNSIGNED_BYTE, readImage(image, getNativeFormat(format)))
133-
if (levels > 1) glGenerateMipmap(GL_TEXTURE_2D) // This take the derived values GL_TEXTURE_BASE_LEVEL and GL_TEXTURE_MAX_LEVEL to generate the stack
109+
glTexImage2D(GL_TEXTURE_2D, offset, GL_RGBA, width, height, 0, format, GL_UNSIGNED_BYTE, readImage(image, nativeFormat))
110+
if (levels > 0) glGenerateMipmap(GL_TEXTURE_2D) // This take the derived values GL_TEXTURE_BASE_LEVEL and GL_TEXTURE_MAX_LEVEL to generate the stack
134111
}
135112

136113
/**
@@ -143,20 +120,18 @@ open class Texture {
143120
* @param offset The mipmap level to upload the image to
144121
*/
145122
fun upload(buffer: ByteBuffer, width: Int, height: Int, offset: Int = 0) {
146-
if (forceConsistency && initialized) throw IllegalStateException("Client tried to update a texture, but the enforce consistency flag was present")
147-
148123
// Store level_base +1 through `level` images and generate
149124
// mipmaps from them
150-
setupLOD(levels = levels)
125+
setupLOD(levels)
151126

152127
this.width = width
153128
this.height = height
154129
initialized = true
155130

156131
// Set this mipmap to `offset` to define the original texture
157132
setupTexture(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR)
158-
glTexImage2D(GL_TEXTURE_2D, offset, internalFormat, width, height, 0, format, GL_UNSIGNED_BYTE, buffer)
159-
if (levels > 1) glGenerateMipmap(GL_TEXTURE_2D) // This take the derived values GL_TEXTURE_BASE_LEVEL and GL_TEXTURE_MAX_LEVEL to generate the stack
133+
glTexImage2D(GL_TEXTURE_2D, offset, GL_RGBA, width, height, 0, format, GL_UNSIGNED_BYTE, buffer)
134+
if (levels > 0) glGenerateMipmap(GL_TEXTURE_2D) // This take the derived values GL_TEXTURE_BASE_LEVEL and GL_TEXTURE_MAX_LEVEL to generate the stack
160135
}
161136

162137
/**
@@ -170,14 +145,9 @@ open class Texture {
170145
*/
171146
fun update(image: BufferedImage, offset: Int = 0) {
172147
if (!initialized) return upload(image, offset)
173-
if (forceConsistency && initialized) throw IllegalStateException("Client tried to update a texture, but the enforce consistency flag was present")
174-
175-
check(image.width + image.height <= this.width + this.height && initialized) {
176-
"Client tried to update a texture with more data than allowed" +
177-
"Expected ${this.width + this.height} bytes but got ${image.width + image.height}"
178-
}
179148

180-
glTexSubImage2D(GL_TEXTURE_2D, offset, 0, 0, width, height, format, GL_UNSIGNED_BYTE, readImage(image, getNativeFormat(format)))
149+
checkDimensions(width, height)
150+
glTexSubImage2D(GL_TEXTURE_2D, offset, 0, 0, width, height, format, GL_UNSIGNED_BYTE, readImage(image, nativeFormat))
181151
}
182152

183153
/**
@@ -193,26 +163,11 @@ open class Texture {
193163
*/
194164
fun update(buffer: ByteBuffer, width: Int, height: Int, offset: Int = 0) {
195165
if (!initialized) return upload(buffer, width, height, offset)
196-
if (forceConsistency && initialized) throw IllegalStateException("Client tried to update a texture, but the enforce consistency flag was present")
197-
198-
check(width + height <= this.width + this.height && initialized) {
199-
"Client tried to update a texture with more data than allowed\n" +
200-
"Expected ${this.width + this.height} bytes but got ${width + height}"
201-
}
202166

167+
checkDimensions(width, height)
203168
glTexSubImage2D(GL_TEXTURE_2D, offset, 0, 0, width, height, format, GL_UNSIGNED_BYTE, buffer)
204169
}
205170

206-
/**
207-
* Draws the texture
208-
* This function binds the texture
209-
*
210-
* @param coord The top left coordinate to draw at
211-
* @param scale The width and height multiplier
212-
*/
213-
fun draw(coord: Vec2d, scale: Double = 0.0) =
214-
TextureRenderer.drawTexture(this, basedOn(coord, width * scale, height * scale))
215-
216171
private fun setupLOD(levels: Int) {
217172
// When you call glTextureStorage, you're specifying the total number of levels, including level 0
218173
// This is a 0-based index system, which means that the maximum mipmap level is n-1
@@ -225,11 +180,28 @@ open class Texture {
225180
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, levels)
226181
}
227182

228-
private fun getNativeFormat(gl: Int) =
229-
when (gl) {
230-
GL_RED, GL_GREEN, GL_BLUE -> NativeImage.Format.LUMINANCE
231-
GL_RG -> NativeImage.Format.LUMINANCE_ALPHA
232-
GL_RGB -> NativeImage.Format.RGB
233-
else -> NativeImage.Format.RGBA
183+
private fun checkDimensions(width: Int, height: Int) =
184+
check(width + height <= this.width + this.height && initialized) {
185+
"Client tried to update a texture with more data than allowed\n" +
186+
"Expected ${this.width + this.height} bytes but got ${width + height}"
234187
}
188+
189+
companion object {
190+
private val nativeMapping = mapOf(
191+
GL_RED to NativeImage.Format.LUMINANCE,
192+
GL_GREEN to NativeImage.Format.LUMINANCE,
193+
GL_BLUE to NativeImage.Format.LUMINANCE,
194+
GL_RG to NativeImage.Format.LUMINANCE_ALPHA,
195+
GL_RGB to NativeImage.Format.RGB,
196+
GL_RGBA to NativeImage.Format.RGBA,
197+
)
198+
199+
private val bufferedMapping = mapOf(
200+
TYPE_BYTE_BINARY to GL_RED,
201+
TYPE_BYTE_GRAY to GL_RG,
202+
TYPE_INT_RGB to GL_RGB,
203+
TYPE_INT_ARGB to GL_RGBA,
204+
TYPE_4BYTE_ABGR to GL_BGRA,
205+
)
206+
}
235207
}

common/src/main/kotlin/com/lambda/graphics/texture/TextureUtils.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ object TextureUtils {
5252

5353
fun readImage(
5454
bufferedImage: BufferedImage,
55-
format: NativeImage.Format = NativeImage.Format.RGBA,
55+
format: NativeImage.Format,
5656
): Long {
5757
val bytes = encoderPreset
5858
.withBufferedImage(bufferedImage)
@@ -68,6 +68,6 @@ object TextureUtils {
6868

6969
fun readImage(
7070
image: ByteBuffer,
71-
format: NativeImage.Format = NativeImage.Format.RGBA,
71+
format: NativeImage.Format,
7272
) = NativeImage.read(format, image).pointer
7373
}

common/src/main/kotlin/com/lambda/module/hud/Watermark.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,8 @@ package com.lambda.module.hud
2020
import com.lambda.graphics.renderer.gui.TextureRenderer.drawTexture
2121
import com.lambda.graphics.renderer.gui.TextureRenderer.drawTextureShaded
2222
import com.lambda.graphics.texture.TextureOwner.upload
23-
import com.lambda.graphics.texture.TextureOwner.uploadGif
2423
import com.lambda.module.HudModule
2524
import com.lambda.module.tag.ModuleTag
26-
import com.lambda.util.math.Vec2d
2725

2826
object Watermark : HudModule(
2927
name = "Watermark",

0 commit comments

Comments
 (0)