2023-10-03 12:43:54 -04:00
# include "renderer.h"
2023-11-20 15:40:43 -05:00
# include <iostream>
# include <cstring>
# include <thread>
# include <queue>
2023-09-30 14:46:54 -04:00
2023-10-03 12:43:54 -04:00
Renderer : : Renderer ( ) {
2023-09-30 14:46:54 -04:00
m_meshes . Reset ( nullptr ) ;
}
2023-10-03 12:43:54 -04:00
Renderer : : ~ Renderer ( ) {
2023-09-30 14:46:54 -04:00
}
2023-11-15 08:27:51 -05:00
void Renderer : : RemoveChunk ( int nbReduit )
{
for ( int x = 0 ; x < WORLD_SIZE_X ; + + x )
for ( int y = 0 ; y < WORLD_SIZE_Y ; + + y )
{
Mesh * chk = nullptr ;
if ( x < nbReduit )
chk = m_meshes . Remove ( x , y ) ;
if ( y < nbReduit )
chk = m_meshes . Remove ( x , y ) ;
if ( y > WORLD_SIZE_Y - nbReduit )
chk = m_meshes . Remove ( x , y ) ;
if ( x > WORLD_SIZE_X - nbReduit )
chk = m_meshes . Remove ( x , y ) ;
// TODO: MakeDirty() les voisins pour qu'ils se redessinent.
if ( ! chk )
continue ;
delete chk ;
}
}
2023-11-19 16:46:13 -05:00
void Renderer : : RenderWorld ( World * origin , int & rendercount , const Vector3f & player_pos , const Vector3f & player_dir , Transformation world , Shader & shader , TextureAtlas & atlas ) const {
2023-09-30 14:46:54 -04:00
rendercount = 0 ;
Vector3f angle ;
Vector3f cursor ;
Vector3f direct = player_dir ;
Vector3f pos = player_pos - direct ;
direct . y = 0 ;
direct . Normalize ( ) ;
pos . y = 1 ;
2023-10-27 13:59:26 -04:00
static Vector3 < unsigned int > renderManifest [ VIEW_DISTANCE * 8 ] ; // Nombre de Chunks maximal <20> <20> tre rendus.
2023-09-30 14:46:54 -04:00
//for (int dist = VIEW_DISTANCE; dist >= 0; dist -= CHUNK_SIZE_X) {
for ( int dist = 0 ; dist < = VIEW_DISTANCE ; dist + = CHUNK_SIZE_X ) {
// Configuration du radar.
float sinus , cosinus ;
int echantillons ;
if ( dist > VIEW_DISTANCE * .1f ) {
2023-10-27 13:59:26 -04:00
sinus = .00872653549f ; // sin(1/2 degr<67> )
cosinus = .99996192306 ; // cos(1/2 degr<67> )
2023-09-30 14:46:54 -04:00
echantillons = 180 ;
}
//else {//if (dist > VIEW_DISTANCE * .3f) {
2023-10-27 13:59:26 -04:00
// sinus = .01151891831f; // sin(2/3 degr<67> )
// cosinus = .99993365506; // cos(2/3 degr<67> )
2023-09-30 14:46:54 -04:00
// echantillons = 120;
//}
//else if (dist > VIEW_DISTANCE * .2f) {
2023-10-27 13:59:26 -04:00
// sinus = .01745240643; // sin(1 degr<67> )
// cosinus = .99984769515; // cos(1 degr<67> )
2023-09-30 14:46:54 -04:00
// echantillons = 90;
//}
//else if (dist > VIEW_DISTANCE * .1f) {
// sinus = .0261769483;
// cosinus = .99965732497;
// echantillons = 60;
//}
else {
sinus = .0348994967 ;
cosinus = .99939082701 ;
echantillons = 45 ;
}
angle . x = direct . z + direct . x ;
angle . z = direct . z - direct . x ;
angle . y = 0 ;
angle . Normalize ( ) ;
for ( int radar = 0 ; radar < echantillons ; + + radar ) {
float x = angle . x ;
angle . x = angle . x * cosinus - angle . z * sinus ;
angle . z = angle . z * cosinus + x * sinus ;
angle . Normalize ( ) ;
cursor = pos - direct * CHUNK_SIZE_X * 4 + angle * dist ;
if ( cursor . y > = 128.f | | cursor . y > = 0.f ) cursor . y = CHUNK_SIZE_Y / 4.f ;
if ( origin - > ChunkAt ( cursor ) ) {
bool valide = true ;
unsigned int chx , chy ;
origin - > ChunkAt ( cursor ) - > GetPosition ( chx , chy ) ;
2023-10-27 13:59:26 -04:00
for ( int index = 0 ; index < rendercount ; + + index ) // Permet de v<> rifier seulement contre celles ajout<75> es dans la frame, et ne pas avoir <20> refaire l'array <20> chaque frame.
2023-09-30 14:46:54 -04:00
if ( renderManifest [ index ] . x = = chx & & renderManifest [ index ] . z = = chy )
valide = false ;
if ( valide ) renderManifest [ rendercount + + ] = Vector3 < unsigned int > ( chx ,
( VIEW_DISTANCE - ( pos - cursor ) . Length ( ) * 3.f + 256.f ) < 0.f ? 0 :
( VIEW_DISTANCE - ( pos - cursor ) . Length ( ) * 3.f + 256.f ) * 1000 ,
chy ) ;
}
}
}
shader . Use ( ) ;
atlas . Bind ( ) ;
glStencilFunc ( GL_EQUAL , 1 , 0x00 ) ;
glStencilOp ( GL_KEEP , GL_KEEP , GL_REPLACE ) ;
unsigned int sx , sy , cx , cy ;
2023-12-15 23:02:20 -05:00
origin - > GetScope ( sx , sy ) ;
2023-09-30 14:46:54 -04:00
for ( int index = 0 ; index < rendercount ; + + index ) {
int chx = ( renderManifest [ index ] . x - sx ) * CHUNK_SIZE_X , chy = ( renderManifest [ index ] . z - sy ) * CHUNK_SIZE_Z ;
world . ApplyTranslation ( chx , 0 , chy ) ;
glLoadMatrixf ( world . GetMatrix ( ) . GetInternalValues ( ) ) ;
float blcolor = renderManifest [ index ] . y / ( VIEW_DISTANCE / 50.f ) ;
glBlendColor ( blcolor , blcolor , blcolor , 1.f ) ;
2023-12-15 23:02:20 -05:00
origin - > ChunkAt ( chx , 1 , chy ) - > GetPosition ( cx , cy ) ;
2023-09-30 14:46:54 -04:00
if ( m_meshes . Get ( cx - sx , cy - sy ) )
2023-12-15 23:02:20 -05:00
m_meshes . Get ( cx - sx , cy - sy ) - > Render ( ) ;
2023-09-30 14:46:54 -04:00
world . ApplyTranslation ( - chx , 0 , - chy ) ;
}
shader . Disable ( ) ;
glStencilFunc ( GL_GREATER , 1 , 0xFF ) ;
2023-11-20 15:40:43 -05:00
}
2023-09-30 14:46:54 -04:00
2023-10-03 12:43:54 -04:00
void Renderer : : UpdateMesh ( World * origin , const Vector3f & player , BlockInfo * blockinfo [ BTYPE_LAST ] ) {
2023-09-30 14:46:54 -04:00
int cx = player . x ;
int cy = player . z ;
static int frameUpdate = 2 ;
int side = 0 ;
int threads = 0 ;
std : : future < Mesh * > updateThList [ THREADS_UPDATE_CHUNKS ] ;
2023-12-15 23:02:20 -05:00
unsigned int mx = 0 , my = 0 , sx , sy ;
2023-09-30 14:46:54 -04:00
origin - > GetScope ( sx , sy ) ;
if ( frameUpdate > 0 ) - - frameUpdate ;
if ( ! frameUpdate )
while ( side * CHUNK_SIZE_X < = VIEW_DISTANCE * 2 ) {
int tx = - side , ty = - side ;
for ( ; tx < = side ; + + tx ) {
if ( frameUpdate )
break ;
unsigned int chx = cx + tx * CHUNK_SIZE_X , chy = cy + ty * CHUNK_SIZE_Z ;
if ( origin - > ChunkAt ( chx , 1 , chy ) & &
origin - > ChunkAt ( chx , 1 , chy ) - > IsDirty ( ) ) {
origin - > ChunkAt ( chx , 1 , chy ) - > GetPosition ( mx , my ) ;
if ( m_meshes . Get ( mx - sx , my - sy ) )
updateThList [ threads + + ] =
std : : async ( std : : launch : : async ,
[ ] ( Mesh * mesh , BlockInfo * blockinfo [ BTYPE_LAST ] , World * world ) {
mesh - > Update ( blockinfo , world ) ; return mesh ; } , m_meshes . Get ( mx - sx , my - sy ) , blockinfo , origin ) ;
else updateThList [ threads + + ] = std : : async ( std : : launch : : async ,
[ ] ( Chunk * chunk ) { return new Mesh ( chunk ) ; } , origin - > ChunkAt ( chx , 1 , chy ) ) ;
if ( threads = = THREADS_UPDATE_CHUNKS ) frameUpdate = FRAMES_UPDATE_CHUNKS ;
}
}
for ( ; ty < = side ; + + ty ) {
if ( frameUpdate )
break ;
unsigned int chx = cx + tx * CHUNK_SIZE_X , chy = cy + ty * CHUNK_SIZE_Z ;
if ( origin - > ChunkAt ( chx , 1 , chy ) & &
origin - > ChunkAt ( chx , 1 , chy ) - > IsDirty ( ) ) {
origin - > ChunkAt ( chx , 1 , chy ) - > GetPosition ( mx , my ) ;
if ( m_meshes . Get ( mx - sx , my - sy ) )
updateThList [ threads + + ] =
std : : async ( std : : launch : : async ,
[ ] ( Mesh * mesh , BlockInfo * blockinfo [ BTYPE_LAST ] , World * world ) {
mesh - > Update ( blockinfo , world ) ; return mesh ; } , m_meshes . Get ( mx - sx , my - sy ) , blockinfo , origin ) ;
else updateThList [ threads + + ] = std : : async ( std : : launch : : async ,
[ ] ( Chunk * chunk ) { return new Mesh ( chunk ) ; } , origin - > ChunkAt ( chx , 1 , chy ) ) ;
if ( threads = = THREADS_UPDATE_CHUNKS ) frameUpdate = FRAMES_UPDATE_CHUNKS ;
}
}
for ( ; tx > = - side ; - - tx ) {
if ( frameUpdate )
break ;
unsigned int chx = cx + tx * CHUNK_SIZE_X , chy = cy + ty * CHUNK_SIZE_Z ;
if ( origin - > ChunkAt ( chx , 1 , chy ) & &
origin - > ChunkAt ( chx , 1 , chy ) - > IsDirty ( ) ) {
origin - > ChunkAt ( chx , 1 , chy ) - > GetPosition ( mx , my ) ;
if ( m_meshes . Get ( mx - sx , my - sy ) )
updateThList [ threads + + ] =
std : : async ( std : : launch : : async ,
[ ] ( Mesh * mesh , BlockInfo * blockinfo [ BTYPE_LAST ] , World * world ) {
mesh - > Update ( blockinfo , world ) ; return mesh ; } , m_meshes . Get ( mx - sx , my - sy ) , blockinfo , origin ) ;
else updateThList [ threads + + ] = std : : async ( std : : launch : : async ,
[ ] ( Chunk * chunk ) { return new Mesh ( chunk ) ; } , origin - > ChunkAt ( chx , 1 , chy ) ) ;
if ( threads = = THREADS_UPDATE_CHUNKS ) frameUpdate = FRAMES_UPDATE_CHUNKS ;
}
}
for ( ; ty > = - side ; - - ty ) {
if ( frameUpdate )
break ;
unsigned int chx = cx + tx * CHUNK_SIZE_X , chy = cy + ty * CHUNK_SIZE_Z ;
if ( origin - > ChunkAt ( chx , 1 , chy ) & &
origin - > ChunkAt ( chx , 1 , chy ) - > IsDirty ( ) ) {
origin - > ChunkAt ( chx , 1 , chy ) - > GetPosition ( mx , my ) ;
if ( m_meshes . Get ( mx - sx , my - sy ) )
updateThList [ threads + + ] =
std : : async ( std : : launch : : async ,
[ ] ( Mesh * mesh , BlockInfo * blockinfo [ BTYPE_LAST ] , World * world ) {
mesh - > Update ( blockinfo , world ) ; return mesh ; } , m_meshes . Get ( mx - sx , my - sy ) , blockinfo , origin ) ;
else updateThList [ threads + + ] = std : : async ( std : : launch : : async ,
[ ] ( Chunk * chunk ) { return new Mesh ( chunk ) ; } , origin - > ChunkAt ( chx , 1 , chy ) ) ;
if ( threads = = THREADS_UPDATE_CHUNKS ) frameUpdate = FRAMES_UPDATE_CHUNKS ;
}
}
if ( frameUpdate )
break ;
+ + side ;
}
if ( threads > 0 ) {
for ( int i = 0 ; i < threads ; + + i ) {
updateThList [ i ] . wait ( ) ;
Mesh * mesh = updateThList [ i ] . get ( ) ;
if ( mesh - > IsNew ( ) ) {
unsigned int x , y ;
mesh - > GetPosition ( x , y , origin ) ;
m_meshes . Set ( x , y , mesh ) ;
}
mesh - > FlushMeshToVBO ( ) ;
}
}
}
2023-10-16 12:02:37 -04:00
2023-12-18 14:24:43 -05:00
void Renderer : : RenderBooster ( TextureAtlas & textureAtlas , Shader & shader , Transformation tran , Player player , Booster * booster ) {
2023-12-15 23:02:20 -05:00
float width = 1.f ;
float height = 1.f ;
2023-12-18 14:24:43 -05:00
Vector3f DiffCam = booster - > GetPosition ( ) - player . GetPosition ( ) ;
2023-12-15 23:02:20 -05:00
Vector3f UpCam = Vector3f ( 0.f , 1.f , 0.f ) ;
Vector3f CrossA = DiffCam . Cross ( UpCam ) ;
Vector3f CrossB = DiffCam . Cross ( CrossA ) ;
CrossA . Normalize ( ) ;
CrossB . Normalize ( ) ;
2023-12-18 14:24:43 -05:00
Vector3f playerPosition = booster - > GetPosition ( ) + Vector3f ( 0.f , - .75f , 0.f ) ;
2023-12-15 23:02:20 -05:00
Vector3f v2 = ( playerPosition + CrossA * 0.5 * width + CrossB * 0.5 * height ) ;
Vector3f v1 = ( playerPosition - CrossA * 0.5 * width + CrossB * 0.5 * height ) ;
Vector3f v3 = ( playerPosition + CrossA * 0.5 * width - CrossB * 0.5 * height ) ;
Vector3f v4 = ( playerPosition - CrossA * 0.5 * width - CrossB * 0.5 * height ) ;
int index ;
2023-12-18 14:24:43 -05:00
BOOST_TYPE type = booster - > GetType ( ) ;
2023-12-15 23:02:20 -05:00
switch ( type )
{
case BTYPE_HEAL :
index = 5 ;
break ;
case BTYPE_DAMAGE :
index = 6 ;
break ;
case BTYPE_SPEED :
index = 7 ;
break ;
case BTYPE_INVINCIBLE :
index = 8 ;
break ;
default :
index = 1 ;
break ;
}
float u , v , w , h ;
shader . Use ( ) ;
textureAtlas . Bind ( ) ;
textureAtlas . TextureIndexToCoord ( index , u , v , w , h ) ;
glEnable ( GL_BLEND ) ;
glBlendFunc ( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA ) ;
glBlendEquation ( GL_FUNC_ADD ) ;
glLoadMatrixf ( tran . GetMatrix ( ) . GetInternalValues ( ) ) ;
glBegin ( GL_QUADS ) ;
glTexCoord2f ( u , v ) ; glVertex3f ( v1 . x , v1 . y , v1 . z ) ;
glTexCoord2f ( u + w , v ) ; glVertex3f ( v2 . x , v2 . y , v2 . z ) ;
glTexCoord2f ( u + w , v + h ) ; glVertex3f ( v3 . x , v3 . y , v3 . z ) ;
glTexCoord2f ( u , v + h ) ; glVertex3f ( v4 . x , v4 . y , v4 . z ) ;
glEnd ( ) ;
glBlendFunc ( GL_CONSTANT_COLOR , GL_ONE_MINUS_CONSTANT_COLOR ) ;
glBlendEquation ( GL_FUNC_SUBTRACT ) ;
glDisable ( GL_BLEND ) ;
shader . Disable ( ) ;
2023-11-20 15:40:43 -05:00
}
2023-10-03 12:43:54 -04:00
void Renderer : : RenderPlayer ( Player * player , Transformation tran ) const {
}
void Renderer : : RenderPlayer ( RemotePlayer * rplayer , const Vector3f & player_pos , const Vector3f & player_dir ) const {
}
2023-10-27 13:59:26 -04:00