mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-18 05:29:18 +02:00
merge (incomplete)
This commit is contained in:
612
renderer.cpp
612
renderer.cpp
@@ -11,8 +11,12 @@ http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include "renderer.h"
|
||||
#include "globals.h"
|
||||
#include "World.h"
|
||||
#include "timer.h"
|
||||
#include "world.h"
|
||||
#include "data.h"
|
||||
#include "dynobj.h"
|
||||
#include "animmodel.h"
|
||||
#include "traction.h"
|
||||
#include "uilayer.h"
|
||||
#include "logs.h"
|
||||
#include "usefull.h"
|
||||
@@ -32,11 +36,11 @@ bool
|
||||
opengl_camera::visible( TDynamicObject const *Dynamic ) const {
|
||||
|
||||
// sphere test is faster than AABB, so we'll use it here
|
||||
float3 diagonal(
|
||||
Dynamic->MoverParameters->Dim.L,
|
||||
Dynamic->MoverParameters->Dim.H,
|
||||
Dynamic->MoverParameters->Dim.W );
|
||||
float const radius = diagonal.Length() * 0.5f;
|
||||
glm::vec3 diagonal(
|
||||
static_cast<float>( Dynamic->MoverParameters->Dim.L ),
|
||||
static_cast<float>( Dynamic->MoverParameters->Dim.H ),
|
||||
static_cast<float>( Dynamic->MoverParameters->Dim.W ) );
|
||||
float const radius = glm::length( diagonal ) * 0.5f;
|
||||
|
||||
return ( m_frustum.sphere_inside( Dynamic->GetPosition(), radius ) > 0.0f );
|
||||
}
|
||||
@@ -103,13 +107,19 @@ opengl_renderer::Init( GLFWwindow *Window ) {
|
||||
World.shader = gl_program_light({ gl_shader("lighting.vert"), gl_shader("blinnphong.frag") });
|
||||
Global::daylight.intensity = 1.0f; //m7todo: przenieść
|
||||
|
||||
WriteLog("Loading common gfx data...");
|
||||
m_glaretextureid = GetTextureId("fx\\lightglare", szTexturePath);
|
||||
m_suntextureid = GetTextureId("fx\\sun", szTexturePath);
|
||||
m_moontextureid = GetTextureId("fx\\moon", szTexturePath);
|
||||
WriteLog("...gfx data pre-loading done");
|
||||
|
||||
return true;
|
||||
|
||||
// preload some common textures
|
||||
WriteLog( "Loading common gfx data..." );
|
||||
m_glaretextureid = GetTextureId( "fx\\lightglare", szTexturePath );
|
||||
m_suntextureid = GetTextureId( "fx\\sun", szTexturePath );
|
||||
m_moontextureid = GetTextureId( "fx\\moon", szTexturePath );
|
||||
WriteLog( "...gfx data pre-loading done" );
|
||||
|
||||
// prepare debug mode objects
|
||||
m_quadric = gluNewQuadric();
|
||||
gluQuadricNormals( m_quadric, GLU_FLAT );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -132,15 +142,22 @@ opengl_renderer::Render() {
|
||||
::glLoadIdentity();
|
||||
|
||||
if( World.InitPerformed() ) {
|
||||
/*
|
||||
World.Camera.SetMatrix();
|
||||
m_camera.update_frustum();
|
||||
*/
|
||||
glm::dmat4 worldcamera;
|
||||
World.Camera.SetMatrix( worldcamera );
|
||||
m_camera.update_frustum( OpenGLMatrices.data( GL_PROJECTION ), worldcamera );
|
||||
// frustum tests are performed in 'world space' but after we set up frustum
|
||||
// we no longer need camera translation, only rotation
|
||||
::glMultMatrixd( glm::value_ptr( glm::dmat4( glm::dmat3( worldcamera ))));
|
||||
|
||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||
Render( &World.Environment );
|
||||
|
||||
glUseProgram(World.shader);
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
World.Ground.Render( World.Camera.Pos );
|
||||
Render( &World.Ground );
|
||||
|
||||
glDebug("rendering cab");
|
||||
World.Render_Cab();
|
||||
@@ -171,13 +188,20 @@ opengl_renderer::Render( world_environment *Environment ) {
|
||||
::glDisable( GL_DEPTH_TEST );
|
||||
::glDepthMask( GL_FALSE );
|
||||
::glPushMatrix();
|
||||
/*
|
||||
::glTranslatef( Global::pCameraPosition.x, Global::pCameraPosition.y, Global::pCameraPosition.z );
|
||||
|
||||
*/
|
||||
/*
|
||||
glm::mat4 worldcamera;
|
||||
World.Camera.SetMatrix( worldcamera );
|
||||
glLoadIdentity();
|
||||
glMultMatrixf( glm::value_ptr( glm::mat4( glm::mat3( worldcamera ) ) ) );
|
||||
*/
|
||||
// setup fog
|
||||
if( Global::fFogEnd > 0 ) {
|
||||
// fog setup
|
||||
::glFogfv( GL_FOG_COLOR, Global::FogColor );
|
||||
::glFogf( GL_FOG_DENSITY, 1.0f / Global::fFogEnd );
|
||||
::glFogf( GL_FOG_DENSITY, static_cast<GLfloat>( 1.0 / Global::fFogEnd ) );
|
||||
::glEnable( GL_FOG );
|
||||
}
|
||||
else { ::glDisable( GL_FOG ); }
|
||||
@@ -230,7 +254,7 @@ opengl_renderer::Render( world_environment *Environment ) {
|
||||
{
|
||||
Bind( m_moontextureid );
|
||||
float3 mooncolor( 255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f );
|
||||
::glColor4f( mooncolor.x, mooncolor.y, mooncolor.z, 1.0f - Global::fLuminance * 0.5f );
|
||||
::glColor4f( mooncolor.x, mooncolor.y, mooncolor.z, static_cast<GLfloat>( 1.0 - Global::fLuminance * 0.5 ) );
|
||||
|
||||
auto const moonvector = Environment->m_moon.getDirection();
|
||||
auto const moonposition = modelview * glm::vec4( moonvector.x, moonvector.y, moonvector.z, 1.0f );
|
||||
@@ -284,14 +308,18 @@ opengl_renderer::Render( world_environment *Environment ) {
|
||||
bool
|
||||
opengl_renderer::Render( TGround *Ground ) {
|
||||
|
||||
glDisable( GL_BLEND );
|
||||
glAlphaFunc( GL_GREATER, 0.50f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f
|
||||
glEnable( GL_LIGHTING );
|
||||
glColor3f( 1.0f, 1.0f, 1.0f );
|
||||
::glEnable( GL_LIGHTING );
|
||||
::glDisable( GL_BLEND );
|
||||
::glAlphaFunc( GL_GREATER, 0.50f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f
|
||||
::glColor3f( 1.0f, 1.0f, 1.0f );
|
||||
|
||||
float3 const cameraposition = float3( Global::pCameraPosition.x, Global::pCameraPosition.y, Global::pCameraPosition.z );
|
||||
int const camerax = std::floor( cameraposition.x / 1000.0f ) + iNumRects / 2;
|
||||
int const cameraz = std::floor( cameraposition.z / 1000.0f ) + iNumRects / 2;
|
||||
++TGroundRect::iFrameNumber; // zwięszenie licznika ramek (do usuwniania nadanimacji)
|
||||
|
||||
Update_Lights( Ground->m_lights );
|
||||
/*
|
||||
glm::vec3 const cameraposition( Global::pCameraPosition.x, Global::pCameraPosition.y, Global::pCameraPosition.z );
|
||||
int const camerax = static_cast<int>( std::floor( cameraposition.x / 1000.0f ) + iNumRects / 2 );
|
||||
int const cameraz = static_cast<int>( std::floor( cameraposition.z / 1000.0f ) + iNumRects / 2 );
|
||||
int const segmentcount = 2 * static_cast<int>(std::ceil( m_drawrange * Global::fDistanceFactor / 1000.0f ));
|
||||
int const originx = std::max( 0, camerax - segmentcount / 2 );
|
||||
int const originz = std::max( 0, cameraz - segmentcount / 2 );
|
||||
@@ -299,34 +327,300 @@ opengl_renderer::Render( TGround *Ground ) {
|
||||
for( int column = originx; column <= originx + segmentcount; ++column ) {
|
||||
for( int row = originz; row <= originz + segmentcount; ++row ) {
|
||||
|
||||
auto &rectangle = Ground->Rects[ column ][ row ];
|
||||
if( m_camera.visible( rectangle.m_area ) ) {
|
||||
rectangle.RenderDL();
|
||||
auto *rectangle = &Ground->Rects[ column ][ row ];
|
||||
if( m_camera.visible( rectangle->m_area ) ) {
|
||||
Render( rectangle );
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
Ground->CameraDirection.x = std::sin( Global::pCameraRotation ); // wektor kierunkowy
|
||||
Ground->CameraDirection.z = std::cos( Global::pCameraRotation );
|
||||
TGroundNode *node;
|
||||
// rednerowanie globalnych (nie za często?)
|
||||
for( node = Ground->srGlobal.nRenderHidden; node; node = node->nNext3 ) {
|
||||
node->RenderHidden();
|
||||
}
|
||||
// renderowanie czołgowe dla obiektów aktywnych a niewidocznych
|
||||
int n = 2 * iNumSubRects; //(2*==2km) promień wyświetlanej mapy w sektorach
|
||||
int c = Ground->GetColFromX( Global::pCameraPosition.x );
|
||||
int r = Ground->GetRowFromZ( Global::pCameraPosition.z );
|
||||
TSubRect *tmp;
|
||||
int i, j, k;
|
||||
for( j = r - n; j <= r + n; j++ ) {
|
||||
for( i = c - n; i <= c + n; i++ ) {
|
||||
if( ( tmp = Ground->FastGetSubRect( i, j ) ) != nullptr ) {
|
||||
// oznaczanie aktywnych sektorów
|
||||
tmp->LoadNodes();
|
||||
|
||||
for( node = tmp->nRenderHidden; node; node = node->nNext3 ) {
|
||||
node->RenderHidden();
|
||||
}
|
||||
// jeszcze dźwięki pojazdów by się przydały, również niewidocznych
|
||||
tmp->RenderSounds();
|
||||
}
|
||||
}
|
||||
}
|
||||
// renderowanie progresywne - zależne od FPS oraz kierunku patrzenia
|
||||
// pre-calculate camera view span
|
||||
double const fieldofviewcosine =
|
||||
std::cos(
|
||||
std::max(
|
||||
// vertical...
|
||||
Global::FieldOfView / Global::ZoomFactor,
|
||||
// ...or horizontal, whichever is bigger
|
||||
Global::FieldOfView / Global::ZoomFactor
|
||||
* std::max( 1.0f, (float)Global::ScreenWidth ) / std::max( 1.0f, (float)Global::ScreenHeight ) ) );
|
||||
|
||||
Ground->iRendered = 0; // ilość renderowanych sektorów
|
||||
Math3D::vector3 direction;
|
||||
for( k = 0; k < Global::iSegmentsRendered; ++k ) // sektory w kolejności odległości
|
||||
{ // przerobione na użycie SectorOrder
|
||||
i = SectorOrder[ k ].x; // na starcie oba >=0
|
||||
j = SectorOrder[ k ].y;
|
||||
do {
|
||||
// pierwszy przebieg: j<=0, i>=0; drugi: j>=0, i<=0; trzeci: j<=0, i<=0 czwarty: j>=0, i>=0;
|
||||
if( j <= 0 )
|
||||
i = -i;
|
||||
j = -j; // i oraz j musi być zmienione wcześniej, żeby continue działało
|
||||
direction = Math3D::vector3( i, 0, j ); // wektor od kamery do danego sektora
|
||||
if( Math3D::LengthSquared3( direction ) > 5 ) // te blisko są zawsze wyświetlane
|
||||
{
|
||||
direction = Math3D::SafeNormalize( direction ); // normalizacja
|
||||
if( Ground->CameraDirection.x * direction.x + Ground->CameraDirection.z * direction.z < 0.5 )
|
||||
continue; // pomijanie sektorów poza kątem patrzenia
|
||||
}
|
||||
// kwadrat kilometrowy nie zawsze, bo szkoda FPS
|
||||
Render( &Ground->Rects[ ( i + c ) / iNumSubRects ][ ( j + r ) / iNumSubRects ] );
|
||||
|
||||
if( ( tmp = Ground->FastGetSubRect( i + c, j + r ) ) != nullptr ) {
|
||||
if( tmp->iNodeCount ) {
|
||||
// o ile są jakieś obiekty, bo po co puste sektory przelatywać
|
||||
Ground->pRendered[ Ground->iRendered++ ] = tmp; // tworzenie listy sektorów do renderowania
|
||||
}
|
||||
}
|
||||
} while( ( i < 0 ) || ( j < 0 ) ); // są 4 przypadki, oprócz i=j=0
|
||||
}
|
||||
// dodać renderowanie terenu z E3D - jedno VBO jest używane dla całego modelu, chyba że jest ich więcej
|
||||
if( Global::pTerrainCompact ) {
|
||||
Global::pTerrainCompact->TerrainRenderVBO( TGroundRect::iFrameNumber );
|
||||
}
|
||||
// renderowanie nieprzezroczystych
|
||||
for( i = 0; i < Ground->iRendered; ++i ) {
|
||||
Render( Ground->pRendered[ i ] );
|
||||
}
|
||||
// regular render takes care of all solid geometry present in the scene, thus we can launch alpha parts render here
|
||||
return Render_Alpha( Ground );
|
||||
}
|
||||
|
||||
// TODO: unify ground render code, until then old version is in place
|
||||
#define EU07_USE_OLD_RENDERCODE
|
||||
bool
|
||||
opengl_renderer::Render( TGroundRect *Groundcell ) {
|
||||
|
||||
::glPushMatrix();
|
||||
auto const &cellorigin = Groundcell->m_area.center;
|
||||
// TODO: unify all math objects
|
||||
auto const originoffset = Math3D::vector3( cellorigin.x, cellorigin.y, cellorigin.z ) - Global::pCameraPosition;
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
|
||||
bool result{ false }; // will be true if we do any rendering
|
||||
|
||||
// TODO: unify render paths
|
||||
|
||||
if ( Groundcell->iLastDisplay != Groundcell->iFrameNumber)
|
||||
{ // tylko jezeli dany kwadrat nie był jeszcze renderowany
|
||||
Groundcell->LoadNodes(); // ewentualne tworzenie siatek
|
||||
if ( Groundcell->nRenderRect && Groundcell->StartVBO())
|
||||
{
|
||||
for (TGroundNode *node = Groundcell->nRenderRect; node; node = node->nNext3) // następny tej grupy
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
node->RaRenderVBO(); // nieprzezroczyste trójkąty kwadratu kilometrowego
|
||||
#else
|
||||
Render( node ); // nieprzezroczyste trójkąty kwadratu kilometrowego
|
||||
#endif
|
||||
Groundcell->EndVBO();
|
||||
Groundcell->iLastDisplay = Groundcell->iFrameNumber;
|
||||
result = true;
|
||||
}
|
||||
if ( Groundcell->nTerrain)
|
||||
Groundcell->nTerrain->smTerrain->iVisible = Groundcell->iFrameNumber; // ma się wyświetlić w tej ramce
|
||||
}
|
||||
::glPopMatrix();
|
||||
|
||||
return result;
|
||||
}
|
||||
#undef EU07_USE_OLD_RENDERCODE
|
||||
|
||||
bool
|
||||
opengl_renderer::Render( TSubRect *Groundsubcell ) {
|
||||
|
||||
Groundsubcell->RaAnimate(); // przeliczenia animacji torów w sektorze
|
||||
|
||||
TGroundNode *node;
|
||||
// nieprzezroczyste obiekty terenu
|
||||
|
||||
// vbo render path
|
||||
if( Groundsubcell->StartVBO() ) {
|
||||
for( node = Groundsubcell->nRenderRect; node; node = node->nNext3 ) {
|
||||
if( node->iVboPtr >= 0 ) {
|
||||
Render( node );
|
||||
}
|
||||
}
|
||||
Groundsubcell->EndVBO();
|
||||
}
|
||||
|
||||
// nieprzezroczyste obiekty (oprócz pojazdów)
|
||||
for( node = Groundsubcell->nRender; node; node = node->nNext3 )
|
||||
Render( node );
|
||||
// nieprzezroczyste z mieszanych modeli
|
||||
for( node = Groundsubcell->nRenderMixed; node; node = node->nNext3 )
|
||||
Render( node );
|
||||
// nieprzezroczyste fragmenty pojazdów na torach
|
||||
for( int j = 0; j < Groundsubcell->iTracks; ++j )
|
||||
Groundsubcell->tTracks[ j ]->RenderDyn();
|
||||
#ifdef EU07_SCENERY_EDITOR
|
||||
// memcells
|
||||
if( DebugModeFlag ) {
|
||||
for( auto const memcell : m_memcells ) {
|
||||
memcell->RenderDL();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
opengl_renderer::Render( TGroundNode *Node ) {
|
||||
|
||||
Node->SetLastUsage( Timer::GetSimulationTime() );
|
||||
|
||||
switch (Node->iType)
|
||||
{ // obiekty renderowane niezależnie od odległości
|
||||
case TP_SUBMODEL:
|
||||
::glPushMatrix();
|
||||
auto const originoffset = Node->pCenter - Global::pCameraPosition;
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
TSubModel::fSquareDist = 0;
|
||||
Render( Node->smTerrain );
|
||||
::glPopMatrix();
|
||||
return true;
|
||||
}
|
||||
|
||||
double const distancesquared = SquareMagnitude( ( Node->pCenter - Global::pCameraPosition ) / Global::ZoomFactor );
|
||||
if( ( distancesquared > ( Node->fSquareRadius * Global::fDistanceFactor ) )
|
||||
|| ( distancesquared < ( Node->fSquareMinRadius / Global::fDistanceFactor ) ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (Node->iType)
|
||||
{
|
||||
case TP_TRACK: {
|
||||
|
||||
if( ( Node->iNumVerts <= 0 ) ) {
|
||||
return false;
|
||||
}
|
||||
// setup
|
||||
::glPushMatrix();
|
||||
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
|
||||
// TODO: unify the render code after generic buffers are in place
|
||||
// vbo render path
|
||||
Node->pTrack->RaRenderVBO( Node->iVboPtr );
|
||||
|
||||
// post-render cleanup
|
||||
::glPopMatrix();
|
||||
return true;
|
||||
}
|
||||
case TP_MODEL: {
|
||||
Node->Model->Render( Node->pCenter - Global::pCameraPosition );
|
||||
return true;
|
||||
}
|
||||
case TP_MEMCELL: {
|
||||
GfxRenderer.Render( Node->MemCell );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: sprawdzic czy jest potrzebny warunek fLineThickness < 0
|
||||
if( ( Node->iFlags & 0x10 )
|
||||
|| ( Node->fLineThickness < 0 ) ) {
|
||||
// TODO: unify the render code after generic buffers are in place
|
||||
|
||||
if( ( Node->iType == GL_LINES )
|
||||
|| ( Node->iType == GL_LINE_STRIP )
|
||||
|| ( Node->iType == GL_LINE_LOOP ) ) {
|
||||
// wszelkie linie są rysowane na samym końcu
|
||||
if( Node->iNumPts ) {
|
||||
// setup
|
||||
// w zaleznosci od koloru swiatla
|
||||
::glColor4ub(
|
||||
static_cast<GLubyte>( std::floor( Node->Diffuse[ 0 ] * Global::daylight.ambient.x ) ),
|
||||
static_cast<GLubyte>( std::floor( Node->Diffuse[ 1 ] * Global::daylight.ambient.y ) ),
|
||||
static_cast<GLubyte>( std::floor( Node->Diffuse[ 2 ] * Global::daylight.ambient.z ) ),
|
||||
static_cast<GLubyte>( std::min( 255.0, 255000 * Node->fLineThickness / ( distancesquared + 1.0 ) ) ) );
|
||||
|
||||
GfxRenderer.Bind( 0 );
|
||||
|
||||
// render
|
||||
// TODO: unify the render code after generic buffers are in place
|
||||
::glPushMatrix();
|
||||
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
::glDrawArrays( Node->iType, Node->iVboPtr, Node->iNumPts );
|
||||
::glPopMatrix();
|
||||
// post-render cleanup
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// GL_TRIANGLE etc
|
||||
if (Node->iVboPtr < 0) {
|
||||
return false;
|
||||
}
|
||||
// setup
|
||||
::glColor3ub(
|
||||
static_cast<GLubyte>( Node->Diffuse[ 0 ] ),
|
||||
static_cast<GLubyte>( Node->Diffuse[ 1 ] ),
|
||||
static_cast<GLubyte>( Node->Diffuse[ 2 ] ) );
|
||||
|
||||
Bind( Node->TextureID );
|
||||
|
||||
// render
|
||||
// TODO: unify the render code after generic buffers are in place
|
||||
// vbo render path
|
||||
::glPushMatrix();
|
||||
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
::glDrawArrays( Node->iType, Node->iVboPtr, Node->iNumVerts );
|
||||
::glPopMatrix();
|
||||
// post-render cleanup
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// in theory we shouldn't ever get here but, eh
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
||||
|
||||
if( false == m_camera.visible( Dynamic ) ) {
|
||||
|
||||
Dynamic->renderme = false;
|
||||
Dynamic->renderme = m_camera.visible( Dynamic );
|
||||
if( false == Dynamic->renderme ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Dynamic->renderme = true;
|
||||
|
||||
// setup
|
||||
TSubModel::iInstance = ( size_t )this; //żeby nie robić cudzych animacji
|
||||
double squaredistance = SquareMagnitude( ( Global::pCameraPosition - Dynamic->vPosition ) / Global::ZoomFactor );
|
||||
auto const originoffset = Dynamic->vPosition - Global::pCameraPosition;
|
||||
double const squaredistance = SquareMagnitude( originoffset / Global::ZoomFactor );
|
||||
Dynamic->ABuLittleUpdate( squaredistance ); // ustawianie zmiennych submodeli dla wspólnego modelu
|
||||
|
||||
::glPushMatrix();
|
||||
|
||||
/*
|
||||
if( Dynamic == Global::pUserDynamic ) {
|
||||
//specjalne ustawienie, aby nie trzęsło
|
||||
//tu trzeba by ustawić animacje na modelu zewnętrznym
|
||||
@@ -335,7 +629,8 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
||||
}
|
||||
else
|
||||
::glTranslated( Dynamic->vPosition.x, Dynamic->vPosition.y, Dynamic->vPosition.z ); // standardowe przesunięcie względem początku scenerii
|
||||
|
||||
*/
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
::glMultMatrixd( Dynamic->mMatrix.getArray() );
|
||||
|
||||
if( Dynamic->fShade > 0.0f ) {
|
||||
@@ -434,7 +729,8 @@ opengl_renderer::Render( TModel3d *Model, material_data const *Material, Math3D:
|
||||
if( Angle.z != 0.0 )
|
||||
::glRotated( Angle.z, 0.0, 0.0, 1.0 );
|
||||
|
||||
auto const result = Render( Model, Material, SquareMagnitude( Position - Global::GetCameraPosition() ) );
|
||||
// auto const result = Render( Model, Material, SquareMagnitude( Position / Global::ZoomFactor ) ); // position is effectively camera offset
|
||||
auto const result = Render( Model, Material, SquareMagnitude( Position ) ); // position is effectively camera offset
|
||||
|
||||
::glPopMatrix();
|
||||
|
||||
@@ -512,7 +808,7 @@ opengl_renderer::Render( TSubModel *Submodel, glm::mat4 m) {
|
||||
float const anglefactor = ( Submodel->fCosViewAngle - Submodel->fCosFalloffAngle ) / ( 1.0f - Submodel->fCosFalloffAngle );
|
||||
// distance attenuation. NOTE: since it's fixed pipeline with built-in gamma correction we're using linear attenuation
|
||||
// we're capping how much effect the distance attenuation can have, otherwise the lights get too tiny at regular distances
|
||||
float const distancefactor = std::max( 0.5, ( Submodel->fSquareMaxDist - TSubModel::fSquareDist ) / ( Submodel->fSquareMaxDist * Global::fDistanceFactor ) );
|
||||
float const distancefactor = static_cast<float>( std::max( 0.5, ( Submodel->fSquareMaxDist - TSubModel::fSquareDist ) / ( Submodel->fSquareMaxDist * Global::fDistanceFactor ) ) );
|
||||
|
||||
if( lightlevel > 0.0f ) {
|
||||
glUseProgram(0);
|
||||
@@ -590,7 +886,226 @@ opengl_renderer::Render( TSubModel *Submodel, glm::mat4 m) {
|
||||
|
||||
if( Submodel->Next )
|
||||
if( Submodel->iAlpha & Submodel->iFlags & 0x1F000000 )
|
||||
Render( Submodel->Next, m ); // dalsze rekurencyjnie
|
||||
Render( Submodel->Next ); // dalsze rekurencyjnie
|
||||
}
|
||||
|
||||
void
|
||||
opengl_renderer::Render( TMemCell *Memcell ) {
|
||||
|
||||
::glPushAttrib( GL_ENABLE_BIT );
|
||||
// ::glDisable( GL_LIGHTING );
|
||||
::glDisable( GL_TEXTURE_2D );
|
||||
// ::glEnable( GL_BLEND );
|
||||
::glPushMatrix();
|
||||
|
||||
auto const position = Memcell->Position();
|
||||
::glTranslated( position.x, position.y + 0.5, position.z );
|
||||
::glColor3f( 0.36f, 0.75f, 0.35f );
|
||||
::gluSphere( m_quadric, 0.35, 4, 2 );
|
||||
|
||||
::glPopMatrix();
|
||||
::glPopAttrib();
|
||||
}
|
||||
|
||||
bool
|
||||
opengl_renderer::Render_Alpha( TGround *Ground ) {
|
||||
|
||||
// legacy version of the code:
|
||||
::glEnable( GL_BLEND );
|
||||
::glAlphaFunc( GL_GREATER, 0.04f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f
|
||||
::glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
|
||||
TGroundNode *node;
|
||||
TSubRect *tmp;
|
||||
// Ra: renderowanie progresywne - zależne od FPS oraz kierunku patrzenia
|
||||
for( int i = Ground->iRendered - 1; i >= 0; --i ) // od najdalszych
|
||||
{ // przezroczyste trójkąty w oddzielnym cyklu przed modelami
|
||||
tmp = Ground->pRendered[ i ];
|
||||
// vbo render path
|
||||
if( tmp->StartVBO() ) {
|
||||
for( node = tmp->nRenderRectAlpha; node; node = node->nNext3 ) {
|
||||
if( node->iVboPtr >= 0 ) {
|
||||
Render_Alpha( node );
|
||||
}
|
||||
}
|
||||
tmp->EndVBO();
|
||||
}
|
||||
}
|
||||
for( int i = Ground->iRendered - 1; i >= 0; --i ) // od najdalszych
|
||||
{ // renderowanie przezroczystych modeli oraz pojazdów
|
||||
Render_Alpha( Ground->pRendered[ i ] );
|
||||
}
|
||||
|
||||
::glDisable( GL_LIGHTING ); // linie nie powinny świecić
|
||||
|
||||
for( int i = Ground->iRendered - 1; i >= 0; --i ) // od najdalszych
|
||||
{ // druty na końcu, żeby się nie robiły białe plamy na tle lasu
|
||||
tmp = Ground->pRendered[ i ];
|
||||
// vbo render path
|
||||
if( tmp->StartVBO() ) {
|
||||
for( node = tmp->nRenderWires; node; node = node->nNext3 ) {
|
||||
Render_Alpha( node );
|
||||
}
|
||||
tmp->EndVBO();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
opengl_renderer::Render_Alpha( TSubRect *Groundsubcell ) {
|
||||
|
||||
TGroundNode *node;
|
||||
for( node = Groundsubcell->nRenderMixed; node; node = node->nNext3 )
|
||||
Render_Alpha( node ); // przezroczyste z mieszanych modeli
|
||||
for( node = Groundsubcell->nRenderAlpha; node; node = node->nNext3 )
|
||||
Render_Alpha( node ); // przezroczyste modele
|
||||
for( int j = 0; j < Groundsubcell->iTracks; ++j )
|
||||
Groundsubcell->tTracks[ j ]->RenderDynAlpha(); // przezroczyste fragmenty pojazdów na torach
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// NOTE: legacy render system switch
|
||||
#define _PROBLEND
|
||||
|
||||
bool
|
||||
opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
||||
|
||||
// SPOSOB NA POZBYCIE SIE RAMKI DOOKOLA TEXTURY ALPHA DLA OBIEKTOW ZAGNIEZDZONYCH W SCN JAKO
|
||||
// NODE
|
||||
|
||||
// W GROUND.H dajemy do klasy TGroundNode zmienna bool PROBLEND to samo robimy w klasie TGround
|
||||
// nastepnie podczas wczytywania textury dla TRIANGLES w TGround::AddGroundNode
|
||||
// sprawdzamy czy w nazwie jest @ i wg tego
|
||||
// ustawiamy PROBLEND na true dla wlasnie wczytywanego trojkata (kazdy trojkat jest osobnym
|
||||
// nodem)
|
||||
// nastepnie podczas renderowania w bool TGroundNode::RenderAlpha()
|
||||
// na poczatku ustawiamy standardowe GL_GREATER = 0.04
|
||||
// pozniej sprawdzamy czy jest wlaczony PROBLEND dla aktualnie renderowanego noda TRIANGLE,
|
||||
// wlasciwie dla kazdego node'a
|
||||
// i jezeli tak to odpowiedni GL_GREATER w przeciwnym wypadku standardowy 0.04
|
||||
|
||||
Node->SetLastUsage( Timer::GetSimulationTime() );
|
||||
|
||||
double const distancesquared = SquareMagnitude( ( Node->pCenter - Global::pCameraPosition ) / Global::ZoomFactor );
|
||||
if( ( distancesquared > ( Node->fSquareRadius * Global::fDistanceFactor ) )
|
||||
|| ( distancesquared < ( Node->fSquareMinRadius / Global::fDistanceFactor ) ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (Node->iType)
|
||||
{
|
||||
case TP_TRACTION: {
|
||||
// TODO: unify the render code after generic buffers are in place
|
||||
if( Node->bVisible ) {
|
||||
// setup
|
||||
::glPushMatrix();
|
||||
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
// render
|
||||
Node->hvTraction->RenderVBO( distancesquared, Node->iVboPtr );
|
||||
// post-render cleanup
|
||||
::glPopMatrix();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
case TP_MODEL: {
|
||||
Node->Model->RenderAlpha( Node->pCenter - Global::pCameraPosition );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: sprawdzic czy jest potrzebny warunek fLineThickness < 0
|
||||
if( ( Node->iNumVerts && ( Node->iFlags & 0x20 ) )
|
||||
|| ( Node->iNumPts && ( Node->fLineThickness > 0 ) ) ) {
|
||||
|
||||
#ifdef _PROBLEND
|
||||
if( ( Node->PROBLEND ) ) // sprawdza, czy w nazwie nie ma @ //Q: 13122011 - Szociu: 27012012
|
||||
{
|
||||
::glDisable( GL_BLEND );
|
||||
::glAlphaFunc( GL_GREATER, 0.50f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f
|
||||
};
|
||||
#endif
|
||||
// TODO: unify the render code after generic buffers are in place
|
||||
// additional setup for display lists
|
||||
if( ( Node->DisplayListID == 0 )
|
||||
|| ( Node->iVersion != Global::iReCompile ) ) { // Ra: wymuszenie rekompilacji
|
||||
Node->Compile(Node->m_rootposition);
|
||||
if( Global::bManageNodes )
|
||||
ResourceManager::Register( Node );
|
||||
};
|
||||
|
||||
bool result( false );
|
||||
|
||||
if( ( Node->iType == GL_LINES )
|
||||
|| ( Node->iType == GL_LINE_STRIP )
|
||||
|| ( Node->iType == GL_LINE_LOOP ) ) {
|
||||
// wszelkie linie są rysowane na samym końcu
|
||||
if( Node->iNumPts ) {
|
||||
// setup
|
||||
::glPushMatrix();
|
||||
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
// w zaleznosci od koloru swiatla
|
||||
::glColor4ub(
|
||||
static_cast<GLubyte>( std::floor( Node->Diffuse[ 0 ] * Global::daylight.ambient.x ) ),
|
||||
static_cast<GLubyte>( std::floor( Node->Diffuse[ 1 ] * Global::daylight.ambient.y ) ),
|
||||
static_cast<GLubyte>( std::floor( Node->Diffuse[ 2 ] * Global::daylight.ambient.z ) ),
|
||||
static_cast<GLubyte>( std::min( 255.0, 255000 * Node->fLineThickness / ( distancesquared + 1.0 ) ) ) );
|
||||
|
||||
GfxRenderer.Bind( 0 );
|
||||
|
||||
// render
|
||||
// TODO: unify the render code after generic buffers are in place
|
||||
::glDrawArrays( Node->iType, Node->iVboPtr, Node->iNumPts );
|
||||
// post-render cleanup
|
||||
::glPopMatrix();
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// GL_TRIANGLE etc
|
||||
// setup
|
||||
::glPushMatrix();
|
||||
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
|
||||
::glColor3ub(
|
||||
static_cast<GLubyte>( Node->Diffuse[ 0 ] ),
|
||||
static_cast<GLubyte>( Node->Diffuse[ 1 ] ),
|
||||
static_cast<GLubyte>( Node->Diffuse[ 2 ] ) );
|
||||
|
||||
Bind( Node->TextureID );
|
||||
|
||||
// render
|
||||
// TODO: unify the render code after generic buffers are in place
|
||||
|
||||
// vbo render path
|
||||
if( Node->iVboPtr >= 0 ) {
|
||||
::glDrawArrays( Node->iType, Node->iVboPtr, Node->iNumVerts );
|
||||
result = true;
|
||||
}
|
||||
|
||||
// post-render cleanup
|
||||
::glPopMatrix();
|
||||
}
|
||||
|
||||
#ifdef _PROBLEND
|
||||
if( ( Node->PROBLEND ) ) // sprawdza, czy w nazwie nie ma @ //Q: 13122011 - Szociu: 27012012
|
||||
{
|
||||
::glEnable( GL_BLEND );
|
||||
::glAlphaFunc( GL_GREATER, 0.04f );
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
// in theory we shouldn't ever get here but, eh
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -603,17 +1118,19 @@ opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
|
||||
|
||||
// setup
|
||||
TSubModel::iInstance = ( size_t )this; //żeby nie robić cudzych animacji
|
||||
double squaredistance = SquareMagnitude( ( Global::pCameraPosition - Dynamic->vPosition ) / Global::ZoomFactor );
|
||||
auto const originoffset = Dynamic->vPosition - Global::pCameraPosition;
|
||||
double const squaredistance = SquareMagnitude( originoffset / Global::ZoomFactor );
|
||||
Dynamic->ABuLittleUpdate( squaredistance ); // ustawianie zmiennych submodeli dla wspólnego modelu
|
||||
|
||||
::glPushMatrix();
|
||||
/*
|
||||
if( Dynamic == Global::pUserDynamic ) { // specjalne ustawienie, aby nie trzęsło
|
||||
::glLoadIdentity(); // zacząć od macierzy jedynkowej
|
||||
Global::pCamera->SetCabMatrix( Dynamic->vPosition ); // specjalne ustawienie kamery
|
||||
}
|
||||
else
|
||||
::glTranslated( Dynamic->vPosition.x, Dynamic->vPosition.y, Dynamic->vPosition.z ); // standardowe przesunięcie względem początku scenerii
|
||||
|
||||
*/
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
::glMultMatrixd( Dynamic->mMatrix.getArray() );
|
||||
|
||||
if( Dynamic->fShade > 0.0f ) {
|
||||
@@ -711,7 +1228,8 @@ opengl_renderer::Render_Alpha( TModel3d *Model, material_data const *Material, M
|
||||
if( Angle.z != 0.0 )
|
||||
::glRotated( Angle.z, 0.0, 0.0, 1.0 );
|
||||
|
||||
auto const result = Render_Alpha( Model, Material, SquareMagnitude( Position - Global::GetCameraPosition() ) );
|
||||
// auto const result = Render_Alpha( Model, Material, SquareMagnitude( Position / Global::ZoomFactor ) ); // position is effectively camera offset
|
||||
auto const result = Render_Alpha( Model, Material, SquareMagnitude( Position ) ); // position is effectively camera offset
|
||||
|
||||
::glPopMatrix();
|
||||
|
||||
@@ -849,9 +1367,9 @@ opengl_renderer::Update ( double const Deltatime ) {
|
||||
int targetsegments;
|
||||
float targetfactor;
|
||||
|
||||
if( framerate > 65.0 ) { targetsegments = 400; targetfactor = 3.0f; }
|
||||
else if( framerate > 40.0 ) { targetsegments = 225; targetfactor = 1.5f; }
|
||||
else if( framerate > 15.0 ) { targetsegments = 90; targetfactor = Global::ScreenHeight / 768.0f; }
|
||||
if( framerate > 90.0 ) { targetsegments = 400; targetfactor = 3.0f; }
|
||||
else if( framerate > 60.0 ) { targetsegments = 225; targetfactor = 1.5f; }
|
||||
else if( framerate > 30.0 ) { targetsegments = 90; targetfactor = Global::ScreenHeight / 768.0f; }
|
||||
else { targetsegments = 9; targetfactor = Global::ScreenHeight / 768.0f * 0.75f; }
|
||||
|
||||
if( targetsegments > Global::iSegmentsRendered ) {
|
||||
|
||||
Reference in New Issue
Block a user