mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-18 00:49:19 +02:00
minor refactoring, shadows colour influenced by sun/moon positions
This commit is contained in:
12
Ground.cpp
12
Ground.cpp
@@ -3493,18 +3493,6 @@ void
|
|||||||
TGround::Update_Lights() {
|
TGround::Update_Lights() {
|
||||||
|
|
||||||
m_lights.update();
|
m_lights.update();
|
||||||
// arrange the light array from closest to farthest from current position of the camera
|
|
||||||
auto const camera = Global::pCameraPosition;
|
|
||||||
std::sort(
|
|
||||||
m_lights.data.begin(),
|
|
||||||
m_lights.data.end(),
|
|
||||||
[&]( light_array::light_record const &Left, light_array::light_record const &Right ) {
|
|
||||||
// move lights which are off at the end...
|
|
||||||
if( Left.intensity == 0.0f ) { return false; }
|
|
||||||
if( Right.intensity == 0.0f ) { return true; }
|
|
||||||
// ...otherwise prefer closer and/or brigher light sources
|
|
||||||
return ((camera - Left.position).LengthSquared() * (1.0f - Left.intensity)) < ((camera - Right.position).LengthSquared() * (1.0f - Right.intensity));
|
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Winger 170204 - szukanie trakcji nad pantografami
|
// Winger 170204 - szukanie trakcji nad pantografami
|
||||||
|
|||||||
@@ -2220,10 +2220,12 @@ world_environment::update() {
|
|||||||
m_sun.update();
|
m_sun.update();
|
||||||
m_moon.update();
|
m_moon.update();
|
||||||
// ...determine source of key light and adjust global state accordingly...
|
// ...determine source of key light and adjust global state accordingly...
|
||||||
auto const sunlightlevel = m_sun.getIntensity();
|
// diffuse (sun) intensity goes down after twilight, and reaches minimum 18 degrees below horizon
|
||||||
|
float twilightfactor = clamp( -m_sun.getAngle(), 0.0f, 18.0f ) / 18.0f;
|
||||||
|
// NOTE: sun light receives extra padding to prevent moon from kicking in too soon
|
||||||
|
auto const sunlightlevel = m_sun.getIntensity() + 0.05f * ( 1.f - twilightfactor );
|
||||||
auto const moonlightlevel = m_moon.getIntensity() * 0.65f; // scaled down by arbitrary factor, it's pretty bright otherwise
|
auto const moonlightlevel = m_moon.getIntensity() * 0.65f; // scaled down by arbitrary factor, it's pretty bright otherwise
|
||||||
float keylightintensity;
|
float keylightintensity;
|
||||||
float twilightfactor;
|
|
||||||
glm::vec3 keylightcolor;
|
glm::vec3 keylightcolor;
|
||||||
if( moonlightlevel > sunlightlevel ) {
|
if( moonlightlevel > sunlightlevel ) {
|
||||||
// rare situations when the moon is brighter than the sun, typically at night
|
// rare situations when the moon is brighter than the sun, typically at night
|
||||||
@@ -2241,8 +2243,7 @@ world_environment::update() {
|
|||||||
Global::DayLight.set_position( m_sun.getPosition() );
|
Global::DayLight.set_position( m_sun.getPosition() );
|
||||||
Global::DayLight.direction = -1.0f * m_sun.getDirection();
|
Global::DayLight.direction = -1.0f * m_sun.getDirection();
|
||||||
keylightintensity = sunlightlevel;
|
keylightintensity = sunlightlevel;
|
||||||
// diffuse (sun) intensity goes down after twilight, and reaches minimum 18 degrees below horizon
|
// include 'golden hour' effect in twilight lighting
|
||||||
twilightfactor = clamp( -Global::SunAngle, 0.0f, 18.0f ) / 18.0f;
|
|
||||||
float const duskfactor = 1.0f - clamp( Global::SunAngle, 0.0f, 18.0f ) / 18.0f;
|
float const duskfactor = 1.0f - clamp( Global::SunAngle, 0.0f, 18.0f ) / 18.0f;
|
||||||
keylightcolor = interpolate(
|
keylightcolor = interpolate(
|
||||||
glm::vec3( 255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f ),
|
glm::vec3( 255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f ),
|
||||||
|
|||||||
21
frustum.cpp
21
frustum.cpp
@@ -83,14 +83,6 @@ cFrustum::calculate( glm::mat4 const &Projection, glm::mat4 const &Modelview ) {
|
|||||||
m_frustum[ side_FRONT ][ plane_C ] = clip[ 11 ] + clip[ 10 ];
|
m_frustum[ side_FRONT ][ plane_C ] = clip[ 11 ] + clip[ 10 ];
|
||||||
m_frustum[ side_FRONT ][ plane_D ] = clip[ 15 ] + clip[ 14 ];
|
m_frustum[ side_FRONT ][ plane_D ] = clip[ 15 ] + clip[ 14 ];
|
||||||
normalize_plane( side_FRONT );
|
normalize_plane( side_FRONT );
|
||||||
|
|
||||||
m_inversetransformation = glm::inverse( Projection * glm::mat4{ glm::mat3{ Modelview } } );
|
|
||||||
|
|
||||||
// calculate frustum corners
|
|
||||||
m_frustumpoints = ndcfrustumshapepoints;
|
|
||||||
transform_to_world(
|
|
||||||
std::begin( m_frustumpoints ),
|
|
||||||
std::end( m_frustumpoints ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -177,19 +169,6 @@ cFrustum::cube_inside( float const X, float const Y, float const Z, float const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::size_t> const frustumshapepoinstorder{ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 };
|
|
||||||
|
|
||||||
// debug helper, draws shape of frustum in world space
|
|
||||||
void
|
|
||||||
cFrustum::draw( glm::vec3 const &Offset ) const {
|
|
||||||
|
|
||||||
::glBegin( GL_LINES );
|
|
||||||
for( auto const pointindex : frustumshapepoinstorder ) {
|
|
||||||
::glVertex3fv( glm::value_ptr( glm::vec3{ m_frustumpoints[ pointindex ] } - Offset ) );
|
|
||||||
}
|
|
||||||
::glEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
void cFrustum::normalize_plane( cFrustum::side const Side ) {
|
void cFrustum::normalize_plane( cFrustum::side const Side ) {
|
||||||
|
|
||||||
float magnitude =
|
float magnitude =
|
||||||
|
|||||||
22
frustum.h
22
frustum.h
@@ -12,10 +12,12 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "float3d.h"
|
#include "float3d.h"
|
||||||
#include "dumb3d.h"
|
#include "dumb3d.h"
|
||||||
|
|
||||||
std::vector<glm::vec4> const ndcfrustumshapepoints = {
|
std::vector<glm::vec4> const ndcfrustumshapepoints {
|
||||||
{ -1, -1, -1, 1 },{ 1, -1, -1, 1 },{ 1, 1, -1, 1 },{ -1, 1, -1, 1 }, // z-near
|
{ -1, -1, -1, 1 },{ 1, -1, -1, 1 },{ 1, 1, -1, 1 },{ -1, 1, -1, 1 }, // z-near
|
||||||
{ -1, -1, 1, 1 },{ 1, -1, 1, 1 },{ 1, 1, 1, 1 },{ -1, 1, 1, 1 } }; // z-far
|
{ -1, -1, 1, 1 },{ 1, -1, 1, 1 },{ 1, 1, 1, 1 },{ -1, 1, 1, 1 } }; // z-far
|
||||||
|
|
||||||
|
std::vector<std::size_t> const frustumshapepoinstorder { 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 };
|
||||||
|
|
||||||
// generic frustum class. used to determine if objects are inside current view area
|
// generic frustum class. used to determine if objects are inside current view area
|
||||||
|
|
||||||
class cFrustum {
|
class cFrustum {
|
||||||
@@ -65,23 +67,6 @@ public:
|
|||||||
cube_inside( Math3D::vector3 const &Center, float const Size ) const { return cube_inside( static_cast<float>( Center.x ), static_cast<float>( Center.y ), static_cast<float>( Center.z ), Size ); }
|
cube_inside( Math3D::vector3 const &Center, float const Size ) const { return cube_inside( static_cast<float>( Center.x ), static_cast<float>( Center.y ), static_cast<float>( Center.z ), Size ); }
|
||||||
bool
|
bool
|
||||||
cube_inside( float const X, float const Y, float const Z, float const Size ) const;
|
cube_inside( float const X, float const Y, float const Z, float const Size ) const;
|
||||||
// transforms provided set of clip space points to world space
|
|
||||||
template <class Iterator_>
|
|
||||||
void
|
|
||||||
transform_to_world( Iterator_ First, Iterator_ Last ) const {
|
|
||||||
std::for_each(
|
|
||||||
First, Last,
|
|
||||||
[this]( glm::vec4 &point ) {
|
|
||||||
// transform each point using the cached matrix...
|
|
||||||
point = this->m_inversetransformation * point;
|
|
||||||
// ...and scale by transformed w
|
|
||||||
point = glm::vec4{ glm::vec3{ point } / point.w, 1.f }; } ); }
|
|
||||||
// debug helper, draws shape of frustum in world space
|
|
||||||
void
|
|
||||||
draw( glm::vec3 const &Offset ) const;
|
|
||||||
|
|
||||||
// members:
|
|
||||||
std::vector<glm::vec4> m_frustumpoints; // coordinates of corners for defined frustum, in world space
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// types:
|
// types:
|
||||||
@@ -96,5 +81,4 @@ private:
|
|||||||
|
|
||||||
// members:
|
// members:
|
||||||
float m_frustum[6][4]; // holds the A B C and D values (normal & distance) for each side of the frustum.
|
float m_frustum[6][4]; // holds the A B C and D values (normal & distance) for each side of the frustum.
|
||||||
glm::mat4 m_inversetransformation; // cached inverse transformation matrix
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -60,10 +60,10 @@ light_array::update() {
|
|||||||
if( ( true == light.owner->MoverParameters->Battery ) || ( true == light.owner->MoverParameters->ConverterFlag ) ) {
|
if( ( true == light.owner->MoverParameters->Battery ) || ( true == light.owner->MoverParameters->ConverterFlag ) ) {
|
||||||
// with power on, the intensity depends on the state of activated switches
|
// with power on, the intensity depends on the state of activated switches
|
||||||
auto const &lightbits = light.owner->iLights[ light.index ];
|
auto const &lightbits = light.owner->iLights[ light.index ];
|
||||||
light.count = 0 +
|
light.count = 0
|
||||||
( ( lightbits & 1 ) ? 1 : 0 ) +
|
+ ( ( lightbits & TMoverParameters::light::headlight_left ) ? 1 : 0 )
|
||||||
( ( lightbits & 4 ) ? 1 : 0 ) +
|
+ ( ( lightbits & TMoverParameters::light::headlight_right ) ? 1 : 0 )
|
||||||
( ( lightbits & 16 ) ? 1 : 0 );
|
+ ( ( lightbits & TMoverParameters::light::headlight_upper ) ? 1 : 0 );
|
||||||
|
|
||||||
if( light.count > 0 ) {
|
if( light.count > 0 ) {
|
||||||
// TODO: intensity can be affected further by dim switch or other factors
|
// TODO: intensity can be affected further by dim switch or other factors
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ public:
|
|||||||
|
|
||||||
TDynamicObject const *owner; // the object in world which 'carries' the light
|
TDynamicObject const *owner; // the object in world which 'carries' the light
|
||||||
int index{ -1 }; // 0: front lights, 1: rear lights
|
int index{ -1 }; // 0: front lights, 1: rear lights
|
||||||
Math3D::vector3 position; // position of the light in 3d scene
|
glm::dvec3 position; // position of the light in 3d scene
|
||||||
glm::vec3 direction; // direction of the light in 3d scene
|
glm::vec3 direction; // direction of the light in 3d scene
|
||||||
float3 color{ 255.0f / 255.0f, 241.0f / 255.0f, 224.0f / 255.0f }; // color of the light, default is halogen light
|
glm::vec3 color{ 255.0f / 255.0f, 241.0f / 255.0f, 224.0f / 255.0f }; // color of the light, default is halogen light
|
||||||
float intensity{ 0.0f }; // (combined) intensity of the light(s)
|
float intensity{ 0.0f }; // (combined) intensity of the light(s)
|
||||||
int count{ 0 }; // number (or pattern) of active light(s)
|
int count{ 0 }; // number (or pattern) of active light(s)
|
||||||
};
|
};
|
||||||
|
|||||||
187
renderer.cpp
187
renderer.cpp
@@ -34,6 +34,20 @@ glm::vec4 const white{ 1.f, 1.f, 1.f, 1.f };
|
|||||||
|
|
||||||
} // namespace colors
|
} // namespace colors
|
||||||
|
|
||||||
|
void
|
||||||
|
opengl_camera::update_frustum( glm::mat4 const &Projection, glm::mat4 const &Modelview ) {
|
||||||
|
|
||||||
|
m_frustum.calculate( Projection, Modelview );
|
||||||
|
// cache inverse tranformation matrix
|
||||||
|
// NOTE: transformation is done only to camera-centric space
|
||||||
|
m_inversetransformation = glm::inverse( Projection * glm::mat4{ glm::mat3{ Modelview } } );
|
||||||
|
// calculate frustum corners
|
||||||
|
m_frustumpoints = ndcfrustumshapepoints;
|
||||||
|
transform_to_world(
|
||||||
|
std::begin( m_frustumpoints ),
|
||||||
|
std::end( m_frustumpoints ) );
|
||||||
|
}
|
||||||
|
|
||||||
// returns true if specified object is within camera frustum, false otherwise
|
// returns true if specified object is within camera frustum, false otherwise
|
||||||
bool
|
bool
|
||||||
opengl_camera::visible( bounding_area const &Area ) const {
|
opengl_camera::visible( bounding_area const &Area ) const {
|
||||||
@@ -55,6 +69,17 @@ opengl_camera::visible( TDynamicObject const *Dynamic ) const {
|
|||||||
return ( m_frustum.sphere_inside( Dynamic->GetPosition(), radius ) > 0.0f );
|
return ( m_frustum.sphere_inside( Dynamic->GetPosition(), radius ) > 0.0f );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// debug helper, draws shape of frustum in world space
|
||||||
|
void
|
||||||
|
opengl_camera::draw( glm::vec3 const &Offset ) const {
|
||||||
|
|
||||||
|
::glBegin( GL_LINES );
|
||||||
|
for( auto const pointindex : frustumshapepoinstorder ) {
|
||||||
|
::glVertex3fv( glm::value_ptr( glm::vec3{ m_frustumpoints[ pointindex ] } - Offset ) );
|
||||||
|
}
|
||||||
|
::glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
opengl_renderer::Init( GLFWwindow *Window ) {
|
opengl_renderer::Init( GLFWwindow *Window ) {
|
||||||
|
|
||||||
@@ -251,15 +276,16 @@ opengl_renderer::Render() {
|
|||||||
m_drawtime = std::max( 20.f, 0.95f * m_drawtime + std::chrono::duration_cast<std::chrono::microseconds>( ( std::chrono::steady_clock::now() - m_drawstart ) ).count() / 1000.f );
|
m_drawtime = std::max( 20.f, 0.95f * m_drawtime + std::chrono::duration_cast<std::chrono::microseconds>( ( std::chrono::steady_clock::now() - m_drawstart ) ).count() / 1000.f );
|
||||||
}
|
}
|
||||||
m_drawstart = std::chrono::steady_clock::now();
|
m_drawstart = std::chrono::steady_clock::now();
|
||||||
auto const drawstartcolor = m_drawstart;
|
auto const drawstartcolorpass = m_drawstart;
|
||||||
|
|
||||||
m_renderpass.draw_mode = rendermode::none; // force setup anew
|
m_renderpass.draw_mode = rendermode::none; // force setup anew
|
||||||
|
m_debuginfo.clear();
|
||||||
Render_pass( rendermode::color );
|
Render_pass( rendermode::color );
|
||||||
|
|
||||||
m_drawcount = m_drawqueue.size();
|
m_drawcount = m_drawqueue.size();
|
||||||
// accumulate last 20 frames worth of render time (cap at 1000 fps to prevent calculations going awry)
|
// accumulate last 20 frames worth of render time (cap at 1000 fps to prevent calculations going awry)
|
||||||
m_drawtimecolor = std::max( 20.f, 0.95f * m_drawtimecolor + std::chrono::duration_cast<std::chrono::microseconds>( ( std::chrono::steady_clock::now() - drawstartcolor ) ).count() / 1000.f );
|
m_drawtimecolorpass = std::max( 20.f, 0.95f * m_drawtimecolorpass + std::chrono::duration_cast<std::chrono::microseconds>( ( std::chrono::steady_clock::now() - drawstartcolorpass ) ).count() / 1000.f );
|
||||||
m_debuginfo += " frame total: " + to_string( m_drawtimecolor / 20.f, 2 ) + " msec (" + std::to_string( m_drawqueue.size() ) + " sectors)";
|
m_debuginfo += "frame total: " + to_string( m_drawtimecolorpass / 20.f, 2 ) + " msec (" + std::to_string( m_drawqueue.size() ) + " sectors) ";
|
||||||
|
|
||||||
glfwSwapBuffers( m_window );
|
glfwSwapBuffers( m_window );
|
||||||
|
|
||||||
@@ -270,25 +296,26 @@ opengl_renderer::Render() {
|
|||||||
void
|
void
|
||||||
opengl_renderer::Render_pass( rendermode const Mode ) {
|
opengl_renderer::Render_pass( rendermode const Mode ) {
|
||||||
|
|
||||||
m_renderpass.setup( Mode, m_framebuffersupport );
|
setup_pass( m_renderpass, Mode );
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
|
|
||||||
case rendermode::color: {
|
case rendermode::color: {
|
||||||
|
|
||||||
opengl_camera shadowcamera; // temporary helper, remove once ortho shadowmap code is done
|
opengl_camera shadowcamera; // temporary helper, remove once ortho shadowmap code is done
|
||||||
if( Global::RenderShadows && World.InitPerformed() ) {
|
if( ( true == Global::RenderShadows )
|
||||||
|
&& ( true == World.InitPerformed() )
|
||||||
|
&& ( m_shadowcolor != colors::white ) ) {
|
||||||
// run shadowmap pass before color
|
// run shadowmap pass before color
|
||||||
Render_pass( rendermode::shadows );
|
Render_pass( rendermode::shadows );
|
||||||
#ifdef EU07_USE_DEBUG_SHADOWMAP
|
#ifdef EU07_USE_DEBUG_SHADOWMAP
|
||||||
UILayer.set_texture( m_shadowdebugtexture );
|
UILayer.set_texture( m_shadowdebugtexture );
|
||||||
#endif
|
#endif
|
||||||
shadowcamera = m_renderpass.camera; // cache shadow camera placement for visualization
|
shadowcamera = m_renderpass.camera; // cache shadow camera placement for visualization
|
||||||
|
setup_pass( m_renderpass, Mode ); // restore draw mode. TBD, TODO: render mode stack
|
||||||
m_renderpass.setup( rendermode::color, m_framebuffersupport ); // restore draw mode. TBD, TODO: render mode stack
|
|
||||||
#ifdef EU07_USE_DEBUG_CAMERA
|
#ifdef EU07_USE_DEBUG_CAMERA
|
||||||
m_worldcamera.setup(
|
setup_pass(
|
||||||
|
m_worldcamera,
|
||||||
rendermode::color,
|
rendermode::color,
|
||||||
m_framebuffersupport,
|
|
||||||
0.f,
|
0.f,
|
||||||
std::min(
|
std::min(
|
||||||
1.f,
|
1.f,
|
||||||
@@ -337,10 +364,10 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
::glColor4f( 1.f, 0.9f, 0.8f, 1.f );
|
::glColor4f( 1.f, 0.9f, 0.8f, 1.f );
|
||||||
::glDisable( GL_LIGHTING );
|
::glDisable( GL_LIGHTING );
|
||||||
::glDisable( GL_TEXTURE_2D );
|
::glDisable( GL_TEXTURE_2D );
|
||||||
shadowcamera.frustum().draw( m_renderpass.camera.position() - shadowcamera.position() );
|
shadowcamera.draw( m_renderpass.camera.position() - shadowcamera.position() );
|
||||||
if( DebugCameraFlag ) {
|
if( DebugCameraFlag ) {
|
||||||
::glColor4f( 0.8f, 1.f, 0.9f, 1.f );
|
::glColor4f( 0.8f, 1.f, 0.9f, 1.f );
|
||||||
m_worldcamera.camera.frustum().draw( m_renderpass.camera.position() - m_worldcamera.camera.position() );
|
m_worldcamera.camera.draw( m_renderpass.camera.position() - m_worldcamera.camera.position() );
|
||||||
}
|
}
|
||||||
::glLineWidth( 1.f );
|
::glLineWidth( 1.f );
|
||||||
::glEnable( GL_LIGHTING );
|
::glEnable( GL_LIGHTING );
|
||||||
@@ -397,8 +424,8 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
|
|
||||||
::glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); // switch back to primary render target
|
::glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); // switch back to primary render target
|
||||||
|
|
||||||
m_drawtimeshadows = 0.95f * m_drawtimeshadows + std::chrono::duration_cast<std::chrono::microseconds>( ( std::chrono::steady_clock::now() - shadowdrawstart ) ).count() / 1000.f;
|
m_drawtimeshadowpass = 0.95f * m_drawtimeshadowpass + std::chrono::duration_cast<std::chrono::microseconds>( ( std::chrono::steady_clock::now() - shadowdrawstart ) ).count() / 1000.f;
|
||||||
m_debuginfo = "shadows: " + to_string( m_drawtimeshadows / 20.f, 2 ) + " msec (" + std::to_string( m_drawqueue.size() ) + " sectors)";
|
m_debuginfo += "shadows: " + to_string( m_drawtimeshadowpass / 20.f, 2 ) + " msec (" + std::to_string( m_drawqueue.size() ) + " sectors) ";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -453,27 +480,29 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
opengl_renderer::renderpass_config::setup( rendermode const Mode, bool const Framebuffersupport, float const Znear, float const Zfar, bool const Ignoredebug ) {
|
opengl_renderer::setup_pass( renderpass_config &Config, rendermode const Mode, float const Znear, float const Zfar, bool const Ignoredebug ) {
|
||||||
|
|
||||||
draw_mode = Mode;
|
Config.draw_mode = Mode;
|
||||||
|
|
||||||
if( false == World.InitPerformed() ) { return; }
|
if( false == World.InitPerformed() ) { return; }
|
||||||
|
// setup draw range
|
||||||
switch( draw_mode ) {
|
switch( Mode ) {
|
||||||
case rendermode::color: { draw_range = Global::BaseDrawRange; break; }
|
case rendermode::color: { Config.draw_range = Global::BaseDrawRange; break; }
|
||||||
case rendermode::shadows: { draw_range = Global::BaseDrawRange * 0.5f; break; }
|
case rendermode::shadows: { Config.draw_range = Global::BaseDrawRange * 0.5f; break; }
|
||||||
case rendermode::pickcontrols: { draw_range = 50.f; break; }
|
case rendermode::pickcontrols: { Config.draw_range = 50.f; break; }
|
||||||
case rendermode::pickscenery: { draw_range = Global::BaseDrawRange * 0.5f; break; }
|
case rendermode::pickscenery: { Config.draw_range = Global::BaseDrawRange * 0.5f; break; }
|
||||||
default: { draw_range = 0.f; break; }
|
default: { Config.draw_range = 0.f; break; }
|
||||||
}
|
}
|
||||||
|
// setup camera
|
||||||
|
auto &camera = Config.camera;
|
||||||
|
|
||||||
camera.projection() = glm::mat4( 1.f );
|
camera.projection() = glm::mat4( 1.f );
|
||||||
glm::dmat4 viewmatrix( 1.0 );
|
glm::dmat4 viewmatrix( 1.0 );
|
||||||
|
|
||||||
switch( draw_mode ) {
|
switch( Mode ) {
|
||||||
case rendermode::color: {
|
case rendermode::color: {
|
||||||
// projection
|
// projection
|
||||||
auto const zfar = draw_range * Global::fDistanceFactor * Zfar;
|
auto const zfar = Config.draw_range * Global::fDistanceFactor * Zfar;
|
||||||
auto const znear = (
|
auto const znear = (
|
||||||
Znear > 0.f ?
|
Znear > 0.f ?
|
||||||
Znear * zfar :
|
Znear * zfar :
|
||||||
@@ -498,33 +527,29 @@ opengl_renderer::renderpass_config::setup( rendermode const Mode, bool const Fra
|
|||||||
|
|
||||||
case rendermode::shadows: {
|
case rendermode::shadows: {
|
||||||
// calculate lightview boundaries based on relevant area of the world camera frustum:
|
// calculate lightview boundaries based on relevant area of the world camera frustum:
|
||||||
// setup chunk of frustum we're interested in...
|
// ...setup chunk of frustum we're interested in...
|
||||||
auto const znear = 0.f;
|
auto const znear = 0.f;
|
||||||
auto const zfar = std::min( 1.f, Global::shadowtune.depth / ( Global::BaseDrawRange * Global::fDistanceFactor ) * std::max( 1.f, Global::ZoomFactor * 0.5f ) );
|
auto const zfar = std::min( 1.f, Global::shadowtune.depth / ( Global::BaseDrawRange * Global::fDistanceFactor ) * std::max( 1.f, Global::ZoomFactor * 0.5f ) );
|
||||||
renderpass_config worldview;
|
renderpass_config worldview;
|
||||||
worldview.setup( rendermode::color, Framebuffersupport, znear, zfar, true );
|
setup_pass( worldview, rendermode::color, znear, zfar, true );
|
||||||
// ...transform frustum shape to camera-centric world space...
|
auto &frustumchunkshapepoints = worldview.camera.frustum_points();
|
||||||
auto frustumchunkshapepoints = ndcfrustumshapepoints;
|
// ...modelview matrix: determine the centre of frustum chunk in world space...
|
||||||
worldview.camera.frustum().transform_to_world( std::begin( frustumchunkshapepoints ), std::end( frustumchunkshapepoints ) );
|
|
||||||
// ...determine the centre of frustum chunk in world space...
|
|
||||||
glm::vec3 frustumchunkmin, frustumchunkmax;
|
glm::vec3 frustumchunkmin, frustumchunkmax;
|
||||||
bounding_box( frustumchunkmin, frustumchunkmax, std::begin( frustumchunkshapepoints ), std::end( frustumchunkshapepoints ) );
|
bounding_box( frustumchunkmin, frustumchunkmax, std::begin( frustumchunkshapepoints ), std::end( frustumchunkshapepoints ) );
|
||||||
auto const frustumchunkcentre = ( frustumchunkmin + frustumchunkmax ) * 0.5f;
|
auto const frustumchunkcentre = ( frustumchunkmin + frustumchunkmax ) * 0.5f;
|
||||||
auto const lighttarget = worldview.camera.position() + glm::dvec3{ frustumchunkcentre };
|
// ...cap the vertical angle to keep shadows from getting too long...
|
||||||
|
|
||||||
auto const lightvector =
|
auto const lightvector =
|
||||||
glm::normalize( glm::vec3{
|
glm::normalize( glm::vec3{
|
||||||
-Global::DayLight.direction.x,
|
Global::DayLight.direction.x,
|
||||||
std::max( -Global::DayLight.direction.y, 0.15f ),
|
std::min( Global::DayLight.direction.y, -0.15f ),
|
||||||
-Global::DayLight.direction.z } );
|
Global::DayLight.direction.z } );
|
||||||
// ...place the light source at the calculated centre...
|
// ...place the light source at the calculated centre and setup world space light view matrix...
|
||||||
camera.position() = lighttarget;// -glm::dvec3{ lightvector };
|
camera.position() = worldview.camera.position() + glm::dvec3{ frustumchunkcentre };
|
||||||
// ...setup world space light view matrix...
|
|
||||||
viewmatrix *= glm::lookAt(
|
viewmatrix *= glm::lookAt(
|
||||||
camera.position(),
|
camera.position(),
|
||||||
camera.position() - glm::dvec3{ lightvector },
|
camera.position() + glm::dvec3{ lightvector },
|
||||||
glm::dvec3{ 0.f, 1.f, 0.f } );
|
glm::dvec3{ 0.f, 1.f, 0.f } );
|
||||||
// ...calculate boundaries of the frustum chunk in light space...
|
// ...projection matrix: calculate boundaries of the frustum chunk in light space...
|
||||||
auto const lightviewmatrix =
|
auto const lightviewmatrix =
|
||||||
glm::translate(
|
glm::translate(
|
||||||
glm::mat4{ glm::mat3{ viewmatrix } },
|
glm::mat4{ glm::mat3{ viewmatrix } },
|
||||||
@@ -547,7 +572,7 @@ opengl_renderer::renderpass_config::setup( rendermode const Mode, bool const Fra
|
|||||||
case rendermode::pickscenery: {
|
case rendermode::pickscenery: {
|
||||||
// TODO: scissor test for pick modes
|
// TODO: scissor test for pick modes
|
||||||
// projection
|
// projection
|
||||||
if( true == Framebuffersupport ) {
|
if( true == m_framebuffersupport ) {
|
||||||
auto const angle = Global::FieldOfView / Global::ZoomFactor;
|
auto const angle = Global::FieldOfView / Global::ZoomFactor;
|
||||||
auto const height = std::max( 1.0f, (float)Global::iWindowWidth ) / std::max( 1.0f, (float)Global::iWindowHeight ) / ( Global::iWindowWidth / EU07_PICKBUFFERSIZE );
|
auto const height = std::max( 1.0f, (float)Global::iWindowWidth ) / std::max( 1.0f, (float)Global::iWindowHeight ) / ( Global::iWindowWidth / EU07_PICKBUFFERSIZE );
|
||||||
camera.projection() *=
|
camera.projection() *=
|
||||||
@@ -555,7 +580,7 @@ opengl_renderer::renderpass_config::setup( rendermode const Mode, bool const Fra
|
|||||||
glm::radians( Global::FieldOfView / Global::ZoomFactor ),
|
glm::radians( Global::FieldOfView / Global::ZoomFactor ),
|
||||||
std::max( 1.f, (float)Global::iWindowWidth ) / std::max( 1.0f, (float)Global::iWindowHeight ) / ( Global::iWindowWidth / EU07_PICKBUFFERSIZE ),
|
std::max( 1.f, (float)Global::iWindowWidth ) / std::max( 1.0f, (float)Global::iWindowHeight ) / ( Global::iWindowWidth / EU07_PICKBUFFERSIZE ),
|
||||||
0.1f * Global::ZoomFactor,
|
0.1f * Global::ZoomFactor,
|
||||||
draw_range * Global::fDistanceFactor );
|
Config.draw_range * Global::fDistanceFactor );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
camera.projection() *=
|
camera.projection() *=
|
||||||
@@ -563,7 +588,7 @@ opengl_renderer::renderpass_config::setup( rendermode const Mode, bool const Fra
|
|||||||
glm::radians( Global::FieldOfView / Global::ZoomFactor ),
|
glm::radians( Global::FieldOfView / Global::ZoomFactor ),
|
||||||
std::max( 1.f, (float)Global::iWindowWidth ) / std::max( 1.f, (float)Global::iWindowHeight ),
|
std::max( 1.f, (float)Global::iWindowWidth ) / std::max( 1.f, (float)Global::iWindowHeight ),
|
||||||
0.1f * Global::ZoomFactor,
|
0.1f * Global::ZoomFactor,
|
||||||
draw_range * Global::fDistanceFactor );
|
Config.draw_range * Global::fDistanceFactor );
|
||||||
}
|
}
|
||||||
// modelview
|
// modelview
|
||||||
camera.position() = Global::pCameraPosition;
|
camera.position() = Global::pCameraPosition;
|
||||||
@@ -681,7 +706,9 @@ opengl_renderer::setup_units( bool const Diffuse, bool const Shadows, bool const
|
|||||||
// shadow texture unit.
|
// shadow texture unit.
|
||||||
// interpolates between primary colour and the previous unit, which should hold darkened variant of the primary colour
|
// interpolates between primary colour and the previous unit, which should hold darkened variant of the primary colour
|
||||||
if( m_shadowtextureunit >= 0 ) {
|
if( m_shadowtextureunit >= 0 ) {
|
||||||
if( ( true == Global::RenderShadows ) && ( true == Shadows ) ) {
|
if( ( true == Global::RenderShadows )
|
||||||
|
&& ( true == Shadows )
|
||||||
|
&& ( m_shadowcolor != colors::white ) ) {
|
||||||
|
|
||||||
::glActiveTexture( m_shadowtextureunit );
|
::glActiveTexture( m_shadowtextureunit );
|
||||||
::glBindTexture( GL_TEXTURE_2D, m_shadowtexture );
|
::glBindTexture( GL_TEXTURE_2D, m_shadowtexture );
|
||||||
@@ -756,7 +783,9 @@ void
|
|||||||
opengl_renderer::switch_units( bool const Diffuse, bool const Shadows, bool const Reflections ) {
|
opengl_renderer::switch_units( bool const Diffuse, bool const Shadows, bool const Reflections ) {
|
||||||
// helper texture unit.
|
// helper texture unit.
|
||||||
if( m_helpertextureunit >= 0 ) {
|
if( m_helpertextureunit >= 0 ) {
|
||||||
if( ( true == Global::RenderShadows ) && ( true == Shadows ) ) {
|
if( ( true == Global::RenderShadows )
|
||||||
|
&& ( true == Shadows )
|
||||||
|
&& ( m_shadowcolor != colors::white ) ) {
|
||||||
::glActiveTexture( m_helpertextureunit );
|
::glActiveTexture( m_helpertextureunit );
|
||||||
::glEnable( GL_TEXTURE_2D );
|
::glEnable( GL_TEXTURE_2D );
|
||||||
}
|
}
|
||||||
@@ -804,6 +833,17 @@ opengl_renderer::setup_shadow_color( glm::vec4 const &Shadowcolor ) {
|
|||||||
bool
|
bool
|
||||||
opengl_renderer::Render( world_environment *Environment ) {
|
opengl_renderer::Render( world_environment *Environment ) {
|
||||||
|
|
||||||
|
// calculate shadow tone, based on positions of celestial bodies
|
||||||
|
m_shadowcolor = interpolate(
|
||||||
|
glm::vec4{ 0.5f, 0.5f, 0.5f, 1.f },
|
||||||
|
glm::vec4{ colors::white },
|
||||||
|
clamp( -Environment->m_sun.getAngle(), 0.f, 6.f ) / 6.f );
|
||||||
|
if( ( Environment->m_sun.getAngle() < -18.f )
|
||||||
|
&& ( Environment->m_moon.getAngle() > 0.f ) ) {
|
||||||
|
// turn on moon shadows after nautical twilight, if the moon is actually up
|
||||||
|
m_shadowcolor = glm::vec4{ 0.5f, 0.5f, 0.5f, 1.f };
|
||||||
|
}
|
||||||
|
|
||||||
if( Global::bWireFrame ) {
|
if( Global::bWireFrame ) {
|
||||||
// bez nieba w trybie rysowania linii
|
// bez nieba w trybie rysowania linii
|
||||||
return false;
|
return false;
|
||||||
@@ -888,7 +928,10 @@ opengl_renderer::Render( world_environment *Environment ) {
|
|||||||
::glLoadIdentity(); // macierz jedynkowa
|
::glLoadIdentity(); // macierz jedynkowa
|
||||||
::glTranslatef( moonposition.x, moonposition.y, moonposition.z );
|
::glTranslatef( moonposition.x, moonposition.y, moonposition.z );
|
||||||
|
|
||||||
float const size = 0.02f; // TODO: expose distance/scale factor from the moon object
|
float const size = interpolate( // TODO: expose distance/scale factor from the moon object
|
||||||
|
0.0175f,
|
||||||
|
0.015f,
|
||||||
|
clamp( Environment->m_moon.getAngle(), 0.f, 90.f ) / 90.f );
|
||||||
// choose the moon appearance variant, based on current moon phase
|
// choose the moon appearance variant, based on current moon phase
|
||||||
// NOTE: implementation specific, 8 variants are laid out in 3x3 arrangement
|
// NOTE: implementation specific, 8 variants are laid out in 3x3 arrangement
|
||||||
// from new moon onwards, top left to right bottom (last spot is left for future use, if any)
|
// from new moon onwards, top left to right bottom (last spot is left for future use, if any)
|
||||||
@@ -2628,7 +2671,7 @@ opengl_renderer::Update( double const Deltatime ) {
|
|||||||
m_framerate = 1000.f / ( m_drawtime / 20.f );
|
m_framerate = 1000.f / ( m_drawtime / 20.f );
|
||||||
|
|
||||||
// adjust draw ranges etc, based on recent performance
|
// adjust draw ranges etc, based on recent performance
|
||||||
auto const framerate = 1000.0f / (m_drawtimecolor / 20.0f);
|
auto const framerate = 1000.0f / (m_drawtimecolorpass / 20.0f);
|
||||||
|
|
||||||
float targetfactor;
|
float targetfactor;
|
||||||
if( framerate > 90.0 ) { targetfactor = 3.0f; }
|
if( framerate > 90.0 ) { targetfactor = 3.0f; }
|
||||||
@@ -2697,7 +2740,18 @@ opengl_renderer::Info() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
opengl_renderer::Update_Lights( light_array const &Lights ) {
|
opengl_renderer::Update_Lights( light_array &Lights ) {
|
||||||
|
// arrange the light array from closest to farthest from current position of the camera
|
||||||
|
auto const camera = m_renderpass.camera.position();
|
||||||
|
std::sort(
|
||||||
|
std::begin( Lights.data ),
|
||||||
|
std::end( Lights.data ),
|
||||||
|
[&camera]( light_array::light_record const &Left, light_array::light_record const &Right ) {
|
||||||
|
// move lights which are off at the end...
|
||||||
|
if( Left.intensity == 0.f ) { return false; }
|
||||||
|
if( Right.intensity == 0.f ) { return true; }
|
||||||
|
// ...otherwise prefer closer and/or brigher light sources
|
||||||
|
return ( glm::length2( camera - Left.position ) * ( 1.f - Left.intensity ) ) < ( glm::length2( camera - Right.position ) * ( 1.f - Right.intensity ) ); } );
|
||||||
|
|
||||||
size_t const count = std::min( m_lights.size(), Lights.data.size() );
|
size_t const count = std::min( m_lights.size(), Lights.data.size() );
|
||||||
if( count == 0 ) { return; }
|
if( count == 0 ) { return; }
|
||||||
@@ -2710,40 +2764,35 @@ opengl_renderer::Update_Lights( light_array const &Lights ) {
|
|||||||
// we ran out of lights to assign
|
// we ran out of lights to assign
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if( scenelight.intensity == 0.0f ) {
|
if( scenelight.intensity == 0.f ) {
|
||||||
// all lights past this one are bound to be off
|
// all lights past this one are bound to be off
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if( ( m_renderpass.camera.position() - scenelight.position ).Length() > 1000.0f ) {
|
auto const lightoffset = glm::vec3{ scenelight.position - camera };
|
||||||
|
if( glm::length( lightoffset ) > 1000.f ) {
|
||||||
// we don't care about lights past arbitrary limit of 1 km.
|
// we don't care about lights past arbitrary limit of 1 km.
|
||||||
// but there could still be weaker lights which are closer, so keep looking
|
// but there could still be weaker lights which are closer, so keep looking
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// if the light passed tests so far, it's good enough
|
// if the light passed tests so far, it's good enough
|
||||||
renderlight->set_position( glm::make_vec3( (scenelight.position - m_renderpass.camera.position()).readArray() ) );
|
renderlight->set_position( lightoffset );
|
||||||
renderlight->direction = scenelight.direction;
|
renderlight->direction = scenelight.direction;
|
||||||
|
|
||||||
auto luminance = Global::fLuminance; // TODO: adjust this based on location, e.g. for tunnels
|
auto luminance = static_cast<float>( Global::fLuminance );
|
||||||
|
// adjust luminance level based on vehicle's location, e.g. tunnels
|
||||||
auto const environment = scenelight.owner->fShade;
|
auto const environment = scenelight.owner->fShade;
|
||||||
if( environment > 0.0f ) {
|
if( environment > 0.f ) {
|
||||||
luminance *= environment;
|
luminance *= environment;
|
||||||
}
|
}
|
||||||
renderlight->diffuse[ 0 ] = static_cast<GLfloat>( std::max( 0.0, scenelight.color.x - luminance ) );
|
renderlight->diffuse =
|
||||||
renderlight->diffuse[ 1 ] = static_cast<GLfloat>( std::max( 0.0, scenelight.color.y - luminance ) );
|
glm::vec4{
|
||||||
renderlight->diffuse[ 2 ] = static_cast<GLfloat>( std::max( 0.0, scenelight.color.z - luminance ) );
|
glm::max( glm::vec3{ colors::none }, scenelight.color - glm::vec3{ luminance } ),
|
||||||
renderlight->ambient[ 0 ] = static_cast<GLfloat>( std::max( 0.0, scenelight.color.x * scenelight.intensity - luminance) );
|
renderlight->diffuse[ 3 ] };
|
||||||
renderlight->ambient[ 1 ] = static_cast<GLfloat>( std::max( 0.0, scenelight.color.y * scenelight.intensity - luminance ) );
|
renderlight->ambient =
|
||||||
renderlight->ambient[ 2 ] = static_cast<GLfloat>( std::max( 0.0, scenelight.color.z * scenelight.intensity - luminance ) );
|
glm::vec4{
|
||||||
/*
|
glm::max( glm::vec3{ colors::none }, scenelight.color * glm::vec3{ scenelight.intensity } - glm::vec3{ luminance } ),
|
||||||
// NOTE: we have no simple way to determine whether the lights are falling on objects located in darker environment
|
renderlight->ambient[ 3 ] };
|
||||||
// until this issue is resolved we're disabling reduction of light strenght based on the global luminance
|
|
||||||
renderlight->diffuse[ 0 ] = std::max( 0.0f, scenelight.color.x );
|
|
||||||
renderlight->diffuse[ 1 ] = std::max( 0.0f, scenelight.color.y );
|
|
||||||
renderlight->diffuse[ 2 ] = std::max( 0.0f, scenelight.color.z );
|
|
||||||
renderlight->ambient[ 0 ] = std::max( 0.0f, scenelight.color.x * scenelight.intensity );
|
|
||||||
renderlight->ambient[ 1 ] = std::max( 0.0f, scenelight.color.y * scenelight.intensity );
|
|
||||||
renderlight->ambient[ 2 ] = std::max( 0.0f, scenelight.color.z * scenelight.intensity );
|
|
||||||
*/
|
|
||||||
::glLightf( renderlight->id, GL_LINEAR_ATTENUATION, static_cast<GLfloat>( (0.25 * scenelight.count) / std::pow( scenelight.count, 2 ) * (scenelight.owner->DimHeadlights ? 1.25 : 1.0) ) );
|
::glLightf( renderlight->id, GL_LINEAR_ATTENUATION, static_cast<GLfloat>( (0.25 * scenelight.count) / std::pow( scenelight.count, 2 ) * (scenelight.owner->DimHeadlights ? 1.25 : 1.0) ) );
|
||||||
::glEnable( renderlight->id );
|
::glEnable( renderlight->id );
|
||||||
|
|
||||||
|
|||||||
36
renderer.h
36
renderer.h
@@ -87,10 +87,9 @@ public:
|
|||||||
// methods:
|
// methods:
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
update_frustum() { m_frustum.calculate( m_projection, m_modelview ); }
|
update_frustum() { update_frustum( m_projection, m_modelview ); }
|
||||||
inline
|
|
||||||
void
|
void
|
||||||
update_frustum(glm::mat4 const &Projection, glm::mat4 const &Modelview) { m_frustum.calculate(Projection, Modelview); }
|
update_frustum( glm::mat4 const &Projection, glm::mat4 const &Modelview );
|
||||||
bool
|
bool
|
||||||
visible( bounding_area const &Area ) const;
|
visible( bounding_area const &Area ) const;
|
||||||
bool
|
bool
|
||||||
@@ -114,15 +113,31 @@ public:
|
|||||||
glm::mat4 &
|
glm::mat4 &
|
||||||
modelview() { return m_modelview; }
|
modelview() { return m_modelview; }
|
||||||
inline
|
inline
|
||||||
cFrustum const &
|
std::vector<glm::vec4> &
|
||||||
frustum() { return m_frustum; }
|
frustum_points() { return m_frustumpoints; }
|
||||||
|
// transforms provided set of clip space points to world space
|
||||||
|
template <class Iterator_>
|
||||||
|
void
|
||||||
|
transform_to_world( Iterator_ First, Iterator_ Last ) const {
|
||||||
|
std::for_each(
|
||||||
|
First, Last,
|
||||||
|
[this]( glm::vec4 &point ) {
|
||||||
|
// transform each point using the cached matrix...
|
||||||
|
point = this->m_inversetransformation * point;
|
||||||
|
// ...and scale by transformed w
|
||||||
|
point = glm::vec4{ glm::vec3{ point } / point.w, 1.f }; } ); }
|
||||||
|
// debug helper, draws shape of frustum in world space
|
||||||
|
void
|
||||||
|
draw( glm::vec3 const &Offset ) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// members:
|
// members:
|
||||||
cFrustum m_frustum;
|
cFrustum m_frustum;
|
||||||
|
std::vector<glm::vec4> m_frustumpoints; // visualization helper; corners of defined frustum, in world space
|
||||||
glm::dvec3 m_position;
|
glm::dvec3 m_position;
|
||||||
glm::mat4 m_projection;
|
glm::mat4 m_projection;
|
||||||
glm::mat4 m_modelview;
|
glm::mat4 m_modelview;
|
||||||
|
glm::mat4 m_inversetransformation; // cached transformation to world space
|
||||||
};
|
};
|
||||||
|
|
||||||
// bare-bones render controller, in lack of anything better yet
|
// bare-bones render controller, in lack of anything better yet
|
||||||
@@ -207,9 +222,6 @@ private:
|
|||||||
opengl_camera camera;
|
opengl_camera camera;
|
||||||
rendermode draw_mode { rendermode::none };
|
rendermode draw_mode { rendermode::none };
|
||||||
float draw_range { 0.0f };
|
float draw_range { 0.0f };
|
||||||
|
|
||||||
void
|
|
||||||
setup( rendermode const Mode, bool const Framebuffersupport, float const Znear = 0.f, float const Zfar = 1.f, bool const Ignoredebug = false );
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<opengl_light> opengllight_array;
|
typedef std::vector<opengl_light> opengllight_array;
|
||||||
@@ -220,6 +232,8 @@ private:
|
|||||||
// runs jobs needed to generate graphics for specified render pass
|
// runs jobs needed to generate graphics for specified render pass
|
||||||
void
|
void
|
||||||
Render_pass( rendermode const Mode );
|
Render_pass( rendermode const Mode );
|
||||||
|
void
|
||||||
|
setup_pass( renderpass_config &Config, rendermode const Mode, float const Znear = 0.f, float const Zfar = 1.f, bool const Ignoredebug = false );
|
||||||
void
|
void
|
||||||
setup_matrices();
|
setup_matrices();
|
||||||
void
|
void
|
||||||
@@ -269,7 +283,7 @@ private:
|
|||||||
void
|
void
|
||||||
Render_Alpha( TSubModel *Submodel );
|
Render_Alpha( TSubModel *Submodel );
|
||||||
void
|
void
|
||||||
Update_Lights( light_array const &Lights );
|
Update_Lights( light_array &Lights );
|
||||||
glm::vec3
|
glm::vec3
|
||||||
pick_color( std::size_t const Index );
|
pick_color( std::size_t const Index );
|
||||||
std::size_t
|
std::size_t
|
||||||
@@ -309,8 +323,8 @@ private:
|
|||||||
float m_drawtime { 1000.f / 30.f * 20.f }; // start with presumed 'neutral' average of 30 fps
|
float m_drawtime { 1000.f / 30.f * 20.f }; // start with presumed 'neutral' average of 30 fps
|
||||||
std::chrono::steady_clock::time_point m_drawstart; // cached start time of previous frame
|
std::chrono::steady_clock::time_point m_drawstart; // cached start time of previous frame
|
||||||
float m_framerate;
|
float m_framerate;
|
||||||
float m_drawtimecolor { 1000.f / 30.f * 20.f };
|
float m_drawtimecolorpass { 1000.f / 30.f * 20.f };
|
||||||
float m_drawtimeshadows { 0.f };
|
float m_drawtimeshadowpass { 0.f };
|
||||||
double m_updateaccumulator { 0.0 };
|
double m_updateaccumulator { 0.0 };
|
||||||
std::string m_debuginfo;
|
std::string m_debuginfo;
|
||||||
|
|
||||||
|
|||||||
13
sun.cpp
13
sun.cpp
@@ -251,21 +251,18 @@ void cSun::refract() {
|
|||||||
|
|
||||||
void cSun::irradiance() {
|
void cSun::irradiance() {
|
||||||
|
|
||||||
static double degrad = 57.295779513; // converts from radians to degrees
|
|
||||||
static double raddeg = 0.0174532925; // converts from degrees to radians
|
|
||||||
|
|
||||||
m_body.dayang = ( simulation::Time.year_day() - 1 ) * 360.0 / 365.0;
|
m_body.dayang = ( simulation::Time.year_day() - 1 ) * 360.0 / 365.0;
|
||||||
double sd = sin( raddeg * m_body.dayang ); // sine of the day angle
|
double sd = std::sin( glm::radians( m_body.dayang ) ); // sine of the day angle
|
||||||
double cd = cos( raddeg * m_body.dayang ); // cosine of the day angle or delination
|
double cd = std::cos( glm::radians( m_body.dayang ) ); // cosine of the day angle or delination
|
||||||
m_body.erv = 1.000110 + 0.034221*cd + 0.001280*sd;
|
m_body.erv = 1.000110 + 0.034221*cd + 0.001280*sd;
|
||||||
double d2 = 2.0 * m_body.dayang;
|
double d2 = 2.0 * m_body.dayang;
|
||||||
double c2 = cos( raddeg * d2 );
|
double c2 = std::cos( glm::radians( d2 ) );
|
||||||
double s2 = sin( raddeg * d2 );
|
double s2 = std::sin( glm::radians( d2 ) );
|
||||||
m_body.erv += 0.000719*c2 + 0.000077*s2;
|
m_body.erv += 0.000719*c2 + 0.000077*s2;
|
||||||
|
|
||||||
double solcon = 1367.0; // Solar constant, 1367 W/sq m
|
double solcon = 1367.0; // Solar constant, 1367 W/sq m
|
||||||
|
|
||||||
m_body.coszen = cos( raddeg * m_body.zenref );
|
m_body.coszen = std::cos( glm::radians( m_body.zenref ) );
|
||||||
if( m_body.coszen > 0.0 ) {
|
if( m_body.coszen > 0.0 ) {
|
||||||
m_body.etrn = solcon * m_body.erv;
|
m_body.etrn = solcon * m_body.erv;
|
||||||
m_body.etr = m_body.etrn * m_body.coszen;
|
m_body.etr = m_body.etrn * m_body.coszen;
|
||||||
|
|||||||
Reference in New Issue
Block a user