(October 2021) Monthly WIP Screenshot Thread

Random stuff, including grass:

A room:

Horrible quality gif (can be “played” at the bottom right), showing how important grass blade texturing is (grass casting shadows is disabled here):
grass-rendered_900

Let’s call it “terrain”:

I’ve been continuing the work on my Vulkan engine after a few months of break lately - Mainly cleaning up and improving the implementations of water, shadows and gltf and now tackling a bit of world generation, in the form of tesselated grass and terrain. I also finally fixed my OBS settings, so the video quality should not be absolutely terrible this time, although the recording still lags when i turn the grass on ;_; No idea why, the actual application doesn’t even lag while recording - Maybe because I did a window capture instead of a game capture or something like that. In any case, the next step would be populating the fitting biomes in the world with grass, planting a few trees, rocks, etc. etc. - And then probably continue on actual important features^^

13 Likes

If you have the means to use Shadowplay (i.e. use NVIDIA card). I suggest that. The only tool that I have found not affecting the frame rates.

OBS using the nvidia hardware encoder seems pretty good.

There is also AMD ReLive, which is integrated in the Adrenalin display driver and uses hardware encoding.

2 Likes

Finaly a small contribution from me again, playing around with Deferred Randing
Imgur

Edit: See #1633 if you want to roll your own :slight_smile:

8 Likes

What do you intend to do with your Vulkan engine? I’ll have to build my own Vulkan engine if JMonkey doesn’t migrate to Vulkan, cause I need my game tools to be viable for the future.

1 Like

It will be available and free-to-use like any other open source engine - But it will still take a bit of time until it’s production ready.

The new Android CompatHarness, A migration of AndroidHarness to use androidx components :slight_smile:

The example of the implementation class :

package com.myGame.JMESurfaceViewExampleActivity.compatTest;

import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.Toast;
import androidx.cardview.widget.CardView;
import androidx.core.content.ContextCompat;
import com.jme3.app.LegacyApplication;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.myGame.R;
import com.scrappers.superiorExtendedEngine.jmeSurfaceView.compat.CompatHarness;

/**
 * An Android CompatHarness Migration test.
 * @author pavl_g.
 */
public class TestCompatHarness extends CompatHarness {

    @Override
    protected void preInitializeGlConfig() {
        //TODO define your egl, display and LayoutManager config here
        EGLConfig.setEglSurfaceDelay(2000);
        Display.setDisplayMode(Display.GAME_MODE);
        //TODO choose whether to bind the app life to the activity one or not, true if you want them bound, false otherwise
        bindAppState(false);
        LayoutManager.setLayoutManager(LayoutManager.Frame_Layout);
    }

    @Override
    protected Class<? extends LegacyApplication> getInstance() {
        //TODO return your game class here
        return CompatGame.class;
    }

    @Override
    protected View getSplashScreen() {
        //TODO define your splash screen here
        final CardView splashScreen = new CardView(this);
        splashScreen.setBackground(ContextCompat.getDrawable(this, R.mipmap.power1));
        return splashScreen;
    }

    @Override
    protected Vector3f getSplashScreenAnimationTranslation() {
        return new Vector3f();
    }

    @Override
    protected Vector2f getSplashScreenAnimationScale() {
        return new Vector2f(0,0);
    }

    @Override
    protected Vector2f getSplashScreenAnimationRotation() {
        return new Vector2f(40, 90);
    }

    @Override
    protected long getSplashScreenAnimationDuration() {
        return 1000;
    }

    @Override
    protected void onExceptionThrown(Throwable throwable) {
        //TODO catch and deal with exceptions/errors here
    }

    @Override
    protected void onStartRenderer(LegacyApplication app) {
        //TODO do something when the renderer starts
    }

    @Override
    protected void onRendererCompletion(LegacyApplication app) {
        //TODO do something when the renderer completes
    }

    @Override
    protected void onLayoutDrawn(LegacyApplication app, View layout) {
        //TODO do something when layout is drawn
        final FrameLayout relativeLayout = (FrameLayout) layout;
        final Button button = new Button(this);
        button.setText("Hello from Compat Harness !");
        button.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        button.setX(Display.getDisplayMetrics(this).widthPixels / 2f - 30);
        button.setY(Display.getDisplayMetrics(this).heightPixels / 2f - 30);
        button.setOnClickListener((view)-> Toast.makeText(TestCompatHarness.this, button.getText().toString(), Toast.LENGTH_SHORT).show());
        relativeLayout.addView(button);
    }

    @Override
    protected void onStopRenderer(LegacyApplication app) {
        //TODO do something when the renderer stops
    }

    @Override
    protected void onPauseRenderer(LegacyApplication app) {
        //TODO do something when the renderer is paused
    }

    @Override
    protected void onResumeRenderer(LegacyApplication app) {
        //TODO do something when the renderer is resumed
    }
}

New Features :

  • Define a LayoutManager to the system if you wish.
  • more lifecycle methods exposed from android & jme (under testing for safe exposure).
  • wrapped display related utils into Display enum.
  • wrapped egl configs into EGLConfig enum.
  • Introduced a defined way in which jme app instance can be independent of android life cycle, so when the activity terminates, jme doesn’t terminate through bindAppState(bool) flag.
  • Crash Dialog holds Copy Crash logs option (wip).
  • A better way to handle splash screens through the abstract factory method pattern View getSplashScreen() + splash screen animations.
  • Added onLayoutDrawn() life cycle method, where inside this factory method, you can build your own platform dependent (android) gui.

Bug Fixes

  • Passing simpleApplication instance through a Class<? extends LegacyApplication> getInstance() factory method for nullary constructor based classes.
  • Passing simpleApplication instance through a LegacyApplication setAppInstance() setter method for non-nullay constructors (for parameterized constructors).

And the system favors the getInstance() over the setInstance(), if they are both used, if one of them is null, then we use the other.

EDIT (Example of an easy to do quick gui) :

  @Override
    protected void onLayoutDrawn(LegacyApplication app, View layout) {
        //TODO do something when layout is drawn
        final RelativeLayout relativeLayout = (RelativeLayout) layout;
        final Button button = new Button(this);
        button.setText("Hello from Compat Harness !");
        button.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        button.setX(Display.getDisplayMetrics(this).widthPixels / 2f - 30);
        button.setY(Display.getDisplayMetrics(this).heightPixels / 2f - 30);
        button.setOnClickListener((view)-> Toast.makeText(TestCompatHarness.this, button.getText().toString(), Toast.LENGTH_SHORT).show());
        relativeLayout.addView(button);

        final GullWing gullWing = new GullWing(this);
        gullWing.setLayoutParams(new RelativeLayout.LayoutParams(400, 400));
        gullWing.setY(Display.getDisplayMetrics(this).heightPixels - (gullWing.getLayoutParams().height + 30));
        gullWing.setX(40);
        gullWing.initializeWheel();
        relativeLayout.addView(gullWing);

        final ControlButtonsView controlButtonsView = new ControlButtonsView(this);
        controlButtonsView.setLayoutParams(new RelativeLayout.LayoutParams(400, 400));
        controlButtonsView.setX(Display.getDisplayMetrics(this).widthPixels - (controlButtonsView.getLayoutParams().width + 30));
        controlButtonsView.setY(Display.getDisplayMetrics(this).heightPixels - (controlButtonsView.getLayoutParams().height + 30));
        controlButtonsView.addControlButton(ControlButtonsView.ButtonSignature.GAMEPAD_BUTTON_X, ControlButtonsView.ButtonStyle.DEFAULT_BUTTONS.STYLE, ControlButtonsView.ButtonIcon.X_BUTTON_ALPHA.ID);
        controlButtonsView.addControlButton(ControlButtonsView.ButtonSignature.GAMEPAD_BUTTON_Y, ControlButtonsView.ButtonStyle.DEFAULT_BUTTONS.STYLE, ControlButtonsView.ButtonIcon.Y_BUTTON_ALPHA.ID);
        controlButtonsView.addControlButton(ControlButtonsView.ButtonSignature.GAMEPAD_BUTTON_A, ControlButtonsView.ButtonStyle.DEFAULT_BUTTONS.STYLE, ControlButtonsView.ButtonIcon.A_BUTTON_ALPHA.ID);
        controlButtonsView.addControlButton(ControlButtonsView.ButtonSignature.GAMEPAD_BUTTON_B, ControlButtonsView.ButtonStyle.DEFAULT_BUTTONS.STYLE, ControlButtonsView.ButtonIcon.B_BUTTON_ALPHA.ID);
        relativeLayout.addView(controlButtonsView);
    }

6 Likes

Cool! But I tried to search the wiki for Android support and found outdated information… is there a thread that can get me up to date? Thanks!

2 Likes

I donot know much about android stuff on wiki, i mainly rely on android java docs and android developer wiki, for jme android development quick start you can currently refer to these simple test cases, the classes are well documented :

Quick Start Guide to run a simple android application (how to create and deploy android activities):

(Jme3 uses the Android Activity as a launcher and GlSurfaceView component to directly display graphics through injecting shaders under the hood.)

The new jme3 JmeSurfaceView is a GlSurfaceView that can act as Jme3 system listener and can start a simpleApplication, you can find it inside the simple examples.

The AndroidHarness wraps a GlSurfaceView inside an android activity(Ui entry point) and it eases the life cycle for you, so you have multiple choices either to use JmeSurfaceView and wrap this ui component inside an AppCompatActivity or just use the harness(by extending it).

You needn’t to know everything about android to develop a jme3 android game, you just need some sort of knowledge about android activities, android Manifest, gradle, android studio and the rest would be your jmonkeyengine main class (SimpleApplication).

EDIT : and this may help you in the process of migrating the game to android platform :

5 Likes