Untitled

mail@pastecode.io avatar
unknown
java
7 months ago
9.5 kB
6
Indexable
Never
package com.jpcodes.physics.screens;

import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.ScreenAdapter;
import com.badlogic.gdx.graphics.*;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g3d.ModelBatch;
import com.badlogic.gdx.graphics.g3d.utils.DepthShaderProvider;
import com.badlogic.gdx.graphics.glutils.FrameBuffer;
import com.badlogic.gdx.graphics.glutils.GLFrameBuffer.FrameBufferBuilder;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.utils.viewport.FitViewport;
import com.jpcodes.physics.BulletPhysicsSystem;
import com.jpcodes.physics.controllers.camera.CameraController;
import lombok.Getter;
import lombok.Setter;
import net.mgsx.gltf.scene3d.attributes.PBRCubemapAttribute;
import net.mgsx.gltf.scene3d.attributes.PBRTextureAttribute;
import net.mgsx.gltf.scene3d.lights.DirectionalLightEx;
import net.mgsx.gltf.scene3d.lights.PointLightEx;
import net.mgsx.gltf.scene3d.lights.SpotLightEx;
import net.mgsx.gltf.scene3d.scene.Scene;
import net.mgsx.gltf.scene3d.scene.SceneManager;
import net.mgsx.gltf.scene3d.scene.SceneSkybox;
import net.mgsx.gltf.scene3d.utils.IBLBuilder;

public class BaseScreen extends ScreenAdapter {

    private static final float SPRINT_FOV = 76f;
    private static final float NORMAL_FOV = 73f;

    private static boolean drawDebug = false;

    protected PerspectiveCamera camera;
    protected CameraController cameraController;
    protected ModelBatch modelBatch;
    protected ModelBatch shadowBatch;

    protected SceneManager sceneManager;
    protected SceneSkybox skybox;
    protected Scene scene;

    protected DirectionalLightEx light;

    protected Cubemap diffuseCubemap;
    protected Cubemap environmentCubemap;
    protected Cubemap specularCubemap;

    protected SpotLightEx spotLight;

    protected ShaderProgram shaderVHS;
    protected BulletPhysicsSystem physicsSystem;
    protected SpriteBatch spriteBatch;
    protected FrameBuffer frameBuffer;
    protected Game game;

    private final Skin ui_skinVHS;
    private final Stage ui_stage;
    private final Label ui_playButton;

    @Setter
    private String frameEvent = "None";
    
    @Getter
    private boolean paused;

    private float u_time;

    public BaseScreen(Game game) {
        this.game = game;
        this.physicsSystem = new BulletPhysicsSystem();

        sceneManager = new SceneManager();

        int screenWidth = Gdx.graphics.getWidth(), screenHeight = Gdx.graphics.getHeight();

        camera = new PerspectiveCamera(NORMAL_FOV, screenWidth, screenHeight);
        camera.fieldOfView = 73f;
        camera.near = 0.001f;
        camera.far = 100f;
        camera.position.set(0,10, 50f);

        // setup light
        light = new DirectionalLightEx();
        light.direction.set(1, -3, 1).nor();
        light.color.set(Color.WHITE);
        sceneManager.environment.add(light);

        spriteBatch = new SpriteBatch();
        spriteBatch.setProjectionMatrix(camera.combined);

        sceneManager = new SceneManager();
        sceneManager.setCamera(camera);

        // setup quick IBL (image based lighting)
        IBLBuilder iblBuilder = IBLBuilder.createOutdoor(light);
        environmentCubemap = iblBuilder.buildEnvMap(1024);
        diffuseCubemap = iblBuilder.buildIrradianceMap(256);
        specularCubemap = iblBuilder.buildRadianceMap(10);
        iblBuilder.dispose();

        // This texture is provided by the library, no need to have it in your assets.
        Texture brdfLUT = new Texture(Gdx.files.classpath("net/mgsx/gltf/shaders/brdfLUT.png"));

        sceneManager.setAmbientLight(0.005f);
        sceneManager.environment.set(new PBRTextureAttribute(PBRTextureAttribute.BRDFLUTTexture, brdfLUT));
        sceneManager.environment.set(PBRCubemapAttribute.createSpecularEnv(specularCubemap));
        sceneManager.environment.set(PBRCubemapAttribute.createDiffuseEnv(diffuseCubemap));
        sceneManager.environment.add(spotLight = new SpotLightEx().setDeg(Color.WHITE, new Vector3(), new Vector3(), 10f, 50f, 100f, 4f));

        // setup skybox
        sceneManager.setSkyBox(skybox = new SceneSkybox(environmentCubemap));

//        sceneManager.environment.add(new DirectionalShadowLight());

//        environment = new Environment();
//
//
//        environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.4f, 0.4f, 0.4f, 5f));
//        environment.add(pointLight = new PointLight().set(Color.RED, 2f, 10f, 2f, 10f));
//        environment.add(spotLight = new SpotLight().set(Color.WHITE, camera.position.cpy(), camera.direction.cpy(), 1f, 1f, 1f));
//        environment.add((shadowLight = new DirectionalShadowLight(2048, 2048, 30f, 30f, 1f, 100f)).set(0.8f, 0.8f, 0.8f, -.4f, -.4f, -.4f));
//        environment.shadowMap = shadowLight;

        ui_skinVHS = new Skin(Gdx.files.internal("skins/vhs/skin/vhs-ui.json"));
        ui_stage = new Stage(new FitViewport(screenWidth, screenHeight));

        ui_playButton = new Label("PLAY", ui_skinVHS.get("play", LabelStyle.class));
        ui_playButton.setFontScale(0.7f);
        ui_playButton.setSize(ui_playButton.getPrefWidth(), ui_playButton.getPrefHeight() * 0.7f);
        ui_playButton.setPosition(40, 650);
        ui_playButton.setText("PLAY");

        ui_stage.addActor(ui_playButton);

        createFBO(screenWidth, screenHeight);

        ShaderProgram.pedantic = false;

        shaderVHS = new ShaderProgram(
                Gdx.files.internal("shaders/vhs.vsh"),
                Gdx.files.internal("shaders/vhs.fsh")
        );

        if (!shaderVHS.isCompiled()) {
            Gdx.app.error("Shader", shaderVHS.getLog());
            throw new IllegalStateException(shaderVHS.getLog());
        }

        spriteBatch.setShader(shaderVHS);

        modelBatch = new ModelBatch(Gdx.files.classpath("com/badlogic/gdx/graphics/g3d/shaders/default.vertex.glsl"), Gdx.files.classpath("com/badlogic/gdx/graphics/g3d/shaders/default.fragment.glsl"));
        shadowBatch = new ModelBatch(new DepthShaderProvider());
    }

    @Override
    public void resize(int width, int height) {
        sceneManager.updateViewport(width, height);
        spriteBatch.getProjectionMatrix().setToOrtho2D(0, 0, width, height);
    }

    @Override
    public void render(float deltaTime) {
        if (Gdx.input.isKeyJustPressed(Input.Keys.ESCAPE)) {
            Gdx.input.setCursorPosition(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 2);
            paused = !paused;
            Gdx.input.setCursorCatched(!paused);
        }

        if (paused) {
            return;
        }

        spotLight.position.set(camera.position);
        spotLight.direction.set(camera.direction);

        u_time += deltaTime;

        if (Gdx.input.isKeyJustPressed(Input.Keys.F1)) {
            drawDebug = !drawDebug;
        }

        if (Gdx.input.isKeyPressed(Input.Keys.CONTROL_LEFT)) {
            if (camera.fieldOfView < SPRINT_FOV) {
                camera.fieldOfView += Math.min(0.2f, SPRINT_FOV - camera.fieldOfView);
            }
        } else {
            if (camera.fieldOfView > NORMAL_FOV) {
                camera.fieldOfView -= Math.min(0.2f, camera.fieldOfView - NORMAL_FOV);
            }
        }

        physicsSystem.update(deltaTime);
        cameraController.update(deltaTime);

        frameBuffer.begin();

        Gdx.gl20.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(
                GL20.GL_COLOR_BUFFER_BIT |
                GL20.GL_DEPTH_BUFFER_BIT | (Gdx.graphics.getBufferFormat()
                        .coverageSampling ? GL20.GL_COVERAGE_BUFFER_BIT_NV : 0)
        );

        sceneManager.update(deltaTime);
        sceneManager.render();

//
//        modelBatch.begin(camera);
//        modelBatch.render(renderInstances, environment);
//        modelBatch.end();

        ui_playButton.setText("Frame Event: " + frameEvent);
        ui_stage.act();
        ui_stage.draw();

        if (drawDebug) {
            physicsSystem.render(camera);
        }

//        shadowLight.begin(Vector3.Zero, camera.direction);
//        shadowBatch.begin(shadowLight.getCamera());
//        shadowBatch.render(renderInstances, environment);
//        shadowBatch.end();
//        shadowLight.end();

        frameBuffer.end();

        spriteBatch.begin();

        Texture texture = frameBuffer.getColorBufferTexture();

        shaderVHS.setUniformf("u_time", u_time);

        spriteBatch.draw(texture, 0, 0, texture.getWidth(), texture.getHeight(), 0, 0, 1, 1);
        spriteBatch.end();
    }

    public void setCameraController(CameraController cameraController) {
        this.cameraController = cameraController;
        Gdx.input.setInputProcessor(cameraController);
        Gdx.input.setCursorCatched(true);
    }

    protected void createFBO(int width, int height) {
        if (frameBuffer != null) {
            frameBuffer.dispose();
            frameBuffer = null;
        }

        FrameBufferBuilder builder = new FrameBufferBuilder(width, height);

        builder.addBasicColorTextureAttachment(Pixmap.Format.RGBA8888);
        builder.addDepthRenderBuffer(GL30.GL_DEPTH_COMPONENT24);

        frameBuffer = builder.build();
    }
}
Leave a Comment