ESENTHEL ENGINE SDK 00 - Start.txt
/******************************************************************************/
#include "stdafx.h" // include precompiled header
#include "resource.h" // include resources (icon)
/******************************************************************************/
void InitPre() // init before engine inits
{
// here you will have to setup initial engine settings
// like application name, its options, screen resolution...
App.name("Start"); // application name
App.icon=(Char*)IDI_ICON1; // setup icon
App.flag=APP_NO_FX; // set APP_NO_FX option to tell engine to load only basic drawing methods (no 3d and special effects)
PakAdd("../data/engine.pak"); // load engine data
}
/******************************************************************************/
Bool Init() // init after engine inits
{
// here when engine will be ready you can load your game data
// return false when error occured
return true;
}
/******************************************************************************/
void Shut() // shut at exit
{
// this is called when the engine is about to exit
}
/******************************************************************************/
Bool Main() // main updating
{
// here you have to process each frame update
if(Kb.bp(KB_ESC))return false; // exit if escape on the keyboard pressed
return true; // continue
}
/******************************************************************************/
void Draw() // main drawing
{
// here you have to tell engine what to draw on the screen
D.clear(TURQ); // clear screen to turquoise color
D.text (0, 0.1,"This is the First Tutorial"); // draw text at (0, 0.1) position
D.text (0,-0.1,"Replace the CPP with some other file to view a different Tutorial"); // draw text at (0,-0.1) position
}
/******************************************************************************/
ESENTHEL ENGINE SDK 01 - Drawing.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************
Here are presented the most basic drawing functions
/******************************************************************************/
void InitPre()
{
App.name("Drawing");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE); // clear to white
// draw texts
{
D.text(0,0,"Default text settings"); // default text draw
TextDS tds; // text draw settings, contains information about font size, aligning, color, ..
tds.color=BLACK; // set black color
tds.scale*=1.4f; // change scale
D.text(tds,0,-0.2,"Bigger");
tds.scale/=1.4f; // reset scale
tds.align.set(1,0); // change aligning
D.text(tds,0,-0.4,"Right Aligned");
tds.color=GREEN; // change color to green
tds.align.set(-1,0); // change aligning
D.text(tds,0,-0.6,"Colored Left Aligned");
tds.align.set(0,0); // reset aligning
tds.color=ColorHue(Tm.time()/3); // assign color to Color Hue according to current time
D.text(tds,0,-0.8,"Multi colored");
}
// draw shapes
{
D.rect (BLUE , 0.5,0.5, 0.6,0.6); // draw blue rectangle at given coordinates
D.circle(RED , 0.1, -0.5,0.5); // draw red circle with 0.1 radius at (-0.5,0.5) position
D.dot (BLACK , 0,0.5); // draw black dot at (0,0.5) position
D.line (GREEN , -0.4,0.5, 0.4,0.6); // draw green line
D.tri (YELLOW,Vec2(-0.5,-0.4),Vec2(-0.4,-0.2),Vec2(-0.4,-0.4)); // draw yellow triangle from given points
}
}
/******************************************************************************/
ESENTHEL ENGINE SDK 02 - Input.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Vec2 point; // point position
Char c; // character pressed
/******************************************************************************/
void InitPre()
{
App.name("Input");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK; // here change the default text color
Text_ds.shadow=0; // here disable shadows
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
if(Kb.c())c=Kb.c(); // if character pressed remember it to draw it later
if(Kb.b(KB_LEFT ))point.x-=Tm.d()/2; // move point left when 'left arrow' is on according to time delta
if(Kb.b(KB_RIGHT))point.x+=Tm.d()/2; // move point right when 'right arrow' is on according to time delta
if(Kb.b(KB_DOWN ))point.y-=Tm.d()/2; // move point down when 'down arrow' is on according to time delta
if(Kb.b(KB_UP ))point.y+=Tm.d()/2; // move point up when 'up arrow' is on according to time delta
if(Kb.bp(KB_Z))point.x-=0.1; // when 'z' is pushed , move point left
if(Kb.br(KB_X))point.x+=0.1; // when 'x' is released , move point right
if(Kb.bd(KB_C))point.y+=0.1; // when 'c' is double clicked, move point up
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
D.dot(RED ,Ms.pos); // draw red dot at mouse cursor position
D.dot(GREEN,point ); // draw green dot at 'point' position
if(Ms.b(0))D.dot(BLACK, -0.1,0.4, 0.1); // when 0th mouse button on, draw big black dot
if(Ms.b(1))D.dot(BLACK, 0.1,0.4, 0.1); // when 1st mouse button on, draw big black dot
D.text(0,0.9, S+"character : "+c ); // draw stored character
D.text(0,0.7, S+"mouse : "+Ms.pos); // draw mouse position
D.text(0,0.6, S+"point : "+point ); // draw point position
}
/******************************************************************************/
ESENTHEL ENGINE SDK 03 - Image.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Gfx gfx; // image
/******************************************************************************/
void InitPre()
{
App.name("Image");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
gfx="../data/gfx/particle/star.gfx"; // load image from file
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(BLACK);
// draw image
gfx.draw(-0.5,0.5, 1,1); // draw at (-0.5,0.5) position with (1,1) size
}
/******************************************************************************/
ESENTHEL ENGINE SDK 04 - Cache.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
void InitPre()
{
App.name("Cache");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(BLACK);
Gfxs("../data/gfx/particle/star.gfx")->draw(-0.5,0.5, 1,1); // get image from cache and draw at (-0.5,0.5) position with (1,1) size
// for safer use, you can first check if resource exists using 'get' method
if(Gfx *gfx=Gfxs.get("non existing image.gfx")) // try to get non existing image, NULL will be returned since image doesn't exist
gfx->draw(-0.5,0.5, 1,1); // this won't happen
// see what will happen if you wan't to use "non existing image.gfx" when space pressed
if(Kb.b(KB_SPACE))
{
Gfxs("non existing image.gfx")->draw(-0.5,0.5, 1,1); // when space pushed an error will be shown and application will exit immediately
}
}
/******************************************************************************/
ESENTHEL ENGINE SDK 05 - Gui.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Window window; // gui window
Text text ; // gui text
Button button; // gui button
/******************************************************************************/
void InitPre()
{
App.name("GUI");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
D.mode(800,600);
}
/******************************************************************************/
Bool Init()
{
Gui +=window.create(Rect(-0.5,-0.4,0.5,0.3) ,"Window Title"); // create window and add it to Gui
window+=text .create(Vec2(0.5,-0.2f) ,"text" ); // create text and add it to 'window', coordinates are relative to parent (it's top left point)
window+=button.create(Rect(0.35f,-0.47f,0.65f,-0.4f),"OK" ); // create button and add it to 'window', coordinates are relative to parent (it's top left point)
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Gui.update(); // update GUI
return true;
}
/******************************************************************************/
void Draw()
{
D .clear(WHITE);
Gui.draw (); // draw GUI
}
/******************************************************************************/
ESENTHEL ENGINE SDK 06 - 3D.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
void InitPre()
{
App.name("3D");
App.flag=APP_NO_FX|APP_MS_EXCLUSIVE; // setup mouse exclusive mode to hide cursor
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Cam.dist=5; // set initial camera distance to 5 meters
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,10,CAMH_ROT|CAMH_ZOOM); // simple camera handle allowing minimum 0.1(10cm) and maximum 10meters zoom, and allowing rotation and zooming
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
Box (1 ).draw(BLACK); // draw black box with 1 meter radius
if(Ms.b(0))Ball(1 , Vec(-3,0,0)).draw(BLACK); // when 0th mouse button pushed draw black ball with 1 meter radius and (-3,0,0) position
if(Ms.b(1))Tube(0.3,2, Vec( 3,0,0)).draw(BLACK); // when 1st mouse button pushed draw black tube with 0.1 meter radius, 2 meters height and (3,0,0) position
}
/******************************************************************************/
ESENTHEL ENGINE SDK 07 - Mesh.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Mshb mshb; // mesh base (contains vertexes, edges, triangles, quads)
/******************************************************************************/
void InitPre()
{
App.name("Mesh");
App.flag=APP_MS_EXCLUSIVE; // mouse exclusive mode to hide cursor, and APP_NO_FX removed since we'll be using vertex lit Mshb rendering
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Cam.dist=4;
mshb.create(Torus(1,0.3),VTX_NRM); // create Mshb from torus, and automatically create vertex normals in order to lit the mshb properly
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,10,CAMH_ROT|CAMH_ZOOM);
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(TURQ);
LightDir(Vec(0,0,1)).set(); // set directional light in (0,0,1) direction before rendering to achieve lighting (NOTE: only directional light is supported in simple rendering mode)
if(Ms.b(0)) // when left mouse button on
{
Torus(1,0.3).draw(WHITE,true); // draw flat colored torus through Torus shape
}else
{
mshb.draw(NULL); // draw through Mshb with default material (it will be shaded properly because it has vertex normals)
}
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Geometry\Camera.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
void InitPre()
{
App.name("Camera");
App.flag=APP_NO_FX|APP_MS_EXCLUSIVE;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Cam.dist=5;
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
// settings
Cam.yaw -=Ms.d.x; // modify yaw according to mouse delta x
Cam.pitch+=Ms.d.y; // modify pitch according to mouse delta y
Cam.roll +=(Kb.b(KB_Z)-Kb.b(KB_X))*Tm.d(); // modify roll according to Z and X keyboard buttons
Cam.dist -=Ms.wheel*0.2; // modify distance according to mouse wheel
Clamp(Cam.dist,0.1,10); // clamp distance to minimum and maximum values
if(Kb.b(KB_LEFT ))Cam.at-=Cam.matrix.x*Tm.d();
if(Kb.b(KB_RIGHT))Cam.at+=Cam.matrix.x*Tm.d();
if(Kb.b(KB_UP ))Cam.at+=Cam.matrix.y*Tm.d();
if(Kb.b(KB_DOWN ))Cam.at-=Cam.matrix.y*Tm.d();
// camera
Cam.setSpherical (Cam.at,Cam.yaw,Cam.pitch,Cam.roll,Cam.dist); // set spherical camera with 'look at' position, angles and distance
Cam.updateVelocities( ); // after camera settings are up, we need to update camera velocities in order to achieve correct motion blur when enabled
Cam.set ( ); // set as active camera
// camera effects
if(Kb.bp(KB_SPACE))QuakeFx.addShort(); // add short quake camera effect when space pressed
QuakeFx.update (); // update camera effects
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
// draw 4x4 boxes
REPD(x,4)
REPD(z,4)Box(0.3,Vec(x,0,z)).draw(BLACK);
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Geometry\Matrix.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************
Matrix is a set of values which can be used to determine object's:
-position
-orientation (rotation)
-scale
Matrix is built from 4 vectors:
-position
-x direction (right )
-y direction (up )
-z direction (forward)
The default Matrix is called MatrixIdentity, it has its vectors set as following:
position(0,0,0) - located at world center, zero position
x (1,0,0) - points right
y (0,1,0) - points up
z (0,0,1) - points forward
/******************************************************************************/
void InitPre()
{
App.name("Matrix");
App.flag=APP_NO_FX|APP_MS_EXCLUSIVE;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Cam.dist=5;
Text_ds.color =BLACK;
Text_ds.shadow=0;
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,10,CAMH_ROT|CAMH_ZOOM);
return true;
}
/******************************************************************************/
void Draw(Matrix &matrix) // this function handles optional 'matrix' drawing
{
if(Kb.b(KB_SPACE)) // draw matrix when space is pressed
{
SetMatrix(); // reset drawing matrix
matrix.pos.draw(GREY,0.02f); // draw matrix position with grey color
D.line(RED , matrix.pos, matrix.pos+matrix.x); // draw matrix 'x' (right ) vector with red color
D.line(GREEN, matrix.pos, matrix.pos+matrix.y); // draw matrix 'y' (up ) vector with green color
D.line(BLUE , matrix.pos, matrix.pos+matrix.z); // draw matrix 'z' (forward) vector with blue color
}
}
void Draw()
{
D.clear(WHITE);
// box
{
SetMatrix(MatrixIdentity); // set default matrix identity
Box(1).draw(BLACK); // draw box at current matrix
Draw(MatrixIdentity); // draw matrix
}
// ball
{
Matrix m; // matrix (matrix is a position + orientation)
m.setPos(Vec(-3,0,0)); // init matrix with initial position
SetMatrix(m); // set as active matrix
Ball(1).draw(BLACK,false,VecI2(8)); // draw ball at current matrix
Draw(m); // draw matrix
}
// tube
{
Matrix m;
m.setRotateX(Tm.time()); // init matrix with initial x-rotation according to angle from time
m.move(Vec(3,0,0)); // move matrix to the right
SetMatrix(m); // set as active matrix
Tube(0.2,2).draw(BLACK,false,6); // draw tube
Draw(m); // draw matrix
}
D.text(0,0.9,"Press Space to draw Matrixes");
}
/******************************************************************************
NOTE : if matrix method starts with 'set' it means it resets matrix and then applies transformation
if matrix method doesn't start with 'set' it means it just applies transformation
instead of writing:
Matrix m;
m.setRotateX(Tm.time());
m.move(Vec(3,0,0));
SetMatrix(m);
you can write:
SetMatrix(Matrix().setRotateX(Tm.time()).move(Vec(3,0,0)));
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Graphics\2D Effects.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Gfx logo , // logo image
fade ; // fading texture
Flt fx_value; // effect value
Int fx_index; // effect index
/******************************************************************************/
void InitPre()
{
App.name("2D Effects");
App.flag=APP_FULL_TOGGLE;
PakAdd("../data/engine.pak");
D.mode(800,600);
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
// import esenthel engine logo
logo.Import("../data/logo.png",-1,GFX_2D);
// create fading texture
fade.create2D(128,128, GFX_L8, 1);
if(fade.lock())
{
REPD(x,fade.x())
REPD(y,fade.y())fade.pixel(x,y,Random(256));
fade.unlock();
}
fade.blur(5,false); // apply gaussian blur with 5 pixel range and no clamping
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
// change effect on key pressed, and reset effect value
if(Kb.bp(KB_1)){fx_index=1; fx_value=0;}
if(Kb.bp(KB_2)){fx_index=2; fx_value=0;}
if(Kb.bp(KB_3)){fx_index=3; fx_value=0;}
if(Kb.bp(KB_4)){fx_index=4; fx_value=0;}
if(Kb.bp(KB_5)){fx_index=5; fx_value=0;}
if(Kb.bp(KB_6)){fx_index=6; fx_value=0;}
// increase effect value
fx_value+=Tm.d();
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
if(Kb.b(KB_SPACE))fade.drawFs();else // if space pressed draw fading texture to full screen
switch(fx_index)
{
case 0:
{
D.text(0,0,"Press 1,2,3,4,5,6 keys to view different effects");
}break;
case 1: // Draw Ripple Effect through Gfx::draw()
{
// set ripple effect values
RippleFx ripple;
ripple.alpha_add = fx_value;
ripple.alpha_scale=-1;
// draw image with ripple effect
logo.draw(ripple, -1,1,2,2);
}break;
case 2: // Draw Ripple Effect through helper screen
{
// draw to helper screen
D.fxBegin(true); // start drawing to helper screen
logo.draw(-1,1,2,2); // image draw
D.fxEnd(); // restore default screen drawing
// set ripple effect values
RippleFx ripple;
ripple.alpha_add = fx_value;
ripple.alpha_scale=-1;
// draw helper screen with ripple effect
ripple.draw();
}break;
case 3: // Draw Fade Effect
{
// draw to helper screen
D.fxBegin(true); // start drawing to helper screen
logo.draw(-1,1,2,2); // image draw
D.fxEnd(); // restore default screen drawing
// fade in helper screen with 'fade' fading texture
FadeFx(fx_value/2,&fade);
}break;
case 4: // Titles Effect
{
// draw to helper screen
D.fxBegin(true); // start drawing to helper screen
REP(30)D.text(0,D.h()+(Frac(Tm.time())-i)*0.08,"Text Text Text"); // draw text
D.fxEnd(); // restore default screen drawing
// set effect values
TitlesFx titles;
// draw helper screen with titles effect
titles.draw();
}break;
case 5: // Wave Effect
{
logo.drawFs(); // draw logo on full screen
WaveFx(Tm.time()/2,0.8); // apply wave effect onto the full screen
}break;
case 6: // Radial Blur Effect
{
logo.drawFs(); // draw logo on full screen
RadialBlurFx(Frac(fx_value)*0.3); // apply radial blur effect onto the full screen
}break;
}
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Graphics\Color Transformations.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
enum COL_TRANS_MODE // color transformation modes
{
CT_RGB,
CT_RBG,
CT_GRB,
CT_GBR,
CT_BRG,
CT_BGR,
CT_MONO,
CT_HUE,
CT_HUE2,
CT_CUSTOM,
CT_CUSTOM2,
};
CChar8 *CTText[]= // color transformation description
{
"RGB",
"RBG",
"GRB",
"GBR",
"BRG",
"BGR",
"MONO",
"HUE",
"HUE+",
"CUSTOM",
"CUSTOM2",
};
Gfx gfx ; // Esenthel image
Tabs tabs ; // transformation tabs
Slider slider; // transformation power/alpha
/******************************************************************************/
void InitPre()
{
App.name("Color Transformations");
PakAdd("../data/engine.pak");
D.mode(800,600);
}
/******************************************************************************/
Bool Init()
{
gfx.Import("../data/logo.png",-1,GFX_2D,1);
Gui+=tabs .create(Rect_U (0,D.h(),D.w()*2,0.06),0,CTText,ELMS(CTText));
Gui+=slider.create(Rect_LU(-D.w(),D.h()-0.1,0.4,0.1)).set(1);
slider.color=WHITE;
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Gui.update();
return true;
}
/******************************************************************************/
void ApplyColorTransformation(Int mode)
{
ColorMatrix cm; // color transformation matrix
Flt alpha=slider(); // color transformation power
switch(mode)
{
case CT_RGB : cm.setRGB ( ).draw(alpha); break;
case CT_RBG : cm.setRBG ( ).draw(alpha); break;
case CT_GRB : cm.setGRB ( ).draw(alpha); break;
case CT_GBR : cm.setGBR ( ).draw(alpha); break;
case CT_BRG : cm.setBRG ( ).draw(alpha); break;
case CT_BGR : cm.setBGR ( ).draw(alpha); break;
case CT_MONO: cm.setMono ( ).draw(alpha); break;
case CT_HUE : cm.setHue (Tm.time()/4).draw(alpha); break;
case CT_HUE2: ColorTransHB(Tm.time()/4,1 ,alpha); break; // use 'ColTransHB' to get correct Hue-Brightness transformation
case CT_CUSTOM:
{
// set custom matrix
// dest.r, dest.g, dest.b
cm.x .set(1 , 1 , 1 ); // src.r
cm.y .set(0 , 0 , 0 ); // src.g
cm.z .set(0 , 0 , 0 ); // src.b
// add.r , add.g , add.b
cm.pos.set(0 , 0.2 , 0 ); // 1
cm.draw(alpha);
}break;
case CT_CUSTOM2:
{
// set custom matrix #2
// dest.r, dest.g, dest.b
cm.x .set(0.5 , 0.5 , 0.5 ); // src.r
cm.y .set(0.5 , 0.5 , 0.5 ); // src.g
cm.z .set(0.3 , 0.3 , 1.0 ); // src.b
// add.r , add.g , add.b
cm.pos.set(0 , 0 , 0 ); // 1
cm.draw(alpha);
}break;
}
}
void Draw()
{
D.clear();
// draw
gfx.drawFs();
D.rectShadedX(BLACK,RED , -D.w()/2,-0.7, D.w()/2, -0.75);
D.rectShadedX(BLACK,GREEN, -D.w()/2,-0.8, D.w()/2, -0.85);
D.rectShadedX(BLACK,BLUE , -D.w()/2,-0.9, D.w()/2, -0.95);
// transform colors
ApplyColorTransformation(tabs());
// draw gui after transformation
Gui.draw();
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Graphics\Colors HSB.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
void InitPre()
{
App.name("Colors HSB");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
D.mode(800,600);
}
/******************************************************************************/
Bool Init()
{
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
REPD(x,1024)
{
Flt s0= x /1024.0f , // calculate step0 (fraction)
s1=(x+1)/1024.0f , // calculate step1 (fraction)
x0=-1+s0*2 , // calculate x0 position
x1=-1+s1*2 ; // calculate x1 position
UInt c0=ColorHue(s0 ), // calculate color0 from hue value
c1=ColorHSB(s0,1,1 ), // calculate color1 from hue saturation brightness value
c2=ColorHue(c1,Ms.pos.x); // calculate color2 from color1 modified by hue from mouse x position
// draw rectangles with different colors
D.rect(c0,x0, 0.1,x1, 0.2);
D.rect(c1,x0,-0.1,x1, 0.0);
D.rect(c2,x0,-0.3,x1,-0.2);
}
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Graphics\Dynamic Image.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Gfx gfx; // image
/******************************************************************************/
void InitPre()
{
App.name("Dynamic Image");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
gfx.create2D(256,256, GFX_A8R8G8B8, 1); // create 256X256 image, A8R8G8B8 type, 1 mipmap
if(gfx.lock()) // in order to edit the texture we must first lock it
{
FREPD(y,gfx.y()) // iterate through all y's
FREPD(x,gfx.x()) // iterate through all x's
{
gfx.color(x,y, ARGB(255,x,y,0)); // set image (x,y) pixel color to ARGB color
}
gfx.unlock(); // unlock
}
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
gfx.draw(-0.5,0.5, 1,1); // draw at (-0.5,0.5) position with (1,1) size
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Graphics\Font Make Unicode.txt
[Error] - File could not be written...
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Graphics\Font Make.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************
Creating Font is split into few parts:
1. Call 'FontMake' to generate an image on your hard disk, the image will contain all desired characters
2. Optionally you can modify the file on your disk, to customize the font graphics
3. Use 'Font::create' method to create a font from the image
Once you have created a Font, you can just save it using 'Font::save',
and then in the game load it via 'Font::load' or by using Font cache - 'Fonts'
Loading already created font ('Font::load' or 'Fonts') is much faster than creating a font ('Font::create')
/******************************************************************************/
Font *font ; // new font
Button button;
/******************************************************************************/
void InitPre()
{
App.name("Font Make");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
void CreateFont()
{
Char *characters=L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!@#$%^&*()[]<>{}`~_-+=;:,.?/|\\'\""; // these are all the basic characters you may want to include in your font
// please note that you don't have to worry about accidentally including the same character multiple times, because the engine will only generate 1 copy of a single character
// for example you can freely set 'characters' to "0123ABC01" and the engine will generate only "0123ABC"
FontMake("Times New Roman",characters,64,0,"LocalData/Times New Roman.png"); // create a image of desired characters created from the font "Times New Roman" located in your "Windows/Fonts" folder, and save it to disk (64 pixel size, 0 weight)
// here you may optionally perform some modifications to the image, for example edit the image in external programs
// after the image is ready, create the final font from it
Font font;
if(font.create("LocalData/Times New Roman.png",characters)) // create font from the image and use exactly the same character set 'characters' which were used in the 'FontMake' function
font.save ("LocalData/Times New Roman.font" ); // save it, to load it later in your application
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
CreateFont(); // create the new font and save it to disk
font=Fonts("LocalData/Times New Roman.font"); // load the font
// now let's change Gui's default font for buttons
Gui.tds_button.font=font; // assign the new font
Gui+=button.create(Rect_C(0,-0.3,0.4,0.1),"Button"); // create a sample button to view the changes
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Gui.update();
return true;
}
/******************************************************************************/
void Draw()
{
D .clear(WHITE);
Gui.draw ();
TextDS tds; // text draw settings
tds.font =font ; // set font parameter to the newly created font
tds.color =BLACK; // set black color
tds.shadow= 0; // set no shadow
D.text( 0,0.2,"This is the default font!"); // draw some text with the default font
D.text(tds,0,0 ,"This is the new font!" ); // draw some text with the newly created font, please note the first parameter 'tds' is used to specify the new settings
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Graphics\Import Image.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Gfx gfx; // image
/******************************************************************************/
void InitPre()
{
App.name("Importing Images");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
gfx.Import("../data/logo.png",-1,GFX_2D); // import PNG format as a texture
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
gfx.draw(-1,0.5, 2,1); // draw at (-1,0.5) position with (2,1) size
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Graphics\VI - Vertex Index Buffer.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
void InitPre()
{
App.name("VI - Vertex Index Buffer");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
// to draw big number of shapes more efficiently please use VertexIndexBuffer (VI)
Char8 *mode;
if(Kb.b(KB_SPACE)) // when space on, draw in classic mode
{
REP(10000)D.line (GREEN, 0,0, Cos(i*PI2/10000),Sin(i*PI2/10000)); // draw 10000 lines in classic mode
REP(10000)D.rectL(ColorHue(i/10000.),Rect_C(0,0,i/20000.)); // draw 10000 rectangles in classic mode
mode="Classic";
}else // draw in buffered mode
{
// draw lines
{
VI.color(GREEN); // set green color
REP(10000)VI.line (0,0, Cos(i*PI2/10000),Sin(i*PI2/10000)); // draw 10000 lines in buffered mode
VI.end (); // finish drawing
}
//draw rectangles
{
REP(10000)VI.rectL(ColorHue(i/10000.),Rect_C(0,0,i/20000.)); // draw 10000 lines in buffered mode
VI.end (); // finish drawing
}
mode="Buffered";
}
D.text(0,0.9,S+mode+" drawing" );
D.text(0,0.8,S+"Fps: "+Tm.fps());
}
/******************************************************************************
NOTE:
Each type of drawing must be ended with it's own "end" method
// forbidden
{
REP(10)VI.line(..);
REP(10)VI.rect(..);
VI.end ();
}
// good
{
REP(10)VI.line(..);
VI.end ();
REP(10)VI.rect(..)
VI.end ();
}
if one drawing method has color parameter and the other doesn't, it means they're different, and separate "end" is needed here as well
// forbidden
{
REP(10)VI.line(RED, x0,y0,x1,y1);
REP(10)VI.line( x0,y0,x1,y1);
VI.end ();
}
// good
{
REP(10)VI.line(RED, x0,y0,x1,y1);
VI.end ();
VI.color(RED);
REP(10)VI.line (x0,y0,x1,y1);
VI.end ();
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Gui\01 - Bars.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Window window ; // gui window
SlideBar slidebar; // gui slidebar
Progress progress; // gui progressbar
Slider slider ; // gui slider
/******************************************************************************/
void InitPre()
{
App.name("Bars");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
D.mode(800,600);
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
Gui +=window .create(Rect(-0.5,-0.4,0.5,0.4),"Window with bars");
window+=slidebar.create(Rect(0.1,-0.2,0.9,-0.12)); // create slidebar
window+=progress.create(Rect(0.1,-0.4,0.9,-0.32)); // create progressbar
window+=slider .create(Rect(0.1,-0.6,0.9,-0.52)); // create slider
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Gui.update();
progress.set(slidebar()); // set progress bar according to slidebar value
return true;
}
/******************************************************************************/
void Draw()
{
D .clear(WHITE);
Gui.draw();
D.text(0,-0.7,S+"SlideBar " +slidebar()); // draw slidebar value
D.text(0,-0.8,S+"ProgressBar "+progress()); // draw progressbar value
D.text(0,-0.9,S+"Slider " +slider ()); // draw slider value
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Gui\02 - Buttons.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Int value ; // simple integer value
Button button_a, // gui button
button_b, // gui button
button_c; // gui button
/******************************************************************************/
void InitPre()
{
App.name("Buttons");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
D.mode(800,600);
}
/******************************************************************************/
void Func(Ptr) // custom function which will be called when button pushed
{
value++;
}
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
Gui+=button_a.create(Rect_C(-0.5,0, 0.45,0.08),"Button Func" ,Func); // create button which will call 'Func' function when pushed
Gui+=button_b.create(Rect_C( 0.0,0, 0.45,0.08),"Button Manual" ); // create button without any functions, we will handle it manually
Gui+=button_c.create(Rect_C( 0.5,0, 0.45,0.08),"Button Stay" ); button_c.mode=BUTTON_STAY; // create button and set a special mode
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Gui.update();
if(button_b())value++; // manually check if button pushed
return true;
}
/******************************************************************************/
void Draw()
{
D .clear(WHITE);
Gui.draw ();
D.text(0,0.6,S+"value = " +value ); // draw 'value' on screen
D.text(0,0.5,S+"button_c() = "+button_c()); // draw state of 'button_c'
// please note that you can also use automatically called functions with BUTTON_STAY mode
// and you can manually check for state change of such button this way:
if(button_c.changed())value++;
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Gui\03 - Tabs.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Window window; // gui window
Tabs tabs ; // gui tabs
Text text ; // gui text
Button button; // gui button
Image image ; // gui image
/******************************************************************************/
void InitPre()
{
App.name("Tabs");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
D.mode(800,600);
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
CChar8 *tab[]=
{
"First",
"Second",
"Third",
};
Gui +=window.create(Rect (-0.5,-0.4,0.5,0.4),"Window with tabs");
window+=tabs .create(Rect_LU(0,0,window.crect.w(),0.08),0,tab,ELMS(tab)); // create tabs
// add some elements to tabs
{
tabs.add(0,text .create(Vec2 (window.crect.w()/2,-window.crect.h()/2 ),"Text" )); // create and add text to 0th tab
tabs.add(1,button.create(Rect_C(window.crect.w()/2,-window.crect.h()/2,0.4,0.1),"Button" )); // create and add button to 1st tab
tabs.add(2,image .create(Rect_C(window.crect.w()/2,-window.crect.h()/2,0.5,0.5),Gfxs("LocalData/image.gfx"))); // create and add image to 2nd tab
}
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Gui.update();
return true;
}
/******************************************************************************/
void Draw()
{
D .clear(WHITE);
Gui.draw ();
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Gui\04 - Window Menu.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Window window; // gui window
Menu menu ; // gui menu
/******************************************************************************/
void InitPre()
{
App.name("Window Menu");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
D.mode(800,600);
}
/******************************************************************************/
// here are defined functions which are going to be used by menu commands when activated
void MenuFileNew (){}
void MenuFileOpen(){}
void MenuFileSave(){}
void MenuFileExit(){StateExit.set();}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
Gui+=window.create(Rect(-0.5,-0.4,0.5,0.4),"Window with menu");
{
using namespace MenuDefs; // use this namespace to simplify menu creation
// from now on (in current scope) N is a menu node
N n; // let's start with main node
{
N &f=(n+="File"); // add "File" element to main node, and store it's reference in 'f'
f.New().create("New" ,MenuFileNew ,KbSc('n',KBSC_CTRL)); // add "New" command to 'f', giving it's procedure and keyboard shortcut (ctrl+n)
f.New().create("Open",MenuFileOpen,KbSc('o',KBSC_CTRL)); // add "Open" command to 'f', giving it's procedure and keyboard shortcut (ctrl+o)
f.New().create("Save",MenuFileSave,KbSc('s',KBSC_CTRL)); // add "Save" command to 'f', giving it's procedure and keyboard shortcut (ctrl+s)
f++; // add empty line
f.New().create("Exit",MenuFileExit,KbSc('x',KBSC_CTRL)); // add "Exit" command to 'f', giving it's procedure and keyboard shortcut (ctrl+x)
}
{
N &e=(n+="Edit");
e.New().create("Option",CMENU_TOGGLABLE); // giving CMENU_TOGGLE flag means that we can toggle this element
{
N &c=(e+="Children");
c+= "child 1";
c.New().create("child 2").desc("This is child 2"); // this element has a description which will be shown when mouse cursor stops on the element
c.New().create("child 3",CMENU_TOGGLABLE).setOn(); // this element can be toggled and is checked by default
}
}
window+=menu.create(n); // create menu from nodes and add it to window
}
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Gui.update();
return true;
}
/******************************************************************************/
void Draw()
{
D .clear(WHITE);
Gui.draw ();
D .text (0,-0.7,S+"'Option' is "+menu("edit/option")); // draw state of "option" located in "edit" using operator() method
// Another way of checking if a command has been selected is to use 'pushed' method, like this:
if(menu.pushed("edit/children/child 1"))
{
// if we're here then "edit/children/child 1" has been selected
}
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Gui\05 - List.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
struct Struct // custom structure
{
Flt f;
Int i;
Byte b;
}data[10]= // sample data array
{
{1.0, 15, 4},
{2.0, 25, 3},
{3.0, 35, 2},
{4.0, 45, 1},
};
ListGroup list_group[]= // gui list group (stores information about structure format)
{
ListGroup(MEMBER(Struct,f),0.3,L"Float" ), // group describing 'f' member in 'Struct' structure, width of group=0.3, name="Float"
ListGroup(MEMBER(Struct,i),0.3,L"Integer"), // group describing 'i' member in 'Struct' structure, width of group=0.3, name="Integer"
ListGroup(MEMBER(Struct,b),0.2,L"Byte" ), // group describing 'b' member in 'Struct' structure, width of group=0.2, name="Byte"
};
/******************************************************************************/
Window window; // gui window
Region region; // gui region
List<Struct> list ; // gui list
/******************************************************************************/
void InitPre()
{
App.name("List");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
D.mode(800,600);
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
Gui +=window.create(Rect(-0.5,-0.4,0.5,0.4),"Window with list");
window+=region.create(Rect(0.05,-0.6,0.95,-0.1)); // create region
region+=list .create(list_group,ELMS(list_group)).setData(data,ELMS(data)); // create list with 'list_group' groups and 'data' data
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Gui.update();
return true;
}
/******************************************************************************/
void Draw()
{
D .clear(WHITE);
Gui.draw ();
if(Struct *cur=list())D.text(0,-0.7,S+"current element's Integer value "+cur->i);
D.text(0,-0.8,S+"current element (on the list) " +list.cur);
D.text(0,-0.9,S+"original element (in data) " +list.orderToElm(list.cur));
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Gui\06 - ComboBox.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
ComboBox combobox_a, // combobox
combobox_b; // combobox
struct ComboBoxElm // combobox element structure
{
VecI2 vec;
}veci2[]=
{
{VecI2(0, 0)},
{VecI2(0,10)},
{VecI2(0,20)},
{VecI2(1, 0)},
{VecI2(1,10)},
{VecI2(1,20)},
};
CChar* ComboBoxElmFunc(ComboBoxElm &elm) // function which transforms ComboBoxElm into a string
{
static Str str;
return str=S+elm.vec.x+" x "+elm.vec.y;
}
/******************************************************************************/
void InitPre()
{
App.name("ComboBox");
App.flag=APP_FULL_TOGGLE|APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
// combobox A (from text-only elements)
{
static CChar8 *elm[]= // combobox elements (must be non-local)
{
"First",
"Second",
"Third",
};
Gui+=combobox_a.create(Rect_C(-0.5,0, 0.4,0.08),elm,ELMS(elm)); // create combobox with simple elements (text-only)
}
// combobox B (from custom structure)
{
ListGroup lg[]= // list groups
{
ListGroup(ComboBoxElmFunc,0.3,L"Function"), // list group which uses custom function for data interpretation
};
Gui+=combobox_b.create(Rect_C(0.5,0, 0.4,0.08)); // create combobox
// assign custom elements
combobox_b.setGroups(lg ,ELMS(lg ),true) // set list groups
.setData (veci2,ELMS(veci2) ); // set list data
}
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Gui.update();
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
D.text (-0.5, 0.1,S+"combobox_a element: "+combobox_a()); // draw selected element
D.text ( 0.5, 0.1,S+"combobox_b element: "+combobox_b()); // draw selected element
Gui.draw();
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Gui\07 - Game Menu.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
struct MenuNew // new-game menu
{
Window window;
Text text;
Button close;
static void Close(Ptr){Mn.window.fadeOut();}
void create()
{
Gui +=window.create(Rect_C(0,0,0.9,0.5)).barVisible(false).hide();
window+=text .create(Vec2 (window.crect.w()/2,-0.15),"New Game");
window+=close .create(Rect_C(window.crect.w()/2,-window.crect.h()/2-0.1,0.4,0.08),"Close",Close);
}
}Mn;
/******************************************************************************/
struct MenuLoad // load-game menu
{
Window window;
Text text;
Button close;
static void Close(Ptr){Ml.window.fadeOut();}
void create()
{
Gui +=window.create(Rect_C(0,0,0.9,0.5)).barVisible(false).hide();
window+=text .create(Vec2 (window.crect.w()/2,-0.15),"Load Game");
window+=close .create(Rect_C(window.crect.w()/2,-window.crect.h()/2-0.1,0.4,0.08),"Close",Close);
}
}Ml;
/******************************************************************************/
struct MenuOptions // options menu
{
Window window;
Text text;
Button close;
static void Close(Ptr){Mo.window.fadeOut();}
void create()
{
Gui +=window.create(Rect_C(0,0,0.9,0.5)).barVisible(false).hide();
window+=text .create(Vec2 (window.crect.w()/2,-0.15),"Options");
window+=close .create(Rect_C(window.crect.w()/2,-window.crect.h()/2-0.1,0.4,0.08),"Close",Close);
}
}Mo;
/******************************************************************************/
struct MenuMain // main menu
{
Window window;
Button b_new,b_load,b_options,b_exit;
static void New (Ptr){Mn.window.fadeIn();}
static void Load (Ptr){Ml.window.fadeIn();}
static void Options(Ptr){Mo.window.fadeIn();}
static void Exit (Ptr){StateExit.set();}
void create()
{
Gui +=window .create(Rect_C(0,-0.1,0.6,0.6)).barVisible(false);
window+=b_new .create(Rect_C(window.crect.w()/2,-0.15,0.4,0.08),"New" ,New);
window+=b_load .create(Rect_C(window.crect.w()/2,-0.25,0.4,0.08),"Load" ,Load);
window+=b_options.create(Rect_C(window.crect.w()/2,-0.35,0.4,0.08),"Options",Options);
window+=b_exit .create(Rect_C(window.crect.w()/2,-0.45,0.4,0.08),"Exit" ,Exit);
window.flag&=~WIN_MOVABLE; // disable moving of this window
window.level=-1 ; // set lower level so this window will be always below the other created in this tutorial
}
}Mm;
/******************************************************************************/
void InitPre()
{
App.name("Game Menu");
App.flag=APP_FULL_TOGGLE; // we'll be using GUI effects (window fading) so make sure APP_NO_FX isn't selected
PakAdd("../data/engine.pak");
D.mode(800,600).sync(true);
}
/******************************************************************************/
Bool Init()
{
// in games disable highlighting elements with keyboard focus
Gui.kb_lit=0;
// change default gui text colors
Gui.tds_text.color=WHITE;
Gui.tds_text.shadow=255;
// change Default Gui Window Style
Gui.style_window.gfx_back =Gfxs("../data/Gui/Style/0/back.gfx");
Gui.style_window.gfx_border =Gfxs("../data/Gui/Style/0/border.gfx");
Gui.style_window.border_color=WHITE;
Gui.style_window.back_color =BLUE;
Gui.style_window.border_width=0.03;
Mn.create();
Ml.create();
Mo.create();
Mm.create();
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Gui.update();
return true;
}
/******************************************************************************/
void Draw()
{
D .clear();
Gui.draw ();
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Gui\08 - Loading Gui Objects.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************
Instead of creating all Gui Objects manually in the code,
you can create them in the Gui Editor tool, and then just load them.
/******************************************************************************/
GuiObjs gui_objs;
TextLine *name;
Button *next;
/******************************************************************************/
void InitPre()
{
App.name("Loading Gui Objects");
App.flag=APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.mode(800,600).sync(true);
}
/******************************************************************************/
void ButtonFunction(Ptr) // custom function called when button pressed
{
if(name)name->clear(); // if we have accessed the 'name' TextLine then simply clear it
}
/******************************************************************************/
Bool Init()
{
Gui.kb_lit=0;
// load prepared Gui Objects in Gui Editor
if(gui_objs.load("gui/obj/player name.gobj"))
{
// if loaded succesfully 'gui_objs' now contains all the buttons, windows and other objects, stored in containers
// first we'll add all of them to the Gui (more specifically to the active desktop) :
Gui+=gui_objs;
// now all objects are placed onto the desktop
// the next step is to access the objects, accessing is done by requesting objects by name
// each objects name has to be manually set in the Gui Editor
name=gui_objs.getTextLine("name"); // get the 'player name' TextLine, which has its name set to "name" (it has been set in the Gui Editor)
next=gui_objs.getButton ("next"); // get the 'next' Button , which has its name set to "next" (it has been set in the Gui Editor)
next->func=ButtonFunction; // once we have the button we can manually assign a function for it, which will be called when the button is pressed
return true;
}
return false;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Gui.update();
return true;
}
/******************************************************************************/
void Draw()
{
D .clear();
Gui.draw ();
if(name)D.text(0,0.9,S+(*name)()); // draw accessed TextLine value
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Gui\09 - Extending Gui Objects.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************
Because the main methods of Gui Objects are virtual, you can extend them.
/******************************************************************************/
struct Button2 : Button // Create a new class extending the default Gui Button
{
virtual void test (GuiPC &gpc); // extend testing if object is under mouse cursor
virtual Button2& update(GuiPC &gpc); // extend updating object
virtual void draw (GuiPC &gpc); // extend drawing object
};
void Button2::test(GuiPC &gpc) // extend testing
{
__super::test(gpc); // call default method
}
Button2& Button2::update(GuiPC &gpc) // extend updating
{
__super::update(gpc); // call default method
return T; // return self
}
void Button2::draw(GuiPC &gpc) // extend drawing
{
D.clip(gpc.clip); // clip display drawing to given clipping rectangle, this is needed for example when object is inside a window, and is partially hidden because the parent's rectangle doesn't fully cover this object
UInt color=(visuallyPushed() ? BLACK : ColorLerp(RED_DARK,RED,lit())); // set different color depending if the button is pushed and highlighted
D.rect(color, rect+gpc.offset); // draw a background rectangle, moved by 'gpc.offset' (parents offset)
D.text(rect.center()+gpc.offset, text); // draw button's text, at center of rectangle and again moved by 'gpc.offset'
}
/******************************************************************************/
Button2 button; // create a sample button
/******************************************************************************/
void InitPre()
{
App.name("Extending Gui Objects");
App.flag=APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.mode(800,600).sync(true);
}
/******************************************************************************/
Bool Init()
{
Gui+=button.create(Rect_C(0,0,0.5,0.1),"New Button"); // add the button to the active desktop
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Gui.update();
return true;
}
/******************************************************************************/
void Draw()
{
D .clear(WHITE);
Gui.draw ();
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Gui\10 - Extending and Loading Gui Objects.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
// Define extended version of default 'Button'
/******************************************************************************/
struct Button2 : Button
{
virtual void test (GuiPC &gpc);
virtual Button2& update(GuiPC &gpc);
virtual void draw (GuiPC &gpc);
};
void Button2::test(GuiPC &gpc)
{
__super::test(gpc);
}
Button2& Button2::update(GuiPC &gpc)
{
__super::update(gpc);
return T;
}
void Button2::draw(GuiPC &gpc)
{
D.clip(gpc.clip);
UInt color=(visuallyPushed() ? BLACK : ColorLerp(RED_DARK,RED,lit()));
D.rect(color, rect+gpc.offset);
D.text(rect.center()+gpc.offset, text);
}
/******************************************************************************/
GuiObjs gui_objs;
Button2 button;
/******************************************************************************/
void InitPre()
{
App.name("Extending and Loading Gui Objects");
App.flag=APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.mode(800,600).sync(true);
}
/******************************************************************************/
Bool Init()
{
Gui.kb_lit=0;
// replace default 'Button' class with extended 'Button2'
gui_objs.replaceButton<Button2>();
// load the gui objects
if(gui_objs.load("gui/obj/player name.gobj"))
{
Gui+=gui_objs;
return true;
}
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Gui.update();
return true;
}
/******************************************************************************/
void Draw()
{
D .clear(BLACK);
Gui.draw ();
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Gui\11 - Multiple Viewports.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************
In this tutorial we'll present multiple viewports with different cameras,
We'll use 'GViewport::user' to set camera's index
/******************************************************************************/
GViewport viewport[2];
Camera camera [2];
/******************************************************************************/
void Render(GViewport &viewport) // rendering function wich will be called when drawing the Gui Viewport element
{
Int camera_index=Mid(viewport.userd,0,ELMS(camera)-1); // get camera index and clamp it for safety, in case the user data is invalid
// activate camera
camera[camera_index].set();
// simple rendering
D.clear(BLACK);
Box(1,Vec(0,0,0)).draw(WHITE);
}
/******************************************************************************/
void InitPre()
{
App.name("Multiple Viewports");
App.flag=APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.mode(800,600).sync(true);
}
/******************************************************************************/
Bool Init()
{
// initialize cameras
camera[0].setSpherical(Vec(0,0,0),0,0,0,3);
camera[1].setSpherical(Vec(0,0,0),0,0,0,3);
Gui+=viewport[0].create(Rect_C(-0.5,0,0.9,0.9),Render,(Ptr)0); // create a viewport with 'user=0' to mark camera[0] usage
Gui+=viewport[1].create(Rect_C( 0.5,0,0.9,0.9),Render,(Ptr)1); // create a viewport with 'user=1' to mark camera[1] usage
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Gui.update();
// now we'll modify camera angles and distance
// first we'll detect which camera to update
{
Camera *cam=NULL; // start with none
// 'Gui.viewport' specifies current Gui Viewport under mouse cursor
if(Gui.viewport==&viewport[0])cam=&camera[0];else
if(Gui.viewport==&viewport[1])cam=&camera[1];
if(cam) // if found a camera
{
// modify camera values by mouse movement
if(Ms.b(0)) // only when mouse button pressed
{
cam->yaw -=Ms.d.x;
cam->pitch+=Ms.d.y;
}
// modify camera distance by mouse wheel
if(Ms.wheel<0)cam->dist*=1.2;
if(Ms.wheel>0)cam->dist/=1.2;
cam->setSpherical(); // apply changes by calling 'setSpherical' which sets camera matrix from current values
}
}
// update all camera velocities, this is needed when using Motion Blur effect
REPA(camera)camera[i].updateVelocities();
return true;
}
/******************************************************************************/
void Draw()
{
D .clear(WHITE);
Gui.draw ( );
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Gui\12 - Window IO.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
WindowIO wio_mesh; // window handling input/ouput
Mesh mesh ; // mesh which will be used for saving,loadng and drawing
/******************************************************************************/
void InitPre()
{
App.name("Window IO");
App.flag=APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.mode(800,600).sync(true);
}
/******************************************************************************/
void Load(CChar *name) // this function will be called when WindowIO will load a file
{
mesh.load(name);
}
void Save(CChar *name) // this function will be called when WindowIO will save a file
{
// here you can save your file, however in this tutorial we're not going to do this
// mesh.save(name);
}
/******************************************************************************/
Bool Init()
{
wio_mesh.create("mesh",CNULL,IOPath(),Load,Save); // create a WindowIO, giving accepted file extension, paths, and IO functions
wio_mesh.path_mode=WIN_IOP_PART; // set displaying path mode on the window title bar
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Gui.update();
wio_mesh.update(); // WindowIO needs to be manually updated
// activate saving/loading on keypress
if(Kb.bp(KB_F2))wio_mesh.save();
if(Kb.bp(KB_F3))wio_mesh.load();
return true;
}
/******************************************************************************/
void Draw()
{
D .clear(GREY);
Cam .setSpherical(Vec(0),Tm.time(),0,0,mesh.box.size().length()*1.2).updateVelocities().set();
LightDir(Cam.matrix.z).set();
mesh.draw(MatrixIdentity);
D .text(0,0.9,"Press F2/F3 to save/load");
Gui .draw();
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Misc\Calculator.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
TextLine textline; // Gui TextLine
/******************************************************************************/
void InitPre()
{
App.name("Calculator");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
Gui+=textline.create(Rect(-0.5,0,0.5,0.1)); // add textline to gui desktop
textline.kbSet(); // set keyboard focus
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Gui.update();
return true;
}
/******************************************************************************/
void Draw()
{
D .clear(WHITE);
Gui.draw ();
D.text(0,-0.4,S+CalcR(textline())); // draw calculated value from 'textline' as Real
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Misc\Config.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
void InitPre()
{
App.name("Config");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
// here you can set initial settings
// they will be used in case "config.txt" file is not found or incomplete
// ..
if(ConfigLoad()) // here settings are loaded from "config.txt"
{
// if settings were loaded properly, you can optionally override them here
// ..
}
}
/******************************************************************************/
Bool Init()
{
return true;
}
/******************************************************************************/
void Shut()
{
ConfigSave(); // here settings are saved to "config.txt"
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Misc\Cpu.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Str s;
/******************************************************************************/
void InitPre()
{
App.name("CPU");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
// check which features are supported
if(Cpu.flag()&CPU_MMX )s.space()+="MMX";
if(Cpu.flag()&CPU_3DNOW )s.space()+="3dNow";
if(Cpu.flag()&CPU_3DNOW2)s.space()+="3dNow+";
if(Cpu.flag()&CPU_SSE )s.space()+="SSE";
if(Cpu.flag()&CPU_SSE2 )s.space()+="SSE2";
if(Cpu.flag()&CPU_SSE3 )s.space()+="SSE3";
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
D.text (0,0.3,S+"Number of cores: " +Cpu.cores());
D.text (0,0.1,S+"Supported features: "+s);
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Misc\Drag & Drop.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Memb<Char[MAX_PATH]> names;
/******************************************************************************/
void Drop()
{
names.clear(); // remove all existing elements in container
for(;CChar *name=DropName();) // iterate through all files dropped
{
// here you can perform operations on dropped file, by accessing it's 'name'
// in this tutorial we will just store the name in a memory container
Set(names.New(),name); // copy 'name' to 'names' container
}
}
/******************************************************************************/
void InitPre()
{
App.name("Drag & Drop");
App.flag=APP_NO_FX;
App.drop=Drop; // enable Drag & Drop by specifying function called when a file will be dropped on window
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
D.text (0,0.9,"Drag & Drop some files to this window");
FREPA(names)D.text(0,0.7-i*0.1,names[i]); // draw all file names
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Misc\File.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************
Files are universal and can be used to:
-read/write from stdio files (typical files on you Hard Drive)
-read files from Pak (an archive of multiple files)
They handle encrypting/decrypting with given Secure key
/******************************************************************************/
struct Data
{
Char text[256];
};
/******************************************************************************/
void InitPre()
{
App.name("File");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
Data data;
Set(data.text,"Sample text");
// for testing we'll start with with writing to a file in memory
{
File f; // file object
f.writeMem( ); // start writing to memory (file will automatically handle the memory allocations)
f.putByte ( 128); // put Byte '128' to file
f.putDwrd (0x12345678); // put U32 '0x12345678' to file
f<<data; // put 'data' to file (it's raw memory)
}
// now let's write all that to a real file on Hard Disk
{
File f;
f.write ("LocalData/file.dat"); // start writing to file
f.putByte( 128);
f.putDwrd(0x12345678);
f<<data;
}
// when the file is created we can now read it
{
File f;
f.read ("LocalData/file.dat"); // start reading file
Byte b=f.getByte(); // read Byt (returns 128)
UInt d=f.getDwrd(); // read U32 (returns 0x12345678)
f>>data ; // read 'data' (data.text should be "Sample text")
}
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Misc\FileFind.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Memb<Char[MAX_PATH]> names;
/******************************************************************************/
void InitPre()
{
App.name("FileFind");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
void AddName(CChar *name) // add 'name' to names list
{
Set(names.New(),name); // create new element in names and set it's name
}
void ManualFind(Str path) // manually iterate through directories and files
{
for(FileFind ff(path); ff();)switch(ff.type) // start looking for files in path, continue while active, and check for encountered type
{
case FSTD_DIR : ManualFind(ff.pathName()); break; // if directory encountered start looking inside it
case FSTD_FILE: AddName (ff.pathName()); break; // if file encountered add it to the list
}
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
if(Kb.bp(KB_SPACE))
{
names.clear(); // clear elements
FAll("source",AddName); // use FAll which operates on all files inside given path (AddName will be called multiple times with each file name as a parameter)
}
if(Kb.bp(KB_ENTER))
{
names.clear(); // clear elements
ManualFind("source"); // manually iterate through all directories and files
}
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
D.text (0,0.9,"Press Space to use FAll, or press Enter for FileFind");
FREPA(names)D.text(0,0.8-i*0.1,names[i]); // draw all file names
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Misc\FileText.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************
FileText is meant for operations performed on a text file
/******************************************************************************/
struct Data // custom Data structure to test text file saving/loading
{
Flt volume;
Int graphics_mode;
Char player_name[64];
Bool saveTxt(Str name); // save data to text file
Bool loadTxt(Str name); // load data from text file
};
/******************************************************************************/
Bool Data::saveTxt(Str name)
{
FileText f; // FileText object
if(f.write(name)) // if file opened successfully
{
f.put ("Volume = ",volume );
f.put ("GraphicsMode = ",graphics_mode); // please note "GraphicsMode" is used instead of "Graphics Mode" (names are required to don't have spaces)
f.putName("PlayerName = ",player_name ); // FileText::putName will automatically put the value in quotes
return true; // return success
}
return false; // return failure
}
Bool Data::loadTxt(Str name)
{
// set default values to members in case file not found or file incomplete
volume=1;
graphics_mode=5;
player_name[0]=0;
FileText f;
if(f.read(name)) // if file opened successfully
{
for(;f.level();) // process file within its level
{
if(f.cur("Volume" ))volume =Sat(f.getReal() );else // if encountered "Volume" then read a floating point value, saturate it and store into 'value'
if(f.cur("GraphicsMode"))graphics_mode=Mid(f.getInt (),0,10);else // if encountered "GraphicsMode" then read a integer value, clamp it and store into 'graphics_mode'
if(f.cur("PlayerName" ))Set(player_name, f.getName() ); // if encountered "PlayerName" then read a string using 'FileText::getName' method into 'player_name'
}
return true; // return success
}
return false; // return failure
}
/******************************************************************************/
void InitPre()
{
App.name("FileText");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
// set sample data values
Data data;
data.volume =0.5;
data.graphics_mode=2;
Set(data.player_name,"He-Man");
data.saveTxt("LocalData/file.txt"); // save data to text file
data.loadTxt("LocalData/file.txt"); // load data from text file
OSLaunch("LocalData/file.txt"); // open the text file in default Windows viewer to check what actually has been saved
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Misc\IO Path.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************
To work easily with relative path's 'IOPath' is used
when IOPath is set it is treated as additional path for your files/resources
For Example you have all your data stored in 'd:/game/data', like:
'd:/game/data/gfx/..'
'd:/game/data/anim/..'
'd:/game/data/obj/..'
and you'd like to access them more simply:
"gfx/.."
"anim/.."
"obj/.."
To do so, all you have to do is set IOPath to "d:/game/data"
/******************************************************************************/
Gfx *gfx;
/******************************************************************************/
void InitPre()
{
App.name("IO Path");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
// in this sample we'll load "image.gfx" which is located in "LocalData" folder where the tutorials are ("LocalData/image.gfx")
IOPath("LocalData"); // setup additional IO Search Path
gfx=Gfxs("image.gfx"); // load image, IOPath will be used automatically
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
gfx->draw(-0.5,0.5, 1,1);
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Misc\Memory.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
struct Data // custom data structure
{
Byte bytes[100];
Int integer;
Flt value;
};
/******************************************************************************/
// memory containers
Memb<Data> memb; // block based
Meml<Data> meml; // list based
/******************************************************************************/
void InitPre()
{
App.name("Memory");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
// adding elements
{
// Memb
{
Data &data=memb.New();
data.integer=5;
}
// Meml
{
Data &data=meml.New();
data.integer=5;
}
}
// iterating through all elements
{
// Memb
for(Int i=0; i<memb.elms(); i++)
{
Data &d=memb[i];
}
// Memb through better macro
FREPA(memb)
{
Data &d=memb[i];
}
// Meml
for(MemlNode *i=meml.first; i; i=i->next)
{
Data &d=meml[i];
}
// Meml through macro
MFREP(meml) // please note that here 'i' is not an 'Int' but a 'MemlNode*'
{
Data &d=meml[i];
}
}
// removing elements
{
// Memb
{
memb.remove(0,true); // remove 0th element, second parameter determines keeping order (read more in the header)
}
// Meml
{
meml.remove(meml.first);
}
}
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Misc\Mouse Cursor.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
void InitPre()
{
App.name("Mouse Cursor");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
if(Kb.bp(KB_1))Ms.cursor(Gfxs("../data/gfx/cursor/0.gfx")); // if '1' pressed change cursor to '0.gfx'
if(Kb.bp(KB_2))Ms.cursor(Gfxs("../data/gfx/cursor/1.gfx")); // if '2' pressed change cursor to '1.gfx'
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
D.text (0,0,"Press '1' or '2' to change mouse cursor");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Misc\Number.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************
Number is a number able to store very big values with big precision (Int or Real)
/******************************************************************************/
Number n0,n1,n2,n3,n4;
/******************************************************************************/
void InitPre()
{
App.name("Number");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
// assign 1.0
n0=1.0;
// do some big operations
n0*=100000; n0.sqrt(); n0+=123.456;
n0*=100000; n0.sqrt(); n0+=123.456;
n0*=100000; n0.sqrt(); n0+=123.456;
// revert operations
n0-=123.456; n0.sqr(); n0/=100000;
n0-=123.456; n0.sqr(); n0/=100000;
n0-=123.456; n0.sqr(); n0/=100000;
// n0 should be back to 1.0
// calculate sqrt(sqrt(sqrt(1000000000000000000000000000000.)))
n1=Str("1000000000000000000000000000000.");
n1.sqrt();
n1.sqrt();
n1.sqrt();
// NOTE: Number can be internally an Int or Real (check Number::real)
// any operation between Int and Int results also in Int (any other in Real)
// when calculating Number(10)/3 you'll get 3 instead of 3.333..
// to convert Number to be Int or Real use toInt() and toReal() methods
{
n2=Number(10 )/3; // Int /Int = Int (3)
n3=Number(10.0)/3; // Real/Int = Real (3.333..)
n4=10; // Int
n4.toReal(); // convert to Real
n4/=3; // Real/Int = Real (3.333..)
}
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
D.text (0,0.6, S+"n0 = "+n0.asReal());
D.text (0,0.4, S+"n1 = "+n1.asReal());
D.text (0,0.2, S+"n2 = "+n2.asReal());
D.text (0,0.1, S+"n3 = "+n3.asReal());
D.text (0,0.0, S+"n4 = "+n4.asReal());
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Misc\Pak Create.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Byte b1,b2; // bytes
/******************************************************************************/
void InitPre()
{
App.name("Pak Create");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
// create Pak from one file/directory
{
PakCreate("LocalData"); // create Pak from "LocalData" folder, if no 'pak_name' is specified it will be automatically set (in this case it'll be "LocalData.pak")
}
// create Pak from list of files
{
Memb<Char[MAX_PATH]> list;
Set(list.New(),"LocalData" ); // add "LocalData" directory to the list
Set(list.New(),"stdafx.h" ); // add "stdafx.h" file to the list
Set(list.New(),"stdafx.cpp"); // add "stdafx.cpp" file to the list
PakCreate(list); // create Pak from list, 'pak_name' will be automatically set to "Tutorials.pak"
}
// create Pak from files in memory
{
Memb<File> file; // array of file's which we'll create and write to them
using namespace PakDefs; // use this namespace to simplify Pak creation
// from now on in current scope:
// N is a file node Node<PakNode>
N n; // lets start with main node
{
File &f=file.New(); // add new file to array
f.writeMem(); // start writing to memory
f.putByte(123); // write a Byte to that file
n.New().set("File 1.dat",f); // add this file to file nodes
}
{
N &d=(n+="Directory"); // add new directory
{
File &f=file.New(); // add new file to array
f.writeMem(); // start writing to memory
f.putByte(234); // write a Byte to that file
d.New().set("File 2.dat",f); // add this file to directory
}
}
PakCreate(n,"Pak from memory.pak"); // create Pak from nodes
}
// load custom Pak
{
PakAdd("Pak from memory.pak");
// from now on any data stored in loaded Pak can be accessed through IO methods
{
File f1("File 1.dat"); // open the file
b1=f1.getByte(); // read Byte from that file
File f2("Directory/File 2.dat"); // open the file
b2=f2.getByte(); // read Byte from that file
}
}
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
D.text (0,0,S+b1+" "+b2); // display bytes
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Misc\Pak.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************
Pak is a storage file type, it contains multiple files inside.
Once you load a Pak you can access all the files inside it.
/******************************************************************************/
Gfx *gfx;
/******************************************************************************/
void InitPre()
{
App.name("Pak's");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
// 'sample.pak' used in this tutorial has only one folder 'folder' and one file 'image.gfx' located in 'folder' like this:
// "folder/image.gfx"
// load custom Pak
PakAdd("../data/sample.pak");
// from now on any data stored in loaded Pak can be accessed through IO methods
{
// you can open files stored in that Pak:
{
File f;
f.read ("folder/image.gfx"); // start reading file
f.getByte( ); // get Byte from that file
}
// you can access resources through cache
{
gfx=Gfxs("folder/image.gfx");
}
}
// Pak's can be easily made using "Converter.exe" located in "Tools" folder
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
gfx->draw(-0.5,0.5, 1,1);
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Misc\Pathfind.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
PathFind pf ; // path finder
Memb<VecI2> path ; // path
VecI2 start,end; // start and end position of wanted path
/******************************************************************************/
void InitPre()
{
App.name("Pathfind");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
D.sync(true);
}
Bool Init()
{
Gfx map;
if( map.ImportTry("../data/gfx/map/map.png",-1,GFX_SOFT))
{
pf.create(map.x(),map.y());
REPD(y,pf.y())
REPD(x,pf.x())
{
UInt color=map.color(x,y); // get pixel color of loaded map
pf.pixelFlag(x,y,(color!=BLACK) ? PFP_WALKABLE : 0); // set non black color for walkable pixels
}
}
return true;
}
void Shut()
{
}
/******************************************************************************/
VecI2 ScreenToPix(Vec2 &screen)
{
Int size=Max(pf.x(),pf.y())*4/3;
return VecI2(Round((screen.x+D.h()*3/4)*size/2),
Round((screen.y+D.h()*3/4)*size/2));
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
// set starting position on LMB
if(Ms.b(0))
{
start=ScreenToPix(Ms.pos);
pf.find(start,path);
}
// set ending position on RMB
if(Ms.b(1))
{
end=ScreenToPix(Ms.pos);
pf.setTarget(end.x,end.y).find(start,path);
}
return true;
}
/******************************************************************************/
void DrawPixel(Int x,Int y,UInt color)
{
Int size=Max(pf.x(),pf.y())*4/3;
VI.dot(color, Vec2(x,y)*2/size-D.h()*3/4, 1.0f/size);
}
void Draw()
{
D.clear(GREY);
REPD(y,pf.y())
REPD(x,pf.x())DrawPixel(x,y,FlagTest(pf.pixelFlag(x,y),PFP_WALKABLE) ? WHITE : BLACK); // draw map
REPA(path )DrawPixel(path[i].x,path[i].y,YELLOW); // draw path with yellow color
DrawPixel(start .x,start .y,GREEN ); // draw starting position with green color
DrawPixel(end .x,end .y,RED ); // draw ending position with red color
VI.end();
D.text(0,0.9,"Press LMB and RMB to set Start and End position");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Misc\Random.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
void InitPre()
{
App.name("Random");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
D.sync(true); // enable screen synchronization
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
Cam .dist =2;
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC ))return false;
if(Kb.b (KB_SPACE))CamHandle(0.1,10,CAMH_ZOOM|CAMH_ROT);
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
if(Kb.b(KB_SPACE)) // when space on draw random points in 3D
{
// here we're rendering 10 000 dots, such big number is more efficient to draw through VertexIndexBuffer (for more information about it check its tutorial in "advanced\graphics")
VI.color(ColorAlpha(TURQ,0.1)); // set color
REP(10000)VI.dot (Random(Capsule(0.5,2))); // draw dot at random position in capsule
VI.end (); // finish buffered drawing
}else
{
D.text(0,0.7,S+Random(4)+" "+Random(10,15)+" "+RandomF()+" "+RandomF(10,15));
REP(1000)D.dot(BLUE,Random(Circle(0.5 ))); // draw 1000 random points inside circle
REP(1000)D.dot(RED ,Random(Rect (0.5,-0.5,1,0.5))); // draw 1000 random points inside rectangle
}
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Misc\Sort.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Flt floats[8];
struct CustomData
{
Byte bytes[100];
Flt real;
Int integer;
}data[8];
Memb<CustomData> memb;
/******************************************************************************
Custom comparing functions must be of "Int name(TYPE &a,TYPE &b)" format
they receive references to 2 custom data elements
they must return:
-1 if 'a' should be before 'b'
+1 if 'a' should be after 'b'
0 if 'a' is the same as 'b'
/******************************************************************************/
Int CompareCustomData(CustomData &a,CustomData &b)
{
if(a.real<b.real)return -1;
if(a.real>b.real)return +1;
return 0;
}
/******************************************************************************/
void InitPre()
{
App.name("Sorting");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
REPA(floats)floats[i] =RandomF(10); // fill 'floats' with random values (0..10)
REPA(data )data [i].real=RandomF(10); // fill 'data.real' with random values (0..10)
REP (8 )memb (i).real=RandomF(10); // fill 'memb.real' with random values (0..10)
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
if(Kb.bp(KB_SPACE)) // sort when space pressed
{
Sort(floats,ELMS(floats) ); // sort 'floats'
Sort(data ,ELMS(data ),CompareCustomData); // sort custom data by giving pointer to data, number of elements and custom comparing function
Sort(memb ,CompareCustomData); // sort custom data by giving memory block and custom comparing function
}
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
D.text (0,0.7,"Press Space to sort");
Str s="floats: "; FREPA(floats){s+=floats[i] ; s+=" ";} D.text(0, 0.2,s); // draw 'floats' in one string
s="data: " ; FREPA(data ){s+=data [i].real; s+=" ";} D.text(0, 0.0,s); // draw 'data.real' in one string
s="memb: " ; FREPA(memb ){s+=memb [i].real; s+=" ";} D.text(0,-0.2,s); // draw 'memb.real' in one string
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Misc\States.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************
States are used for different 'Application States'
for example there can be 'intro state', 'menu state', 'game state'
/******************************************************************************/
extern State StateMenu,StateIntro,StateGame; // forward declare used states in this tutorial
/******************************************************************************/
void InitPre()
{
App.name("States");
PakAdd("../data/engine.pak");
}
Bool Init()
{
StateIntro.set(); // set StateIntro as the active state, this means that from now on, only StateIntro's update and drawing methods will be called instead of 'Main' and 'Draw'
return true;
}
void Shut()
{
}
Bool Main(){return true;}
void Draw(){}
/******************************************************************************/
// INTRO
/******************************************************************************/
Bool InitIntro(){return true;}
void ShutIntro(){}
Bool UpdateIntro()
{
if(StateActive->time()>3 || Kb.bp(KB_ESC)) // if active state (which here is StateIntro) is running for more than 3 seconds or escape pressed
StateMenu.set(1.0); // then switch to 'StateMenu' state with 1.0 second smooth fading
return true;
}
void DrawIntro()
{
D.clear(BLACK);
D.text (0,0,"Intro");
}
State StateIntro(UpdateIntro,DrawIntro,InitIntro,ShutIntro);
/******************************************************************************/
// MENU
/******************************************************************************/
Bool InitMenu(){return true;}
void ShutMenu(){}
Bool UpdateMenu()
{
if(Kb.bp(KB_ESC))return false; // when escape pressed exit application
if(Kb.bp(KB_ENTER))StateGame.set(0.5); // when enter pressed set 'StateGame' with 0.5 second smooth fading
return true;
}
void DrawMenu()
{
D.clear(GREY);
D.text (0, 0 ,"Menu");
D.text (0,-0.3,"Press Enter to start the game");
D.text (0,-0.5,"Press Escape to exit");
}
State StateMenu(UpdateMenu,DrawMenu,InitMenu,ShutMenu);
/******************************************************************************/
// GAME
/******************************************************************************/
Bool InitGame(){return true;}
void ShutGame(){}
Bool UpdateGame()
{
if(Kb.bp(KB_ESC))StateMenu.set(1.0); // when escape pressed set 'StateMenu' with 1.0 second smooth fading
return true;
}
void DrawGame()
{
D.clear(TURQ);
D.text (0,0,"Game");
}
State StateGame(UpdateGame,DrawGame,InitGame,ShutGame);
/******************************************************************************
Typically methods will be called in this order:
Init()
InitIntro()
UpdateIntro()
DrawIntro()
..
UpdateIntro()
DrawIntro()
ShutIntro()
InitMenu ()
UpdateMenu()
DrawMenu()
..
UpdateMenu()
DrawMenu()
ShutMenu()
InitGame()
UpdateGame()
DrawGame()
..
UpdateGame()
DrawGame()
ShutGame()
InitMenu()
UpdateMenu()
DrawMenu()
..
UpdateMenu()
DrawMenu()
ShutMenu()
Shut()
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Misc\Threads 2.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Flt time;
/******************************************************************************/
void Calculate(Real x)
{
// perform lot's of numerical calculations
REP(1000)
REP(1000)
{
x =Cos(Sin(x*x+Sqrt(x)));
x+=Pow(10+x,10+x*5);
x =Cbrt(Tan(x));
}
}
/******************************************************************************/
void SingleThreadCalculate()
{
Calculate(1);
Calculate(2);
}
/******************************************************************************/
Bool ThreadProcA(Thread &thread)
{
Calculate(1); // perform calculations
return false; // stop the thread after calculations
}
Bool ThreadProcB(Thread &thread)
{
Calculate(2); // perform calculations
return false; // stop the thread after calculations
}
void MultiThreadCalculate()
{
// create the threads
Thread thread_a(ThreadProcA),
thread_b(ThreadProcB);
// wait for the threads to finish processing
thread_a.wait();
thread_b.wait();
// delete threads
thread_a.del();
thread_b.del();
}
/******************************************************************************/
void InitPre()
{
App.name("Threads");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
if(Kb.bp(KB_1))
{
time=Tm.curTime(); // get current time
SingleThreadCalculate(); // perform calculations on one thread
time=Tm.curTime()-time; // get difference between remembered and current time
}
if(Kb.bp(KB_2))
{
time=Tm.curTime(); // get current time
MultiThreadCalculate(); // perform calculations on multiple threads
time=Tm.curTime()-time; // get difference between remembered and current time
}
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
D.text(0,0.9,S+"Press 1 for single threaded calculations");
D.text(0,0.8,S+"Press 2 for multi threaded calculations");
D.text(0,0,S+"Time spent for calculations : "+time);
REP(3)
{
Flt a=Tm.time()*2+i*PI2/3;
Tri2 t;
t.p[0].set(0,0);
t.p[1].set(Cos(a ),Sin(a ));
t.p[2].set(Cos(a+PI2/9),Sin(a+PI2/9));
(t*0.2-Vec2(0,0.5)).draw(GREY);
}
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Misc\Threads.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************
Threads are programs (functions) which run simultaneously
/******************************************************************************/
// global integers
Int x,
y[2];
// threads
Thread thread_x,
thread_y0,
thread_y1;
/******************************************************************************
Thread functions must be of "Bool name(Thread &thread)" format
they return true when wan't to continue thread processing, and false when wan't to stop them
as input parameter thread functions receive reference to the Thread which calls them
/******************************************************************************/
Bool ThreadProc(Thread &thread_caller)
{
x++; // simple increase x value
return true; // continue processing
}
Bool ThreadProcWithUserData(Thread &thread_caller)
{
y[thread_caller.userd]++; // make use of thread_caller 'userd' user data, and increase wanted 'y' (it will be y[0] or y[1])
return true; // continue processing
}
/******************************************************************************/
void InitPre()
{
App.name("Threads");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
// create threads
thread_x .create(ThreadProc , 0,0,100 ); // thread_x will use 'ThreadProc' as it's procedure, and it will be called once in 100 miliseconds
thread_y0.create(ThreadProcWithUserData, 0,0,100, Ptr(0)); // thread_y0 will use 'ThreadProcWithUserData' as it's procedure, it will be called once in 100 miliseconds, and it will use '0' as it's user data
thread_y1.create(ThreadProcWithUserData, 0,0,100, Ptr(1)); // thread_y1 will use 'ThreadProcWithUserData' as it's procedure, it will be called once in 100 miliseconds, and it will use '1' as it's user data
return true;
}
/******************************************************************************/
void Shut()
{
// delete threads
thread_x .del();
thread_y0.del();
thread_y1.del();
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
// draw values
D.text(0,0.2,S+"x: " +x );
D.text(0,0.1,S+"y[0]: "+y[0]);
D.text(0,0.0,S+"y[1]: "+y[1]);
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Misc\Video Playback.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Theora video;
/******************************************************************************/
void InitPre()
{
App.name("Video Playback");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
if(!video.create("../data/video/test.ogv"))return Exit("Can't create video"); // create video from Theora File
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
video.update(Tm.curTime()); // update video to current application time
return true;
}
/******************************************************************************/
void Draw()
{
D .clear();
video.draw (); // draw video
D .text (0,0.9,S+video.time()); // draw time position of video
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Misc\Zip.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Char text[]={L"This is a simple text which will be compressed using ZLIB compression. 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ"};
Byte * compressed, // buffer where compressed data will be stored
*decompressed; // buffer where decompressed data will be stored
I32 src_size=SIZE(text),
compressed_buf_size,
compressed_size,
decompressed_size;
/******************************************************************************/
void InitPre()
{
App.name("Zip compression");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
// compression
{
// for compression we'll need buffer which will hould enough data
// how much is enough is calculated through 'ZipSize' function and giving source size
compressed_buf_size=ZipSize(src_size);
// create raw memory buffer able to store 'compressed_buf_size' bytes
Alloc(compressed,compressed_buf_size);
// compress data
// before compressing we must set destination buffer size('compressed_size') to maximum memory available
compressed_size=compressed_buf_size;
ZipCompress(compressed,compressed_size,text,src_size); // now 'compressed' contains compressed data, and 'compressed_size' is the actual size of compressed data
}
// decompression
{
// for decompression we'll need buffer which will hold decompressed data (we know that decompressed size is the size of the source)
Alloc(decompressed,src_size);
// decompress data
// before decompression we must set destination buffer size('decompressed_size') to maximum memory available
decompressed_size=src_size;
ZipDecompress(decompressed,decompressed_size,compressed,compressed_size); // now 'decompressed' contains decompressed data, and 'decompressed_size' is the actual size of decompressed data
}
return true;
}
/******************************************************************************/
void Shut()
{
// free buffers
Free( compressed);
Free(decompressed);
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
D.text(0,0.2,S+"Source size: "+src_size);
D.text(0,0.1,S+"Compressed size: "+compressed_size);
D.text(0,0.0,S+"Buffer size used for compression: "+compressed_buf_size);
D.text(0,-0.2,"Source text:" ); D.text(Sin(Tm.time())*2.5,-0.3, text);
D.text(0,-0.5,"Decompressed text:"); D.text(Sin(Tm.time())*2.5,-0.6,(Char*)decompressed);
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Net\Download.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Gfx gfx;
Download download;
/******************************************************************************/
void InitPre()
{
App.name("Downloading file");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
download.create("http://www.esenthel.com/download/logo.gfx"); // create downloader
return true;
}
/******************************************************************************/
void Shut()
{
download.del(); // delete downloader
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
if(download.state()==DWNL_DONE) // if all data downloaded successfully
{
// data can be accessed freely through Download::buf,size methods
// for example download.buf()[0] is the first Byte of data
// we'll use the downloaded data to load an image from it
if(!gfx.is()) // check if we haven't already created it
{
File f(download.data(),download.size()); // create a file from memory data
gfx.load(f); // load a gfx from the file
}
}
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
if(gfx.is()) // when image is downloaded and created
gfx.drawFs(); // draw it
switch(download.state())
{
case DWNL_NONE : D.text(0, 0, "Nothing");break;
case DWNL_WAIT : D.text(0, 0, "Awaiting for connection..");break;
case DWNL_DOWNLOAD: D.text(0, 0,S+"Downloading.. "+download.done()+'/'+download.size());break;
case DWNL_DONE : D.text(0,-0.9, "Done");break;
case DWNL_ERROR : D.text(0, 0, "Error encountered");break;
}
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Net\Ftp.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
void InitPre()
{
App.name("FTP");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
D.sync(true);
}
Bool Init()
{
Ftp ftp; // create and Ftp object
// login to the FTP
if(ftp.login("ftp.host.com","user","password")) // in order to connect to an FTP server you will need to change these parameters to your custom
{
// sample upload
ftp.upload(File("c:/test.file"),"/test.file"); // upload "c:/test.file" to the FTP "/test.file"
// sample download
File file; file.writeMem(); // open the file for writing to memory
ftp.download("/test.file",file); // download "/test.file" from the FTP to 'file'
// sample list files
Memb<FtpFile> files; // container for the files
ftp.listFiles("/",files); // list all files in the root "/" ftp to the 'files' container
// logout
ftp.logout();
}
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
return true;
}
void Draw()
{
D.clear(WHITE);
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Net\Socket.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************
This tutorial presents the most basic socket usage.
It needs to be launched few times, so multiple windows of it will appear on the desktop.
Each of the program instances (windows) will create it's own 'player' and a socket (internet connection).
At the start of the program, it tries to contact other instances (windows) by sending empty data to specific ports.
When each of the program instances (windows) receive data from other instances, they store their address in a memory container, as a list of "external players"
In the update each instance sends its own player position to all other instances, so they'll know the most recent player position.
This way each instance receives data from other instances about their player positions.
/******************************************************************************/
#define BASE_PORT 10000
/******************************************************************************/
struct Player // player, contains only a position
{
Vec2 pos; // position
void draw(UInt color) // draw
{
Circle(0.1,pos).draw(color,true);
}
Player() // constructor
{
pos.zero();
}
};
struct Peer // peers (external players from other program instances)
{
SockAddr addr ; // their socket address
Player player; // their player data
};
/******************************************************************************/
Player player; // this program instance player
Socket sock ; // this program instance socket
Memb<Peer> peer ; // container of external peers
/******************************************************************************/
void InitPre()
{
App.name("Socket");
App.flag=APP_NO_FX|APP_WORK_IN_BACKGROUND; // specify work in background flag to work also when not focused
PakAdd("../data/engine.pak");
D.mode(400,300).sync(true);
}
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
Text_ds.scale*=2;
// create this instance socket (internet connection)
{
// try to initialize socket on one of the ports starting from BASE_PORT
// some ports will not be accessible because other program instances may have already reserved them
FREP(50)if(sock.createPeer(BASE_PORT+i))break; // 50 attempts, stops on first usable port
sock.block(false); // set non-blocking mode, this will disable waiting when receiving data through socket
}
// make contact with other sockets created by other program instances
{
SockAddr addr; // socket address
addr.ip("127.0.0.1"); // set address ip to 'localhost', which is your computer
FREP(50) // now check 50 ports where possibly other instances of the tutorial have created a socket
{
addr.port(BASE_PORT+i); // set port of the address
if(addr.port()!=sock.port()) // if it's on a different port than our socket (which means that it's not us)
sock.send(addr,NULL,0); // send empty data just to contact the other socket to let it know that we exist
}
}
return true;
}
/******************************************************************************/
void Shut()
{
sock.del();
peer.del();
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
// update this instance player position
if(App.active() && Ms.b(0)) // when application is active (focused) and left mouse button pushed
{
player.pos+=Ms.d; // move player position
}
// send this instance player position to all external players
REPA(peer)
{
sock.send(peer[i].addr,&player.pos,SIZE(player.pos));
}
// receive positions from other players
for(SockAddr addr;;)
{
Vec2 pos;
Int rcv=sock.receive(addr,&pos,SIZE(pos)); // check if the socket receives any data
if( rcv<0)break; // if no data then break
// here we've received some data from an external program instance
{
// first we'll check for its address, and store it on the "external player" list
Peer *p=NULL;
REPA(peer)if(peer[i].addr==addr){p=&peer[i]; break;} // check if it's already stored on the list
if(!p) // if not found in add it
{
p=&peer.New();
p->addr=addr;
}
// now we've got the sender stored on the list, so we can check for any data that the external player is sending to us
if(rcv==SIZE(pos))p->player.pos=pos; // if number of received data bytes is equal to Vec2 size then it's a new position of the external player
}
}
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
// draw players
player.draw(ColorI( sock.port())); // draw this instance player with color depending on its socket port number
REPA(peer)peer[i].player.draw(ColorI(peer[i].addr.port())); // draw external players with color depending on their socket port number
// draw instructions
D.text(0,0.88,"Launch this tutorial multiple times");
D.text(0,0.74,"Press LMB and move the Mouse");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Sound\Music.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
// music themes, each for storing tracks
MusicTheme *mt_battle , // this is battle theme used for playing when battles
*mt_explore, // exploring theme
*mt_calm ; // calm theme
/******************************************************************************/
void InitPre()
{
App.name("Music");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
if(mt_battle=MusicThemeNew()) // create 'mt_battle' theme
{
*mt_battle+="../data/music/battle0.ogg"; // add "battle0.ogg" track to 'mt_battle' theme
*mt_battle+="../data/music/battle1.ogg"; // add "battle1.ogg" track to 'mt_battle' theme
}
if(mt_explore=MusicThemeNew()) // create 'mt_explore' theme
{
*mt_explore+="../data/music/explore.ogg"; // add "explore.ogg" track to 'mt_explore' theme
}
if(mt_calm=MusicThemeNew()) // create 'mt_calm' theme
{
*mt_calm+="../data/music/calm.ogg"; // add "calm.ogg" track to 'mt_calm' theme
}
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
if(Kb.c('1'))Music.play(mt_battle );
if(Kb.c('2'))Music.play(mt_explore);
if(Kb.c('3'))Music.play(mt_calm );
if(Kb.c('4'))Music.play(NULL );
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
if(Music.theme) // if any theme playing
{
D.text(0,0.2,S+"song: "+Music.name());
D.text(0,0.0,S+"time " +Music.time()+" / "+Music.length()+" length");
}else
{
D.text(0,0,"No theme playing");
}
D.text(0,-0.2,"Press 1-battle, 2-explore, 3-calm, 4-none");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Sound\Sound 3D.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Sound sound; // sound
Vec pos(0,0,3); // sound position
/******************************************************************************/
void InitPre()
{
App.name("Sound 3D");
App.flag=APP_NO_FX|APP_MS_EXCLUSIVE;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
sound.play("../data/sound/water.ogg",pos,1,true); // play looped 3D sound, volume=1, position='pos'
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,10,CAMH_ZOOM|CAMH_ROT);
// update all 3D sound positions
{
sound.pos(pos); // since 'pos' is the same in each frame, the sound position doesn't need to be updated, but let's do it anyway
}
// update listener parameters
{
Listener.pos (Cam.matrix.pos ) // set listener position (from camera)
.orn (Cam.matrix.z,Cam.matrix.y) // set listener orientation (from camera)
.update( ); // updates all 3D parameters, only after this call all changes take effect
}
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
Ball(1,pos).draw(BLACK); // draw ball at sound position
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Sound\Sound.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Sound sound; // water sound
/******************************************************************************/
void InitPre()
{
App.name("Sound");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC ))return false;
if(Kb.bp(KB_SPACE))SoundPlay("../data/sound/metal.ogg"); // play sound on space
if(Kb.bp(KB_ENTER)) // toggle water on enter
{
if(sound.playing()) // if already playing
{
sound.del(); // delete sound
}else
{
sound.play("../data/sound/water.ogg",true); // play with loop option enabled
}
}
// change volumes on mouse wheel
{
if(Ms.wheel>0)sound.volume(sound.volume()+0.1);else
if(Ms.wheel<0)sound.volume(sound.volume()-0.1);
}
// change speed on LMB/RMB
{
if(Ms.b(0))sound.speed(sound.speed()-Tm.d()*0.4);
if(Ms.b(1))sound.speed(sound.speed()+Tm.d()*0.4);
}
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
D.text (0, 0.2, "Press space to play 'metal'");
D.text (0, 0.0,S+"Press enter to stop/play looped 'water' (playing: " +sound.playing()+')');
D.text (0,-0.2,S+"Use mouse wheel to change water sound volume (current: "+sound.volume ()+')');
D.text (0,-0.4,S+ "Press LMB/RMB to change water sound speed (current: " +sound.speed ()+')');
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\1 - Geometry, Graphics, Gui, Misc, Net, Sound\Sound\Volume Groups.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
MusicTheme *mt_battle , // music themes
*mt_explore ;
Sound sound ; // sound
Slider vol_fx , // volume bars
vol_music ,
vol_ambient;
Text tvol_fx , // volume text
tvol_music ,
tvol_ambient;
/******************************************************************************/
void InitPre()
{
App.name("Volume groups");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Gui.tds_text.scale*=1.5f; // make all Text objects bigger
if(mt_battle=MusicThemeNew()) // create mt_battle theme
{
*mt_battle+="../data/music/battle0.ogg"; // add "battle0.ogg" track to 'mt_battle' theme
*mt_battle+="../data/music/battle1.ogg"; // add "battle0.ogg" track to 'mt_battle' theme
}
if(mt_explore=MusicThemeNew()) // create mt_explore theme
{
*mt_explore+="../data/music/explore.ogg"; // add "explore.ogg" track to 'mt_explore' theme
}
Music .play(mt_battle ); // play theme as music
Ambient.play(mt_explore); // play theme as ambient
sound .play("../data/sound/water.ogg",true); // play looped sound
Gui+=vol_fx .create(Rect(-0.1,0.30,0.3,0.40),SoundVolume.fx ()); Gui+=tvol_fx .create(Vec2(-0.3,0.35),"Fx" );
Gui+=vol_music .create(Rect(-0.1,0.15,0.3,0.25),SoundVolume.music ()); Gui+=tvol_music .create(Vec2(-0.3,0.20),"Music" );
Gui+=vol_ambient.create(Rect(-0.1,0.00,0.3,0.10),SoundVolume.ambient()); Gui+=tvol_ambient.create(Vec2(-0.3,0.05),"Ambient");
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Gui.update();
// set new volumes
SoundVolume.fx (vol_fx ());
SoundVolume.music (vol_music ());
SoundVolume.ambient(vol_ambient());
return true;
}
/******************************************************************************/
void Draw()
{
D .clear(WHITE);
Gui.draw ();
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Animation\01 - Animation.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
CSkeleton cskel;
/******************************************************************************/
void InitPre()
{
App.name("Animation");
App.flag=APP_MS_EXCLUSIVE;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
Cam.dist=2;
Cam.yaw =PI;
cskel.create("../data/obj/chr/skeleton/0.skel",1.7); // create controlled skeleton from skel file, with 1.7 meter height
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,10,CAMH_ROT|CAMH_ZOOM);
// set animations
{
cskel.clear(); // clear controlled skeleton animation
if(Kb.b(KB_SPACE)) // when space pressed
{
cskel.animate(L"../data/anim/walk.anim",Tm.time()); // animate with "walk" animation and current time position
}
cskel.updateMatrix(MatrixIdentity); // update controlled skeleton animation matrixes
cskel.updateVelocities( ); // update controlled skeleton bone velocities (this is needed for Motion Blur effect)
}
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
// render
{
LightDir(Vec(0,0,-1)).set(); // set light
Meshs("../data/obj/chr/skeleton/0.mesh")->draw(cskel); // get mesh from cache and render it with controlled skeleton matrixes
if(Kb.ctrl) // when control pressed
{
SetMatrix(); // restore default matrix
cskel.draw(RED); // draw controlled skeleton
}
}
D.text(0,0.8,"Hold space to animate");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Animation\02 - Skeleton Points.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************
Skeleton points are special points attached to skeletons
They can be used to render items in correct places
Skeleton points can be accessed after animating skeleton through CSkeleton::getPoint method,
which returns reference to OrientP structure which is an orientation and position
/******************************************************************************/
CSkeleton cskel;
/******************************************************************************/
void InitPre()
{
App.name("Skeleton Points");
App.flag=APP_MS_EXCLUSIVE;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Cam.dist=2;
Cam.yaw =PI;
cskel.create("../data/obj/chr/skeleton/0.skel",1.7);
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,10,CAMH_ROT|CAMH_ZOOM);
// set animations
cskel.clear().animate(L"../data/anim/walk.anim",Tm.time()).updateMatrix(MatrixIdentity).updateVelocities();
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
LightDir(Vec(0,0,-1)).set();
// draw mesh
Meshs("../data/obj/chr/skeleton/0.mesh")->draw(cskel);
// draw skeleton point
SetMatrix();
cskel.getPoint("HandR").draw(RED);
cskel.getPoint("HandL").draw(RED);
cskel.getPoint("Head" ).draw(RED);
// draw item in right hand
{
OrientP &hand_r=cskel.getPoint("HandR");
Matrix m;
m.setPosDir(hand_r.pos,hand_r.perp,hand_r.dir) // set position and directions according to skeleton point
.scaleOrn(0.7); // scale down the matrix orientation a little, making the item smaller
Meshs("../data/obj/item/weapon/blunt/club/0.mesh")->draw(m); // render item with matrix
}
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Animation\03 - Blending.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
CSkeleton cskel;
Flt blend; // blending value (0..1)
Bool walk ; // if want to walk
/******************************************************************************/
void InitPre()
{
App.name("Animation Blending");
App.flag=APP_MS_EXCLUSIVE;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Text_ds.color =BLACK;
Text_ds.shadow=0;
Cam.dist=2;
Cam.yaw =PI;
cskel.create("../data/obj/chr/skeleton/0.skel",1.7); // create controlled skeleton from skel file, with 1.7 meter height
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,10,CAMH_ROT|CAMH_ZOOM);
if(Kb.bp(KB_SPACE))walk^=1; // change 'walk' when space pressed
// adjust blend value
if(walk)
{
blend+=Tm.d()*2;
if(blend>1)blend=1;
}else
{
blend-=Tm.d()*2;
if(blend<0)blend=0;
}
// set animations
{
cskel.clear (); // clear controlled skeleton animation
cskel.animate(L"../data/anim/walk.anim",Tm.time(), blend); // animate with "walk" animation, current time position and ' blend' blending weight
cskel.animate(L"../data/anim/run.anim" ,Tm.time(), 1-blend); // animate with "walk" animation, current time position and '1-blend' blending weight
cskel.updateMatrix(MatrixIdentity).updateVelocities(); // update controlled skeleton animation and velocities
}
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
LightDir(Vec(0,0,-1)).set();
// render
{
Meshs("../data/obj/chr/skeleton/0.mesh")->draw(cskel); // get mesh from cache and render it with controlled skeleton
if(Kb.ctrl) // when control pressed
{
SetMatrix(); // restore default matrix
cskel.draw(RED); // draw controlled skeleton
}
}
D.text(0,0.8,S+"Press space to toggle blending (Walk: "+walk+", Blend: "+blend+')');
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Animation\04 - Manual Editing.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
CSkeleton cskel;
/******************************************************************************/
void InitPre()
{
App.name("Animation Manual Editing");
App.flag=APP_MS_EXCLUSIVE;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Cam.dist=2;
Cam.yaw =PI;
cskel.create("../data/obj/chr/skeleton/0.skel",1.7);
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,10,CAMH_ROT|CAMH_ZOOM);
// set animations
{
cskel.clear().animate(L"../data/anim/walk.anim",Tm.time()); // set default walking animation
Orient &head=cskel.getBone("head").orn; // get head bone orientation
head*=Matrix3().setRotateZ(Sin(Tm.time()*1.5)); // rotate head orientation according to time
cskel.updateMatrix(MatrixIdentity) // update all matrixes
.updateVelocities(); // update all bone velocities
}
return true;
}
/******************************************************************************/
void Draw()
{
D.clear(WHITE);
LightDir(Vec(0,0,-1)).set();
// draw
Meshs("../data/obj/chr/skeleton/0.mesh")->draw(cskel);
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Physics\01 - Physics.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************
This tutorial is using PhysX, to run it, you must:
-have PhysX SystemSoftware installed from http://developer.nvidia.com/object/physx_downloads.html
-have "NxCooking.dll" in your application folder
/******************************************************************************/
Actor ground,
box ,
ball ;
/******************************************************************************/
void InitPre()
{
App.name("Physics");
App.flag=APP_MS_EXCLUSIVE|APP_NO_FX;
PakAdd("../data/engine.pak");
D.sync(true);
}
Bool Init()
{
Cam.dist=4;
// create physics
Physics.create();
// create actors
ground.create(Box (15,1,15,Vec(0 ,-2, 0)), 0); // create ground actor from Box and density=0 (which means it's a static actor - will not move)
box .create(Box (0.3 ,Vec(0.1, 1, 0)));
ball .create(Ball(0.3 ,Vec( 0, 0, 0)));
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,10,CAMH_ZOOM|CAMH_ROT);
// physics update
{
Physics.sim(); // start frame simulation
// physics simulation takes some time, so you can do some calculations here
// important : you may not modify actors between Physics.sim() and Physics.get()
Physics.get(); // get results of frame simulation
}
Flt s=3;
// add forces to ball
if(Kb.b(KB_UP ))ball.addForce(Vec(0,0, 1)*s);
if(Kb.b(KB_DOWN ))ball.addForce(Vec(0,0,-1)*s);
if(Kb.b(KB_LEFT ))ball.addForce(Vec(-1,0,0)*s);
if(Kb.b(KB_RIGHT))ball.addForce(Vec( 1,0,0)*s);
// add forces to ball according to camera
if(Kb.b(KB_W))ball.addForce( !PointOnPlane(Cam.matrix.z,Vec(0,1,0))*s);
if(Kb.b(KB_S))ball.addForce(-!PointOnPlane(Cam.matrix.z,Vec(0,1,0))*s);
if(Kb.b(KB_A))ball.addForce(-!PointOnPlane(Cam.matrix.x,Vec(0,1,0))*s);
if(Kb.b(KB_D))ball.addForce( !PointOnPlane(Cam.matrix.x,Vec(0,1,0))*s);
// add velocity to ball
if(Kb.bp(KB_SPACE))ball.addVel(Vec(0,3,0));
return true;
}
/******************************************************************************/
void Draw()
{
D .clear();
Physics.draw (); // draw physical actors
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Physics\02 - Multi shaped actor.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Actor ground,
ball ,
actor ;
/******************************************************************************/
void InitPre()
{
App.name("Multi shaped actors");
App.flag=APP_MS_EXCLUSIVE|APP_NO_FX;
PakAdd("../data/engine.pak");
D.sync(true);
}
Bool Init()
{
Cam.dist=4;
Physics.create();
ground .create(Box (15,1,15,Vec(0,-2,0)), 0);
ball .create(Ball(0.3,Vec(0,1.3,0)));
ActorCD acd; // multi-shaped actor creation description
acd.add(Box (0.2 )); // add box to 'acd'
acd.add(Ball(0.2,Vec(-0.3,0.2,0))); // add ball to 'acd'
acd.add(Ball(0.2,Vec( 0.3,0.2,0))); // add ball to 'acd'
actor.create(acd,Vec(0,0.3,0)); // create actor from 'acd'
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,10,CAMH_ZOOM|CAMH_ROT);
Physics.sim().get();
return true;
}
/******************************************************************************/
void Draw()
{
D .clear();
Physics.draw ();
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Physics\03 - Joints.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Actor ground,
ball ,
box ;
Joint joint ; // joint, used to connect two actors together, or attach one to a fixed point in the world
Vec joint_pos , // joint position (used only for drawing)
joint_axis; // joint axis (used only for drawing)
/******************************************************************************/
void InitPre()
{
App.name("Joints");
App.flag=APP_MS_EXCLUSIVE|APP_NO_FX;
PakAdd("../data/engine.pak");
D.sync(true);
}
Bool Init()
{
Cam.dist =4;
Cam.pitch=-0.2;
Physics.create();
ground .create(Box_U(15,1,15,Vec(0,0,0)), 0);
ball .create(Ball (0.3,Vec(-1,0.3,0))).vel(Vec(5,0,0)); // create a ball on ground and set its initial velocity to right
Box_D b(0.1,2,2,Vec(2,0,0));
box.create(b).ignore(ground); // create a box from 'b' and ignore collisions with 'ground' actor
joint_pos=b.cornerLDF(); // set joint position to box left-down-front corner
joint_axis.set(0,1,0); // set joint axis to up
joint.createHinge(box,NULL, joint_pos, joint_axis); // create a hinge joint in order to attach 'box' actor at 'joint_pos' world position and 'joint_axis' axis
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,10,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
Physics.sim().get();
return true;
}
/******************************************************************************/
void Draw()
{
D .clear();
Physics.draw ();
joint_pos.draw(RED); // draw joint position
D.line(GREEN, joint_pos, joint_pos+joint_axis*3); // draw a line from joint position and it's axis
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Physics\04 - Joints 2.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Actor ground,
box ;
Joint joint ;
Vec joint_pos,
joint_dir;
/******************************************************************************/
void InitPre()
{
App.name("Joints");
App.flag=APP_MS_EXCLUSIVE|APP_NO_FX;
PakAdd("../data/engine.pak");
D.sync(true);
}
Bool Init()
{
Cam.dist=4;
Physics.create();
ground .create(Box(15,1,15,Vec(0,-2,0)), 0);
Box_D b(2,2,0.2);
box.create(b); // create a box from 'b'
joint_pos=b.cornerLDF(); // set joint position to box left-down-front corner
joint_dir.set(1,0,0); // set joint direction to right
joint.createSliding(box, NULL, joint_pos, joint_dir, 0, 1.5); // create a sliding joint in order to attach 'box' actor at 'joint_pos' world position, 'joint_dir' direction and 0 .. 1.5 moving limits
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,10,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
Physics.sim().get();
if(Kb.b(KB_LEFT ))box.addVel(Vec(-Tm.d(),0,0)); // add left velocity
if(Kb.b(KB_RIGHT))box.addVel(Vec( Tm.d(),0,0)); // add right velocity
if(Kb.b(KB_UP ))box.addVel(Vec(0,0, Tm.d())); // add forward velocity which will not affect the actor
if(Kb.b(KB_DOWN ))box.addVel(Vec(0,0,-Tm.d())); // add bacward velocity which will not affect the actor
return true;
}
/******************************************************************************/
void Draw()
{
D .clear();
Physics.draw ();
joint_pos.draw(RED); // draw joint position
D.line(GREEN, joint_pos, joint_pos+joint_dir*3); // draw a line from joint position and it's direction
D.text(0,0.9,S+"Press Left / Right to change velocity");
D.text(0,0.8,S+"Press Up / Down to change velocity, the object won't move because of the joint");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Physics\05 - Controllers.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Actor ground ,
actor[10];
Controller ctrl ; // controller - it's meant to be used as a 'character actor'
/******************************************************************************/
void InitPre()
{
App.name("Character Controllers");
App.flag=APP_MS_EXCLUSIVE|APP_NO_FX;
PakAdd("../data/engine.pak");
D.sync(true);
}
Bool Init()
{
Cam .dist=4;
Physics.create();
ground .create(Box(15,1,15,Vec(0,-2,0)), 0);
// create random actors
REPA(actor)switch(Random(3))
{
case 0: actor[i].create(Box (RandomF(0.1,0.5), Random(Box(10,1,10)))); break;
case 1: actor[i].create(Ball (RandomF(0.1,0.5), Random(Box(10,1,10)))); break;
case 2: actor[i].create(Capsule(RandomF(0.1,0.2),RandomF(0.5,1.0),Random(Box(10,1,10)))); break;
}
// create controller
ctrl.create(Capsule(0.4,1.7));
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,10,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT)); // move camera on right mouse button
Physics.sim().get();
// update controller (move on WSAD keys, crouch on Shift key, jump on Space key)
Flt s=3;
Vec vel(0,0,0);
if(Kb.b(KB_W))vel+=!PointOnPlane(Cam.matrix.z,Vec(0,1,0))*s;
if(Kb.b(KB_S))vel-=!PointOnPlane(Cam.matrix.z,Vec(0,1,0))*s;
if(Kb.b(KB_A))vel-=!PointOnPlane(Cam.matrix.x,Vec(0,1,0))*s;
if(Kb.b(KB_D))vel+=!PointOnPlane(Cam.matrix.x,Vec(0,1,0))*s;
ctrl.update(vel, Kb.shift, Kb.bp(KB_SPACE) ? 3.5 : 0);
return true;
}
/******************************************************************************/
void Draw()
{
D .clear();
Physics.draw ();
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Physics\06 - Testing.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Actor ground,ball;
/******************************************************************************/
void InitPre()
{
App.name("Testing");
App.flag=APP_MS_EXCLUSIVE|APP_NO_FX;
PakAdd("../data/engine.pak");
D.sync(true);
}
Bool Init()
{
Cam.dist=4;
Physics.create();
ground.create(Box (15,1,15,Vec(0,-2,0)), 0);
ball .create(Ball(1,Vec(0,3,0)));
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,10,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT)); // move camera on right mouse button
Physics.sim().get();
if(Kb.bp(KB_SPACE))ball.addVel(Vec(0,5,0)); // add velocity to the ball when space pressed
return true;
}
/******************************************************************************/
void Draw()
{
D .clear();
Physics.draw ();
// test if custom ray hits some actor
{
Vec start( 4,0,0), // starting position of ray
end (-4,0,0); // ending position of ray
PhysHit phys_hit ; // phys-hit object for receiving hit parameters if any
if(Physics.ray(start,end-start,&phys_hit)) // if ray hit something
{
D.line(RED , start, phys_hit.plane.p); // draw a red line from staring position to hit position
D.line(GREEN, phys_hit.plane.p, phys_hit.plane.p+phys_hit.plane.n*0.3); // draw a green line presenting the hit normal vector
D.dot (RED , phys_hit.plane.p); // draw the contact point
}else
{
D.line(BLUE, start, end); // draw a blue line from starting position to end position
}
}
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Physics\07 - Detecting objects under cursor.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
enum ACTOR_GROUPS // actor groups (for example in the game you can specify following groups: door, item, character, ..)
{
GROUP_BACKGROUND, // background
GROUP_OBJ , // objects
};
/******************************************************************************/
Actor ground,
obj[10];
/******************************************************************************/
void InitPre()
{
App.name("Detecting objects under cursor");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
D.sync(true);
}
Bool Init()
{
Cam.setSpherical(Vec(0,0,-2), 0,-0.7,0, 6).set(); // set camera position and activate it
Physics.create();
ground.create(Box(15,1,15,Vec(0,-2,0)), 0).group(GROUP_BACKGROUND); // create ground and set its group to background
// create random actors
REPA(obj)
{
switch(Random(3))
{
case 0: obj[i].create(Box (RandomF(0.1,0.5), Random(Box(10,1,10)))); break;
case 1: obj[i].create(Ball (RandomF(0.1,0.5), Random(Box(10,1,10)))); break;
case 2: obj[i].create(Capsule(RandomF(0.1,0.2),RandomF(0.5,1.0),Random(Box(10,1,10)))); break;
}
obj[i].group(GROUP_OBJ).userd(i); // set actor's group to 'object' group and set its user data, in this tutorial it'll be index of the object in the array
}
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Physics.sim().get();
return true;
}
/******************************************************************************/
void Draw()
{
D .clear();
Physics.draw ();
// we'll now test if mouse points on some actor
// to do that we'll perform a standard ray testing
// with initial ray 'start' point located near the camera, and 'end' point located as far as viewport range reaches
{
// to obtain 'start' and 'end' point we'll use a special function called 'ScreenToPosDir' which transforms a screen position (Vec2) to world space position and direction
Vec screen_pos,
screen_dir;
ScreenToPosDir(Ms.pos, screen_pos, screen_dir); // obtain 'screen_pos' and 'screen_dir' from Mouse cursor position
// now having world space position and direction we can calculate ray 'start' and 'end' positions
Vec start=screen_pos,
end =screen_pos + screen_dir*Viewport.range;
// having ray positions we can perform a ray test
PhysHit phys_hit;
if(Physics.ray(start,end-start,&phys_hit)) // if ray hit something
{
D.text(0,0.9, "Ray has hit an actor!");
D.text(0,0.8,S+"Actor's group: " +phys_hit.group);
D.text(0,0.7,S+"Actor's user data (index): "+phys_hit.userd);
}else
{
D.text(0,0.9,"Ray hasn't hit anything");
}
}
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Physics\08 - Grabbing.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Actor ground, // ground
obj ; // object
Grab grab ; // grabber
/******************************************************************************/
void InitPre()
{
App.name("Grabbing objects");
App.flag=APP_NO_FX;
PakAdd("../data/engine.pak");
D.sync(true);
}
Bool Init()
{
Cam.setSpherical(Vec(0,0,-2), 0,-0.7,0, 6).set(); // set camera position and activate it
Physics.create();
ground.create(Box(15,1,15,Vec(0,-2,0)), 0); // create ground
obj .create(Box(0.3 ) ); // create object
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Physics.sim().get();
if(Kb.ctrl) // if want to grab
{
if(!grab.is()) // if not yet grabbing
{
grab.create(obj,Vec(0,0.3,0),10); // start grabbing 'obj' actor at (0,0.3,0) local position with a power of 10
}
if(grab.is()) // if grabbing something
{
// drag the object to left/right/forward/backwards
Vec dir(0);
if(Kb.b(KB_LEFT ))dir.x--;
if(Kb.b(KB_RIGHT))dir.x++;
if(Kb.b(KB_DOWN ))dir.y--;
if(Kb.b(KB_UP ))dir.y++;
grab.pos(grab.pos()+dir*Tm.d()*2);
}
}else
{
if(grab.is())grab.del();
}
return true;
}
/******************************************************************************/
void Draw()
{
D .clear();
Physics.draw ();
if(!grab.is())D.text(0,0.9,"Hold Control to grab the object");
else D.text(0,0.9,"Use the arrow keys to drag around the object");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Physics\09 - Physical meshes.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Controller ctrl ; // character controller
MeshGroup mshg ; // mesh group (used for rendering)
PhysGroup phsg ; // physical mesh group (used for collisions)
Memb<Actor> actor; // container of actors that will be created out of 'phsg'
/******************************************************************************/
void InitPre()
{
App.name("Physical meshes");
App.flag=APP_MS_EXCLUSIVE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).sync(true);
}
Bool Init()
{
Cam.dist=6;
Physics.create();
ctrl.create(Capsule(0.4,1.7,Vec(0,1,0))); // create character controller
mshg.load ("obj/terrain/0.mshg"); // load terrain MeshGroup
phsg.create(mshg); // create physical body group (PhysGroup) from 'mshg'
FREPA(phsg) // for all physical bodies (Phys) inside 'phsg'
{
Actor &a=actor.New(); // create new Actor in container
a.create(phsg.phys(i)); // create that Actor from i-th Phys in 'phsg'
}
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,100,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT)); // move camera on right mouse button
Physics.sim().get();
// update controller (move on WSAD keys, crouch on Shift key, jump on Space key)
Flt s=3;
Vec vel(0,0,0);
if(Kb.b(KB_W))vel+=!PointOnPlane(Cam.matrix.z,Vec(0,1,0))*s;
if(Kb.b(KB_S))vel-=!PointOnPlane(Cam.matrix.z,Vec(0,1,0))*s;
if(Kb.b(KB_A))vel-=!PointOnPlane(Cam.matrix.x,Vec(0,1,0))*s;
if(Kb.b(KB_D))vel+=!PointOnPlane(Cam.matrix.x,Vec(0,1,0))*s;
ctrl.update(vel, Kb.shift, Kb.bp(KB_SPACE) ? 3.5 : 0);
return true;
}
/******************************************************************************/
void Draw()
{
D.clear();
LightDir(Cam.matrix.z).set();
mshg .draw(MatrixIdentity); // draw mesh
Physics.draw( ); // draw physics
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Physics\10 - Ragdoll.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Actor ground , // ground actor
box[3] ; // stairs
CSkeleton cskel ; // controlled skeleton
Ragdoll ragdoll; // ragdoll
/******************************************************************************/
void SetPose()
{
cskel.clear().updateMatrix(Matrix().setRotateX(0.45).move(Vec(0,3,0))).updateVelocities(); // set skeleton animation to default pose and custom matrix
ragdoll.fromSkel(cskel); // setup ragdoll from skeleton animation
}
/******************************************************************************/
void InitPre()
{
App.name("Ragdoll");
App.flag=APP_MS_EXCLUSIVE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).sync(true);
Cam.dist =5;
Cam.pitch=-0.3;
Cam.yaw =PI;
}
Bool Init()
{
Physics.create();
ground.create(Box_U(15,1,15,Vec(0,-1,0)),0);
REPA(box)box[i].create(Box(1,Vec(0,i*0.5-0.5,i*-0.5-0.3)),0);
cskel .create("obj/chr/skeleton/0.skel",1.8); // create skeleton
ragdoll.create(cskel); // create ragdoll from skeleton
SetPose();
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,100,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT)); // move camera on right mouse button
Physics.sim().get();
ragdoll.toSkel(cskel); // set skeleton from ragdoll
if(Kb.bp(KB_SPACE))SetPose();
return true;
}
/******************************************************************************/
void Draw()
{
D.clear();
LightDir(Cam.matrix.z).set();
Meshs("obj/chr/skeleton/0.mesh")->draw(cskel);
Physics.draw();
D.text(0,0.9,"Press Space to reset simulation");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Physics\11 - Vehicle.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Flt angle ; // car wheel angle
Actor car , // car actor
ground ; // ground actor
Wheel wheel[4]; // wheels
/******************************************************************************/
void InitPre()
{
App.name("Vehicle");
App.flag=APP_FULL_TOGGLE|APP_NO_FX;
PakAdd("../data/engine.pak");
D.mode(800,600).sync(true);
ViewportFull.range=200;
}
Bool Init()
{
Cam.dist=10;
Physics.create();
ground .create(Box_U(100,1,100),0);
ground .pos (ground.pos()-Vec(0,3,0));
// create car
car.create (Box(2,1,4)); // create actor
car.massCenter(car.massCenter()-Vec(0,1.0,0)); // lower mass center
// create car wheels
Wheel::Param wp; // wheel parameters
wheel[0].create(car,Vec( 1,-0.5, 1.5),wp);
wheel[1].create(car,Vec(-1,-0.5, 1.5),wp);
wheel[2].create(car,Vec( 1,-0.5,-1.5),wp);
wheel[3].create(car,Vec(-1,-0.5,-1.5),wp);
return true;
}
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1f,200,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
Physics.sim().get();
if(Kb.bp(KB_ENTER))car.pos(Vec(0,3,0)); // reset car position on ENTER key
// adjust car controls
{
angle=LerpTime(angle,(Kb.b(KB_D)-Kb.b(KB_A))*PI_4,0.01); // adjust wheel angle
Flt accel=(Kb.b(KB_W)-Kb.b(KB_S))*1600, // acceleration
brake= Kb.b(KB_SPACE) *3200; // brakes
wheel[0].angle(angle); // set angle
wheel[1].angle(angle); // set angle
wheel[2].accel(accel).brake(brake); // set acceleration and brakes
wheel[3].accel(accel).brake(brake); // set acceleration and brakes
}
// update wheels
REPAO(wheel).update();
return true;
}
void Draw()
{
D .clear();
Physics.draw ();
(car.massCenter()*car.matrix()).draw(RED); // draw mass center
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Physics\12 - Cloth.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Actor ground,
box ,
ball ;
Cloth cloth ; // Physical Cloth
/******************************************************************************/
void InitPre()
{
App.name("Physical Clothes");
App.flag=APP_MS_EXCLUSIVE;
PakAdd("../data/engine.pak");
D.mode(1024,768).sync(true);
}
Bool Init()
{
Cam.dist =4;
Cam.pitch=-PI_4;
Physics.create();
ground.create(Box (15,1,15,Vec( 0,-2,0)), 0);
box .create(Box (0.3 ,Vec(-1, 0,0)));
ball .create(Ball(0.3 ,Vec( 1, 0,0)));
// create cloth
Cloth::Param param; // parameters for cloth creation
Mshb mshb ; // clothes are created from meshes, so create a mesh for it
mshb .createPlane(32,32,VTX_TX0) // create mesh as 32x32 vertex plane with texture coordinates set
.transform(Matrix().setRotateX(PI_2).move(Vec(-0.5,1,-0.5)).scale(3)); // transform mesh by matrix
cloth.create(mshb,Materials("../data/mtrl/ground/0.mtrl"),param); // create cloth from mesh
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,10,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
Physics.sim().get();
return true;
}
/******************************************************************************/
void Draw()
{
LightDir(Cam.matrix.z).set();
D .clear();
Physics.draw ();
cloth .draw (); // draw cloth
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Rendering\01 - Rendering.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Mesh mesh;
/******************************************************************************/
void InitPre()
{
App.name("Rendering");
App.flag=APP_MS_EXCLUSIVE;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Cam.dist=2;
mesh.create(1).base(0).create(Ball(1),VTX_TX0|VTX_NRM|VTX_TNG); // create Mesh with 1 Mshb, and create this Mshb from Ball with automatic texture coordinates, normals and tangents
mesh.setMaterial(Materials("../data/mtrl/brick/0.mtrl")).setRender().setBox(); // set mesh material, rendering version and bounding box
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(1.5,10,CAMH_ZOOM|CAMH_ROT);
return true;
}
/******************************************************************************/
void Render() // Rendering Method
{
switch(Renderer()) // Rendering Method will be called multiple times with different Rendering Modes
{
// first there is "solid rendering" mode where you need to render all solid meshes
case RM_SOLID:
mesh.draw(MatrixIdentity);
break;
// then there is "light rendering" mode where you need to render all the lights
case RM_LIGHT:
LightDir(Vec(0,0,1)).add();
break;
}
}
void Draw()
{
// instead of typical "D.clear(WHITE);" we'll now use advanced rendering :
Renderer(Render); // render with 'Render' method
D.text(0,0.9,S+"Fps: "+Tm.fps()); // show number of fps
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Rendering\02 - Sky.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Mesh mesh; // sample mesh
Gfx gfx ; // sky box texture
/******************************************************************************/
void InitPre()
{
App.name("Rendering Sky");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
PakAdd("../data/engine.pak");
D.mode(800,600);
ViewportFull.range=20; // set initial viewport range to 20 meters to see sky fog when zoomed out
}
/******************************************************************************/
Bool Init()
{
Cam.dist=6;
// create mesh
mesh.create(1).base(0).create(Ball(1),VTX_TX0|VTX_NRM|VTX_TNG);
mesh.setMaterial(Materials("../data/mtrl/brick/0.mtrl")).setRender().setBox();
// import skybox
gfx.Import("../data/gfx/sky/skybox.jpg",GFX_A8R8G8B8,GFX_CUBE);
// set default sky
Sky.set();
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(2.5,18,CAMH_ZOOM|CAMH_ROT);
if(Kb.bp(KB_1))Sky.clear( ); // disable sky
if(Kb.bp(KB_2))Sky.set (Vec(0.35,0.45,0.64),Vec(0.30,0.38,0.54)); // set sky from colors
if(Kb.bp(KB_3))Sky.set (gfx ); // set sky from skybox
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_SOLID:
REPD(x,3)
REPD(z,3)mesh.draw(Matrix(1,Vec(x-1,0,z-1)*3));
break;
case RM_LIGHT:
LightDir(!Vec(1,-1,1)).add();
break;
}
}
void Draw()
{
Renderer(Render);
D.text(0,0.9,"Press 1,2,3 for different skies");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Rendering\03 - Fog.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Material *brick,
*glass;
Mesh mbox ,
mball;
Vec pos[64];
Window window;
Slider fog_frac,
fog_exp ;
Text tfog_frac,
tfog_exp ;
/******************************************************************************/
void InitPre()
{
App.name("Fog");
App.flag=APP_FULL_TOGGLE;
PakAdd("../data/engine.pak");
D.full(true).bloom(0.8,0.6,0.3,true);
ViewportFull.range=25;
// hide mouse
Ms.hide();
}
/******************************************************************************/
Bool Init()
{
brick=Materials("../data/mtrl/brick/0.mtrl");
glass=Materials("../data/mtrl/glass/0.mtrl");
mbox .create(1).base(0).create( Box( 10),VTX_TX0|VTX_NRM|VTX_TNG).reverse(); // create mesh box, reverse it because it's meant to be viewed from inside
mball.create(1).base(0).create(Ball(0.5),VTX_TX0|VTX_NRM|VTX_TNG) ; // create mesh ball
// set mesh materials, rendering versions and bounding boxes
mbox .setMaterial(brick).setRender().setBox();
mball.setMaterial(glass).setRender().setBox();
// set random positions inside box
REPA(pos)pos[i]=Random(mbox.box);
// set camera
Cam.at = mbox.box.cornerLDF()/2;
Cam.dist = 10;
Cam.pitch=-PI_4;
Cam.yaw = PI_4;
// set Sky and initial fog parameters
Sky.set (Vec(0.3),Vec(0.3))
.fogFrac(0);
// add gui fog controls
Gui +=window .create(Rect_C(0,-0.75,0.9,0.34),"Fog Parameters").hide();
window+=tfog_frac.create(Vec2(0.2,-0.08),"Fraction"); window+=fog_frac.create(Rect_C(0.2+window.crect.w()/2,-0.08,0.25,0.05),Sky.fogFrac()).desc("Fraction of the Viewport Range where the Fog starts");
window+=tfog_exp .create(Vec2(0.2,-0.16),"Exponent"); window+=fog_exp .create(Rect_C(0.2+window.crect.w()/2,-0.16,0.25,0.05),Sky.fogExp ()).desc("Fog Density");
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Gui.update();
CamHandle(0.01,100,Ms.hidden() ? CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT) : 0); // when mouse hidden operate the camera
if(Kb.bp(KB_TAB))
{
Ms .toggle (); // toggle mouse visibility when tab pressed
window.visibleToggleActivate(); // toggle window visibility when tab pressed
}
// set fog parameters
Sky.fogFrac( fog_frac() )
.fogExp (Pow(fog_exp (),16));
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_SOLID:
mbox.draw(MatrixIdentity);
REPA(pos)
{
glass->color.v3=ColorVec(ColorHue(Flt(i)/ELMS(pos)));
glass->validate();
mball.draw(Matrix(pos[i]));
}
break;
case RM_LIGHT:
LightPoint(40,Vec(0,0,0)).add();
break;
}
}
void Draw()
{
Renderer(Render);
Gui.draw();
if(Ms.hidden())D.text(0,0.9,S+"Press Tab to toggle parameters");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Rendering\04 - Suns.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
MeshGroup terrain;
/******************************************************************************/
void InitPre()
{
App.name("Suns");
App.flag=APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).ambPower(0.3).hpRt(true).hwDepthBuffer(true);
Cam.pitch=0.5f;
}
Bool Init()
{
terrain.load("obj/terrain/0.mshg"); // terrain
Sky.set(); // sky
// sun
{
Sun &sun=Suns.New(); // create a new sun in 'Suns' container
sun.set(*Gfxs("gfx/sky/sun.gfx")); // set image
sun.pos=!Vec(1,1,1); // set custom position
}
// moon
{
Sun &moon=Suns.New(); // create a new sun in 'Suns' container
moon.set(*Gfxs("gfx/sky/moon.gfx")); // set image
moon.pos =!Vec(-1,1,1); // set custom position
moon.size*=0.6; // decrease default size
moon.blend=false; // disable blending, and thus set adding mode
moon.gfx_color=0x00404040; // set gfx color
moon.light_color=0; // disable light casting
moon.rays.mode=SUN_RAYS_OFF; // disable sun rays for the moon
}
return true;
}
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.01,500,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_SOLID:
terrain.draw(MatrixIdentity);
break;
}
}
void Draw()
{
Renderer(Render);
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Rendering\05 - Bumpmapping.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Mesh mbox ,
mball;
/******************************************************************************
In this tutorial we'll dynamically show different Bump Mapping modes
Changing Bump Mapping modes in runtime requires reseting shader effects of manually created Meshes
To achieve this we need to create a function which will reset effects of those meshes:
/******************************************************************************/
void SetEffect()
{
mbox .setEffect();
mball.setEffect();
}
/******************************************************************************/
void InitPre()
{
App.name("Rendering Bumpmapping");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
PakAdd("../data/engine.pak");
D.set_effect=SetEffect ; // set 'SetEffect' function to be used when needed
D.full(true).bumpMode(BUMP_FLAT); // start with flat bump mapping
}
/******************************************************************************/
Bool Init()
{
Cam.dist=3;
Material *material=Materials("../data/mtrl/brick/0.mtrl");
mbox .create(1).base(0).create( Box(4),VTX_TX0|VTX_NRM|VTX_TNG).reverse(); // create mesh box, reverse it because it's meant to be viewed from inside
mball.create(1).base(0).create(Ball(1),VTX_TX0|VTX_NRM|VTX_TNG) ; // create mesh ball
// set mesh materials, rendering versions and bounding boxes
mbox .setMaterial(material).setRender().setBox();
mball.setMaterial(material).setRender().setBox();
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,10,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT)); // move camera on right mouse button
// change bump mapping when keys pressed
if(Kb.bp(KB_1))D.bumpMode(BUMP_FLAT );
if(Kb.bp(KB_2))D.bumpMode(BUMP_NORMAL );
if(Kb.bp(KB_3))D.bumpMode(BUMP_PARALLAX);
if(Kb.bp(KB_4))D.bumpMode(BUMP_RELIEF );
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_SOLID:
mbox .draw(MatrixIdentity);
mball.draw(MatrixIdentity);
break;
case RM_LIGHT:
LightPoint(25,Vec(0,3,0)).add();
break;
}
}
void Draw()
{
Renderer(Render);
D.text(0,0.9,S+"Fps "+Tm.fps());
D.text(0,0.8,"Press 1,2,3,4 keys for different Bumpmapping modes");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Rendering\06 - Viewport.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Mesh mbox ,
mball;
/******************************************************************************/
void InitPre()
{
App.name("Viewport");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
PakAdd("../data/engine.pak");
D.full(true);
}
/******************************************************************************/
Bool Init()
{
Cam.dist=3;
Material *material=Materials("../data/mtrl/brick/0.mtrl");
mbox .create(1).base(0).create( Box(4),VTX_TX0|VTX_NRM|VTX_TNG).reverse(); // create mesh box, reverse it because it's meant to be viewed from inside
mball.create(1).base(0).create(Ball(1),VTX_TX0|VTX_NRM|VTX_TNG) ; // create mesh ball
// set mesh materials, rendering versions and bounding boxes
mbox .setMaterial(material).setRender().setBox();
mball.setMaterial(material).setRender().setBox();
return true;
}
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,10,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT)); // move camera on right mouse button
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_SOLID:
mbox .draw(MatrixIdentity);
mball.draw(MatrixIdentity);
break;
case RM_LIGHT:
LightPoint(25,Vec(0,3,0)).add();
break;
}
}
void Draw()
{
// render to active viewport
Renderer(Render);
// render to another viewport
{
// set new viewport
Rect rect(-D.w(),-D.h(),0,0); // setup viewport rectangle to left bottom quarter
rect.extend(-0.05); // extend with negative value, to make it smaller
Viewport.set(rect); // set viewport with given rectangle
// render everything once again
Renderer(Render);
// restore default viewport by activating ViewportFull
ViewportFull.set();
}
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Rendering\07 - Motion Blur.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
struct Object
{
Matrix matrix; // matrix
Vec vel, // linear velocity
ang_vel; // angular velocity
}object[12];
/******************************************************************************/
Mesh mbox ,
mball;
/******************************************************************************/
void InitPre()
{
App.name("Rendering Motion Blur");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
PakAdd("../data/engine.pak");
D.full(true).mtnMode(MTN_HIGH); // enable motion blur
D.mtnVelScale(0.20); // increase motion blurring
}
/******************************************************************************/
Bool Init()
{
Cam.dist=3;
Material *material=Materials("../data/mtrl/brick/0.mtrl");
mbox .create(1).base(0).create( Box( 4),VTX_TX0|VTX_NRM|VTX_TNG).reverse(); // create mesh box, reverse it because it's meant to be viewed from inside
mball.create(1).base(0).create(Ball(0.2),VTX_TX0|VTX_NRM|VTX_TNG) ; // create mesh ball
// set mesh materials, rendering versions and bounding boxes
mbox .setMaterial(material).setRender().setBox();
mball.setMaterial(material).setRender().setBox();
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,10,CAMH_ZOOM|(Ms.b(1) ? CAMH_MOVE : CAMH_ROT)); // move camera on right mouse button
// change motion blur mode when keys pressed
if(Kb.bp(KB_1))D.mtnMode(MTN_NONE);
if(Kb.bp(KB_2))D.mtnMode(MTN_LOW );
if(Kb.bp(KB_3))D.mtnMode(MTN_HIGH);
// update ball object matrixes and calculate velocity changes automatically
Flt speed=4;
REPA(object)
{
// calculate new matrix
Vec2 v; SinCos(v.y,v.x, i*PI2/ELMS(object) + Tm.time()*speed); // calculate sine and cosine of angle
Matrix new_matrix(Vec(v.x,0,v.y)); // create 'new_matrix' with initial position
// calculate velocity changes according to old and new matrix
GetVel(object[i].vel,object[i].ang_vel, object[i].matrix,new_matrix);
// store new matrix
object[i].matrix=new_matrix;
}
return true;
}
/******************************************************************************/
void Render() // rendering method
{
switch(Renderer())
{
case RM_SOLID:
mbox.draw(MatrixIdentity,Vec(0,0,0)); // box is rendered with identity matrix and (0,0,0) velocity
REPA(object)mball.draw(object[i].matrix,object[i].vel,object[i].ang_vel); // draw ball objects with their matrix and velocities
break;
case RM_LIGHT:
LightPoint(25,Vec(0,3,0)).add();
break;
}
}
void Draw()
{
Renderer(Render);
D.text(0,0.9,S+"Fps "+Tm.fps()); // show number of fps
D.text(0,0.8,"Press 1,2,3 keys for different Motion Blur modes");
switch(D.mtnMode())
{
case MTN_NONE: D.text(0,0.7,"No Motion Blur" ); break;
case MTN_LOW : D.text(0,0.7,"Camera only" ); break;
case MTN_HIGH: D.text(0,0.7,"Camera + Objects"); break;
}
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Rendering\08 - Materials.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Material material_brick,
material_fur,
material_glow,
material_rfl;
Mesh mesh;
/******************************************************************************/
void InitPre()
{
App.name("Rendering Materials");
App.flag=APP_MS_EXCLUSIVE;
PakAdd("../data/engine.pak");
D.full(true);
}
/******************************************************************************/
Bool Init()
{
Cam.dist=4;
material_brick.reset(); // setup defaults
material_brick.diffuse=Gfxs("../data/mtrl/brick/0.gfx" ); // set diffuse texture
material_brick.normal =Gfxs("../data/mtrl/brick/0.n.gfx"); // set normal texture
material_brick.detail =Gfxs("../data/mtrl/brick/det.gfx"); // set detail texture
material_fur.reset(); // setup defaults
material_fur.technique=MTECH_FUR; // set fur technique
material_fur.det_power =1; // in fur technique 'det_power' is used for fur length
material_fur.det_scale/=2; // in fur technique 'det_scale' is used for fur scale
material_glow.reset(); // setup defaults
material_glow.glow=0.5; // set glow amount
material_rfl.reset(); // setup defaults
material_rfl.diffuse =Gfxs("../data/mtrl/glass/0.gfx" ); // set diffuse texture to white
material_rfl.normal =Gfxs("../data/mtrl/glass/0.n.gfx"); // set normal texture
material_rfl.reflection=Gfxs("../data/mtrl/glass/rfl.gfx"); // set reflection texture
material_rfl.color.set(1,0.66,0.33,0); // set color
material_rfl.specular=0.5 ; // set specular
material_rfl.bump =0.09; // set bump value
material_rfl.rough =0.05; // set roughness
material_rfl.reflect =0.8 ; // set reflection
mesh.create(1).base(0).create(Ball(1),VTX_TX0|VTX_NRM|VTX_TNG); // create Mesh with 1 Mshb, and create this Mshb from Ball and automatic texture coordinates, normals and tangents
mesh.setRender().setBox(); // set mesh rendering version and bounding box
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(1.5,10,CAMH_ZOOM|CAMH_ROT);
if(Ms.b(0)) // on left mouse button change colors of materials
{
material_glow .color.x=0.5;
material_brick.color.y=0.5;
material_fur .color.z=0.5;
}else
{
// restore default rgb color values
material_glow .color.v3=1;
material_brick.color.v3=1;
material_fur .color.v3=1;
}
// validate changes
material_glow .validate();
material_brick.validate();
material_fur .validate();
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_FUR : // here since fur technique is being used we must process also 'RM_FUR' mode, in it we can simply render everything which is in 'RM_SOLID' mode
case RM_SOLID:
mesh.setMaterial(&material_glow ).draw(Matrix(Vec(-1, 1,0)));
mesh.setMaterial(&material_brick).draw(Matrix(Vec( 1, 1,0)));
mesh.setMaterial(&material_fur ).draw(Matrix(Vec( 1,-1,0)));
mesh.setMaterial(&material_rfl ).draw(Matrix(Vec(-1,-1,0)));
break;
case RM_LIGHT: LightDir(Vec(0,0,1)).add(); break;
}
}
void Draw()
{
Renderer(Render);
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Rendering\09 - Shadows.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Mesh mbox , // mesh box
mball; // mesh ball
/******************************************************************************/
void InitPre()
{
App.name("Rendering Shadows");
App.flag=APP_MS_EXCLUSIVE;
PakAdd("../data/engine.pak");
}
/******************************************************************************/
Bool Init()
{
Cam.dist=3;
Material *material=Materials("../data/mtrl/brick/0.mtrl");
mbox .create(1).base(0).create( Box(3),VTX_TX0|VTX_NRM|VTX_TNG).reverse(); // create mesh box, reverse it because it's meant to be viewed from inside
mball.create(1).base(0).create(Ball(1),VTX_TX0|VTX_NRM|VTX_TNG) ; // create mesh ball
// set mesh materials, rendering versions and bounding boxes
mbox .setMaterial(material).setRender().setBox();
mball.setMaterial(material).setRender().setBox();
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(1.5,10,CAMH_ZOOM|CAMH_ROT);
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_SOLID:
mbox .draw(MatrixIdentity);
mball.draw(MatrixIdentity);
break;
case RM_LIGHT:
LightPoint(10,Vec(Cos(Tm.time()),Sin(Tm.time()),-1.5)).add();
break;
// since we want to render shadows we have to process additional rendering mode 'RM_SHD_MAP' (render shadows through shadow maps)
// here we will render all meshes which cast shadows
case RM_SHD_MAP:
mball.draw(MatrixIdentity);
break;
}
}
void Draw()
{
Renderer(Render);
D.text(0,0.9,S+"Fps "+Tm.fps()); // show number of fps
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Rendering\10 - Volumetric Lights.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Mesh mbox, // mesh box
mmb ; // mesh middle barrier
/******************************************************************************/
void InitPre()
{
App.name("Volumetric Lights");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE; // mouse exclusive, display can be toggled with Alt+Enter
PakAdd("../data/engine.pak");
D.mode(1024,700).volLight(true); // enable volumetric lighting
}
/******************************************************************************/
Bool Init()
{
Cam.dist=8;
Material *material=Materials("../data/mtrl/brick/0.mtrl");
mbox.create(1).base(0).create(Box(3) ,VTX_TX0|VTX_NRM|VTX_TNG).reverse();
mmb .create(1).base(0).create(Box(6,1,6),VTX_TX0|VTX_NRM|VTX_TNG);
// make hole inside 'mmb' by subtracting from it a temporary box (3D geometry subtraction will be used)
{
Mshb temp;
temp.create(Box(1),VTX_TX0|VTX_NRM|VTX_TNG); // create temporary box
mmb .base(0).csg(temp,SEL_SUB); // subtract 'temp' from 'mmb'
mmb.setNormals().setTangents().setBinormals(); // re-create normals tangents and binormals
}
mbox.setMaterial(material).setRender().setBox();
mmb .setMaterial(material).setRender().setBox();
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(2,10,CAMH_ZOOM|CAMH_ROT);
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_SOLID:
mbox.draw(MatrixIdentity);
mmb .draw(MatrixIdentity);
break;
case RM_LIGHT:
LightPoint(5,Vec(Cos(Tm.time()),1,Sin(Tm.time())),Vec(1), 0.1).add(); // render light with volumetric amount set to 0.1
break;
case RM_SHD_MAP:
mbox.draw(MatrixIdentity); // volumetric lighting depends on shadow map, so we need to render 'mbox' too
mmb .draw(MatrixIdentity);
break;
}
}
void Draw()
{
Renderer(Render);
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Rendering\11 - Ambient Occlusion.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************
In this tutorial is presented how to achieve high ambient lighting value with satisfactionary looks
/******************************************************************************/
struct AmbientControls
{
Window win;
Text tmode,tsoft,tjitter,thalf_res,tpower,tcontrast,trange,tscale,tbias;
ComboBox mode, soft;
CheckBox jitter,half_res;
Slider power,contrast,range,scale,bias;
void create()
{
static CChar8 *modes[]=
{
"off",
"low",
"high #1",
"high #2",
"high #3",
"high #4",
};
static CChar8 *softing[]=
{
"0",
"1",
"2",
};
Flt y=0,h=0.062;
Gui+= win .create(Rect_RD(D.w(),-D.h(),0.9,0.67),"Ambient Parameters").hide(); y-=h;
win+=tmode .create(Vec2 (0.2,y),"Mode" ); win+=mode .create(Rect_C(0.2+win.crect.w()/2,y,0.25,0.05),modes ,ELMS(modes )).set(D.ambMode()); y-=h;
win+=tsoft .create(Vec2 (0.2,y),"Soft" ); win+=soft .create(Rect_C(0.2+win.crect.w()/2,y,0.25,0.05),softing,ELMS(softing)).set(D.ambSoft()); y-=h;
win+=tjitter .create(Vec2 (0.2,y),"Jitter" ); win+=jitter .create(Rect_C(0.2+win.crect.w()/2,y,0.05,0.05),D.ambJitter () ); y-=h;
win+=thalf_res.create(Vec2 (0.2,y),"Half Resolution"); win+=half_res.create(Rect_C(0.2+win.crect.w()/2,y,0.05,0.05),D.ambHalfRes () ); y-=h;
win+=tpower .create(Vec2 (0.2,y),"Power" ); win+=power .create(Rect_C(0.2+win.crect.w()/2,y,0.25,0.05),D.ambPower () ); y-=h;
win+=tcontrast.create(Vec2 (0.2,y),"Contrast" ); win+=contrast.create(Rect_C(0.2+win.crect.w()/2,y,0.25,0.05),D.ambContrast()/4 ); y-=h;
win+=trange .create(Vec2 (0.2,y),"Range" ); win+=range .create(Rect_C(0.2+win.crect.w()/2,y,0.25,0.05),D.ambRange ()/0.4); y-=h;
win+=tscale .create(Vec2 (0.2,y),"3D Scale" ); win+=scale .create(Rect_C(0.2+win.crect.w()/2,y,0.25,0.05),D.ambScale ()/4 ); y-=h;
win+=tbias .create(Vec2 (0.2,y),"Bias" ); win+=bias .create(Rect_C(0.2+win.crect.w()/2,y,0.25,0.05),D.ambBias () ); y-=h;
}
}AC;
/******************************************************************************/
Mesh mbackground,
mball,
mbox ;
Matrix matrix_ball[25],
matrix_box [25];
/******************************************************************************/
void InitPre()
{
App.name("Ambient Occlusion");
App.flag=APP_FULL_TOGGLE;
PakAdd("../data/engine.pak");
D.full(true).ambMode(AMB_HIGH3).ambSoft(1).ambJitter(1).ambHalfRes(1).ambPower(0.8); // set initial ambient occlusion parameters
Ms.hide(); // hide mouse
}
/******************************************************************************/
Bool Init()
{
Cam.dist=5;
Material *brick=Materials("../data/mtrl/brick/0.mtrl"),
*glass=Materials("../data/mtrl/glass/0.mtrl");
mbackground.create(1).base(0).create( Box(3 ),VTX_TX0|VTX_NRM|VTX_TNG).reverse(); // create background box
mbox .create(1).base(0).create( Box(0.5),VTX_TX0|VTX_NRM|VTX_TNG); // create box
mball .create(1).base(0).create(Ball(0.5),VTX_TX0|VTX_NRM|VTX_TNG); // create ball
mbackground.setMaterial(brick).setRender().setBox();
mbox .setMaterial(glass).setRender().setBox();
mball .setMaterial(glass).setRender().setBox();
// setup random matrixes
REPA(matrix_ball)matrix_ball[i].setRotateXY(RandomF(PI2),RandomF(PI2)).move(Random(mbackground.box));
REPA(matrix_box )matrix_box [i].setRotateXY(RandomF(PI2),RandomF(PI2)).move(Random(mbackground.box));
AC.create();
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Gui.update();
CamHandle(0.01,100,Ms.hidden() ? CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT) : 0); // when mouse hidden operate the camera
if(Kb.bp(KB_TAB))
{
Ms .toggle (); // toggle mouse visibility when tab pressed
AC.win.visibleToggleActivate(); // toggle window visibility when tab pressed
}
// set Ambient Occlusion parameters
D.ambMode (AC.mode ())
.ambSoft (AC.soft ())
.ambJitter (AC.jitter ())
.ambHalfRes (AC.half_res())
.ambPower (AC.power ())
.ambContrast(AC.contrast()*4)
.ambRange (AC.range ()*0.4)
.ambScale (AC.scale ()*4)
.ambBias (AC.bias ());
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_SOLID:
mbackground.draw(MatrixIdentity);
REPA(matrix_ball)mball.draw(matrix_ball[i]);
REPA(matrix_box )mbox .draw(matrix_box [i]);
break;
}
}
void Draw()
{
Renderer(Render);
Gui.draw();
if(Ms.hidden())D.text(0,0.9,S+"Press Tab to toggle parameters");
else D.text(0,0.9,S+"Fps: "+Tm.fps());
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Rendering\12 - Early Z.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************
EarlyZ is a technique of rejecting pixels which aren't visible
Another way of doing this optimization is to sort objects manually before rendering, so they will be rendered in front-to-back order.
- Advantage of EarlyZ is that it's simpler to use and it's pixel-precise, instead of object-precise as in manual object sorting
-Disadvantage is that it requires additional pass of rendering, but fortunately it consists only of vertex transformations and z-buffer setting
/******************************************************************************/
Mesh mbox ,
mball;
/******************************************************************************/
void InitPre()
{
App.name("Early Z");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
PakAdd("../data/engine.pak");
D.full(true).bumpMode(BUMP_RELIEF); // setup relief bump mapping to enable pixel-heavy processing
}
/******************************************************************************/
Bool Init()
{
Cam.dist=3;
Material *material=Materials("../data/mtrl/brick/0.mtrl");
mbox .create(1).base(0).create( Box(5),VTX_TX0|VTX_NRM|VTX_TNG).reverse();
mball.create(1).base(0).create(Ball(1),VTX_TX0|VTX_NRM|VTX_TNG);
mbox .setMaterial(material).setRender().setBox();
mball.setMaterial(material).setRender().setBox();
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,10,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
return true;
}
/******************************************************************************/
void Render()
{
// to use EarlyZ just render in 'RM_EARLY_Z' mode all big objects which occlude others
switch(Renderer())
{
case RM_EARLY_Z: // in this tutorial we'll simply render the same things as in 'RM_SOLID' mode
if(!Kb.b(KB_SPACE)) // disable EarlyZ when space pressed
{
mbox .draw(MatrixIdentity);
FREP(5)mball.draw(Matrix(2,Vec(0,0,5-i))); // draw in back-to-front order to present EarlyZ speedup
}
break;
case RM_SOLID:
mbox .draw(MatrixIdentity);
FREP(5)mball.draw(Matrix(2,Vec(0,0,5-i))); // draw in back-to-front order to present EarlyZ speedup
break;
case RM_LIGHT:
LightPoint(25,Vec(0,3,-1)).add();
break;
}
}
void Draw()
{
Renderer(Render);
D.text(0,0.9,S+"Fps: "+Tm.fps());
D.text(0,0.8, "Hold Space to disable EarlyZ");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Rendering\13 - Bloom.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Material *brick,
*glass;
Mesh mbox ,
mball;
Vec pos[32];
Window window;
Text tbloom_org,
tbloom_scale,
tbloom_cut,
tbloom_overbright;
Slider bloom_org,
bloom_scale,
bloom_cut;
CheckBox bloom_overbright;
/******************************************************************************/
void InitPre()
{
App.name("Bloom configuration");
App.flag=APP_FULL_TOGGLE;
PakAdd("../data/engine.pak");
D.full(true);
}
/******************************************************************************/
Bool Init()
{
Cam.dist=3;
brick=Materials("../data/mtrl/brick/0.mtrl");
glass=Materials("../data/mtrl/glass/0.mtrl");
mbox .create(1).base(0).create( Box( 4),VTX_TX0|VTX_NRM|VTX_TNG).reverse(); // create mesh box, reverse it because it's meant to be viewed from inside
mball.create(1).base(0).create(Ball(0.5),VTX_TX0|VTX_NRM|VTX_TNG) ; // create mesh ball
// set mesh materials, rendering versions and bounding boxes
mbox .setMaterial(brick).setRender().setBox();
mball.setMaterial(glass).setRender().setBox();
// set random positions inside box
REPA(pos)pos[i]=Random(mbox.box);
// add gui bloom controls
Gui +=window.create(Rect_C(0,-0.7,0.6,0.5),"Bloom Parameters");
window+=tbloom_org .create(Vec2(0.13,-0.08),"Origin" ); window+=bloom_org .create(Rect_C(0.1+window.crect.w()/2,-0.08,0.25,0.05),D.bloomOriginal ());
window+=tbloom_scale .create(Vec2(0.13,-0.16),"Scale" ); window+=bloom_scale .create(Rect_C(0.1+window.crect.w()/2,-0.16,0.25,0.05),D.bloomScale ());
window+=tbloom_cut .create(Vec2(0.13,-0.24),"Cutoff" ); window+=bloom_cut .create(Rect_C(0.1+window.crect.w()/2,-0.24,0.25,0.05),D.bloomCut ());
window+=tbloom_overbright.create(Vec2(0.13,-0.32),"OverBright" ); window+=bloom_overbright.create(Rect_C(0.1+window.crect.w()/2,-0.32,0.05,0.05),D.bloomOverbright());
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Gui.update();
Cam.setSpherical(Vec(0,0,0),Tm.time()/16,-0.3,0,3).updateVelocities().set(); // set autorotating camera
D.bloom(bloom_org(),bloom_scale(),bloom_cut(),bloom_overbright()); // set bloom parameters
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_SOLID:
mbox.draw(MatrixIdentity);
REPA(pos)
{
glass->color.v3=ColorVec(ColorHue(Flt(i)/ELMS(pos)));
mball.draw(Matrix(pos[i]));
}
break;
case RM_LIGHT:
LightPoint(25,Vec(0,3,0)).add();
break;
}
}
void Draw()
{
Renderer(Render);
Gui.draw();
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Rendering\14 - Depth of Field.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Material *brick,
*glass;
Mesh mbox ,
mball;
Vec pos[32];
Window window;
CheckBox dof_hi;
ComboBox dof_blurs;
Slider dof_power,
dof_range;
Text tdof_hi,
tdof_blurs,
tdof_power,
tdof_range;
/******************************************************************************/
void InitPre()
{
App.name("Depth of Field");
App.flag=APP_FULL_TOGGLE;
PakAdd("../data/engine.pak");
D.full(true).dof(DOF_HIGH,1, 1,0,5); // set initial depth of field parameters
// hide mouse
Ms.hide();
}
/******************************************************************************/
Bool Init()
{
brick=Materials("../data/mtrl/brick/0.mtrl");
glass=Materials("../data/mtrl/glass/0.mtrl");
mbox .create(1).base(0).create( Box( 4),VTX_TX0|VTX_NRM|VTX_TNG).reverse(); // create mesh box, reverse it because it's meant to be viewed from inside
mball.create(1).base(0).create(Ball(0.5),VTX_TX0|VTX_NRM|VTX_TNG) ; // create mesh ball
// set mesh materials, rendering versions and bounding boxes
mbox .setMaterial(brick).setRender().setBox();
mball.setMaterial(glass).setRender().setBox();
// set random positions inside box
REPA(pos)pos[i]=Random(mbox.box);
// set camera
Cam.at = mbox.box.cornerLDF()/2;
Cam.dist = 10;
Cam.pitch=-PI_4;
Cam.yaw = PI_4;
// add gui Dof controls
static CChar8 *blurs[]=
{
"1",
"2",
"3",
};
Gui +=window .create(Rect_C(0,-0.7,0.9,0.50),"Depth of Field Parameters").hide();
window+=tdof_hi .create(Vec2(0.2,-0.08),"High Quality"); window+=dof_hi .create(Rect_C(0.2+window.crect.w()/2,-0.08,0.05,0.05),D.dofMode ()==DOF_HIGH).desc("Prevents foreground objects leaking into background");
window+=tdof_blurs.create(Vec2(0.2,-0.16),"Blurs" ); window+=dof_blurs.create(Rect_C(0.2+window.crect.w()/2,-0.16,0.25,0.05),blurs,ELMS(blurs)).set(D.dofBlurs()-1);
window+=tdof_power.create(Vec2(0.2,-0.24),"Power" ); window+=dof_power.create(Rect_C(0.2+window.crect.w()/2,-0.24,0.25,0.05),D.dofPower());
window+=tdof_range.create(Vec2(0.2,-0.32),"Range" ); window+=dof_range.create(Rect_C(0.2+window.crect.w()/2,-0.32,0.25,0.05),D.dofRange()/10);
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Gui.update();
CamHandle(0.01,100,Ms.hidden() ? CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT) : 0); // when mouse hidden operate the camera
if(Kb.bp(KB_TAB))
{
Ms .toggle (); // toggle mouse visibility when tab pressed
window.visibleToggleActivate(); // toggle window visibility when tab pressed
}
// set depth of field parameters
D.dof(dof_hi () ? DOF_HIGH : DOF_ON, dof_blurs()+1, dof_power(), Cam.dist, dof_range()*10);
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_SOLID:
mbox.draw(MatrixIdentity);
REPA(pos)
{
glass->color.v3=ColorVec(ColorHue(Flt(i)/ELMS(pos)));
glass->validate(); // changing parameters realtime requires calling 'validate'
mball.draw(Matrix(pos[i]));
}
break;
case RM_LIGHT:
LightPoint(25,Vec(0,3,0)).add();
break;
}
}
void Draw()
{
Renderer(Render);
Gui.draw();
if(Ms.hidden())D.text(0,0.9,S+"Press Tab to toggle parameters");
else D.text(0,0.9,S+"Fps "+Tm.fps());
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Rendering\15 - Particles.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Mesh mbox;
Particles part[4]; // particles
/******************************************************************************/
void InitPre()
{
App.name("Particles");
App.flag=APP_FULL_TOGGLE|APP_MS_EXCLUSIVE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true);
Cam.dist=2;
}
/******************************************************************************/
Bool Init()
{
// create mesh box
mbox.create(1).base(0).create(Box(4),VTX_TX0|VTX_NRM|VTX_TNG).reverse();
mbox.setMaterial(Materials("mtrl/brick/0.mtrl")).setRender().setBox();
// create particles
{
// we'll start with a fire-like particle
Gfx *gfx =Gfxs("gfx/particle/fire.gfx"); // image
UInt col =ARGB(0,40,0,0); // color
Int num =30; // number
Flt r =0.1, // radius
life =1.0, // average life
vel =0.2; // random velocity
Vec accel(0,1,0); // acceleration
Shape shape(Ball(0.05)); // particles initial shape
part[0].create(*gfx,col,num,r,life,vel,accel,shape); // create particles
part[0].set (Vec(-0.5,0,0) ); // move to the left
part[0].reset ( ); // reset every single particle for random position and other parameters
// let's set part[1] with different settings, to make it magic-like
{
gfx =Gfxs("gfx/particle/fire.gfx");
col =ARGB(0,0,0,40);
num =100;
r =0.05;
life=1.0;
vel =0;
accel.zero();
shape=Capsule(0.1,0.4);
part[1].create(*gfx,col,num,r,life,vel,accel,shape); // create particles
part[1].reset ( ); // reset every single particle
part[1].func=PARTICLE_SIN; // change particles power function to sinus based
}
// and now part[2], fountain-like
{
gfx =Gfxs("gfx/particle/drop.gfx");
col =ARGB(150,20,120,200); // part[2] will be rendered in a different way (alpha blended) so make sure to set up alpha value in the color
num =500;
r =0.02;
life=1.0;
vel =1.0;
accel.set(0,-2,0);
shape=Vec(0,0,0);
part[2].create(*gfx,col,num,r,life,vel,accel,shape); // create particles
part[2].set (Vec(0.5,0,0) ); // move to the right
part[2].vel.set(2,2,0); // set initial vector velocity
part[2].damping=0.98; // enable damping
part[2].reset( ); // reset every single particle
}
// part[3], smoke-like
{
gfx =Gfxs("gfx/particle/fire.gfx");
col =ARGB(100,0,0,0); // part[3] will be rendered in a different way (alpha blended) so make sure to set up alpha value in the color
num =40;
r =0.15;
life=1.5;
vel =0.2;
accel.zero();
shape=Vec(0,0,0);
part[3].create(*gfx,col,num,r,life,vel,accel,shape); // create particles
part[3].set (Vec(-1,0,0) ); // move to the left
part[3].reset ( ); // reset every single particle
}
}
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.01,100,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
// modify part[3] position
Vec2 pos; SinCos(pos.y,pos.x,Tm.time()+PI);
part[3].set(Vec(pos.x,0,pos.y));
// update particles
REPA(part)part[i].update();
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_SOLID:
mbox.draw(MatrixIdentity);
break;
case RM_LIGHT:
LightPoint(30,Vec(0,3,0)).add();
break;
// particles are rendered in RM_PALETTE or RM_BLEND modes
// the first one (RM_PALETTE) is for objects rendered using color palette, and take their colors from 'Renderer.color_palette' texture (you can assign this texure to your custom version with command "Renderer.color_palette=Gfxs(..)")
// the second one (RM_BLEND ) is for objects rendered with standard alpha blending
// let's render part[0] and part[1] as pallette based, and part[2] and part[3] with standard alpha blending
case RM_PALETTE: // palette based
part[0].draw();
part[1].draw();
break;
case RM_BLEND: // alpha blending
part[2].draw();
part[3].draw();
break;
}
}
void Draw()
{
Renderer(Render);
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Rendering\16 - Blood.txt
/******************************************************************************/
#include "stdafx.h"
#include <EsenthelEngine/EsenthelEngine.h>
/******************************************************************************/
Mesh *chr ; // character mesh
Gfx *main , // main blood texture
*single; // single blood texture
BloodFx blood ; // blood particle effect
/******************************************************************************/
void InitPre()
{
App.name("Blood Effect");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak",NULL);
Cam.dist=3;
D.full(1).hpRt(true);
}
/******************************************************************************/
Bool Init()
{
Sky.set();
chr=Meshs("obj/chr/human/0.mesh");
main =Gfxs("gfx/particle/blood/0.gfx");
single=Gfxs("gfx/particle/blood/1.gfx");
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1f,100,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
// enable blood effect
if(Kb.bp(KB_SPACE)) // on space
blood.create(main,single,0xFF800000,60,Vec(0,1,0),Vec(1.6,0,0),1); // create blood effect
// update blood effect
blood.update();
return true;
}
/******************************************************************************/
Void Render()
{
switch(Renderer())
{
case RM_SOLID:
case RM_SHD_MAP:
chr->draw(Matrix(2).rotateY(PI)); // draw character mesh
break;
case RM_LIGHT:
LightPoint(5,Vec(0,1,-1)).add();
break;
case RM_BLEND:
blood.draw(); // draw Blood Effect in Alpha Blending mode
break;
}
}
void Draw()
{
Renderer(Render);
D.text(0,0.9,"Press Space to enable Blood Effect");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Rendering\17 - Explosion.txt
/******************************************************************************/
#include "stdafx.h"
#include <EsenthelEngine/EsenthelEngine.h>
/******************************************************************************/
Mesh *chr , // character mesh
box ; // box mesh
Gfx *main , // main explosion texture
*single ; // single explosion texture
ExplosionFx explosion; // explosion particle effect
/******************************************************************************/
void InitPre()
{
App.name("Blood Effect");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak",NULL);
Cam.dist=3;
D.full(1).bumpMode(BUMP_PARALLAX).mtnMode(MTN_HIGH); // Explosion Effect makes use of Motion Blur
}
/******************************************************************************/
Bool Init()
{
box.create(1).base(0).create(Box(2),VTX_TX0|VTX_NRM|VTX_TNG).reverse();
box.setMaterial(Materials("mtrl/brick/0.mtrl")).setRender().setBox();
chr=Meshs("obj/chr/human/0.mesh");
main =Gfxs("gfx/particle/explosion/0.gfx");
single=Gfxs("gfx/particle/explosion/1.gfx");
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
// enable explosion effect
if(Kb.bp(KB_SPACE)) // on space
{
explosion.create(main,single,0x00600000,32,Vec(0,0,0),1); // create explosion effect
QuakeFx.addMedium(); // add medium earth quake
}
// update Explosion Effect
explosion.update();
// update Quake Effect
QuakeFx.update();
CamHandle(0.1f,100,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
return true;
}
/******************************************************************************/
Void Render()
{
switch(Renderer())
{
case RM_SOLID :
case RM_SHD_MAP:
box .draw(MatrixIdentity);
chr->draw(Matrix(2).rotateY(PI));
break;
case RM_LIGHT:
LightPoint(5,Vec(0,1,-1)).add();
break;
case RM_PALETTE:
explosion.draw(); // draw Explosion Effect in Color Palette mode
break;
}
}
void Draw()
{
Renderer(Render);
D.text(0,0.9,"Press Space to enable Explosion Effect");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Rendering\18 - Holographic Images.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Mesh mbox,mball;
Gfx gfx;
Flt density_factor=0.05;
/******************************************************************************/
void InitPre()
{
App.name("Holographic Images");
App.flag=APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).ambPower(0.1);
}
/******************************************************************************/
Bool Init()
{
Cam.dist=3;
// create standard meshes and materials
Material *material=Materials("mtrl/brick/0.mtrl");
mbox .create(1).base(0).create( Box(5),VTX_TX0|VTX_NRM|VTX_TNG).reverse( ); mbox .setMaterial(material).setRender().setBox();
mball.create(1).base(0).create(Ball(1),VTX_TX0|VTX_NRM|VTX_TNG).weldVal(VTX_POS); mball.setMaterial(material).setRender().setBox();
// create holographic image
Int size=64;
gfx.create(size,size,size,GFX_A8R8G8B8,GFX_3D,1); // size x size x size dimensions, A8R8G8B8 type, 3D mode, 1 mip map
if(gfx.lock()) // start manual pixel editing
{
REPD(z,gfx.z())
REPD(y,gfx.y())
REPD(x,gfx.x())
{
Flt fx=Flt(x)/(gfx.x()-1), // x pixel fraction value 0..1
fy=Flt(y)/(gfx.y()-1), // y pixel fraction value 0..1
fz=Flt(z)/(gfx.z()-1); // z pixel fraction value 0..1
Flt px=fx*2-1, // x pixel position value -1..1
py=fy*2-1, // y pixel position value -1..1
pz=fz*2-1; // z pixel position value -1..1
Vec4 color=0;
if(x<=1 || x>=gfx.x()-2
|| y<=1 || y>=gfx.y()-2
|| z<=1 || z>=gfx.z()-2) // if current pixel is on border
{
color.set(0,1,0, RandomF(0.5,1)); // green color with random alpha
}
else // if current pixel is inside
{
// blue sphere
Flt length=Vec(px,py,pz).length();
Flt sphere=(1-Sat(Abs(length-0.5)*8));//*RandomF();
// red fade
Flt red_fade=0.5*fx*fx*RandomF();
// color value from blue sphere and red fade
if(Flt sum=sphere+red_fade) // total alpha value
color.set(1*red_fade/sum, 0.5*sphere/sum, 1*sphere/sum, sum);
}
gfx.color3DF(x,y,z,color); // store the pixel color
}
gfx.unlock(); // end pixel editing
}
REP(3)gfx.sharpen(1,1,true,true); // sharpen the image 3 times
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,1000,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
if(Kb.b(KB_Q))density_factor/=1+Tm.d();
if(Kb.b(KB_W))density_factor*=1+Tm.d();
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_SOLID :
case RM_SHD_MAP:
mbox .draw(MatrixIdentity);
mball.draw(Matrix(Vec(0,-3,0)));
break;
case RM_LIGHT:
LightPoint(20,Vec(0,3,3)).add();
break;
case RM_BLEND: // holographic images need to be drawn in RM_BLEND mode
gfx.draw3D(WHITE,0, Matrix(Vec(1,1,1),Vec(0)), density_factor, 1, 4,64);
break;
}
}
void Draw()
{
Renderer(Render);
D.text(0,0.9,S+"Fps: "+Tm.fps());
D.text(0,0.8,S+"Density Factor: "+density_factor+" (Q/W to change)");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Rendering\19 - Layered Clouds.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
MeshGroup terrain;
/******************************************************************************/
void InitPre()
{
App.name("Layered Clouds");
App.flag=APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).ambPower(0.3);
}
Bool Init()
{
terrain.load ("obj/terrain/0.mshg"); // terrain
Sky .set (); // sky
Suns .New().set ( *Gfxs("gfx/sky/sun.gfx")); // sun
Clouds .layered.set(3,Gfxs("Clouds/Layers/0.gfx")); // clouds
return true;
}
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.01,500,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
if(Kb.bp(KB_F10))Renderer.screenShots("screenshot/","bmp");
if(Kb.bp(KB_F11))D.toggle();
if(!Kb.b(KB_SPACE))Clouds.layered.update(); // if space not pressed then update clouds position
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_SOLID:
terrain.draw(MatrixIdentity);
break;
}
}
void Draw()
{
Renderer(Render);
D.text(0,0.9,S+"Fps "+Tm.fps());
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Rendering\20 - Volumetric Clouds.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
struct DisplayOptions
{
Window window;
CheckBox vol, hp_rt, hdr;
Text tvol,thp_rt,thdr;
void create()
{
Gui +=window.create(Rect_R(D.w(),0.5,0.8,0.35),"Display Options");
window+=vol .create(Rect (0.05,-0.10,0.10,-0.05)); window+=tvol .create(Vec2(0.45,-0.075),"Volumetric Lighting");
window+=hp_rt .create(Rect (0.05,-0.18,0.10,-0.13)); window+=thp_rt.create(Vec2(0.45,-0.155),"High Precision RenderTargets");
window+=hdr .create(Rect (0.05,-0.26,0.10,-0.21)); window+=thdr .create(Vec2(0.45,-0.235),"High Dynamic Range");
}
void update()
{
D.volLight(vol ());
D.hpRt (hp_rt());
D.hdr (hdr ());
}
}Opt;
/******************************************************************************/
struct CloudImages
{
Window window;
Button generate,save,load;
Gfx cloud,detail;
static void Generate(Ptr)
{
if(!Ci.detail.is()) // if detail image hasn't yet been created
{
CreateVolumetricDetail(Ci.detail,128,16,128); // create volumetric detail image, this image is used in cloud image creation, and it also can be used in the drawing process for additional quality
Ci.detail.blur(1,false); // blur it
}
CreateVolumetricCloud(Ci.cloud,&Ci.detail, 256,32,256, 3, false, 80);
Ci.cloud.lumFromAlphaAndLight(DIRF_RIGHT|DIRF_DOWN|DIRF_FORWARD,1.0);
Tm .skipUpdate(); // generating clouds is slow, so don't update timer in this frame
}
static void Save(Ptr){Ci.cloud.save("LocalData/cloud.gfx"); Ci.detail.save("LocalData/detail.gfx");}
static void Load(Ptr){Ci.cloud.load("LocalData/cloud.gfx"); Ci.detail.load("LocalData/detail.gfx");}
void create()
{
Gui +=window .create(Rect_LD(-D.w(),-D.h(),0.5,0.3),"Cloud Images");
window+=generate.create(Rect_C (window.rect.w() /2,-0.08,0.35,0.06),"Generate",Generate);
window+=save .create(Rect_C (window.rect.w()*1/3,-0.18,0.15,0.06),"Save" ,Save );
window+=load .create(Rect_C (window.rect.w()*2/3,-0.18,0.15,0.06),"Load" ,Load );
Clouds.volumetric.set(&cloud,NULL);
}
}Ci;
/******************************************************************************/
struct CloudParams
{
Window window;
Slider dns, shd, col0, col1, scale, curve, height;
Text tdns,tshd,tcol0,tcol1, tscale,tcurve,theight;
CheckBox detail, hi_res;
Text tdetail,thi_res;
Button save , load ;
static void Save(Ptr){ Clouds.volumetric.save("LocalData/volumetric_clouds"); }
static void Load(Ptr){if(Clouds.volumetric.load("LocalData/volumetric_clouds"))Cp.cloudsToGui();}
void create()
{
Gui+=window.create(Rect_RD(D.w(),-D.h(),0.6,0.77),"Cloud Parameters");
window+=tdns .create(Vec2(0.15,-0.05),"Density"); window+=dns .create(Rect_LU(0.3,-0.03,0.25,0.05), 3.0/6);
window+=tshd .create(Vec2(0.15,-0.10),"Shadow" ); window+=shd .create(Rect_LU(0.3,-0.08,0.25,0.05), 0.5 );
window+=tcol0.create(Vec2(0.15,-0.15),"Color0" ); window+=col0.create(Rect_LU(0.3,-0.13,0.25,0.05), 0.38 );
window+=tcol1.create(Vec2(0.15,-0.20),"Color1" ); window+=col1.create(Rect_LU(0.3,-0.18,0.25,0.05), 0.7 );
window+=tscale .create(Vec2(0.15,-0.30),"Scale" ); window+=scale .create(Rect_LU(0.3,-0.28,0.25,0.05), 0.5);
window+=tcurve .create(Vec2(0.15,-0.35),"Curve" ); window+=curve .create(Rect_LU(0.3,-0.33,0.25,0.05), 0.5);
window+=theight.create(Vec2(0.15,-0.40),"Height"); window+=height.create(Rect_LU(0.3,-0.38,0.25,0.05), 0.5);
window+=tdetail.create(Vec2(0.20,-0.50),"Detail" ); window+=detail.create(Rect(0.40,-0.53,0.45,-0.48));
window+=thi_res.create(Vec2(0.20,-0.57),"High Resolution"); window+=hi_res.create(Rect(0.40,-0.60,0.45,-0.55));
window+=save.create(Rect_C(0.17,-0.67,0.18,0.06),"Save",Save);
window+=load.create(Rect_C(0.43,-0.67,0.18,0.06),"Load",Load);
}
void cloudsToGui()
{
dns .set(Clouds.volumetric.density/6);
shd .set(Clouds.volumetric.shadow);
col0.set(Clouds.volumetric.dark_color .avg());
col1.set(Clouds.volumetric.bright_color.avg());
scale .set(LerpR(0.125f,0.375f,Clouds.volumetric.scale ));
curve .set(LerpR(0.000f,0.060f,Clouds.volumetric.curve ));
height.set(LerpR(0.000f,1.540f,Clouds.volumetric.height));
detail.set(Clouds.volumetric.detail!=NULL);
hi_res.set(Clouds.volumetric.hi_res );
}
void guiToClouds()
{
Clouds.volumetric.density=Lerp(0,6,dns());
Clouds.volumetric.shadow =Lerp(0,1,shd());
Clouds.volumetric.dark_color .set(col0());
Clouds.volumetric.bright_color.set(col1());
Clouds.volumetric.scale =Lerp(0.125f,0.375f,scale ());
Clouds.volumetric.curve =Lerp(0.000f,0.060f,curve ());
Clouds.volumetric.height=Lerp(0.000f,1.540f,height());
Clouds.volumetric.detail=(detail() ? &Ci.detail : NULL);
Clouds.volumetric.hi_res=hi_res();
}
}Cp;
/******************************************************************************/
MeshGroup terrain;
/******************************************************************************/
void InitPre()
{
App.name("Volumetric Clouds");
App.flag=APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).ambPower(0.3).hdrExposure(0.7);
}
Bool Init()
{
terrain.load("obj/terrain/0.mshg");
Sky .set();
Suns.New().set(*Gfxs("gfx/sky/sun.gfx"));
// gui
Opt.create();
Ci .create();
Cp .create();
return true;
}
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.01,500,Ms.hidden() ? CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT) : 0); // when mouse hidden operate the camera
if(Kb.bp(KB_TAB))
{
Ms . toggle(); // toggle mouse visibility when tab pressed
Opt.window.visibleToggle();
Ci .window.visibleToggle();
Cp .window.visibleToggle();
}
Gui.update();
Opt.update();
Cp .guiToClouds();
if(Kb.bp(KB_F10))Renderer.screenShots("screenshot/","bmp");
if(Kb.bp(KB_F11))D .toggle();
if(!Kb.b(KB_SPACE))Clouds.volumetric.update(Vec2(4,4)); // if space not pressed then update clouds position by given velocity
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_SOLID:
terrain.draw(MatrixIdentity);
break;
}
}
void Draw()
{
Renderer(Render);
Gui.draw();
D.text(0,0.9,S+"Fps "+Tm.fps());
D.text(0,0.8,Ms.hidden() ? "Press Tab to toggle parameters" : "Press Tab to operate the camera");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Rendering\21 - Object Clouds.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
MeshGroup terrain ;
Gfx image[3]; // cloud images
struct Cloud
{
Gfx *gfx;
Matrix matrix;
Cloud()
{
gfx=NULL;
}
void draw(UInt color,UInt color_add)
{
if(gfx)gfx->draw3D(color,color_add, matrix, 0.5, 0.5);
}
};
Memb<Cloud> clouds; // container of clouds
/******************************************************************************/
void InitPre()
{
App.name("Object Clouds");
App.flag=APP_FULL_TOGGLE|APP_MS_EXCLUSIVE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).ambPower(0.3).hpRt(true);
Cam.dist =1;
Cam.yaw =2.8;
Cam.pitch=0.3;
Cam.at.set(0,0,0);
ViewportFull.range=200;
}
Bool Init()
{
terrain.load("obj/terrain/0.mshg");
Sky.set();
{
Sun &sun=Suns.New();
sun.set(*Gfxs("gfx/sky/sun.gfx"));
sun.rays.mode=SUN_RAYS_HIGH;
}
// create cloud images
Gfx detail; CreateVolumetricDetail(detail, 32,16,32); detail.blur(1,false);
REPA(image)
{
CreateVolumetricCloud(image[i],&detail, 64,32,64, 3, true, 80);
image[i].mulAdd(Vec4(1,1,1,4),Vec4(0,0,0,0)); // scale alpha value
image[i].lumFromAlphaAndLight(DIRF_RIGHT|DIRF_DOWN|DIRF_FORWARD,0.5);
}
Flt average_size=4;
// holographic images may not intersect with each other, so set positions based on a regular grid modified by slight rotations and offsets
for(Int x=-2; x<=2; x++)
for(Int z=-2; z<=2; z++)
{
Cloud &cloud=clouds.New();
// set random image
cloud.gfx=&image[Random(ELMS(image))];
// set cloud matrix
cloud.matrix.setScale(average_size*RandomF(0.8,1.2))
.scale (Vec(1,0.5,1))
.rotateXY(RandomF(-0.1,0.1),RandomF(-0.4,0.4))
.move ((Vec(x,0,z)+Random.vec(-0.25,0.25))*average_size*2)
.move (Vec(0,10,0));
}
return true;
}
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.01,500,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
return true;
}
/******************************************************************************/
Int Compare(Cloud &c0,Cloud &c1)
{
return CompareTransparencyOrder(c0.matrix.pos,c1.matrix.pos);
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_SOLID:
terrain.draw(MatrixIdentity);
break;
case RM_CLOUD: // clouds in order to affect the sun rays must be drawn in RM_CLOUD mode
{
Flt color_dark =0.38,
color_bright=0.78;
UInt color = ColorBrightness(color_bright-color_dark) ,
color_add =ColorAlpha(ColorBrightness( color_dark),0);
// clouds are transparent so they need to be sorted before rendering
clouds.sort(Compare);
// draw the clouds
REPAO(clouds).draw(color,color_add);
}break;
}
}
void Draw()
{
Renderer(Render);
D.text(0,0.9,S+"Fps "+Tm.fps());
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Rendering\22 - Water.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
MeshGroup terrain;
/******************************************************************************/
void InitPre()
{
App.name("Water");
App.flag=APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).ambPower(0.3).hpRt(true).hwDepthBuffer(true);
Cam.at.set(0,2,0);
Cam.pitch=-0.5;
Cam.dist =30;
Cam.yaw =2.8;
}
Bool Init()
{
terrain.load("obj/terrain/0.mshg"); // terrain
terrain.scale(Vec(1,10,1)).move(Vec(0,5,0)); // scale and move terrain vertically
Sky .set(); // sky
Suns.New().set(*Gfxs("gfx/sky/sun.gfx")); // sun
Water.set(*Gfxs("gfx/water/0.gfx"),*Gfxs("gfx/water/0.n.gfx"),Gfxs("gfx/fx/reflection.gfx")); // set water from textures
return true;
}
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.01,500,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
// here you can optionally set different water surface plane
if(Kb.b(KB_UP ))Water.plane(Water.plane() + Vec(0,1,0)*Tm.d()); // move water surface plane upwards
if(Kb.b(KB_DOWN))Water.plane(Water.plane() - Vec(0,1,0)*Tm.d()); // move water surface plane downwards
// update water waves movement
Water.update(Vec2(0.2,0.2));
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
// When rendering water, an additional rendering mode has to be used
// RM_SOLID_M is "rendering solid in mirrors / water surfaces" mode
// for the most simplicity you can render the same things as in RM_SOLID mode
case RM_SOLID :
case RM_SOLID_M:
terrain.draw(MatrixIdentity);
break;
}
}
void Draw()
{
Renderer(Render);
D.text(0,0.9,S+"Fps "+Tm.fps());
D.text(0,0.8,"Press up/down keys to change water level");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Rendering\23 - Markers.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
MeshGroup terrain;
Marker marker[2]; // 2 markers
/******************************************************************************/
void InitPre()
{
App.name("Markers");
App.flag=APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).ambPower(0.3);
Cam.pitch=-0.5;
Cam.dist =10;
}
Bool Init()
{
terrain.load("obj/terrain/0.mshg");
Sky .set();
Suns.New().set(*Gfxs("gfx/sky/sun.gfx"));
// setup markers
REPA(marker)
{
Marker &m=marker[i];
m.glow =0;
m.color=(i ? YELLOW : RED);
m.gfx =Gfxs("gfx/particle/star.gfx");
m.size =2;
m.range_opaque=0.2;
m.range_fade =0.3;
m.local_matrix.setPosDir(Vec(0,0,0), Vec(0,1,0)); // setup matrix to (0,0,0) position, facing up (0,1,0)
// set matrix position at terrain surface
PosPointMeshY(Vec2(i ? 1 : -1, 0),terrain,&m.local_matrix.pos);
}
return true;
}
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.01,500,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
// rotate markers matrix in their Z axis according to time delta
REPA(marker)marker[i].local_matrix.orn.rotateZVec(Tm.d());
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_SOLID:
terrain.draw(MatrixIdentity);
break;
// markers can be rendered in RM_OVERLAY, RM_BLEND and RM_PALETTE modes, in this tutorial we'll use RM_BLEND
case RM_BLEND:
REPA(marker)marker[i].draw(MatrixIdentity);
break;
}
}
void Draw()
{
Renderer(Render);
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Rendering\24 - Mesh Outline.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Material *brick,
*glass;
Mesh mbox ,
mball;
Vec pos[32];
/******************************************************************************/
void InitPre()
{
App.name("Depth of Field");
App.flag=APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true);
}
/******************************************************************************/
Bool Init()
{
brick=Materials("mtrl/brick/0.mtrl");
glass=Materials("mtrl/glass/0.mtrl");
mbox .create(1).base(0).create( Box( 4),VTX_TX0|VTX_NRM|VTX_TNG).reverse(); // create mesh box, reverse it because it's meant to be viewed from inside
mball.create(1).base(0).create(Ball(0.5),VTX_TX0|VTX_NRM|VTX_TNG) ; // create mesh ball
// set mesh materials, rendering versions and bounding boxes
mbox .setMaterial(brick).setRender().setBox();
mball.setMaterial(glass).setRender().setBox();
// set random positions inside box
REPA(pos)pos[i]=Random(mbox.box);
// set camera
Cam.dist=5;
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.01,100,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_LIGHT:
LightPoint(25,Vec(0,3,0)).add();
break;
case RM_SOLID:
mbox.draw(MatrixIdentity);
REPA(pos)
{
glass->color.v3=ColorVec(ColorHue(Flt(i)/ELMS(pos)));
glass->validate();
mball.draw(Matrix(pos[i]));
}
break;
// when we wan't to use Mesh Outlining we need to process additional rendering mode 'RM_OUTLINE'
case RM_OUTLINE:
if(Kb.b(KB_SPACE)) // outline only when space pressed
{
Renderer.outlineUse(); // outlining mode is optional, and when used the engine needs to be notified about it
Flt alpha=Frac(Tm.time()*2,2);
if( alpha>1)alpha=2-alpha;
REPA(pos) // for all balls
{
UInt hue=ColorHue (Flt(i)/ELMS(pos)),
col=ColorAlpha(hue,alpha);
SetHighlight(col); // before drawing the mesh, set highlight color
mball.draw(Matrix(pos[i])); // now draw the mesh
}
}
break;
}
}
void Draw()
{
Renderer(Render);
D.text(0,0.9,"Press Space to outline the balls");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Rendering\25 - Laser and Electricity.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Mesh mbox ;
Vec point[32]; // laser can be drawn out of an array of points, this is such an array which will be filled with circle coordinates
// instead of drawing one laser, we will render few of them, each with it's own vertical position
struct Laser
{
Flt position_y,
velocity_y;
}laser[]=
{
{0, 0.4},
{0, 0.6},
{0, 0.8},
{0,-0.4},
{0,-0.6},
{0,-0.8},
};
ElectricityFx electricity; // electricity effect
/******************************************************************************/
void InitPre()
{
App.name("Laser");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
PakAdd("../data/engine.pak");
D.full(true);
}
/******************************************************************************/
Bool Init()
{
Cam.dist=3;
// create standard meshes and materials
Material *material=Materials("../data/mtrl/brick/0.mtrl");
mbox.create(1).base(0).create(Box(4),VTX_TX0|VTX_NRM|VTX_TNG).reverse();
mbox.setMaterial(material).setRender().setBox();
// setup point array for laser
REPA(point)
{
Flt angle=Lerp(PI_4, -PI-PI_4, i/Flt(ELMS(point)-1)); // linearly interpolate angle from 'i' (0..point elements)
point[i].set(Cos(angle),0,Sin(angle)); // set point positions on a circle
}
// setup electricity effect control points
electricity.original.New().set(-1,0,-1);
electricity.original.New().set( 0,0, 1);
electricity.original.New().set( 1,0,-1);
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,10,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT)); // move camera on right mouse button
// update laser positions
REPA(laser)
{
Laser &l=laser[i];
// update lasers position
l.position_y+=l.velocity_y*Tm.d();
// if position is too high or to low then change the sign of velocity, so the laser will start moving in a different direction
if(l.position_y>1 || l.position_y<-1)CHS(l.velocity_y);
}
// update electricity
electricity.update();
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_SOLID:
mbox.draw(MatrixIdentity);
break;
case RM_LIGHT:
LightPoint(25,Vec(0,3,0)).add();
break;
}
// draw laser and electricity in RM_LIGHT and RM_SOLID modes
switch(Renderer())
{
case RM_LIGHT:
case RM_SOLID:
{
// draw laser
REPA(laser)
{
SetMatrix(Matrix(Vec(0,laser[i].position_y,0))); // setup matrix for the laser
DrawLaser(ARGB(128,128,0,0), ARGB(128,128,0,0), 1, 0.005, false, point,ELMS(point)); // here alpha determines glow amount
}
// draw electricity
SetMatrix(Matrix(Vec(0,-1.5,1)));
electricity.draw();
}break;
}
}
void Draw()
{
Renderer(Render);
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Rendering\26 - Cel Shading.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Material glass;
Mesh mball;
Vec pos[32];
/******************************************************************************/
void InitPre()
{
App.name("Cel Shading");
App.flag=APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true);
}
/******************************************************************************/
Bool Init()
{
// set cel shading
D.bumpMode (BUMP_FLAT ); // cel-shading works best with flat bump mapping
D.hpRt (true ); // cel-shading works best with high precision render targets
D.edgeDetect(EDGE_DETECT_FAT); // set edge detection
Renderer.cel_shade_palette=Gfxs("gfx/fx/cel light palette.gfx"); // set light palette which modifies global lighting
// set sky, material and mesh
Sky.set();
glass.reset();
mball.create(1).base(0).create(Ball(0.5),VTX_TX0|VTX_NRM|VTX_TNG);
mball.setMaterial(glass).setRender().setBox();
REPA(pos)pos[i]=Random(Box(8,4,8,Vec(0,2,0)));
Cam.dist=10;
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.01,100,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_LIGHT:
{
LightDir(!Vec(1,-1,1)).add();
}break;
case RM_SOLID:
{
Mshgs("obj/terrain/0.mshg")->draw(MatrixIdentity);
REPA(pos)
{
glass.color.v3=ColorVec(ColorHue(Flt(i)/ELMS(pos)));
glass.validate();
mball.draw(Matrix(pos[i]));
}
}break;
}
}
void Draw()
{
Renderer(Render);
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\2 - Animation, Physics, Rendering\Rendering\27 - Multi-Threaded Rendering.txt
/******************************************************************************/
#include "stdafx.h"
#include <EsenthelEngine/EsenthelEngine.h>
/******************************************************************************
In order to take advantage of multiple cores on your CPU, multi-threaded rendering is used.
It works by rendering graphics on one thread, and processing data on the other.
To avoid multi-threaded issues you need to store your game data in two versions:
-backuped data (which contains only data required for rendering, like position and mesh)
-normal data (which contains all the data of your object, including position, mesh and other custom parameters)
Multi-threaded rendering will look like this:
+-------------------------+-----------------------+
| Thread 1 | Thread 2 |
+-------------------------+-----------------------+
| Backup your data | |
+-------------------------+-----------------------+
| Process the data update | Render 3D graphics |
+-------------------------+-----------------------+
| Wait until rendered | |
+-------------------------+-----------------------+
| Draw 2D graphics | |
+-------------------------+-----------------------+
While Rendering 3D graphics on other thread:
- you must not modify 'Viewport' viewport or activate another viewport
- you must not modify 'Cam' camera or activate another camera
- you must not call methods changing rendering matrixes/velocities (SetMatrix, SetVel, SetAngVel, CSkeleton::setMatrix)
Note:
Performance gains may vary depending on:
-your system (mainly GPU & CPU - number of cores and general performance)
-amount of calculations in update
-amount of objects rendered
/******************************************************************************/
struct ObjectBackup // game object backup - contains only data required for rendering
{
Vec pos;
Mesh *mesh;
void draw() // rendering method
{
mesh->draw(Matrix(pos)); // render 'mesh' at 'pos' position
}
};
struct Object // game object
{
Flt parameters[256];
Vec pos;
Mesh *mesh;
// note that this structure doesn't contain any rendering method, as we'll be rendering only through ObjectBackup::draw
void backup(ObjectBackup &dst) // backup data method
{
// backup all data needed for rendering here
dst.pos =pos;
dst.mesh=mesh;
}
Object(){Zero(T);}
};
/******************************************************************************/
Bool multi_threaded; // if multi-threaded mode
Mesh mbox , // mesh box
mball; // mesh sphere
Memb<Object > mobj ; // Object's memory block
Memb<ObjectBackup> mobj_backup; // ObjectBackup's memory block
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_EARLY_Z:
case RM_SHD_MAP:
case RM_SOLID :
mbox.draw(MatrixIdentity);
REPA(mobj_backup)mobj_backup[i].draw(); // render backuped data
break;
case RM_LIGHT:
LightPoint(1,Vec(0,0.8,0)).add();
break;
}
}
void Render3D()
{
Renderer(Render);
}
void Draw2D()
{
D.text(0,0.9,multi_threaded ? "Multi-threaded rendering" : "Single-threaded rendering");
D.text(0,0.8,S+"CPU Cores "+Cpu.cores());
D.text(0,0.7,S+"Fps " +Tm .fps ());
D.text(0,0.6, "Press 1,2 to change rendering mode");
}
/******************************************************************************/
void InitPre()
{
App.name("Multi-Threaded Rendering");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
PakAdd("../data/engine.pak",NULL);
D.full(true).bumpMode(BUMP_PARALLAX).shdSoft(2);
}
/******************************************************************************/
Bool Init()
{
// create materials
Material *brick=Materials("../data/mtrl/brick/0.mtrl");
// create meshes
mbox .create(1).base(0).create(Box (1 ),VTX_TX0|VTX_NRM|VTX_TNG).reverse(); // create mesh box
mball.create(1).base(0).create(Ball(0.08),VTX_TX0|VTX_NRM|VTX_TNG) ; // create mesh sphere
// set mesh materials, rendering versions and bounding boxes
mbox .setMaterial(brick).setRender().setBox();
mball.setMaterial(brick).setRender().setBox();
// create some objects
REP(256)
{
Object &obj=mobj.New(); // create new object in container
obj.pos =Random(mbox.box); // set it's random position
obj.mesh=&mball; // set it's mesh
}
if(Cpu.cores()>1) // if we have more than one core
{
StateMain.threadedSet(Render3D); // set StateMain (our current state) to have multi-threaded rendering
multi_threaded=true;
}
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.01f,10,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
// toggle multi-threaded rendering when keys pressed
if(Kb.bp(KB_1)){StateActive->threadedSet(NULL ); multi_threaded=false;} // disable multi-threaded rendering when '1' pressed
if(Kb.bp(KB_2)){StateActive->threadedSet(Render3D); multi_threaded=true ;} // enable multi-threaded rendering when '2' pressed
// 4 steps of multi-threaded processing
{
// 1st - Backup data
mobj.backup(mobj_backup); // backup all object's to object_bkp's
// 2nd - Start multi-threaded rendering
StateActive->threadedStart(); // after this call, Render3D will be working on the second thread
// 3rd - Process data update here
REPA(mobj)
{
Object &obj=mobj[i];
// do some heavy floating point operations
REPA(obj.parameters)obj.parameters[i]+=Sqrt(Sin(i*PI)*Pow(i,i*2.0)*16);
}
// 4th - Stop multi-threaded rendering (if it hasn't finished yet, it will wait for it)
if(StateActive->threadedStop())
{
// if we're here then multi-threaded rendering is enabled, so we need to call 2D drawing manually
Draw2D();
}
}
return true;
}
/******************************************************************************/
void Draw() // if multi-threaded rendering is enabled, classic 'Draw' will not be called
{
Render3D();
Draw2D();
D.text(0,-0.9,"Rendering through 'Draw'");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\3 - Mesh\Mesh\Grass 2.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
MeshGroup terrain ; // terrain mesh
Grass grass ; // grass renderer
Grass::Elm grass_elm[4096]; // single grass element
/******************************************************************************/
void InitPre()
{
App.name("Grass");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).sync(true).ambPower(0.3).shdMapSize(1024);
ViewportFull.range=50;
}
/******************************************************************************/
Bool Init()
{
Cam.dist=6;
Cam.at.set(0,2,0);
Sky .set();
Suns.New().set(*Gfxs("gfx/sky/sun.gfx"));
// load terrain mesh
terrain.load("obj/terrain/0.mshg");
// create grass renderer
grass.create();
// set random grass matrixes
terrain.setFaceNormals(); // make sure terrain has face normals, since we'll need those later
REPA(grass_elm)
{
Grass::Elm &elm =grass_elm[i];
Matrix &matrix=elm.matrix;
elm.param.set(0,0,0,255); // set parameters
matrix.setScale(Vec(0.18,0.3,0.18)).rotateY(RandomF(PI2)); // set scaled matrix and rotate it
Vec start=Random(terrain.box); // set random position at top of the terrain mesh box
start.y=terrain.box.max.y;
I32 hit_face,hit_mshb,hit_mesh;
if(SweepPointMesh(start,-Vec(0,terrain.box.h(),0),terrain,NULL,NULL,&matrix.pos,&hit_face,&hit_mshb,&hit_mesh)) // cast a ray down-wards and store contact info
{
Mshb &mshb=terrain.mesh(hit_mesh).base(hit_mshb); // this is the Mshb that we've hit
Vec &nrm =((hit_face&SIGN_BIT) ? mshb.quad.nrm[hit_face^SIGN_BIT] : mshb.tri.nrm[hit_face]); // this is the face normal that we've hit
matrix.orn*=Matrix3().setUp(nrm); // transform our grass matrix according to surface normal
matrix.pos.y-=0.05; // move it down a little
}
}
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,100,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT)); // move camera on right mouse button
UpdateGrassAndLeafs(); // update grass bending
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_SHD_MAP:
case RM_SOLID :
terrain.draw(MatrixIdentity); // render terrain
grass.draw(grass_elm,ELMS(grass_elm)); // render grass
break;
}
}
void Draw()
{
Renderer(Render);
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\3 - Mesh\Mesh\Grass.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
MeshGroup terrain ; // terrain mesh
Mesh grass ; // grass mesh
Vec pos[600]; // grass positions
/******************************************************************************/
void InitPre()
{
App.name("Grass");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).ambPower(0.3).shdMapSize(1024).shdSoft(1);
ViewportFull.range=30;
}
/******************************************************************************/
Bool Init()
{
Cam.dist =6;
Cam.pitch=-1;
Sky .set();
Suns.New().set(*Gfxs("gfx/sky/sun.gfx"));
// load terrain mesh
terrain.load("obj/terrain/0.mshg");
// create grass mesh
grass.create(1).base(0).createGrass(48);
grass.setMaterial(Materials("mtrl/grass/blade.mtrl")).setRender().setBox();
// set random positions on terrain surface
REPA(pos)PosPointMeshY(Random(terrain.box).xz()*0.4,terrain,&pos[i]);
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,100,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT)); // move camera on right mouse button
UpdateGrassAndLeafs(); // update grass bending
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_SHD_MAP:
case RM_SOLID :
REPA(pos)grass .draw(Matrix(0.25,pos[i]));
terrain.draw(MatrixIdentity);
break;
}
}
void Draw()
{
Renderer(Render);
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\3 - Mesh\Mesh\Separate parts rendering 1.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Mesh mesh;
Matrix matrix;
/******************************************************************************/
void InitPre()
{
App.name("Separate parts rendering");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.mode(800,600);
Cam.dist=3;
}
/******************************************************************************/
Bool Init()
{
mesh.create(3); // create mesh with room for 3 parts
// setup #0
{
MeshPart &part=mesh.part(0);
part.base.create(Ball(0.7),VTX_TX0|VTX_NRM|VTX_TNG); // create Mshb
part.setMaterial(Materials("mtrl/brick/0.mtrl")); // set material
Set(part.name,"ball"); // set name
}
// setup #1
{
MeshPart &part=mesh.part(1);
part.base.create(Tube(0.3,3),VTX_TX0|VTX_NRM|VTX_TNG); // create Mshb
part.setMaterial(Materials("mtrl/glass/0.mtrl")); // set material
Set(part.name,"tube"); // set name
}
// setup #2
{
MeshPart &part=mesh.part(2);
part.base.create(Box(3,0.3,0.3),VTX_TX0|VTX_NRM|VTX_TNG); // create Mshb
part.setMaterial(Materials("mtrl/grass/0.mtrl")); // set material
Set(part.name,"box"); // set name
}
mesh.setRender().setBox(); // setup mesh rendering version and bounding box
matrix.setPos(Vec(0,0,1)); // setup object matrix with position (0,0,1)
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.01f,10,CAMH_ZOOM|(Ms.b(1) ? CAMH_MOVE : CAMH_ROT));
return true;
}
/******************************************************************************/
void Draw()
{
D.clear();
LightDir(Cam.matrix.z).set();
if(!Kb.b(KB_SPACE)) // if space not pressed
{
mesh.draw(matrix); // render all parts with one object matrix
}else
{
// when space pressed render each part separately with different matrix
{
CChar8 *name[]=
{
"tube",
"box",
};
mesh.showAll().hide(name,ELMS(name)).draw(matrix); // render all parts EXCEPT those listed in 'names'
}
{
Matrix local_transformation;
local_transformation.setRotateX(Tm.time()/2);
mesh.hideAll().show("tube").draw(local_transformation*matrix); // render ONLY those parts that are named "tube"
}
{
Matrix local_transformation;
local_transformation.setRotateZ(Tm.time()/2);
mesh.hideAll().show("box").draw(local_transformation*matrix); // render ONLY those parts that are named "box"
}
mesh.showAll(); // remember to un-hide all elements after separate parts rendering
}
D.text(0,0.8,"Hold space to render each part with different matrix");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\3 - Mesh\Mesh\Separate parts rendering 2 - Skeleton.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Mesh *mesh;
Skeleton *skel;
Flt rifle_angle=0,
turret_angle=0;
/******************************************************************************/
void InitPre()
{
App.name("Separate parts rendering");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.mode(800,600).ambPower(0.5);
Cam.dist=3;
}
/******************************************************************************/
Bool Init()
{
mesh=Meshs ("Obj/vehicle/tank/0.mesh");
skel=Skeletons("Obj/vehicle/tank/0.skel");
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.01f,10,CAMH_ZOOM|(Ms.b(1) ? CAMH_MOVE : CAMH_ROT));
rifle_angle+=(Kb.b(KB_S)-Kb.b(KB_W))*Tm.d(); Clamp(rifle_angle,-0.5,0.1);
turret_angle+=(Kb.b(KB_E)-Kb.b(KB_Q))*Tm.d();
return true;
}
/******************************************************************************/
void DrawTank(Matrix &world_matrix)
{
// access skeleton bones
OrientP &rifle =skel->getBone("rifle" );
OrientP &turret=skel->getBone("turret");
// set local transformations
Matrix rifle_transform; rifle_transform.setTransformAtPos(rifle .pos,Matrix3().setRotateX( rifle_angle));
Matrix turret_transform; turret_transform.setTransformAtPos(turret.pos,Matrix3().setRotateY(turret_angle));
// convert local transformations to global matrixes (which is equal to 'local transformation' * 'parent matrix')
Matrix turret_matrix=turret_transform* world_matrix,
rifle_matrix= rifle_transform*turret_matrix;
// draw the mesh parts separately
mesh->hideAll().show("rifle" ).draw( rifle_matrix);
mesh->hideAll().show("turret").draw(turret_matrix);
mesh->hideAll().show("hull" ).draw( world_matrix);
mesh->showAll();
}
/******************************************************************************/
void Draw()
{
D.clear(0xFF6080FF);
LightDir(Cam.matrix.z).set();
DrawTank(MatrixIdentity);
D.text(0,0.9,S+ "Rifle Angle : "+ rifle_angle+" (W/S to change)");
D.text(0,0.8,S+"Turret Angle : "+turret_angle+" (Q/E to change)");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\3 - Mesh\Mesh\Separate parts rendering 3 - Controlled Skeleton.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************
In this tutorial we'll render separate parts with matrixes automatically calculated by Controlled Skeleton
CSkeleton will handle transforming child matrixes by parent matrixes
All we need to do is:
1. Create CSkeleton on the base of the object's Skeleton
2. Animate the CSkeleton
3. Render the parts using CSkeleton bone matrixes
As for animating the CSkeleton we'll use CSkelBone's relative rotation - CSkelBone::rot which is an 'AxisRoll' object
AxisRoll contains of:
struct AxisRoll
{
Vec axis;
Flt roll;
};
Where 'axis' direction determines the axis of rotation
'axis' length determines how much we'll rotate the object around 'axis' direction
'roll' is an additional parameter, which determines the angle of rotation around original bone direction
AxisRoll members when calling CSkeleton::clear() are reset {axis=Vec(0,0,0); roll=0;}
After reseting the members we'll adjust their values according to our desired angles
/******************************************************************************/
Mesh *mesh;
Skeleton *skel;
CSkeleton cskel;
Flt rifle_angle=0,
turret_angle=0;
/******************************************************************************/
void InitPre()
{
App.name("Separate parts rendering");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.mode(800,600).ambPower(0.5);
Cam.dist=3;
}
/******************************************************************************/
Bool Init()
{
mesh=Meshs ("Obj/vehicle/tank/0.mesh");
skel=Skeletons("Obj/vehicle/tank/0.skel");
cskel.create(*skel); // create a controlled skeleton
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
void AnimateTank(Matrix &world_matrix) // animate the tank skeleton
{
cskel.clear(); // reset the rotation values
cskel.getBone("rifle" ).rot.axis.x+= rifle_angle; // adjust rotation in X axis by 'rifle_angle'
cskel.getBone("turret").rot.roll +=turret_angle; // adjust rotation around bone's original direction by 'turret_angle'
cskel.updateMatrix(world_matrix); // calculate the final matrixes
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.01f,10,CAMH_ZOOM|(Ms.b(1) ? CAMH_MOVE : CAMH_ROT));
rifle_angle+=(Kb.b(KB_S)-Kb.b(KB_W))*Tm.d(); Clamp(rifle_angle,-0.5,0.1);
turret_angle+=(Kb.b(KB_E)-Kb.b(KB_Q))*Tm.d();
AnimateTank(MatrixIdentity);
return true;
}
/******************************************************************************/
void DrawTank()
{
// draw the mesh parts separately
// use calculated skeleton bone transformation matrixes
mesh->hideAll().show("rifle" ).draw(cskel.getBone("rifle" ).matrix());
mesh->hideAll().show("turret").draw(cskel.getBone("turret").matrix());
mesh->hideAll().show("hull" ).draw(cskel. matrix());
mesh->showAll();
}
/******************************************************************************/
void Draw()
{
D.clear(0xFF6080FF);
LightDir(Cam.matrix.z).set();
DrawTank();
D.text(0,0.9,S+ "Rifle Angle : "+ rifle_angle+" (W/S to change)");
D.text(0,0.8,S+"Turret Angle : "+turret_angle+" (Q/E to change)");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\3 - Mesh\Mesh\Terrain.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Gfx ground;
MeshGroup mshg ; // here MeshGroup is used instead of a Mesh (single mesh)
/******************************************************************************/
void InitPre()
{
App.name("Terrain");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).ambPower(0.3).shdSoft(1);
ViewportFull.range=40;
}
/******************************************************************************/
void CreateMesh(Mesh &mesh)
{
// create random terrain heightmap
Gfx gfx(128,128,1,GFX_I8,GFX_SOFT);
REPD(y,gfx.y())
REPD(x,gfx.x())gfx.pixel(x,y,Random(256)); // software images don't need to be locked/unlocked
gfx.blur(5,false); // apply gaussian blur to the heightmap with 5 pixel range and no clamping
// create terrain Mesh
mesh.create(1).base(0).createPlane(128,128,VTX_TX0); // create 2D plane with 128x128 vertexes
mesh.base(0).texScale(Vec2(16)); // scale texture coordinates
mesh.base(0).displaceZ(gfx); // displace vertexes Z position from heightmap
mesh.transform(Matrix().setPos(Vec(-0.5,-0.6,-0.5)).rotateX(PI_2).scale(Vec(50,8,50))); // transform by matrix
mesh.setNormals(); // recalculate normals
mesh.setMaterial(Materials("mtrl/grass/0.mtrl")); // set material
mesh.setBox(); // set bounding box
}
/******************************************************************************/
Bool Init()
{
Cam.at.y+=2; // move camera up
Sky .set();
Suns.New().set(*Gfxs("gfx/sky/sun.gfx"));
// create mesh
Mesh mesh;
CreateMesh(mesh);
// create terrain MeshGroup from standard Mesh
mshg.create(mesh,VecI(5,1,5)); // create MeshGroup with 5x1x5 (5*1*5=25) splits (Mesh is splitted to 25 parts along axises)
mshg.setRender();
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.01f,10,CAMH_ZOOM|(Ms.b(1) ? CAMH_MOVE : CAMH_ROT));
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_SOLID:
mshg.draw(MatrixIdentity);
break;
}
}
void Draw()
{
Renderer(Render);
if(Kb.b(KB_SPACE))REPA(mshg)mshg.mesh(i).box.draw(); // draw mesh bounding boxes
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\3 - Mesh\Mesh\Tree.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Mesh tree; // tree mesh
/******************************************************************************/
void InitPre()
{
App.name("Tree");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).ambPower(0.3);
}
/******************************************************************************/
Bool Init()
{
Cam.dist=14;
Cam.at.set(0,8,0);
Sky .set();
Suns.New().set(*Gfxs("gfx/sky/sun.gfx")).light_color=1-D.ambColor();
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,100,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT)); // move camera on right mouse button
if(Kb.bp(KB_TAB))D.ambMode(!D.ambMode()); // toggle ambient occlusion on tab pressed
if(Kb.bp(KB_SPACE))
{
// create the tree
Memb<Material*> leaf_materials; // container of leaf materials
leaf_materials.New()=Materials("mtrl/leaf/0/0.mtrl");
leaf_materials.New()=Materials("mtrl/leaf/0/1.mtrl");
tree.createTree(Materials("mtrl/bark/0.mtrl"),leaf_materials)
.setRender ();
}
UpdateGrassAndLeafs(); // call this to update wind bending
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_SOLID:
tree.draw(MatrixIdentity);
break;
}
}
void Draw()
{
Renderer(Render);
D.text(0,0.9,"Press Space to create a tree");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\4 - Demos, Game Basics\Demos\Auto Depth of Field.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Bool ray_hit ; // if testing ray hit anything
Vec ray_hit_pos; // if hit, then this is the hit position
Material *brick,
*glass;
Mesh mbox ,
mball,
mcapsule;
struct Object // object
{
Actor actor; // actor
Mesh *mesh ; // mesh
void draw() // draw
{
if(mesh)mesh->draw(actor.matrix());
}
};
Memb<Object> obj; // objects
/******************************************************************************/
void InitPre()
{
App.name("Auto Depth of Field");
App.flag=APP_FULL_TOGGLE;
PakAdd("../data/engine.pak");
D.full(true).sync(true);
ViewportFull.range=32;
Ms.hide();
// set initial depth of field parameters
D.dof(DOF_HIGH,1, 1,0,6);
}
/******************************************************************************/
Bool Init()
{
Physics.create();
// get materials
brick=Materials("../data/mtrl/brick/0.mtrl");
glass=Materials("../data/mtrl/glass/0.mtrl");
// shapes used for mesh and actor creation
Box box (32,1,32);
Ball ball(0.5);
Capsule capsule(0.3,2);
// create meshes
mbox .create(1).base(0).create(box ,VTX_TX0|VTX_NRM|VTX_TNG).texScale(Vec2(16));
mball .create(1).base(0).create(ball ,VTX_TX0|VTX_NRM|VTX_TNG);
mcapsule.create(1).base(0).create(capsule,VTX_TX0|VTX_NRM|VTX_TNG);
// set mesh materials, rendering versions and bounding boxes
mbox .setMaterial(brick).setRender().setBox();
mball .setMaterial(glass).setRender().setBox();
mcapsule.setMaterial(brick).setRender().setBox();
// create objects
{
// ground
{
Object &o=obj.New();
o.mesh=&mbox;
o.actor.create(box,0).pos(Vec(0,-box.h()/2,0));
}
// pillars
REPD(x,16)
REPD(z,16)
{
Object &o=obj.New();
o.mesh=&mcapsule;
o.actor.create(capsule,0).pos(Vec(box.lerpX(x/15.0),capsule.h/2-capsule.r,box.lerpZ(z/15.0)));
}
// balls
REP(100)
{
Object &o=obj.New();
o.mesh=&mball;
o.actor.create(ball).pos(Vec(box.lerpX(RandomF()),ball.r+capsule.h,box.lerpZ(RandomF())));
}
}
// set initial camera
Cam.setAngle(Vec(0,2,0),0,-0.2).set();
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Physics.sim().get();
// update camera
{
if(Kb.b(KB_A ))Cam.matrix.pos-=Cam.matrix.x*Tm.d();
if(Kb.b(KB_D ))Cam.matrix.pos+=Cam.matrix.x*Tm.d();
if(Kb.b(KB_W ))Cam.matrix.pos+=Cam.matrix.z*Tm.d();
if(Kb.b(KB_S ))Cam.matrix.pos-=Cam.matrix.z*Tm.d();
if(Kb.b(KB_SPACE))Cam.matrix.pos+=Cam.matrix.y*Tm.d();
if(Kb.b(KB_LCTRL))Cam.matrix.pos-=Cam.matrix.y*Tm.d();
if(Ms.hidden())
{
Cam.yaw -=Ms.dir_d.x;
Cam.pitch+=Ms.dir_d.y;
}
Cam.setAngle(Cam.matrix.pos,Cam.yaw,Cam.pitch).updateVelocities().set();
}
// toggle mouse
if(Kb.bp(KB_TAB))Ms.toggle();
// test ray
{
Flt new_z; // new Z focus
PhysHit phys_hit;
Vec pos,dir;
if(Ms.hidden())
{
pos=Cam.matrix.pos;
dir=Cam.matrix.z;
}else
{
ScreenToPosDir(Ms.pos,pos,dir);
}
if(Physics.ray(pos,dir*Viewport.range,&phys_hit)) // cast a ray from camera and check if it hits something
{
ray_hit =true;
ray_hit_pos=phys_hit.plane.p;
new_z =phys_hit.dist; //set new z focus to ray hit distance
}else
{
ray_hit=false;
new_z =Viewport.range; // set new z focus to viewport range
}
// set new depth of field z focus
D.dofZ(LerpTime(D.dofZ(),new_z,0.001));
}
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_SOLID:
REPAO(obj).draw();
break;
case RM_LIGHT:
LightDir(!Vec(1,-1,1)).add();
break;
}
}
void Draw()
{
Renderer(Render);
if(ray_hit)
{
SetMatrix();
Ball(0.1,ray_hit_pos).draw();
}
D.text(0,0.9,"Press Tab to toggle mouse, WSAD+Space+Control to move camera");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\4 - Demos, Game Basics\Demos\Day Night Cycle.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
MeshGroup terrain; // terrain mesh
Flt hour ; // current hour
/******************************************************************************/
void InitPre()
{
App.name("Nature");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).ambPower(0.2).hpRt(true).shdSoft(1).shdMapSize(1024);
}
/******************************************************************************/
Bool Init()
{
Cam.dist=6;
Cam.at.set(0,2,0);
Sky .set();
Suns.New().set(*Gfxs("gfx/sky/sun.gfx")).rays.mode=SUN_RAYS_HIGH;
// load terrain mesh
terrain.load("obj/terrain/0.mshg");
// set initial hour
hour=5;
// load clouds
Clouds.layered.set(3,Gfxs("Clouds/Layers/0.gfx"));
REPAO(Clouds.layered.layer).velocity*=4;
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,100,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT)); // move camera on right mouse button
// update hour
hour+=Tm.d()*2;
// set sun position
Sun &sun=Suns[0];
SinCos(sun.pos.y,sun.pos.x,hour/24*PI2-PI_2); sun.pos.z=0;
sun.pos*=Matrix3().setRotateY(PI-PI_4);
// tweak the sun to rise earlier, and set later
sun.pos.y+=0.5;
sun.pos.normalize();
// set sun color
Flt power=Sat(Cbrt(sun.pos.y));
sun.light_color=power;
// set sky color
Vec night_color(0.02,0.04,0.10),
horizon_color(0.35,0.45,0.64),
sky_color(0.30,0.38,0.54);
Sky.set(Lerp(night_color,horizon_color,power),sky_color*power);
// update clouds
Clouds.layered.update();
REP(Clouds.layered.layers())Clouds.layered.layer[i].color=ColorBrightness(power);
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_SHD_MAP:
case RM_SOLID :
terrain.draw(MatrixIdentity); // render terrain
break;
}
}
void Draw()
{
Renderer(Render);
D.text(0,0.9,S+"Hour "+(Trunc(hour)%24));
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\4 - Demos, Game Basics\Demos\Facial Animation.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
CSkeleton cskel;
Mesh *mesh;
Window window;
Text text [5];
Slider slider[4];
CheckBox blink;
/******************************************************************************/
void InitPre()
{
App.name("Facial Animation");
App.flag=APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).ambPower(0.2).shdMode(SHD_MAP_HW).shdSoft(1).shdMapSize(1024).hpRt(true);
ViewportFull.range=8;
}
/******************************************************************************/
Bool Init()
{
// camera
Cam.dist=0.4;
Cam.at.set(0,0.75,0);
Cam.yaw=PI;
Cam.setSpherical().set();
// sun
Sun &sun=Suns.New();
sun.set(*Gfxs("gfx/sky/sun.gfx"));
sun.pos =!Vec(1,1,3);
sun.light_color=1-D.ambColor();
// sky
Sky.set();
// character
cskel.create("obj/chr/human/0.skel",1.8);
mesh=Meshs ("obj/chr/human/0.mesh");
// gui
Gui +=window .create(Rect_R(D.w(),0,0.49,0.50),"Expressions");
window+=text[0].create(Vec2(0.13,-0.05),"Angry" ); window+=slider[0].create(Rect_L(0.26,-0.05,0.2 ,0.05));
window+=text[1].create(Vec2(0.13,-0.13),"Astonished"); window+=slider[1].create(Rect_L(0.26,-0.13,0.2 ,0.05));
window+=text[2].create(Vec2(0.13,-0.21),"Sad" ); window+=slider[2].create(Rect_L(0.26,-0.21,0.2 ,0.05));
window+=text[3].create(Vec2(0.13,-0.29),"Smile" ); window+=slider[3].create(Rect_L(0.26,-0.29,0.2 ,0.05));
window+=text[4].create(Vec2(0.13,-0.37),"Blink" ); window+=blink .create(Rect_L(0.26,-0.37,0.05,0.05),true);
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Gui.update();
// animate
Flt time=Tm.time();
cskel.clear ()
.animate(L"anim/face/angry.anim" ,time,slider[0]())
.animate(L"anim/face/astonished.anim",time,slider[1]())
.animate(L"anim/face/sad.anim" ,time,slider[2]())
.animate(L"anim/face/smile.anim" ,time,slider[3]());
if(blink())
{
Flt blend=Frac(time,3); // blink every 3 seconds
blend/=0.1; // blink duration = 0.1 seconds
if( blend>1)blend=2-blend;
cskel.animate(L"anim/face/blink.anim",time,blend,true);
}
cskel.updateMatrix(MatrixIdentity)
.updateVelocities();
if(!Gui.window_lit && Ms.b(0))CamHandle(0.01,10,CAMH_ZOOM|CAMH_ROT);
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_SOLID :
case RM_SHD_MAP:
mesh->draw(cskel);
break;
}
}
void Draw()
{
Renderer(Render);
Gui.draw();
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\4 - Demos, Game Basics\Demos\Lights.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
Int lights=3 ; // number of lights (1..3)
Material material ; // material light
Mesh mbox , // mesh box
mball , // mesh ball
mlight , // mesh light
mballs ; // mesh ball (shadow stencil version)
Vec ball_pos[8], // ball positions
light_pos[3]; // light positions
/******************************************************************************/
void SetEffect()
{
mbox .setEffect();
mball.setEffect();
}
/******************************************************************************/
void InitPre()
{
App.name("Lights Rendering Demo");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
PakAdd("../data/engine.pak");
D.set_effect=SetEffect;
D.full(true).bumpMode(BUMP_RELIEF).shdSoft(1).shdJitter(true);
}
/******************************************************************************/
Bool Init()
{
// create materials
Material *brick=Materials("../data/mtrl/brick/0.mtrl");
material.reset();
material.glow=0.6;
material.ambient=1;
// create meshes
mbox .create(1).base(0).create( Box(1 ),VTX_TX0|VTX_NRM|VTX_TNG).reverse( ); // create mesh box , reverse it because it's meant to be viewed from inside
mball .create(1).base(0).create(Ball(0.15),VTX_TX0|VTX_NRM|VTX_TNG).weldVal(VTX_POS); // create mesh ball, weld it's vertex positions (stencil shadows are very sensitive to even the smallest irregularities)
mlight.create(1).base(0).create(Ball(0.04));
// set mesh materials, rendering versions and bounding boxes
mbox .setMaterial( brick ).setRender().setBox();
mball .setMaterial( brick ).setRender().setBox();
mlight.setMaterial(&material).setRender().setBox();
// create stencil shadow version of ball mesh
mballs.create(mball).toStencilShadow();
// set random positions
REPA(ball_pos)ball_pos[i]=Random(Box(0.9));
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.01f,10,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
// update light positions when space is not pressed
if(!Kb.b(KB_SPACE))
{
static Flt t; t+=Tm.d()/2;
light_pos[0].set(0,0,0.3); light_pos[0]*=Matrix3().setRotateX(t).rotateY(t/2 ).rotateZ(t/3 );
light_pos[1].set(0,0,0.6); light_pos[1]*=Matrix3().setRotateX(t).rotateY(t/1.5).rotateZ(t/2.5);
light_pos[2].set(0,0,0.5); light_pos[2]*=Matrix3().setRotateX(t).rotateY(t/1.3).rotateZ(t/3.2);
}
// change settings
if(Kb.c('1'))lights=1;
if(Kb.c('2'))lights=2;
if(Kb.c('3'))lights=3;
if(Kb.c('q'))D.shdMode(SHD_NONE);
if(Kb.c('w'))D.shdMode(SHD_MAP ).shdSoft(0);
if(Kb.c('e'))D.shdMode(SHD_MAP ).shdSoft(1);
if(Kb.c('r'))D.shdMode(SHD_MAP_HW ).shdSoft(0);
if(Kb.c('t'))D.shdMode(SHD_MAP_HW ).shdSoft(1);
if(Kb.c('y'))D.shdMode(SHD_STENCIL).shdSoft(0);
if(Kb.c('u'))D.shdMode(SHD_STENCIL).shdSoft(1);
if(Kb.c('a'))D.bumpMode(BUMP_FLAT );
if(Kb.c('s'))D.bumpMode(BUMP_NORMAL );
if(Kb.c('d'))D.bumpMode(BUMP_PARALLAX);
if(Kb.c('f'))D.bumpMode(BUMP_RELIEF );
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_SHD_STENCIL:
REPA(ball_pos)mballs.draw(Matrix(ball_pos[i]));
break;
case RM_EARLY_Z:
case RM_SHD_MAP:
case RM_SOLID :
{
mbox .draw(MatrixIdentity);
REPA(ball_pos)mball.draw(Matrix(ball_pos[i]));
if(Renderer()!=RM_SHD_MAP) // don't render light balls in shadow mapping mode - this will disable casting shadows for them
{
material.color.v3.set(1 ,1,0.5); material.validate(); mlight.draw(Matrix(light_pos[0]));
if(lights>=2){material.color.v3.set(0.5,1,1 ); material.validate(); mlight.draw(Matrix(light_pos[1]));}
if(lights>=3){material.color.v3.set(0.5,1,0.5); material.validate(); mlight.draw(Matrix(light_pos[2]));}
}
}break;
case RM_LIGHT:
{
REP(lights)mlight.draw(Matrix(light_pos[i]));
switch(lights)
{
case 1:
LightPoint(0.50,light_pos[0],Vec(1)).add();
break;
case 2:
LightPoint(0.45,light_pos[0],Vec(1,0.5,0.0)).add();
LightPoint(0.45,light_pos[1],Vec(0,0.5,1.0)).add();
break;
case 3:
LightPoint(0.40,light_pos[0],Vec(1 ,0.3,0.0)).add();
LightPoint(0.40,light_pos[1],Vec(0.0,0.3,1 )).add();
LightPoint(0.40,light_pos[2],Vec(0.0,0.4,0.0)).add();
break;
}
}break;
}
}
void Draw()
{
Renderer(Render);
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\4 - Demos, Game Basics\Demos\Nature.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************/
const Bool hi_quality=true; // change to false to disable hi-quality settings
/******************************************************************************/
MeshGroup terrain; // terrain mesh
Mesh tree[4]; // tree mesh
Grass grass ; // grass renderer
Grass::Elm grass_elm [hi_quality ? 5000 : 3000]; // single grass element
Matrix tree_matrix[hi_quality ? 20 : 10]; // tree matrixes
/******************************************************************************/
void InitPre()
{
App.name("Nature");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).ambPower(0.35).hwDepthBuffer(true).shdMode(SHD_MAP_HW);
if(hi_quality)
{
D.hdr(true).hpRt(true).bumpMode(BUMP_PARALLAX).hdrExposure(0.7).bloomOverbright(true)
.ambMode(AMB_LOW).ambRange(0.05).ambHalfRes(true)
.shdSoft(1).shdMapSize(1024).shdJitter(true).grassShadow(true)
.mtnMode(MTN_HIGH);
ViewportFull.range=50;
}else
{
D.bendLeafs(false);
ViewportFull.range=35;
}
}
/******************************************************************************/
Bool Init()
{
Cam.dist=6;
Cam.at.set(0,2,0);
Sky.set();
// set sun
Sun &sun=Suns.New();
sun.set(*Gfxs("gfx/sky/sun.gfx"));
sun.light_color=1-D.ambColor();
sun.rays.mode =(hi_quality ? SUN_RAYS_HIGH : SUN_RAYS_LOW);
// set water
if(hi_quality)
{
Water.set (*Gfxs("gfx/water/0.gfx"),*Gfxs("gfx/water/0.n.gfx"),Gfxs("gfx/fx/reflection.gfx"));
Water.plane(Water.plane()-Vec(0,0.8,0));
Water.wave_scale=0.3;
}
// load clouds
Clouds.layered.set(3,Gfxs("Clouds/Layers/0.gfx"));
// load terrain mesh
terrain.load("obj/terrain/0.mshg");
// create tree meshes
Memb<Material*> leaf_materials;
leaf_materials.New()=Materials("mtrl/leaf/0/0.mtrl");
leaf_materials.New()=Materials("mtrl/leaf/0/1.mtrl");
REPA(tree)tree[i].createTree(Materials("mtrl/bark/0.mtrl"),leaf_materials).scale(Vec(0.5)).setRender();
// create grass renderer
grass.create();
// set tree matrixes
REPA(tree_matrix)
{
tree_matrix[i].setRotateY(RandomF(PI2)); // set matrix from random Y rotation
PosPointMeshY(Random(terrain.box).xz(),terrain,&tree_matrix[i].pos); // set random position on surface
tree_matrix[i].pos.y-=0.1; // move it down a little
}
// set random grass matrixes
terrain.setFaceNormals(); // make sure terrain has face normals, since we'll need those later
REPA(grass_elm)
{
Grass::Elm &elm =grass_elm[i];
Matrix &matrix=elm.matrix;
elm.param.set(0,0,0,Random(16,128)); // set parameters
matrix.setScale(Vec(0.18,0.3,0.18)).rotateY(RandomF(PI2)); // set scaled matrix and rotate it
Vec start =Random(terrain.box); // set random position at top of the terrain mesh box
start.y=terrain.box.max.y;
I32 hit_face,hit_mshb,hit_mesh;
if(SweepPointMesh(start,-Vec(0,terrain.box.h(),0),terrain,NULL,NULL,&matrix.pos,&hit_face,&hit_mshb,&hit_mesh)) // cast a ray down-wards and store contact info
{
Mshb &mshb=terrain.mesh(hit_mesh).base(hit_mshb); // this is the Mshb that we've hit
Vec &nrm =((hit_face&SIGN_BIT) ? mshb.quad.nrm[hit_face^SIGN_BIT] : mshb.tri.nrm[hit_face]); // this is the face normal that we've hit
matrix.orn *=Matrix3().setUp(nrm); // transform our grass matrix according to surface normal
matrix.pos.y-=0.05; // move it down a little
}
}
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,100,CAMH_ZOOM|(Ms.b(0)?CAMH_MOVE_XZ:(Ms.b(1)?CAMH_MOVE:CAMH_ROT))); // move camera on left/right mouse button
Clouds.layered.update();
Water . update(Vec2(0.2));
UpdateGrassAndLeafs();
if(Kb.bp(KB_F10))Renderer.screenShots("ScreenShot/","bmp");
return true;
}
/******************************************************************************/
void Render()
{
switch(Renderer())
{
case RM_SHD_MAP:
case RM_SOLID :
case RM_SOLID_M:
terrain.draw(MatrixIdentity); // render terrain
REPA(tree_matrix)tree[i%ELMS(tree)].draw(tree_matrix[i]); // render trees
grass.draw(grass_elm,ELMS(grass_elm)); // render grass
break;
}
}
void Draw()
{
Renderer(Render);
D.text(0,0.9,S+"Fps "+Tm.fps());
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\4 - Demos, Game Basics\Game Basics\01 - Character.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************
Define your custom player character class basing on already defined Game::Chr
Game::Chr is a class which handles the most basic character methods
including : movement, animations, physics and actions
/******************************************************************************/
struct Player : Game::Chr // extend character class by defining a player class based on the character
{
virtual Bool update(); // here we'll update the player (please note that this is a virtual method)
};
/******************************************************************************/
Bool Player::update()
{
// here we update character input according to mouse and keyboard
// before we set the input, we need to check if the character isn't controlled by an automatic action
if(action)
{
// if it's controlled by an action we leave the input with no changes,
// however we can optionally break that action, by pressing for example movement keys
if(Kb.b(KB_W) || Kb.b(KB_S) || Kb.b(KB_A) || Kb.b(KB_D) || Kb.b(KB_Q) || Kb.b(KB_E))actionBreak();
}
if(!action) // if the character isn't controlled by an automatic action, we can set the input
{
// turn & move
input.anglei.x=Kb.b(KB_Q)-Kb.b(KB_E);
input.anglei.y=Kb.b(KB_T)-Kb.b(KB_G);
input.diri .x=Kb.b(KB_D)-Kb.b(KB_A);
input.diri .z=Kb.b(KB_W)-Kb.b(KB_S);
input.diri .y=Kb.b(KB_SPACE)-Kb.b(KB_LSHIFT);
// dodge, crouch, walk, jump
input.dodge = Kb.bd(KB_D)-Kb.bd(KB_A);
input.crouch= Kb.b (KB_LSHIFT);
input.walk = Kb.b (KB_LCTRL );
input.jump =(Kb.bp(KB_SPACE) ? 3.5 : 0);
// mouse turn
Flt max=DegToRad(900)*Tm.d(),
dx =Ms.dir_ds.x*1.7,
dy =Ms.dir_ds.y*1.7*Ms.inv();
angle.x-=Mid(dx,-max,max);
angle.y+=Mid(dy,-max,max);
// ready stance change
ready^=Kb.bp(KB_R);
}
return __super::update(); // call Game::Chr::update on which Player is based on
}
/******************************************************************************/
Actor ground; // ground actor
Player player; // player
/******************************************************************************/
void InitPre()
{
App.name("Game Character");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).sync(true);
Cam.dist=5;
}
/******************************************************************************/
Bool Init()
{
Physics.create();
ground .create(Box(15,1,15,Vec(0,-2,0)),0);
player.create(0.45, 1.8, Vec(0,0,0), *Meshs("obj/chr/human/0.mesh"), *Skeletons("obj/chr/human/0.skel"), 1.8); // create player by radius, height, position, mesh, skeleton and mesh/skeleton scale
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Physics.sim().get();
player.update(); // update player
Cam.setSpherical(player.ctrl.actor.pos()+Vec(0,1,0),player.angle.x,player.angle.y,0,Cam.dist*ScaleFactor(Ms.wheel*-0.2)).updateVelocities().set(); // update camera according to player angles and mouse wheel
return true;
}
/******************************************************************************/
void Draw()
{
D.clear();
LightDir(Cam.matrix.z).set();
ground.draw(); // draw ground actor
player.draw(); // draw player
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\4 - Demos, Game Basics\Game Basics\02 - World.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************
When writing applications with worlds, you need to additionaly include all the Headers generated by the World Editor
these Headers are stored in the "enum/_enums.h" file in your Game Data folder
for more information about Enums and Headers please check World Editor documentation
/******************************************************************************/
#include "../../../../../data/enum/_enums.h"
/******************************************************************************/
Game::ObjMemx<Game::Static> Statics; // container for static objects
Game::ObjMemx<Game::Item > Items; // container for item objects
Game::ObjMemx<Game::Chr > Chrs; // container for character objects
/******************************************************************************/
void InitPre()
{
App.name("World Manager");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).sync(true).shdMapSize(1024);
Cam.dist =10;
Cam.yaw =-PI_4;
Cam.pitch=-0.5;
Cam.at.set(16,0,16);
}
/******************************************************************************/
Bool Init()
{
Physics.create();
Game::World.init(); // initialize world, optionally you can change default parameters here
// once the world is initialized, we need to tell the world 'which class handles which type'
// this is done by assigning memory containers to certain Object Types defined in Game Enums (which were used in the World Editor)
Game::World.setType(Statics,OBJ_STATIC) // set 'Statics' memory container for 'OBJ_STATIC' objects
.setType(Items ,OBJ_ITEM ) // set 'Items' memory container for 'OBJ_ITEM' objects
.setType(Chrs ,OBJ_CHR ); // set 'Chrs' ' memory container for 'OBJ_CHR' objects
// now when the engine is set up properly we can start a 'new game' with a builded world
Game::World.New("world/sample"); // create the world by giving path to builded world
// when the world is loaded it doesn't actually load all the terrain and objects into memory
// it loads only information about them
// you need to tell the world which terrain and objects you need to use at the moment
// to do that call:
Game::World.update(Cam.at); // which updates world to use only terrain and objects at given position, here camera position is used
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,100,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
Game::World.update(Cam.at); // update the world to given position
return true;
}
/******************************************************************************/
void Render()
{
Game::World.draw(); // draw world (this is done outside of 'switch(Renderer())' because world automatically detects active rendering mode)
switch(Renderer())
{
case RM_LIGHT:
LightDir(!Vec(1,-1,1)).add();
break;
}
}
void Draw()
{
Renderer(Render);
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\4 - Demos, Game Basics\Game Basics\03 - World with Character.txt
/******************************************************************************/
#include "stdafx.h"
#include "../../../../../data/enum/_enums.h"
/******************************************************************************
In this tutorial is presented how to combine extending base classes with World Manager usage
/******************************************************************************/
struct Player : Game::Chr // extend character structure by defining a player class based on the character
{
Memx<Game::Item> item; // here is the characters inventory, a container of items
virtual _Memx* itemContainer(){return &item;} // override default method of character, to return proper item container
void updateItems(); // update items actions
virtual Bool update (); // here we'll update the player
};
/******************************************************************************/
Game::ObjMemx<Game::Static> Statics; // container for static objects
Game::ObjMemx<Game::Item > Items ; // container for item objects
Game::ObjMemx< Player> Players; // container for player objects
/******************************************************************************/
void Player::updateItems()
{
if(Kb.bp(KB_1)) // try to pickup an item
if(Items.elms()) // if world items container has some elements
itemPickUp(Items[0]); // pick up the first valid item
if(Kb.bp(KB_2)) // try to drop down an item
if(item.elms()) // if inventory has some items
itemDropDown(item[0]); // drop down the first item
if(!Kb.alt)grabStop();else // if don't want to grab
{
if(grab.is()) // if already grabbing
{
Vec pos;
SinCos(pos.z,pos.x,angle.x+PI_2); // set direction according to player angle
pos *=ctrl.radius()+0.5; // set radius according to player controller radius
pos.y=ctrl.height()*0.4; // set vertical position
pos +=T.pos();
grab.pos(pos); // set desired grab position
}else
if(Items.elms()) // if isn't grabbing anything check for presence of world items
{
grabStart(Items[0]); // grab first present
}
}
}
/******************************************************************************/
Bool Player::update()
{
if(action)
{
if(Kb.b(KB_W) || Kb.b(KB_S) || Kb.b(KB_A) || Kb.b(KB_D) || Kb.b(KB_Q) || Kb.b(KB_E))actionBreak();
}
if(!action)
{
// turn & move
input.anglei.x=Kb.b(KB_Q)-Kb.b(KB_E);
input.anglei.y=Kb.b(KB_T)-Kb.b(KB_G);
input.diri .x=Kb.b(KB_D)-Kb.b(KB_A);
input.diri .z=Kb.b(KB_W)-Kb.b(KB_S);
input.diri .y=Kb.b(KB_SPACE)-Kb.b(KB_LSHIFT);
// dodge, crouch, walk, jump
input.dodge = Kb.bd(KB_D)-Kb.bd(KB_A);
input.crouch= Kb.b (KB_LSHIFT);
input.walk = Kb.b (KB_LCTRL );
input.jump =(Kb.bp(KB_SPACE ) ? 3.5 : 0);
// mouse turn
Flt max=DegToRad(900)*Tm.d(),
dx =Ms.dir_ds.x*1.7,
dy =Ms.dir_ds.y*1.7*Ms.inv();
angle.x-=Mid(dx,-max,max);
angle.y+=Mid(dy,-max,max);
// ready stance change
ready^=Kb.bp(KB_R);
}
updateItems();
return __super::update();
}
/******************************************************************************/
void InitPre()
{
App.name("World with Character");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).sync(true).shdMapSize(1024);
}
/******************************************************************************/
Bool Init()
{
Text_ds.scale*=0.8;
Physics.create();
// create the world
Game::World.init()
.setType(Statics,OBJ_STATIC)
.setType(Players,OBJ_CHR ) // please note that here we'll use 'Players' memory container for 'OBJ_CHR' objects
.setItem(Items ,OBJ_ITEM ) // please note that here is called 'setItem' instead of 'setType', this is used for enabling built-in character<->item relations such as picking up and dropping items
.New("world/sample" );
Cam.setSpherical(Vec(16,0,16),-PI_4,-0.5,0,10).set(); // set initial camera
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Game::World.update(Cam.at); // update world to given position
return true;
}
/******************************************************************************/
void Render()
{
Game::World.draw();
switch(Renderer())
{
case RM_LIGHT:
LightDir(!Vec(1,-1,1)).add();
break;
}
}
void Draw()
{
Renderer(Render);
D.text(0,0.9,"Press WSAD keys to move, 1/2 to pick up/drop item, Alt to grab");
if(Players.elms())D.text(0,0.8,S+"Items in inventory : "+Players[0].item.elms());
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\4 - Demos, Game Basics\Game Basics\04 - Lights.txt
/******************************************************************************/
#include "stdafx.h"
#include "../../../../../data/enum/_enums.h"
/******************************************************************************
In this tutorial is presented how to use lighting created in World Editor
Here 2 light sources are used:
1st is a static light defined in a constant position in the World Editor
2nd is a light stored in a candle object, as a sub-object
/******************************************************************************/
struct Item : Game::Item // extend game items
{
Game::LightPoint light_point; // point light
virtual void create(Game::ObjParams &obj); // extend creation
virtual void draw ( ); // extend drawing
virtual void save (File &f); // extend saving
virtual Bool load (File &f); // extend loading
};
/******************************************************************************/
void Item::create(Game::ObjParams &obj)
{
__super::create(obj); // default create
// add custom children
for(Game::ObjParams *cur=&obj; cur; cur=cur->base()) // check 'obj' and all its bases
FREPA(cur->sub_obj) // for each sub-object in 'cur'
{
Game::ObjParams &o=cur->sub_obj[i];
switch(Game::World.objType(o.type())) // check the type of sub-object
{
case OBJ_LGT_PNT: // if its light, then create our member from its parameters
light_point.create(o);
break;
}
}
}
/******************************************************************************/
void Item::draw()
{
if(0) // optionally you can disable shadow casting of the item, when the item is the light source
{
if(Renderer()==RM_SHD_MAP && CurrentLight.src==&light_point)return; // if in shadowing mode and current light source is 'light_point' then don't draw anything
}
__super :: draw( ); // default draw
light_point.draw(actor.matrix()); // draw light with item's matrix
}
/******************************************************************************/
void Item::save(File &f)
{
__super::save(f); // save default data
light_point.save(f); // save point light
}
Bool Item::load(File &f)
{
if(__super::load(f)) // load default data
{
light_point.load(f); // load point light
return true;
}
return false;
}
/******************************************************************************/
Game::ObjMemx<Item > Items;
Game::ObjMemx<Game::LightPoint> LightPoints; // container for point light objects
/******************************************************************************/
void InitPre()
{
App.name("Lights");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).sync(true).shdMapSize(1024);
Cam.dist =10;
Cam.yaw =-PI_4;
Cam.pitch=-0.5;
Cam.at.set(16,0,16);
}
/******************************************************************************/
Bool Init()
{
Physics.create();
Game::World.init ( )
.setType(Items ,OBJ_ITEM )
.setType(LightPoints,OBJ_LGT_PNT)
.New ("world/lights" )
.update (Cam.at );
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,100,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
Game::World.update(Cam.at);
return true;
}
/******************************************************************************/
void Render()
{
Game::World.draw();
}
void Draw()
{
Renderer(Render);
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\4 - Demos, Game Basics\Game Basics\05 - Saving and Loading.txt
/******************************************************************************/
#include "stdafx.h"
#include "../../../../../data/enum/_enums.h"
/******************************************************************************
In this tutorial is presented how to save and load World states
/******************************************************************************/
Game::ObjMemx<Game::Item> Items;
/******************************************************************************/
void InitPre()
{
App.name("Lights");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).sync(true).shdMapSize(1024).ambPower(0.3);
Cam.dist =10;
Cam.yaw =-PI_4;
Cam.pitch=-0.5;
Cam.at.set(16,0,16);
}
/******************************************************************************/
Bool Init()
{
Physics.create();
Sky .set();
Sun &sun=Suns.New(); sun.set(*Gfxs("gfx/sky/sun.gfx")).light_color=1-D.ambColor(); sun.pos.set(0,1,0);
Game::World.init ( )
.setType(Items,OBJ_ITEM )
.New ("world/barrels")
.update (Cam.at );
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,100,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
if(Kb.bp(KB_F2))Game::World.save("LocalData/save.sav"); // save game
if(Kb.bp(KB_F3))Game::World.load("LocalData/save.sav"); // load game
Game::World.update(Cam.at);
// add some velocity to objects
if(Kb.bp(KB_SPACE))REPA(Items)Items[i].actor.addVel(5*Random.dir(Vec(0,1,0),0.7));
return true;
}
/******************************************************************************/
void Render()
{
Game::World.draw();
}
void Draw()
{
Renderer(Render);
D.text(0,0.9,"Press F2 to save and F3 to load");
D.text(0,0.8,"Press Space to add velocity");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\4 - Demos, Game Basics\Game Basics\06 - Pathfind.txt
/******************************************************************************/
#include "stdafx.h"
#include "../../../../../data/enum/_enums.h"
/******************************************************************************/
Game::ObjMemx<Game::Chr > Chrs ;
Game::ObjMemx<Game::Static> Statics;
Marker marker; // marker pointing character destination target
/******************************************************************************/
void InitPre()
{
App.name("Pathfind");
App.flag=APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).sync(true).shdMapSize(1024).ambPower(0.3);
ViewportFull.range=50;
Cam.dist = 10;
Cam.yaw =-PI_4;
Cam.pitch=-PI_3;
}
/******************************************************************************/
Bool Init()
{
Physics.create();
Sky .set ();
Suns .New ().set(*Gfxs("gfx/sky/sun.gfx")).light_color=1-D.ambColor();
Game::World.init ( )
.setType(Chrs ,OBJ_CHR )
.setType(Statics,OBJ_STATIC)
.New ("world/path" )
.update (Cam.at );
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Game::World.update(Cam.at);
// move player
if(Ms.bp(0) && Chrs.elms()) // on LMB pressed
{
Vec pos,dir ; ScreenToPosDir(Ms.pos,pos,dir); // convert screen mouse position to world position and direction
PhysHit phys_hit;
if(Physics.ray(pos,dir*Viewport.range,&phys_hit)) // if ray-test hit something
{
Chrs[0].actionMoveTo(phys_hit.plane.p); // order character to move to that location
marker.color=YELLOW;
marker.size=2;
marker.range_opaque=0.1;
marker.range_fade =0.2;
marker.gfx=Gfxs("gfx/particle/star.gfx");
marker.local_matrix.setPosDir(phys_hit.plane.p,Vec(0,1,0));
}
}
// rotate camera
if(Ms.b(1))
{
Cam.yaw -=Ms.dir_d.x;
Cam.pitch+=Ms.dir_d.y;
}
Cam.setSpherical(Chrs[0].pos(),Cam.yaw,Cam.pitch,0,Cam.dist*ScaleFactor(Ms.wheel*-0.2)).updateVelocities().set();
// rotate marker around its z axis
marker.local_matrix.orn.rotateZVec(Tm.d());
return true;
}
/******************************************************************************/
void Render()
{
Game::World.draw();
switch(Renderer())
{
case RM_BLEND:
if(Chrs[0].action==Game::ACTION_MOVE_TO)marker.draw(MatrixIdentity);
break;
}
}
void Draw()
{
Renderer(Render);
// show blocked places
if(Kb.b(KB_SPACE)) // if space pressed
if(Chrs.elms()) // if at least one character is available
{
Vec pos =Chrs[0].pos(); // get character position
VecI2 area_pos=Game::World.worldToAreaPos(pos); // convert from world position to area coordinates
if(const Game::Area::Path *path=Game::World.pathGet(area_pos)) // if found paths at given coordinates
{
D.clearZ (); // clear Z Buffer
SetMatrix(); // reset drawing matrix
Vec world_pos=Game::World.areaToWorldPos(area_pos).x0y(); // convert 2D Area Coordinates to 3D World Position
Flt cell_size=(1.0f/AREA_PATH_RES)*Game::World.areaSize(); // get size of a single path cell
VI.color(ColorAlpha(RED,0.5f)); // set drawing color to transparent RED
REPD(y,AREA_PATH_RES)
REPD(x,AREA_PATH_RES)if(!path->walkable(x,y)) // if current cell isn't walkable
{
Vec pos=world_pos+Vec(x,0,y)*cell_size; // get world position of a single path cell
VI.quad(pos+Vec( 0,0,cell_size), // draw a quad which extends 'pos' to right and forward by 'cell_size'
pos+Vec(cell_size,0,cell_size),
pos+Vec(cell_size,0, 0),
pos+Vec( 0,0, 0));
}
VI.end();
}
}
// informations
D.text(0,0.9,"Press LMB to move player, RMB to rotate camera");
D.text(0,0.8,"Press Space to show blocked places at character position");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\4 - Demos, Game Basics\Game Basics\07 - Doors.txt
/******************************************************************************/
#include "stdafx.h"
#include "../../../../../data/enum/_enums.h"
/******************************************************************************/
struct Door : Game::Door // extend doors
{
virtual void draw(); // extend default drawing, we'll use it to enable door highlighting
};
struct Chr : Game::Chr // extend characters
{
virtual Bool update(); // extend default updating, we'll use it to detect if when moving there are some closed doors which we'll open automatically
};
/******************************************************************************/
Game::ObjMemx< Chr > Chrs ;
Game::ObjMemx< Door > Doors ; // container for door objects
Game::ObjMemx<Game::Static> Statics;
Game::Obj *Object; // game object under mouse cursor
/******************************************************************************/
void Door::draw() // extended door drawing
{
if(Object==this && Renderer()==RM_SOLID)SetHighlight(ARGB(0,30,30,30)); // if the objects is the one under cursor, enable highlight before drawing it
__super::draw(); // default draw
if(Renderer()==RM_SOLID)SetHighlight(); // clear highlight to zero
}
/******************************************************************************/
Bool Chr::update() // extended character updating
{
if(__super::update())
{
// we wan't to detect if a player is moving to a destination path, and if on its way there is a closed door
if(action==Game::ACTION_MOVE_TO) // if we're in automatic action move to
{
// setup movement direction
Vec dir;
dir.y=0;
SinCos(dir.z,dir.x,angle.x+PI_2); // 'dir' is the direction where the player is moving at the moment
// setup a ball at characters position
Ball ball(ctrl.radius(),pos());
// sweep for an obstacle
PhysHit phys_hit;
if(Physics.sweep(ball,dir,&phys_hit,IndexToFlag(Game::GROUP_DOOR))) // test for obstacles in 1 meter range, test door actor groups only
if(Door *door=CAST(Door,phys_hit.obj)) // if it's actually a door
{
door->open(); // automatically open the door
}
}
return true;
}
return false;
}
/******************************************************************************/
void InitPre()
{
App.name("Doors");
App.flag=APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).sync(true).shdMapSize(1024).ambPower(0.3);
ViewportFull.range=50;
Cam.dist = 10;
Cam.yaw =-PI_4;
Cam.pitch=-PI_3;
}
/******************************************************************************/
Bool Init()
{
Text_ds.scale*=0.8;
Physics.create();
Sky .set ();
Suns .New ().set(*Gfxs("gfx/sky/sun.gfx")).light_color=1-D.ambColor();
Game::World.init ( )
.setType(Chrs ,OBJ_CHR )
.setType(Doors ,OBJ_DOOR )
.setType(Statics,OBJ_STATIC)
.New ("world/door" )
.update (Cam.at );
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Game::World.update(Cam.at);
// detect object under cursor
Vec pos,dir ; ScreenToPosDir(Ms.pos,pos,dir); // convert screen mouse position to world position and direction
PhysHit phys_hit;
if(Physics.ray(pos,dir*Viewport.range,&phys_hit)) // if ray-test hit something
{
Object=phys_hit.obj; // get encountered object
if(Ms.bp(0)) // if LMB is pressed
{
if(Door *door=CAST(Door,Object)) // if current object is of 'Door' type
{
door->toggle(); // toggle door
}
else // if not then move to that position
{
if(Chrs.elms())Chrs[0].actionMoveTo(phys_hit.plane.p);
}
}
}else
{
Object=NULL; // clear object pointer
}
// rotate camera
if(Ms.b(1))
{
Cam.yaw -=Ms.dir_d.x;
Cam.pitch+=Ms.dir_d.y;
}
if(Chrs.elms())Cam.setSpherical(Chrs[0].pos(),Cam.yaw,Cam.pitch,0,Cam.dist*ScaleFactor(Ms.wheel*-0.2)).updateVelocities().set();
return true;
}
/******************************************************************************/
void Render()
{
Game::World.draw();
}
void Draw()
{
Renderer(Render);
D.text(0,0.92,"Press LMB on the door to open or close it");
D.text(0,0.84,"Press LMB on the ground to move the player");
D.text(0,0.76,"Press RMB to rotate the camera");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\4 - Demos, Game Basics\Game Basics\08 - Custom Parameters.txt
/******************************************************************************/
#include "stdafx.h"
#include "../../../../../data/enum/_enums.h"
/******************************************************************************/
// ITEM
/******************************************************************************/
struct Item : Game::Item // extend items
{
Char name[64]; // add new parameter 'name'
I32 value ; // add new parameter 'value'
virtual void create(Game::ObjParams &obj); // extend default creation
// since new parameters are declared we need to properly initialize them in constructor, and save/load them in IO methods:
// constructor
Item();
// io methods
virtual void save(File &f);
virtual Bool load(File &f);
};
/******************************************************************************/
void Item::create(Game::ObjParams &obj)
{
__super::create(obj); // default create
// now setup custom parameters from 'obj'
if(Game::Param *par=obj.findParam("name" ))Set(name ,par->asStr());
if(Game::Param *par=obj.findParam("value")) value=par->asInt() ;
}
/******************************************************************************/
Item::Item()
{
name[0]=0;
value=0;
}
/******************************************************************************/
void Item::save(File &f)
{
__super::save(f); // default save
f<<name<<value; // save custom parameters
}
Bool Item::load(File &f)
{
if(__super::load(f)) // if default load was successful
{
f>>name>>value; // load custom parameters
return true; // return success
}
return false; // return failure
}
/******************************************************************************/
// MAIN
/******************************************************************************/
Game::ObjMemx<Item> Items;
/******************************************************************************/
void InitPre()
{
App.name("Custom Parameters");
App.flag=APP_FULL_TOGGLE|APP_MS_EXCLUSIVE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).sync(true).shdMapSize(1024).ambPower(0.3);
ViewportFull.range=50;
Cam.at.set(16,0,16);
Cam.dist = 10;
Cam.pitch=-PI_3;
}
/******************************************************************************/
Bool Init()
{
Text_ds.scale*=0.8;
Physics.create();
Sky .set ();
Suns .New ().set(*Gfxs("gfx/sky/sun.gfx")).light_color=1-D.ambColor();
Game::World.init ( )
.setItem(Items,OBJ_ITEM )
.New ("world/custom params");
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,100,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
Game::World.update(Cam.at);
return true;
}
/******************************************************************************/
void Render()
{
Game::World.draw();
}
void Draw()
{
Renderer(Render);
// draw item parameters
REPA(Items)
{
Item &item =Items[i]; // get i-th Items
Vec2 screen=PosToScreen(item.pos()); // convert world position to screen position
D.text(screen,item.name); // draw item's name
}
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\4 - Demos, Game Basics\Game Basics\09 - Extending Game Object Class.txt
/******************************************************************************/
#include "stdafx.h"
#include "../../../../../data/enum/_enums.h"
/******************************************************************************
In this tutorial is presented how to extend a Game Object class.
But unlike in previous examples, we won't base on Character/Item or other classes.
This time we'll extend the most base class - Game::Obj.
/******************************************************************************/
struct NewObj : Game::Obj // extend Game Object
{
Vec position; // the class will contain only position
// provide necessary methods required by Game::Obj :
virtual void create(Game::ObjParams &obj); // extend default creation
virtual Vec pos( ){return position ;} // get position
virtual void pos(Vec &pos){ T.position=pos;} // set position
virtual Matrix matrix( ){return position ;} // get matrix
virtual void matrix(Matrix &matrix){ T.position=matrix.pos;} // set matrix
virtual Bool update(){return true;} // object update
virtual void draw (); // object draw
virtual void disable(){}
virtual void enable(){}
// constructor
NewObj();
// io methods
virtual void save(File &f);
virtual Bool load(File &f);
};
/******************************************************************************/
NewObj::NewObj() // initialize values in constructor
{
position.zero();
}
void NewObj::create(Game::ObjParams &obj)
{
// now setup custom parameters from 'obj'
position=obj.matrixFinal().pos; // obtain our 'position' member from 'obj'
}
/******************************************************************************/
void NewObj::draw()
{
switch(Renderer())
{
case RM_SOLID:
case RM_LIGHT:
{
SetMatrix();
Ball(1,position).draw(ARGB(0,255,255,255)); // draw white ball at objects position
}break;
}
}
/******************************************************************************/
void NewObj::save(File &f)
{
__super::save(f); // default save
f<<position; // save custom parameters
}
Bool NewObj::load(File &f)
{
if(__super::load(f)) // if default load was successful
{
f>>position; // load custom parameters
return true; // return success
}
return false; // return failure
}
/******************************************************************************/
// MAIN
/******************************************************************************/
Game::ObjMemx<NewObj> NewObjs; // container for objects
/******************************************************************************/
void InitPre()
{
App.name("Game::Obj class");
App.flag=APP_FULL_TOGGLE|APP_MS_EXCLUSIVE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).sync(true).shdMapSize(1024).ambPower(0.3);
ViewportFull.range=50;
Cam.at.set(16,0,16);
Cam.dist = 10;
Cam.pitch=-PI_3;
}
/******************************************************************************/
Bool Init()
{
Physics.create();
Sky .set ();
Suns .New ().set(*Gfxs("gfx/sky/sun.gfx")).light_color=1-D.ambColor();
Game::World.init ( )
.setType(NewObjs,OBJ_ITEM ) // use OBJ_ITEM type because objects in the world we're using are saved with OBJ_ITEM type
.New ("world/custom params");
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,100,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
Game::World.update(Cam.at);
return true;
}
/******************************************************************************/
void Render()
{
Game::World.draw();
}
void Draw()
{
Renderer(Render);
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\4 - Demos, Game Basics\Game Basics\10 - Dynamically Created Objects.txt
/******************************************************************************/
#include "stdafx.h"
#include "../../../../../data/enum/_enums.h"
/******************************************************************************
In this tutorial is presented how to dynamically create objects
/******************************************************************************/
Game::ObjMemx<Game::Item> Items;
/******************************************************************************/
void InitPre()
{
App.name("Dynamically Created Objects");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).sync(true).shdMapSize(1024).ambPower(0.3);
Cam.dist =16;
Cam.yaw =-PI_4;
Cam.pitch=-0.5;
Cam.at.set(16,0,16);
}
/******************************************************************************/
Bool Init()
{
Physics.create();
Sky .set ();
Suns .New ().set(*Gfxs("gfx/sky/sun.gfx")).pos.set(0,1,0);
Game::World.init ( )
.setType(Items,OBJ_ITEM )
.New ("world/barrels")
.update (Cam.at );
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,100,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
Game::World.update(Cam.at);
if(Kb.bp(KB_SPACE)) // on space
{
Game::ObjParams &obj=*Game::Objs("obj/item/misc/barrel/0.obj"); // get barrel object parameters
Game::World.objCreate(obj,Matrix(obj.scale(),Vec(16,8,16))); // create new object at (16,8,16) position and give objects default scaling
}
return true;
}
/******************************************************************************/
void Render()
{
Game::World.draw();
}
void Draw()
{
Renderer(Render);
D.text(0,0.9,"Press Space to add a Barrel");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\4 - Demos, Game Basics\Game Basics\11 - Waypoints.txt
/******************************************************************************/
#include "stdafx.h"
#include "../../../../../data/enum/_enums.h"
/******************************************************************************/
void InitPre()
{
App.name("Waypoints");
App.flag=APP_FULL_TOGGLE|APP_MS_EXCLUSIVE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).sync(true).ambPower(0.3);
ViewportFull.range=50;
Cam.at.set(16,0,16);
Cam.dist = 20;
Cam.pitch=-PI_3;
}
/******************************************************************************/
Bool Init()
{
Text_ds.scale*=0.8;
Physics.create();
Sky .set ();
Suns .New ().set(*Gfxs("gfx/sky/sun.gfx")).light_color=1-D.ambColor();
Game::World.init( )
.New ("world/waypoints");
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,100,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
Game::World.update(Cam.at);
return true;
}
/******************************************************************************/
void Render()
{
Game::World.draw();
}
void DrawWaypoints(Str name)
{
if(Game::Waypoint *waypoint=Game::World.findWaypoint(name)) // if waypoint exists
{
waypoint->draw( ); // draw waypoint
Vec pos=waypoint->pos (Tm.time()*2); // access waypoints position at 'Tm.time()*2' length
pos.draw(RED); // draw the position as red dot
}
}
void Draw()
{
Renderer(Render);
// draw waypoints
// 3 waypoints are stored in World used in this tutorial, they're named as follow: "0", "1", "2"
SetMatrix(); // first reset matrix
REP(3)DrawWaypoints(S+i); // draw each waypoint
D.text(0,0.9,"Notice that different Waypoints have different looping modes");
D.text(0,0.8,"Waypoints with their looping modes are set in World Editor");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\4 - Demos, Game Basics\Game Basics\12 - Character Animations.txt
/******************************************************************************/
#include "stdafx.h"
#include "../../../../../data/enum/_enums.h"
/******************************************************************************/
struct Player : Game::Chr
{
Motion attack;
virtual void animate(); // extend skeleton animation
virtual Bool update ();
// io
virtual void save(File &f);
virtual Bool load(File &f);
};
/******************************************************************************/
void Player::animate()
{
__super::animate(); // call default animations
// now the skeleton is animated with default character animations (walking, running, crouching, ..)
// so after the basic animations we can optionally replace them with custom ones, for example attacking:
cskel.animate(attack,true); // animate skeleton with 'attack' animation motion, 'true' for replace animation mode
}
/******************************************************************************/
Bool Player::update()
{
if(action)
{
if(Kb.b(KB_W) || Kb.b(KB_S) || Kb.b(KB_A) || Kb.b(KB_D) || Kb.b(KB_Q) || Kb.b(KB_E))actionBreak();
}
if(!action)
{
// turn & move
input.anglei.x=Kb.b(KB_Q)-Kb.b(KB_E);
input.anglei.y=Kb.b(KB_T)-Kb.b(KB_G);
input.diri .x=Kb.b(KB_D)-Kb.b(KB_A);
input.diri .z=Kb.b(KB_W)-Kb.b(KB_S);
input.diri .y=Kb.b(KB_SPACE)-Kb.b(KB_LSHIFT);
// dodge, crouch, walk, jump
input.dodge = Kb.bd(KB_D)-Kb.bd(KB_A);
input.crouch= Kb.b (KB_LSHIFT);
input.walk = Kb.b (KB_LCTRL );
input.jump =(Kb.bp(KB_SPACE ) ? 3.5 : 0);
// mouse turn
Flt max=DegToRad(900)*Tm.d(),
dx =Ms.dir_ds.x*1.7,
dy =Ms.dir_ds.y*1.7*Ms.inv();
angle.x-=Mid(dx,-max,max);
angle.y+=Mid(dy,-max,max);
// ready stance change
ready^=Kb.bp(KB_R);
}
// update animation
{
if(Kb.bp(KB_ENTER)) // on enter pressed
attack.set(cskel,"anim/swing/r-l.anim"); // initialize "right-hand swing to left direction" attack animation
attack.updateAuto(3,3,1); // update attack animation motion
}
return __super::update();
}
/******************************************************************************/
void Player::save(File &f)
{
__super::save(f);
attack.save(f);
}
Bool Player::load(File &f)
{
if(__super::load(f))
{
return attack.load(f,cskel);
}
return false;
}
/******************************************************************************/
Game::ObjMemx<Game::Static> Statics;
Game::ObjMemx<Game::Item > Items ;
Game::ObjMemx< Player> Players;
/******************************************************************************/
void InitPre()
{
App.name("Character Animations");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).sync(true).shdMapSize(1024).ambPower(0.3);
}
/******************************************************************************/
Bool Init()
{
Physics.create();
Sky .set ();
Suns .New ().set(*Gfxs("gfx/sky/sun.gfx")).light_color=1-D.ambColor();
Game::World.init()
.setType(Statics,OBJ_STATIC)
.setItem(Items ,OBJ_ITEM )
.setType(Players,OBJ_CHR )
.New ("world/sample" );
Cam.setSpherical(Vec(16,0,16),-PI_4,-0.5,0,10).set();
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Game::World.update(Cam.at);
return true;
}
/******************************************************************************/
void Render()
{
Game::World.draw();
}
void Draw()
{
Renderer(Render);
D.text(0,0.9,"Press Enter to play a custom animation");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\4 - Demos, Game Basics\Game Basics\13 - Character Default Animations.txt
/******************************************************************************/
#include "stdafx.h"
#include "../../../../../data/enum/_enums.h"
/******************************************************************************/
struct Chr : Game::Chr
{
Int move_to; // index of Waypoint point to move to
virtual void create(Game::ObjParams &obj); // override default creation method to setup custom default animations after character creation
virtual Bool update(); // override default updating to set movement commands
Chr();
};
/******************************************************************************/
Game::ObjMemx<Game::Static> Statics ;
Game::ObjMemx< Chr > Chrs ;
Game::Waypoint *waypoint; // pointer to waypoint stored in world
/******************************************************************************/
Chr::Chr()
{
move_to=0;
}
void Chr::create(Game::ObjParams &obj)
{
__super::create(obj); // call default creation
// now when object has been created we can optionally override its default animations
// for example change it's walking animation
// to achieve this we need to change the default animation from characters skeleton animation cache 'Chr::sac'
// on the test map used with this tutorial, there are 2 characters human and a skeleton
// we'll replace the animation only for the skeleton character leaving human character with its default animation
// detect if current character is a skeleton
Bool is_skeleton=false;
for(Game::ObjParams *cur=&obj; cur; cur=cur->base()) // iterate through all ObjParams bases
if(CChar *name=Game::Objs(cur)) // if received the name of the object
if(Contains(name,"skeleton")) // if the object name contains "skeleton" word
{
is_skeleton=true;
break;
}
// replace the animation
if(is_skeleton) // only for the skeleton
{
sac.walk=&cskel.getSkelAnim("anim/custom/scary walk.anim"); // this will load the animation, cache it, and set into character's animation
}
move_walking=true; // order the characters to always move by walking instead of running
}
Bool Chr::update()
{
if(__super::update())
{
if(!action) // if not performing any action
{
if(waypoint && waypoint->points()) // if have waypoint with some points in it
{
move_to=(move_to+1)%waypoint->points(); // set variable to next point index
actionMoveTo(waypoint->point(move_to).pos); // order the character to move to the point position
}
}
return true;
}
return false;
}
/******************************************************************************/
void InitPre()
{
App.name("Character Default Animations");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).sync(true).shdMapSize(1024).shdMode(SHD_NONE).ambPower(0.3);
}
/******************************************************************************/
Bool Init()
{
Physics.create();
Sky .set ();
Suns .New ().set(*Gfxs("gfx/sky/sun.gfx")).light_color=1-D.ambColor();
// create the world
Game::World.init()
.setType(Statics,OBJ_STATIC)
.setType(Chrs ,OBJ_CHR )
.New ("world/animations");
// access the Waypoint
waypoint=Game::World.getWaypoint("0"); // load waypoint named "0" stored in current world
Cam.setSpherical(Vec(17,2,12),-0.4,-0.9,0,11).set(); // set initial camera
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Game::World.update(Cam.at);
CamHandle(0.1,100,CAMH_ZOOM|(Ms.b(1) ? CAMH_MOVE : CAMH_ROT));
return true;
}
/******************************************************************************/
void Render()
{
Game::World.draw();
}
void Draw()
{
Renderer(Render);
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\4 - Demos, Game Basics\Game Basics\14 - Character Facial Animations.txt
/******************************************************************************/
#include "stdafx.h"
#include "../../../../../data/enum/_enums.h"
/******************************************************************************/
struct Player : Game::Chr
{
virtual void animate(); // extend skeleton animation
virtual Bool update ();
// optionally you can override default 'face blend' value by defining your own function
virtual Flt animateFaceBlend();
};
/******************************************************************************/
void Player::animate()
{
__super::animate(); // call default animations
// facial animation
{
Flt blend=animateFaceBlend(); // get facial animation blending value
// this is a factor which determines the intensity of facial animations
// for example if the character is near the camera the blend is full (1.0) so facial animations will be performed normally
// and if the character is far away so face isn't visible very well, blending value will be disabled (0.0)
// disabling facial animations speeds up rendering process, so its visible only in some distance from camera
if(blend>0)
{
Flt time =Tm.time(),
smile_blend=1;
cskel.animate(L"anim/face/smile.anim",time,smile_blend*blend);
}
}
}
Flt Player::animateFaceBlend()
{
Flt distance =Dist(pos(),Cam.matrix.pos), // distance from camera
full_blend_range=1 , // custom range where the facial animation should be full (1 meter)
no_blend_range=1.5; // custom range where the facial animation should be disabled (1.5 meter)
return LerpRS(no_blend_range,full_blend_range,distance); // this will returned a saturated value 0..1
}
/******************************************************************************/
Bool Player::update()
{
if(action)
{
if(Kb.b(KB_W) || Kb.b(KB_S) || Kb.b(KB_A) || Kb.b(KB_D) || Kb.b(KB_Q) || Kb.b(KB_E))actionBreak();
}
if(!action)
{
// turn & move
input.anglei.x=Kb.b(KB_Q)-Kb.b(KB_E);
input.anglei.y=Kb.b(KB_T)-Kb.b(KB_G);
input.diri .x=Kb.b(KB_D)-Kb.b(KB_A);
input.diri .z=Kb.b(KB_W)-Kb.b(KB_S);
input.diri .y=Kb.b(KB_SPACE)-Kb.b(KB_LSHIFT);
// dodge, crouch, walk, jump
input.dodge = Kb.bd(KB_D)-Kb.bd(KB_A);
input.crouch= Kb.b (KB_LSHIFT);
input.walk = Kb.b (KB_LCTRL );
input.jump =(Kb.bp(KB_SPACE ) ? 3.5 : 0);
// mouse turn
Flt max=DegToRad(900)*Tm.d(),
dx =Ms.dir_ds.x*1.7,
dy =Ms.dir_ds.y*1.7*Ms.inv();
angle.x-=Mid(dx,-max,max);
angle.y+=Mid(dy,-max,max);
// ready stance change
ready^=Kb.bp(KB_R);
}
return __super::update();
}
/******************************************************************************/
Game::ObjMemx<Game::Static> Statics; // container for static objects
Game::ObjMemx< Player> Players; // container for player objects
/******************************************************************************/
void InitPre()
{
App.name("Character Facial Animation");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).sync(true).shdMapSize(1024).shdSoft(1).ambPower(0.3).hpRt(true);
ViewportFull.range=20;
}
/******************************************************************************/
Bool Init()
{
Physics.create();
Sky .set ();
Sun &sun=Suns.New(); sun.set(*Gfxs("gfx/sky/sun.gfx")).light_color=1-D.ambColor(); sun.rays.mode=SUN_RAYS_HIGH;
// create the world
Game::World.init()
.setType(Statics,OBJ_STATIC)
.setType(Players,OBJ_CHR )
.New ("world/sample" );
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Game::World.update(Cam.at);
if(Players.elms())Cam.setSpherical(Players[0].cskel.getPoint("Head").pos,Players[0].angle.x+PI,-Players[0].angle.y,0,Max(0.1f,Cam.dist*ScaleFactor(Ms.wheel*-0.2))).updateVelocities().set();
return true;
}
/******************************************************************************/
void Render()
{
Game::World.draw();
}
void Draw()
{
Renderer(Render);
if(Players.elms())D.text(0,0.9,S+"Facial blending factor for Players[0] is: "+Players[0].animateFaceBlend());
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\4 - Demos, Game Basics\Game Basics\15 - Character Ragdoll.txt
/******************************************************************************/
#include "stdafx.h"
#include "../../../../../data/enum/_enums.h"
/******************************************************************************/
Game::ObjMemx<Game::Static> Statics; // container for static objects
Game::ObjMemx<Game::Chr > Chrs ; // container for player objects
/******************************************************************************/
void InitPre()
{
App.name("Character Ragdoll");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).sync(true).shdMapSize(1024).shdSoft(1).ambPower(0.3);
ViewportFull.range=30;
Cam.at.set(16,0,16);
Cam.yaw =-PI_4;
Cam.pitch =-0.5;
Cam.dist =4;
}
/******************************************************************************/
Bool Init()
{
Physics.create();
Sky .set ();
Suns .New ().set(*Gfxs("gfx/sky/sun.gfx")).light_color=1-D.ambColor();
// create the world
Game::World.init()
.setType(Statics,OBJ_STATIC)
.setType(Chrs ,OBJ_CHR )
.New ("world/sample" );
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Game::World.update(Cam.at);
if(Chrs.elms())
{
Game::Chr &chr=Chrs[0];
if(Kb.bp(KB_1))chr.ragdollEnable (); // switch to ragdoll
if(Kb.bp(KB_2))chr.ragdollDisable(); // switch to skeleton animation
if(Kb.bp(KB_Q))if(chr.ragdollBlend())if(Actor *actor=chr.ragdoll.findActor("Head" ))actor->addVel(Vec(0,0,3));
if(Kb.bp(KB_W))if(chr.ragdollBlend())if(Actor *actor=chr.ragdoll.findActor("Body" ))actor->addVel(Vec(0,0,3));
if(Kb.bp(KB_E))if(chr.ragdollBlend())if(Actor *actor=chr.ragdoll.findActor("FootR"))actor->addVel(Vec(0,0,4));
if(Kb.bp(KB_R))if(chr.ragdollBlend())if(Actor *actor=chr.ragdoll.findActor("HandR"))actor->addVel(Vec(0,0,4));
Cam.setSpherical(chr.pos(),Cam.yaw-Ms.d.x,Cam.pitch+Ms.d.y,0,Max(0.1f,Cam.dist*ScaleFactor(Ms.wheel*-0.2))).updateVelocities().set();
}
return true;
}
/******************************************************************************/
void Render()
{
Game::World.draw();
}
void Draw()
{
Renderer(Render);
D.text(0,0.9,"Press 1,2 to switch between skeleton<->ragdoll animation");
D.text(0,0.8,"Press q,w,e,r to simulate shot hits");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\4 - Demos, Game Basics\Game Basics\16 - Camera Modes.txt
/******************************************************************************/
#include "stdafx.h"
#include "../../../../../data/enum/_enums.h"
/******************************************************************************
Here we'll present how to properly use different camera modes
/******************************************************************************/
// Define viewing modes:
enum VIEW_MODE // Viewing Mode
{
VIEW_FPP, // First Person
VIEW_TPP, // Third Person
VIEW_ISO, // Isometric
VIEW_NUM, // number of view modes
};
U32 View; // current VIEW_MODE
/******************************************************************************/
struct Player : Game::Chr
{
virtual Bool update();
virtual void draw(); // extend drawing to disable head rendering in FPP mode
};
/******************************************************************************/
Game::ObjMemx<Game::Static> Statics; // container for static objects
Game::ObjMemx<Game::Item > Items ; // container for item objects
Game::ObjMemx< Player> Players; // container for player objects
/******************************************************************************/
Bool Player::update()
{
if(action)
{
if(Kb.b(KB_W) || Kb.b(KB_S) || Kb.b(KB_A) || Kb.b(KB_D) || Kb.b(KB_Q) || Kb.b(KB_E))actionBreak();
}
if(!action)
{
// turn & move
input.anglei.x=Kb.b(KB_Q)-Kb.b(KB_E);
input.anglei.y=Kb.b(KB_T)-Kb.b(KB_G);
input.diri .x=Kb.b(KB_D)-Kb.b(KB_A);
input.diri .z=Kb.b(KB_W)-Kb.b(KB_S);
input.diri .y=Kb.b(KB_SPACE)-Kb.b(KB_LSHIFT);
// dodge, crouch, walk, jump
input.dodge = Kb.bd(KB_D)-Kb.bd(KB_A);
input.crouch= Kb.b (KB_LSHIFT);
input.walk = Kb.b (KB_LCTRL );
input.jump =(Kb.bp(KB_SPACE ) ? 3.5 : 0);
// mouse turn
if(View!=VIEW_ISO) // don't use mouse turning when in Isometric mode
{
Flt max=DegToRad(900)*Tm.d(),
dx =Ms.dir_ds.x*1.7,
dy =Ms.dir_ds.y*1.7*Ms.inv();
angle.x-=Mid(dx,-max,max);
angle.y+=Mid(dy,-max,max);
}
// ready stance change
ready^=Kb.bp(KB_R);
}
return __super::update();
}
void Player::draw()
{
Bool disable_head_draw=(View==VIEW_FPP && Renderer()!=RM_SHD_MAP && mesh); // disable drawing head when we're in FPP mode and we're not in shadowing mode (if this isn't included player will cast head-less shadows)
if(disable_head_draw)mesh->hide("head"); // hide "head" mesh part in 'mesh'
__super::draw(); // call default drawing
if(disable_head_draw)mesh->show("head"); // un-hide "head" mesh part, so other objects which use the same mesh will have the head rendered properly
}
/******************************************************************************/
void InitPre()
{
App.name("Camera Modes");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).sync(true).shdMapSize(1024).ambPower(0.3).hpRt(true);
}
/******************************************************************************/
Bool Init()
{
Physics.create();
Sky .set ();
Sun &sun=Suns.New(); sun.set(*Gfxs("gfx/sky/sun.gfx")).light_color=1-D.ambColor(); sun.rays.mode=SUN_RAYS_HIGH;
// create the world
Game::World.init()
.setType(Statics,OBJ_STATIC)
.setType(Players,OBJ_CHR )
.setItem(Items ,OBJ_ITEM )
.New("world/sample" );
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Game::World.update(Cam.at);
// set next camera mode when Tab pressed
if(Kb.bp(KB_TAB))
{
View=(View+1)%VIEW_NUM;
if(View==VIEW_ISO) // when set to isometric view
{
Cam.dist = 10; // set bigger camera distance at start
Cam.pitch=-PI_4; // set starting camera pitch angle
}
}
// setup the camera
if(Players.elms()) // if we have at least one player
{
// set camera depending on current view mode
switch(View)
{
case VIEW_FPP:
{
OrientP &head=Players[0].cskel.getPoint("head"); // obtain player "head" skeleton point (this was created in Mesh Editor)
Cam.setPosDir(head.pos,head.dir,head.perp); // set camera from 'head' position, direction and perpendicular to direction
}break;
case VIEW_TPP:
{
Cam.dist=Max(1.0f,Cam.dist*ScaleFactor(Ms.wheel*-0.1)); // update camera distance according to mouse wheel
Cam.setSpherical(Players[0].pos()+Vec(0,0.5,0), Players[0].angle.x, Players[0].angle.y, 0, Cam.dist); // set spherical camera looking at player position with given player angles
}break;
default: // VIEW_ISO
{
Cam.yaw -=Ms.ds.x; // update camera yaw angle according to mouse smooth delta x
Cam.pitch+=Ms.ds.y; // update camera pitch angle according to mouse smooth delta y
Clamp(Cam.pitch,-PI_2,0); // clamp to possible camera pitch angle
Cam.dist =Max(1.0f,Cam.dist*ScaleFactor(Ms.wheel*-0.1)); // update camera distance according to mouse wheel
Cam.setSpherical(Players[0].pos(), Cam.yaw, Cam.pitch, 0, Cam.dist); // set spherical camera looking at player using camera angles
}break;
}
// after setting camera position and angles:
Cam.updateVelocities().set(); // update camera velocities and activate it
}
else // when no player on the scene
{
CamHandle(0.1,100,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT)); // default camera handling actions
}
return true;
}
/******************************************************************************/
void Render()
{
Game::World.draw();
}
void Draw()
{
Renderer(Render);
D.text (0,0.9,"Press Tab to switch camera modes");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\4 - Demos, Game Basics\Game Basics\17 - Camera Collisions.txt
/******************************************************************************/
#include "stdafx.h"
#include "../../../../../data/enum/_enums.h"
/******************************************************************************
Here we'll present how to detect camera collisions
/******************************************************************************/
struct Player : Game::Chr
{
virtual Bool update();
};
/******************************************************************************/
Camera desired_camera; // create a helper desired camera
/******************************************************************************/
Game::ObjMemx<Game::Static> Statics;
Game::ObjMemx<Game::Item > Items ;
Game::ObjMemx< Player> Players;
/******************************************************************************/
Bool Player::update()
{
if(action)
{
if(Kb.b(KB_W) || Kb.b(KB_S) || Kb.b(KB_A) || Kb.b(KB_D) || Kb.b(KB_Q) || Kb.b(KB_E))actionBreak();
}
if(!action)
{
// turn & move
input.anglei.x=Kb.b(KB_Q)-Kb.b(KB_E);
input.anglei.y=Kb.b(KB_T)-Kb.b(KB_G);
input.diri .x=Kb.b(KB_D)-Kb.b(KB_A);
input.diri .z=Kb.b(KB_W)-Kb.b(KB_S);
input.diri .y=Kb.b(KB_SPACE)-Kb.b(KB_LSHIFT);
// dodge, crouch, walk, jump
input.dodge = Kb.bd(KB_D)-Kb.bd(KB_A);
input.crouch= Kb.b (KB_LSHIFT);
input.walk = Kb.b (KB_LCTRL );
input.jump =(Kb.bp(KB_SPACE ) ? 3.5 : 0);
// ready stance change
ready^=Kb.bp(KB_R);
}
return __super::update();
}
/******************************************************************************/
void InitPre()
{
App.name("Camera Collisions");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).sync(true).shdMapSize(1024).ambPower(0.3).hpRt(true);
}
/******************************************************************************/
Bool Init()
{
Physics.create();
Sky .set ();
Sun &sun=Suns.New(); sun.set(*Gfxs("gfx/sky/sun.gfx")).light_color=1-D.ambColor(); sun.rays.mode=SUN_RAYS_HIGH;
// create the world
Game::World.init()
.setType(Statics,OBJ_STATIC)
.setType(Players,OBJ_CHR )
.setItem(Items ,OBJ_ITEM )
.New("world/sample" );
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
Game::World.update(Cam.at);
// setup the camera
if(Players.elms()) // if we have at least one player
{
// first setup the desired camera as in the previous tutorials
desired_camera.yaw -=Ms.ds.x; // update camera yaw angle according to mouse smooth delta x
desired_camera.pitch+=Ms.ds.y; // update camera pitch angle according to mouse smooth delta y
Clamp(desired_camera.pitch,-PI_2,PI_4); // clamp to possible camera pitch angle
desired_camera.dist=Max(1.0f,desired_camera.dist*ScaleFactor(Ms.wheel*-0.1)); // update camera distance according to mouse wheel
desired_camera.at =Players[0].pos();
desired_camera.setSpherical(); // set as spherical from current values, this will set the camera's matrix (desired_camera.matrix)
// now what we'll do is cast a small sized Ball from starting position to target camera destination
// we'll stop the ball at first contact point, and set camera at that place
// create a helper ball which will be used for collision detection
Ball ball(0.1f, desired_camera.at); // we place it at starting point (where the camera is looking at)
// now we'll move the ball in the direction where the camera should be
Physics.move(ball, desired_camera.matrix.pos-ball.pos); // use physics move to move the ball as far as it can go without any collisions
// now the ball.pos is located at either maximum movement distance or at nearest collision point
// having ball's position we can now set the final camera position
Cam.setPosDir(ball.pos, desired_camera.matrix.z, desired_camera.matrix.y); // we'll use desired_camera.matrix directions which were set in 'setSpherical' camera method
Cam.updateVelocities().set(); // update camera velocities and activate it
}
else // when no player on the scene
{
CamHandle(0.1,100,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT)); // default camera handling actions
}
return true;
}
/******************************************************************************/
void Render()
{
Game::World.draw();
}
void Draw()
{
Renderer(Render);
D.text(0,0.9,"Try to move the camera around");
D.text(0,0.8,"and see how it gets blocked by the terrain");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\4 - Demos, Game Basics\Game Basics\18 - Object References.txt
/******************************************************************************/
#include "stdafx.h"
/******************************************************************************
In this tutorial is presented how to properly use references to world objects using 'Reference' class.
Let's assume a Character wants to reference an Item
So first let's think how we would do this the easy way:
Add a pointer to an item?
struct Chr : Game::Chr
{
Item *item;
...
This looks ok, but what happens if 'item' points to the Item object,
and then during a Game Update, the Item Object is removed/deleted.
For example another player picked up the item,
so item's memory address has moved to a inventory container.
Or the item has become too far from the center of action,
that the world had to flush the item object to a temporary file on the disk.
In that scenario 'Chr::item' still points to a memory address but at which
there is no original Item.
This means that additional caution needs to be taken.
To solve this problem we'll use object's 'id' value.
Before going any further let's sum up how objects are handled in the world:
-When each object is created it has its 'id' set to a random value different than zero
-When each object is deleted its 'id' is set to zero
-Object's 'id' values are saved and loaded in SaveGame
-After removing/deleting a world object, its memory is still accessible, but:
-it's not used at all ('id' value is zero)
-it's used but by another object created later ('id' value is set to new object's 'id')
So to properly reference an object we must store a pointer to its memory and its 'id',
in case the referenced objects memory will be used by another object later with another 'id'.
For this - 'Reference' class is used which stores a pointer and an 'id'.
So for example let's use a World Character and a World Item.
The Character will hold a reference to the item as 'desired_item'.
/******************************************************************************/
#include "../../../../../data/enum/_enums.h"
/******************************************************************************/
struct Chr : Game::Chr // extend default character
{
Reference<Game::Item> desired_item; // add a new parameter, which is a reference to an item (something like 'Item *desired_item;')
// draw
void draw2D() // this is a helper method for drawing text on the screen
{
if(desired_item.valid()) // check if the reference is valid
{
Vec pos=desired_item().pos(); // referenced objects can be accessed using operator(), but only after validation using 'valid' method as above
D.text(0,0.8,S+"My desired item is at: ("+pos+") position");
}
else // if the reference has become invalid
{
D.text(0,0.8,"My desired item is gone"); // display a text that the reference is now invalid
}
}
// handle saving and loading, following methods are needed only for saving and loading the Reference
void save(File &f)
{
__super::save(f);
desired_item.save(f); // save Reference
}
Bool load(File &f)
{
if(__super::load(f))
{
desired_item.load(f); // load Reference, here only the Reference 'id' is loaded, the pointer to the object is cleared because the object may not exist yet
// searching for the actual object will be performed later (inside 'linkReferences') after all objects have been loaded
return true;
}
return false;
}
void linkReferences() // this is called when all of the objects have been loaded
{
// in this method you should call 'link' on all references which the object contains
desired_item.link(); // by calling 'link' the world manager will try to find the referenced object according to the 'id', and store its pointer into the Reference
}
};
/******************************************************************************/
Game::ObjMemx<Game::Static> Statics;
Game::ObjMemx<Game::Item > Items ;
Game::ObjMemx< Chr > Chrs ;
/******************************************************************************/
void InitPre()
{
App.name("Object References");
App.flag=APP_MS_EXCLUSIVE|APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).sync(true).shdMapSize(1024);
Cam.dist =10;
Cam.yaw =-PI_4;
Cam.pitch=-0.5;
Cam.at.set(16,0,16);
}
/******************************************************************************/
Bool Init()
{
Physics.create();
Game::World.init()
.setType(Statics,OBJ_STATIC)
.setItem(Items ,OBJ_ITEM )
.setType(Chrs ,OBJ_CHR )
.New ("world/sample" );
// after loading the world, let's set the 'desired_item' for the Character
{
Game::World.update(Cam.at); // first world needs to be updated to a location to make sure that objects at that location are loaded
if(Chrs.elms() && Items.elms()) // now check if the world has at least one character and one item
Chrs[0].desired_item=Items[0]; // set the Character's reference to point to the first Item (this stores the item's memory address and its 'id')
}
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,100,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
if(Kb.bp(KB_F2))Game::World.save("LocalData/save.sav"); // save game
if(Kb.bp(KB_F3))Game::World.load("LocalData/save.sav"); // load game
Game::World.update(Cam.at);
if(Kb.bp(KB_SPACE) && Items.elms()) // when space pressed and if World Items has elements
Items.removeValid(0); // remove 0-th item
return true;
}
/******************************************************************************/
void Render()
{
Game::World.draw();
switch(Renderer())
{
case RM_LIGHT:
LightDir(!Vec(1,-1,1)).add();
break;
}
}
void Draw()
{
Renderer(Render);
D.text(0,0.9,"Press Space to remove the item");
if(Chrs.elms())Chrs[0].draw2D(); // draw characters text
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\4 - Demos, Game Basics\Game Basics\19 - Small Overlays.txt
/******************************************************************************/
#include "stdafx.h"
#include "../../../../../data/enum/_enums.h"
/******************************************************************************/
struct Marker2 : Marker // create a helper class which bases on Marker and uses time fading
{
Flt time; // time left until overlay fades out
Marker2()
{
time=10; // default time is 10 seconds for an overlay to live
}
Bool update()
{
time-=Tm.d(); // decrease time left
return time<=0 ; // if there is no time left then return true (which means that the overlay can be deleted)
}
void draw(Matrix &matrix)
{
Marker::draw(matrix,Sat(time)); // draw the overlay with transparency of 'Saturate(time)' value
}
// io
void save(File &f)
{
Marker::save(f);
f<<time;
}
Bool load(File &f)
{
if(Marker::load(f))
{
f>>time;
return true;
}
return false;
}
};
/******************************************************************************/
struct Item : Game::Item // extend items
{
Memb<Marker2> marker; // add marker, which is used for rendering semi transparent images on solid surfaces
virtual Bool update(); // extend updating to include 'marker' update
virtual void draw (); // extend drawing to include rendering of 'marker'
// io
virtual void save(File &f); // extend saving to include members saving
virtual Bool load(File &f); // extend loading to include members loading
// operations
void addBulletHole(Vec &pos,Vec &surface_normal,Vec &shot_dir); // helper method for adding a bullet hole (Marker) onto the item mesh
};
/******************************************************************************/
Game::ObjMemx<Item> Items;
/******************************************************************************/
// ITEM
/******************************************************************************/
Bool Item::update()
{
if(__super::update())
{
REPA(marker)if(marker[i].update()) // update all overlays
marker.remove(i,true); // and remove them if they faded out
return true;
}
return false;
}
/******************************************************************************/
void Item::draw()
{
__super::draw(); // call default drawing
switch(Renderer())
{
case RM_OVERLAY: // overlays need to be rendered in RM_OVERLAY mode
REPAO(marker).draw(matrixScaled()); // draw mesh_overlays with the same matrix used for default item drawing
break;
}
}
/******************************************************************************/
void Item::save(File &f)
{
__super::save(f);
marker.save(f);
}
Bool Item::load(File &f)
{
if(__super::load(f))
{
return marker.load(f);
}
return false;
}
/******************************************************************************/
void Item::addBulletHole(Vec &pos,Vec &surface_normal,Vec &shot_dir)
{
// add a marker to the item
marker.New().set(WHITE,0,*Gfxs("gfx/hole/bullet.gfx"),0.1f,0.05f,0.05f).matrix(matrixScaled(),Matrix().setPosDir(pos,surface_normal));
// add impulse to the actor
actor.addImpulse(shot_dir * 1.5f,pos);
}
/******************************************************************************/
// MAIN
/******************************************************************************/
void InitPre()
{
App.name("Small Overlays");
App.flag=APP_FULL_TOGGLE|APP_MS_EXCLUSIVE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).sync(true).shdMapSize(1024).ambPower(0.3);
ViewportFull.range=70;
Cam.at.set(16,2,12);
Cam.dist = 0.01;
Cam.pitch=-0.2f;
}
/******************************************************************************/
Bool Init()
{
Physics.create();
Sky .set ();
Sun &sun=Suns.New(); sun.set(*Gfxs("gfx/sky/sun.gfx")).light_color=1-D.ambColor(); sun.rays.mode=SUN_RAYS_HIGH;
Game::World.init ( )
.setItem(Items,OBJ_ITEM )
.New ("world/custom params");
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
// update the camera FPP 'WSAD' style
if(Kb.b(KB_A ))Cam.at-=Cam.matrix.x*Tm.d()*2;
if(Kb.b(KB_D ))Cam.at+=Cam.matrix.x*Tm.d()*2;
if(Kb.b(KB_S ))Cam.at-=Cam.matrix.z*Tm.d()*2;
if(Kb.b(KB_W ))Cam.at+=Cam.matrix.z*Tm.d()*2;
if(Kb.b(KB_LSHIFT))Cam.at-=Vec(0,1,0) *Tm.d()*2;
if(Kb.b(KB_SPACE ))Cam.at+=Vec(0,1,0) *Tm.d()*2;
CamHandle(0.01,0.01,CAMH_ROT); // allow only rotation
Game::World.update(Cam.at);
if(Ms.bp(0)) // on LMB pressed
{
// calculate world position and direction vectors
Vec pos, dir; ScreenToPosDir(Vec2(0,0),pos,dir);
PhysHit phys_hit; if(Physics.ray(pos,dir*Viewport.range,&phys_hit)) // if ray test hit an actor
{
if(phys_hit.obj) // if the actor comes from an object
{
if(Item *item=CAST(Item,phys_hit.obj)) // if the object is an item
{
item->addBulletHole(phys_hit.plane.p, phys_hit.plane.n, dir); // call item method to add a bullet hole
}
}
else // the actor doesn't have an object set, so most probably it's a terrain actor
{
// add a marker to the world terrain
Game::World.terrainAddMarker(WHITE,0,*Gfxs("gfx/hole/bullet.gfx"),Matrix().setPosDir(phys_hit.plane.p, phys_hit.plane.n),0.1f,0.05f,0.05f);
}
}
}
return true;
}
/******************************************************************************/
void Render()
{
Game::World.draw();
}
void Draw()
{
Renderer(Render);
D.text(0,0.9,"Press LMB to shoot");
// draw simple crosshair
D.lineX(WHITE, 0, -0.08f,0.08f);
D.lineY(WHITE, 0, -0.08f,0.08f);
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\4 - Demos, Game Basics\Game Basics\20 - Big Overlays.txt
/******************************************************************************/
#include "stdafx.h"
#include "../../../../../data/enum/_enums.h"
/******************************************************************************/
struct MeshOverlay2 : MeshOverlay // create a helper class which bases on MeshOverlay and uses time fading
{
Flt time; // time left until overlay fades out
MeshOverlay2()
{
time=10; // default time is 10 seconds for an overlay to live
}
Bool update()
{
time-=Tm.d(); // decrease time left
return time<=0 ; // if there is no time left then return true (which means that the overlay can be deleted)
}
void draw(Matrix &matrix)
{
MeshOverlay::draw(matrix,Sat(time)); // draw the overlay with transparency of 'Saturate(time)' value
}
// io
void save(File &f)
{
MeshOverlay::save(f);
f<<time;
}
Bool load(File &f)
{
if(MeshOverlay::load(f))
{
f>>time;
return true;
}
return false;
}
};
/******************************************************************************/
struct Item : Game::Item // extend items
{
I32 type ; // ITEM_TYPE
Memb<MeshOverlay2> mesh_overlay; // add mesh overlay, which is used for rendering semi transparent images on solid surfaces
virtual void create(Game::ObjParams &obj); // extend creation to include accessing item type
virtual Bool update( ); // extend updating to include bomb explosion, and 'mesh_overlay' update
virtual void draw ( ); // extend drawing to include rendering of 'mesh_overlay'
// io
virtual void save(File &f); // extend saving to include members saving
virtual Bool load(File &f); // extend loading to include members loading
Item();
};
/******************************************************************************/
Memb<ExplosionFx> explosion;
Game::ObjMemx<Item> Items;
/******************************************************************************/
void CreateExplosion(Vec &pos) // helper function for creating an explosion at given position
{
// add an earthquake effect
QuakeFx.addMedium();
// create a new explosion effect
explosion.New().create(Gfxs("gfx/particle/explosion/0.gfx"),Gfxs("gfx/particle/explosion/1.gfx"),0x00600000,32,pos,3);
// set overlay parameters
Flt overlay_angle=RandomF(PI2),
overlay_scale=RandomF(4,7);
Gfx &overlay_gfx =*Gfxs("gfx/hole/bomb.gfx");
// add terrain overlay
Matrix m;
m.setPosDir (pos,Vec(0,-1,0)); // set position and direction
m.orn.rotateZVec(overlay_angle ); // rotate along matrix z axis
m.scaleOrn (overlay_scale ); // scale the overlay
Game::World.terrainAddOverlay(WHITE,0,overlay_gfx,m);
Memb<Game::Obj*> objects;
Game::World.objQuery(objects,Ball(overlay_scale*SQRT3+1,pos),OBJ_ITEM); // get objects in explosion radius
REPA(objects)if(Item *item=CAST(Item,objects[i])) // process world items to add overlays and apply forces to actors
{
// apply forces to item actors
Actor &actor=item->actor;
Vec dir =actor.pos()-pos; // get difference between actor position and explosion position
Flt dist =dir.normalize(); // normalize direction and store its previous length into 'dist'
dist*=dist; // distance is now equal to squared distance
if(dist)actor.addImpulse(30 * dir / dist); // final equation for impulse = (power) * (normalized direction) / (distance^2)
// set mesh overlay for item
if(item->mesh)
{
m.orn.setDir (dir);
m.orn.rotateZVec(overlay_angle);
m.scaleOrn (overlay_scale);
if(!item->mesh_overlay.New().create(*item->mesh,overlay_gfx,m,&item->matrixScaled()))item->mesh_overlay.removeLast();
}
}
}
/******************************************************************************/
// ITEM
/******************************************************************************/
Item::Item()
{
type=ITEM_NONE;
}
/******************************************************************************/
void Item::create(Game::ObjParams &obj)
{
__super::create(obj);
if(Game::Param *param=obj.findParam("type"))type=param->asEnum(); // get item type from .obj file
}
/******************************************************************************/
Bool Item::update()
{
if(__super::update())
{
if(type==ITEM_MISSILE) // if this is a missile
{
Vec vec=actor.vel(); vec*=Tm.d()*3;
if(actor.sweep(vec)) // if the missile actor has encountered an obstacle along the way
{
CreateExplosion(pos()); // create explosion at bomb's position
return false; // return false which will delete the bomb Item
}
}
REPA(mesh_overlay)if(mesh_overlay[i].update()) // update all overlays
mesh_overlay.remove(i,true); // and remove them if they faded out
return true;
}
return false;
}
/******************************************************************************/
void Item::draw()
{
__super::draw(); // call default drawing
switch(Renderer())
{
case RM_OVERLAY: // mesh overlays need to be rendered in RM_OVERLAY mode
REPAO(mesh_overlay).draw(matrixScaled()); // draw mesh_overlays with the same matrix used for default item drawing
break;
}
}
/******************************************************************************/
void Item::save(File &f)
{
__super::save(f);
f<<type;
mesh_overlay.save(f);
}
Bool Item::load(File &f)
{
if(__super::load(f))
{
f>>type;
return mesh_overlay.load(f);
}
return false;
}
/******************************************************************************/
// MAIN
/******************************************************************************/
void InitPre()
{
App.name("Big Overlays");
App.flag=APP_FULL_TOGGLE|APP_MS_EXCLUSIVE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).sync(true).shdMapSize(1024).ambPower(0.3);
ViewportFull.range=70;
Cam.at.set(16,0,16);
Cam.dist = 28;
Cam.pitch=-PI_6;
}
/******************************************************************************/
Bool Init()
{
Physics.create();
Sky .set ();
Sun &sun=Suns.New(); sun.set(*Gfxs("gfx/sky/sun.gfx")).light_color=1-D.ambColor(); sun.rays.mode=SUN_RAYS_HIGH;
// increase default earthquake effect scale
QuakeFx.scale*=3;
Game::World.init ( )
.setItem(Items,OBJ_ITEM )
.New ("world/custom params");
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
CamHandle(0.1,100,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
Game::World.update(Cam.at);
// update earthquake effect
QuakeFx.update();
// update explosions
REPA(explosion)if(explosion[i].update())explosion.remove(i);
if(Kb.bp(KB_SPACE)) // on space pressed
{
// create a 'bomb' item
Game::ObjParams &bomb=*Game::Objs("obj/item/missile/bomb/0.obj");
Game::World.objCreate(bomb,Matrix().setPosUp(Vec(RandomF(13,19),14,RandomF(13,19)),Vec(0,-1,0)).scaleOrn(bomb.scale()*2));
}
return true;
}
/******************************************************************************/
void Render()
{
Game::World.draw();
switch(Renderer())
{
case RM_PALETTE:
REPA(explosion)explosion[i].draw(); // draw explosions
break;
}
}
void Draw()
{
Renderer(Render);
D.text(0,0.9,"Press Space to drop a Bomb");
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\5 - Projects (here all files from a single directory need to be included in project)\01 - Simple Project\Game.txt
/******************************************************************************/
#include "stdafx.h"
#include "Main.h"
/******************************************************************************/
Bool InitGame()
{
return true;
}
void ShutGame()
{
}
/******************************************************************************/
Bool UpdateGame()
{
if(Kb.bp(KB_ESC))StateMenu.set(1.0);
return true;
}
void DrawGame()
{
D.clear(TURQ);
D.text (0,0,"Game");
}
/******************************************************************************/
State StateGame(UpdateGame,DrawGame,InitGame,ShutGame);
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\5 - Projects (here all files from a single directory need to be included in project)\01 - Simple Project\Intro.txt
/******************************************************************************/
#include "stdafx.h"
#include "Main.h"
/******************************************************************************/
Bool InitIntro()
{
return true;
}
void ShutIntro()
{
}
/******************************************************************************/
Bool UpdateIntro()
{
if(StateActive->time()>3 || Kb.bp(KB_ESC))
StateMenu.set(1.0);
return true;
}
void DrawIntro()
{
D.clear(BLACK);
D.text (0,0,"Intro");
}
/******************************************************************************/
State StateIntro(UpdateIntro,DrawIntro,InitIntro,ShutIntro);
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\5 - Projects (here all files from a single directory need to be included in project)\01 - Simple Project\Main.txt
/******************************************************************************/
#include "stdafx.h"
#include "Main.h" // include the main header, which includes all other headers
/******************************************************************************/
void InitPre()
{
App.name("Simple Multi CPP Project");
IOPath("../data");
PakAdd("engine.pak");
}
Bool Init()
{
StateIntro.set();
return true;
}
void Shut()
{
}
/******************************************************************************/
Bool Main()
{
return true;
}
void Draw()
{
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\5 - Projects (here all files from a single directory need to be included in project)\01 - Simple Project\Menu.txt
/******************************************************************************/
#include "stdafx.h"
#include "Main.h"
/******************************************************************************/
Bool InitMenu()
{
return true;
}
void ShutMenu()
{
}
/******************************************************************************/
Bool UpdateMenu()
{
if(Kb.bp(KB_ESC))return false;
if(Kb.bp(KB_ENTER))StateGame.set(0.5);
return true;
}
void DrawMenu()
{
D.clear(GREY);
D.text (0, 0 ,"Menu");
D.text (0,-0.3,"Press Enter to start the game");
D.text (0,-0.5,"Press Escape to exit");
}
/******************************************************************************/
State StateMenu(UpdateMenu,DrawMenu,InitMenu,ShutMenu);
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\5 - Projects (here all files from a single directory need to be included in project)\02 - Inventory\Inventory Gui.txt
/******************************************************************************/
#include "stdafx.h"
#include "main.h"
/******************************************************************************/
InventoryGui InvGui;
/******************************************************************************/
// MANAGE
/******************************************************************************/
void InventoryGui::create()
{
// window
Gui+=window.create(Rect_R(D.w(),0,1,1.5f),"Inventory");
// slots
{
// background images
Flt w=0.11, // default unit width
s=0.03; // default unit spacing
Gfx *gfx=Gfxs("gfx/inventory/slot.gfx");
window+=slot_img[SLOT_HEAD ][0].create(Rect_U (window.crect.w()/2 , -0.05, w*2,w*2),gfx).desc("Head");
window+=slot_img[SLOT_BODY ][0].create(Rect_U (window.crect.w()/2 , slot_img[SLOT_HEAD][0].rect.min.y-s, w*2,w*3),gfx).desc("Body");
window+=slot_img[SLOT_ARM_L][0].create(Rect_RU(slot_img[SLOT_BODY][0].rect.min.x-s, slot_img[SLOT_BODY][0].rect.max.y , w*2,w*3),gfx).desc("Left Arm");
window+=slot_img[SLOT_ARM_R][0].create(Rect_LU(slot_img[SLOT_BODY][0].rect.max.x+s, slot_img[SLOT_BODY][0].rect.max.y , w*2,w*3),gfx).desc("Right Arm");
// item images
REPA(slot_img)if(i!=SLOT_TEMP)
{
window+=slot_img[i][1].create(slot_img[i][0].rect).desc(slot_img[i][0].desc()); slot_img[i][1].rect_color=0;
}
}
// region
{
Rect_LU rect(0,0,window.crect.w(),window.crect.h());
rect.max.y=rect.min.y+0.7f;
rect.extend(-0.05f);
window+=region.create(rect);
}
// list
{
ListGroup lg[]=
{
ListGroup(MEMBER(Item,icon ),0.2f,L"Icon" ), // 0
ListGroup(MEMBER(Item,name ),0.5f,L"Name" ), // 1
ListGroup(MEMBER(Item,power),0.2f,L"Power"), // 2
};
lg[2].precision=1; // set showing only 1 decimal precision for power float attribute
region+=list.create(lg,ELMS(lg));
list. cur_mode=LCM_MOUSE;
list.draw_mode=LDM_RECTS;
}
}
/******************************************************************************/
// OPERATIONS
/******************************************************************************/
void InventoryGui::link(Inventory *inv)
{
if(T.inv!=inv)
{
T.inv=inv;
if(inv)inv->inv_gui=this;
setGui();
}
}
/******************************************************************************/
void InventoryGui::setGui()
{
if(inv)
{
// set item list
{
// here we have to hide the items which are assigned to slots
// create a 'is' array which determines visibility of an element (1=visible, 0=hidden)
Byte *is=AllocN(Byte,inv->items.elms()); // allocate bytes for all items in container
SetMem(is,1,inv->items.elms()); // set memory to '1' (make all items visible by default)
REPA(inv->slot) // iterate through all slots
{
if(inv->slot[i].valid()) // if the slot is valid
{
Int index=inv->items.validIndex(&inv->slot[i]()); // get index of a slot item in items container
if(InRange(index,inv->items)) // if its valid
is[index]=0; // set visibility for item assigned to a slot to 0, to be hidden on the list
}
}
list.setData(inv->items,is); // set list data from items container and visibility list
Free(is); // free allocated memory
}
// set slot images
REP(SLOT_NUM) // for all slots
if(i!=SLOT_TEMP) // skip temporary slot because it's not drawn using 'Image' class
{
Image &img_back= slot_img[i][0], // background image, we use it for accessing its rectangle
&img_item= slot_img[i][1]; // item image
Reference<Item> & item=inv->slot [i] ; // item at slot
if(!item.valid())img_item.set(NULL);else // if there is no item then clear the item image slot
{
Gfx *icon=item().icon; // access item's icon
img_item.set(icon); // set slot image as the item's icon
if(icon) // set proper scaling
{
Vec2 size(icon->x(),icon->y()); size*=PIXEL_SIZE; // set default size
if(size.x>img_back.rect.w())size*=img_back.rect.w()/size.x; // clamp item size to background slot width
if(size.y>img_back.rect.h())size*=img_back.rect.h()/size.y; // clamp item size to background slot height
Rect rect(img_back.rect.center()); rect.extend(size/2);
img_item.setRect(rect);
}
}
}
}else
{
list.clear();
REP(SLOT_NUM)slot_img[i][1].set(NULL);
}
}
/******************************************************************************/
// UPDATE
/******************************************************************************/
void InventoryGui::update(Game::Chr &owner)
{
if(inv)
{
if(Ms.bp(0)) // if mouse button pressed
{
if(inv->slot[SLOT_TEMP].valid()) // if we have an item attached with mouse
{
if(Gui.ms==&list) // if mouse cursor is on the list
{
inv->slot[SLOT_TEMP].clear(); // clear the slot reference which will result in "putting back the item into the list"
setGui(); // update visuals
}else
if(Gui.ms==Gui.desktop || !Gui.ms) // if mouse cursor is on the desktop or nothing (this means the game world area)
{
owner.itemDropDown(inv->slot[SLOT_TEMP]()); // drop the item onto the world
}
}
else // we don't have an item so we want to get one
{
if(Gui.ms==&list) // from the list
{
if(Item *item=list())
{
inv->slot[SLOT_TEMP]=item;
setGui();
}
}
}
REP(SLOT_NUM)
if(Gui.ms==&slot_img[i][0] || Gui.ms==&slot_img[i][1]) // if we want to put the item onto the i-th slot
if(inv->slotsCanBeSwapped(SLOT_TEMP,i))
{
Swap(inv->slot[SLOT_TEMP],inv->slot[i]); // swap temporary with i-th slot
setGui(); // update visuals
}
}
}
}
/******************************************************************************/
// DRAW
/******************************************************************************/
void InventoryGui::draw()
{
if(inv && inv->slot[SLOT_TEMP].valid())inv->slot[SLOT_TEMP]().drawIcon(Ms.pos);
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\5 - Projects (here all files from a single directory need to be included in project)\02 - Inventory\Inventory.txt
/******************************************************************************/
#include "stdafx.h"
#include "main.h"
/******************************************************************************/
Inventory::~Inventory()
{
if(inv_gui)inv_gui->unlink();
}
/******************************************************************************/
// GET
/******************************************************************************/
Bool Inventory::slotCanBePutTo(Int src,Int dest)
{
if(!InRange(src,SLOT_NUM) || !InRange(dest,SLOT_NUM))return false;
if(slot[src].valid())switch(dest)
{
case SLOT_HEAD:
case SLOT_BODY:
if(slot[src]().type==ITEM_WEAPON)return false;
break;
}
return true;
}
Bool Inventory::slotsCanBeSwapped(Int a,Int b)
{
return slotCanBePutTo(a,b) && slotCanBePutTo(b,a);
}
/******************************************************************************/
// OPERATIONS
/******************************************************************************/
void Inventory::itemRemoved(Game::Item &item) // when an item is being removed from a character
{
// perform check if it is a equipped item
REPA(slot) // for all slots
if(slot[i]==item) // if i-th slot is set to item which is being removed
slot[i].clear(); // clear the slot so it can no longer be referenced to the removed item
}
void Inventory::itemRemoved( ){setGui();} // when item has been removed from a character
void Inventory::itemAdded (Game::Item &item){setGui();} // when item has been added to a character
void Inventory::setGui ( ){if(inv_gui)inv_gui->setGui();}
/******************************************************************************/
// UPDATE
/******************************************************************************/
void Inventory::update(Game::Chr &owner)
{
if(inv_gui)inv_gui->update(owner);
// set matrixes for items in hands
if(slot[SLOT_ARM_L].valid())
if(OrientP *point=owner.cskel.findPoint("HandL"))
slot[SLOT_ARM_L]().matrix(Matrix().setPosDir(point->pos,point->perp,point->dir));
if(slot[SLOT_ARM_R].valid())
if(OrientP *point=owner.cskel.findPoint("HandR"))
slot[SLOT_ARM_R]().matrix(Matrix().setPosDir(point->pos,point->perp,point->dir));
}
/******************************************************************************/
// DRAW
/******************************************************************************/
void Inventory::draw(Game::Chr &owner)
{
// draw items in hands
if(slot[SLOT_ARM_L].valid())slot[SLOT_ARM_L]().draw();
if(slot[SLOT_ARM_R].valid())slot[SLOT_ARM_R]().draw();
}
/******************************************************************************/
// IO
/******************************************************************************/
void Inventory::save(File &f)
{
FREPA(slot) // for all slots
f.putI32(items.validIndex(&slot[i]())); // store the valid index of i-th slot item in 'items' container
}
Bool Inventory::load(File &f)
{
FREPA(slot) // for all slots
{
Int item_index=f.getI32(); // read index of i-th slot in 'items' container
if(InRange(item_index,items)) // if the index is in valid range
slot[i]=items[item_index]; // set the slot to point to requested item
else
slot[i].clear(); // clear the item reference in i-th slot
}
setGui();
return true;
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\5 - Projects (here all files from a single directory need to be included in project)\02 - Inventory\Item.txt
/******************************************************************************/
#include "stdafx.h"
#include "main.h"
/******************************************************************************/
Item::Item()
{
name[0]=0;
type=ITEM_NONE;
power=0;
icon=NULL;
}
/******************************************************************************/
// MANAGE
/******************************************************************************/
void Item::create(Game::ObjParams &obj)
{
__super::create(obj);
// set name
if(Game::Param *p=obj.findParam("name"))Set(name,p->asStr());
// set type
if(Game::Param *p=obj.findParam("type"))type=p->asEnum();
// set power
if(Game::Param *p=obj.findParam("power"))power=p->asFlt();
// get icon
for(Game::ObjParams *op=&obj; op; op=op->base()) // iterate through all ObjParams, to find first with a valid icon
if(CChar *op_file_name=Game::Objs(op)) // if current ObjParams is stored in a file (the file name is not NULL)
if(icon=Gfxs.get(GetExtNot(op_file_name)+".ico.gfx")) // if there exists an icon with the same name as ObjParams but with different extension
break; // break
}
/******************************************************************************/
// DRAW
/******************************************************************************/
void Item::draw()
{
if(Lit==this && Renderer()==RM_SOLID)SetHighlight(0x303030); __super::draw();
if(Lit==this && Renderer()==RM_SOLID)SetHighlight(0);
}
/******************************************************************************/
void Item::drawIcon(Vec2 &pos)
{
if(icon)
{
icon->drawFit(pos.x,pos.y, icon->x()*PIXEL_SIZE, icon->y()*PIXEL_SIZE);
}
}
/******************************************************************************/
// IO
/******************************************************************************/
void Item::save(File &f)
{
__super::save(f);
f<<name<<power<<type;
f.putStr16(Gfxs(icon));
}
Bool Item::load(File &f)
{
if(__super::load(f))
{
f>>name>>power>>type;
icon=Gfxs(f.getStr16());
return true;
}
return false;
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\5 - Projects (here all files from a single directory need to be included in project)\02 - Inventory\Main.txt
/******************************************************************************/
#include "stdafx.h"
#include "main.h"
/******************************************************************************/
Game::Obj *Lit ; // highlighted world object
Game::ObjMemx<Item > Items ;
Game::ObjMemx<Player> Players;
/******************************************************************************/
void InitPre()
{
App.name("Inventory");
App.flag=APP_FULL_TOGGLE;
IOPath("../data");
PakAdd("engine.pak");
D.full(true).sync(true).shdMapSize(1024).ambPower(0.3);
ViewportFull.range=70;
Cam.at.set(16,0,16);
Cam.dist = 10;
Cam.pitch=-PI_6;
}
/******************************************************************************/
Bool Init()
{
Physics.create();
Sky .set ();
Sun &sun=Suns.New(); sun.set(*Gfxs("gfx/sky/sun.gfx")).light_color=1-D.ambColor(); sun.rays.mode=SUN_RAYS_HIGH;
Game::World.init ( )
.setType(Players,OBJ_CHR )
.setItem(Items ,OBJ_ITEM)
.New ("world/sample" );
InvGui.create();
// modify default gui visuals
Gui.style_window.blur_color=0xFF442200;
Gui.style_window.back_color=0xFFFF4400;
Gui.style_region.back_color=0x66000000;
Gui.kb_lit=0;
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
void GetWorldObjectUnderCursor()
{
Lit=NULL;
if(!Gui.ms || Gui.ms==Gui.desktop)
{
Vec pos,dir; ScreenToPosDir(Ms.pos,pos,dir);
PhysHit phys_hit; if(Physics.ray(pos,dir*Viewport.range,&phys_hit,1))Lit=phys_hit.obj;
}
}
/******************************************************************************/
Bool Main()
{
if(Kb.bp(KB_ESC))return false;
if(Players.elms())Cam.at=Players[0].pos();
CamHandle(0.1,100,CAMH_ZOOM|(Ms.b(1)?CAMH_ROT:0));
if(Kb.bp(KB_F2))Game::World.save("LocalData/save.sav");
if(Kb.bp(KB_F3))Game::World.load("LocalData/save.sav");
Game::World.update(Cam.at);
Gui.update();
GetWorldObjectUnderCursor();
return true;
}
/******************************************************************************/
void Render()
{
Game::World.draw();
}
void Draw()
{
Renderer(Render);
Gui .draw();
InvGui.draw();
}
/******************************************************************************/
ESENTHEL ENGINE SDK Advanced\5 - Projects (here all files from a single directory need to be included in project)\02 - Inventory\Player.txt
/******************************************************************************/
#include "stdafx.h"
#include "main.h"
/******************************************************************************/
Player::Player()
{
InvGui.link(&inv); // when creating a player automatically link him with InvGui
}
/******************************************************************************/
// UPDATE
/******************************************************************************/
Bool Player::update()
{
if(__super::update())
{
// detect if the player wants to pickup an item
if(Lit && Ms.bp(0)) // if hase highlighted object and mouse button pressed
if(Item *item=CAST(Item,Lit)) // if the object is an item
itemPickUp(*item); // pick it up
// update the inventory
inv.update(T);
return true;
}
return false;
}
/******************************************************************************/
// DRAW
/******************************************************************************/
void Player::draw()
{
__super::draw( );
inv.draw(T);
}
/******************************************************************************/
// IO
/******************************************************************************/
void Player::save(File &f)
{
__super::save(f);
inv.save(f);
}
Bool Player::load(File &f)
{
if(__super::load(f))
{
return inv.load(f);
}
return false;
}
/******************************************************************************/