refactoring: skydome visualization code extraction

This commit is contained in:
tmj-fstate
2019-10-23 16:45:56 +02:00
parent ae40f5486f
commit bc8b3d72f3
11 changed files with 181 additions and 69 deletions

View File

@@ -366,6 +366,9 @@
<ClCompile Include="openglparticles.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="openglskydome.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Globals.h">
@@ -629,9 +632,6 @@
<ClInclude Include="sky.h">
<Filter>Header Files\gfx</Filter>
</ClInclude>
<ClInclude Include="skydome.h">
<Filter>Header Files\gfx</Filter>
</ClInclude>
<ClInclude Include="Texture.h">
<Filter>Header Files\gfx</Filter>
</ClInclude>
@@ -671,6 +671,12 @@
<ClInclude Include="openglparticles.h">
<Filter>Header Files\gfx</Filter>
</ClInclude>
<ClInclude Include="openglskydome.h">
<Filter>Header Files\gfx</Filter>
</ClInclude>
<ClInclude Include="skydome.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="maszyna.rc">

View File

@@ -125,6 +125,7 @@ opengl_particles::update( opengl_camera const &Camera ) {
}
// ...and cleanup
::glPopClientAttrib();
::glBindBuffer( GL_ARRAY_BUFFER, 0 );
}
std::size_t
@@ -148,11 +149,8 @@ opengl_particles::render( int const Textureunit ) {
// ...draw...
::glDrawArrays( GL_QUADS, 0, m_particlevertices.size() );
// ...and cleanup
::glBindBuffer( GL_ARRAY_BUFFER, 0 );
if( Global.bUseVBO ) {
gfx::opengl_vbogeometrybank::reset();
}
::glPopClientAttrib();
::glBindBuffer( GL_ARRAY_BUFFER, 0 );
return m_particlevertices.size() / 4;
}

View File

@@ -1375,7 +1375,7 @@ opengl_renderer::Render( world_environment *Environment ) {
// drawn with 500m radius to blend in if the fog range is low
::glPushMatrix();
::glScalef( 500.f, 500.f, 500.f );
Environment->m_skydome.Render();
m_skydomerenderer.render();
if( Global.bUseVBO ) {
gfx::opengl_vbogeometrybank::reset();
}
@@ -2955,7 +2955,9 @@ opengl_renderer::Render_particles() {
Bind_Texture( m_smoketexture );
m_debugstats.particles = m_particlerenderer.render( m_diffusetextureunit );
if( Global.bUseVBO ) {
gfx::opengl_vbogeometrybank::reset();
}
::glDepthMask( GL_TRUE );
::glEnable( GL_LIGHTING );
}
@@ -3011,6 +3013,9 @@ opengl_renderer::Render_precipitation() {
::glDepthMask( GL_FALSE );
simulation::Environment.m_precipitation.render();
if( Global.bUseVBO ) {
gfx::opengl_vbogeometrybank::reset();
}
::glDepthMask( GL_TRUE );
::glEnable( GL_LIGHTING );
@@ -3769,6 +3774,7 @@ opengl_renderer::Update( double const Deltatime ) {
// update particle subsystem
renderpass_config renderpass;
setup_pass( renderpass, rendermode::color );
m_skydomerenderer.update();
m_particlerenderer.update( renderpass.camera );
}

View File

@@ -14,6 +14,7 @@ http://mozilla.org/MPL/2.0/.
#include "opengllight.h"
#include "openglcamera.h"
#include "openglparticles.h"
#include "openglskydome.h"
#include "lightarray.h"
#include "scene.h"
#include "simulationenvironment.h"
@@ -247,6 +248,8 @@ private:
texture_manager m_textures;
opengl_light m_sunlight;
opengllight_array m_lights;
opengl_skydome m_skydomerenderer;
opengl_particles m_particlerenderer; // particle visualization subsystem
/*
float m_sunandviewangle; // cached dot product of sunlight and camera vectors
*/
@@ -287,8 +290,6 @@ private:
int m_environmentcubetextureface { 0 }; // helper, currently processed cube map face
int m_environmentupdatetime { 0 }; // time of the most recent environment map update
glm::dvec3 m_environmentupdatelocation; // coordinates of most recent environment map update
// particle visualization subsystem
opengl_particles m_particlerenderer;
int m_helpertextureunit { GL_TEXTURE0 };
int m_shadowtextureunit { GL_TEXTURE1 };

98
openglskydome.cpp Normal file
View File

@@ -0,0 +1,98 @@
/*
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
*/
#include "stdafx.h"
#include "openglskydome.h"
#include "simulationenvironment.h"
#include "openglgeometrybank.h"
opengl_skydome::~opengl_skydome() {
if( m_vertexbuffer != 0 ) { ::glDeleteBuffers( 1, &m_vertexbuffer ); }
if( m_indexbuffer != 0 ) { ::glDeleteBuffers( 1, &m_indexbuffer ); }
if( m_coloursbuffer != 0 ) { ::glDeleteBuffers( 1, &m_coloursbuffer ); }
}
void opengl_skydome::update() {
auto &skydome { simulation::Environment.skydome() };
// cache entry state
::glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT );
// setup gpu data buffers:
// ...static data...
if( m_indexbuffer == -1 ) {
::glGenBuffers( 1, &m_indexbuffer );
if( ( m_indexbuffer > 0 ) && ( m_indexbuffer != (GLuint)-1 ) ) {
::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_indexbuffer );
auto const &indices { skydome.indices() };
::glBufferData( GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof( unsigned short ), indices.data(), GL_STATIC_DRAW );
m_indexcount = indices.size();
}
}
if( m_vertexbuffer == -1 ) {
::glGenBuffers( 1, &m_vertexbuffer );
if( ( m_vertexbuffer > 0 ) && ( m_vertexbuffer != (GLuint)-1 ) ) {
::glBindBuffer( GL_ARRAY_BUFFER, m_vertexbuffer );
auto const &vertices { skydome.vertices() };
::glBufferData( GL_ARRAY_BUFFER, vertices.size() * sizeof( glm::vec3 ), vertices.data(), GL_STATIC_DRAW );
}
}
// ...and dynamic data
if( m_coloursbuffer == -1 ) {
::glGenBuffers( 1, &m_coloursbuffer );
if( ( m_coloursbuffer > 0 ) && ( m_coloursbuffer != (GLuint)-1 ) ) {
::glBindBuffer( GL_ARRAY_BUFFER, m_coloursbuffer );
auto const &colors { skydome.colors() };
::glBufferData( GL_ARRAY_BUFFER, colors.size() * sizeof( glm::vec3 ), colors.data(), GL_DYNAMIC_DRAW );
}
}
// ship the current dynamic data to the gpu
// TODO: ship the data if it changed since the last update
if( true == skydome.is_dirty() ) {
if( ( m_coloursbuffer > 0 ) && ( m_coloursbuffer != (GLuint)-1 ) ) {
::glBindBuffer( GL_ARRAY_BUFFER, m_coloursbuffer );
auto const &colors { skydome.colors() };
::glBufferSubData( GL_ARRAY_BUFFER, 0, colors.size() * sizeof( glm::vec3 ), colors.data() );
skydome.is_dirty() = false;
}
}
// cleanup
::glPopClientAttrib();
::glBindBuffer( GL_ARRAY_BUFFER, 0 );
::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
}
// render skydome to screen
void opengl_skydome::render() {
if( ( m_indexbuffer == 0 ) || ( m_indexbuffer == (GLuint)-1 )
|| ( m_vertexbuffer == 0 ) || ( m_vertexbuffer == (GLuint)-1 )
|| ( m_coloursbuffer == 0 ) || ( m_coloursbuffer == (GLuint)-1 ) ) {
return;
}
// setup:
::glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT );
// ...positions...
::glBindBuffer( GL_ARRAY_BUFFER, m_vertexbuffer );
::glVertexPointer( 3, GL_FLOAT, sizeof( glm::vec3 ), reinterpret_cast<void const*>( 0 ) );
::glEnableClientState( GL_VERTEX_ARRAY );
// ...colours...
::glBindBuffer( GL_ARRAY_BUFFER, m_coloursbuffer );
::glColorPointer( 3, GL_FLOAT, sizeof( glm::vec3 ), reinterpret_cast<void const*>( 0 ) );
::glEnableClientState( GL_COLOR_ARRAY );
// ...indices
::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_indexbuffer );
// draw
::glDrawElements( GL_TRIANGLES, static_cast<GLsizei>( m_indexcount ), GL_UNSIGNED_SHORT, reinterpret_cast<void const*>( 0 ) );
// cleanup
::glPopClientAttrib();
::glBindBuffer( GL_ARRAY_BUFFER, 0 );
::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
}

33
openglskydome.h Normal file
View File

@@ -0,0 +1,33 @@
/*
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
*/
#pragma once
#include "GL/glew.h"
class opengl_skydome {
public:
// constructors
opengl_skydome() = default;
// destructor
~opengl_skydome();
// methods
// updates data stores on the opengl end. NOTE: unbinds
void update();
// draws the skydome
void render();
private:
// members
GLuint m_indexbuffer{ (GLuint)-1 }; // id of the buffer holding index data on the opengl end
std::size_t m_indexcount { 0 };
GLuint m_vertexbuffer{ (GLuint)-1 }; // id of the buffer holding vertex data on the opengl end
GLuint m_coloursbuffer{ (GLuint)-1 }; // id of the buffer holding colour data on the opengl end
};

View File

@@ -203,4 +203,6 @@ basic_precipitation::render() {
::glLoadIdentity();
::glMatrixMode( GL_MODELVIEW );
::glPopClientAttrib();
::glBindBuffer( GL_ARRAY_BUFFER, 0 );
::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
}

View File

@@ -37,10 +37,16 @@ public:
// calculates current weather
void compute_weather() const;
// data access
glm::vec3 const &
inline auto const &
skydome() const {
return m_skydome; }
inline auto &
skydome() {
return m_skydome; }
inline auto const &
wind() const {
return m_wind.vector; }
float const &
inline auto const &
wind_azimuth() const {
return m_wind.azimuth; }

View File

@@ -706,7 +706,12 @@ state_serializer::deserialize_endtrainset( cParser &Input, scene::scratch_data &
}
if( Scratchpad.trainset.couplings.back() == coupling::faux ) {
// jeśli ostatni pojazd ma sprzęg 0 to założymy mu końcówki blaszane (jak AI się odpali, to sobie poprawi)
Scratchpad.trainset.vehicles.back()->RaLightsSet( -1, light::rearendsignals );
// place end signals only on trains without a driver, activate markers otherwise
Scratchpad.trainset.vehicles.back()->RaLightsSet(
-1,
( Scratchpad.trainset.driver != nullptr ?
light::redmarker_left | light::redmarker_right | light::rearendsignals :
light::rearendsignals ) );
}
// all done
Scratchpad.trainset.is_open = false;

View File

@@ -116,42 +116,6 @@ void CSkyDome::Update( glm::vec3 const &Sun ) {
}
// render skydome to screen
void CSkyDome::Render() {
// cache entry state
::glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT );
if( m_vertexbuffer == -1 ) {
// build the buffers
::glGenBuffers( 1, &m_vertexbuffer );
::glBindBuffer( GL_ARRAY_BUFFER, m_vertexbuffer );
::glBufferData( GL_ARRAY_BUFFER, m_vertices.size() * sizeof( glm::vec3 ), m_vertices.data(), GL_STATIC_DRAW );
::glGenBuffers( 1, &m_coloursbuffer );
::glBindBuffer( GL_ARRAY_BUFFER, m_coloursbuffer );
::glBufferData( GL_ARRAY_BUFFER, m_colours.size() * sizeof( glm::vec3 ), m_colours.data(), GL_DYNAMIC_DRAW );
::glGenBuffers( 1, &m_indexbuffer );
::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_indexbuffer );
::glBufferData( GL_ELEMENT_ARRAY_BUFFER, m_indices.size() * sizeof( unsigned short ), m_indices.data(), GL_STATIC_DRAW );
// NOTE: vertex and index source data is superfluous past this point, but, eh
}
// begin
::glEnableClientState( GL_VERTEX_ARRAY );
::glEnableClientState( GL_COLOR_ARRAY );
// positions
::glBindBuffer( GL_ARRAY_BUFFER, m_vertexbuffer );
::glVertexPointer( 3, GL_FLOAT, sizeof( glm::vec3 ), reinterpret_cast<void const*>( 0 ) );
// colours
::glBindBuffer( GL_ARRAY_BUFFER, m_coloursbuffer );
::glColorPointer( 3, GL_FLOAT, sizeof( glm::vec3 ), reinterpret_cast<void const*>( 0 ) );
// indices
::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_indexbuffer );
::glDrawElements( GL_TRIANGLES, static_cast<GLsizei>( m_indices.size() ), GL_UNSIGNED_SHORT, reinterpret_cast<void const*>( 0 ) );
// cleanup
::glPopClientAttrib();
}
bool CSkyDome::SetSunPosition( glm::vec3 const &Direction ) {
if( Direction == m_sundirection ) {
@@ -341,23 +305,11 @@ void CSkyDome::RebuildColors() {
averagehorizoncolor += color;
}
}
// NOTE: average reduced to 25% makes nice tint value for clouds lit from behind
// down the road we could interpolate between it and full strength average, to improve accuracy of cloud appearance
m_averagecolour = glm::max( glm::vec3(), averagecolor / static_cast<float>( m_vertices.size() ) );
m_averagehorizoncolour = glm::max( glm::vec3(), averagehorizoncolor / static_cast<float>( m_tesselation * 2 ) );
if( m_coloursbuffer != -1 ) {
// the colour buffer was already initialized, so on this run we update its content
// cache entry state
::glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT );
// begin
::glEnableClientState( GL_VERTEX_ARRAY );
// update
::glBindBuffer( GL_ARRAY_BUFFER, m_coloursbuffer );
::glBufferSubData( GL_ARRAY_BUFFER, 0, m_colours.size() * sizeof( glm::vec3 ), m_colours.data() );
// cleanup
::glPopClientAttrib();
}
m_dirty = true;
}
//******************************************************************************//

View File

@@ -19,13 +19,20 @@ public:
// update skydome
void Update( glm::vec3 const &Sun );
// render skydome to screen
void Render();
// retrieves average colour of the sky dome
glm::vec3 GetAverageColor() { return m_averagecolour * 8.f / 6.f; }
glm::vec3 GetAverageHorizonColor() { return m_averagehorizoncolour; }
std::vector<glm::vec3> const & vertices() const {
return m_vertices; }
std::vector<glm::vec3> const & colors() const {
return m_colours; }
std::vector<std::uint16_t> const & indices() const {
return m_indices; }
auto const & is_dirty() const { return m_dirty; }
auto & is_dirty() { return m_dirty; }
private:
// shading parametrs
glm::vec3 m_sundirection;
@@ -44,9 +51,7 @@ private:
std::vector<std::uint16_t> m_indices;
// std::vector<float3> m_normals;
std::vector<glm::vec3> m_colours;
GLuint m_vertexbuffer{ (GLuint)-1 };
GLuint m_indexbuffer{ (GLuint)-1 };
GLuint m_coloursbuffer{ (GLuint)-1 };
bool m_dirty { true }; // indicates sync state between simulation and gpu sides
static float m_distributionluminance[ 5 ][ 2 ];
static float m_distributionxcomp[ 5 ][ 2 ];