16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-22 19:49: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); 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 #define CameraH
#include "dumb3d.h" #include "dumb3d.h"
#include "frustum.h"
#include "dynobj.h" #include "dynobj.h"
using namespace Math3D; using namespace Math3D;
@@ -28,7 +27,6 @@ class TCamera
{ {
private: private:
vector3 pOffset; // nie używane (zerowe) vector3 pOffset; // nie używane (zerowe)
cFrustum m_frustum;
public: // McZapkie: potrzebuje do kiwania na boki public: // McZapkie: potrzebuje do kiwania na boki
double Pitch; double Pitch;
@@ -56,11 +54,6 @@ class TCamera
void SetCabMatrix(vector3 &p); void SetCabMatrix(vector3 &p);
void RaLook(); void RaLook();
void Stop(); void Stop();
inline
void
SetFrustum() { m_frustum.calculate(); }
bool
IsVisible( TDynamicObject const *Dynamic ) const;
// bool GetMatrix(matrix4x4 &Matrix); // bool GetMatrix(matrix4x4 &Matrix);
vector3 PtNext, PtPrev; vector3 PtNext, PtPrev;
}; };

View File

@@ -523,7 +523,7 @@ void TDynamicObject::UpdateLeverEnum(TAnim *pAnim)
}; };
// ABu 29.01.05 przeklejone z render i renderalpha: ********************* // 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 { // ABu290105: pozbierane i uporzadkowane powtarzajace
// sie rzeczy z Render i RenderAlpha // sie rzeczy z Render i RenderAlpha
// dodatkowy warunek, if (ObjSqrDist<...) zeby niepotrzebnie nie zmianiec w // dodatkowy warunek, if (ObjSqrDist<...) zeby niepotrzebnie nie zmianiec w
@@ -3699,38 +3699,11 @@ void TDynamicObject::TurnOff()
btMechanik1.TurnOff(); btMechanik1.TurnOff();
btMechanik2.TurnOff(); btMechanik2.TurnOff();
}; };
/*
void TDynamicObject::Render() void TDynamicObject::Render()
{ // rysowanie elementów nieprzezroczystych { // rysowanie elementów nieprzezroczystych
// youBy - sprawdzamy, czy jest sens renderowac // 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)) if (Global::pCamera->IsVisible(this))
{ {
TSubModel::iInstance = (size_t)this; //żeby nie robić cudzych animacji TSubModel::iInstance = (size_t)this; //żeby nie robić cudzych animacji
@@ -3904,6 +3877,7 @@ void TDynamicObject::Render()
TurnOff(); // przywrócenie domyślnych pozycji submodeli TurnOff(); // przywrócenie domyślnych pozycji submodeli
} // yB - koniec mieszania z grafika } // yB - koniec mieszania z grafika
}; };
*/
void TDynamicObject::RenderSounds() void TDynamicObject::RenderSounds()
{ // przeliczanie dźwięków, bo będzie { // przeliczanie dźwięków, bo będzie
@@ -4273,7 +4247,7 @@ void TDynamicObject::RenderSounds()
} }
*/ */
}; };
/*
void TDynamicObject::RenderAlpha() void TDynamicObject::RenderAlpha()
{ // rysowanie elementów półprzezroczystych { // rysowanie elementów półprzezroczystych
if (renderme) if (renderme)
@@ -4352,6 +4326,7 @@ void TDynamicObject::RenderAlpha()
} }
return; return;
} // koniec renderalpha } // koniec renderalpha
*/
// McZapkie-250202 // McZapkie-250202
// wczytywanie pliku z danymi multimedialnymi (dzwieki) // wczytywanie pliku z danymi multimedialnymi (dzwieki)

View File

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

View File

@@ -28,6 +28,7 @@ Stele, firleju, szociu, hunter, ZiomalCl, OLI_EU and others
#include "World.h" #include "World.h"
#include "Mover.h" #include "Mover.h"
#include "usefull.h" #include "usefull.h"
#include "timer.h"
#pragma comment( lib, "glfw3dll.lib" ) #pragma comment( lib, "glfw3dll.lib" )
#pragma comment( lib, "glew32.lib" ) #pragma comment( lib, "glew32.lib" )
@@ -148,7 +149,15 @@ void key_callback( GLFWwindow *window, int key, int scancode, int action, int mo
break; break;
} }
case GLFW_KEY_F7: 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; Global::bWireFrame = !Global::bWireFrame;
if( true == Global::bWireFrame ) { if( true == Global::bWireFrame ) {
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); 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 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 #ifdef _WINDOWS
extern "C" extern "C"
{ {
@@ -283,6 +300,7 @@ int main(int argc, char *argv[])
glfwSetFramebufferSizeCallback(window, window_resize_callback); glfwSetFramebufferSizeCallback(window, window_resize_callback);
glfwSetCursorPosCallback(window, cursor_pos_callback); glfwSetCursorPosCallback(window, cursor_pos_callback);
glfwSetKeyCallback(window, key_callback); glfwSetKeyCallback(window, key_callback);
glfwSetScrollCallback( window, scroll_callback );
glfwSetWindowFocusCallback(window, focus_callback); glfwSetWindowFocusCallback(window, focus_callback);
{ {
int width, height; int width, height;
@@ -329,7 +347,9 @@ int main(int argc, char *argv[])
} // po zrobieniu E3D odpalamy normalnie scenerię, by ją zobaczyć } // po zrobieniu E3D odpalamy normalnie scenerię, by ją zobaczyć
Console::On(); // włączenie konsoli Console::On(); // włączenie konsoli
while (!glfwWindowShouldClose(window) && World.Update()) while (!glfwWindowShouldClose(window)
&& World.Update()
&& GfxRenderer.Render())
{ {
glfwSwapBuffers(window); glfwSwapBuffers(window);
glfwPollEvents(); glfwPollEvents();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -168,7 +168,6 @@ bool TWorld::Init( GLFWwindow *w ) {
window = w; window = w;
Global::window = w; // do WM_COPYDATA Global::window = w; // do WM_COPYDATA
Global::pCamera = &Camera; // Ra: wskaźnik potrzebny do likwidacji drgań Global::pCamera = &Camera; // Ra: wskaźnik potrzebny do likwidacji drgań
Global::detonatoryOK = true;
WriteLog("Starting MaSzyna rail vehicle simulator."); WriteLog("Starting MaSzyna rail vehicle simulator.");
WriteLog(Global::asVersion); WriteLog(Global::asVersion);
/* /*
@@ -1184,26 +1183,12 @@ bool TWorld::Update()
// variable step render time routines // variable step render time routines
Update_Camera( dt ); // TODO: move the fixed step cab camera updates to fixed step secondary routines section 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 GfxRenderer.Update( dt );
// Ra 2014-12: przy 0.15 się skarżyli, że nie widać smug => zmieniłem na 0.25 ResourceSweep();
// 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 ) ) );
}
m_init = true; m_init = true;
// visualize state changes return true;
if (!Render())
return false;
return (true);
}; };
void void
@@ -1430,36 +1415,9 @@ void TWorld::Update_Environment() {
#endif #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() ); ResourceManager::Sweep( Timer::GetSimulationTime() );
return true;
}; };
// rendering kabiny gdy jest oddzielnym modelem i ma byc wyswietlana // 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 ); dynamic->mdKabina->RaRenderAlpha( 0.0, dynamic->ReplacableSkinID, dynamic->iAlpha );
} }
else { // renderowanie z Display List else { // renderowanie z Display List
dynamic->mdKabina->Render( 0.0, dynamic->ReplacableSkinID, dynamic->iAlpha ); GfxRenderer.Render( dynamic->mdKabina, dynamic, 0.0 );
dynamic->mdKabina->RenderAlpha( 0.0, dynamic->ReplacableSkinID, dynamic->iAlpha ); GfxRenderer.Render_Alpha( dynamic->mdKabina, dynamic, 0.0 );
} }
#ifdef EU07_USE_OLD_LIGHTING_MODEL #ifdef EU07_USE_OLD_LIGHTING_MODEL
// TODO: re-implement this // TODO: re-implement this
@@ -1765,13 +1723,14 @@ TWorld::Render_UI() {
if( Global::iTextMode == GLFW_KEY_F8 ) { if( Global::iTextMode == GLFW_KEY_F8 ) {
Global::iViewMode = GLFW_KEY_F8; Global::iViewMode = GLFW_KEY_F8;
OutText1 = "FPS: "; OutText1 = "FPS: " + to_string( Timer::GetFPS(), 2 );
OutText1 += to_string( Timer::GetFPS(), 2 );
//OutText1 += sprintf(); //OutText1 += sprintf();
if( Global::iSlowMotion ) if( Global::iSlowMotion )
OutText1 += " (slowmotion " + to_string( Global::iSlowMotion ) + ")"; OutText1 += " (slowmotion " + to_string( Global::iSlowMotion ) + ")";
OutText1 += ", sectors: "; OutText1 += ", sectors: " + to_string( Ground.iRendered );
OutText1 += to_string( Ground.iRendered ); if( DebugModeFlag ) {
OutText1 += " FoV: " + to_string( Global::FieldOfView / Global::ZoomFactor, 1 );
}
} }
// if (Console::Pressed(VK_F7)) // 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 ); .substr( 0 + 2 * floor( fmod( 8 + ( Camera.Yaw + 0.5 * M_PI_4 ) / M_PI_4, 8 ) ), 2 );
// current luminance level // current luminance level
OutText2 = "Light level: " + to_string( Global::fLuminance, 3 ); OutText2 = "Light level: " + to_string( Global::fLuminance, 3 );
if( Global::FakeLight ) { OutText2 += "(*)"; }
} }
// OutText3= AnsiString(" Online documentation (PL, ENG, DE, soon CZ): // OutText3= AnsiString(" Online documentation (PL, ENG, DE, soon CZ):
// http://www.eu07.pl"); // http://www.eu07.pl");
@@ -2463,7 +2423,6 @@ TWorld::Render_UI() {
// ABu 150205: prosty help, zeby sie na forum nikt nie pytal, jak ma ruszyc :) // 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 (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 if( Global::iTextMode == GLFW_KEY_F9 ) { // informacja o wersji, sposobie wyświetlania i błędach OpenGL
// Global::iViewMode=VK_F9; // Global::iViewMode=VK_F9;
@@ -2596,7 +2555,6 @@ TWorld::Render_UI() {
} }
} }
} }
}
// if (Global::iViewMode!=Global::iTextMode) // if (Global::iViewMode!=Global::iTextMode)
//{//Ra: taka maksymalna prowizorka na razie //{//Ra: taka maksymalna prowizorka na razie
// WriteLog("Pressed function key F"+AnsiString(Global::iViewMode-111)); // WriteLog("Pressed function key F"+AnsiString(Global::iViewMode-111));
@@ -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 void
world_environment::init() { world_environment::init() {
@@ -2976,3 +2949,9 @@ world_environment::render() {
::glEnable( GL_FOG ); ::glEnable( GL_FOG );
::glEnable( GL_LIGHTING ); ::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 "stars.h"
#include "skydome.h" #include "skydome.h"
#include "mczapkie/mover.h" #include "mczapkie/mover.h"
#include "glfw/glfw3.h" #include "renderer.h"
// wrapper for environment elements -- sky, sun, stars, clouds etc // wrapper for environment elements -- sky, sun, stars, clouds etc
class world_environment { class world_environment {
@@ -27,6 +27,7 @@ public:
void init(); void init();
void update(); void update();
void render(); void render();
void time( int const Hour = -1, int const Minute = -1, int const Second = -1 );
private: private:
CSkyDome m_skydome; CSkyDome m_skydome;
@@ -37,6 +38,9 @@ private:
class TWorld 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 InOutKey( bool const Near = true );
void FollowView(bool wycisz = true); void FollowView(bool wycisz = true);
void DistantView( bool const Near = false ); void DistantView( bool const Near = false );
@@ -53,6 +57,8 @@ class TWorld
void OnCommandGet(DaneRozkaz *pRozkaz); void OnCommandGet(DaneRozkaz *pRozkaz);
bool Update(); bool Update();
void TrainDelete(TDynamicObject *d = NULL); void TrainDelete(TDynamicObject *d = NULL);
// switches between static and dynamic daylight calculation
void ToggleDaylight();
TWorld(); TWorld();
~TWorld(); ~TWorld();
// double Aspect; // double Aspect;
@@ -63,7 +69,7 @@ class TWorld
std::string OutText4; std::string OutText4;
void Update_Environment(); void Update_Environment();
void Update_Camera( const double Deltatime ); void Update_Camera( const double Deltatime );
bool Render(); void ResourceSweep();
void Render_Cab(); void Render_Cab();
void Render_UI(); void Render_UI();
TCamera Camera; TCamera Camera;

View File

@@ -1,4 +1,4 @@
/* /*
This Source Code Form is subject to the This Source Code Form is subject to the
terms of the Mozilla Public License, v. terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not 2.0. If a copy of the MPL was not
@@ -10,8 +10,25 @@ http://mozilla.org/MPL/2.0/.
#include "stdafx.h" #include "stdafx.h"
#include "renderer.h" #include "renderer.h"
#include "globals.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; opengl_renderer GfxRenderer;
extern TWorld World;
void void
opengl_renderer::Init() { 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 void
opengl_renderer::Update_Lights( light_array const &Lights ) { opengl_renderer::Update_Lights( light_array const &Lights ) {

View File

@@ -13,6 +13,7 @@ http://mozilla.org/MPL/2.0/.
#include "texture.h" #include "texture.h"
#include "lightarray.h" #include "lightarray.h"
#include "dumb3d.h" #include "dumb3d.h"
#include "frustum.h"
struct opengl_light { 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 // bare-bones render controller, in lack of anything better yet
class opengl_renderer { class opengl_renderer {
@@ -78,6 +95,24 @@ public:
// methods // methods
void void
Init(); 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 void
Update_Lights( light_array const &Lights ); Update_Lights( light_array const &Lights );
@@ -118,6 +153,8 @@ private:
rendermode renderpass{ rendermode::color }; rendermode renderpass{ rendermode::color };
opengllight_array m_lights; opengllight_array m_lights;
texture_manager m_textures; texture_manager m_textures;
opengl_camera m_camera;
float m_drawrange{ 2500.0f }; // current drawing range
}; };
extern opengl_renderer GfxRenderer; extern opengl_renderer GfxRenderer;

View File

@@ -46,8 +46,8 @@ void TSky::Render( float3 const &Tint )
} }
else else
{ // renderowanie z Display List { // renderowanie z Display List
mdCloud->Render(100, 0); GfxRenderer.Render( mdCloud, nullptr, 100.0 );
mdCloud->RenderAlpha(100, 0); GfxRenderer.Render_Alpha( mdCloud, nullptr, 100.0 );
} }
#ifdef EU07_USE_OLD_LIGHTING_MODEL #ifdef EU07_USE_OLD_LIGHTING_MODEL
glPopMatrix(); 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 ::glRotatef( -std::fmod( Global::fTimeAngleDeg, 360.0f ), 0.0f, 1.0f, 0.0f ); // obrót dobowy osi OX
::glPointSize( 2.0f ); ::glPointSize( 2.0f );
m_stars.Render( 1.0 ); GfxRenderer.Render( &m_stars, nullptr, 1.0 );
::glPointSize( 3.0f ); ::glPointSize( 3.0f );
::glPopMatrix(); ::glPopMatrix();

13
sun.cpp
View File

@@ -3,6 +3,7 @@
#include "sun.h" #include "sun.h"
#include "globals.h" #include "globals.h"
#include "mtable.h" #include "mtable.h"
#include "usefull.h"
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// cSun -- class responsible for dynamic calculation of position and intensity of the Sun, // 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 ; 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 ) { void cSun::setTemperature( float const Temperature ) {
m_observer.temp = Temperature; m_observer.temp = Temperature;
@@ -112,6 +121,10 @@ void cSun::move() {
SYSTEMTIME localtime; // time for the calculation SYSTEMTIME localtime; // time for the calculation
time( &localtime ); 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 double ut = localtime.wHour
+ localtime.wMinute / 60.0 // too low resolution, noticeable skips + localtime.wMinute / 60.0 // too low resolution, noticeable skips
+ localtime.wSecond / 3600.0; // good enough in normal circumstances + localtime.wSecond / 3600.0; // good enough in normal circumstances

5
sun.h
View File

@@ -27,6 +27,8 @@ public:
float getAngle(); float getAngle();
// returns current intensity of the sun // returns current intensity of the sun
float getIntensity(); 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 // sets current geographic location
void setLocation( float const Longitude, float const Latitude ); void setLocation( float const Longitude, float const Latitude );
// sets ambient temperature in degrees C. // sets ambient temperature in degrees C.
@@ -87,6 +89,9 @@ protected:
double latitude; // latitude, degrees north (south negative) double latitude; // latitude, degrees north (south negative)
double longitude; // longitude, degrees east (west negative) double longitude; // longitude, degrees east (west negative)
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 utime; // universal (Greenwich) standard time
double timezone; // time zone, east (west negative). USA: Mountain = -7, Central = -6, etc. double timezone; // time zone, east (west negative). USA: Mountain = -7, Central = -6, etc.
double gmst; // Greenwich mean sidereal time, hours double gmst; // Greenwich mean sidereal time, hours