Skip to content

Create your first graphical application

Maeiky edited this page Jan 24, 2020 · 24 revisions

From our previous project "Hello World", we will build a portable GUI.


First we want to create an Interface to show our graphics. Interface depends on platform, but it most likely a Window.

Generally, we don't want that our Interface block execution from the rest of our application. So here come the Threading concept.

In C~, Threads are created by design. So a Class can be a Thread by itself, and thus eliminate most of the multi-threading problem. Thereby we do not face problems like Data races, because our class will be isolated. But not completely, we also want to be able to communicate with other threads.


Now the code -> Editing MainEntry.cw


First we import the required Class. We need ThreadExt, an external view of a thread class. Also our Class interface that we will create, named "MainInterface"

import GZ.Base.Thread.ThreadExt;
import Demo.MainInterface;

Note: import never have relative path to easily be able to change a file location and reduce refactoring

Next in the Class Body, we create a variable ThreadExt and a new Class

public class MainEntry extends EntryPoint {

	public var oThread: ThreadExt; //Object Variable of our Class

	public function MainEntry():Int {

		Debug.fTrace("Hello GZE!");
		
		oThread = new MainInterface(); //Create our Class Interface
		
		return 1; //We return "1" (true) to continue execution
	}
	
}

Now our MainInterface -> Create a new file MainEntry.cw next to MainEntry.cw.


Inside we can put this code:

import GZ.Sys.ThreadItf;

public thread<ThreadItf> MainInterface extends Interface {
	
	public function MainInterface( _oThreadItf : ThreadItf ):Void {
	
		//!New thread started, this and subclass are isolated for thread safety
		
		//!Select rendering on GPU on CPU
		bGpuDraw = false;
		
		//Extends Class Parameters
		Interface(_oThreadItf, "Hello GZE GUI", 800, 600);

		//Create a new windows interface
		fCreateInterface();
	}

	override public function fWinStart():Void {
		Debug.fPass(" --------------------------------------- ");
		Debug.fPass(" ---- My First GZE Graphical Window ---- ");
		Debug.fPass(" --------------------------------------- ");
	}
	
}	

Result:

In console output, between brackets, we can see in which thread ID we print message, here we have two different thread: 0 and 1


GZE can either render on GPU and CPU, for best compatibility, we choose to render on CPU for now.


What about a first scene? -> Create a new file Scene.cw next to MainInterface.cw.


Let's put something interesting in our Window, like some vector graphics.

In our new file, put this code:

import GZ.Gfx.Root;
import GZ.Gfx.Clip;
import GZ.Gfx.Vector.Box;

public class Scene extends Clip {

	public var oObj : Box;

	public function Scene( _oParent : Root ):Void {
		Clip(_oParent, 0.0, 0.0);
		
		//!Nex Box Object:     X ,Y,  Width,Height,  LineSize
		oObj = new Box(this,  300,300,  200,200,       5);
	}
}

Result:


Let's animate this


Modify your scene function constructor and add a new override function fUpdateParentToChild which is updated every frames

Here we modify the vector propriety of our object, also GZE have build-in easing on it with the fTo function.

public function Scene( _oParent : Root ):Void {
	Clip(_oParent, 0.0, 0.0);
	
	//!Nex Box Object:        X ,Y,   Width,Height, LineSize
	oObj = new Box(this, 300,300,  200,200,    5);
	
	//Moving
	//! ----- Pos -- In Screen Coordinate (0.0, 0.0, 0.0 = Top left)
	oObj.vPos.nX.fTo(400.0);
	
	//Fading
	//! ----- Alpha ------- (0.0 = Transparent, 1.0 = Normal)
	oObj.vColor.nAlpha = 0.0;
	oObj.vColor.nAlpha.fTo(1.0);
	
	//Coloring
	//! ------ Colors  ---- (0.0 = Normal, -1.0 = Dark, 1.0 = Bright)
	oObj.vColor.nRed = 0.0;
	oObj.vColor.nRed.fTo(1.0);

	//Scaling
	//! ------ Size ------- (1.0 = Normal, 0.5 Half, 2.0 Double)
	oObj.vSize.nWidth.fTo(0.5);
	oObj.vSize.nHeight.fTo(0.5);
	
}

//!Updated each frame, parents before
override public function fUpdateParentToChild():Void {

	//! -----Rotation ----- (0.0 = Normal, PI/2.0 = 90deg,  PI = 180deg ) *All in radian
	oObj.vRot.nPitch = oObj.vRot.nPitch + 0.005;
	oObj.vRot.nRoll  = oObj.vRot.nRoll  + 0.008;
}

You will now see a 3d rotating square with a Red color:


The complete project is here



Clone this wiki locally