mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 13:59:19 +02:00
upgraded reflection map to dynamic environment cube map
This commit is contained in:
@@ -27,7 +27,7 @@ class opengl_stack {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// constructors:
|
// constructors:
|
||||||
opengl_stack() { m_stack.emplace(1.0f); }
|
opengl_stack() { m_stack.emplace(1.f); }
|
||||||
|
|
||||||
// methods:
|
// methods:
|
||||||
glm::mat4 const &
|
glm::mat4 const &
|
||||||
@@ -86,29 +86,32 @@ private:
|
|||||||
mat4_stack m_stack;
|
mat4_stack m_stack;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum stack_mode { gl_projection = 0, gl_modelview = 1 };
|
enum stack_mode { gl_modelview = 0, gl_projection = 1, gl_texture = 2 };
|
||||||
typedef std::vector<opengl_stack> openglstack_array;
|
typedef std::vector<opengl_stack> openglstack_array;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// constructors:
|
// constructors:
|
||||||
opengl_matrices() {
|
opengl_matrices() {
|
||||||
m_stacks.emplace_back(); // projection
|
|
||||||
m_stacks.emplace_back(); // modelview
|
m_stacks.emplace_back(); // modelview
|
||||||
|
m_stacks.emplace_back(); // projection
|
||||||
|
m_stacks.emplace_back(); // texture
|
||||||
}
|
}
|
||||||
|
|
||||||
// methods:
|
// methods:
|
||||||
void
|
void
|
||||||
mode( GLuint const Mode ) {
|
mode( GLuint const Mode ) {
|
||||||
switch( Mode ) {
|
switch( Mode ) {
|
||||||
case GL_PROJECTION: { m_mode = stack_mode::gl_projection; break; }
|
|
||||||
case GL_MODELVIEW: { m_mode = stack_mode::gl_modelview; break; }
|
case GL_MODELVIEW: { m_mode = stack_mode::gl_modelview; break; }
|
||||||
|
case GL_PROJECTION: { m_mode = stack_mode::gl_projection; break; }
|
||||||
|
case GL_TEXTURE: { m_mode = stack_mode::gl_texture; break; }
|
||||||
default: { break; } }
|
default: { break; } }
|
||||||
glMatrixMode( Mode ); }
|
::glMatrixMode( Mode ); }
|
||||||
glm::mat4 const &
|
glm::mat4 const &
|
||||||
data( GLuint const Mode = -1 ) const {
|
data( GLuint const Mode = -1 ) const {
|
||||||
switch( Mode ) {
|
switch( Mode ) {
|
||||||
case GL_PROJECTION: { return m_stacks[ stack_mode::gl_projection ].data(); }
|
|
||||||
case GL_MODELVIEW: { return m_stacks[ stack_mode::gl_modelview ].data(); }
|
case GL_MODELVIEW: { return m_stacks[ stack_mode::gl_modelview ].data(); }
|
||||||
|
case GL_PROJECTION: { return m_stacks[ stack_mode::gl_projection ].data(); }
|
||||||
|
case GL_TEXTURE: { return m_stacks[ stack_mode::gl_texture ].data(); }
|
||||||
default: { return m_stacks[ m_mode ].data(); } } }
|
default: { return m_stacks[ m_mode ].data(); } } }
|
||||||
float const *
|
float const *
|
||||||
data_array( GLuint const Mode = -1 ) const {
|
data_array( GLuint const Mode = -1 ) const {
|
||||||
@@ -128,7 +131,7 @@ public:
|
|||||||
void
|
void
|
||||||
rotate( Type_ const Angle, Type_ const X, Type_ const Y, Type_ const Z ) {
|
rotate( Type_ const Angle, Type_ const X, Type_ const Y, Type_ const Z ) {
|
||||||
m_stacks[ m_mode ].rotate(
|
m_stacks[ m_mode ].rotate(
|
||||||
static_cast<float>(Angle) * 0.0174532925f, // deg2rad
|
static_cast<float>(glm::radians(Angle)),
|
||||||
glm::vec3(
|
glm::vec3(
|
||||||
static_cast<float>(X),
|
static_cast<float>(X),
|
||||||
static_cast<float>(Y),
|
static_cast<float>(Y),
|
||||||
|
|||||||
291
renderer.cpp
291
renderer.cpp
@@ -26,6 +26,7 @@ opengl_renderer GfxRenderer;
|
|||||||
extern TWorld World;
|
extern TWorld World;
|
||||||
|
|
||||||
int const EU07_PICKBUFFERSIZE { 1024 }; // size of (square) textures bound with the pick framebuffer
|
int const EU07_PICKBUFFERSIZE { 1024 }; // size of (square) textures bound with the pick framebuffer
|
||||||
|
int const EU07_ENVIRONMENTBUFFERSIZE { 256 }; // size of (square) environmental cube map texture
|
||||||
|
|
||||||
namespace colors {
|
namespace colors {
|
||||||
|
|
||||||
@@ -173,11 +174,11 @@ opengl_renderer::Init( GLFWwindow *Window ) {
|
|||||||
// texture
|
// texture
|
||||||
::glGenTextures( 1, &m_picktexture );
|
::glGenTextures( 1, &m_picktexture );
|
||||||
::glBindTexture( GL_TEXTURE_2D, m_picktexture );
|
::glBindTexture( GL_TEXTURE_2D, m_picktexture );
|
||||||
|
::glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, EU07_PICKBUFFERSIZE, EU07_PICKBUFFERSIZE, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL );
|
||||||
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
|
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
|
||||||
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
|
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
|
||||||
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
|
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
|
||||||
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
|
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
|
||||||
::glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, EU07_PICKBUFFERSIZE, EU07_PICKBUFFERSIZE, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL );
|
|
||||||
// depth buffer
|
// depth buffer
|
||||||
::glGenRenderbuffersEXT( 1, &m_pickdepthbuffer );
|
::glGenRenderbuffersEXT( 1, &m_pickdepthbuffer );
|
||||||
::glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, m_pickdepthbuffer );
|
::glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, m_pickdepthbuffer );
|
||||||
@@ -251,7 +252,42 @@ opengl_renderer::Init( GLFWwindow *Window ) {
|
|||||||
}
|
}
|
||||||
::glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); // switch back to primary render target for now
|
::glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); // switch back to primary render target for now
|
||||||
}
|
}
|
||||||
|
// environment cube map resources
|
||||||
|
if( true == m_framebuffersupport ) {
|
||||||
|
// texture:
|
||||||
|
::glGenTextures( 1, &m_environmentcubetexture );
|
||||||
|
::glBindTexture( GL_TEXTURE_CUBE_MAP, m_environmentcubetexture );
|
||||||
|
// allocate space
|
||||||
|
for( GLuint faceindex = GL_TEXTURE_CUBE_MAP_POSITIVE_X; faceindex < GL_TEXTURE_CUBE_MAP_POSITIVE_X + 6; ++faceindex ) {
|
||||||
|
::glTexImage2D( faceindex, 0, GL_RGBA8, EU07_ENVIRONMENTBUFFERSIZE, EU07_ENVIRONMENTBUFFERSIZE, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL );
|
||||||
|
}
|
||||||
|
// setup parameters
|
||||||
|
::glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||||||
|
::glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||||
|
::glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
|
||||||
|
::glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
|
||||||
|
::glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE );
|
||||||
|
// depth buffer
|
||||||
|
::glGenRenderbuffersEXT( 1, &m_environmentdepthbuffer );
|
||||||
|
::glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, m_environmentdepthbuffer );
|
||||||
|
::glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, EU07_ENVIRONMENTBUFFERSIZE, EU07_ENVIRONMENTBUFFERSIZE );
|
||||||
|
// create and assemble the framebuffer
|
||||||
|
::glGenFramebuffersEXT( 1, &m_environmentframebuffer );
|
||||||
|
::glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, m_environmentframebuffer );
|
||||||
|
::glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X, m_environmentcubetexture, 0 );
|
||||||
|
::glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_environmentdepthbuffer );
|
||||||
|
// check if we got it working
|
||||||
|
GLenum status = ::glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
|
||||||
|
if( status == GL_FRAMEBUFFER_COMPLETE_EXT ) {
|
||||||
|
WriteLog( "Reflections framebuffer setup complete" );
|
||||||
|
m_environmentcubetexturesupport = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ErrorLog( "Reflections framebuffer setup failed" );
|
||||||
|
m_environmentcubetexturesupport = false;
|
||||||
|
}
|
||||||
|
::glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); // switch back to primary render target for now
|
||||||
|
}
|
||||||
// prepare basic geometry chunks
|
// prepare basic geometry chunks
|
||||||
auto const geometrybank = m_geometry.create_bank();
|
auto const geometrybank = m_geometry.create_bank();
|
||||||
float const size = 2.5f;
|
float const size = 2.5f;
|
||||||
@@ -337,6 +373,14 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
glm::vec3{ m_renderpass.camera.position() - shadowcamera.position() } );
|
glm::vec3{ m_renderpass.camera.position() - shadowcamera.position() } );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( ( true == m_environmentcubetexturesupport )
|
||||||
|
&& ( true == World.InitPerformed() ) ) {
|
||||||
|
// potentially update environmental cube map
|
||||||
|
if( true == Render_reflections() ) {
|
||||||
|
setup_pass( m_renderpass, Mode ); // restore draw mode. TBD, TODO: render mode stack
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
::glViewport( 0, 0, Global::iWindowWidth, Global::iWindowHeight );
|
::glViewport( 0, 0, Global::iWindowWidth, Global::iWindowHeight );
|
||||||
|
|
||||||
if( World.InitPerformed() ) {
|
if( World.InitPerformed() ) {
|
||||||
@@ -383,6 +427,15 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
switch_units( true, false, false );
|
switch_units( true, false, false );
|
||||||
// cab render is done in translucent phase to deal with badly configured vehicles
|
// cab render is done in translucent phase to deal with badly configured vehicles
|
||||||
if( World.Train != nullptr ) { Render_cab( World.Train->Dynamic() ); }
|
if( World.Train != nullptr ) { Render_cab( World.Train->Dynamic() ); }
|
||||||
|
|
||||||
|
if( m_environmentcubetexturesupport ) {
|
||||||
|
// restore default texture matrix for reflections cube map
|
||||||
|
Active_Texture( m_helpertextureunit );
|
||||||
|
::glMatrixMode( GL_TEXTURE );
|
||||||
|
::glPopMatrix();
|
||||||
|
Active_Texture( m_diffusetextureunit );
|
||||||
|
::glMatrixMode( GL_MODELVIEW );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
UILayer.render();
|
UILayer.render();
|
||||||
break;
|
break;
|
||||||
@@ -394,7 +447,7 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
// setup
|
// setup
|
||||||
auto const shadowdrawstart = std::chrono::steady_clock::now();
|
auto const shadowdrawstart = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
::glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, m_shadowframebuffer );
|
::glBindFramebufferEXT( GL_FRAMEBUFFER, m_shadowframebuffer );
|
||||||
|
|
||||||
::glViewport( 0, 0, m_shadowbuffersize, m_shadowbuffersize );
|
::glViewport( 0, 0, m_shadowbuffersize, m_shadowbuffersize );
|
||||||
|
|
||||||
@@ -431,6 +484,39 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case rendermode::reflections: {
|
||||||
|
// NOTE: buffer and viewport setup in this mode is handled by the wrapper method
|
||||||
|
::glClearColor( 0.f, 0.f, 0.f, 1.f );
|
||||||
|
::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||||
|
|
||||||
|
if( World.InitPerformed() ) {
|
||||||
|
|
||||||
|
::glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE );
|
||||||
|
// setup
|
||||||
|
setup_matrices();
|
||||||
|
// render
|
||||||
|
setup_drawing( true );
|
||||||
|
setup_units( true, false, false );
|
||||||
|
Render( &World.Environment );
|
||||||
|
// opaque parts...
|
||||||
|
setup_drawing( false );
|
||||||
|
setup_units( true, true, true );
|
||||||
|
Render( &World.Ground );
|
||||||
|
/*
|
||||||
|
// reflections are limited to sky and ground only, the update rate is too low for anything else
|
||||||
|
// ...translucent parts
|
||||||
|
setup_drawing( true );
|
||||||
|
Render_Alpha( &World.Ground );
|
||||||
|
// cab render is performed without shadows, due to low resolution and number of models without windows :|
|
||||||
|
switch_units( true, false, false );
|
||||||
|
// cab render is done in translucent phase to deal with badly configured vehicles
|
||||||
|
if( World.Train != nullptr ) { Render_cab( World.Train->Dynamic() ); }
|
||||||
|
*/
|
||||||
|
::glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case rendermode::pickcontrols: {
|
case rendermode::pickcontrols: {
|
||||||
if( World.InitPerformed() ) {
|
if( World.InitPerformed() ) {
|
||||||
// setup
|
// setup
|
||||||
@@ -480,6 +566,32 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// creates dynamic environment cubemap
|
||||||
|
bool
|
||||||
|
opengl_renderer::Render_reflections() {
|
||||||
|
|
||||||
|
auto const &time = simulation::Time.data();
|
||||||
|
auto const timestamp = time.wDay * 60 * 24 + time.wHour * 60 + time.wMinute;
|
||||||
|
if( timestamp - m_environmenttimestamp < 5 ) {
|
||||||
|
// run update every 5+ mins of simulation time
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_environmenttimestamp = timestamp;
|
||||||
|
|
||||||
|
::glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, m_environmentframebuffer );
|
||||||
|
::glViewport( 0, 0, EU07_ENVIRONMENTBUFFERSIZE, EU07_ENVIRONMENTBUFFERSIZE );
|
||||||
|
for( m_environmentcubetextureface = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
||||||
|
m_environmentcubetextureface < GL_TEXTURE_CUBE_MAP_POSITIVE_X + 6;
|
||||||
|
++m_environmentcubetextureface ) {
|
||||||
|
|
||||||
|
::glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0, m_environmentcubetextureface, m_environmentcubetexture, 0 );
|
||||||
|
Render_pass( rendermode::reflections );
|
||||||
|
}
|
||||||
|
::glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
opengl_renderer::setup_pass( renderpass_config &Config, rendermode const Mode, 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 ) {
|
||||||
|
|
||||||
@@ -490,6 +602,7 @@ opengl_renderer::setup_pass( renderpass_config &Config, rendermode const Mode, f
|
|||||||
switch( Mode ) {
|
switch( Mode ) {
|
||||||
case rendermode::color: { Config.draw_range = Global::BaseDrawRange; break; }
|
case rendermode::color: { Config.draw_range = Global::BaseDrawRange; break; }
|
||||||
case rendermode::shadows: { Config.draw_range = Global::BaseDrawRange * 0.5f; break; }
|
case rendermode::shadows: { Config.draw_range = Global::BaseDrawRange * 0.5f; break; }
|
||||||
|
case rendermode::reflections: { Config.draw_range = Global::BaseDrawRange; break; }
|
||||||
case rendermode::pickcontrols: { Config.draw_range = 50.f; break; }
|
case rendermode::pickcontrols: { Config.draw_range = 50.f; break; }
|
||||||
case rendermode::pickscenery: { Config.draw_range = Global::BaseDrawRange * 0.5f; break; }
|
case rendermode::pickscenery: { Config.draw_range = Global::BaseDrawRange * 0.5f; break; }
|
||||||
default: { Config.draw_range = 0.f; break; }
|
default: { Config.draw_range = 0.f; break; }
|
||||||
@@ -573,6 +686,29 @@ opengl_renderer::setup_pass( renderpass_config &Config, rendermode const Mode, f
|
|||||||
frustumchunkmin.z - 500.f, frustumchunkmax.z + 500.f );
|
frustumchunkmin.z - 500.f, frustumchunkmax.z + 500.f );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case rendermode::reflections: {
|
||||||
|
// projection
|
||||||
|
camera.projection() *=
|
||||||
|
glm::perspective(
|
||||||
|
glm::radians( 90.f ),
|
||||||
|
1.f,
|
||||||
|
0.1f * Global::ZoomFactor,
|
||||||
|
Config.draw_range * Global::fDistanceFactor );
|
||||||
|
// modelview
|
||||||
|
camera.position() = (
|
||||||
|
( ( true == DebugCameraFlag ) && ( false == Ignoredebug ) ) ?
|
||||||
|
Global::DebugCameraPosition :
|
||||||
|
Global::pCameraPosition );
|
||||||
|
glm::dvec3 const cubefacetargetvectors[ 6 ] = { { 1.0, 0.0, 0.0 }, { -1.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }, { 0.0, -1.0, 0.0 }, { 0.0, 0.0, 1.0 }, { 0.0, 0.0, -1.0 } };
|
||||||
|
glm::dvec3 const cubefaceupvectors[ 6 ] = { { 0.0, -1.0, 0.0 }, { 0.0, -1.0, 0.0 }, { 0.0, 0.0, 1.0 }, { 0.0, 0.0, -1.0 }, { 0.0, -1.0, 0.0 }, { 0.0, -1.0, 0.0 } };
|
||||||
|
auto const cubefaceindex = m_environmentcubetextureface - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
||||||
|
viewmatrix *=
|
||||||
|
glm::lookAt(
|
||||||
|
camera.position(),
|
||||||
|
camera.position() + cubefacetargetvectors[ cubefaceindex ],
|
||||||
|
cubefaceupvectors[ cubefaceindex ] );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case rendermode::pickcontrols:
|
case rendermode::pickcontrols:
|
||||||
case rendermode::pickscenery: {
|
case rendermode::pickscenery: {
|
||||||
@@ -602,6 +738,17 @@ opengl_renderer::setup_matrices() {
|
|||||||
|
|
||||||
::glMatrixMode( GL_PROJECTION );
|
::glMatrixMode( GL_PROJECTION );
|
||||||
OpenGLMatrices.load_matrix( m_renderpass.camera.projection() );
|
OpenGLMatrices.load_matrix( m_renderpass.camera.projection() );
|
||||||
|
|
||||||
|
if( ( m_renderpass.draw_mode == rendermode::color )
|
||||||
|
&& ( m_environmentcubetexturesupport ) ) {
|
||||||
|
// special case, for colour render pass setup texture matrix for reflections cube map
|
||||||
|
Active_Texture( m_helpertextureunit );
|
||||||
|
::glMatrixMode( GL_TEXTURE );
|
||||||
|
::glPushMatrix();
|
||||||
|
::glMultMatrixf( glm::value_ptr( glm::inverse( glm::mat4{ glm::mat3{ m_renderpass.camera.modelview() } } ) ) );
|
||||||
|
Active_Texture( m_diffusetextureunit );
|
||||||
|
}
|
||||||
|
|
||||||
// trim modelview matrix just to rotation, since rendering is done in camera-centric world space
|
// trim modelview matrix just to rotation, since rendering is done in camera-centric world space
|
||||||
::glMatrixMode( GL_MODELVIEW );
|
::glMatrixMode( GL_MODELVIEW );
|
||||||
OpenGLMatrices.load_matrix( glm::mat4( glm::mat3( m_renderpass.camera.modelview() ) ) );
|
OpenGLMatrices.load_matrix( glm::mat4( glm::mat3( m_renderpass.camera.modelview() ) ) );
|
||||||
@@ -621,7 +768,8 @@ opengl_renderer::setup_drawing( bool const Alpha ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
case rendermode::color: {
|
case rendermode::color:
|
||||||
|
case rendermode::reflections: {
|
||||||
::glEnable( GL_LIGHTING );
|
::glEnable( GL_LIGHTING );
|
||||||
::glShadeModel( GL_SMOOTH );
|
::glShadeModel( GL_SMOOTH );
|
||||||
if( Global::iMultisampling ) {
|
if( Global::iMultisampling ) {
|
||||||
@@ -668,12 +816,27 @@ opengl_renderer::setup_units( bool const Diffuse, bool const Shadows, bool const
|
|||||||
|
|
||||||
if( ( true == Reflections )
|
if( ( true == Reflections )
|
||||||
|| ( ( true == Global::RenderShadows ) && ( true == Shadows ) ) ) {
|
|| ( ( true == Global::RenderShadows ) && ( true == Shadows ) ) ) {
|
||||||
|
// we need to have texture on the helper for either the reflection and shadow generation (or both)
|
||||||
|
if( true == m_environmentcubetexturesupport ) {
|
||||||
|
// bind dynamic environment cube if it's enabled...
|
||||||
|
// NOTE: environment cube map isn't part of regular texture system, so we use direct bind call here
|
||||||
|
::glBindTexture( GL_TEXTURE_CUBE_MAP, m_environmentcubetexture );
|
||||||
|
::glEnable( GL_TEXTURE_CUBE_MAP );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// ...otherwise fallback on static spherical image
|
||||||
m_textures.bind( textureunit::helper, m_reflectiontexture );
|
m_textures.bind( textureunit::helper, m_reflectiontexture );
|
||||||
::glEnable( GL_TEXTURE_2D );
|
::glEnable( GL_TEXTURE_2D );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if( true == m_environmentcubetexturesupport ) {
|
||||||
|
::glDisable( GL_TEXTURE_CUBE_MAP );
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
::glDisable( GL_TEXTURE_2D );
|
::glDisable( GL_TEXTURE_2D );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( ( true == Global::RenderShadows ) && ( true == Shadows ) ) {
|
if( ( true == Global::RenderShadows ) && ( true == Shadows ) ) {
|
||||||
|
|
||||||
@@ -700,16 +863,34 @@ opengl_renderer::setup_units( bool const Diffuse, bool const Shadows, bool const
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( true == Reflections ) {
|
if( true == Reflections ) {
|
||||||
|
if( true == m_environmentcubetexturesupport ) {
|
||||||
|
::glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP );
|
||||||
|
::glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP );
|
||||||
|
::glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP );
|
||||||
|
::glEnable( GL_TEXTURE_GEN_S );
|
||||||
|
::glEnable( GL_TEXTURE_GEN_T );
|
||||||
|
::glEnable( GL_TEXTURE_GEN_R );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// fixed texture fall back
|
||||||
::glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
|
::glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
|
||||||
::glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
|
::glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
|
||||||
::glEnable( GL_TEXTURE_GEN_S );
|
::glEnable( GL_TEXTURE_GEN_S );
|
||||||
::glEnable( GL_TEXTURE_GEN_T );
|
::glEnable( GL_TEXTURE_GEN_T );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if( true == m_environmentcubetexturesupport ) {
|
||||||
|
::glDisable( GL_TEXTURE_GEN_S );
|
||||||
|
::glDisable( GL_TEXTURE_GEN_T );
|
||||||
|
::glDisable( GL_TEXTURE_GEN_R );
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
::glDisable( GL_TEXTURE_GEN_S );
|
::glDisable( GL_TEXTURE_GEN_S );
|
||||||
::glDisable( GL_TEXTURE_GEN_T );
|
::glDisable( GL_TEXTURE_GEN_T );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// 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 ) {
|
||||||
@@ -810,6 +991,10 @@ opengl_renderer::setup_units( bool const Diffuse, bool const Shadows, bool const
|
|||||||
::glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA );
|
::glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA );
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
// update unit state
|
||||||
|
m_unitstate.diffuse = Diffuse;
|
||||||
|
m_unitstate.shadows = Shadows;
|
||||||
|
m_unitstate.reflections = Reflections;
|
||||||
}
|
}
|
||||||
|
|
||||||
// enables and disables specified texture units
|
// enables and disables specified texture units
|
||||||
@@ -817,18 +1002,27 @@ 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 ) {
|
||||||
|
Active_Texture( m_helpertextureunit );
|
||||||
if( ( true == Reflections )
|
if( ( true == Reflections )
|
||||||
|| ( ( true == Global::RenderShadows )
|
|| ( ( true == Global::RenderShadows )
|
||||||
&& ( true == Shadows )
|
&& ( true == Shadows )
|
||||||
&& ( m_shadowcolor != colors::white ) ) ) {
|
&& ( m_shadowcolor != colors::white ) ) ) {
|
||||||
Active_Texture( m_helpertextureunit );
|
if( true == m_environmentcubetexturesupport ) {
|
||||||
::glEnable( GL_TEXTURE_2D );
|
::glEnable( GL_TEXTURE_CUBE_MAP );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
::glEnable( GL_TEXTURE_2D );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if( true == m_environmentcubetexturesupport ) {
|
||||||
|
::glDisable( GL_TEXTURE_CUBE_MAP );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Active_Texture( m_helpertextureunit );
|
|
||||||
::glDisable( GL_TEXTURE_2D );
|
::glDisable( GL_TEXTURE_2D );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// shadow texture unit.
|
// shadow texture unit.
|
||||||
if( m_shadowtextureunit >= 0 ) {
|
if( m_shadowtextureunit >= 0 ) {
|
||||||
if( ( true == Global::RenderShadows ) && ( true == Shadows ) ) {
|
if( ( true == Global::RenderShadows ) && ( true == Shadows ) ) {
|
||||||
@@ -864,6 +1058,10 @@ opengl_renderer::switch_units( bool const Diffuse, bool const Shadows, bool cons
|
|||||||
Active_Texture( m_diffusetextureunit );
|
Active_Texture( m_diffusetextureunit );
|
||||||
::glDisable( GL_TEXTURE_2D );
|
::glDisable( GL_TEXTURE_2D );
|
||||||
}
|
}
|
||||||
|
// update unit state
|
||||||
|
m_unitstate.diffuse = Diffuse;
|
||||||
|
m_unitstate.shadows = Shadows;
|
||||||
|
m_unitstate.reflections = Reflections;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1186,6 +1384,19 @@ opengl_renderer::Render( TGround *Ground ) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case rendermode::reflections: {
|
||||||
|
// reflections render only terrain geometry
|
||||||
|
for( int column = originx; column <= originx + segmentcount; ++column ) {
|
||||||
|
for( int row = originz; row <= originz + segmentcount; ++row ) {
|
||||||
|
|
||||||
|
auto *cell = &Ground->Rects[ column ][ row ];
|
||||||
|
if( m_renderpass.camera.visible( cell->m_area ) ) {
|
||||||
|
Render( cell );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case rendermode::shadows:
|
case rendermode::shadows:
|
||||||
case rendermode::pickscenery: {
|
case rendermode::pickscenery: {
|
||||||
// these render modes don't bother with anything non-visual, or lights
|
// these render modes don't bother with anything non-visual, or lights
|
||||||
@@ -1228,7 +1439,8 @@ opengl_renderer::Render( TGroundRect *Groundcell ) {
|
|||||||
// non-interactive scenery elements get neutral colour
|
// non-interactive scenery elements get neutral colour
|
||||||
::glColor3fv( glm::value_ptr( colors::none ) );
|
::glColor3fv( glm::value_ptr( colors::none ) );
|
||||||
}
|
}
|
||||||
case rendermode::color: {
|
case rendermode::color:
|
||||||
|
case rendermode::reflections: {
|
||||||
if( Groundcell->nRenderRect != nullptr ) {
|
if( Groundcell->nRenderRect != nullptr ) {
|
||||||
// nieprzezroczyste trójkąty kwadratu kilometrowego
|
// nieprzezroczyste trójkąty kwadratu kilometrowego
|
||||||
for( TGroundNode *node = Groundcell->nRenderRect; node != nullptr; node = node->nNext3 ) {
|
for( TGroundNode *node = Groundcell->nRenderRect; node != nullptr; node = node->nNext3 ) {
|
||||||
@@ -1263,6 +1475,10 @@ opengl_renderer::Render( TGroundRect *Groundcell ) {
|
|||||||
result = true;
|
result = true;
|
||||||
|
|
||||||
// add the subcells of the cell to the draw queue
|
// add the subcells of the cell to the draw queue
|
||||||
|
switch( m_renderpass.draw_mode ) {
|
||||||
|
case rendermode::color:
|
||||||
|
case rendermode::shadows:
|
||||||
|
case rendermode::pickscenery: {
|
||||||
if( Groundcell->pSubRects != nullptr ) {
|
if( Groundcell->pSubRects != nullptr ) {
|
||||||
for( std::size_t subcellindex = 0; subcellindex < iNumSubRects * iNumSubRects; ++subcellindex ) {
|
for( std::size_t subcellindex = 0; subcellindex < iNumSubRects * iNumSubRects; ++subcellindex ) {
|
||||||
auto subcell = Groundcell->pSubRects + subcellindex;
|
auto subcell = Groundcell->pSubRects + subcellindex;
|
||||||
@@ -1274,6 +1490,14 @@ opengl_renderer::Render( TGroundRect *Groundcell ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case rendermode::reflections:
|
||||||
|
case rendermode::pickcontrols:
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -1831,7 +2055,8 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
|||||||
if( Submodel->iAlpha & Submodel->iFlags & 0x1F ) {
|
if( Submodel->iAlpha & Submodel->iFlags & 0x1F ) {
|
||||||
// rysuj gdy element nieprzezroczysty
|
// rysuj gdy element nieprzezroczysty
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
case rendermode::color: {
|
case rendermode::color:
|
||||||
|
case rendermode::reflections: {
|
||||||
// NOTE: code disabled as normalization marking doesn't take into account scaling propagation down hierarchy chains
|
// NOTE: code disabled as normalization marking doesn't take into account scaling propagation down hierarchy chains
|
||||||
// for the time being we'll do with enforced worst-case scaling method, when speculars are enabled
|
// for the time being we'll do with enforced worst-case scaling method, when speculars are enabled
|
||||||
#ifdef EU07_USE_OPTIMIZED_NORMALIZATION
|
#ifdef EU07_USE_OPTIMIZED_NORMALIZATION
|
||||||
@@ -1865,11 +2090,15 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
|||||||
::glEnable( GL_RESCALE_NORMAL );
|
::glEnable( GL_RESCALE_NORMAL );
|
||||||
}
|
}
|
||||||
// ...luminance
|
// ...luminance
|
||||||
|
auto const unitstate = m_unitstate;
|
||||||
if( Global::fLuminance < Submodel->fLight ) {
|
if( Global::fLuminance < Submodel->fLight ) {
|
||||||
// zeby swiecilo na kolorowo
|
// zeby swiecilo na kolorowo
|
||||||
::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( Submodel->f4Diffuse * Submodel->f4Emision.a ) );
|
::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( Submodel->f4Diffuse * Submodel->f4Emision.a ) );
|
||||||
// disable shadows so they don't obstruct self-lit items
|
// disable shadows so they don't obstruct self-lit items
|
||||||
|
/*
|
||||||
setup_shadow_color( colors::white );
|
setup_shadow_color( colors::white );
|
||||||
|
*/
|
||||||
|
switch_units( m_unitstate.diffuse, false, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
// main draw call
|
// main draw call
|
||||||
@@ -1882,7 +2111,10 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
|||||||
if( Global::fLuminance < Submodel->fLight ) {
|
if( Global::fLuminance < Submodel->fLight ) {
|
||||||
// restore default (lack of) brightness
|
// restore default (lack of) brightness
|
||||||
::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( colors::none ) );
|
::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( colors::none ) );
|
||||||
|
/*
|
||||||
setup_shadow_color( m_shadowcolor );
|
setup_shadow_color( m_shadowcolor );
|
||||||
|
*/
|
||||||
|
switch_units( m_unitstate.diffuse, unitstate.shadows, unitstate.reflections );
|
||||||
}
|
}
|
||||||
#ifdef EU07_USE_OPTIMIZED_NORMALIZATION
|
#ifdef EU07_USE_OPTIMIZED_NORMALIZATION
|
||||||
switch( Submodel->m_normalizenormals ) {
|
switch( Submodel->m_normalizenormals ) {
|
||||||
@@ -1945,7 +2177,8 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
|||||||
|
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
// spotlights are only rendered in colour mode(s)
|
// spotlights are only rendered in colour mode(s)
|
||||||
case rendermode::color: {
|
case rendermode::color:
|
||||||
|
case rendermode::reflections: {
|
||||||
auto const &modelview = OpenGLMatrices.data( GL_MODELVIEW );
|
auto const &modelview = OpenGLMatrices.data( GL_MODELVIEW );
|
||||||
auto const lightcenter =
|
auto const lightcenter =
|
||||||
modelview
|
modelview
|
||||||
@@ -1977,15 +2210,22 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
|||||||
::glPushMatrix();
|
::glPushMatrix();
|
||||||
::glLoadIdentity();
|
::glLoadIdentity();
|
||||||
::glTranslatef( lightcenter.x, lightcenter.y, lightcenter.z ); // początek układu zostaje bez zmian
|
::glTranslatef( lightcenter.x, lightcenter.y, lightcenter.z ); // początek układu zostaje bez zmian
|
||||||
|
/*
|
||||||
setup_shadow_color( colors::white );
|
setup_shadow_color( colors::white );
|
||||||
|
*/
|
||||||
|
auto const unitstate = m_unitstate;
|
||||||
|
switch_units( m_unitstate.diffuse, false, false );
|
||||||
|
|
||||||
// main draw call
|
// main draw call
|
||||||
m_geometry.draw( Submodel->m_geometry );
|
m_geometry.draw( Submodel->m_geometry );
|
||||||
|
|
||||||
// post-draw reset
|
// post-draw reset
|
||||||
// re-enable shadows
|
// re-enable shadows
|
||||||
|
/*
|
||||||
setup_shadow_color( m_shadowcolor );
|
setup_shadow_color( m_shadowcolor );
|
||||||
|
*/
|
||||||
|
switch_units( m_unitstate.diffuse, unitstate.shadows, unitstate.reflections );
|
||||||
|
|
||||||
::glPopMatrix();
|
::glPopMatrix();
|
||||||
::glPopAttrib();
|
::glPopAttrib();
|
||||||
}
|
}
|
||||||
@@ -2001,7 +2241,8 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
|||||||
|
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
// colour points are only rendered in colour mode(s)
|
// colour points are only rendered in colour mode(s)
|
||||||
case rendermode::color: {
|
case rendermode::color:
|
||||||
|
case rendermode::reflections: {
|
||||||
if( Global::fLuminance < Submodel->fLight ) {
|
if( Global::fLuminance < Submodel->fLight ) {
|
||||||
|
|
||||||
// material configuration:
|
// material configuration:
|
||||||
@@ -2048,7 +2289,8 @@ opengl_renderer::Render( TTrack *Track ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
case rendermode::color: {
|
case rendermode::color:
|
||||||
|
case rendermode::reflections: {
|
||||||
Track->EnvironmentSet();
|
Track->EnvironmentSet();
|
||||||
if( Track->m_material1 != 0 ) {
|
if( Track->m_material1 != 0 ) {
|
||||||
Bind_Material( Track->m_material1 );
|
Bind_Material( Track->m_material1 );
|
||||||
@@ -2061,8 +2303,8 @@ opengl_renderer::Render( TTrack *Track ) {
|
|||||||
Track->EnvironmentReset();
|
Track->EnvironmentReset();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case rendermode::pickscenery:
|
case rendermode::shadows:
|
||||||
case rendermode::shadows: {
|
case rendermode::pickscenery: {
|
||||||
if( Track->m_material1 != 0 ) {
|
if( Track->m_material1 != 0 ) {
|
||||||
Bind_Material( Track->m_material1 );
|
Bind_Material( Track->m_material1 );
|
||||||
m_geometry.draw( std::begin( Track->Geometry1 ), std::end( Track->Geometry1 ) );
|
m_geometry.draw( std::begin( Track->Geometry1 ), std::end( Track->Geometry1 ) );
|
||||||
@@ -2098,11 +2340,12 @@ opengl_renderer::Render( TMemCell *Memcell ) {
|
|||||||
::glPopAttrib();
|
::glPopAttrib();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case rendermode::pickscenery:
|
case rendermode::shadows:
|
||||||
case rendermode::shadows: {
|
case rendermode::pickscenery: {
|
||||||
::gluSphere( m_quadric, 0.35, 4, 2 );
|
::gluSphere( m_quadric, 0.35, 4, 2 );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case rendermode::reflections:
|
||||||
case rendermode::pickcontrols: {
|
case rendermode::pickcontrols: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2502,11 +2745,15 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
|||||||
::glMaterialfv( GL_FRONT, GL_SPECULAR, glm::value_ptr( Submodel->f4Specular * Global::DayLight.specular.a * m_speculartranslucentscalefactor ) );
|
::glMaterialfv( GL_FRONT, GL_SPECULAR, glm::value_ptr( Submodel->f4Specular * Global::DayLight.specular.a * m_speculartranslucentscalefactor ) );
|
||||||
}
|
}
|
||||||
// ...luminance
|
// ...luminance
|
||||||
|
auto const unitstate = m_unitstate;
|
||||||
if( Global::fLuminance < Submodel->fLight ) {
|
if( Global::fLuminance < Submodel->fLight ) {
|
||||||
// zeby swiecilo na kolorowo
|
// zeby swiecilo na kolorowo
|
||||||
::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( Submodel->f4Diffuse * Submodel->f4Emision.a ) );
|
::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( Submodel->f4Diffuse * Submodel->f4Emision.a ) );
|
||||||
// disable shadows so they don't obstruct self-lit items
|
// disable shadows so they don't obstruct self-lit items
|
||||||
|
/*
|
||||||
setup_shadow_color( colors::white );
|
setup_shadow_color( colors::white );
|
||||||
|
*/
|
||||||
|
switch_units( m_unitstate.diffuse, false, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
// main draw call
|
// main draw call
|
||||||
@@ -2519,7 +2766,10 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
|||||||
if( Global::fLuminance < Submodel->fLight ) {
|
if( Global::fLuminance < Submodel->fLight ) {
|
||||||
// restore default (lack of) brightness
|
// restore default (lack of) brightness
|
||||||
::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( colors::none ) );
|
::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( colors::none ) );
|
||||||
|
/*
|
||||||
setup_shadow_color( m_shadowcolor );
|
setup_shadow_color( m_shadowcolor );
|
||||||
|
*/
|
||||||
|
switch_units( m_unitstate.diffuse, unitstate.shadows, unitstate.reflections );
|
||||||
}
|
}
|
||||||
#ifdef EU07_USE_OPTIMIZED_NORMALIZATION
|
#ifdef EU07_USE_OPTIMIZED_NORMALIZATION
|
||||||
switch( Submodel->m_normalizenormals ) {
|
switch( Submodel->m_normalizenormals ) {
|
||||||
@@ -2571,7 +2821,11 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
|||||||
::glTranslatef( lightcenter.x, lightcenter.y, lightcenter.z ); // początek układu zostaje bez zmian
|
::glTranslatef( lightcenter.x, lightcenter.y, lightcenter.z ); // początek układu zostaje bez zmian
|
||||||
::glRotated( std::atan2( lightcenter.x, lightcenter.z ) * 180.0 / M_PI, 0.0, 1.0, 0.0 ); // jedynie obracamy w pionie o kąt
|
::glRotated( std::atan2( lightcenter.x, lightcenter.z ) * 180.0 / M_PI, 0.0, 1.0, 0.0 ); // jedynie obracamy w pionie o kąt
|
||||||
// disable shadows so they don't obstruct self-lit items
|
// disable shadows so they don't obstruct self-lit items
|
||||||
|
/*
|
||||||
setup_shadow_color( colors::white );
|
setup_shadow_color( colors::white );
|
||||||
|
*/
|
||||||
|
auto const unitstate = m_unitstate;
|
||||||
|
switch_units( m_unitstate.diffuse, false, false );
|
||||||
|
|
||||||
// main draw call
|
// main draw call
|
||||||
m_geometry.draw( m_billboardgeometry );
|
m_geometry.draw( m_billboardgeometry );
|
||||||
@@ -2584,7 +2838,10 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
|||||||
// ...etc instead IF we had easy access to camera's forward and right vectors. TODO: check if Camera matrix is accessible
|
// ...etc instead IF we had easy access to camera's forward and right vectors. TODO: check if Camera matrix is accessible
|
||||||
*/
|
*/
|
||||||
// post-render cleanup
|
// post-render cleanup
|
||||||
|
/*
|
||||||
setup_shadow_color( m_shadowcolor );
|
setup_shadow_color( m_shadowcolor );
|
||||||
|
*/
|
||||||
|
switch_units( m_unitstate.diffuse, unitstate.shadows, unitstate.reflections );
|
||||||
|
|
||||||
::glPopMatrix();
|
::glPopMatrix();
|
||||||
::glPopAttrib();
|
::glPopAttrib();
|
||||||
|
|||||||
30
renderer.h
30
renderer.h
@@ -213,6 +213,7 @@ private:
|
|||||||
none,
|
none,
|
||||||
color,
|
color,
|
||||||
shadows,
|
shadows,
|
||||||
|
reflections,
|
||||||
pickcontrols,
|
pickcontrols,
|
||||||
pickscenery
|
pickscenery
|
||||||
};
|
};
|
||||||
@@ -233,14 +234,18 @@ private:
|
|||||||
float draw_range { 0.0f };
|
float draw_range { 0.0f };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct units_state {
|
||||||
|
|
||||||
|
bool diffuse { false };
|
||||||
|
bool shadows { false };
|
||||||
|
bool reflections { false };
|
||||||
|
};
|
||||||
|
|
||||||
typedef std::vector<opengl_light> opengllight_array;
|
typedef std::vector<opengl_light> opengllight_array;
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
bool
|
bool
|
||||||
Init_caps();
|
Init_caps();
|
||||||
// runs jobs needed to generate graphics for specified render pass
|
|
||||||
void
|
|
||||||
Render_pass( rendermode const Mode );
|
|
||||||
void
|
void
|
||||||
setup_pass( renderpass_config &Config, rendermode const Mode, float const Znear = 0.f, float const Zfar = 1.f, bool const Ignoredebug = false );
|
setup_pass( renderpass_config &Config, rendermode const Mode, float const Znear = 0.f, float const Zfar = 1.f, bool const Ignoredebug = false );
|
||||||
void
|
void
|
||||||
@@ -253,6 +258,12 @@ private:
|
|||||||
setup_shadow_color( glm::vec4 const &Shadowcolor );
|
setup_shadow_color( glm::vec4 const &Shadowcolor );
|
||||||
void
|
void
|
||||||
switch_units( bool const Diffuse, bool const Shadows, bool const Reflections );
|
switch_units( bool const Diffuse, bool const Shadows, bool const Reflections );
|
||||||
|
// runs jobs needed to generate graphics for specified render pass
|
||||||
|
void
|
||||||
|
Render_pass( rendermode const Mode );
|
||||||
|
// creates dynamic environment cubemap
|
||||||
|
bool
|
||||||
|
Render_reflections();
|
||||||
bool
|
bool
|
||||||
Render( world_environment *Environment );
|
Render( world_environment *Environment );
|
||||||
bool
|
bool
|
||||||
@@ -311,25 +322,32 @@ private:
|
|||||||
texture_handle m_moontexture { -1 };
|
texture_handle m_moontexture { -1 };
|
||||||
texture_handle m_reflectiontexture { -1 };
|
texture_handle m_reflectiontexture { -1 };
|
||||||
GLUquadricObj *m_quadric { nullptr }; // helper object for drawing debug mode scene elements
|
GLUquadricObj *m_quadric { nullptr }; // helper object for drawing debug mode scene elements
|
||||||
|
// TODO: refactor framebuffer stuff into an object
|
||||||
bool m_framebuffersupport { false };
|
bool m_framebuffersupport { false };
|
||||||
#ifdef EU07_USE_PICKING_FRAMEBUFFER
|
#ifdef EU07_USE_PICKING_FRAMEBUFFER
|
||||||
GLuint m_pickframebuffer { NULL }; // TODO: refactor pick framebuffer stuff into an object
|
GLuint m_pickframebuffer { NULL };
|
||||||
GLuint m_picktexture { NULL };
|
GLuint m_picktexture { NULL };
|
||||||
GLuint m_pickdepthbuffer { NULL };
|
GLuint m_pickdepthbuffer { NULL };
|
||||||
#endif
|
#endif
|
||||||
int m_shadowbuffersize { 4096 };
|
int m_shadowbuffersize { 2048 };
|
||||||
GLuint m_shadowframebuffer { NULL };
|
GLuint m_shadowframebuffer { NULL };
|
||||||
GLuint m_shadowtexture { NULL };
|
GLuint m_shadowtexture { NULL };
|
||||||
#ifdef EU07_USE_DEBUG_SHADOWMAP
|
#ifdef EU07_USE_DEBUG_SHADOWMAP
|
||||||
GLuint m_shadowdebugtexture{ NULL };
|
GLuint m_shadowdebugtexture{ NULL };
|
||||||
#endif
|
#endif
|
||||||
glm::mat4 m_shadowtexturematrix; // conversion from camera-centric world space to light-centric clip space
|
glm::mat4 m_shadowtexturematrix; // conversion from camera-centric world space to light-centric clip space
|
||||||
|
GLuint m_environmentframebuffer { NULL };
|
||||||
|
GLuint m_environmentcubetexture { NULL };
|
||||||
|
GLuint m_environmentdepthbuffer { NULL };
|
||||||
|
bool m_environmentcubetexturesupport { false }; // indicates whether we can use the dynamic environment cube map
|
||||||
|
int m_environmentcubetextureface { NULL }; // helper, currently processed cube map face
|
||||||
|
int m_environmenttimestamp { 0 }; // time of the most recent environment map update
|
||||||
|
|
||||||
int m_helpertextureunit { GL_TEXTURE0 };
|
int m_helpertextureunit { GL_TEXTURE0 };
|
||||||
int m_shadowtextureunit { GL_TEXTURE1 };
|
int m_shadowtextureunit { GL_TEXTURE1 };
|
||||||
int m_normaltextureunit { GL_TEXTURE2 };
|
int m_normaltextureunit { GL_TEXTURE2 };
|
||||||
int m_diffusetextureunit{ GL_TEXTURE3 };
|
int m_diffusetextureunit{ GL_TEXTURE3 };
|
||||||
|
units_state m_unitstate;
|
||||||
|
|
||||||
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
|
||||||
|
|||||||
Reference in New Issue
Block a user