2021-09-24 10:15:43 -04:00
# include "engine.h"
# include <algorithm>
# include <cmath>
2021-09-27 11:30:18 -04:00
# include "transformation.h"
2021-09-27 13:15:57 -04:00
# include "player.h"
2021-09-24 10:15:43 -04:00
2021-09-27 11:30:18 -04:00
Engine : : Engine ( ) { }
2021-09-24 10:15:43 -04:00
2021-09-27 11:30:18 -04:00
Engine : : ~ Engine ( ) { }
2021-09-24 10:15:43 -04:00
2021-11-30 19:55:11 -05:00
void Engine : : Init ( ) {
2021-10-11 11:37:58 -04:00
GLenum glewErr = glewInit ( ) ;
2021-10-12 15:58:54 -04:00
if ( glewErr ! = GLEW_OK ) {
2021-10-11 11:37:58 -04:00
std : : cerr < < " ERREUR GLEW : " < < glewGetErrorString ( glewErr ) < < std : : endl ;
abort ( ) ;
}
2021-09-27 10:20:58 -04:00
glClearColor ( 0.0f , 0.0f , 0.0f , 1.0f ) ;
glEnable ( GL_TEXTURE_2D ) ;
glMatrixMode ( GL_PROJECTION ) ;
glLoadIdentity ( ) ;
gluPerspective ( 45.0f , ( float ) Width ( ) / ( float ) Height ( ) , 0.0001f , 1000.0f ) ;
glEnable ( GL_DEPTH_TEST ) ;
glHint ( GL_PERSPECTIVE_CORRECTION_HINT , GL_NICEST ) ;
2021-11-30 19:55:11 -05:00
//glShadeModel(GL_SMOOTH);
2021-09-27 10:20:58 -04:00
glEnable ( GL_LIGHTING ) ;
glEnable ( GL_LINE_SMOOTH ) ;
2021-10-06 21:32:12 -04:00
glEnable ( GL_CULL_FACE ) ;
2021-11-30 19:55:11 -05:00
glDisable ( GL_FRAMEBUFFER_SRGB ) ;
glEnable ( GL_BLEND ) ;
glBlendFunc ( GL_CONSTANT_ALPHA , GL_ONE_MINUS_CONSTANT_ALPHA ) ;
2021-09-27 10:20:58 -04:00
// Light
2021-11-19 08:35:19 -05:00
GLfloat light0Pos [ 4 ] = { 0.0f , CHUNK_SIZE_Y , 0.0f , 1.0f } ;
2021-10-25 10:50:08 -04:00
GLfloat light0Amb [ 4 ] = { 0.2f , 0.2f , 0.2f , 1.f } ;
2021-09-27 14:45:59 -04:00
GLfloat light0Diff [ 4 ] = { 1.f , 1.f , 1.f , 1.f } ;
2021-09-27 10:20:58 -04:00
GLfloat light0Spec [ 4 ] = { 0.2f , 0.2f , 0.2f , 1.0f } ;
glEnable ( GL_LIGHT0 ) ;
glLightfv ( GL_LIGHT0 , GL_POSITION , light0Pos ) ;
glLightfv ( GL_LIGHT0 , GL_AMBIENT , light0Amb ) ;
glLightfv ( GL_LIGHT0 , GL_DIFFUSE , light0Diff ) ;
2021-11-19 08:35:19 -05:00
glLightfv ( GL_LIGHT0 , GL_SPECULAR , light0Spec ) ;
2021-09-27 10:20:58 -04:00
2021-11-30 19:55:11 -05:00
// Init manifeste de chunks render<65> s.
m_renderManifest . reserve ( 3000 ) ;
2021-10-12 15:58:54 -04:00
// Objet de skybox avec sa propre texture et son propre shader!
m_skybox . Init ( 0.00013f ) ;
2021-10-04 12:29:10 -04:00
2021-10-19 10:27:59 -04:00
// Objet de musique!
2021-11-30 19:55:11 -05:00
//m_audio.ToggleMusicState();
2021-11-15 20:58:13 -05:00
2021-11-16 20:48:52 -05:00
// Init Chunks
2021-11-19 11:11:08 -05:00
m_world . GetChunks ( ) . Reset ( nullptr ) ;
2021-11-02 18:01:06 -04:00
2021-10-31 00:31:08 -04:00
// Gestion de souris.
2021-09-27 10:20:58 -04:00
CenterMouse ( ) ;
HideCursor ( ) ;
2021-09-24 10:15:43 -04:00
}
2021-09-27 11:30:18 -04:00
void Engine : : DeInit ( ) { }
2021-09-24 10:15:43 -04:00
2021-09-27 11:30:18 -04:00
void Engine : : LoadResource ( ) {
2021-10-02 15:00:48 -04:00
LoadTexture ( m_textureFloor , TEXTURE_PATH " grass.png " ) ;
2021-10-12 15:58:54 -04:00
LoadTexture ( m_skybox . GetTexture ( ) , TEXTURE_PATH " skybox.png " ) ;
2021-10-26 17:28:37 -04:00
LoadTexture ( m_textureCrosshair , TEXTURE_PATH " cross.bmp " ) ;
LoadTexture ( m_textureFont , TEXTURE_PATH " font.bmp " ) ;
2021-10-31 00:31:08 -04:00
TextureAtlas : : TextureIndex texDirtIndex = m_textureAtlas . AddTexture ( TEXTURE_PATH " metal3.png " ) ;
TextureAtlas : : TextureIndex texIceIndex = m_textureAtlas . AddTexture ( TEXTURE_PATH " dirt.png " ) ;
TextureAtlas : : TextureIndex texGrassIndex = m_textureAtlas . AddTexture ( TEXTURE_PATH " grass.png " ) ;
TextureAtlas : : TextureIndex texMetalIndex = m_textureAtlas . AddTexture ( TEXTURE_PATH " metal.png " ) ;
2021-10-26 17:28:37 -04:00
2021-11-30 19:55:11 -05:00
if ( ! m_textureAtlas . Generate ( 512 , false ) ) {
2021-10-26 17:28:37 -04:00
std : : cout < < " Unable to generate texture atlas ... " < < std : : endl ;
abort ( ) ;
}
2021-10-11 11:37:58 -04:00
2021-10-31 00:31:08 -04:00
float u , v , s ;
m_textureAtlas . TextureIndexToCoord ( texDirtIndex , u , v , s , s ) ;
m_blockinfo [ BTYPE_DIRT ] = new BlockInfo ( BTYPE_DIRT , " Dirt " , u , v , s , 1 ) ;
m_textureAtlas . TextureIndexToCoord ( texGrassIndex , u , v , s , s ) ;
m_blockinfo [ BTYPE_GRASS ] = new BlockInfo ( BTYPE_GRASS , " Grass " , u , v , s , 1 ) ;
m_textureAtlas . TextureIndexToCoord ( texMetalIndex , u , v , s , s ) ;
m_blockinfo [ BTYPE_METAL ] = new BlockInfo ( BTYPE_METAL , " Metal " , u , v , s , 1 ) ;
m_textureAtlas . TextureIndexToCoord ( texIceIndex , u , v , s , s ) ;
m_blockinfo [ BTYPE_ICE ] = new BlockInfo ( BTYPE_ICE , " Ice " , u , v , s , 1 ) ;
2021-10-11 11:37:58 -04:00
std : : cout < < " Loading and compiling shaders ... " < < std : : endl ;
2021-10-12 15:58:54 -04:00
if ( ! m_shader01 . Load ( SHADER_PATH " shader01.vert " , SHADER_PATH " shader01.frag " , true ) ) {
2021-10-11 11:37:58 -04:00
std : : cout < < " Failed to load shader " < < std : : endl ;
exit ( 1 ) ;
}
2021-09-24 10:15:43 -04:00
2021-10-12 15:58:54 -04:00
if ( ! m_skybox . GetShader ( ) . Load ( SHADER_PATH " skybox.vert " , SHADER_PATH " skybox.frag " , true ) ) {
std : : cout < < " Failed to load shader " < < std : : endl ;
exit ( 1 ) ;
}
2021-09-24 10:15:43 -04:00
}
2021-11-15 20:58:13 -05:00
void Engine : : UnloadResource ( ) { }
2021-10-12 15:58:54 -04:00
2021-10-26 17:28:37 -04:00
void Engine : : DrawHud ( float elapsedTime ) {
// Setter le blend function , tout ce qui sera noir sera transparent
glDisable ( GL_LIGHTING ) ;
glColor4f ( 1.f , 1.f , 1.f , 1.f ) ;
glBlendFunc ( GL_SRC_ALPHA , GL_ONE ) ;
2021-11-30 19:55:11 -05:00
//glEnable(GL_BLEND);
2021-10-26 17:28:37 -04:00
glDisable ( GL_DEPTH_TEST ) ;
glMatrixMode ( GL_PROJECTION ) ;
glPushMatrix ( ) ;
glLoadIdentity ( ) ;
glOrtho ( 0 , Width ( ) , 0 , Height ( ) , - 1 , 1 ) ;
glMatrixMode ( GL_MODELVIEW ) ;
glPushMatrix ( ) ;
// Bind de la texture pour le font
m_textureFont . Bind ( ) ;
std : : ostringstream ss ;
ss < < " Fps : " < < GetFps ( elapsedTime ) ;
PrintText ( 10 , Height ( ) - 25 , ss . str ( ) ) ;
ss . str ( " " ) ;
2021-11-26 11:59:02 -05:00
ss < < " Rendered Chunks : " < < m_renderCount ;
PrintText ( 10 , Height ( ) - 35 , ss . str ( ) ) ;
ss . str ( " " ) ;
2021-11-30 19:55:11 -05:00
ss < < " Bad Hits on Chunks : " < < m_badHitCount ;
PrintText ( 10 , Height ( ) - 45 , ss . str ( ) ) ;
ss . str ( " " ) ;
2021-10-26 17:28:37 -04:00
ss < < " Velocity : " < < m_player . GetVelocity ( ) ; // IMPORTANT : on utilise l <20> operateur << pour afficher la position
PrintText ( 10 , 10 , ss . str ( ) ) ;
ss . str ( " " ) ;
ss < < " Direction : " < < m_player . GetDirection ( ) ;
PrintText ( 10 , 20 , ss . str ( ) ) ;
ss . str ( " " ) ;
ss < < " Position : " < < m_player . GetPosition ( ) ;
PrintText ( 10 , 30 , ss . str ( ) ) ;
2021-11-15 20:58:13 -05:00
ss . str ( " " ) ;
2021-11-16 20:48:52 -05:00
ss < < " CamPos : " < < m_player . GetPOV ( ) ;
2021-11-15 20:58:13 -05:00
PrintText ( 10 , 40 , ss . str ( ) ) ;
2021-10-26 17:28:37 -04:00
// Affichage du crosshair
m_textureCrosshair . Bind ( ) ;
static const int crossSize = 32 ;
glLoadIdentity ( ) ;
glTranslated ( Width ( ) / 2 - crossSize / 2 , Height ( ) / 2 - crossSize / 2 , 0 ) ;
glBegin ( GL_QUADS ) ;
2021-11-15 20:58:13 -05:00
glTexCoord2f ( 0 , 0 ) ;
2021-10-26 17:28:37 -04:00
glVertex2i ( 0 , 0 ) ;
glTexCoord2f ( 1 , 0 ) ;
glVertex2i ( crossSize , 0 ) ;
glTexCoord2f ( 1 , 1 ) ;
glVertex2i ( crossSize , crossSize ) ;
glTexCoord2f ( 0 , 1 ) ;
glVertex2i ( 0 , crossSize ) ;
glEnd ( ) ;
glEnable ( GL_LIGHTING ) ;
2021-11-30 19:55:11 -05:00
//glDisable(GL_BLEND);
//glBlendFuncSeparate(GL_SRC_COLOR, GL_ONE_MINUS_DST_COLOR, GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA);
glBlendFunc ( GL_CONSTANT_ALPHA , GL_ONE_MINUS_CONSTANT_ALPHA ) ;
2021-10-26 17:28:37 -04:00
glEnable ( GL_DEPTH_TEST ) ;
glMatrixMode ( GL_PROJECTION ) ;
glPopMatrix ( ) ;
glMatrixMode ( GL_MODELVIEW ) ;
glPopMatrix ( ) ;
}
void Engine : : PrintText ( unsigned int x , unsigned int y , const std : : string & t ) {
glLoadIdentity ( ) ;
glTranslated ( x , y , 0 ) ;
for ( unsigned int i = 0 ; i < t . length ( ) ; + + i ) {
float left = ( float ) ( ( t [ i ] - 32 ) % 16 ) / 16.f ;
float top = ( float ) ( ( t [ i ] - 32 ) / 16 ) / 16.f ;
top + = .5f ;
glBegin ( GL_QUADS ) ;
glTexCoord2f ( left , 1.f - top - .0625f ) ;
glVertex2f ( 0 , 0 ) ;
glTexCoord2f ( left + .0625f , 1.f - top - .0625f ) ;
glVertex2f ( 12 , 0 ) ;
glTexCoord2f ( left + .0625f , 1.f - top ) ;
glVertex2f ( 12 , 12 ) ;
glTexCoord2f ( left , 1.f - top ) ;
glVertex2f ( 0 , 12 ) ;
glEnd ( ) ;
glTranslated ( 8 , 0 , 0 ) ;
}
}
int Engine : : GetFps ( float elapsedTime ) const { return 1 / elapsedTime ; }
void Engine : : Render ( float elapsedTime ) {
2021-09-27 10:20:58 -04:00
static float gameTime = elapsedTime ;
2021-11-15 20:58:13 -05:00
if ( elapsedTime > 0.1f ) return ;
2021-09-27 10:20:58 -04:00
gameTime + = elapsedTime ;
2021-09-27 13:15:57 -04:00
Transformation all ;
2021-09-27 13:56:29 -04:00
Transformation skybox ;
2021-09-27 10:20:58 -04:00
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
// Transformations initiales
glMatrixMode ( GL_MODELVIEW ) ;
glLoadIdentity ( ) ;
2021-11-15 20:58:13 -05:00
m_player . ApplyPhysics ( m_player . GetInput ( m_keyW , m_keyS , m_keyA , m_keyD , m_keySpace , m_keylshift , elapsedTime ) , m_world , elapsedTime ) ;
2021-11-19 08:35:19 -05:00
m_audio . Update3DAudio ( m_player . GetPOV ( ) , m_player . GetDirection ( ) , m_player . GetVelocity ( ) ) ; // Ajustement du positionnement 3D avec les coordonn<6E> es du joueur et
2021-10-26 17:28:37 -04:00
// son vecteur de v<> locit<69> (pour l'effet Doppler)
2021-09-27 13:15:57 -04:00
m_player . ApplyTransformation ( all ) ;
2021-11-19 13:25:52 -05:00
2021-10-06 21:33:56 -04:00
m_player . ApplyTransformation ( skybox , false ) ; // Version d'ApplyTransformation qui ne tient compte que de la rotation
// (donc l'objet ne bouge pas relativement au joueur, ce qui est pratique pour une skybox!).
2021-11-30 19:55:11 -05:00
2021-10-25 10:50:08 -04:00
glDisable ( GL_LIGHT0 ) ;
2021-12-01 21:21:45 -05:00
if ( m_isSkybox ) m_skybox . Render ( skybox ) ;
2021-11-26 11:59:02 -05:00
glEnable ( GL_LIGHT0 ) ;
2021-11-30 19:55:11 -05:00
if ( m_mouseL )
ChangeBlockAtCursor ( BTYPE_DIRT ) ;
else if ( m_mouseR )
ChangeBlockAtCursor ( BTYPE_AIR ) ;
// G<> n<EFBFBD> ration/Update des Chunks.
2021-11-26 11:59:02 -05:00
m_textureAtlas . Bind ( ) ;
int cx = m_player . GetPosition ( ) . x ;
int cy = m_player . GetPosition ( ) . z ;
static int frameGenerate = 0 ;
static int frameUpdate = 0 ;
int side = 0 ;
2021-11-19 13:25:52 -05:00
2021-11-26 11:59:02 -05:00
if ( frameGenerate > 0 ) - - frameGenerate ;
if ( frameUpdate > 0 ) - - frameUpdate ;
if ( ! frameGenerate | | ! frameUpdate )
2021-11-30 19:55:11 -05:00
while ( side * CHUNK_SIZE_X < = VIEW_DISTANCE * 2 ) {
2021-11-26 11:59:02 -05:00
int tx = - side , ty = - side ;
for ( ; tx < = side ; + + tx )
UpdateWorld ( frameGenerate , frameUpdate , cx + tx * CHUNK_SIZE_X , cy + ty * CHUNK_SIZE_Z ) ;
for ( ; ty < = side ; + + ty )
UpdateWorld ( frameGenerate , frameUpdate , cx + tx * CHUNK_SIZE_X , cy + ty * CHUNK_SIZE_Z ) ;
for ( ; tx > = - side ; - - tx )
UpdateWorld ( frameGenerate , frameUpdate , cx + tx * CHUNK_SIZE_X , cy + ty * CHUNK_SIZE_Z ) ;
for ( ; ty > = - side ; - - ty )
UpdateWorld ( frameGenerate , frameUpdate , cx + tx * CHUNK_SIZE_X , cy + ty * CHUNK_SIZE_Z ) ;
2021-11-19 13:25:52 -05:00
2021-11-26 11:59:02 -05:00
+ + side ;
}
2021-11-19 13:25:52 -05:00
2021-11-30 19:55:11 -05:00
// Rendering des Chunks.
m_shader01 . Use ( ) ;
m_renderCount = 0 ;
m_badHitCount = 0 ;
Vector3f angle ;
Vector3f cursor ;
Vector3f direct = m_player . GetDirection ( ) ;
Vector3f pos = m_player . GetPosition ( ) - direct ;
direct . y = 0 ;
direct . Normalize ( ) ;
pos . y = 1 ;
m_renderManifest . clear ( ) ;
for ( int dist = VIEW_DISTANCE ; dist > = 0 ; dist - = CHUNK_SIZE_X ) {
// Configuration du radar.
angle . x = direct . z + direct . x ;
angle . y = 0 ;
angle . z = direct . z - direct . x ;
angle . Normalize ( ) ;
float sinus = .01745240643 ; // sin(1 degr<67> )
float cosinus = .99984769515 ; // cos(1 degr<67> )
int echantillons = 90 ;
for ( int radar = 0 ; radar < echantillons ; + + radar ) {
float x = angle . x ;
float z = angle . z ;
angle . x = x * cosinus - z * sinus ;
angle . z = z * cosinus + x * sinus ;
angle . Normalize ( ) ;
cursor = pos - direct * CHUNK_SIZE_X * 2 + angle * dist ;
if ( cursor . y > = 128.f | | cursor . y > = 0.f ) cursor . y = 1 ;
bool valide = true ;
if ( m_world . ChunkAt ( cursor ) ) {
int chx , chy ;
m_world . ChunkAt ( cursor ) - > GetPosition ( chx , chy ) ;
for ( int index = 0 ; index < m_renderManifest . size ( ) ; + + index )
if ( m_renderManifest [ index ] = = Vector3i ( chx , 0 , chy ) ) {
valide = false ;
+ + m_badHitCount ;
2021-11-27 13:35:39 -05:00
}
2021-11-26 11:59:02 -05:00
2021-11-30 19:55:11 -05:00
if ( valide ) {
all . ApplyTranslation ( chx * CHUNK_SIZE_X , 0 , chy * CHUNK_SIZE_Z ) ;
all . Use ( ) ;
float dist = ( pos - cursor ) . Length ( ) ;
float blend = ( ( float ) VIEW_DISTANCE - dist * 2.f + 128.f ) / ( float ) VIEW_DISTANCE ;
glBlendColor ( 0.f , 0.f , 0.f , blend ) ;
2021-11-26 11:59:02 -05:00
m_world . GetChunks ( ) . Get ( chx , chy ) - > Render ( ) ;
2021-11-30 19:55:11 -05:00
all . ApplyTranslation ( - chx * CHUNK_SIZE_X , 0 , - chy * CHUNK_SIZE_Z ) ;
m_renderManifest . push_back ( Vector3i ( chx , 0 , chy ) ) ;
2021-11-26 11:59:02 -05:00
+ + m_renderCount ;
}
2021-11-27 13:35:39 -05:00
}
2021-11-30 19:55:11 -05:00
}
2021-11-26 11:59:02 -05:00
}
2021-09-27 10:20:58 -04:00
2021-11-30 19:55:11 -05:00
m_shader01 . Disable ( ) ;
2021-11-26 11:59:02 -05:00
2021-10-26 17:28:37 -04:00
if ( m_wireframe )
glPolygonMode ( GL_FRONT_AND_BACK , GL_FILL ) ;
DrawHud ( elapsedTime ) ;
if ( m_wireframe )
glPolygonMode ( GL_FRONT_AND_BACK , GL_LINE ) ;
2021-11-26 11:59:02 -05:00
if ( m_player . GetPosition ( ) . y < - 20.f )
2021-12-01 21:21:45 -05:00
m_player = Player ( Vector3f ( 0 , CHUNK_SIZE_Y + 1.8f , 0 ) ) ; // Respawn si le bonho- joueur tombe en bas du monde.
2021-09-24 10:15:43 -04:00
}
void Engine : : KeyPressEvent ( unsigned char key )
{
2021-10-11 11:37:58 -04:00
switch ( key ) {
2021-09-27 10:20:58 -04:00
case 36 : // ESC
2021-11-30 19:55:11 -05:00
for ( int x = 0 ; x < WORLD_SIZE_X ; + + x ) // Les destructeurs de Chunks ont de la mis<69> re je les aide un peu!
for ( int y = 0 ; y < WORLD_SIZE_Y ; + + y )
if ( m_world . GetChunks ( ) . Get ( x , y ) )
m_world . GetChunks ( ) . Get ( x , y ) - > ~ Chunk ( ) ;
m_world . GetChunks ( ) . Reset ( nullptr ) ; // Hack cheap qui emp<6D> che d'avoir une exception en sortant du jeu
2021-09-27 10:20:58 -04:00
Stop ( ) ;
break ;
case 94 : // F10
SetFullscreen ( ! IsFullscreen ( ) ) ;
break ;
case 22 : // W
if ( ! m_keyW ) {
std : : cout < < " W " < < std : : endl ;
m_keyW = true ;
}
break ;
case 0 : // A
if ( ! m_keyA ) {
std : : cout < < " A " < < std : : endl ;
m_keyA = true ;
}
break ;
case 18 : // S
if ( ! m_keyS ) {
std : : cout < < " S " < < std : : endl ;
m_keyS = true ;
}
break ;
case 3 : // D
if ( ! m_keyD ) {
std : : cout < < " D " < < std : : endl ;
m_keyD = true ;
}
break ;
2021-10-04 12:29:10 -04:00
case 38 : // Left Shift
if ( ! m_keylshift ) {
std : : cout < < " Dash! " < < std : : endl ;
m_keylshift = true ;
}
break ;
2021-10-01 10:52:33 -04:00
case 57 : // Space
if ( ! m_keySpace ) {
std : : cout < < " Jump! " < < std : : endl ;
m_keySpace = true ;
}
break ;
2021-09-27 10:20:58 -04:00
case 24 : // Y - Ignorer
case 255 : // Fn - Ignorer
2021-10-19 10:27:59 -04:00
case 12 : // M - Ignorer
2021-11-26 11:59:02 -05:00
case 17 : // R - Ignorer
2021-09-27 10:20:58 -04:00
break ;
default :
std : : cout < < " Unhandled key: " < < ( int ) key < < std : : endl ;
}
2021-09-24 10:15:43 -04:00
}
void Engine : : KeyReleaseEvent ( unsigned char key )
{
2021-10-11 11:37:58 -04:00
switch ( key ) {
2021-10-19 10:27:59 -04:00
case 12 :
2021-10-25 10:50:08 -04:00
m_audio . ToggleMusicState ( ) ;
2021-10-19 10:27:59 -04:00
break ;
2021-11-26 11:59:02 -05:00
case 17 :
2021-12-01 21:21:45 -05:00
m_isSkybox = ! m_isSkybox ;
2021-11-26 11:59:02 -05:00
break ;
2021-09-27 10:20:58 -04:00
case 24 : // Y
m_wireframe = ! m_wireframe ;
if ( m_wireframe )
glPolygonMode ( GL_FRONT_AND_BACK , GL_LINE ) ;
else
glPolygonMode ( GL_FRONT_AND_BACK , GL_FILL ) ;
break ;
case 22 : // W
std : : cout < < " rW " < < std : : endl ;
m_keyW = false ;
break ;
case 0 : // A
std : : cout < < " rA " < < std : : endl ;
m_keyA = false ;
break ;
case 18 : // S
std : : cout < < " rS " < < std : : endl ;
m_keyS = false ;
break ;
case 3 : // D
std : : cout < < " rD " < < std : : endl ;
m_keyD = false ;
break ;
2021-10-04 12:29:10 -04:00
case 38 : // Left Shift
std : : cout < < " rLS " < < std : : endl ;
m_keylshift = false ;
case 57 : // Espace
2021-10-01 10:52:33 -04:00
std : : cout < < " rSpace " < < std : : endl ;
m_keySpace = false ;
break ;
2021-09-27 10:20:58 -04:00
}
2021-09-24 10:15:43 -04:00
}
void Engine : : MouseMoveEvent ( int x , int y )
{
2021-10-04 12:29:10 -04:00
m_player . TurnLeftRight ( x - ( Width ( ) / 2 ) ) ;
m_player . TurnTopBottom ( y - ( Height ( ) / 2 ) ) ;
2021-09-27 13:15:57 -04:00
2021-09-27 10:20:58 -04:00
// Centrer la souris seulement si elle n'est pas d<> j<EFBFBD> centr<74> e
// Il est n<> cessaire de faire la v<> rification pour <20> viter de tomber
// dans une boucle infinie o<> l'appel <20> CenterMouse g<> n<EFBFBD> re un
// MouseMoveEvent, qui rapelle CenterMouse qui rapelle un autre
// MouseMoveEvent, etc
if ( x = = ( Width ( ) / 2 ) & & y = = ( Height ( ) / 2 ) )
return ;
CenterMouse ( ) ;
2021-09-24 10:15:43 -04:00
}
2021-11-26 11:59:02 -05:00
void Engine : : MousePressEvent ( const MOUSE_BUTTON & button , int x , int y ) {
switch ( button ) {
case MOUSE_BUTTON_LEFT :
m_mouseL = true ;
break ;
case MOUSE_BUTTON_RIGHT :
m_mouseR = true ;
break ;
case MOUSE_BUTTON_MIDDLE :
m_mouseC = true ;
break ;
case MOUSE_BUTTON_WHEEL_UP :
m_mouseWU = true ;
break ;
case MOUSE_BUTTON_WHEEL_DOWN :
m_mouseWD = true ;
break ;
case MOUSE_BUTTON_NONE : break ;
}
2021-09-24 10:15:43 -04:00
}
2021-11-26 11:59:02 -05:00
void Engine : : MouseReleaseEvent ( const MOUSE_BUTTON & button , int x , int y ) {
switch ( button ) {
case MOUSE_BUTTON_LEFT :
m_mouseL = false ;
2021-11-27 13:35:39 -05:00
m_block = false ;
2021-11-26 11:59:02 -05:00
break ;
case MOUSE_BUTTON_RIGHT :
m_mouseR = false ;
2021-11-27 13:35:39 -05:00
m_block = false ;
2021-11-26 11:59:02 -05:00
break ;
case MOUSE_BUTTON_MIDDLE :
m_mouseC = false ;
break ;
case MOUSE_BUTTON_WHEEL_UP :
m_mouseWU = false ;
break ;
case MOUSE_BUTTON_WHEEL_DOWN :
m_mouseWD = false ;
break ;
case MOUSE_BUTTON_NONE : break ;
}
2021-09-24 10:15:43 -04:00
}
bool Engine : : LoadTexture ( Texture & texture , const std : : string & filename , bool stopOnError )
{
2021-09-27 10:20:58 -04:00
texture . Load ( filename ) ;
if ( ! texture . IsValid ( ) )
{
std : : cerr < < " Unable to load texture ( " < < filename < < " ) " < < std : : endl ;
if ( stopOnError )
Stop ( ) ;
2021-09-24 10:15:43 -04:00
2021-09-27 10:20:58 -04:00
return false ;
}
2021-09-24 10:15:43 -04:00
2021-09-27 10:20:58 -04:00
return true ;
2021-09-24 10:15:43 -04:00
}
2021-11-26 11:59:02 -05:00
bool Engine : : GenerateChunk ( int chx , int chy ) {
if ( chx < WORLD_SIZE_X * CHUNK_SIZE_X & & chy < WORLD_SIZE_Y * CHUNK_SIZE_Z & &
chx > = 0 & & chy > = 0 )
if ( ! m_world . ChunkAt ( chx , 1 , chy ) ) {
2021-11-30 19:55:11 -05:00
std : : ostringstream pos ;
pos < < CHUNK_PATH < < chx / CHUNK_SIZE_X < < ' _ ' < < chy / CHUNK_SIZE_Z < < " .chunk " ;
std : : ifstream input ( pos . str ( ) . c_str ( ) , std : : fstream : : binary ) ;
if ( input . fail ( ) ) {
m_world . GetChunks ( ) . Set ( chx / CHUNK_SIZE_X , chy / CHUNK_SIZE_Z , new Chunk ( chx / CHUNK_SIZE_X , chy / CHUNK_SIZE_Z ) ) ;
Chunk * chunk = m_world . GetChunks ( ) . Get ( chx / CHUNK_SIZE_X , chy / CHUNK_SIZE_Z ) ;
for ( int x = 0 ; x < CHUNK_SIZE_X ; + + x )
for ( int z = 0 ; z < CHUNK_SIZE_Z ; + + z ) {
Vector3f perlin ;
perlin . z = x * CHUNK_SIZE_X + CHUNK_SIZE_X * chx ;
perlin . y = 0 ;
perlin . x = z * CHUNK_SIZE_Z + CHUNK_SIZE_Z * chy ;
perlin . Normalize ( ) ;
float height = m_perlin . Get ( perlin . x , perlin . z ) * 3 - 32 ;
for ( int y = 0 ; y < = ( int ) height % CHUNK_SIZE_Y ; + + y ) {
chunk - > SetBlock ( x , y , z , BTYPE_METAL , & m_world ) ;
}
}
2021-11-26 11:59:02 -05:00
2021-11-30 19:55:11 -05:00
for ( int x = 0 ; x < CHUNK_SIZE_X ; + + x )
for ( int z = 0 ; z < CHUNK_SIZE_Z ; + + z ) {
Vector3f perlin ;
perlin . x = x * CHUNK_SIZE_X + CHUNK_SIZE_X * chx ;
perlin . y = 0 ;
perlin . z = z * CHUNK_SIZE_Z + CHUNK_SIZE_Z * chy ;
perlin . Normalize ( ) ;
float height = m_perlin . Get ( perlin . x , perlin . z ) + 16 ;
for ( int y = 0 ; y < = ( int ) height % CHUNK_SIZE_Y ; + + y ) {
if ( chunk - > GetBlock ( x , y , z ) = = BTYPE_AIR )
chunk - > SetBlock ( x , y , z , BTYPE_GRASS , & m_world ) ;
}
}
for ( int x = 0 ; x < CHUNK_SIZE_X ; + + x )
for ( int z = 0 ; z < CHUNK_SIZE_Z ; + + z ) {
for ( int y = 0 ; y < = 10 ; + + y ) {
if ( chunk - > GetBlock ( x , y , z ) = = BTYPE_AIR )
chunk - > SetBlock ( x , y , z , BTYPE_ICE , & m_world ) ;
}
}
2021-11-26 11:59:02 -05:00
2021-11-30 19:55:11 -05:00
for ( int x = 0 ; x < CHUNK_SIZE_X ; + + x )
for ( int z = 0 ; z < CHUNK_SIZE_Z ; + + z ) {
for ( int y = 0 ; y < CHUNK_SIZE_Y ; + + y ) {
Vector3f perlin ;
perlin . x = x * CHUNK_SIZE_X + CHUNK_SIZE_X * chx ;
perlin . y = ( x + z ) * CHUNK_SIZE_Y ;
perlin . z = z * CHUNK_SIZE_Z + CHUNK_SIZE_Z * chy ;
perlin . Normalize ( ) ;
float height = m_perlin . Get ( perlin . x , perlin . y , perlin . z ) ;
if ( chunk - > GetBlock ( x , y , z ) ! = BTYPE_AIR & & height > 18 )
chunk - > SetBlock ( x , y , z , BTYPE_DIRT , & m_world ) ;
}
}
}
else {
input . seekg ( 0 , std : : ios_base : : end ) ;
int size = input . tellg ( ) ;
input . seekg ( 0 , std : : ios_base : : beg ) ;
char * data = new char [ size ] ;
input . read ( data , size ) ;
input . close ( ) ;
m_world . GetChunks ( ) . Set ( chx / CHUNK_SIZE_X , chy / CHUNK_SIZE_Z , new Chunk ( chx / CHUNK_SIZE_X , chy / CHUNK_SIZE_Z , data ) ) ;
delete [ ] data ;
}
std : : cout < < " Chunk generated: " < < chx / CHUNK_SIZE_X < < " , " < < chy / CHUNK_SIZE_Z < < std : : endl ;
2021-11-26 11:59:02 -05:00
return true ;
}
return false ;
}
void Engine : : UpdateWorld ( int & generates , int & updates , int chx , int chy ) {
if ( generates = = 0 & & GenerateChunk ( chx , chy ) ) generates = FRAMES_RENDER_CHUNKS ;
if ( updates = = 0 & & m_world . ChunkAt ( chx , 1 , chy ) & &
m_world . ChunkAt ( chx , 1 , chy ) - > IsDirty ( ) ) {
m_world . ChunkAt ( chx , 1 , chy ) - > Update ( m_blockinfo , & m_world ) ;
updates = FRAMES_UPDATE_CHUNKS ;
}
}
2021-11-30 19:55:11 -05:00
void Engine : : ChangeBlockAtCursor ( BlockType blockType ) {
2021-11-27 14:14:05 -05:00
Vector3f currentPos = m_player . GetPosition ( ) ;
Vector3f currentBlock = currentPos ;
2021-11-27 13:35:39 -05:00
Vector3f ray = m_player . GetDirection ( ) ;
bool found = false ;
2021-11-26 11:59:02 -05:00
2021-11-27 13:35:39 -05:00
if ( m_block ) return ;
2021-11-26 11:59:02 -05:00
2021-11-27 14:14:05 -05:00
while ( ( currentPos - currentBlock ) . Length ( ) < = MAX_SELECTION_DISTANCE & & ! found ) {
2021-11-27 13:35:39 -05:00
currentBlock + = ray / 10.f ;
2021-11-26 11:59:02 -05:00
2021-11-27 13:35:39 -05:00
BlockType bt = m_world . BlockAt ( currentBlock ) ;
2021-11-30 19:55:11 -05:00
2021-11-27 13:35:39 -05:00
if ( bt ! = BTYPE_AIR )
found = true ;
}
2021-11-26 11:59:02 -05:00
2021-11-27 13:35:39 -05:00
if ( found ) {
if ( blockType ! = BTYPE_AIR ) {
found = false ;
2021-11-27 14:14:05 -05:00
while ( ( currentPos - currentBlock ) . Length ( ) > = 1.7f & & ! found ) {
2021-11-27 13:35:39 -05:00
currentBlock - = ray / 10.f ;
2021-11-26 11:59:02 -05:00
2021-11-27 13:35:39 -05:00
BlockType bt = m_world . BlockAt ( currentBlock ) ;
2021-11-26 11:59:02 -05:00
2021-11-30 19:55:11 -05:00
if ( bt = = BTYPE_AIR ) { // V<> rification pour <20> tre s<> r que le bloc <20> changer n'est pas dans le joueur.
2021-11-27 14:14:05 -05:00
int Bx = ( int ) currentBlock . x ;
int By = ( int ) currentBlock . y ;
int Bz = ( int ) currentBlock . z ;
int Px = ( int ) currentPos . x ;
int PyA = ( int ) currentPos . y ;
int PyB = ( int ) ( currentPos . y - .9f ) ;
int PyC = ( int ) ( currentPos . y - 1.7f ) ;
int Pz = ( int ) currentPos . z ;
2021-11-30 19:55:11 -05:00
if ( ! ( Bx = = Px & &
( By = = PyA | |
By = = PyB | |
By = = PyC ) & &
Bz = = Pz ) )
found = true ;
2021-11-27 14:14:05 -05:00
}
2021-11-26 11:59:02 -05:00
}
}
}
2021-11-27 14:14:05 -05:00
if ( found & & ( int ) currentBlock . y < CHUNK_SIZE_Y ) {
2021-11-26 11:59:02 -05:00
int bx = ( int ) currentBlock . x % CHUNK_SIZE_X ;
int by = ( int ) currentBlock . y % CHUNK_SIZE_Y ;
int bz = ( int ) currentBlock . z % CHUNK_SIZE_Z ;
m_world . ChunkAt ( currentBlock ) - > SetBlock ( bx , by , bz , blockType , & m_world ) ;
m_world . ChunkAt ( currentBlock ) - > MakeModified ( ) ;
2021-11-27 13:35:39 -05:00
m_block = true ;
2021-11-26 11:59:02 -05:00
}
}