fucking finally... (needs cleanup)

This commit is contained in:
minjaesong
2017-08-27 23:47:30 +09:00
parent 3ffbb8bef6
commit 62c1f34b88
2 changed files with 65 additions and 37 deletions

View File

@@ -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!

View File

@@ -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()
}
}
}
private fun Float.ceil(): Float = FastMath.ceil(this).toFloat()