mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-17 00:56:07 +09:00
shader seems working!; it's messed up by all the test codes but I commit anyway
This commit is contained in:
@@ -5,7 +5,7 @@ uniform sampler2D u_texture;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
uniform vec3 iResolution;
|
uniform vec2 iResolution;
|
||||||
uniform float flip;
|
uniform float flip;
|
||||||
uniform vec2 direction;
|
uniform vec2 direction;
|
||||||
|
|
||||||
|
|||||||
BIN
assets/testimage2.png
Normal file
BIN
assets/testimage2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
@@ -77,8 +77,9 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var worldDrawFrameBuffer = FrameBuffer(Pixmap.Format.RGBA8888, Gdx.graphics.width, Gdx.graphics.height, false)
|
var worldDrawFrameBuffer = FrameBuffer(Pixmap.Format.RGBA8888, Gdx.graphics.width, Gdx.graphics.height, false)
|
||||||
var lightmapFrameBuffer = FrameBuffer(Pixmap.Format.RGBA8888, Gdx.graphics.width.div(lightmapDownsample).ceilInt(), Gdx.graphics.height.div(lightmapDownsample).ceilInt(), false)
|
var lightmapFboA = FrameBuffer(Pixmap.Format.RGBA8888, Gdx.graphics.width.div(lightmapDownsample).ceilInt(), Gdx.graphics.height.div(lightmapDownsample).ceilInt(), false)
|
||||||
// lightmapFrameBuffer: used to smooth out lightmap using shader
|
var lightmapFboB = FrameBuffer(Pixmap.Format.RGBA8888, Gdx.graphics.width.div(lightmapDownsample).ceilInt(), Gdx.graphics.height.div(lightmapDownsample).ceilInt(), false)
|
||||||
|
|
||||||
|
|
||||||
//private lateinit var shader12BitCol: Shader // grab LibGDX if you want some shader
|
//private lateinit var shader12BitCol: Shader // grab LibGDX if you want some shader
|
||||||
//private lateinit var shaderBlur: Shader
|
//private lateinit var shaderBlur: Shader
|
||||||
@@ -370,6 +371,8 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val testTex = Texture("assets/test_texture.tga")
|
||||||
|
|
||||||
private fun renderGame(batch: SpriteBatch) {
|
private fun renderGame(batch: SpriteBatch) {
|
||||||
Gdx.gl.glClearColor(.157f, .157f, .157f, 0f)
|
Gdx.gl.glClearColor(.157f, .157f, .157f, 0f)
|
||||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
||||||
@@ -379,16 +382,6 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
|
|||||||
//batch.projectionMatrix = camera.combined
|
//batch.projectionMatrix = camera.combined
|
||||||
|
|
||||||
|
|
||||||
// clean the shit beforehand
|
|
||||||
worldDrawFrameBuffer.inAction {
|
|
||||||
Gdx.gl.glClearColor(0f,0f,0f,0f)
|
|
||||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
|
||||||
}
|
|
||||||
lightmapFrameBuffer.inAction {
|
|
||||||
Gdx.gl.glClearColor(0f,0f,0f,0f)
|
|
||||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Post-update; ones that needs everything is completed //
|
// Post-update; ones that needs everything is completed //
|
||||||
FeaturesDrawer.render(batch) //
|
FeaturesDrawer.render(batch) //
|
||||||
@@ -396,20 +389,42 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
|
|||||||
if (TerrarumGDX.getConfigBoolean("fullframelightupdate") or (TerrarumGDX.GLOBAL_RENDER_TIMER % 2 == 1)) { //
|
if (TerrarumGDX.getConfigBoolean("fullframelightupdate") or (TerrarumGDX.GLOBAL_RENDER_TIMER % 2 == 1)) { //
|
||||||
LightmapRenderer.fireRecalculateEvent() //
|
LightmapRenderer.fireRecalculateEvent() //
|
||||||
} //
|
} //
|
||||||
// end of post-update //
|
// end of post-update /
|
||||||
|
|
||||||
|
|
||||||
// now the actual drawing part //
|
|
||||||
lightmapFrameBuffer.inAction {
|
|
||||||
// TODO gaussian blur p=8
|
|
||||||
|
|
||||||
batch.shader = TerrarumGDX.shaderBlur
|
|
||||||
|
///////////////////
|
||||||
|
// blur lightmap //
|
||||||
|
///////////////////
|
||||||
|
val blurIterations = 16 // ideally, 4 * radius; must be even number -- odd number will flip the image
|
||||||
|
val blurRadius = 4f
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
lightmapFboA.inAction(null, null) {
|
||||||
|
Gdx.gl.glClearColor(0f, 0f, 0f, 0f)
|
||||||
|
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
||||||
|
}
|
||||||
|
|
||||||
|
lightmapFboA.inAction(null, null) {
|
||||||
|
Gdx.gl.glClearColor(0f, 0f, 0f, 0f)
|
||||||
|
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var blurWriteBuffer = lightmapFboA
|
||||||
|
var blurReadBuffer = lightmapFboB
|
||||||
|
|
||||||
|
|
||||||
|
KeyToggler.forceSet(Input.Keys.F6, false)
|
||||||
|
KeyToggler.forceSet(Input.Keys.F7, true)
|
||||||
|
|
||||||
|
|
||||||
|
// initialise readBuffer with untreated lightmap
|
||||||
|
blurReadBuffer.inAction(camera, batch) {
|
||||||
batch.inUse {
|
batch.inUse {
|
||||||
//batch.shader.setUniform3fv("iResolution", floatArrayOf(lightmapFrameBuffer.width.toFloat(), lightmapFrameBuffer.height.toFloat(), 0f), 0, 12)
|
|
||||||
//batch.shader.setUniformi("iChannel0", 0)
|
|
||||||
//batch.shader.setUniform2fv("direction", floatArrayOf(8f, 8f), 0, 8)
|
|
||||||
|
|
||||||
|
|
||||||
// using custom code for camera; this is obscure and tricky
|
// using custom code for camera; this is obscure and tricky
|
||||||
camera.position.set(WorldCamera.gdxCamX, WorldCamera.gdxCamY, 0f) // make camara work
|
camera.position.set(WorldCamera.gdxCamX, WorldCamera.gdxCamY, 0f) // make camara work
|
||||||
camera.update()
|
camera.update()
|
||||||
@@ -417,11 +432,67 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
|
|||||||
|
|
||||||
|
|
||||||
blendNormal()
|
blendNormal()
|
||||||
LightmapRenderer.draw(batch)
|
batch.color = Color.WHITE
|
||||||
|
//LightmapRenderer.draw(batch)
|
||||||
|
|
||||||
|
batch.draw(testTex, 0f, 0f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
worldDrawFrameBuffer.inAction {
|
|
||||||
|
for (i in 0..blurIterations - 1) {
|
||||||
|
blurWriteBuffer.inAction(camera, batch) {
|
||||||
|
|
||||||
|
batch.inUse {
|
||||||
|
val texture = if (i == 0)
|
||||||
|
testTex
|
||||||
|
else
|
||||||
|
blurReadBuffer.colorBufferTexture
|
||||||
|
|
||||||
|
texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
|
||||||
|
|
||||||
|
|
||||||
|
batch.shader = TerrarumGDX.shaderBlur
|
||||||
|
batch.shader.setUniformf("iResolution", blurWriteBuffer.width.toFloat(), blurWriteBuffer.height.toFloat())
|
||||||
|
batch.shader.setUniformf("flip", 1f)
|
||||||
|
if (i % 2 == 0)
|
||||||
|
batch.shader.setUniformf("direction", blurRadius, 0f)
|
||||||
|
else
|
||||||
|
batch.shader.setUniformf("direction", 0f, blurRadius)
|
||||||
|
|
||||||
|
|
||||||
|
batch.color = Color.WHITE
|
||||||
|
batch.draw(texture, 0f, 0f)
|
||||||
|
|
||||||
|
|
||||||
|
// swap
|
||||||
|
val t = blurWriteBuffer
|
||||||
|
blurWriteBuffer = blurReadBuffer
|
||||||
|
blurReadBuffer = t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TEST: passthru to writeBuffer
|
||||||
|
/*blurWriteBuffer.inAction(camera, batch) {
|
||||||
|
batch.inUse {
|
||||||
|
batch.color = Color.WHITE
|
||||||
|
batch.draw(testTex, 0f, 0f)
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////
|
||||||
|
// draw world to the FBO //
|
||||||
|
///////////////////////////
|
||||||
|
|
||||||
|
worldDrawFrameBuffer.inAction(camera, batch) {
|
||||||
|
Gdx.gl.glClearColor(0f,0f,0f,0f)
|
||||||
|
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
||||||
|
|
||||||
|
|
||||||
batch.inUse {
|
batch.inUse {
|
||||||
batch.shader = null
|
batch.shader = null
|
||||||
|
|
||||||
@@ -464,10 +535,14 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
|
|||||||
if (!KeyToggler.isOn(Input.Keys.F6)) { // F6 to disable lightmap draw
|
if (!KeyToggler.isOn(Input.Keys.F6)) { // F6 to disable lightmap draw
|
||||||
setCameraPosition(0f, 0f)
|
setCameraPosition(0f, 0f)
|
||||||
|
|
||||||
val lightTex = lightmapFrameBuffer.colorBufferTexture // TODO zoom!
|
val lightTex = blurWriteBuffer.colorBufferTexture // TODO zoom!
|
||||||
if (KeyToggler.isOn(Input.Keys.F7)) blendNormal()
|
if (KeyToggler.isOn(Input.Keys.F7)) blendNormal()
|
||||||
else blendMul()
|
else blendMul()
|
||||||
batch.draw(lightTex, 0f, 0f, lightTex.width * lightmapDownsample, lightTex.height * lightmapDownsample)
|
batch.color = Color.WHITE
|
||||||
|
//batch.draw(lightTex, 0f, 0f, lightTex.width * lightmapDownsample, lightTex.height * lightmapDownsample)
|
||||||
|
|
||||||
|
TerrarumGDX.fontGame.draw(batch, "Thumbnail:", 100f, 80f)
|
||||||
|
batch.draw(lightTex, 100f, 100f, 100f, 100f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -496,6 +571,8 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
|
|||||||
/////////////////////////
|
/////////////////////////
|
||||||
// draw to main screen //
|
// draw to main screen //
|
||||||
/////////////////////////
|
/////////////////////////
|
||||||
|
camera.setToOrtho(true, Gdx.graphics.width.toFloat(), Gdx.graphics.height.toFloat())
|
||||||
|
batch.projectionMatrix = camera.combined
|
||||||
batch.inUse {
|
batch.inUse {
|
||||||
batch.shader = null
|
batch.shader = null
|
||||||
|
|
||||||
@@ -1143,8 +1220,11 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
|
|||||||
override fun resize(width: Int, height: Int) {
|
override fun resize(width: Int, height: Int) {
|
||||||
worldDrawFrameBuffer.dispose()
|
worldDrawFrameBuffer.dispose()
|
||||||
worldDrawFrameBuffer = FrameBuffer(Pixmap.Format.RGBA8888, width, height, false)
|
worldDrawFrameBuffer = FrameBuffer(Pixmap.Format.RGBA8888, width, height, false)
|
||||||
lightmapFrameBuffer.dispose()
|
lightmapFboA.dispose()
|
||||||
lightmapFrameBuffer = FrameBuffer(Pixmap.Format.RGBA8888, width.div(lightmapDownsample).ceilInt(), height.div(lightmapDownsample).ceilInt(), false)
|
lightmapFboA = FrameBuffer(Pixmap.Format.RGBA8888, width.div(lightmapDownsample).ceilInt(), height.div(lightmapDownsample).ceilInt(), false)
|
||||||
|
lightmapFboB.dispose()
|
||||||
|
lightmapFboB = FrameBuffer(Pixmap.Format.RGBA8888, width.div(lightmapDownsample).ceilInt(), height.div(lightmapDownsample).ceilInt(), false)
|
||||||
|
|
||||||
|
|
||||||
// Set up viewport when window is resized
|
// Set up viewport when window is resized
|
||||||
initViewPort(width, height)
|
initViewPort(width, height)
|
||||||
|
|||||||
@@ -6,10 +6,7 @@ import com.badlogic.gdx.Screen
|
|||||||
import com.badlogic.gdx.assets.loaders.ShaderProgramLoader
|
import com.badlogic.gdx.assets.loaders.ShaderProgramLoader
|
||||||
import com.badlogic.gdx.backends.lwjgl.LwjglApplication
|
import com.badlogic.gdx.backends.lwjgl.LwjglApplication
|
||||||
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration
|
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.*
|
||||||
import com.badlogic.gdx.graphics.GL20
|
|
||||||
import com.badlogic.gdx.graphics.GL30
|
|
||||||
import com.badlogic.gdx.graphics.Texture
|
|
||||||
import com.badlogic.gdx.graphics.g2d.Batch
|
import com.badlogic.gdx.graphics.g2d.Batch
|
||||||
import com.badlogic.gdx.graphics.g2d.BitmapFont
|
import com.badlogic.gdx.graphics.g2d.BitmapFont
|
||||||
import com.badlogic.gdx.graphics.g2d.CpuSpriteBatch
|
import com.badlogic.gdx.graphics.g2d.CpuSpriteBatch
|
||||||
@@ -46,9 +43,9 @@ fun main(args: Array<String>) {
|
|||||||
config.foregroundFPS = TerrarumGDX.RENDER_FPS
|
config.foregroundFPS = TerrarumGDX.RENDER_FPS
|
||||||
config.backgroundFPS = TerrarumGDX.RENDER_FPS
|
config.backgroundFPS = TerrarumGDX.RENDER_FPS
|
||||||
//config.vSyncEnabled = true
|
//config.vSyncEnabled = true
|
||||||
config.resizable = true
|
config.resizable = false
|
||||||
config.width = 1072
|
config.width = 512//1072
|
||||||
config.height = 742
|
config.height = 512//742
|
||||||
config.backgroundFPS = 9999
|
config.backgroundFPS = 9999
|
||||||
config.foregroundFPS = 9999
|
config.foregroundFPS = 9999
|
||||||
//config.useGL30 = true
|
//config.useGL30 = true
|
||||||
@@ -297,7 +294,6 @@ object TerrarumGDX : ApplicationAdapter() {
|
|||||||
ShaderProgram.pedantic = false
|
ShaderProgram.pedantic = false
|
||||||
shaderBlur = ShaderProgram(Gdx.files.internal("assets/blur.vert"), Gdx.files.internal("assets/blur.frag"))
|
shaderBlur = ShaderProgram(Gdx.files.internal("assets/blur.vert"), Gdx.files.internal("assets/blur.frag"))
|
||||||
|
|
||||||
|
|
||||||
ModMgr // invoke Module Manager, will also invoke BlockCodex
|
ModMgr // invoke Module Manager, will also invoke BlockCodex
|
||||||
ItemCodex // invoke Item Codex
|
ItemCodex // invoke Item Codex
|
||||||
|
|
||||||
@@ -305,8 +301,9 @@ object TerrarumGDX : ApplicationAdapter() {
|
|||||||
|
|
||||||
|
|
||||||
ingame = StateInGameGDX(batch)
|
ingame = StateInGameGDX(batch)
|
||||||
ingame!!.enter()
|
|
||||||
currentScreen = ingame as Screen
|
currentScreen = ingame as Screen
|
||||||
|
ingame!!.enter()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun render() {
|
override fun render() {
|
||||||
@@ -522,8 +519,12 @@ inline fun ShapeRenderer.inUse(shapeRendererType: ShapeRenderer.ShapeType = Shap
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Use Batch inside of it! */
|
/** Use Batch inside of it! */
|
||||||
inline fun FrameBuffer.inAction(action: (FrameBuffer) -> Unit) {
|
inline fun FrameBuffer.inAction(camera: OrthographicCamera?, batch: SpriteBatch?, action: (FrameBuffer) -> Unit) {
|
||||||
this.begin()
|
this.begin()
|
||||||
|
camera?.setToOrtho(true, this.width.toFloat(), this.height.toFloat())
|
||||||
|
camera?.position?.set(this.width / 2f, this.height / 2f, 0f) // are these actually needed?
|
||||||
|
camera?.update() // are these actually needed?
|
||||||
|
batch?.projectionMatrix = camera?.combined
|
||||||
action(this)
|
action(this)
|
||||||
this.end()
|
this.end()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,40 +2,50 @@ package net.torvald.terrarum
|
|||||||
|
|
||||||
import com.badlogic.gdx.ApplicationAdapter
|
import com.badlogic.gdx.ApplicationAdapter
|
||||||
import com.badlogic.gdx.Gdx
|
import com.badlogic.gdx.Gdx
|
||||||
|
import com.badlogic.gdx.Screen
|
||||||
import com.badlogic.gdx.backends.lwjgl.LwjglApplication
|
import com.badlogic.gdx.backends.lwjgl.LwjglApplication
|
||||||
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration
|
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration
|
||||||
import com.badlogic.gdx.graphics.GL20
|
import com.badlogic.gdx.graphics.*
|
||||||
import com.badlogic.gdx.graphics.Pixmap
|
|
||||||
import com.badlogic.gdx.graphics.Texture
|
|
||||||
import com.badlogic.gdx.graphics.g2d.BitmapFont
|
import com.badlogic.gdx.graphics.g2d.BitmapFont
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
||||||
import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
||||||
import net.torvald.terrarumsansbitmap.gdx.GameFontBase
|
import net.torvald.terrarumsansbitmap.gdx.GameFontBase
|
||||||
import com.badlogic.gdx.graphics.OrthographicCamera
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2017-06-11.
|
* Created by minjaesong on 2017-06-11.
|
||||||
*/
|
*/
|
||||||
class TestTestTest : ApplicationAdapter() {
|
class TestTestTest(val batch: SpriteBatch) : Screen {
|
||||||
|
|
||||||
lateinit var batch: SpriteBatch
|
|
||||||
lateinit var img: Texture
|
lateinit var img: Texture
|
||||||
|
|
||||||
lateinit var gameFont: BitmapFont
|
lateinit var gameFont: BitmapFont
|
||||||
|
|
||||||
lateinit var blurShader: ShaderProgram
|
|
||||||
|
|
||||||
lateinit var blurFboA: FrameBuffer
|
lateinit var blurFboA: FrameBuffer
|
||||||
lateinit var blurFboB: FrameBuffer
|
lateinit var blurFboB: FrameBuffer
|
||||||
|
|
||||||
lateinit var cam: OrthographicCamera
|
lateinit var worldFbo: FrameBuffer
|
||||||
|
|
||||||
|
lateinit var camera: OrthographicCamera
|
||||||
|
|
||||||
|
// invert Y
|
||||||
|
fun initViewPort(width: Int, height: Int) {
|
||||||
|
// Set Y to point downwards
|
||||||
|
camera.setToOrtho(true, width.toFloat(), height.toFloat())
|
||||||
|
|
||||||
|
// Update camera matrix
|
||||||
|
camera.update()
|
||||||
|
|
||||||
|
// Set viewport to restrict drawing
|
||||||
|
Gdx.gl20.glViewport(0, 0, width, height)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun enter() {
|
||||||
|
// init view port
|
||||||
|
camera = OrthographicCamera(Gdx.graphics.width.toFloat(), Gdx.graphics.height.toFloat())
|
||||||
|
|
||||||
|
|
||||||
override fun create() {
|
|
||||||
batch = SpriteBatch()
|
|
||||||
img = Texture("assets/test_texture.tga")
|
img = Texture("assets/test_texture.tga")
|
||||||
|
|
||||||
gameFont = GameFontBase("assets/graphics/fonts/terrarum-sans-bitmap")
|
gameFont = GameFontBase("assets/graphics/fonts/terrarum-sans-bitmap")
|
||||||
@@ -45,20 +55,21 @@ class TestTestTest : ApplicationAdapter() {
|
|||||||
blurFboA = FrameBuffer(Pixmap.Format.RGBA8888, img.width, img.height, false)
|
blurFboA = FrameBuffer(Pixmap.Format.RGBA8888, img.width, img.height, false)
|
||||||
blurFboB = FrameBuffer(Pixmap.Format.RGBA8888, img.width, img.height, false)
|
blurFboB = FrameBuffer(Pixmap.Format.RGBA8888, img.width, img.height, false)
|
||||||
|
|
||||||
ShaderProgram.pedantic = false
|
worldFbo = FrameBuffer(Pixmap.Format.RGBA8888, Gdx.graphics.width, Gdx.graphics.height, false)
|
||||||
blurShader = ShaderProgram(Gdx.files.internal("assets/blur.vert"), Gdx.files.internal("assets/blur.frag"))
|
|
||||||
|
|
||||||
blurShader.begin()
|
//blurShader.begin()
|
||||||
blurShader.setUniformf("iResolution", img.width.toFloat(), img.height.toFloat(), 0f)
|
//blurShader.setUniformf("iResolution", img.width.toFloat(), img.height.toFloat(), 0f)
|
||||||
blurShader.end()
|
//blurShader.end()
|
||||||
|
|
||||||
|
|
||||||
cam = OrthographicCamera(Gdx.graphics.width.toFloat(), Gdx.graphics.height.toFloat())
|
initViewPort(Gdx.graphics.width, Gdx.graphics.height)
|
||||||
cam.setToOrtho(false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun render() {
|
override fun render(delta: Float) {
|
||||||
val iterations = 16
|
Gdx.graphics.setTitle("TestTestTest — F: ${Gdx.graphics.framesPerSecond}")
|
||||||
|
|
||||||
|
|
||||||
|
val iterations = 16 // ideally, 4 * radius; must be even number -- odd number will flip the image
|
||||||
val radius = 4f
|
val radius = 4f
|
||||||
|
|
||||||
|
|
||||||
@@ -66,12 +77,12 @@ class TestTestTest : ApplicationAdapter() {
|
|||||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
||||||
|
|
||||||
|
|
||||||
blurFboA.inAction {
|
blurFboA.inAction(null, null) {
|
||||||
Gdx.gl.glClearColor(0f, 0f, 0f, 0f)
|
Gdx.gl.glClearColor(0f, 0f, 0f, 0f)
|
||||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
||||||
}
|
}
|
||||||
|
|
||||||
blurFboB.inAction {
|
blurFboB.inAction(null, null) {
|
||||||
Gdx.gl.glClearColor(0f, 0f, 0f, 0f)
|
Gdx.gl.glClearColor(0f, 0f, 0f, 0f)
|
||||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
||||||
}
|
}
|
||||||
@@ -82,12 +93,9 @@ class TestTestTest : ApplicationAdapter() {
|
|||||||
|
|
||||||
|
|
||||||
for (i in 0..iterations - 1) {
|
for (i in 0..iterations - 1) {
|
||||||
writeBuffer.inAction {
|
writeBuffer.inAction(camera, batch) {
|
||||||
|
|
||||||
batch.inUse {
|
batch.inUse {
|
||||||
cam.setToOrtho(false, writeBuffer.width.toFloat(), writeBuffer.height.toFloat())
|
|
||||||
batch.projectionMatrix = cam.combined
|
|
||||||
|
|
||||||
|
|
||||||
val texture = if (i == 0)
|
val texture = if (i == 0)
|
||||||
img
|
img
|
||||||
else
|
else
|
||||||
@@ -95,7 +103,9 @@ class TestTestTest : ApplicationAdapter() {
|
|||||||
|
|
||||||
texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
|
texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
|
||||||
|
|
||||||
batch.shader = blurShader
|
|
||||||
|
batch.shader = TestTestMain.blurShader
|
||||||
|
batch.shader.setUniformf("iResolution", writeBuffer.width.toFloat(), writeBuffer.height.toFloat())
|
||||||
batch.shader.setUniformf("flip", 1f)
|
batch.shader.setUniformf("flip", 1f)
|
||||||
if (i % 2 == 0)
|
if (i % 2 == 0)
|
||||||
batch.shader.setUniformf("direction", radius, 0f)
|
batch.shader.setUniformf("direction", radius, 0f)
|
||||||
@@ -103,7 +113,7 @@ class TestTestTest : ApplicationAdapter() {
|
|||||||
batch.shader.setUniformf("direction", 0f, radius)
|
batch.shader.setUniformf("direction", 0f, radius)
|
||||||
|
|
||||||
|
|
||||||
|
batch.color = Color.WHITE
|
||||||
batch.draw(texture, 0f, 0f)
|
batch.draw(texture, 0f, 0f)
|
||||||
|
|
||||||
|
|
||||||
@@ -115,16 +125,57 @@ class TestTestTest : ApplicationAdapter() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw last FBO to screen
|
|
||||||
batch.inUse {
|
worldFbo.inAction(camera, batch) {
|
||||||
cam.setToOrtho(false, Gdx.graphics.width.toFloat(), Gdx.graphics.height.toFloat())
|
Gdx.gl.glClearColor(0f,0f,0f,0f)
|
||||||
batch.projectionMatrix = cam.combined
|
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
||||||
|
|
||||||
|
batch.inUse {
|
||||||
|
batch.shader = null
|
||||||
|
|
||||||
|
camera.position.set(Gdx.graphics.width / 2f - 50f, Gdx.graphics.height / 2f - 50f, 0f)
|
||||||
|
camera.update()
|
||||||
|
batch.projectionMatrix = camera.combined
|
||||||
|
|
||||||
|
|
||||||
batch.shader.setUniformf("direction", 0f, 0f)
|
|
||||||
batch.shader.setUniformf("flip", if (iterations % 2 != 0) 1f else 0f)
|
batch.color = Color.WHITE
|
||||||
batch.draw(writeBuffer.colorBufferTexture, 0f, 0f)
|
batch.draw(writeBuffer.colorBufferTexture, 0f, 0f)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
camera.setToOrtho(true, Gdx.graphics.width.toFloat(), Gdx.graphics.height.toFloat())
|
||||||
|
batch.projectionMatrix = camera.combined
|
||||||
|
batch.inUse {
|
||||||
|
|
||||||
|
camera.position.set(Gdx.graphics.width / 2f, Gdx.graphics.height / 2f, 0f)
|
||||||
|
camera.update()
|
||||||
|
batch.projectionMatrix = camera.combined
|
||||||
|
|
||||||
|
|
||||||
|
batch.color = Color.WHITE
|
||||||
|
batch.draw(worldFbo.colorBufferTexture, 0f, 0f)
|
||||||
|
|
||||||
|
|
||||||
|
batch.draw(img, 0f, 0f, 100f, 100f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hide() {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun show() {
|
||||||
|
initViewPort(Gdx.graphics.width, Gdx.graphics.height)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun pause() {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun resume() {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun resize(width: Int, height: Int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun dispose() {
|
override fun dispose() {
|
||||||
@@ -133,18 +184,42 @@ class TestTestTest : ApplicationAdapter() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private inline fun SpriteBatch.inUse(action: () -> Unit) {
|
}
|
||||||
this.begin()
|
|
||||||
action()
|
object TestTestMain : ApplicationAdapter() {
|
||||||
this.end()
|
lateinit var blurShader: ShaderProgram
|
||||||
|
lateinit var batch: SpriteBatch
|
||||||
|
|
||||||
|
lateinit var currentScreen: TestTestTest
|
||||||
|
|
||||||
|
override fun create() {
|
||||||
|
ShaderProgram.pedantic = false
|
||||||
|
blurShader = ShaderProgram(Gdx.files.internal("assets/blur.vert"), Gdx.files.internal("assets/blur.frag"))
|
||||||
|
|
||||||
|
// culprit #4
|
||||||
|
blurShader.begin()
|
||||||
|
blurShader.setUniformf("dir", 0f, 0f); //direction of blur; nil for now
|
||||||
|
blurShader.setUniformf("resolution", maxOf(Gdx.graphics.width.toFloat(), Gdx.graphics.height.toFloat())) //size of FBO texture
|
||||||
|
blurShader.setUniformf("radius", 9f) //radius of blur
|
||||||
|
blurShader.end()
|
||||||
|
|
||||||
|
Gdx.graphics.isContinuousRendering = true // culprit #3
|
||||||
|
|
||||||
|
|
||||||
|
batch = SpriteBatch()
|
||||||
|
|
||||||
|
|
||||||
|
currentScreen = TestTestTest(batch)
|
||||||
|
currentScreen.enter()
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun FrameBuffer.inAction(action: (FrameBuffer) -> Unit) {
|
override fun render() {
|
||||||
this.begin()
|
currentScreen.render(Gdx.graphics.deltaTime)
|
||||||
action(this)
|
|
||||||
this.end()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun dispose() {
|
||||||
|
currentScreen.dispose()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main(args: Array<String>) { // LWJGL 3 won't work? java.lang.VerifyError
|
fun main(args: Array<String>) { // LWJGL 3 won't work? java.lang.VerifyError
|
||||||
@@ -155,5 +230,5 @@ fun main(args: Array<String>) { // LWJGL 3 won't work? java.lang.VerifyError
|
|||||||
config.width = 1072
|
config.width = 1072
|
||||||
config.height = 742
|
config.height = 742
|
||||||
config.foregroundFPS = 9999
|
config.foregroundFPS = 9999
|
||||||
LwjglApplication(TestTestTest(), config)
|
LwjglApplication(TestTestMain, config)
|
||||||
}
|
}
|
||||||
@@ -83,14 +83,6 @@ class UIBasicNotifier(private val player: ActorHumanoid?) : UICanvas {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun render(batch: SpriteBatch) {
|
override fun render(batch: SpriteBatch) {
|
||||||
// backplate
|
|
||||||
batch.draw(atlas.get(0, 0), 0f, 0f)
|
|
||||||
|
|
||||||
// because what the fuck (rendered darker than what it supposed to be)
|
|
||||||
/*blendScreen()
|
|
||||||
batch.color = Color(0x0c0c0c_ff)
|
|
||||||
batch.draw(atlas.get(0, 1), 0f, 0f)*/
|
|
||||||
|
|
||||||
// light overlay or EL
|
// light overlay or EL
|
||||||
if (ELon) {
|
if (ELon) {
|
||||||
blendNormal()
|
blendNormal()
|
||||||
@@ -108,9 +100,11 @@ class UIBasicNotifier(private val player: ActorHumanoid?) : UICanvas {
|
|||||||
else {
|
else {
|
||||||
lightLevel = TerrarumGDX.ingame!!.world.globalLight.normaliseToColour()
|
lightLevel = TerrarumGDX.ingame!!.world.globalLight.normaliseToColour()
|
||||||
}
|
}
|
||||||
blendMul()
|
|
||||||
|
|
||||||
|
// backplate
|
||||||
batch.color = lightLevel
|
batch.color = lightLevel
|
||||||
batch.draw(atlas.get(0, 1), 0f, 0f)
|
batch.draw(atlas.get(0, 0), 0f, 0f)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LCD back
|
// LCD back
|
||||||
|
|||||||
@@ -58,14 +58,6 @@ class UITierOneWatch(private val player: ActorHumanoid?) : UICanvas {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun render(batch: SpriteBatch) {
|
override fun render(batch: SpriteBatch) {
|
||||||
// backplate
|
|
||||||
batch.draw(atlas.get(0, 0), 0f, 0f)
|
|
||||||
|
|
||||||
// because what the fuck (rendered darker than what it supposed to be)
|
|
||||||
/*blendScreen()
|
|
||||||
batch.color = Color(0x0c0c0c_ff)
|
|
||||||
batch.draw(atlas.get(0, 1), 0f, 0f)*/
|
|
||||||
|
|
||||||
// light overlay or EL
|
// light overlay or EL
|
||||||
if (ELon) {
|
if (ELon) {
|
||||||
blendNormal()
|
blendNormal()
|
||||||
@@ -83,9 +75,10 @@ class UITierOneWatch(private val player: ActorHumanoid?) : UICanvas {
|
|||||||
else {
|
else {
|
||||||
lightLevel = TerrarumGDX.ingame!!.world.globalLight.normaliseToColour()
|
lightLevel = TerrarumGDX.ingame!!.world.globalLight.normaliseToColour()
|
||||||
}
|
}
|
||||||
blendMul()
|
|
||||||
|
// backplate
|
||||||
batch.color = lightLevel
|
batch.color = lightLevel
|
||||||
batch.draw(atlas.get(0, 1), 0f, 0f)
|
batch.draw(atlas.get(0, 0), 0f, 0f)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LCD back
|
// LCD back
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import net.torvald.terrarum.gameactors.ActorWithPhysics
|
|||||||
import net.torvald.terrarum.gameworld.GameWorld
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
import net.torvald.terrarum.blockproperties.Block
|
import net.torvald.terrarum.blockproperties.Block
|
||||||
import net.torvald.terrarum.fillRect
|
import net.torvald.terrarum.fillRect
|
||||||
|
import net.torvald.terrarum.gameactors.roundInt
|
||||||
import net.torvald.terrarum.inUse
|
import net.torvald.terrarum.inUse
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -285,10 +286,10 @@ object LightmapRenderer {
|
|||||||
* sample ambient for eight points and apply attenuation for those
|
* sample ambient for eight points and apply attenuation for those
|
||||||
* maxblend eight values and use it
|
* maxblend eight values and use it
|
||||||
*/
|
*/
|
||||||
/* + */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLight(x - 1, y - 1) ?: 0, scaleColour(thisTileOpacity, 1.4142f))
|
/* + */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLight(x - 1, y - 1) ?: 0, scaleSqrt2(thisTileOpacity))
|
||||||
/* + */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLight(x + 1, y - 1) ?: 0, scaleColour(thisTileOpacity, 1.4142f))
|
/* + */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLight(x + 1, y - 1) ?: 0, scaleSqrt2(thisTileOpacity))
|
||||||
/* + */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLight(x - 1, y + 1) ?: 0, scaleColour(thisTileOpacity, 1.4142f))
|
/* + */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLight(x - 1, y + 1) ?: 0, scaleSqrt2(thisTileOpacity))
|
||||||
/* + */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLight(x + 1, y + 1) ?: 0, scaleColour(thisTileOpacity, 1.4142f))
|
/* + */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLight(x + 1, y + 1) ?: 0, scaleSqrt2(thisTileOpacity))
|
||||||
|
|
||||||
/* * */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLight(x , y - 1) ?: 0, thisTileOpacity)
|
/* * */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLight(x , y - 1) ?: 0, thisTileOpacity)
|
||||||
/* * */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLight(x , y + 1) ?: 0, thisTileOpacity)
|
/* * */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLight(x , y + 1) ?: 0, thisTileOpacity)
|
||||||
@@ -462,17 +463,25 @@ object LightmapRenderer {
|
|||||||
// use equation with magic number 8.0
|
// use equation with magic number 8.0
|
||||||
// should draw somewhat exponential curve when you plot the propagation of light in-game
|
// should draw somewhat exponential curve when you plot the propagation of light in-game
|
||||||
|
|
||||||
return ((data.r() * (1f - darken.r() * lightScalingMagic)).clampZero() * CHANNEL_MAX).round() * MUL_2 +
|
return ((data.r() * (1f - darken.r() * lightScalingMagic)).clampZero() * CHANNEL_MAX).round().shl(20) or
|
||||||
((data.g() * (1f - darken.g() * lightScalingMagic)).clampZero() * CHANNEL_MAX).round() * MUL +
|
((data.g() * (1f - darken.g() * lightScalingMagic)).clampZero() * CHANNEL_MAX).round().shl(10) or
|
||||||
((data.b() * (1f - darken.b() * lightScalingMagic)).clampZero() * CHANNEL_MAX).round()
|
((data.b() * (1f - darken.b() * lightScalingMagic)).clampZero() * CHANNEL_MAX).round()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun scaleColour(data: Int, scale: Float): RGB10 {
|
fun scaleColour(data: Int, scale: Float): RGB10 {
|
||||||
return ((data.r() * scale).clampOne() * CHANNEL_MAX).round() * MUL_2 +
|
return ((data.r() * scale).clampOne() * CHANNEL_MAX).round().shl(20) or
|
||||||
((data.g() * scale).clampOne() * CHANNEL_MAX).round() * MUL +
|
((data.g() * scale).clampOne() * CHANNEL_MAX).round().shl(10) or
|
||||||
((data.b() * scale).clampOne() * CHANNEL_MAX).round()
|
((data.b() * scale).clampOne() * CHANNEL_MAX).round()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun scaleSqrt2(data: Int): RGB10 {
|
||||||
|
return scaleSqrt2Lookup[data.rawR()].shl(20) or
|
||||||
|
scaleSqrt2Lookup[data.rawG()].shl(10) or
|
||||||
|
scaleSqrt2Lookup[data.rawB()]
|
||||||
|
}
|
||||||
|
|
||||||
|
private val scaleSqrt2Lookup = IntArray(MUL, { it -> minOf(MUL - 1, (it * 1.41421356).roundInt()) })
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add each channel's RGB value.
|
* Add each channel's RGB value.
|
||||||
*
|
*
|
||||||
@@ -559,37 +568,37 @@ object LightmapRenderer {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private infix fun RGB10.maxBlend(other: Int): RGB10 {
|
private infix fun RGB10.maxBlend(other: Int): RGB10 {
|
||||||
return (if (this.rawR() > other.rawR()) this.rawR() else other.rawR()) * MUL_2 +
|
return (if (this.rawR() > other.rawR()) this.rawR() else other.rawR()).shl(20) or
|
||||||
(if (this.rawG() > other.rawG()) this.rawG() else other.rawG()) * MUL +
|
(if (this.rawG() > other.rawG()) this.rawG() else other.rawG()).shl(10) or
|
||||||
(if (this.rawB() > other.rawB()) this.rawB() else other.rawB())
|
(if (this.rawB() > other.rawB()) this.rawB() else other.rawB())
|
||||||
}
|
}
|
||||||
|
|
||||||
private infix fun RGB10.linMix(other: Int): RGB10 {
|
private infix fun RGB10.linMix(other: Int): RGB10 {
|
||||||
return ((this.rawR() + other.rawR()) ushr 1) * MUL_2 +
|
return ((this.rawR() + other.rawR()) ushr 1).shl(20) or
|
||||||
((this.rawG() + other.rawG()) ushr 1) * MUL +
|
((this.rawG() + other.rawG()) ushr 1).shl(10) or
|
||||||
((this.rawB() + other.rawB()) ushr 1)
|
((this.rawB() + other.rawB()) ushr 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
private infix fun RGB10.colSub(other: Int): RGB10 {
|
private infix fun RGB10.colSub(other: Int): RGB10 {
|
||||||
return ((this.rawR() - other.rawR()).clampChannel()) * MUL_2 +
|
return ((this.rawR() - other.rawR()).clampChannel()).shl(20) or
|
||||||
((this.rawG() - other.rawG()).clampChannel()) * MUL +
|
((this.rawG() - other.rawG()).clampChannel()).shl(10) or
|
||||||
((this.rawB() - other.rawB()).clampChannel())
|
((this.rawB() - other.rawB()).clampChannel())
|
||||||
}
|
}
|
||||||
|
|
||||||
private infix fun RGB10.colAdd(other: Int): RGB10 {
|
private infix fun RGB10.colAdd(other: Int): RGB10 {
|
||||||
return ((this.rawR() + other.rawR()).clampChannel()) * MUL_2 +
|
return ((this.rawR() + other.rawR()).clampChannel()).shl(20) or
|
||||||
((this.rawG() + other.rawG()).clampChannel()) * MUL +
|
((this.rawG() + other.rawG()).clampChannel()).shl(10) or
|
||||||
((this.rawB() + other.rawB()).clampChannel())
|
((this.rawB() + other.rawB()).clampChannel())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun RGB10.rawR() = this / MUL_2
|
inline fun RGB10.rawR() = this.ushr(20) and 1023
|
||||||
fun RGB10.rawG() = this % MUL_2 / MUL
|
inline fun RGB10.rawG() = this.ushr(10) and 1023
|
||||||
fun RGB10.rawB() = this % MUL
|
inline fun RGB10.rawB() = this and 1023
|
||||||
|
|
||||||
/** 0.0 - 1.0 for 0-1023 (0.0 - 0.25 for 0-255) */
|
/** 0.0 - 1.0 for 0-1023 (0.0 - 0.25 for 0-255) */
|
||||||
fun RGB10.r(): Float = this.rawR() / CHANNEL_MAX_FLOAT
|
inline fun RGB10.r(): Float = this.rawR() / CHANNEL_MAX_FLOAT
|
||||||
fun RGB10.g(): Float = this.rawG() / CHANNEL_MAX_FLOAT
|
inline fun RGB10.g(): Float = this.rawG() / CHANNEL_MAX_FLOAT
|
||||||
fun RGB10.b(): Float = this.rawB() / CHANNEL_MAX_FLOAT
|
inline fun RGB10.b(): Float = this.rawB() / CHANNEL_MAX_FLOAT
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
@@ -617,8 +626,8 @@ object LightmapRenderer {
|
|||||||
//if (g !in 0..CHANNEL_MAX) throw IllegalArgumentException("Green: out of range ($g)")
|
//if (g !in 0..CHANNEL_MAX) throw IllegalArgumentException("Green: out of range ($g)")
|
||||||
//if (b !in 0..CHANNEL_MAX) throw IllegalArgumentException("Blue: out of range ($b)")
|
//if (b !in 0..CHANNEL_MAX) throw IllegalArgumentException("Blue: out of range ($b)")
|
||||||
|
|
||||||
return r * MUL_2 +
|
return r.shl(20) or
|
||||||
g * MUL +
|
g.shl(10) or
|
||||||
b
|
b
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -627,8 +636,8 @@ object LightmapRenderer {
|
|||||||
//if (g < 0 || g > CHANNEL_MAX_DECIMAL) throw IllegalArgumentException("Green: out of range ($g)")
|
//if (g < 0 || g > CHANNEL_MAX_DECIMAL) throw IllegalArgumentException("Green: out of range ($g)")
|
||||||
//if (b < 0 || b > CHANNEL_MAX_DECIMAL) throw IllegalArgumentException("Blue: out of range ($b)")
|
//if (b < 0 || b > CHANNEL_MAX_DECIMAL) throw IllegalArgumentException("Blue: out of range ($b)")
|
||||||
|
|
||||||
return (r * CHANNEL_MAX).round() * MUL_2 +
|
return (r * CHANNEL_MAX).round().shl(20) or
|
||||||
(g * CHANNEL_MAX).round() * MUL +
|
(g * CHANNEL_MAX).round().shl(10) or
|
||||||
(b * CHANNEL_MAX).round()
|
(b * CHANNEL_MAX).round()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user