16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-18 21:29:18 +02:00

Merge remote-tracking branch 'tmj-fstate/mover_in_c++' into mover_in_c++

This commit is contained in:
firleju
2017-07-24 14:47:36 +02:00
23 changed files with 372 additions and 186 deletions

View File

@@ -445,7 +445,7 @@ bool TAnimModel::Init(std::string const &asName, std::string const &asReplacable
asText = asReplacableTexture.substr(1, asReplacableTexture.length() - 1); // zapamiętanie tekstu
else if (asReplacableTexture != "none")
m_materialdata.replacable_skins[1] =
GfxRenderer.GetTextureId( asReplacableTexture, "" );
GfxRenderer.Fetch_Texture( asReplacableTexture, "" );
if( ( m_materialdata.replacable_skins[ 1 ] != 0 )
&& ( GfxRenderer.Texture( m_materialdata.replacable_skins[ 1 ] ).has_alpha ) ) {
// tekstura z kanałem alfa - nie renderować w cyklu nieprzezroczystych
@@ -606,6 +606,7 @@ int TAnimModel::Flags()
//-----------------------------------------------------------------------------
// 2011-03-16 funkcje renderowania z możliwością pochylania obiektów
//-----------------------------------------------------------------------------
#ifdef EU07_USE_OLD_RENDERCODE
void TAnimModel::Render( vector3 const &Position ) {
RaAnimate(); // jednorazowe przeliczenie animacji
RaPrepare();
@@ -617,7 +618,7 @@ void TAnimModel::RenderAlpha( vector3 const &Position ) {
if( pModel ) // renderowanie rekurencyjne submodeli
GfxRenderer.Render_Alpha( pModel, Material(), Position, vAngle );
};
#endif
//---------------------------------------------------------------------------
bool TAnimModel::TerrainLoaded()
{ // zliczanie kwadratów kilometrowych (główna linia po Next) do tworznia tablicy

View File

@@ -164,8 +164,10 @@ class TAnimModel {
bool Load(cParser *parser, bool ter = false);
TAnimContainer * AddContainer(char *pName);
TAnimContainer * GetContainer(char *pName);
#ifdef EU07_USE_OLD_RENDERCODE
void Render( vector3 const &Position );
void RenderAlpha( vector3 const &Position );
#endif
int Flags();
void RaAnglesSet(double a, double b, double c)
{

View File

@@ -14,13 +14,6 @@ http://mozilla.org/MPL/2.0/.
#include "Console.h"
#include "logs.h"
TButton::TButton()
{
iFeedbackBit = 0;
bData = NULL;
Clear();
};
void TButton::Clear(int i)
{
pModelOn = nullptr;

View File

@@ -36,7 +36,7 @@ class TButton
play( PSound Sound );
public:
TButton();
TButton() = default;
void Clear(int const i = -1);
inline void FeedbackBitSet(int const i) {
iFeedbackBit = 1 << i; };

View File

@@ -4066,7 +4066,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
{
std::string nowheretexture = TextureTest(Global::asCurrentTexturePath + "nowhere"); // na razie prymitywnie
if( false == nowheretexture.empty() ) {
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.GetTextureId( nowheretexture, "", 9 );
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.Fetch_Texture( nowheretexture, "", 9 );
}
if (m_materialdata.multi_textures > 0) {
@@ -4078,7 +4078,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
int skinindex = 0;
std::string texturename; nameparser >> texturename;
while( ( texturename != "" ) && ( skinindex < 4 ) ) {
m_materialdata.replacable_skins[ skinindex + 1 ] = GfxRenderer.GetTextureId( Global::asCurrentTexturePath + texturename, "" );
m_materialdata.replacable_skins[ skinindex + 1 ] = GfxRenderer.Fetch_Texture( Global::asCurrentTexturePath + texturename, "" );
++skinindex;
texturename = ""; nameparser >> texturename;
}
@@ -4088,7 +4088,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
// otherwise try the basic approach
int skinindex = 0;
do {
texture_handle texture = GfxRenderer.GetTextureId( Global::asCurrentTexturePath + ReplacableSkin + "," + std::to_string( skinindex + 1 ), "", Global::iDynamicFiltering, true );
texture_handle texture = GfxRenderer.Fetch_Texture( Global::asCurrentTexturePath + ReplacableSkin + "," + std::to_string( skinindex + 1 ), "", Global::iDynamicFiltering, true );
if( texture == NULL ) {
break;
}
@@ -4098,12 +4098,12 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
m_materialdata.multi_textures = skinindex;
if( m_materialdata.multi_textures == 0 ) {
// zestaw nie zadziałał, próbujemy normanie
m_materialdata.replacable_skins[ 1 ] = GfxRenderer.GetTextureId( Global::asCurrentTexturePath + ReplacableSkin, "", Global::iDynamicFiltering );
m_materialdata.replacable_skins[ 1 ] = GfxRenderer.Fetch_Texture( Global::asCurrentTexturePath + ReplacableSkin, "", Global::iDynamicFiltering );
}
}
}
else {
m_materialdata.replacable_skins[ 1 ] = GfxRenderer.GetTextureId( Global::asCurrentTexturePath + ReplacableSkin, "", Global::iDynamicFiltering );
m_materialdata.replacable_skins[ 1 ] = GfxRenderer.Fetch_Texture( Global::asCurrentTexturePath + ReplacableSkin, "", Global::iDynamicFiltering );
}
if( GfxRenderer.Texture( m_materialdata.replacable_skins[ 1 ] ).has_alpha ) {
// tekstura -1 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
@@ -5426,13 +5426,13 @@ void TDynamicObject::DestinationSet(std::string to, std::string numer)
std::string x = TextureTest(asBaseDir + numer + "@" + MoverParameters->TypeName);
if (!x.empty())
{
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.GetTextureId( x, "", 9 ); // rozmywania 0,1,4,5 nie nadają się
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.Fetch_Texture( x, "", 9 ); // rozmywania 0,1,4,5 nie nadają się
return;
}
x = TextureTest(asBaseDir + numer );
if (!x.empty())
{
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.GetTextureId( x, "", 9 ); // rozmywania 0,1,4,5 nie nadają się
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.Fetch_Texture( x, "", 9 ); // rozmywania 0,1,4,5 nie nadają się
return;
}
if (to.empty())
@@ -5440,17 +5440,17 @@ void TDynamicObject::DestinationSet(std::string to, std::string numer)
x = TextureTest(asBaseDir + to + "@" + MoverParameters->TypeName); // w pierwszej kolejności z nazwą FIZ/MMD
if (!x.empty())
{
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.GetTextureId( x, "", 9 ); // rozmywania 0,1,4,5 nie nadają się
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.Fetch_Texture( x, "", 9 ); // rozmywania 0,1,4,5 nie nadają się
return;
}
x = TextureTest(asBaseDir + to); // na razie prymitywnie
if (!x.empty())
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.GetTextureId( x, "", 9 ); // rozmywania 0,1,4,5 nie nadają się
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.Fetch_Texture( x, "", 9 ); // rozmywania 0,1,4,5 nie nadają się
else
{
x = TextureTest(asBaseDir + "nowhere"); // jak nie znalazł dedykowanej, to niech daje nowhere
if (!x.empty())
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.GetTextureId( x, "", 9 );
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.Fetch_Texture( x, "", 9 );
}
// Ra 2015-01: żeby zalogować błąd, trzeba by mieć pewność, że model używa tekstury nr 4
};

View File

@@ -180,7 +180,7 @@ void TGauge::DecValue(double fNewDesired)
void
TGauge::UpdateValue( double fNewDesired, PSound Fallbacksound ) {
if( static_cast<int>( std::round( ( fDesiredValue - fOffset ) / fScale ) ) == static_cast<int>( fNewDesired ) ) {
if( static_cast<int>( std::round( 100.0 * ( fDesiredValue - fOffset ) / fScale ) ) == static_cast<int>( 100.0 * fNewDesired ) ) {
return;
}
fDesiredValue = fNewDesired * fScale + fOffset;

View File

@@ -87,6 +87,7 @@ float Global::Overcast { 0.1f }; // NOTE: all this weather stuff should be moved
opengl_light Global::DayLight;
int Global::DynamicLightCount { 3 };
bool Global::ScaleSpecularValues { true };
bool Global::RenderShadows { false };
bool Global::bRollFix = true; // czy wykonać przeliczanie przechyłki
bool Global::bJoinEvents = false; // czy grupować eventy o tych samych nazwach
int Global::iHiddenEvents = 1; // czy łączyć eventy z torami poprzez nazwę toru
@@ -544,6 +545,11 @@ void Global::ConfigParse(cParser &Parser)
Parser.getTokens();
Parser >> Global::ScaleSpecularValues;
}
else if( token == "shadows" ) {
// shadow render toggle
Parser.getTokens();
Parser >> Global::RenderShadows;
}
else if (token == "smoothtraction")
{
// podwójna jasność ambient

View File

@@ -226,6 +226,7 @@ class Global
static opengl_light DayLight;
static int DynamicLightCount;
static bool ScaleSpecularValues;
static bool RenderShadows;
static int iSlowMotion;
static TDynamicObject *changeDynObj;

View File

@@ -49,15 +49,6 @@ extern "C"
bool bCondition; // McZapkie: do testowania warunku na event multiple
std::string LogComment;
// tests whether provided points form a degenerate triangle
bool
degenerate( glm::dvec3 const &Vertex1, glm::dvec3 const &Vertex2, glm::dvec3 const &Vertex3 ) {
return ( ( Vertex1 == Vertex2 )
|| ( Vertex2 == Vertex3 )
|| ( Vertex3 == Vertex1 ) );
}
//---------------------------------------------------------------------------
// Obiekt renderujący siatkę jest sztucznie tworzonym obiektem pomocniczym,
// grupującym siatki obiektów dla danej tekstury. Obiektami składowymi mogą
@@ -1331,7 +1322,7 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
*parser >> token;
}
str = token;
tmp->TextureID = GfxRenderer.GetTextureId( str, szTexturePath );
tmp->TextureID = GfxRenderer.Fetch_Texture( str );
bool const clamps = (
tmp->TextureID ?
GfxRenderer.Texture( tmp->TextureID ).traits.find( 's' ) != std::string::npos :

View File

@@ -341,7 +341,7 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
if( texture.find_first_of( "/\\" ) == texture.npos ) {
texture.insert( 0, Global::asCurrentTexturePath );
}
TextureID = GfxRenderer.GetTextureId( texture, szTexturePath );
TextureID = GfxRenderer.Fetch_Texture( texture );
// renderowanie w cyklu przezroczystych tylko jeśli:
// 1. Opacity=0 (przejściowo <1, czy tam <100) oraz
// 2. tekstura ma przezroczystość
@@ -460,10 +460,8 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
>> Vertices[i].texture.t;
if (i % 3 == 2) {
// jeżeli wczytano 3 punkty
if (Vertices[i ].position == Vertices[i - 1].position
|| Vertices[i - 1].position == Vertices[i - 2].position
|| Vertices[i - 2].position == Vertices[i ].position)
{ // jeżeli punkty się nakładają na siebie
if( true == degenerate( Vertices[ i ].position, Vertices[ i - 1 ].position, Vertices[ i - 2 ].position ) ) {
// jeżeli punkty się nakładają na siebie
--facecount; // o jeden trójkąt mniej
iNumVerts -= 3; // czyli o 3 wierzchołki
i -= 3; // wczytanie kolejnego w to miejsce
@@ -1670,7 +1668,7 @@ void TSubModel::BinInit(TSubModel *s, float4x4 *m, std::vector<std::string> *t,
pTexture = t->at(iTexture);
if (pTexture.find_last_of("/\\") == std::string::npos)
pTexture.insert(0, Global::asCurrentTexturePath);
TextureID = GfxRenderer.GetTextureId(pTexture, szTexturePath);
TextureID = GfxRenderer.Fetch_Texture(pTexture);
if( ( iFlags & 0x30 ) == 0 ) {
// texture-alpha based fallback if for some reason we don't have opacity flag set yet
iFlags |=

View File

@@ -483,20 +483,20 @@ void TTrack::Load(cParser *parser, vector3 pOrigin, std::string name)
{
parser->getTokens();
*parser >> str; // railtex
TextureID1 = (str == "none" ? 0 : GfxRenderer.GetTextureId(
str, szTexturePath,
(iCategoryFlag & 1) ? Global::iRailProFiltering :
Global::iBallastFiltering));
TextureID1 = (
str == "none" ?
NULL :
GfxRenderer.Fetch_Texture( str ) );
parser->getTokens();
*parser >> fTexLength; // tex tile length
if (fTexLength < 0.01)
fTexLength = 4; // Ra: zabezpiecznie przed zawieszeniem
parser->getTokens();
*parser >> str; // sub || railtex
TextureID2 = (str == "none" ? 0 : GfxRenderer.GetTextureId(
str, szTexturePath,
(eType == tt_Normal) ? Global::iBallastFiltering :
Global::iRailProFiltering));
TextureID2 = (
str == "none" ?
NULL :
GfxRenderer.Fetch_Texture( str ) );
parser->getTokens(3);
*parser >> fTexHeight1 >> fTexWidth >> fTexSlope;
if (iCategoryFlag & 4)
@@ -1267,31 +1267,32 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
}
vertex_array vertices;
Segment->RenderLoft(vertices, origin, bpts1, iTrapezoid ? -4 : 4, fTexLength);
if( ( Bank != 0 ) && ( true == Geometry2.empty() ) ) {
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
}
if( ( Bank == 0 ) && ( false == Geometry2.empty() ) ) {
// special variant, replace existing data for a turntable track
GfxRenderer.Replace( vertices, Geometry2[ 0 ] );
}
else {
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
}
}
if (TextureID1)
{ // szyny - generujemy dwie, najwyżej rysować się będzie jedną
vertex_array vertices;
if( ( Bank != 0 ) && ( true == Geometry1.empty() ) ) {
Segment->RenderLoft( vertices, origin, rpts1, iTrapezoid ? -nnumPts : nnumPts, fTexLength );
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear(); // reuse the scratchpad
Segment->RenderLoft( vertices, origin, rpts2, iTrapezoid ? -nnumPts : nnumPts, fTexLength );
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
}
if( ( Bank == 0 ) && ( false == Geometry1.empty() ) ) {
// special variant, replace existing data for a turntable track
Segment->RenderLoft( vertices, origin, rpts1, iTrapezoid ? -nnumPts : nnumPts, fTexLength );
GfxRenderer.Replace( vertices, Geometry1[ 0 ] );
vertices.clear(); // reuse the scratchpad
Segment->RenderLoft( vertices, origin, rpts2, iTrapezoid ? -nnumPts : nnumPts, fTexLength );
GfxRenderer.Replace( vertices, Geometry1[ 1 ] );
}
else {
Segment->RenderLoft( vertices, origin, rpts1, iTrapezoid ? -nnumPts : nnumPts, fTexLength );
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear(); // reuse the scratchpad
Segment->RenderLoft( vertices, origin, rpts2, iTrapezoid ? -nnumPts : nnumPts, fTexLength );
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
}
}
break;
case tt_Switch: // dla zwrotnicy dwa razy szyny
@@ -1865,22 +1866,6 @@ void TTrack::EnvironmentReset()
}
};
void TTrack::RenderDyn()
{ // renderowanie nieprzezroczystych fragmentów pojazdów
for( auto dynamic : Dynamics ) {
// sam sprawdza, czy VBO; zmienia kontekst VBO!
GfxRenderer.Render( dynamic );
}
};
void TTrack::RenderDynAlpha()
{ // renderowanie przezroczystych fragmentów pojazdów
for( auto dynamic : Dynamics ) {
// sam sprawdza, czy VBO; zmienia kontekst VBO!
GfxRenderer.Render_Alpha( dynamic );
}
};
void TTrack::RenderDynSounds()
{ // odtwarzanie dźwięków pojazdów jest niezależne od ich wyświetlania
for( auto dynamic : Dynamics ) {

View File

@@ -236,8 +236,6 @@ public:
/*
void RaRenderVBO(int iPtr); // renderowanie z VBO sektora
*/
void RenderDyn(); // renderowanie nieprzezroczystych pojazdów (oba tryby)
void RenderDynAlpha(); // renderowanie przezroczystych pojazdów (oba tryby)
void RenderDynSounds(); // odtwarzanie dźwięków pojazdów jest niezależne od ich wyświetlania
void RaOwnerSet(TSubRect *o) {

View File

@@ -125,9 +125,11 @@ mouse_input::button( int const Button, int const Action ) {
// TODO: pass correct entity id once the missing systems are in place
m_relay.post( mousecommand, 0, 0, Action, 0 );
m_updateaccumulator = 0.0; // prevent potential command repeat right after issuing one
/*
if( mousecommand == user_command::mastercontrollerincrease ) {
m_updateaccumulator -= 0.15; // extra pause on first increase of master controller
}
*/
switch( mousecommand ) {
case user_command::mastercontrollerincrease:
case user_command::mastercontrollerdecrease:

View File

@@ -120,10 +120,9 @@ opengl_renderer::Init( GLFWwindow *Window ) {
m_lights.emplace_back( light );
}
#ifdef EU07_USE_PICKING_FRAMEBUFFER
// pick buffer resources
if( true == m_framebuffersupport ) {
// try to create the pick buffer. RGBA8 2D texture, 24 bit depth texture, 1024x512
int const width { 1024 };
int const height { 512 };
// try to create the pick buffer. RGBA8 2D texture, 24 bit depth texture, 1024x1024 (height of 512 would suffice but, eh)
// texture
::glGenTextures( 1, &m_picktexture );
::glBindTexture( GL_TEXTURE_2D, m_picktexture );
@@ -131,18 +130,17 @@ opengl_renderer::Init( GLFWwindow *Window ) {
::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_MAG_FILTER, GL_NEAREST );
::glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL );
::glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, m_pickbuffersize, m_pickbuffersize, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL );
// depth buffer
::glGenRenderbuffersEXT( 1, &m_pickdepthbuffer );
::glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, m_pickdepthbuffer );
::glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, width, height );
// create and set up the framebuffer
::glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, m_pickbuffersize, m_pickbuffersize );
// create and assemble the framebuffer
::glGenFramebuffersEXT( 1, &m_pickframebuffer );
::glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, m_pickframebuffer );
::glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_picktexture, 0 );
::glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_pickdepthbuffer );
//-------------------------
//Does the GPU support current FBO configuration?
// check if we got it working
GLenum status = ::glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
if( status == GL_FRAMEBUFFER_COMPLETE_EXT ) {
WriteLog( "Picking framebuffer setup complete" );
@@ -154,12 +152,47 @@ opengl_renderer::Init( GLFWwindow *Window ) {
::glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); // switch back to primary render target for now
}
#endif
// shadowmap resources
if( ( true == Global::RenderShadows )
&& ( true == m_framebuffersupport ) ) {
// texture:
::glGenTextures( 1, &m_shadowtexture );
::glBindTexture( GL_TEXTURE_2D, m_shadowtexture );
::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_MIN_FILTER, GL_NEAREST );
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
// enable shadow comparison: true (ie not in shadow) if r<=texture...
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE );
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL );
// ...shadow comparison should generate an INTENSITY result
::glTexParameteri( GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY );
::glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, m_shadowbuffersize, m_shadowbuffersize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL );
// create and assemble the framebuffer
::glGenFramebuffersEXT( 1, &m_shadowframebuffer );
::glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, m_shadowframebuffer );
::glDrawBuffer( GL_NONE ); // we won't be rendering colour data, so can skip the colour attachment
::glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, m_shadowtexture, 0 );
// check if we got it working
GLenum status = ::glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
if( status == GL_FRAMEBUFFER_COMPLETE_EXT ) {
WriteLog( "Shadows framebuffer setup complete" );
}
else {
ErrorLog( "Shadows framebuffer setup failed" );
m_framebuffersupport = false;
Global::RenderShadows = false;
}
::glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); // switch back to primary render target for now
::glDrawBuffer( GL_BACK );
}
::glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
// preload some common textures
WriteLog( "Loading common gfx data..." );
m_glaretexture = GetTextureId( "fx\\lightglare", szTexturePath );
m_suntexture = GetTextureId( "fx\\sun", szTexturePath );
m_moontexture = GetTextureId( "fx\\moon", szTexturePath );
m_glaretexture = Fetch_Texture( "fx\\lightglare" );
m_suntexture = Fetch_Texture( "fx\\sun" );
m_moontexture = Fetch_Texture( "fx\\moon" );
WriteLog( "...gfx data pre-loading done" );
// prepare basic geometry chunks
auto const geometrybank = m_geometry.create_bank();
@@ -203,13 +236,27 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
case rendermode::color: {
// TODO: run shadowmap pass before color
if( Global::RenderShadows && World.InitPerformed() ) {
// run shadowmap pass before color
::glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, m_shadowframebuffer );
::glDrawBuffer( GL_NONE ); // we won't be rendering colour data, so can skip the colour attachment
Render_pass( rendermode::shadows );
m_renderpass.draw_mode = rendermode::color; // restore draw mode. TODO: render mode stack
::glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); // switch back to primary render target
::glDrawBuffer( GL_BACK );
}
::glViewport( 0, 0, Global::ScreenWidth, Global::ScreenHeight );
// ::glViewport( 0, 0, Global::ScreenWidth, Global::ScreenHeight );
if( World.InitPerformed() ) {
auto const skydomecolour = World.Environment.m_skydome.GetAverageColor();
::glClearColor( skydomecolour.x, skydomecolour.y, skydomecolour.z, 0.0f ); // kolor nieba
}
else {
::glClearColor( 51.0f / 255.0f, 102.0f / 255.0f, 85.0f / 255.0f, 1.0f ); // initial background Color
}
::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
if( World.InitPerformed() ) {
@@ -234,9 +281,32 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
break;
}
case rendermode::shadows: {
::glViewport( 0, 0, m_shadowbuffersize, m_shadowbuffersize );
::glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
::glClear( GL_DEPTH_BUFFER_BIT );
if( World.InitPerformed() ) {
// setup
m_renderpass.draw_range = 500.0f; // 1.0km square centered around camera
Render_projection();
Render_camera();
::glDepthFunc( GL_LEQUAL );
// render
// opaque parts...
Render_setup();
Render( &World.Ground );
}
break;
}
case rendermode::pickcontrols: {
// ::glViewport( 0, 0, 1024, 512 );
#ifdef EU07_USE_PICKING_FRAMEBUFFER
::glViewport( 0, 0, m_pickbuffersize, m_pickbuffersize );
#endif
::glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
@@ -259,7 +329,9 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
case rendermode::pickscenery: {
// ::glViewport( 0, 0, 1024, 512 );
#ifdef EU07_USE_PICKING_FRAMEBUFFER
::glViewport( 0, 0, m_pickbuffersize, m_pickbuffersize );
#endif
::glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
@@ -294,9 +366,11 @@ opengl_renderer::Render_projection() {
switch( m_renderpass.draw_mode ) {
case rendermode::color:
#ifndef EU07_USE_PICKING_FRAMEBUFFER
case rendermode::pickcontrols:
case rendermode::pickscenery: {
case rendermode::pickscenery:
#endif
case rendermode::color: {
::gluPerspective(
Global::FieldOfView / Global::ZoomFactor,
std::max( 1.0f, (float)Global::ScreenWidth ) / std::max( 1.0f, (float)Global::ScreenHeight ),
@@ -304,21 +378,28 @@ opengl_renderer::Render_projection() {
m_renderpass.draw_range * Global::fDistanceFactor );
break;
}
/*
// version for the smaller pickbuffer. ultimately scratched because resolution isn't comfortable/reliable enough for the user
#ifdef EU07_USE_PICKING_FRAMEBUFFER
case rendermode::pickcontrols:
case rendermode::pickscenery: {
// TODO: render to buffer and scissor test for pick modes
// TODO: scissor test for pick modes
auto const angle = Global::FieldOfView / Global::ZoomFactor;
auto const height = std::max( 1.0f, (float)Global::ScreenWidth ) / std::max( 1.0f, (float)Global::ScreenHeight ) / ( Global::ScreenWidth / m_pickbuffersize );
::gluPerspective(
Global::FieldOfView / Global::ZoomFactor,
std::max( 1.0f, (float)Global::ScreenWidth ) / std::max( 1.0f, (float)Global::ScreenHeight ) / ( Global::ScreenWidth / 1024.0f ),
std::max( 1.0f, (float)Global::ScreenWidth ) / std::max( 1.0f, (float)Global::ScreenHeight ) / ( Global::ScreenWidth / m_pickbuffersize ),
0.1f * Global::ZoomFactor,
m_renderpass.draw_range * Global::fDistanceFactor );
break;
}
*/
#endif
case rendermode::shadows: {
// TODO: set parallel projection
::gluPerspective(
Global::FieldOfView,
1.f,
// std::max( 1.0f, (float)Global::ScreenWidth ) / std::max( 1.0f, (float)Global::ScreenHeight ),
2.f,
m_renderpass.draw_range * Global::fDistanceFactor );
break;
}
@@ -346,7 +427,7 @@ opengl_renderer::Render_camera() {
break;
}
case rendermode::shadows: {
m_renderpass.camera.position() = Global::pCameraPosition - glm::dvec3{ Global::DayLight.direction * 750.f };
m_renderpass.camera.position() = Global::pCameraPosition - glm::dvec3{ Global::DayLight.direction * 250.f };
m_renderpass.camera.position().y = std::max( 50.0, m_renderpass.camera.position().y ); // prevent shadow source from dipping too low
viewmatrix = glm::lookAt(
m_renderpass.camera.position(),
@@ -380,6 +461,9 @@ opengl_renderer::Render_setup( bool const Alpha ) {
case rendermode::color: {
::glEnable( GL_LIGHTING );
::glShadeModel( GL_SMOOTH );
if( Global::iMultisampling ) {
::glEnable( GL_MULTISAMPLE );
}
// setup fog
if( Global::fFogEnd > 0 ) {
// fog setup
@@ -407,9 +491,12 @@ opengl_renderer::Render_setup( bool const Alpha ) {
case rendermode::shadows:
case rendermode::pickcontrols:
case rendermode::pickscenery: {
::glDisable( GL_FOG );
::glDisable( GL_LIGHTING );
::glShadeModel( GL_FLAT );
if( Global::iMultisampling ) {
::glDisable( GL_MULTISAMPLE );
}
::glDisable( GL_FOG );
if( m_texenvmode != m_renderpass.draw_mode ) {
// solid colour with texture alpha
@@ -441,19 +528,32 @@ opengl_renderer::Render( world_environment *Environment ) {
}
Bind( NULL );
::glDisable( GL_LIGHTING );
::glDisable( GL_DEPTH_TEST );
::glDepthMask( GL_FALSE );
::glPushMatrix();
// skydome
Environment->m_skydome.Render();
if( true == Global::bUseVBO ) {
// skydome uses a custom vbo which could potentially confuse the main geometry system. hardly elegant but, eh
opengl_vbogeometrybank::reset();
}
Environment->m_stars.render();
// stars
if( Environment->m_stars.m_stars != nullptr ) {
// setup
::glPushMatrix();
::glRotatef( Environment->m_stars.m_latitude, 1.f, 0.f, 0.f ); // ustawienie osi OY na północ
::glRotatef( -std::fmod( (float)Global::fTimeAngleDeg, 360.f ), 0.f, 1.f, 0.f ); // obrót dobowy osi OX
::glPointSize( 2.f );
// render
GfxRenderer.Render( Environment->m_stars.m_stars, nullptr, 1.0 );
// post-render cleanup
::glPointSize( 3.f );
::glPopMatrix();
}
// celestial bodies
float const duskfactor = 1.0f - clamp( std::abs( Environment->m_sun.getAngle() ), 0.0f, 12.0f ) / 12.0f;
glm::vec3 suncolor = interpolate(
glm::vec3( 255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f ),
@@ -534,10 +634,26 @@ opengl_renderer::Render( world_environment *Environment ) {
::glPopAttrib();
// clouds
Environment->m_clouds.Render(
interpolate( Environment->m_skydome.GetAverageColor(), suncolor, duskfactor * 0.25f )
* ( 1.0f - Global::Overcast * 0.5f ) // overcast darkens the clouds
* 2.5f ); // arbitrary adjustment factor
if( Environment->m_clouds.mdCloud ) {
// setup
Disable_Lights();
::glEnable( GL_LIGHTING );
::glLightModelfv(
GL_LIGHT_MODEL_AMBIENT,
glm::value_ptr(
interpolate( Environment->m_skydome.GetAverageColor(), suncolor, duskfactor * 0.25f )
* ( 1.0f - Global::Overcast * 0.5f ) // overcast darkens the clouds
* 2.5f // arbitrary adjustment factor
) );
// render
Render( Environment->m_clouds.mdCloud, nullptr, 100.0 );
Render_Alpha( Environment->m_clouds.mdCloud, nullptr, 100.0 );
// post-render cleanup
GLfloat noambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, noambient );
::glEnable( GL_LIGHT0 ); // other lights will be enabled during lights update
::glDisable( GL_LIGHTING );
}
Global::DayLight.apply_angle();
Global::DayLight.apply_intensity();
@@ -588,7 +704,7 @@ opengl_renderer::Vertices( geometry_handle const &Geometry ) const {
// texture methods
texture_handle
opengl_renderer::GetTextureId( std::string Filename, std::string const &Dir, int const Filter, bool const Loadnow ) {
opengl_renderer::Fetch_Texture( std::string const &Filename, std::string const &Dir, int const Filter, bool const Loadnow ) {
return m_textures.create( Filename, Dir, Filter, Loadnow );
}
@@ -787,7 +903,7 @@ opengl_renderer::Render( TSubRect *Groundsubcell ) {
#ifdef EU07_SCENERY_EDITOR
// memcells
if( EditorModeFlag ) {
for( auto const memcell : m_memcells ) {
for( auto const memcell : Groundsubcell->m_memcells ) {
Render( memcell );
}
}
@@ -821,7 +937,7 @@ opengl_renderer::Render( TSubRect *Groundsubcell ) {
#ifdef EU07_SCENERY_EDITOR
// memcells
if( EditorModeFlag ) {
for( auto const memcell : m_memcells ) {
for( auto const memcell : Groundsubcell->m_memcells ) {
::glColor3fv( glm::value_ptr( pick_color( m_picksceneryitems.size() + 1 ) ) );
Render( memcell );
}
@@ -894,7 +1010,14 @@ opengl_renderer::Render( TGroundNode *Node ) {
break;
}
}
#ifdef EU07_USE_OLD_RENDERCODE
Node->Model->Render( Node->pCenter - m_renderpass.camera.position() );
#else
Node->Model->RaAnimate(); // jednorazowe przeliczenie animacji
Node->Model->RaPrepare();
if( Node->Model->pModel ) // renderowanie rekurencyjne submodeli
Render( Node->Model->pModel, Node->Model->Material(), Node->pCenter - m_renderpass.camera.position(), Node->Model->vAngle );
#endif
return true;
}
@@ -1258,6 +1381,9 @@ opengl_renderer::Render( TSubModel *Submodel ) {
// rysuj gdy element nieprzezroczysty
switch( m_renderpass.draw_mode ) {
case rendermode::color: {
// 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
#ifdef EU07_USE_OPTIMIZED_NORMALIZATION
switch( Submodel->m_normalizenormals ) {
case TSubModel::normalize: {
::glEnable( GL_NORMALIZE ); break; }
@@ -1266,6 +1392,11 @@ opengl_renderer::Render( TSubModel *Submodel ) {
default: {
break; }
}
#else
if( true == m_renderspecular ) {
::glEnable( GL_NORMALIZE );
}
#endif
// material configuration:
// textures...
if( Submodel->TextureID < 0 ) { // zmienialne skóry
@@ -1280,6 +1411,7 @@ opengl_renderer::Render( TSubModel *Submodel ) {
if( ( true == m_renderspecular ) && ( Global::DayLight.specular.a > 0.01f ) ) {
// specular strength in legacy models is set uniformly to 150, 150, 150 so we scale it down for opaque elements
::glMaterialfv( GL_FRONT, GL_SPECULAR, glm::value_ptr( Submodel->f4Specular * Global::DayLight.specular.a * m_specularopaquescalefactor ) );
::glEnable( GL_RESCALE_NORMAL );
}
// ...luminance
if( Global::fLuminance < Submodel->fLight ) {
@@ -1298,6 +1430,7 @@ opengl_renderer::Render( TSubModel *Submodel ) {
// restore default (lack of) brightness
::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( colors::none ) );
}
#ifdef EU07_USE_OPTIMIZED_NORMALIZATION
switch( Submodel->m_normalizenormals ) {
case TSubModel::normalize: {
::glDisable( GL_NORMALIZE ); break; }
@@ -1306,6 +1439,11 @@ opengl_renderer::Render( TSubModel *Submodel ) {
default: {
break; }
}
#else
if( true == m_renderspecular ) {
::glDisable( GL_NORMALIZE );
}
#endif
break;
}
case rendermode::shadows:
@@ -1355,32 +1493,42 @@ opengl_renderer::Render( TSubModel *Submodel ) {
// spotlights are only rendered in colour mode(s)
case rendermode::color: {
auto const &modelview = OpenGLMatrices.data( GL_MODELVIEW );
auto const lightcenter = modelview * glm::vec4( 0.0f, 0.0f, -0.05f, 1.0f ); // pozycja punktu świecącego względem kamery
Submodel->fCosViewAngle = glm::dot( glm::normalize( modelview * glm::vec4( 0.0f, 0.0f, -1.0f, 1.0f ) - lightcenter ), glm::normalize( -lightcenter ) );
auto const lightcenter =
modelview
* interpolate(
glm::vec4( 0.f, 0.f, -0.05f, 1.f ),
glm::vec4( 0.f, 0.f, -0.25f, 1.f ),
static_cast<float>( TSubModel::fSquareDist / Submodel->fSquareMaxDist ) ); // pozycja punktu świecącego względem kamery
Submodel->fCosViewAngle = glm::dot( glm::normalize( modelview * glm::vec4( 0.f, 0.f, -1.f, 1.f ) - lightcenter ), glm::normalize( -lightcenter ) );
if( Submodel->fCosViewAngle > Submodel->fCosFalloffAngle ) // kąt większy niż maksymalny stożek swiatła
{
float lightlevel = 1.0f; // TODO, TBD: parameter to control light strength
// view angle attenuation
if( Submodel->fCosViewAngle > Submodel->fCosFalloffAngle ) {
// kąt większy niż maksymalny stożek swiatła
float lightlevel = 1.f; // TODO, TBD: parameter to control light strength
// view angle attenuation
float const anglefactor = ( Submodel->fCosViewAngle - Submodel->fCosFalloffAngle ) / ( 1.0f - Submodel->fCosFalloffAngle );
// distance attenuation. NOTE: since it's fixed pipeline with built-in gamma correction we're using linear attenuation
// we're capping how much effect the distance attenuation can have, otherwise the lights get too tiny at regular distances
float const distancefactor = static_cast<float>( std::max( 0.5, ( Submodel->fSquareMaxDist - TSubModel::fSquareDist ) / ( Submodel->fSquareMaxDist * Global::fDistanceFactor ) ) );
if( lightlevel > 0.0f ) {
if( lightlevel > 0.f ) {
// material configuration:
::glPushAttrib( GL_ENABLE_BIT | GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_POINT_BIT );
Bind( 0 );
::glPointSize( std::max( 2.0f, 4.0f * distancefactor * anglefactor ) );
::glPointSize( std::max( 3.f, 5.f * distancefactor * anglefactor ) );
::glColor4f( Submodel->f4Diffuse[ 0 ], Submodel->f4Diffuse[ 1 ], Submodel->f4Diffuse[ 2 ], lightlevel * anglefactor );
::glDisable( GL_LIGHTING );
::glEnable( GL_BLEND );
::glPushMatrix();
::glLoadIdentity();
::glTranslatef( lightcenter.x, lightcenter.y, lightcenter.z ); // początek układu zostaje bez zmian
// main draw call
m_geometry.draw( Submodel->m_geometry );
// post-draw reset
::glPopMatrix();
::glPopAttrib();
}
}
@@ -1477,19 +1625,35 @@ opengl_renderer::Render( TTrack *Track ) {
void
opengl_renderer::Render( TMemCell *Memcell ) {
::glPushAttrib( GL_ENABLE_BIT );
// ::glDisable( GL_LIGHTING );
::glDisable( GL_TEXTURE_2D );
// ::glEnable( GL_BLEND );
::glPushMatrix();
auto const position = Memcell->Position();
auto const position = Memcell->Position() - m_renderpass.camera.position();
::glTranslated( position.x, position.y + 0.5, position.z );
::glColor3f( 0.36f, 0.75f, 0.35f );
::gluSphere( m_quadric, 0.35, 4, 2 );
switch( m_renderpass.draw_mode ) {
case rendermode::color: {
::glPushAttrib( GL_ENABLE_BIT );
::glDisable( GL_TEXTURE_2D );
::glColor3f( 0.36f, 0.75f, 0.35f );
::gluSphere( m_quadric, 0.35, 4, 2 );
::glPopAttrib();
break;
}
case rendermode::pickscenery:
case rendermode::shadows: {
::gluSphere( m_quadric, 0.35, 4, 2 );
break;
}
case rendermode::pickcontrols: {
break;
}
default: {
break;
}
}
::glPopMatrix();
::glPopAttrib();
}
bool
@@ -1533,8 +1697,11 @@ opengl_renderer::Render_Alpha( TSubRect *Groundsubcell ) {
Render_Alpha( node ); // przezroczyste z mieszanych modeli
for( node = Groundsubcell->nRenderAlpha; node; node = node->nNext3 )
Render_Alpha( node ); // przezroczyste modele
for( int j = 0; j < Groundsubcell->iTracks; ++j )
Groundsubcell->tTracks[ j ]->RenderDynAlpha(); // przezroczyste fragmenty pojazdów na torach
for( int trackidx = 0; trackidx < Groundsubcell->iTracks; ++trackidx ) {
for( auto dynamic : Groundsubcell->tTracks[ trackidx ]->Dynamics ) {
Render_Alpha( dynamic ); // przezroczyste fragmenty pojazdów na torach
}
}
return true;
}
@@ -1595,7 +1762,13 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
}
}
case TP_MODEL: {
#ifdef EU07_USE_OLD_RENDERCODE
Node->Model->RenderAlpha( Node->pCenter - m_renderpass.camera.position() );
#else
Node->Model->RaPrepare();
if( Node->Model->pModel ) // renderowanie rekurencyjne submodeli
Render_Alpha( Node->Model->pModel, Node->Model->Material(), Node->pCenter - m_renderpass.camera.position(), Node->Model->vAngle );
#endif
return true;
}
@@ -1800,6 +1973,9 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
// renderowanie obiektów OpenGL
if( Submodel->iAlpha & Submodel->iFlags & 0x2F ) // rysuj gdy element przezroczysty
{
// 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
#ifdef EU07_USE_OPTIMIZED_NORMALIZATION
switch( Submodel->m_normalizenormals ) {
case TSubModel::normalize: {
::glEnable( GL_NORMALIZE ); break; }
@@ -1808,6 +1984,11 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
default: {
break; }
}
#else
if( true == m_renderspecular ) {
::glEnable( GL_NORMALIZE );
}
#endif
// textures...
if( Submodel->TextureID < 0 ) { // zmienialne skóry
Bind( Submodel->ReplacableSkinId[ -Submodel->TextureID ] );
@@ -1838,6 +2019,7 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
// restore default (lack of) brightness
::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( colors::none ) );
}
#ifdef EU07_USE_OPTIMIZED_NORMALIZATION
switch( Submodel->m_normalizenormals ) {
case TSubModel::normalize: {
::glDisable( GL_NORMALIZE ); break; }
@@ -1846,6 +2028,11 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
default: {
break; }
}
#else
if( true == m_renderspecular ) {
::glDisable( GL_NORMALIZE );
}
#endif
}
}
else if( Submodel->eType == TP_FREESPOTLIGHT ) {
@@ -1854,8 +2041,13 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
// NOTE: we're forced here to redo view angle calculations etc, because this data isn't instanced but stored along with the single mesh
// TODO: separate instance data from reusable geometry
auto const &modelview = OpenGLMatrices.data( GL_MODELVIEW );
auto const lightcenter = modelview * glm::vec4( 0.0f, 0.0f, -0.05f, 1.0f ); // pozycja punktu świecącego względem kamery
Submodel->fCosViewAngle = glm::dot( glm::normalize( modelview * glm::vec4( 0.0f, 0.0f, -1.0f, 1.0f ) - lightcenter ), glm::normalize( -lightcenter ) );
auto const lightcenter =
modelview
* interpolate(
glm::vec4( 0.f, 0.f, -0.05f, 1.f ),
glm::vec4( 0.f, 0.f, -0.10f, 1.f ),
static_cast<float>( TSubModel::fSquareDist / Submodel->fSquareMaxDist ) ); // pozycja punktu świecącego względem kamery
Submodel->fCosViewAngle = glm::dot( glm::normalize( modelview * glm::vec4( 0.f, 0.f, -1.f, 1.f ) - lightcenter ), glm::normalize( -lightcenter ) );
float glarelevel = 0.6f; // luminosity at night is at level of ~0.1, so the overall resulting transparency is ~0.5 at full 'brightness'
if( Submodel->fCosViewAngle > Submodel->fCosFalloffAngle ) {
@@ -1954,12 +2146,14 @@ opengl_renderer::Update_Pick_Control() {
glm::dvec2 mousepos;
glfwGetCursorPos( m_window, &mousepos.x, &mousepos.y );
mousepos.y = Global::ScreenHeight - mousepos.y; // cursor coordinates are flipped compared to opengl
/*
#ifdef EU07_USE_PICKING_FRAMEBUFFER
glm::ivec2 pickbufferpos {
mousepos.x * 1024.0f / Global::ScreenWidth,
mousepos.y * 512.0f / Global::ScreenHeight };
*/
mousepos.x * m_pickbuffersize / Global::ScreenWidth,
mousepos.y * m_pickbuffersize / Global::ScreenHeight };
#else
glm::ivec2 pickbufferpos{ mousepos };
#endif
unsigned char pickreadout[4];
::glReadPixels( pickbufferpos.x, pickbufferpos.y, 1, 1, GL_BGRA, GL_UNSIGNED_BYTE, pickreadout );
@@ -1998,12 +2192,14 @@ opengl_renderer::Update_Pick_Node() {
glm::dvec2 mousepos;
glfwGetCursorPos( m_window, &mousepos.x, &mousepos.y );
mousepos.y = Global::ScreenHeight - mousepos.y; // cursor coordinates are flipped compared to opengl
/*
#ifdef EU07_USE_PICKING_FRAMEBUFFER
glm::ivec2 pickbufferpos {
mousepos.x * 1024.0f / Global::ScreenWidth,
mousepos.y * 512.0f / Global::ScreenHeight };
*/
mousepos.x * m_pickbuffersize / Global::ScreenWidth,
mousepos.y * m_pickbuffersize / Global::ScreenHeight };
#else
glm::ivec2 pickbufferpos{ mousepos };
#endif
unsigned char pickreadout[4];
::glReadPixels( pickbufferpos.x, pickbufferpos.y, 1, 1, GL_BGRA, GL_UNSIGNED_BYTE, pickreadout );
@@ -2037,15 +2233,11 @@ opengl_renderer::Update( double const Deltatime ) {
// adjust draw ranges etc, based on recent performance
auto const framerate = 1000.0f / (m_drawtime / 20.0f);
// NOTE: until we have quadtree in place we have to rely on the legacy rendering
// once this is resolved we should be able to simply adjust draw range
int targetsegments;
float targetfactor;
if( framerate > 90.0 ) { targetsegments = 400; targetfactor = 3.0f; }
else if( framerate > 60.0 ) { targetsegments = 225; targetfactor = 1.5f; }
else if( framerate > 30.0 ) { targetsegments = 90; targetfactor = Global::ScreenHeight / 768.0f; }
else { targetsegments = 9; targetfactor = Global::ScreenHeight / 768.0f * 0.75f; }
if( framerate > 90.0 ) { targetfactor = 3.0f; }
else if( framerate > 60.0 ) { targetfactor = 1.5f; }
else if( framerate > 30.0 ) { targetfactor = Global::ScreenHeight / 768.0f; }
else { targetfactor = Global::ScreenHeight / 768.0f * 0.75f; }
if( targetfactor > Global::fDistanceFactor ) {
@@ -2198,15 +2390,13 @@ opengl_renderer::Init_caps() {
WriteLog( "Supported extensions:" + std::string((char *)glGetString( GL_EXTENSIONS )) );
WriteLog( std::string("Render path: ") + ( Global::bUseVBO ? "VBO" : "Display lists" ) );
#ifdef EU07_USE_PICKING_FRAMEBUFFER
if( GLEW_EXT_framebuffer_object ) {
m_framebuffersupport = true;
WriteLog( "Framebuffer objects enabled" );
}
else {
WriteLog( "Framebuffer objects not supported, resorting to back buffer rendering" );
WriteLog( "Framebuffer objects not supported, resorting to back buffer rendering where possible" );
}
#endif
if( Global::iMultisampling )
WriteLog( "Using multisampling x" + std::to_string( 1 << Global::iMultisampling ) );
// ograniczenie maksymalnego rozmiaru tekstur - parametr dla skalowania tekstur

View File

@@ -119,21 +119,6 @@ public:
// main draw call. returns false on error
bool
Render();
// render sub-methods, temporarily exposed until we complete migrating render code to the renderer
bool
Render( TDynamicObject *Dynamic );
bool
Render( TModel3d *Model, material_data const *Material, Math3D::vector3 const &Position, Math3D::vector3 const &Angle );
bool
Render( TModel3d *Model, material_data const *Material, double const Squaredistance );
void
Render( TSubModel *Submodel );
bool
Render_Alpha( TDynamicObject *Dynamic );
bool
Render_Alpha( TModel3d *Model, material_data const *Material, Math3D::vector3 const &Position, Math3D::vector3 const &Angle );
bool
Render_Alpha( TModel3d *Model, material_data const *Material, double const Squaredistance );
// geometry methods
// NOTE: hands-on geometry management is exposed as a temporary measure; ultimately all visualization data should be generated/handled automatically by the renderer itself
// creates a new geometry bank. returns: handle to the bank or NULL
@@ -153,7 +138,7 @@ public:
Vertices( geometry_handle const &Geometry ) const;
// texture methods
texture_handle
GetTextureId( std::string Filename, std::string const &Dir, int const Filter = -1, bool const Loadnow = true );
Fetch_Texture( std::string const &Filename, std::string const &Dir = szTexturePath, int const Filter = -1, bool const Loadnow = true );
void
Bind( texture_handle const Texture );
opengl_texture const &
@@ -225,6 +210,14 @@ private:
Render( TSubRect *Groundsubcell );
bool
Render( TGroundNode *Node );
bool
Render( TDynamicObject *Dynamic );
bool
Render( TModel3d *Model, material_data const *Material, Math3D::vector3 const &Position, Math3D::vector3 const &Angle );
bool
Render( TModel3d *Model, material_data const *Material, double const Squaredistance );
void
Render( TSubModel *Submodel );
void
Render( TTrack *Track );
bool
@@ -237,6 +230,12 @@ private:
Render_Alpha( TSubRect *Groundsubcell );
bool
Render_Alpha( TGroundNode *Node );
bool
Render_Alpha( TDynamicObject *Dynamic );
bool
Render_Alpha( TModel3d *Model, material_data const *Material, Math3D::vector3 const &Position, Math3D::vector3 const &Angle );
bool
Render_Alpha( TModel3d *Model, material_data const *Material, double const Squaredistance );
void
Render_Alpha( TSubModel *Submodel );
void
@@ -254,7 +253,11 @@ private:
GLuint m_pickframebuffer { 0 }; // TODO: refactor pick framebuffer stuff into an object
GLuint m_picktexture { 0 };
GLuint m_pickdepthbuffer { 0 };
int m_pickbuffersize { 1024 }; // size of (square) textures bound with the pick framebuffer
#endif
GLuint m_shadowframebuffer { 0 };
GLuint m_shadowtexture { 0 };
int m_shadowbuffersize { 2048 };
GLUquadricObj *m_quadric { nullptr }; // helper object for drawing debug mode scene elements
geometry_handle m_billboardgeometry { 0, 0 };
@@ -273,6 +276,7 @@ private:
bool m_framebuffersupport { false };
rendermode m_texenvmode { rendermode::color }; // last configured texture environment
renderpass_config m_renderpass;
// std::stack<renderpass_config> m_renderpasses;
bool m_renderspecular { false }; // controls whether to include specular component in the calculations
std::vector<TGroundNode const *> m_picksceneryitems;
std::vector<TSubModel const *> m_pickcontrolsitems;

15
sky.cpp
View File

@@ -9,24 +9,22 @@ http://mozilla.org/MPL/2.0/.
#include "stdafx.h"
#include "sky.h"
#include "Logs.h"
#include "Globals.h"
#include "MdlMngr.h"
//---------------------------------------------------------------------------
GLfloat lightPos[4] = {0.0f, 0.0f, 0.0f, 1.0f};
//GLfloat lightPos[4] = {0.0f, 0.0f, 0.0f, 1.0f};
TSky::~TSky(){};
void TSky::Init() {
TSky::TSky(){};
if( ( Global::asSky != "1" )
&& ( Global::asSky != "0" ) ) {
void TSky::Init()
{
WriteLog( "Clouds init" );
if ((Global::asSky != "1") && (Global::asSky != "0"))
mdCloud = TModelsManager::GetModel( Global::asSky );
}
};
#ifdef EU07_USE_OLD_RENDERCODE
void TSky::Render( glm::vec3 const &Tint )
{
if (mdCloud)
@@ -45,5 +43,6 @@ void TSky::Render( glm::vec3 const &Tint )
::glDisable( GL_LIGHTING );
}
};
#endif
//---------------------------------------------------------------------------

16
sky.h
View File

@@ -12,16 +12,18 @@ http://mozilla.org/MPL/2.0/.
#include "Model3d.h"
class TSky
{
private:
TModel3d *mdCloud;
class TSky {
public:
TSky();
~TSky();
friend class opengl_renderer;
private:
TModel3d *mdCloud { nullptr };
public:
void Init();
#ifdef EU07_USE_OLD_RENDERCODE
void Render( glm::vec3 const &Tint = glm::vec3(1.0f, 1.0f, 1.0f) );
#endif
};
//---------------------------------------------------------------------------

View File

@@ -2,6 +2,7 @@
#include "stdafx.h"
#include "stars.h"
#include "globals.h"
#include "MdlMngr.h"
//////////////////////////////////////////////////////////////////////////////////////////
// cStars -- simple starfield model, simulating appearance of starry sky
@@ -9,9 +10,9 @@
void
cStars::init() {
m_stars.LoadFromFile( "models\\skydome_stars.t3d", false );
m_stars = TModelsManager::GetModel( "models\\skydome_stars.t3d", false );
}
#ifdef EU07_USE_OLD_RENDERCODE
void
cStars::render() {
// setup
@@ -27,4 +28,5 @@ cStars::render() {
::glPointSize( 3.0f );
::glPopMatrix();
}
}
#endif

View File

@@ -8,13 +8,16 @@
class cStars {
friend class opengl_renderer;
public:
// types:
// methods:
void init();
void render();
#ifdef EU07_USE_OLD_RENDERCODE
void render();
#endif
// constructors:
// deconstructor:
@@ -29,5 +32,5 @@ private:
// members:
float m_longitude{ 19.0f }; // geograpic coordinates hardcoded roughly to Poland location, for the time being
float m_latitude{ 52.0f };
TModel3d m_stars;
TModel3d *m_stars { nullptr };
};

View File

@@ -91,4 +91,4 @@
#include <glm/gtx/rotate_vector.hpp>
#include <glm/gtx/norm.hpp>
#include "openglmatrixstack.h"
#include "openglmatrixstack.h"

View File

@@ -96,7 +96,7 @@ void
ui_layer::set_background( std::string const &Filename ) {
if( false == Filename.empty() ) {
m_background = GfxRenderer.GetTextureId( Filename, szTexturePath );
m_background = GfxRenderer.Fetch_Texture( Filename );
}
else {
m_background = NULL;

View File

@@ -71,4 +71,13 @@ interpolate( Type_ const &First, Type_ const &Second, double const Factor ) {
return ( First * ( 1.0 - Factor ) ) + ( Second * Factor );
}
// tests whether provided points form a degenerate triangle
template <typename VecType_>
bool
degenerate( VecType_ const &Vertex1, VecType_ const &Vertex2, VecType_ const &Vertex3 ) {
// degenerate( A, B, C, minarea ) = ( ( B - A ).cross( C - A ) ).lengthSquared() < ( 4.0f * minarea * minarea );
return glm::length2( glm::cross( Vertex2 - Vertex1, Vertex3 - Vertex1 ) ) < std::numeric_limits<VecType_::value_type>::epsilon();
}
//---------------------------------------------------------------------------

View File

@@ -1,5 +1,5 @@
#pragma once
#define VERSION_MAJOR 17
#define VERSION_MINOR 715
#define VERSION_MINOR 721
#define VERSION_REVISION 0