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 ;
origin - > GetScope ( sx , sy ) ;
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 ) ;
origin - > ChunkAt ( chx , 1 , chy ) - > GetPosition ( cx , cy ) ;
if ( m_meshes . Get ( cx - sx , cy - sy ) )
m_meshes . Get ( cx - sx , cy - sy ) - > Render ( ) ;
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 ] ;
unsigned int mx = 0 , my = 0 , sx , sy ;
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-11-20 15:40:43 -05:00
void Renderer : : RenderBillboard ( const Vector3f pos , TextureAtlas textureAtlas , TextureAtlas : : TextureIndex idx , Shader & shader , Transformation tran )
{
//float x = pos.x;
//float y = pos.y;
//float z = pos.z;
//float width = 1.0f;
//float height = 1.0f;
//float u, v, w, h;
//shader.Use();
//textureAtlas.Bind();
//textureAtlas.TextureIndexToCoord(idx, u, v, w, h);
//glLoadMatrixf(tran.GetMatrix().GetInternalValues());
//glBegin(GL_QUADS);
//glTexCoord2f(u, v); glVertex3f(x - width / 2., y - height, z); //glVertex3f(v4.x, v4.y, v4.z);//glVertex3f(0, 50, 0);
//glTexCoord2f(u + w, v); glVertex3f(x + width / 2., y - height, z); //glVertex3f(v3.x, v3.y, v3.z); //glVertex3f(50,50, 0);
//glTexCoord2f(u + w, v + h); glVertex3f(x + width / 2., y, z); //glVertex3f(v2.x, v2.y, v2.z); //glVertex3f(50, 0, 0);
//glTexCoord2f(u, v + h); glVertex3f(x - width / 2., y, z); //glVertex3f(v1.x, v1.y, v1.z);// glVertex3f(0, 0, 0);
//glEnd();
//shader.Disable();
}
2023-10-27 13:59:26 -04: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