-
Notifications
You must be signed in to change notification settings - Fork 4
3. Hello World
Hyrdaboo edited this page Jul 6, 2023
·
1 revision
All Dwarf applications need to derive from the Application class. Here's an example of the most basic Dwarf app
import DwarfEngine.Core.Application;
class HelloWorld extends Application {
// Start is called at the start of the application
@Override
public void OnStart() {
// the title of the window
title = "Hello World";
}
// Update is called every frame
@Override
public void OnUpdate() {
}
}
public class Main {
public static void main(String[] args) {
HelloWorld app = new HelloWorld();
// specify the resolution in this case 1280x720 (720p)
// the third parameter is pixel scale which tells the application
// how many device pixels does every pixel of the application correspond to
app.Initialize(1280, 720, 1);
}
}After running this code we get an empty window with 1280x720 resolution:
Let's draw a circle where mouse is. Our updated code will look like this:
import DwarfEngine.Core.Application;
import DwarfEngine.Core.Input;
import DwarfEngine.MathTypes.Vector2;
// import everything inside the DisplayRenderer class
import static DwarfEngine.Core.DisplayRenderer.*;
import java.awt.Color;
class HelloWorld extends Application {
// Start is called at the start of the application
@Override
public void OnStart() {
// the title of the window
title = "Hello World";
}
// Update is called every frame
@Override
public void OnUpdate() {
//Clear the screen. Without this we would see the old frames on top of each other
clear(Color.black);
Vector2 mousePos = Input.getMousePosition();
// Draws a red circle with a radius of 10 at the position of mouse cursor
FillCircle(mousePos, 10, Color.red);
}
}
public class Main {
public static void main(String[] args) {
HelloWorld app = new HelloWorld();
// specify the resolution in this case 1280x720 (720p)
// the third parameter is pixel scale which tells the application
// how many device pixels does every pixel of the application correspond to
app.Initialize(1280, 720, 1);
}
}Run this and you will have a small red circle following your cursor. Not very impressive? Well let's get some 3D stuff going!
First of all every scene needs to derive from Scene class and implement its methods. We'll see it in a minute now. I will now recreate the first scene from the demos.
package Demos;
import java.io.File;
import DwarfEngine.Texture;
import DwarfEngine.Core.Application;
import DwarfEngine.MathTypes.Vector3;
import Renderer3D.Camera;
import Renderer3D.Light;
import Renderer3D.Light.LightType;
import Renderer3D.ObjLoader;
import Renderer3D.Prop;
import Renderer3D.Scene;
import Renderer3D.BuiltInShaders.Phong;
import Renderer3D.BuiltInShaders.Unlit;
// Loading a simple 3D scene with a model. Every scene needs to derive from Scene class
public class SuzanneDemo extends Scene {
// Store a reference to the application so that we may use its methods later
Application app;
public SuzanneDemo(Application application) {
super(application);
// set a reference to application to access its functions
app = application;
app.title = "Simple Scene with 1 object";
}
// This function is called when the scene is loaded
@Override
protected void OnSceneLoad() {
// load a texture
Texture uvchecker = new Texture();
uvchecker.Load("DemoResources/uvgrid.png");
// create a phong shader from unlit texture shader
Unlit unlit = new Unlit();
unlit.setTexture(uvchecker);
Phong phong = new Phong(unlit);
phong.shininess = 50;
File suzanneFile = new File("DemoResources/suzanne.obj");
// every object in a scene that gets rendered is a prop
// a prop has a mesh that describes its shape and a shader that describes the surface appearance
suzanne = new Prop(ObjLoader.Load(suzanneFile));
//set the shader to the phong shader that we have created and add this prop to the list of objects
suzanne.setShader(phong);
objects.add(suzanne);
// load a skybox object which is actually a giant sphere turned inside out (flipped normals) with an hdri
Texture skyTexture = new Texture();
skyTexture.Load("DemoResources/skyImage.png");
Unlit skyShader = new Unlit();
skyShader.setTexture(skyTexture);
File skyFile = new File("DemoResources/sky.obj");
Prop sky = new Prop(ObjLoader.Load(skyFile));
sky.setShader(skyShader);
sky.transform.scale = Vector3.mulVecFloat(Vector3.one(), 1000);
objects.add(sky);
// add a sun and rotate it
Light sun = new Light();
sun.transform.rotation = new Vector3(40, 25, 0);
sun.setColor(new Vector3(1, 1, 0.6f));
// every light source needs to be added to the list of lights
lights.add(sun);
// add ambient light so that it isn't so dark where light doesn't shine directly
Light ambient = new Light();
ambient.setColor(new Vector3(0.3f, 0.37f, 0.43f));
ambient.type = LightType.Ambient;
lights.add(ambient);
// add camera so that we can see and move it back 3 units
camera = new Camera();
camera.transform.position.z = -3;
setCamera(camera);
}
Prop suzanne;
Camera camera;
@Override
protected void OnSceneUpdate() {
// simple fps control. Check out the demos if you wanna see more
FpsControls.GetInput((float) app.getDeltaTime(), camera.transform);
suzanne.transform.rotation.y += app.getDeltaTime() * 10;
}
}Now back in our HelloWorld class let's initialize and render this scene. Modifying our code like so:
import DwarfEngine.Core.Application;
import DwarfEngine.Core.Input;
import DwarfEngine.Core.Keycode;
import Renderer3D.SceneManager;
import Demos.SuzanneDemo;
class HelloWorld extends Application {
@Override
public void OnStart() {
// Add the Suzannedemo.class with the name `demo` to the scene manager
//so that it knows which class to instantiate when the scene with this name is loaded
SceneManager.AddScene(SuzanneDemo.class, "demo");
// actually load the scene which will instantiate new SuzanneDemo object
SceneManager.LoadScene("demo");
}
@Override
public void OnUpdate() {
// render currently loaded scene
SceneManager.renderActiveScene();
// Switch fullscreen when 'F' key is pressed
if (Input.OnKeyPressed(Keycode.F)) {
switchFullscreen();
}
}
}
public class Main {
public static void main(String[] args) {
HelloWorld app = new HelloWorld();
// I'll lower the resolution by half to get better performace :(
// If you are wondering why check out the readme of this project where
// it is explained
app.Initialize(1280/2, 720/2, 1);
}
}After modifying the code you should see this result:
This wraps up our wiki tutorials. I would honestly want to make more tutorials but I don't think anybody is ever gonna use this and I was running out of time for this project. It already took much longer than it should have. If you have gotten up to this point you are a legend and this belongs to you 👑