mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-08 04:41:51 +09:00
working UV simulation using alpha channel
This commit is contained in:
@@ -102,5 +102,5 @@ val kappa = 24389f/27f
|
||||
* u, v: -100+ - 100+
|
||||
* (Hundred-based-plus)
|
||||
*/
|
||||
data class CIELab(var L: Float = 0f, var a: Float = 0f, var b: Float = 0f, val alpha: Float = 1f)
|
||||
data class CIELab(var L: Float = 0f, var a: Float = 0f, var b: Float = 0f, var alpha: Float = 1f)
|
||||
|
||||
|
||||
@@ -108,4 +108,4 @@ fun CIELuv.toColor() = this.toXYZ().toColor()
|
||||
* u, v: -100+ - 100+
|
||||
* (Hundred-based-plus)
|
||||
*/
|
||||
data class CIELuv(var L: Float = 0f, var u: Float = 0f, var v: Float = 0f, val alpha: Float = 1f)
|
||||
data class CIELuv(var L: Float = 0f, var u: Float = 0f, var v: Float = 0f, var alpha: Float = 1f)
|
||||
|
||||
@@ -96,16 +96,16 @@ object CIEXYZUtil {
|
||||
}
|
||||
|
||||
/** Range: X, Y, Z: 0 - 1.0+ (One-based-plus) */
|
||||
data class CIEXYZ(var X: Float = 0f, var Y: Float = 0f, var Z: Float = 0f, val alpha: Float = 1f) {
|
||||
data class CIEXYZ(var X: Float = 0f, var Y: Float = 0f, var Z: Float = 0f, var alpha: Float = 1f) {
|
||||
init {
|
||||
if (X > 2f || Y > 2f || Z > 2f)
|
||||
throw IllegalArgumentException("Value range error - CIEXYZ is one-based (0.0 - 1.0+): ($X, $Y, $Z)")
|
||||
throw IllegalArgumentException("Value range error - this version of CIEXYZ is one-based (0.0 - 1.0+): ($X, $Y, $Z)")
|
||||
}
|
||||
}
|
||||
|
||||
/** Range: r, g, b: 0 - 1.0 (One-based) */
|
||||
data class RGB(var r: Float = 0f, var g: Float = 0f, var b: Float = 0f, val alpha: Float = 1f) {
|
||||
data class RGB(var r: Float = 0f, var g: Float = 0f, var b: Float = 0f, var alpha: Float = 1f) {
|
||||
constructor(color: Color) : this() {
|
||||
r = color.r; g = color.g; b = color.b
|
||||
r = color.r; g = color.g; b = color.b; alpha = color.a
|
||||
}
|
||||
}
|
||||
@@ -9,33 +9,34 @@ import javax.naming.OperationNotSupportedException
|
||||
* Created by minjaesong on 2017-06-17.
|
||||
*/
|
||||
|
||||
typealias XRGB888 = Int
|
||||
|
||||
class GdxColorMap {
|
||||
|
||||
constructor(imageFile: FileHandle) {
|
||||
val pixmap = Pixmap(imageFile)
|
||||
width = pixmap.width
|
||||
height = pixmap.height
|
||||
is2D = pixmap.height == 1
|
||||
is2D = pixmap.height > 1
|
||||
|
||||
data = kotlin.IntArray(pixmap.width * pixmap.height, {
|
||||
pixmap.getPixel(it % pixmap.width, it / pixmap.width)
|
||||
})
|
||||
|
||||
|
||||
println("[GdxColorMap] Loading colormap from ${imageFile.name()}; PixmapFormat: ${pixmap.format}; Dimension: $width x $height")
|
||||
|
||||
|
||||
pixmap.dispose()
|
||||
}
|
||||
|
||||
constructor(xrgb888: XRGB888) {
|
||||
data = intArrayOf(xrgb888.shl(24) + xrgb888.shl(16) + xrgb888.shl(8) + 255)
|
||||
constructor(color: Color) {
|
||||
data = intArrayOf(color.toIntBits())
|
||||
width = 1
|
||||
height = 1
|
||||
is2D = false
|
||||
}
|
||||
|
||||
constructor(gradStart: XRGB888, gradEnd: XRGB888) {
|
||||
data = intArrayOf(gradStart.shl(24) + gradStart.shl(16) + gradStart.shl(8) + 255,
|
||||
gradEnd.shl(24) + gradEnd.shl(16) + gradEnd.shl(8) + 255)
|
||||
constructor(gradStart: Color, gradEnd: Color) {
|
||||
data = intArrayOf(gradStart.toIntBits(), gradEnd.toIntBits())
|
||||
width = 1
|
||||
height = 2
|
||||
is2D = true
|
||||
@@ -49,9 +50,9 @@ class GdxColorMap {
|
||||
|
||||
|
||||
fun get(x: Int, y: Int): Color = Color(data[y * width + x])
|
||||
operator fun get(x: Int): Color = if (!is2D) throw OperationNotSupportedException("This is 2D color map") else Color(data[x])
|
||||
operator fun get(x: Int): Color = if (is2D) throw OperationNotSupportedException("This is 2D color map") else Color(data[x])
|
||||
|
||||
fun getRaw(x: Int, y: Int): RGBA8888 = data[y * width + x]
|
||||
fun getRaw(x: Int): RGBA8888 = if (!is2D) throw OperationNotSupportedException("This is 2D color map") else data[x]
|
||||
fun getRaw(x: Int): RGBA8888 = if (is2D) throw OperationNotSupportedException("This is 2D color map") else data[x]
|
||||
|
||||
}
|
||||
@@ -152,6 +152,7 @@ class Ingame(val batch: SpriteBatch) : Screen {
|
||||
|
||||
var camera = OrthographicCamera(Terrarum.WIDTH.toFloat(), Terrarum.HEIGHT.toFloat())
|
||||
|
||||
/** Actually just a mesh of four vertices, two triangles -- not a literal glQuad */
|
||||
var fullscreenQuad = Mesh(
|
||||
true, 4, 6,
|
||||
VertexAttribute.Position(),
|
||||
@@ -675,12 +676,8 @@ class Ingame(val batch: SpriteBatch) : Screen {
|
||||
batch.color = Color.WHITE
|
||||
blendNormal()
|
||||
|
||||
Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // reset active textureunit to zero (i don't know tbh)
|
||||
|
||||
|
||||
Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // reset active textureunit to zero (i don't know tbh, but it won't work without this)
|
||||
batch.shader = null
|
||||
batch.color = Color.RED
|
||||
batch.fillRect(0f, 0f, 16f, 16f)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -711,9 +708,6 @@ class Ingame(val batch: SpriteBatch) : Screen {
|
||||
batch.draw(blendedTex, 0f, 0f, blendedTex.width.toFloat(), blendedTex.height.toFloat())
|
||||
|
||||
|
||||
batch.color = Color.GREEN
|
||||
batch.fillRect(16f, 16f, 16f, 16f)
|
||||
|
||||
|
||||
// an old code.
|
||||
/*batch.shader = null
|
||||
|
||||
@@ -11,7 +11,7 @@ class BlockProp {
|
||||
|
||||
var nameKey: String = ""
|
||||
|
||||
|
||||
/** 1.0f for 1023, 0.25f for 255 */
|
||||
var shadeColR = 0f
|
||||
var shadeColG = 0f
|
||||
var shadeColB = 0f
|
||||
@@ -33,6 +33,7 @@ class BlockProp {
|
||||
var isVertFriction: Boolean = false
|
||||
|
||||
|
||||
/** 1.0f for 1023, 0.25f for 255 */
|
||||
var lumColR = 0f
|
||||
var lumColG = 0f
|
||||
var lumColB = 0f
|
||||
|
||||
@@ -13,12 +13,13 @@ internal object SetGlobalLightOverride : ConsoleCommand {
|
||||
private set
|
||||
|
||||
override fun execute(args: Array<String>) {
|
||||
if (args.size == 4) {
|
||||
if (args.size == 5) {
|
||||
try {
|
||||
val r = args[1].toFloat()
|
||||
val g = args[2].toFloat()
|
||||
val b = args[3].toFloat()
|
||||
val GL = Color(r, g, b, 1f)
|
||||
val a = args[4].toFloat()
|
||||
val GL = Color(r, g, b, a)
|
||||
|
||||
lightOverride = true
|
||||
Terrarum.ingame!!.world.globalLight = GL
|
||||
@@ -37,6 +38,6 @@ internal object SetGlobalLightOverride : ConsoleCommand {
|
||||
}
|
||||
|
||||
override fun printUsage() {
|
||||
Echo("Usage: setgl [raw_value|r g b|“none”]")
|
||||
Echo("Usage: setgl [r g b a|“none”]")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
|
||||
if (houseDesignation != null) houseDesignation!!.clear()
|
||||
}
|
||||
|
||||
override var luminosity: Color
|
||||
override var color: Color
|
||||
get() = Color(
|
||||
(actorValue.getAsFloat(AVKey.LUMR) ?: 0f) / LightmapRenderer.MUL_FLOAT,
|
||||
(actorValue.getAsFloat(AVKey.LUMG) ?: 0f) / LightmapRenderer.MUL_FLOAT,
|
||||
|
||||
@@ -12,7 +12,7 @@ import java.util.*
|
||||
*/
|
||||
internal class FixtureTikiTorch : FixtureBase(), Luminous {
|
||||
|
||||
override var luminosity: Color
|
||||
override var color: Color
|
||||
get() = BlockCodex[Block.TORCH].luminosity
|
||||
set(value) {
|
||||
throw UnsupportedOperationException()
|
||||
|
||||
@@ -8,9 +8,11 @@ import com.badlogic.gdx.graphics.Color
|
||||
interface Luminous {
|
||||
|
||||
/**
|
||||
* Range of 0.0 - 4.0 for each channel
|
||||
*
|
||||
* Recommended implementation:
|
||||
*
|
||||
override var luminosity: Color
|
||||
override var color: Color
|
||||
get() = Color(
|
||||
(actorValue.getAsFloat(AVKey.LUMR) ?: 0f) / LightmapRenderer.MUL_FLOAT,
|
||||
(actorValue.getAsFloat(AVKey.LUMG) ?: 0f) / LightmapRenderer.MUL_FLOAT,
|
||||
@@ -24,7 +26,7 @@ interface Luminous {
|
||||
actorValue[AVKey.LUMA] = value.a * LightmapRenderer.MUL_FLOAT
|
||||
}
|
||||
*/
|
||||
var luminosity: Color
|
||||
var color: Color
|
||||
|
||||
/**
|
||||
* Arguments:
|
||||
|
||||
@@ -50,9 +50,9 @@ object PlayerBuilderSigrid {
|
||||
p.actorValue[AVKey.INTELLIGENT] = true
|
||||
|
||||
//p.actorValue[AVKey.LUMR] = 0.84
|
||||
//p.actorValue[AVKey.LUMR] = 0.93
|
||||
//p.actorValue[AVKey.LUMR] = 1.37
|
||||
p.actorValue[AVKey.LUMA] = 0.32
|
||||
//p.actorValue[AVKey.LUMG] = 0.93
|
||||
//p.actorValue[AVKey.LUMB] = 1.37
|
||||
//p.actorValue[AVKey.LUMA] = 1.93
|
||||
|
||||
p.actorValue[AVKey.BASEDEFENCE] = 141
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ open class ProjectileSimple(
|
||||
val speed: Int
|
||||
|
||||
|
||||
override var luminosity: Color
|
||||
override var color: Color
|
||||
get() = (bulletDatabase[type][OFFSET_LUMINOSITY] as Color).cpy()
|
||||
set(value) {
|
||||
}
|
||||
|
||||
@@ -11,13 +11,13 @@ class WeaponSwung(val itemID: Int) : ActorWithPhysics(Actor.RenderOrder.MIDTOP),
|
||||
/**
|
||||
* Recommended implementation:
|
||||
*
|
||||
override var luminosity: Int
|
||||
override var color: Int
|
||||
get() = actorValue.getAsInt(AVKey.LUMINOSITY) ?: 0
|
||||
set(value) {
|
||||
actorValue[AVKey.LUMINOSITY] = value
|
||||
}
|
||||
*/
|
||||
override var luminosity: Color
|
||||
override var color: Color
|
||||
get() = throw UnsupportedOperationException()
|
||||
set(value) {
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ class GameWorld(val width: Int, val height: Int) {
|
||||
/** Meter per second squared. Currently only the downward gravity is supported. No reverse gravity :p */
|
||||
var gravitation: Vector2 = Vector2(0.0, 9.8)
|
||||
/** 0.0..1.0+ */
|
||||
var globalLight = Color(0f,0f,0f,1f)
|
||||
var globalLight = Color(0f,0f,0f,0f)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ class UIBasicNotifier(private val player: ActorHumanoid?) : UICanvas {
|
||||
|
||||
|
||||
// backplate
|
||||
batch.color = lightLevel
|
||||
batch.color = Color(lightLevel.r, lightLevel.g, lightLevel.b, 1f)
|
||||
batch.draw(atlas.get(0, 0), 0f, 0f)
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ class UITierOneWatch(private val player: ActorHumanoid?) : UICanvas {
|
||||
}
|
||||
|
||||
// backplate
|
||||
batch.color = lightLevel
|
||||
batch.color = Color(lightLevel.r, lightLevel.g, lightLevel.b, 1f)
|
||||
batch.draw(atlas.get(0, 0), 0f, 0f)
|
||||
}
|
||||
|
||||
|
||||
@@ -89,14 +89,9 @@ object WeatherMixer {
|
||||
}
|
||||
globalLightNow.set(getGlobalLightOfTime(world.time.todaySeconds).mul(0.3f, 0.3f, 0.3f, 0.58f))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Color.set(other: Color) {
|
||||
this.r = other.r
|
||||
this.g = other.g
|
||||
this.b = other.b
|
||||
this.a = other.a
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,9 +105,7 @@ object WeatherMixer {
|
||||
|
||||
// calculate global light
|
||||
val globalLight = getGradientColour(skyboxColourMap, 2, timeNow)
|
||||
globalLightNow.r = globalLight.r
|
||||
globalLightNow.g = globalLight.g
|
||||
globalLightNow.b = globalLight.b
|
||||
globalLightNow.set(globalLight)
|
||||
|
||||
// draw skybox to provided graphics instance
|
||||
batch.end()
|
||||
@@ -140,7 +133,6 @@ object WeatherMixer {
|
||||
fun getGlobalLightOfTime(timeInSec: Int): Color =
|
||||
getGradientColour(currentWeather.skyboxGradColourMap, 2, timeInSec)
|
||||
|
||||
// TODO colour gradient load from image, store to array
|
||||
fun getGradientColour(colorMap: GdxColorMap, row: Int, timeInSec: Int): Color {
|
||||
val dataPointDistance = WorldTime.DAY_LENGTH / colorMap.width
|
||||
|
||||
@@ -150,7 +142,7 @@ object WeatherMixer {
|
||||
val colourThis = colorMap.get(phaseThis, row)
|
||||
val colourNext = colorMap.get(phaseNext, row)
|
||||
|
||||
// interpolate R, G and B
|
||||
// interpolate R, G, B and A
|
||||
val scale = (timeInSec % dataPointDistance).toFloat() / dataPointDistance // [0.0, 1.0]
|
||||
|
||||
val newCol = CIELabUtil.getGradient(scale, colourThis, colourNext)
|
||||
|
||||
@@ -80,7 +80,7 @@ object LightmapRenderer {
|
||||
return null
|
||||
}
|
||||
else {
|
||||
return Color(col.r * MUL_FLOAT, col.g * MUL_FLOAT, col.b * MUL_FLOAT, 1f)
|
||||
return Color(col.r * MUL_FLOAT, col.g * MUL_FLOAT, col.b * MUL_FLOAT, col.a * MUL_FLOAT)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,10 +244,13 @@ object LightmapRenderer {
|
||||
..lightBoxY.plus(lightBoxH).div(TILE_SIZE).floorInt()) {
|
||||
for (x in lightBoxX.div(TILE_SIZE).floorInt()
|
||||
..lightBoxX.plus(lightBoxW).div(TILE_SIZE).floorInt()) {
|
||||
lanternMap.add(Lantern(x, y, it.luminosity))
|
||||
|
||||
val normalisedColor = it.color.cpy().mul(DIV_FLOAT)
|
||||
|
||||
lanternMap.add(Lantern(x, y, normalisedColor))
|
||||
// Q&D fix for Roundworld anomaly
|
||||
lanternMap.add(Lantern(x + world.width, y, it.luminosity))
|
||||
lanternMap.add(Lantern(x - world.width, y, it.luminosity))
|
||||
lanternMap.add(Lantern(x + world.width, y, normalisedColor))
|
||||
lanternMap.add(Lantern(x - world.width, y, normalisedColor))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -268,7 +271,7 @@ object LightmapRenderer {
|
||||
val thisWall = Terrarum.ingame!!.world.getTileFromWall(x, y)
|
||||
val thisTileLuminosity = BlockCodex[thisTerrain].luminosity // already been div by four
|
||||
val thisTileOpacity = BlockCodex[thisTerrain].opacity // already been div by four
|
||||
val sunLight = Terrarum.ingame!!.world.globalLight.cpy().mul(DIV_FLOAT, DIV_FLOAT, DIV_FLOAT, DIV_FLOAT)
|
||||
val sunLight = Terrarum.ingame!!.world.globalLight.cpy().mul(DIV_FLOAT)
|
||||
|
||||
// MIX TILE
|
||||
// open air
|
||||
@@ -285,13 +288,12 @@ object LightmapRenderer {
|
||||
}
|
||||
// END MIX TILE
|
||||
|
||||
for (i in 0..lanternMap.size - 1) {
|
||||
for (i in 0 until lanternMap.size) {
|
||||
val lmap = lanternMap[i]
|
||||
if (lmap.posX == x && lmap.posY == y)
|
||||
lightLevelThis = lightLevelThis maxBlend lmap.luminosity // maximise to not exceed 1.0 with normal (<= 1.0) light
|
||||
lightLevelThis = lightLevelThis maxBlend lmap.color // maximise to not exceed 1.0 with normal (<= 1.0) light
|
||||
}
|
||||
|
||||
|
||||
if (!doNotCalculateAmbient) {
|
||||
// calculate ambient
|
||||
/* + * +
|
||||
@@ -310,11 +312,18 @@ object LightmapRenderer {
|
||||
/* * */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLightInternal(x - 1, y ) ?: Color(0f,0f,0f,0f), thisTileOpacity)
|
||||
/* * */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLightInternal(x + 1, y ) ?: Color(0f,0f,0f,0f), thisTileOpacity)
|
||||
|
||||
return lightLevelThis maxBlend ambientAccumulator
|
||||
val ret = lightLevelThis maxBlend ambientAccumulator
|
||||
|
||||
|
||||
|
||||
return ret
|
||||
}
|
||||
else {
|
||||
return lightLevelThis
|
||||
val ret = lightLevelThis
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun getLightForOpaque(x: Int, y: Int): Color? { // ...so that they wouldn't appear too dark
|
||||
@@ -415,7 +424,7 @@ object LightmapRenderer {
|
||||
data.r * (1f - darken.r * lightScalingMagic),//.clampZero(),
|
||||
data.g * (1f - darken.g * lightScalingMagic),//.clampZero(),
|
||||
data.b * (1f - darken.b * lightScalingMagic),//.clampZero(),
|
||||
data.a * (1f - darken.b * lightScalingMagic))
|
||||
data.a * (1f - darken.a * lightScalingMagic))
|
||||
}
|
||||
|
||||
private fun scaleSqrt2(data: Color): Color {
|
||||
@@ -438,7 +447,7 @@ object LightmapRenderer {
|
||||
data.r * (1f + brighten.r * lightScalingMagic),
|
||||
data.g * (1f + brighten.g * lightScalingMagic),
|
||||
data.b * (1f + brighten.b * lightScalingMagic),
|
||||
data.a * (1f + brighten.b * lightScalingMagic)
|
||||
data.a * (1f + brighten.a * lightScalingMagic)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -453,7 +462,7 @@ object LightmapRenderer {
|
||||
if (darken < 0 || darken > CHANNEL_MAX)
|
||||
throw IllegalArgumentException("darken: out of range ($darken)")
|
||||
|
||||
val darkenColoured = Color(darken, darken, darken, 1f)
|
||||
val darkenColoured = Color(darken, darken, darken, darken)
|
||||
return darkenColoured(data, darkenColoured)
|
||||
}
|
||||
|
||||
@@ -543,7 +552,7 @@ object LightmapRenderer {
|
||||
private fun purgeLightmap() {
|
||||
for (y in 0..LIGHTMAP_HEIGHT - 1) {
|
||||
for (x in 0..LIGHTMAP_WIDTH - 1) {
|
||||
lightmap[y][x] = Color(0f,0f,0f,1f)
|
||||
lightmap[y][x] = Color(0f,0f,0f,0f)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -559,12 +568,6 @@ object LightmapRenderer {
|
||||
inline fun Float.ceil() = FastMath.ceil(this)
|
||||
inline fun Int.even(): Boolean = this and 1 == 0
|
||||
inline fun Int.odd(): Boolean = this and 1 == 1
|
||||
/*inline fun Int.normaliseToColour(): Color = Color(
|
||||
Math.min(this.r(), 1f),
|
||||
Math.min(this.g(), 1f),
|
||||
Math.min(this.b(), 1f),
|
||||
1f
|
||||
)*/
|
||||
|
||||
// TODO: float LUT lookup using linear interpolation
|
||||
|
||||
@@ -665,7 +668,10 @@ object LightmapRenderer {
|
||||
1f
|
||||
)
|
||||
|
||||
data class Lantern(val posX: Int, val posY: Int, val luminosity: Color)
|
||||
/**
|
||||
* color values are normalised -- 0.0 to 1.0 for 0..1023
|
||||
*/
|
||||
data class Lantern(val posX: Int, val posY: Int, val color: Color)
|
||||
|
||||
private fun Color.nonZero() = this.r != 0f || this.g != 0f || this.b != 0f || this.a != 0f
|
||||
|
||||
|
||||
Reference in New Issue
Block a user