diff --git a/assets/tiling.frag b/assets/tiling.frag index 64dbc482a..e79ba0e16 100644 --- a/assets/tiling.frag +++ b/assets/tiling.frag @@ -12,20 +12,22 @@ varying vec2 v_texCoords; uniform sampler2D u_texture; +uniform vec2 screenDimension; +uniform vec2 tilesInAxes; -uniform vec2 tilemapSize; +uniform ivec2 tilemapDimension; uniform sampler2D tilemap; // MUST be RGBA8888 uniform sampler2D tilesAtlas; uniform sampler2D backgroundTexture; -uniform vec2 tileInAtlas = vec2(256, 256); -uniform vec2 atlasTexSize = vec2(4096, 4096); +uniform ivec2 tileInAtlas = ivec2(256, 256); +uniform ivec2 atlasTexSize = ivec2(4096, 4096); -uniform vec2 tileInDim; // vec2(tiles_in_horizontal, tiles_in_vertical) +//uniform vec2 tileInDim; // vec2(tiles_in_horizontal, tiles_in_vertical) uniform vec2 cameraTranslation = vec2(0, 0); // Y-flipped -uniform float tileSizeInPx = 16; +uniform int tileSizeInPx = 16; @@ -33,23 +35,32 @@ ivec2 getTileXY(int tileNumber) { return ivec2(tileNumber % int(tileInAtlas.x), tileNumber / int(tileInAtlas.x)); } +int getTileFromColor(vec4 color) { + return int(color.b * 255) + (int(color.g * 255) * 256) + (int(color.r * 255) * 65536); +} + void main() { // READ THE FUCKING MANUAL, YOU DONKEY !! // - // Without further code in either GDX or this shader, // - // Onscreen TILE COORD WILL BE UPSIDE DOWN (bottom first). // - // This is intended behaviour. // + // This code purposedly uses flipped fragcoord. // + // Make sure you don't use gl_FragCoord unknowingly! // - vec2 pxCoord = gl_FragCoord.xy + cameraTranslation; + // default gl_FragCoord takes half-integer (represeting centre of the pixel) -- could be useful for phys solver? + // This one, however, takes exact integer by rounding down. // + vec2 overscannedScreenDimension = tilesInAxes * tileSizeInPx; + vec2 flippedFragCoord = vec2(v_texCoords.x * screenDimension.x, (1 - v_texCoords.y) * screenDimension.y); // NO IVEC2!! + + vec2 pxCoord = flippedFragCoord.xy + cameraTranslation; + + mediump vec4 tileFromMap = texture2D(tilemap, flippedFragCoord / overscannedScreenDimension); // <- THE CULPRIT + int tile = getTileFromColor(tileFromMap); + - int tile = 0;// uses usual absolute tile ID for atlas (upper-left); sample from texture2D(tileAtlas, some more code); ivec2 tileXY = getTileXY(tile); - vec2 coordInTile = mod(pxCoord, tileSizeInPx) / tileSizeInPx; // 0..1 regardless of tile position in atlas - // flip Y of coordInTile // - coordInTile = vec2(coordInTile.x, 1 - coordInTile.y); + vec2 coordInTile = mod(pxCoord, tileSizeInPx) / tileSizeInPx; // 0..1 regardless of tile position in atlas highp vec2 singleTileSizeInUV = vec2(1) / tileInAtlas; // 0.00390625 highp vec2 uvCoordForTile = coordInTile * singleTileSizeInUV; // 0..0.00390625 regardless of tile position in atlas @@ -59,8 +70,9 @@ void main() { highp vec2 finalUVCoordForTile = uvCoordForTile + uvCoordOffset;// where we should be actually looking for in atlas, using UV coord (0..1) - gl_FragColor = vec4(texture2D(tilesAtlas, finalUVCoordForTile)); - + gl_FragColor = texture2D(tilesAtlas, finalUVCoordForTile); + //gl_FragColor = texture2D(tilemap, v_texCoords); // tilemap seems normal... + //gl_FragColor = tileFromMap; // <- oh, THIS WAS THE CULPRIT! diff --git a/src/net/torvald/terrarum/GlslTilingTest.kt b/src/net/torvald/terrarum/GlslTilingTest.kt index 823eff5f7..afd69d094 100644 --- a/src/net/torvald/terrarum/GlslTilingTest.kt +++ b/src/net/torvald/terrarum/GlslTilingTest.kt @@ -7,7 +7,10 @@ import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration import com.badlogic.gdx.graphics.* import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.glutils.ShaderProgram +import com.jme3.math.FastMath import net.torvald.terrarum.gameactors.ceilInt +import net.torvald.terrarum.gameactors.floor +import net.torvald.terrarum.gameactors.floorInt import net.torvald.terrarum.worlddrawer.BlocksDrawer import net.torvald.terrarumsansbitmap.gdx.GameFontBase @@ -39,6 +42,7 @@ object GlslTilingTest : ApplicationAdapter() { lateinit var fucktex: Texture val TILE_SIZE = 16 + val TILE_SIZEF = 16f lateinit var tilesBuffer: Pixmap @@ -66,8 +70,8 @@ object GlslTilingTest : ApplicationAdapter() { - val tilesInHorizontal = Gdx.graphics.width.toFloat() / TILE_SIZE - val tilesInVertical = Gdx.graphics.height.toFloat() / TILE_SIZE + val tilesInHorizontal = (Gdx.graphics.width.toFloat() / TILE_SIZE).ceil() + 1f + val tilesInVertical = (Gdx.graphics.height.toFloat() / TILE_SIZE).ceil() + 1f tilesQuad = Mesh( true, 4, 6, @@ -76,16 +80,16 @@ object GlslTilingTest : ApplicationAdapter() { VertexAttribute.TexCoords(0) ) - tilesQuad.setVertices(floatArrayOf( - 0f, 0f, 0f, 1f, 1f, 1f, 1f, 0f, 1f, - Gdx.graphics.width.toFloat(), 0f, 0f, 1f, 1f, 1f, 1f, 1f, 1f, - Gdx.graphics.width.toFloat(), Gdx.graphics.height.toFloat(), 0f, 1f, 1f, 1f, 1f, 1f, 0f, - 0f, Gdx.graphics.height.toFloat(), 0f, 1f, 1f, 1f, 1f, 0f, 0f + tilesQuad.setVertices(floatArrayOf( // WARNING! not ususal quads; TexCoords of Y is flipped + 0f, 0f, 0f, 1f, 1f, 1f, 1f, 0f, 0f, + Gdx.graphics.width.toFloat(), 0f, 0f, 1f, 1f, 1f, 1f, 1f, 0f, + Gdx.graphics.width.toFloat(), Gdx.graphics.height.toFloat(), 0f, 1f, 1f, 1f, 1f, 1f, 1f, + 0f, Gdx.graphics.height.toFloat(), 0f, 1f, 1f, 1f, 1f, 0f, 1f )) tilesQuad.setIndices(shortArrayOf(0, 1, 2, 2, 3, 0)) - tilesBuffer = Pixmap(tilesInHorizontal.ceilInt(), tilesInVertical.ceilInt(), Pixmap.Format.RGBA8888) + tilesBuffer = Pixmap(tilesInHorizontal.toInt(), tilesInVertical.toInt(), Pixmap.Format.RGBA8888) camera = OrthographicCamera(Gdx.graphics.width.toFloat(), Gdx.graphics.height.toFloat()) @@ -100,42 +104,52 @@ object GlslTilingTest : ApplicationAdapter() { tileAtlas = Texture(Gdx.files.internal("assets/terrain.tga"))//BlocksDrawer.tilesTerrain.texture - println(tilesBuffer.format) - // 0brrrrrrrr_gggggggg_bbbbbbbb_aaaaaaaa - for (x in 0 until tilesBuffer.width * tilesBuffer.height) { - val color = Color(0f, 1f/16f, 0f, 1f) - tilesBuffer.drawPixel(x / tilesBuffer.width, x % tilesBuffer.width, 0x00ff00ff) - } } override fun render() { Gdx.graphics.setTitle("GlslTilingTest — F: ${Gdx.graphics.framesPerSecond}") - Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()) - Gdx.gl.glClearColor(0f, 0f, 0f, 1f) + + // 0brrrrrrrr_gggggggg_bbbbbbbb_aaaaaaaa + for (y in 0 until tilesBuffer.height) { + for (x in 0 until tilesBuffer.width) { + val i = (y * 256) + x + val color = Color(i.shl(8).or(255)) + tilesBuffer.setColor(color) + tilesBuffer.drawPixel(x, y) + } + } + + + + + Gdx.gl.glViewport(0, 0, Gdx.graphics.width, Gdx.graphics.height) + Gdx.gl.glClearColor(1f, 0f, 1f, 1f) Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) Gdx.gl.glEnable(GL20.GL_TEXTURE_2D) Gdx.gl.glEnable(GL20.GL_BLEND) Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA) - val tilesInHorizontal = Gdx.graphics.width.toFloat() / TILE_SIZE - val tilesInVertical = Gdx.graphics.height.toFloat() / TILE_SIZE + val tilesInHorizontal = (Gdx.graphics.width.toFloat() / TILE_SIZE).ceil() + 1f + val tilesInVertical = (Gdx.graphics.height.toFloat() / TILE_SIZE).ceil() + 1f val tilesBufferAsTex = Texture(tilesBuffer) + tilesBufferAsTex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest) tilesBufferAsTex.bind(2) tileAtlas.bind(1) // for some fuck reason, it must be bound as last shader.begin() shader.setUniformMatrix("u_projTrans", batch.projectionMatrix)//camera.combined) + shader.setUniformf("screenDimension", Gdx.graphics.width.toFloat(), Gdx.graphics.height.toFloat()) shader.setUniformi("tilesAtlas", 1) shader.setUniformi("tilemap", 2) - shader.setUniformf("tilemapSize", tilesBuffer.width.toFloat(), tilesBuffer.height.toFloat()) - shader.setUniformf("tileInDim", tilesInHorizontal, tilesInVertical) - shader.setUniformf("cameraTranslation", 4f, 1f) + shader.setUniformi("tilemapDimension", tilesBuffer.width, tilesBuffer.height) + shader.setUniformf("tilesInAxes", tilesInHorizontal, tilesInVertical) + shader.setUniformf("cameraTranslation", 0f, 0f) tilesQuad.render(shader, GL20.GL_TRIANGLES) shader.end() tilesBufferAsTex.dispose() @@ -145,4 +159,6 @@ object GlslTilingTest : ApplicationAdapter() { override fun dispose() { shader.dispose() } -} \ No newline at end of file +} + +private fun Float.ceil(): Float = FastMath.ceil(this).toFloat()