texture dumping

This commit is contained in:
Moritz Zwerger 2023-11-06 18:50:31 +01:00
parent a73fc2a43c
commit 12b5d13cff
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
7 changed files with 55 additions and 23 deletions

View File

@ -229,7 +229,7 @@ testing {
val options = this as TestNGOptions val options = this as TestNGOptions
options.preserveOrder = true options.preserveOrder = true
// options.excludeGroups("models", "mesher", "chunk", "input", "font", "command", "registry", "biome", "version", "fluid", "world", "raycasting", "pixlyzer", "item", "block", "physics", "light", "packet", "container", "item_stack", "signature", "private_key", "interaction", "item_digging", "chunk_renderer", "rendering", "texture", "atlas", "gui") // options.excludeGroups("models", "mesher", "chunk", "input", "font", "command", "registry", "biome", "version", "fluid", "world", "raycasting", "pixlyzer", "item", "block", "physics", "light", "packet", "container", "item_stack", "signature", "private_key", "interaction", "item_digging", "chunk_renderer", "rendering", "texture", "atlas", "gui")
options.excludeGroups("models", "chunk", "input", "font", "command", "registry", "biome", "version", "fluid", "world", "raycasting", "pixlyzer", "item", "physics", "light", "packet", "container", "item_stack", "signature", "private_key", "interaction", "item_digging", "chunk_renderer", "texture", "atlas", "gui") // options.excludeGroups("models", "chunk", "input", "font", "command", "registry", "biome", "version", "fluid", "world", "raycasting", "pixlyzer", "item", "physics", "light", "packet", "container", "item_stack", "signature", "private_key", "interaction", "item_digging", "chunk_renderer", "texture", "atlas", "gui")
} }
} }
} }

View File

@ -23,6 +23,7 @@ import de.bixilon.minosoft.gui.rendering.system.base.texture.array.StaticTexture
import de.bixilon.minosoft.gui.rendering.system.base.texture.array.TextureArrayStates import de.bixilon.minosoft.gui.rendering.system.base.texture.array.TextureArrayStates
import de.bixilon.minosoft.gui.rendering.system.base.texture.sprite.SpriteAnimator import de.bixilon.minosoft.gui.rendering.system.base.texture.sprite.SpriteAnimator
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture
import java.nio.ByteBuffer
class DummyStaticTextureArray(renderSystem: RenderSystem) : StaticTextureArray { class DummyStaticTextureArray(renderSystem: RenderSystem) : StaticTextureArray {
private val textures: MutableMap<ResourceLocation, Texture> = synchronizedMapOf() private val textures: MutableMap<ResourceLocation, Texture> = synchronizedMapOf()
@ -52,6 +53,6 @@ class DummyStaticTextureArray(renderSystem: RenderSystem) : StaticTextureArray {
override fun activate() { override fun activate() {
} }
override fun use(shader: NativeShader, name: String) { override fun use(shader: NativeShader, name: String) = Unit
} override fun dump(texture: Texture): ByteBuffer = throw UnsupportedOperationException()
} }

View File

@ -32,7 +32,7 @@ class EntityRenderInfo(private val entity: Entity) : Drawable, Tickable {
private var eyeHeight0 = 0.0f private var eyeHeight0 = 0.0f
private var eyeHeight1 = entity.eyeHeight private var eyeHeight1 = eyeHeight0
var position: Vec3d = position1 var position: Vec3d = position1
private set private set

View File

@ -18,6 +18,7 @@ import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.gui.rendering.system.base.texture.sprite.SpriteAnimator import de.bixilon.minosoft.gui.rendering.system.base.texture.sprite.SpriteAnimator
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.file.PNGTexture import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.file.PNGTexture
import java.nio.ByteBuffer
interface StaticTextureArray : TextureArray { interface StaticTextureArray : TextureArray {
val animator: SpriteAnimator val animator: SpriteAnimator
@ -30,4 +31,6 @@ interface StaticTextureArray : TextureArray {
fun createTexture(resourceLocation: ResourceLocation, mipmaps: Boolean = true, properties: Boolean = true, default: (mipmaps: Boolean) -> Texture = { PNGTexture(resourceLocation, mipmaps = it) }): Texture fun createTexture(resourceLocation: ResourceLocation, mipmaps: Boolean = true, properties: Boolean = true, default: (mipmaps: Boolean) -> Texture = { PNGTexture(resourceLocation, mipmaps = it) }): Texture
fun load(latch: AbstractLatch) fun load(latch: AbstractLatch)
fun dump(texture: Texture): ByteBuffer
} }

View File

@ -41,10 +41,12 @@ import de.bixilon.minosoft.util.json.Jackson
import de.bixilon.minosoft.util.logging.Log import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogLevels import de.bixilon.minosoft.util.logging.LogLevels
import de.bixilon.minosoft.util.logging.LogMessageType import de.bixilon.minosoft.util.logging.LogMessageType
import org.lwjgl.BufferUtils
import org.lwjgl.opengl.GL12.* import org.lwjgl.opengl.GL12.*
import org.lwjgl.opengl.GL13.GL_TEXTURE0 import org.lwjgl.opengl.GL13.GL_TEXTURE0
import org.lwjgl.opengl.GL13.glActiveTexture import org.lwjgl.opengl.GL13.glActiveTexture
import org.lwjgl.opengl.GL30.GL_TEXTURE_2D_ARRAY import org.lwjgl.opengl.GL30.GL_TEXTURE_2D_ARRAY
import org.lwjgl.opengl.GL45.glGetTextureSubImage
import java.nio.ByteBuffer import java.nio.ByteBuffer
import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicInteger
@ -245,6 +247,19 @@ class OpenGLTextureArray(
} }
} }
override fun dump(texture: Texture): ByteBuffer {
val shaderId = texture.shaderId
val level = 0
val buffer = BufferUtils.createByteBuffer(texture.array.size * texture.array.size * 4)
// glBindTexture(GL_TEXTURE_2D_ARRAY, shaderId shr 28)
glGetTextureSubImage(textureIds[TEXTURE_RESOLUTION_ID_MAP.indexOf(texture.array.size)], 0, 0, 0, (shaderId shr 12) and 0xFFFFF, texture.array.size shr level, texture.array.size shr level, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer)
return buffer
}
companion object { companion object {
const val TEXTURE_MAX_RESOLUTION = 2048 const val TEXTURE_MAX_RESOLUTION = 2048

View File

@ -14,6 +14,7 @@
package de.bixilon.minosoft.gui.rendering.textures package de.bixilon.minosoft.gui.rendering.textures
import de.bixilon.kotlinglm.vec2.Vec2i import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.kutil.file.FileUtil.createParent
import de.bixilon.minosoft.data.registries.identified.ResourceLocation import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.data.registries.identified.ResourceLocationUtil.extend import de.bixilon.minosoft.data.registries.identified.ResourceLocationUtil.extend
import de.bixilon.minosoft.gui.rendering.chunk.mesh.ChunkMesh import de.bixilon.minosoft.gui.rendering.chunk.mesh.ChunkMesh
@ -26,7 +27,9 @@ import org.lwjgl.system.MemoryUtil
import java.awt.image.BufferedImage import java.awt.image.BufferedImage
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.io.DataOutputStream import java.io.DataOutputStream
import java.io.File
import java.io.InputStream import java.io.InputStream
import java.nio.ByteBuffer
import javax.imageio.ImageIO import javax.imageio.ImageIO
object TextureUtil { object TextureUtil {
@ -94,4 +97,30 @@ object TextureUtil {
readTexture2() readTexture2()
} }
} }
fun dump(file: File, size: Vec2i, buffer: ByteBuffer, alpha: Boolean, flipY: Boolean) {
val bufferedImage = BufferedImage(size.x, size.y, if (alpha) BufferedImage.TYPE_INT_ARGB else BufferedImage.TYPE_INT_RGB)
val components = if (alpha) 4 else 3
for (x in 0 until size.x) {
for (y in 0 until size.y) {
val index: Int = (x + size.x * y) * components
val red: Int = buffer[index].toInt() and 0xFF
val green: Int = buffer[index + 1].toInt() and 0xFF
val blue: Int = buffer[index + 2].toInt() and 0xFF
val targetY = if (flipY) size.y - (y + 1) else y
bufferedImage.setRGB(x, targetY, 0xFF shl 24 or (red shl 16) or (green shl 8) or blue)
if (alpha) {
val alpha = buffer[index + 3].toInt() and 0xFF
bufferedImage.alphaRaster.setSample(x, targetY, 0, alpha)
}
}
}
file.createParent()
ImageIO.write(bufferedImage, "png", file)
}
} }

View File

@ -17,7 +17,6 @@ import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.kutil.concurrent.pool.DefaultThreadPool import de.bixilon.kutil.concurrent.pool.DefaultThreadPool
import de.bixilon.kutil.concurrent.pool.ThreadPool import de.bixilon.kutil.concurrent.pool.ThreadPool
import de.bixilon.kutil.concurrent.pool.runnable.ForcePooledRunnable import de.bixilon.kutil.concurrent.pool.runnable.ForcePooledRunnable
import de.bixilon.kutil.file.FileUtil.createParent
import de.bixilon.kutil.file.FileUtil.slashPath import de.bixilon.kutil.file.FileUtil.slashPath
import de.bixilon.kutil.time.TimeUtil.millis import de.bixilon.kutil.time.TimeUtil.millis
import de.bixilon.minosoft.assets.util.AssetsOptions import de.bixilon.minosoft.assets.util.AssetsOptions
@ -31,10 +30,9 @@ import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.gui.screen.menu.confirmation.DeleteScreenshotDialog import de.bixilon.minosoft.gui.rendering.gui.gui.screen.menu.confirmation.DeleteScreenshotDialog
import de.bixilon.minosoft.gui.rendering.system.base.PixelTypes import de.bixilon.minosoft.gui.rendering.system.base.PixelTypes
import de.bixilon.minosoft.gui.rendering.textures.TextureUtil
import de.bixilon.minosoft.terminal.RunConfiguration import de.bixilon.minosoft.terminal.RunConfiguration
import java.awt.image.BufferedImage
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import javax.imageio.ImageIO
class ScreenshotTaker( class ScreenshotTaker(
@ -44,7 +42,7 @@ class ScreenshotTaker(
try { try {
val width = context.window.size.x val width = context.window.size.x
val height = context.window.size.y val height = context.window.size.y
val buffer = context.system.readPixels(Vec2i(0, 0), Vec2i(width, height), PixelTypes.RGBA) val buffer = context.system.readPixels(Vec2i(0, 0), Vec2i(width, height), PixelTypes.RGB)
val path = RunConfiguration.HOME_DIRECTORY.resolve("screenshots").resolve(context.connection.address.hostname) val path = RunConfiguration.HOME_DIRECTORY.resolve("screenshots").resolve(context.connection.address.hostname)
@ -60,22 +58,8 @@ class ScreenshotTaker(
DefaultThreadPool += ForcePooledRunnable(priority = ThreadPool.HIGHER) { DefaultThreadPool += ForcePooledRunnable(priority = ThreadPool.HIGHER) {
try { try {
val bufferedImage = BufferedImage(width, height, BufferedImage.TYPE_INT_RGB)
for (x in 0 until width) {
for (y in 0 until height) {
val index: Int = (x + width * y) * 4
val red: Int = buffer[index].toInt() and 0xFF
val green: Int = buffer[index + 1].toInt() and 0xFF
val blue: Int = buffer[index + 2].toInt() and 0xFF
bufferedImage.setRGB(x, height - (y + 1), 0xFF shl 24 or (red shl 16) or (green shl 8) or blue)
}
}
val file = path.resolve(filename).toFile() val file = path.resolve(filename).toFile()
file.createParent() TextureUtil.dump(file, Vec2i(width, height), buffer, false, true)
ImageIO.write(bufferedImage, "png", file)
var deleted = false var deleted = false
val component = BaseComponent() val component = BaseComponent()