littlektframework / littlekt

A multiplatform WebGPU 2D game framework written in Kotlin. Build your own game engine on top.
https://littlekt.com
Apache License 2.0
313 stars 12 forks source link

LittleKt rendering screen upside down. #235

Closed ValleyDragon888 closed 6 months ago

ValleyDragon888 commented 6 months ago

For some reason if you don't do batch.use(camera.viewProjection) {} and instead use batch.use() {} or

batch.begin()
// Code using batch
batch.end()

it renders the screen upside down. I'm not sure whether this is intended behaviour, or whether I'm misunderstanding, but here is a minimal reproductive example:

package com.game.template

import com.lehaine.littlekt.Context
import com.lehaine.littlekt.ContextListener
import com.lehaine.littlekt.graph.node.resource.HAlign
import com.lehaine.littlekt.graphics.Color
import com.lehaine.littlekt.graphics.Fonts
import com.lehaine.littlekt.graphics.g2d.SpriteBatch
import com.lehaine.littlekt.graphics.g2d.shape.ShapeRenderer
import com.lehaine.littlekt.graphics.g2d.use
import com.lehaine.littlekt.graphics.gl.ClearBufferMask
import com.lehaine.littlekt.graphics.toFloatBits
import com.lehaine.littlekt.math.geom.degrees
import com.lehaine.littlekt.math.geom.radians
import com.lehaine.littlekt.util.viewport.ExtendViewport
import kotlin.time.Duration.Companion.milliseconds

class Game(context: Context) : ContextListener(context) {

    override suspend fun Context.start() {
        val batch = SpriteBatch(this)
        val shapeRenderer = ShapeRenderer(batch)
        val viewport = ExtendViewport(960, 540)
        val camera = viewport.camera
        var rotation = 0.radians
        var rotationTimer = 0.milliseconds

        onResize { width, height ->
            viewport.update(width, height, context)
        }

        onRender { dt ->
            gl.clearColor(Color.DARK_GRAY)
            gl.clear(ClearBufferMask.COLOR_BUFFER_BIT)

            batch.use() {
                Fonts.default.draw(it, "Hello LittleKt!", 0f, 0f, align = HAlign.CENTER)
                shapeRenderer.filledRectangle(-50f, 50f, 100f, 50f, rotation, color = Color.RED.toFloatBits())
            }
            rotationTimer += dt
            if (rotationTimer > 10.milliseconds) {
                rotationTimer = 0.milliseconds
                rotation += 1.degrees
            }
        }
    }
}

This is just the example code modified.

ValleyDragon888 commented 6 months ago

Here is the repo: https://github.com/ValleyDragon888/minimalreproductiveexample (I used it to quickly open a codespace)

LeHaine commented 6 months ago

This makes sense. OpenGL uses a y-up axis, by default. LittleKt uses a y-down axis. Without passing in the matrix to OpenGL, it'll render with its default Ortho identity matrix.

Edit: As I look into this more I think we could update the initial matrix (when one isn't passed in) used in SpriteBatch and flip it to render correctly the first time.

ValleyDragon888 commented 6 months ago

Nice. When will this make it into LittleKt?

LeHaine commented 6 months ago

It's set for 0.9.1 but can be used immediately if you use the SNAPSHOT.