16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-19 11:09:19 +02:00

render code relocation, mouse wheel zoom control

This commit is contained in:
tmj-fstate
2017-03-10 17:40:52 +01:00
parent b5ae395c42
commit 3708a01d26
20 changed files with 579 additions and 308 deletions

View File

@@ -170,16 +170,3 @@ void TCamera::Stop()
Velocity = vector3(0, 0, 0);
};
// returns true if specified object is within camera frustum, false otherwise
bool
TCamera::IsVisible( TDynamicObject const *Dynamic ) const {
// sphere test is faster than AABB, so we'll use it here
float3 diagonal(
Dynamic->MoverParameters->Dim.L,
Dynamic->MoverParameters->Dim.H,
Dynamic->MoverParameters->Dim.W );
float const radius = static_cast<float>(diagonal.Length()) * 0.5f;
return ( m_frustum.sphere_inside( Dynamic->GetPosition(), radius ) > 0.0f );
}

View File

@@ -11,7 +11,6 @@ http://mozilla.org/MPL/2.0/.
#define CameraH
#include "dumb3d.h"
#include "frustum.h"
#include "dynobj.h"
using namespace Math3D;
@@ -28,7 +27,6 @@ class TCamera
{
private:
vector3 pOffset; // nie używane (zerowe)
cFrustum m_frustum;
public: // McZapkie: potrzebuje do kiwania na boki
double Pitch;
@@ -56,11 +54,6 @@ class TCamera
void SetCabMatrix(vector3 &p);
void RaLook();
void Stop();
inline
void
SetFrustum() { m_frustum.calculate(); }
bool
IsVisible( TDynamicObject const *Dynamic ) const;
// bool GetMatrix(matrix4x4 &Matrix);
vector3 PtNext, PtPrev;
};

View File

@@ -523,7 +523,7 @@ void TDynamicObject::UpdateLeverEnum(TAnim *pAnim)
};
// ABu 29.01.05 przeklejone z render i renderalpha: *********************
void __inline TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
{ // ABu290105: pozbierane i uporzadkowane powtarzajace
// sie rzeczy z Render i RenderAlpha
// dodatkowy warunek, if (ObjSqrDist<...) zeby niepotrzebnie nie zmianiec w
@@ -3699,38 +3699,11 @@ void TDynamicObject::TurnOff()
btMechanik1.TurnOff();
btMechanik2.TurnOff();
};
/*
void TDynamicObject::Render()
{ // rysowanie elementów nieprzezroczystych
// youBy - sprawdzamy, czy jest sens renderowac
/*
double modelrotate;
vector3 tempangle;
// zmienne
renderme = false;
// przeklejka
double ObjSqrDist = SquareMagnitude(Global::pCameraPosition - vPosition) / Global::ZoomFactor;
// koniec przeklejki
if (ObjSqrDist < 500) // jak jest blisko - do 70m
modelrotate = 0.01; // mały kąt, żeby nie znikało
else
{ // Global::pCameraRotation to kąt bewzględny w świecie (zero - na północ)
tempangle = (vPosition - Global::pCameraPosition); // wektor od kamery
modelrotate = ABuAcos(tempangle); // określenie kąta
// if (modelrotate>M_PI) modelrotate-=(2*M_PI);
modelrotate += Global::pCameraRotation;
}
if (modelrotate > M_PI)
modelrotate -= (2 * M_PI);
if (modelrotate < -M_PI)
modelrotate += (2 * M_PI);
ModCamRot = modelrotate;
modelrotate = abs(modelrotate);
if (modelrotate < maxrot)
renderme = true;
*/
if (Global::pCamera->IsVisible(this))
{
TSubModel::iInstance = (size_t)this; //żeby nie robić cudzych animacji
@@ -3904,6 +3877,7 @@ void TDynamicObject::Render()
TurnOff(); // przywrócenie domyślnych pozycji submodeli
} // yB - koniec mieszania z grafika
};
*/
void TDynamicObject::RenderSounds()
{ // przeliczanie dźwięków, bo będzie
@@ -4273,7 +4247,7 @@ void TDynamicObject::RenderSounds()
}
*/
};
/*
void TDynamicObject::RenderAlpha()
{ // rysowanie elementów półprzezroczystych
if (renderme)
@@ -4352,6 +4326,7 @@ void TDynamicObject::RenderAlpha()
}
return;
} // koniec renderalpha
*/
// McZapkie-250202
// wczytywanie pliku z danymi multimedialnymi (dzwieki)

View File

@@ -141,6 +141,9 @@ class TAnim
//---------------------------------------------------------------------------
class TDynamicObject { // klasa pojazdu
friend class opengl_renderer;
private: // położenie pojazdu w świecie oraz parametry ruchu
vector3 vPosition; // Ra: pozycja pojazdu liczona zaraz po przesunięciu
vector3 vCoulpler[ 2 ]; // współrzędne sprzęgów do liczenia zderzeń czołowych
@@ -417,8 +420,10 @@ public: // modele składowe pojazdu
bool FastUpdate(double dt);
void Move(double fDistance);
void FastMove(double fDistance);
/*
void Render();
void RenderAlpha();
*/
void RenderSounds();
inline vector3 GetPosition() const
{

View File

@@ -28,6 +28,7 @@ Stele, firleju, szociu, hunter, ZiomalCl, OLI_EU and others
#include "World.h"
#include "Mover.h"
#include "usefull.h"
#include "timer.h"
#pragma comment( lib, "glfw3dll.lib" )
#pragma comment( lib, "glew32.lib" )
@@ -148,7 +149,15 @@ void key_callback( GLFWwindow *window, int key, int scancode, int action, int mo
break;
}
case GLFW_KEY_F7:
if( DebugModeFlag ) { // siatki wyświetlane tyko w trybie testowym
if( DebugModeFlag ) {
if( Global::ctrlState ) {
// ctrl + f7 toggles static daylight
World.ToggleDaylight();
break;
}
// f7: wireframe toggle
// siatki wyświetlane tyko w trybie testowym
Global::bWireFrame = !Global::bWireFrame;
if( true == Global::bWireFrame ) {
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
@@ -177,6 +186,14 @@ void focus_callback( GLFWwindow *window, int focus )
Global::iPause |= 4; // włączenie pauzy, gdy nieaktywy
}
void scroll_callback( GLFWwindow* window, double xoffset, double yoffset ) {
if( DebugModeFlag && Global::ctrlState ) {
// ctrl + scroll wheel adjusts fov in debug mode
Global::FieldOfView = clamp( static_cast<float>(Global::FieldOfView - yoffset * 20.0 / Global::fFpsAverage), 15.0f, 75.0f );
}
}
#ifdef _WINDOWS
extern "C"
{
@@ -283,6 +300,7 @@ int main(int argc, char *argv[])
glfwSetFramebufferSizeCallback(window, window_resize_callback);
glfwSetCursorPosCallback(window, cursor_pos_callback);
glfwSetKeyCallback(window, key_callback);
glfwSetScrollCallback( window, scroll_callback );
glfwSetWindowFocusCallback(window, focus_callback);
{
int width, height;
@@ -329,7 +347,9 @@ int main(int argc, char *argv[])
} // po zrobieniu E3D odpalamy normalnie scenerię, by ją zobaczyć
Console::On(); // włączenie konsoli
while (!glfwWindowShouldClose(window) && World.Update())
while (!glfwWindowShouldClose(window)
&& World.Update()
&& GfxRenderer.Render())
{
glfwSwapBuffers(window);
glfwPollEvents();

View File

@@ -23,7 +23,7 @@ class float3
y = b;
z = c;
};
double inline Length() const;
float inline Length() const;
};
inline bool operator==(const float3 &v1, const float3 &v2)
@@ -49,9 +49,9 @@ inline float3 operator+(const float3 &v1, const float3 &v2)
{
return float3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
};
double inline float3::Length() const
float inline float3::Length() const
{
return sqrt(x * x + y * y + z * z);
return std::sqrt(x * x + y * y + z * z);
};
inline float3 operator*( float3 const &v, float const k ) {
return float3( v.x * k, v.y * k, v.z * k );

View File

@@ -39,7 +39,6 @@ std::string Global::asCurrentDynamicPath = "";
int Global::iSlowMotion =
0; // info o malym FPS: 0-OK, 1-wyłączyć multisampling, 3-promień 1.5km, 7-1km
TDynamicObject *Global::changeDynObj = NULL; // info o zmianie pojazdu
bool Global::detonatoryOK; // info o nowych detonatorach
double Global::ABuDebug = 0;
std::string Global::asSky = "1";
double Global::fOpenGL = 0.0; // wersja OpenGL - do sprawdzania obecności rozszerzeń
@@ -80,7 +79,6 @@ cParser *Global::pParser = NULL;
int Global::iSegmentsRendered = 90; // ilość segmentów do regulacji wydajności
TCamera *Global::pCamera = NULL; // parametry kamery
TDynamicObject *Global::pUserDynamic = NULL; // pojazd użytkownika, renderowany bez trzęsienia
bool Global::bSmudge = false; // czy wyświetlać smugę, a pojazd użytkownika na końcu
/*
std::string Global::asTranscript[5]; // napisy na ekranie (widoczne)
*/
@@ -125,7 +123,7 @@ int Global::iFeedbackMode = 1; // tryb pracy informacji zwrotnej
int Global::iFeedbackPort = 0; // dodatkowy adres dla informacji zwrotnych
bool Global::bFreeFly = false;
bool Global::bFullScreen = false;
bool Global::VSync{ true };
bool Global::VSync{ false };
bool Global::bInactivePause = true; // automatyczna pauza, gdy okno nieaktywne
float Global::fMouseXScale = 1.5f;
float Global::fMouseYScale = 0.2f;
@@ -133,6 +131,7 @@ std::string Global::SceneryFile = "td.scn";
std::string Global::asHumanCtrlVehicle = "EU07-424";
int Global::iMultiplayer = 0; // blokada działania niektórych funkcji na rzecz komunikacji
double Global::fMoveLight = -1; // ruchome światło
bool Global::FakeLight{ false }; // toggle between fixed and dynamic daylight
double Global::fLatitudeDeg = 52.0; // szerokość geograficzna
float Global::fFriction = 1.0; // mnożnik tarcia - KURS90
double Global::fBrakeStep = 1.0; // krok zmiany hamulca dla klawiszy [Num3] i [Num9]
@@ -282,8 +281,7 @@ void Global::ConfigParse(cParser &Parser)
Parser.getTokens( 1, false );
Parser >> Global::FieldOfView;
// guard against incorrect values
Global::FieldOfView = std::min( 75.0f, Global::FieldOfView );
Global::FieldOfView = std::max( 15.0f, Global::FieldOfView );
Global::FieldOfView = clamp( Global::FieldOfView, 15.0f, 75.0f );
}
else if (token == "width")
{
@@ -583,8 +581,8 @@ void Global::ConfigParse(cParser &Parser)
Parser.getTokens( 1, false );
Parser >> Global::DynamicLightCount;
// clamp the light number
Global::DynamicLightCount = std::min( 7, Global::DynamicLightCount ); // max 8 lights per opengl specs, and one used for sun
Global::DynamicLightCount = std::max( 1, Global::DynamicLightCount ); // at least one light for controlled vehicle
// max 8 lights per opengl specs, minus one used for sun. at least one light for controlled vehicle
Global::DynamicLightCount = clamp( Global::DynamicLightCount, 1, 7 );
}
else if (token == "smoothtraction")
{

View File

@@ -244,7 +244,6 @@ class Global
static int iSlowMotion;
static TDynamicObject *changeDynObj;
static double ABuDebug;
static bool detonatoryOK;
static std::string asSky;
static bool bnewAirCouplers;
// Ra: nowe zmienne globalne
@@ -274,13 +273,13 @@ class Global
static int iCameraLast;
static std::string asRelease; // numer
static std::string asVersion; // z opisem
static int
iViewMode; // co aktualnie widać: 0-kabina, 1-latanie, 2-sprzęgi, 3-dokumenty, 4-obwody
static int iViewMode; // co aktualnie widać: 0-kabina, 1-latanie, 2-sprzęgi, 3-dokumenty, 4-obwody
static GLint iMaxTextureSize; // maksymalny rozmiar tekstury
static int iTextMode; // tryb pracy wyświetlacza tekstowego
static int iScreenMode[12]; // numer ekranu wyświetlacza tekstowego
static bool bDoubleAmbient; // podwójna jasność ambient
static double fMoveLight; // numer dnia w roku albo -1
static bool FakeLight; // toggle between fixed and dynamic daylight
static bool bSmoothTraction; // wygładzanie drutów
static double fSunDeclination; // deklinacja Słońca
static double fTimeSpeed; // przyspieszenie czasu, zmienna do testów
@@ -326,7 +325,6 @@ class Global
// informacje podczas kalibracji
static double fBrakeStep; // krok zmiany hamulca dla klawiszy [Num3] i [Num9]
static bool bJoinEvents; // czy grupować eventy o tych samych nazwach
static bool bSmudge; // czy wyświetlać smugę, a pojazd użytkownika na końcu
/*
static std::string asTranscript[5]; // napisy na ekranie (widoczne)
*/

View File

@@ -29,7 +29,7 @@ using namespace Mtable;
double TSubModel::fSquareDist = 0;
size_t TSubModel::iInstance; // numer renderowanego egzemplarza obiektu
texture_manager::size_type *TSubModel::ReplacableSkinId = NULL;
texture_manager::size_type const *TSubModel::ReplacableSkinId = NULL;
int TSubModel::iAlpha = 0x30300030; // maska do testowania flag tekstur wymiennych
TModel3d *TSubModel::pRoot; // Ra: tymczasowo wskaźnik na model widoczny z submodelu
std::string *TSubModel::pasText;
@@ -2196,7 +2196,7 @@ Root->Render(ReplacableSkinId,iAlpha);
glPopMatrix();
};
*/
/*
void TModel3d::Render(double fSquareDistance, texture_manager::size_type *ReplacableSkinId, int iAlpha)
{
iAlpha ^= 0x0F0F000F; // odwrócenie flag tekstur, aby wyłapać nieprzezroczyste
@@ -2217,7 +2217,7 @@ void TModel3d::RenderAlpha(double fSquareDistance, texture_manager::size_type *R
Root->RenderAlphaDL();
}
};
*/
/*
void TModel3d::RaRender(vector3 pPosition,double fAngle,GLuint
*ReplacableSkinId,int

View File

@@ -131,7 +131,10 @@ class TModel3d;
class TSubModel
{ // klasa submodelu - pojedyncza siatka, punkt świetlny albo grupa punktów
//m7todo: zrobić normalną serializację
//m7todo: zrobić normalną serializację
friend class opengl_renderer;
private:
int iNext;
int iChild;
@@ -222,7 +225,7 @@ private:
public:
static size_t iInstance; // identyfikator egzemplarza, który aktualnie renderuje model
static texture_manager::size_type *ReplacableSkinId;
static texture_manager::size_type const *ReplacableSkinId;
static int iAlpha; // maska bitowa dla danego przebiegu
static double fSquareDist;
static TModel3d *pRoot;
@@ -279,7 +282,7 @@ public:
void DisplayLists();
void BinInit(TSubModel *s, float4x4 *m, float8 *v,
std::vector<std::string> *t, std::vector<std::string> *n, bool dynamic);
void ReplacableSet(texture_manager::size_type *r, int a)
void ReplacableSet(texture_manager::size_type const *r, int a)
{
ReplacableSkinId = r;
iAlpha = a;
@@ -322,6 +325,8 @@ public:
class TModel3d : public CMesh
{
friend class opengl_renderer;
private:
// TMaterial *Materials;
// int MaterialsCount; //Ra: nie używane
@@ -355,32 +360,19 @@ public:
void SaveToBinFile(char const *FileName);
void BreakHierarhy();
// renderowanie specjalne
/*
void Render(double fSquareDistance, texture_manager::size_type *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
void RenderAlpha(double fSquareDistance, texture_manager::size_type *ReplacableSkinId = NULL,
int iAlpha = 0x30300030);
void RenderAlpha(double fSquareDistance, texture_manager::size_type *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
*/
void RaRender(double fSquareDistance, texture_manager::size_type *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
void RaRenderAlpha(double fSquareDistance, texture_manager::size_type *ReplacableSkinId = NULL,
int iAlpha = 0x30300030);
// jeden kąt obrotu
void Render(vector3 pPosition, double fAngle = 0, texture_manager::size_type *ReplacableSkinId = NULL,
int iAlpha = 0x30300030);
void RenderAlpha(vector3 pPosition, double fAngle = 0, texture_manager::size_type *ReplacableSkinId = NULL,
int iAlpha = 0x30300030);
void RaRender(vector3 pPosition, double fAngle = 0, texture_manager::size_type *ReplacableSkinId = NULL,
int iAlpha = 0x30300030);
void RaRenderAlpha(vector3 pPosition, double fAngle = 0, texture_manager::size_type *ReplacableSkinId = NULL,
int iAlpha = 0x30300030);
void RaRenderAlpha(double fSquareDistance, texture_manager::size_type *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
// trzy kąty obrotu
void Render(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type *ReplacableSkinId = NULL,
int iAlpha = 0x30300030);
void RenderAlpha(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type *ReplacableSkinId = NULL,
int iAlpha = 0x30300030);
void RaRender(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type *ReplacableSkinId = NULL,
int iAlpha = 0x30300030);
void RaRenderAlpha(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type *ReplacableSkinId = NULL,
int iAlpha = 0x30300030);
void Render(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
void RenderAlpha(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
void RaRender(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
void RaRenderAlpha(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
// inline int GetSubModelsCount() { return (SubModelsCount); };
int Flags()
int Flags() const
{
return iFlags;
};

View File

@@ -2645,7 +2645,7 @@ void TTrack::RenderDyn()
#else
for( auto dynamic : Dynamics ) {
// sam sprawdza, czy VBO; zmienia kontekst VBO!
dynamic->Render();
GfxRenderer.Render( dynamic );
}
#endif
};
@@ -2662,7 +2662,7 @@ void TTrack::RenderDynAlpha()
#else
for( auto dynamic : Dynamics ) {
// sam sprawdza, czy VBO; zmienia kontekst VBO!
dynamic->RenderAlpha();
GfxRenderer.Render_Alpha( dynamic );
}
#endif
};

View File

@@ -1792,21 +1792,18 @@ if
{ // tryb freefly
int CouplNr = -1; // normalnie żaden ze sprzęgów
TDynamicObject *tmp;
tmp = DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), 1, 1500,
CouplNr);
if (tmp == NULL)
tmp = DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), -1,
1500, CouplNr);
if (tmp && (CouplNr != -1))
tmp = DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), 1, 1500, CouplNr);
if (tmp == nullptr)
tmp = DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), -1, 1500, CouplNr);
if( ( CouplNr != -1 )
&& ( tmp != nullptr )
&& ( tmp->MoverParameters->Couplers[ CouplNr ].Connected != nullptr ) )
{
if (tmp->MoverParameters->Couplers[CouplNr].CouplingFlag ==
0) // najpierw hak
if (tmp->MoverParameters->Couplers[CouplNr].CouplingFlag == 0) // najpierw hak
{
if ((tmp->MoverParameters->Couplers[CouplNr]
.Connected->Couplers[CouplNr]
.AllowedFlag &
tmp->MoverParameters->Couplers[CouplNr].AllowedFlag &
ctrain_coupler) == ctrain_coupler)
if ((tmp->MoverParameters->Couplers[CouplNr].Connected->Couplers[CouplNr].AllowedFlag
& tmp->MoverParameters->Couplers[CouplNr].AllowedFlag
& ctrain_coupler) == ctrain_coupler)
if (tmp->MoverParameters->Attach(
CouplNr, 2,
tmp->MoverParameters->Couplers[CouplNr].Connected,
@@ -1815,46 +1812,37 @@ if
// tmp->MoverParameters->Couplers[CouplNr].Render=true;
// //podłączony sprzęg będzie widoczny
if (DynamicObject->Mechanik) // na wszelki wypadek
DynamicObject->Mechanik->CheckVehicles(
Connect); // aktualizacja flag kierunku w składzie
DynamicObject->Mechanik->CheckVehicles(Connect); // aktualizacja flag kierunku w składzie
dsbCouplerAttach->SetVolume(DSBVOLUME_MAX);
dsbCouplerAttach->Play(0, 0, 0);
}
else
WriteLog("Mechanical coupling failed.");
}
else if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag,
ctrain_pneumatic)) // pneumatyka
else if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag, ctrain_pneumatic)) // pneumatyka
{
if ((tmp->MoverParameters->Couplers[CouplNr]
.Connected->Couplers[CouplNr]
.AllowedFlag &
tmp->MoverParameters->Couplers[CouplNr].AllowedFlag &
ctrain_pneumatic) == ctrain_pneumatic)
if ((tmp->MoverParameters->Couplers[CouplNr].Connected->Couplers[CouplNr].AllowedFlag
& tmp->MoverParameters->Couplers[CouplNr].AllowedFlag
& ctrain_pneumatic) == ctrain_pneumatic)
if (tmp->MoverParameters->Attach(
CouplNr, 2,
tmp->MoverParameters->Couplers[CouplNr].Connected,
tmp->MoverParameters->Couplers[CouplNr].CouplingFlag +
ctrain_pneumatic))
tmp->MoverParameters->Couplers[CouplNr].CouplingFlag + ctrain_pneumatic))
{
rsHiss.Play(1, DSBPLAY_LOOPING, true, tmp->GetPosition());
DynamicObject->SetPneumatic(CouplNr != 0, true); // Ra: to mi się nie podoba !!!!
tmp->SetPneumatic(CouplNr != 0, true);
}
}
else if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag,
ctrain_scndpneumatic)) // zasilajacy
else if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag, ctrain_scndpneumatic)) // zasilajacy
{
if ((tmp->MoverParameters->Couplers[CouplNr]
.Connected->Couplers[CouplNr]
.AllowedFlag &
tmp->MoverParameters->Couplers[CouplNr].AllowedFlag &
ctrain_scndpneumatic) == ctrain_scndpneumatic)
if ((tmp->MoverParameters->Couplers[CouplNr].Connected->Couplers[CouplNr].AllowedFlag
& tmp->MoverParameters->Couplers[CouplNr].AllowedFlag
& ctrain_scndpneumatic) == ctrain_scndpneumatic)
if (tmp->MoverParameters->Attach(
CouplNr, 2,
tmp->MoverParameters->Couplers[CouplNr].Connected,
tmp->MoverParameters->Couplers[CouplNr].CouplingFlag +
ctrain_scndpneumatic))
tmp->MoverParameters->Couplers[CouplNr].CouplingFlag + ctrain_scndpneumatic))
{
// rsHiss.Play(1,DSBPLAY_LOOPING,true,tmp->GetPosition());
dsbCouplerDetach->SetVolume(DSBVOLUME_MAX);
@@ -1863,8 +1851,7 @@ if
tmp->SetPneumatic(CouplNr != 0, false);
}
}
else if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag,
ctrain_controll)) // ukrotnionko
else if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag, ctrain_controll)) // ukrotnionko
{
if ((tmp->MoverParameters->Couplers[CouplNr]
.Connected->Couplers[CouplNr]

319
World.cpp
View File

@@ -168,7 +168,6 @@ bool TWorld::Init( GLFWwindow *w ) {
window = w;
Global::window = w; // do WM_COPYDATA
Global::pCamera = &Camera; // Ra: wskaźnik potrzebny do likwidacji drgań
Global::detonatoryOK = true;
WriteLog("Starting MaSzyna rail vehicle simulator.");
WriteLog(Global::asVersion);
/*
@@ -1184,26 +1183,12 @@ bool TWorld::Update()
// variable step render time routines
Update_Camera( dt ); // TODO: move the fixed step cab camera updates to fixed step secondary routines section
// przy 0.25 smuga gaśnie o 6:37 w Quarku, a mogłaby już 5:40
// Ra 2014-12: przy 0.15 się skarżyli, że nie widać smug => zmieniłem na 0.25
// changed light activation threshold to 0.5, paired with strength reduction in daylight
if( Train ) {
// jeśli nie usunięty
Global::bSmudge =
( FreeFlyModeFlag ?
false :
( Train->Dynamic()->fShade <= 0.0 ?
( Global::fLuminance <= 0.5 ) :
( Train->Dynamic()->fShade * Global::fLuminance <= 0.5 ) ) );
}
GfxRenderer.Update( dt );
ResourceSweep();
m_init = true;
// visualize state changes
if (!Render())
return false;
return (true);
return true;
};
void
@@ -1430,36 +1415,9 @@ void TWorld::Update_Environment() {
#endif
}
bool TWorld::Render()
void TWorld::ResourceSweep()
{
glColor3ub(255, 255, 255);
// glColor3b(255, 0, 255);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDepthFunc( GL_LEQUAL );
glMatrixMode( GL_PROJECTION ); // select the Projection Matrix
glLoadIdentity(); // reset the Projection Matrix
// calculate the aspect ratio of the window
gluPerspective( Global::FieldOfView / Global::ZoomFactor, (GLdouble)Global::ScreenWidth / std::max((GLdouble)Global::ScreenHeight, 1.0), 0.1f * Global::ZoomFactor, 2500.0f * Global::ZoomFactor );
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity();
Camera.SetMatrix(); // ustawienie macierzy kamery względem początku scenerii
Camera.SetFrustum(); // update camera frustum to match current data
if( !Global::bWireFrame ) {
// bez nieba w trybie rysowania linii
Environment.render();
}
if( false == Ground.Render( Camera.Pos ) ) { return false; }
Render_Cab();
Render_UI();
ResourceManager::Sweep( Timer::GetSimulationTime() );
return true;
};
// rendering kabiny gdy jest oddzielnym modelem i ma byc wyswietlana
@@ -1716,8 +1674,8 @@ TWorld::Render_Cab() {
dynamic->mdKabina->RaRenderAlpha( 0.0, dynamic->ReplacableSkinID, dynamic->iAlpha );
}
else { // renderowanie z Display List
dynamic->mdKabina->Render( 0.0, dynamic->ReplacableSkinID, dynamic->iAlpha );
dynamic->mdKabina->RenderAlpha( 0.0, dynamic->ReplacableSkinID, dynamic->iAlpha );
GfxRenderer.Render( dynamic->mdKabina, dynamic, 0.0 );
GfxRenderer.Render_Alpha( dynamic->mdKabina, dynamic, 0.0 );
}
#ifdef EU07_USE_OLD_LIGHTING_MODEL
// TODO: re-implement this
@@ -1765,13 +1723,14 @@ TWorld::Render_UI() {
if( Global::iTextMode == GLFW_KEY_F8 ) {
Global::iViewMode = GLFW_KEY_F8;
OutText1 = "FPS: ";
OutText1 += to_string( Timer::GetFPS(), 2 );
OutText1 = "FPS: " + to_string( Timer::GetFPS(), 2 );
//OutText1 += sprintf();
if( Global::iSlowMotion )
OutText1 += " (slowmotion " + to_string( Global::iSlowMotion ) + ")";
OutText1 += ", sectors: ";
OutText1 += to_string( Ground.iRendered );
OutText1 += ", sectors: " + to_string( Ground.iRendered );
if( DebugModeFlag ) {
OutText1 += " FoV: " + to_string( Global::FieldOfView / Global::ZoomFactor, 1 );
}
}
// if (Console::Pressed(VK_F7))
@@ -2203,6 +2162,7 @@ TWorld::Render_UI() {
.substr( 0 + 2 * floor( fmod( 8 + ( Camera.Yaw + 0.5 * M_PI_4 ) / M_PI_4, 8 ) ), 2 );
// current luminance level
OutText2 = "Light level: " + to_string( Global::fLuminance, 3 );
if( Global::FakeLight ) { OutText2 += "(*)"; }
}
// OutText3= AnsiString(" Online documentation (PL, ENG, DE, soon CZ):
// http://www.eu07.pl");
@@ -2463,136 +2423,134 @@ TWorld::Render_UI() {
// ABu 150205: prosty help, zeby sie na forum nikt nie pytal, jak ma ruszyc :)
if( Global::detonatoryOK ) {
// if (Console::Pressed(VK_F9)) ShowHints(); //to nie działa prawidłowo - prosili wyłączyć
if( Global::iTextMode == GLFW_KEY_F9 ) { // informacja o wersji, sposobie wyświetlania i błędach OpenGL
// Global::iViewMode=VK_F9;
OutText1 = Global::asVersion; // informacja o wersji
OutText2 = std::string( "Rendering mode: " ) + ( Global::bUseVBO ? "VBO" : "Display Lists" );
if( Global::iMultiplayer )
OutText2 += ". Multiplayer is active";
OutText2 += ".";
GLenum err = glGetError();
if( err != GL_NO_ERROR ) {
OutText3 = "OpenGL error " + to_string( err ) + ": " +
Global::Bezogonkow( ( (char *)gluErrorString( err ) ) );
}
// if (Console::Pressed(VK_F9)) ShowHints(); //to nie działa prawidłowo - prosili wyłączyć
if( Global::iTextMode == GLFW_KEY_F9 ) { // informacja o wersji, sposobie wyświetlania i błędach OpenGL
// Global::iViewMode=VK_F9;
OutText1 = Global::asVersion; // informacja o wersji
OutText2 = std::string( "Rendering mode: " ) + ( Global::bUseVBO ? "VBO" : "Display Lists" );
if( Global::iMultiplayer )
OutText2 += ". Multiplayer is active";
OutText2 += ".";
GLenum err = glGetError();
if( err != GL_NO_ERROR ) {
OutText3 = "OpenGL error " + to_string( err ) + ": " +
Global::Bezogonkow( ( (char *)gluErrorString( err ) ) );
}
if( Global::iTextMode == GLFW_KEY_F3 ) { // wyświetlenie rozkładu jazdy, na razie jakkolwiek
TDynamicObject *tmp = FreeFlyModeFlag ?
Ground.DynamicNearest( Camera.Pos ) :
Controlled; // w trybie latania lokalizujemy wg mapy
Mtable::TTrainParameters *tt = NULL;
if( tmp )
if( tmp->Mechanik ) {
tt = tmp->Mechanik->Timetable();
if( tt ) // musi być rozkład
{ // wyświetlanie rozkładu
glColor3f( 1.0f, 1.0f, 1.0f ); // a, damy białym
// glTranslatef(0.0f,0.0f,-0.50f);
glRasterPos2f( -0.25f, 0.20f );
OutText1 = tmp->Mechanik->Relation() + " (" +
tmp->Mechanik->Timetable()->TrainName + ")";
glPrint( Global::Bezogonkow( OutText1, true ).c_str() );
glRasterPos2f( -0.25f, 0.19f );
// glPrint("|============================|=======|=======|=====|");
// glPrint("| Posterunek | Przyj.| Odjazd| Vmax|");
// glPrint("|============================|=======|=======|=====|");
glPrint( "|----------------------------|-------|-------|-----|" );
TMTableLine *t;
for( int i = tmp->Mechanik->iStationStart; i <= tt->StationCount; ++i ) { // wyświetlenie pozycji z rozkładu
t = tt->TimeTable + i; // linijka rozkładu
OutText1 = ( t->StationName +
" " ).substr( 0, 26 );
OutText2 = ( t->Ah >= 0 ) ?
to_string( int( 100 + t->Ah ) ).substr( 1, 2 ) + ":" +
to_string( int( 100 + t->Am ) ).substr( 1, 2 ) :
std::string( " " );
OutText3 = ( t->Dh >= 0 ) ?
to_string( int( 100 + t->Dh ) ).substr( 1, 2 ) + ":" +
to_string( int( 100 + t->Dm ) ).substr( 1, 2 ) :
std::string( " " );
OutText4 = " " + to_string( t->vmax, 0 );
OutText4 = OutText4.substr( OutText4.length() - 3,
3 ); // z wyrównaniem do prawej
// if (AnsiString(t->StationWare).Pos("@"))
OutText1 = "| " + OutText1 + " | " + OutText2 + " | " + OutText3 +
" | " + OutText4 + " | " + t->StationWare;
glRasterPos2f( -0.25f,
0.18f - 0.02f * ( i - tmp->Mechanik->iStationStart ) );
if( ( tmp->Mechanik->iStationStart < tt->StationIndex ) ?
( i < tt->StationIndex ) :
false ) { // czas minął i odjazd był, to nazwa stacji będzie na zielono
glColor3f( 0.0f, 1.0f, 0.0f ); // zielone
glRasterPos2f(
-0.25f,
0.18f - 0.02f * ( i - tmp->Mechanik->iStationStart ) ); // dopiero
// ustawienie
// pozycji
// ustala
// kolor,
// dziwne...
glPrint( Global::Bezogonkow( OutText1, true ).c_str() );
glColor3f( 1.0f, 1.0f, 1.0f ); // a reszta białym
}
else // normalne wyświetlanie, bez zmiany kolorów
glPrint( Global::Bezogonkow( OutText1, true ).c_str() );
glRasterPos2f( -0.25f,
0.17f - 0.02f * ( i - tmp->Mechanik->iStationStart ) );
glPrint( "|----------------------------|-------|-------|-----|" );
}
if( Global::iTextMode == GLFW_KEY_F3 ) { // wyświetlenie rozkładu jazdy, na razie jakkolwiek
TDynamicObject *tmp = FreeFlyModeFlag ?
Ground.DynamicNearest( Camera.Pos ) :
Controlled; // w trybie latania lokalizujemy wg mapy
Mtable::TTrainParameters *tt = NULL;
if( tmp )
if( tmp->Mechanik ) {
tt = tmp->Mechanik->Timetable();
if( tt ) // musi być rozkład
{ // wyświetlanie rozkładu
glColor3f( 1.0f, 1.0f, 1.0f ); // a, damy białym
// glTranslatef(0.0f,0.0f,-0.50f);
glRasterPos2f( -0.25f, 0.20f );
OutText1 = tmp->Mechanik->Relation() + " (" +
tmp->Mechanik->Timetable()->TrainName + ")";
glPrint( Global::Bezogonkow( OutText1, true ).c_str() );
glRasterPos2f( -0.25f, 0.19f );
// glPrint("|============================|=======|=======|=====|");
// glPrint("| Posterunek | Przyj.| Odjazd| Vmax|");
// glPrint("|============================|=======|=======|=====|");
glPrint( "|----------------------------|-------|-------|-----|" );
TMTableLine *t;
for( int i = tmp->Mechanik->iStationStart; i <= tt->StationCount; ++i ) { // wyświetlenie pozycji z rozkładu
t = tt->TimeTable + i; // linijka rozkładu
OutText1 = ( t->StationName +
" " ).substr( 0, 26 );
OutText2 = ( t->Ah >= 0 ) ?
to_string( int( 100 + t->Ah ) ).substr( 1, 2 ) + ":" +
to_string( int( 100 + t->Am ) ).substr( 1, 2 ) :
std::string( " " );
OutText3 = ( t->Dh >= 0 ) ?
to_string( int( 100 + t->Dh ) ).substr( 1, 2 ) + ":" +
to_string( int( 100 + t->Dm ) ).substr( 1, 2 ) :
std::string( " " );
OutText4 = " " + to_string( t->vmax, 0 );
OutText4 = OutText4.substr( OutText4.length() - 3,
3 ); // z wyrównaniem do prawej
// if (AnsiString(t->StationWare).Pos("@"))
OutText1 = "| " + OutText1 + " | " + OutText2 + " | " + OutText3 +
" | " + OutText4 + " | " + t->StationWare;
glRasterPos2f( -0.25f,
0.18f - 0.02f * ( i - tmp->Mechanik->iStationStart ) );
if( ( tmp->Mechanik->iStationStart < tt->StationIndex ) ?
( i < tt->StationIndex ) :
false ) { // czas minął i odjazd był, to nazwa stacji będzie na zielono
glColor3f( 0.0f, 1.0f, 0.0f ); // zielone
glRasterPos2f(
-0.25f,
0.18f - 0.02f * ( i - tmp->Mechanik->iStationStart ) ); // dopiero
// ustawienie
// pozycji
// ustala
// kolor,
// dziwne...
glPrint( Global::Bezogonkow( OutText1, true ).c_str() );
glColor3f( 1.0f, 1.0f, 1.0f ); // a reszta białym
}
else // normalne wyświetlanie, bez zmiany kolorów
glPrint( Global::Bezogonkow( OutText1, true ).c_str() );
glRasterPos2f( -0.25f,
0.17f - 0.02f * ( i - tmp->Mechanik->iStationStart ) );
glPrint( "|----------------------------|-------|-------|-----|" );
}
}
OutText1 = OutText2 = OutText3 = OutText4 = "";
}
else if( OutText1 != "" ) { // ABu: i od razu czyszczenie tego, co bylo napisane
// glTranslatef(0.0f,0.0f,-0.50f);
glRasterPos2f( -0.25f, 0.20f );
glPrint( OutText1.c_str() );
OutText1 = "";
if( OutText2 != "" ) {
glRasterPos2f( -0.25f, 0.19f );
glPrint( OutText2.c_str() );
OutText2 = "";
}
if( OutText3 != "" ) {
glRasterPos2f( -0.25f, 0.18f );
glPrint( OutText3.c_str() );
OutText3 = "";
if( OutText4 != "" ) {
glRasterPos2f( -0.25f, 0.17f );
glPrint( OutText4.c_str() );
OutText4 = "";
}
OutText1 = OutText2 = OutText3 = OutText4 = "";
}
else if( OutText1 != "" ) { // ABu: i od razu czyszczenie tego, co bylo napisane
// glTranslatef(0.0f,0.0f,-0.50f);
glRasterPos2f( -0.25f, 0.20f );
glPrint( OutText1.c_str() );
OutText1 = "";
if( OutText2 != "" ) {
glRasterPos2f( -0.25f, 0.19f );
glPrint( OutText2.c_str() );
OutText2 = "";
}
if( OutText3 != "" ) {
glRasterPos2f( -0.25f, 0.18f );
glPrint( OutText3.c_str() );
OutText3 = "";
if( OutText4 != "" ) {
glRasterPos2f( -0.25f, 0.17f );
glPrint( OutText4.c_str() );
OutText4 = "";
}
}
// if ((Global::iTextMode!=VK_F3))
{ // stenogramy dźwięków (ukryć, gdy tabelka skanowania lub rozkład?)
}
// if ((Global::iTextMode!=VK_F3))
{ // stenogramy dźwięków (ukryć, gdy tabelka skanowania lub rozkład?)
/*
glColor3f( 1.0f, 1.0f, 0.0f ); //żółte
for( int i = 0; i < 5; ++i ) { // kilka linijek
if( Global::asTranscript[ i ].empty() )
break; // dalej nie trzeba
else {
glRasterPos2f( -0.20f, -0.05f - 0.01f * i );
glPrint( Global::Bezogonkow( Global::asTranscript[ i ] ).c_str() );
}
glColor3f( 1.0f, 1.0f, 0.0f ); //żółte
for( int i = 0; i < 5; ++i ) { // kilka linijek
if( Global::asTranscript[ i ].empty() )
break; // dalej nie trzeba
else {
glRasterPos2f( -0.20f, -0.05f - 0.01f * i );
glPrint( Global::Bezogonkow( Global::asTranscript[ i ] ).c_str() );
}
}
*/
int i = 0;
for( auto const &transcript : Global::tranTexts.aLines ) {
int i = 0;
for( auto const &transcript : Global::tranTexts.aLines ) {
if( Global::fTimeAngleDeg >= transcript.fShow ) {
if( Global::fTimeAngleDeg >= transcript.fShow ) {
cParser parser( transcript.asText );
while( true == parser.getTokens(1, false, "|") ) {
cParser parser( transcript.asText );
while( true == parser.getTokens(1, false, "|") ) {
std::string transcriptline; parser >> transcriptline;
::glColor3f( 1.0f, 1.0f, 0.0f ); //żółte
::glRasterPos2f( -0.20f, -0.05f - 0.01f * i );
glPrint( transcriptline.c_str() );
++i;
}
std::string transcriptline; parser >> transcriptline;
::glColor3f( 1.0f, 1.0f, 0.0f ); //żółte
::glRasterPos2f( -0.20f, -0.05f - 0.01f * i );
glPrint( transcriptline.c_str() );
++i;
}
}
}
@@ -2899,6 +2857,21 @@ void TWorld::CabChange(TDynamicObject *old, TDynamicObject *now)
};
//---------------------------------------------------------------------------
void
TWorld::ToggleDaylight() {
Global::FakeLight = !Global::FakeLight;
if( Global::FakeLight ) {
// for fake daylight enter fixed hour
Environment.time( 10, 30, 0 );
}
else {
// local clock based calculation
Environment.time();
}
}
void
world_environment::init() {
@@ -2976,3 +2949,9 @@ world_environment::render() {
::glEnable( GL_FOG );
::glEnable( GL_LIGHTING );
}
void
world_environment::time( int const Hour, int const Minute, int const Second ) {
m_sun.setTime( Hour, Minute, Second );
}

10
World.h
View File

@@ -18,7 +18,7 @@ http://mozilla.org/MPL/2.0/.
#include "stars.h"
#include "skydome.h"
#include "mczapkie/mover.h"
#include "glfw/glfw3.h"
#include "renderer.h"
// wrapper for environment elements -- sky, sun, stars, clouds etc
class world_environment {
@@ -27,6 +27,7 @@ public:
void init();
void update();
void render();
void time( int const Hour = -1, int const Minute = -1, int const Second = -1 );
private:
CSkyDome m_skydome;
@@ -37,6 +38,9 @@ private:
class TWorld
{
// NOTE: direct access is a shortcut, but world etc needs some restructuring regardless
friend opengl_renderer;
void InOutKey( bool const Near = true );
void FollowView(bool wycisz = true);
void DistantView( bool const Near = false );
@@ -53,6 +57,8 @@ class TWorld
void OnCommandGet(DaneRozkaz *pRozkaz);
bool Update();
void TrainDelete(TDynamicObject *d = NULL);
// switches between static and dynamic daylight calculation
void ToggleDaylight();
TWorld();
~TWorld();
// double Aspect;
@@ -63,7 +69,7 @@ class TWorld
std::string OutText4;
void Update_Environment();
void Update_Camera( const double Deltatime );
bool Render();
void ResourceSweep();
void Render_Cab();
void Render_UI();
TCamera Camera;

View File

@@ -1,4 +1,4 @@
/*
/*
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
@@ -10,8 +10,25 @@ http://mozilla.org/MPL/2.0/.
#include "stdafx.h"
#include "renderer.h"
#include "globals.h"
#include "world.h"
#include "dynobj.h"
// returns true if specified object is within camera frustum, false otherwise
bool
opengl_camera::visible( TDynamicObject const *Dynamic ) const {
// sphere test is faster than AABB, so we'll use it here
float3 diagonal(
Dynamic->MoverParameters->Dim.L,
Dynamic->MoverParameters->Dim.H,
Dynamic->MoverParameters->Dim.W );
float const radius = diagonal.Length() * 0.5f;
return ( m_frustum.sphere_inside( Dynamic->GetPosition(), radius ) > 0.0f );
}
opengl_renderer GfxRenderer;
extern TWorld World;
void
opengl_renderer::Init() {
@@ -32,6 +49,265 @@ opengl_renderer::Init() {
}
}
bool
opengl_renderer::Render() {
::glColor3ub( 255, 255, 255 );
::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
::glDepthFunc( GL_LEQUAL );
::glMatrixMode( GL_PROJECTION ); // select the Projection Matrix
::glLoadIdentity(); // reset the Projection Matrix
// calculate the aspect ratio of the window
::gluPerspective(
Global::FieldOfView / Global::ZoomFactor,
(GLdouble)Global::ScreenWidth / std::max( (GLdouble)Global::ScreenHeight, 1.0 ),
0.1f * Global::ZoomFactor,
m_drawrange );
::glMatrixMode( GL_MODELVIEW ); // Select The Modelview Matrix
::glLoadIdentity();
World.Camera.SetMatrix(); // ustawienie macierzy kamery względem początku scenerii
m_camera.update_frustum();
if( !Global::bWireFrame ) {
// bez nieba w trybie rysowania linii
World.Environment.render();
}
if( false == World.Ground.Render( World.Camera.Pos ) ) { return false; }
World.Render_Cab();
World.Render_UI();
return true; // for now always succeed
}
bool
opengl_renderer::Render( TDynamicObject *Dynamic ) {
if( false == m_camera.visible( Dynamic ) ) {
Dynamic->renderme = false;
return false;
}
Dynamic->renderme = true;
TSubModel::iInstance = ( size_t )this; //żeby nie robić cudzych animacji
double squaredistance = SquareMagnitude( Global::pCameraPosition - Dynamic->vPosition ) / Global::ZoomFactor;
Dynamic->ABuLittleUpdate( squaredistance ); // ustawianie zmiennych submodeli dla wspólnego modelu
::glPushMatrix();
if( Dynamic == Global::pUserDynamic ) {
//specjalne ustawienie, aby nie trzęsło
//tu trzeba by ustawić animacje na modelu zewnętrznym
::glLoadIdentity(); // zacząć od macierzy jedynkowej
Global::pCamera->SetCabMatrix( Dynamic->vPosition ); // specjalne ustawienie kamery
}
else
::glTranslated( Dynamic->vPosition.x, Dynamic->vPosition.y, Dynamic->vPosition.z ); // standardowe przesunięcie względem początku scenerii
::glMultMatrixd( Dynamic->mMatrix.getArray() );
// wersja Display Lists
// NOTE: VBO path is removed
// TODO: implement universal render path down the road
if( Dynamic->mdLowPolyInt ) {
// low poly interior
if( FreeFlyModeFlag ? true : !Dynamic->mdKabina || !Dynamic->bDisplayCab ) {
// enable cab light if needed
if( Dynamic->InteriorLightLevel > 0.0f ) {
// crude way to light the cabin, until we have something more complete in place
auto const cablight = Dynamic->InteriorLight * Dynamic->InteriorLightLevel;
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &cablight.x );
}
Render( Dynamic->mdLowPolyInt, Dynamic, squaredistance );
if( Dynamic->InteriorLightLevel > 0.0f ) {
// reset the overall ambient
GLfloat ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient );
}
}
}
// Dynamic->mdModel->Render( squaredistance, Dynamic->ReplacableSkinID, Dynamic->iAlpha );
Render( Dynamic->mdModel, Dynamic, squaredistance );
if( Dynamic->mdLoad ) // renderowanie nieprzezroczystego ładunku
Render( Dynamic->mdLoad, Dynamic, squaredistance );
if( Dynamic->mdPrzedsionek )
Render( Dynamic->mdPrzedsionek, Dynamic, squaredistance );
::glPopMatrix();
// TODO: check if this reset is needed. In theory each object should render all buttons based on its own instance data anyway?
if( Dynamic->btnOn )
Dynamic->TurnOff(); // przywrócenie domyślnych pozycji submodeli
return true;
}
bool
opengl_renderer::Render( TModel3d *Model, TDynamicObject const *Instance, double const Squaredistance ) {
auto alpha =
( Instance != nullptr ?
Instance->iAlpha :
0x30300030 );
alpha ^= 0x0F0F000F; // odwrócenie flag tekstur, aby wyłapać nieprzezroczyste
if( 0 == ( alpha & Model->iFlags & 0x1F1F001F ) ) {
// czy w ogóle jest co robić w tym cyklu?
return false;
}
Model->Root->fSquareDist = Squaredistance; // zmienna globalna!
Model->Root->ReplacableSet(
( Instance != nullptr ?
Instance->ReplacableSkinID :
nullptr ),
alpha );
Model->Root->RenderDL();
return true;
}
bool
opengl_renderer::Render( TModel3d *Model, TDynamicObject const *Instance, Math3D::vector3 const &Position, Math3D::vector3 const &Angle ) {
::glPushMatrix();
::glTranslated( Position.x, Position.y, Position.z );
if( Angle.y != 0.0 )
::glRotated( Angle.y, 0.0, 1.0, 0.0 );
if( Angle.x != 0.0 )
::glRotated( Angle.x, 1.0, 0.0, 0.0 );
if( Angle.z != 0.0 )
::glRotated( Angle.z, 0.0, 0.0, 1.0 );
auto const result = Render( Model, Instance, SquareMagnitude( Position - Global::GetCameraPosition() ) );
::glPopMatrix();
return result;
}
bool
opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
if( false == Dynamic->renderme ) {
return false;
}
TSubModel::iInstance = ( size_t )this; //żeby nie robić cudzych animacji
double squaredistance = SquareMagnitude( Global::pCameraPosition - Dynamic->vPosition );
Dynamic->ABuLittleUpdate( squaredistance ); // ustawianie zmiennych submodeli dla wspólnego modelu
::glPushMatrix();
if( Dynamic == Global::pUserDynamic ) { // specjalne ustawienie, aby nie trzęsło
::glLoadIdentity(); // zacząć od macierzy jedynkowej
Global::pCamera->SetCabMatrix( Dynamic->vPosition ); // specjalne ustawienie kamery
}
else
::glTranslated( Dynamic->vPosition.x, Dynamic->vPosition.y, Dynamic->vPosition.z ); // standardowe przesunięcie względem początku scenerii
::glMultMatrixd( Dynamic->mMatrix.getArray() );
// wersja Display Lists
// NOTE: VBO path is removed
// TODO: implement universal render path down the road
if( Dynamic->mdLowPolyInt ) {
// low poly interior
if( FreeFlyModeFlag ? true : !Dynamic->mdKabina || !Dynamic->bDisplayCab ) {
// enable cab light if needed
if( Dynamic->InteriorLightLevel > 0.0f ) {
// crude way to light the cabin, until we have something more complete in place
auto const cablight = Dynamic->InteriorLight * Dynamic->InteriorLightLevel;
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &cablight.x );
}
Render_Alpha( Dynamic->mdLowPolyInt, Dynamic, squaredistance );
if( Dynamic->InteriorLightLevel > 0.0f ) {
// reset the overall ambient
GLfloat ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient );
}
}
}
Render_Alpha( Dynamic->mdModel, Dynamic, squaredistance );
if( Dynamic->mdLoad ) // renderowanie nieprzezroczystego ładunku
Render_Alpha( Dynamic->mdLoad, Dynamic, squaredistance );
if( Dynamic->mdPrzedsionek )
Render_Alpha( Dynamic->mdPrzedsionek, Dynamic, squaredistance );
::glPopMatrix();
if( Dynamic->btnOn )
Dynamic->TurnOff(); // przywrócenie domyślnych pozycji submodeli
return true;
}
bool
opengl_renderer::Render_Alpha( TModel3d *Model, TDynamicObject const *Instance, double const Squaredistance ) {
auto alpha =
( Instance != nullptr ?
Instance->iAlpha :
0x30300030 );
if( 0 == ( alpha & Model->iFlags & 0x2F2F002F ) ) {
// nothing to render
return false;
}
Model->Root->fSquareDist = Squaredistance; // zmienna globalna!
Model->Root->ReplacableSet(
( Instance != nullptr ?
Instance->ReplacableSkinID :
nullptr ),
alpha );
Model->Root->RenderAlphaDL();
return true;
}
bool
opengl_renderer::Render_Alpha( TModel3d *Model, TDynamicObject const *Instance, Math3D::vector3 const &Position, Math3D::vector3 const &Angle ) {
::glPushMatrix();
::glTranslated( Position.x, Position.y, Position.z );
if( Angle.y != 0.0 )
::glRotated( Angle.y, 0.0, 1.0, 0.0 );
if( Angle.x != 0.0 )
::glRotated( Angle.x, 1.0, 0.0, 0.0 );
if( Angle.z != 0.0 )
::glRotated( Angle.z, 0.0, 0.0, 1.0 );
auto const result = Render_Alpha( Model, Instance, SquareMagnitude( Position - Global::GetCameraPosition() ) );
::glPopMatrix();
return result;
}
void
opengl_renderer::Update ( double const Deltatile ) {
// TODO: add garbage collection and other works here
};
void
opengl_renderer::Update_Lights( light_array const &Lights ) {

View File

@@ -13,6 +13,7 @@ http://mozilla.org/MPL/2.0/.
#include "texture.h"
#include "lightarray.h"
#include "dumb3d.h"
#include "frustum.h"
struct opengl_light {
@@ -69,6 +70,22 @@ struct opengl_material {
};
// simple camera object. paired with 'virtual camera' in the scene
class opengl_camera {
public:
// methods:
inline
void
update_frustum() { m_frustum.calculate(); }
bool
visible( TDynamicObject const *Dynamic ) const;
private:
// members:
cFrustum m_frustum;
};
// bare-bones render controller, in lack of anything better yet
class opengl_renderer {
@@ -78,6 +95,24 @@ public:
// methods
void
Init();
// main draw call. returns false on error
bool
Render();
bool
Render( TDynamicObject *Dynamic );
bool
Render( TModel3d *Model, TDynamicObject const *Instance, double const Squaredistance );
bool
Render( TModel3d *Model, TDynamicObject const *Instance, Math3D::vector3 const &Position, Math3D::vector3 const &Angle );
bool
Render_Alpha( TDynamicObject *Dynamic );
bool
Render_Alpha( TModel3d *Model, TDynamicObject const *Instance, double const Squaredistance );
bool
Render_Alpha( TModel3d *Model, TDynamicObject const *Instance, Math3D::vector3 const &Position, Math3D::vector3 const &Angle );
// maintenance jobs
void
Update( double const Deltatime);
void
Update_Lights( light_array const &Lights );
@@ -118,6 +153,8 @@ private:
rendermode renderpass{ rendermode::color };
opengllight_array m_lights;
texture_manager m_textures;
opengl_camera m_camera;
float m_drawrange{ 2500.0f }; // current drawing range
};
extern opengl_renderer GfxRenderer;

View File

@@ -46,8 +46,8 @@ void TSky::Render( float3 const &Tint )
}
else
{ // renderowanie z Display List
mdCloud->Render(100, 0);
mdCloud->RenderAlpha(100, 0);
GfxRenderer.Render( mdCloud, nullptr, 100.0 );
GfxRenderer.Render_Alpha( mdCloud, nullptr, 100.0 );
}
#ifdef EU07_USE_OLD_LIGHTING_MODEL
glPopMatrix();

View File

@@ -21,7 +21,7 @@ cStars::render() {
::glRotatef( -std::fmod( Global::fTimeAngleDeg, 360.0f ), 0.0f, 1.0f, 0.0f ); // obrót dobowy osi OX
::glPointSize( 2.0f );
m_stars.Render( 1.0 );
GfxRenderer.Render( &m_stars, nullptr, 1.0 );
::glPointSize( 3.0f );
::glPopMatrix();

13
sun.cpp
View File

@@ -3,6 +3,7 @@
#include "sun.h"
#include "globals.h"
#include "mtable.h"
#include "usefull.h"
//////////////////////////////////////////////////////////////////////////////////////////
// cSun -- class responsible for dynamic calculation of position and intensity of the Sun,
@@ -94,6 +95,14 @@ void cSun::setLocation( float const Longitude, float const Latitude ) {
m_observer.latitude = (int)Latitude + (Latitude - (int)(Latitude)) * 100.0 / 60.0 ;
}
// sets current time, overriding one acquired from the system clock
void cSun::setTime( int const Hour, int const Minute, int const Second ) {
m_observer.hour = clamp( Hour, -1, 23 );
m_observer.minute = clamp( Minute, 0, 59 );
m_observer.second = clamp( Second, 0, 59 );
}
void cSun::setTemperature( float const Temperature ) {
m_observer.temp = Temperature;
@@ -112,6 +121,10 @@ void cSun::move() {
SYSTEMTIME localtime; // time for the calculation
time( &localtime );
if( m_observer.hour >= 0 ) { localtime.wHour = m_observer.hour; }
if( m_observer.minute >= 0 ) { localtime.wMinute = m_observer.minute; }
if( m_observer.second >= 0 ) { localtime.wSecond = m_observer.second; }
double ut = localtime.wHour
+ localtime.wMinute / 60.0 // too low resolution, noticeable skips
+ localtime.wSecond / 3600.0; // good enough in normal circumstances

7
sun.h
View File

@@ -27,6 +27,8 @@ public:
float getAngle();
// returns current intensity of the sun
float getIntensity();
// sets current time, overriding one acquired from the system clock
void setTime( int const Hour, int const Minute, int const Second );
// sets current geographic location
void setLocation( float const Longitude, float const Latitude );
// sets ambient temperature in degrees C.
@@ -87,7 +89,10 @@ protected:
double latitude; // latitude, degrees north (south negative)
double longitude; // longitude, degrees east (west negative)
double utime; // universal (Greenwich) standard time
int hour{ -1 }; // current time, used for calculation of utime. if set to -1, time for
int minute{ -1 };// calculation will be obtained from the local clock
int second{ -1 };
double utime; // universal (Greenwich) standard time
double timezone; // time zone, east (west negative). USA: Mountain = -7, Central = -6, etc.
double gmst; // Greenwich mean sidereal time, hours
double lmst; // local mean sidereal time, degrees