mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-18 00:49:19 +02:00
implemented geometry bank manager, unified traction render code
This commit is contained in:
@@ -3992,7 +3992,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
|||||||
// otherwise try the basic approach
|
// otherwise try the basic approach
|
||||||
int skinindex = 0;
|
int skinindex = 0;
|
||||||
do {
|
do {
|
||||||
texture_manager::size_type texture = GfxRenderer.GetTextureId( Global::asCurrentTexturePath + ReplacableSkin + "," + std::to_string( skinindex + 1 ), "", Global::iDynamicFiltering, true );
|
texture_handle texture = GfxRenderer.GetTextureId( Global::asCurrentTexturePath + ReplacableSkin + "," + std::to_string( skinindex + 1 ), "", Global::iDynamicFiltering, true );
|
||||||
if( false == GfxRenderer.Texture( texture ).is_ready ) {
|
if( false == GfxRenderer.Texture( texture ).is_ready ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
2
DynObj.h
2
DynObj.h
@@ -143,7 +143,7 @@ class TAnim
|
|||||||
struct material_data {
|
struct material_data {
|
||||||
|
|
||||||
int textures_alpha{ 0x30300030 }; // maska przezroczystości tekstur. default: tekstury wymienne nie mają przezroczystości
|
int textures_alpha{ 0x30300030 }; // maska przezroczystości tekstur. default: tekstury wymienne nie mają przezroczystości
|
||||||
texture_manager::size_type replacable_skins[ 5 ]; // McZapkie:zmienialne nadwozie
|
texture_handle replacable_skins[ 5 ]; // McZapkie:zmienialne nadwozie
|
||||||
int multi_textures{ 0 }; //<0 tekstury wskazane wpisem, >0 tekstury z przecinkami, =0 jedna
|
int multi_textures{ 0 }; //<0 tekstury wskazane wpisem, >0 tekstury z przecinkami, =0 jedna
|
||||||
|
|
||||||
material_data() {
|
material_data() {
|
||||||
|
|||||||
65
Ground.cpp
65
Ground.cpp
@@ -380,7 +380,14 @@ void TSubRect::NodeAdd(TGroundNode *Node)
|
|||||||
// nRenderWires - lista grup renderowanych z własnych VBO albo DL - druty i linie
|
// nRenderWires - lista grup renderowanych z własnych VBO albo DL - druty i linie
|
||||||
// nMeshed - obiekty do pogrupowania wg tekstur
|
// nMeshed - obiekty do pogrupowania wg tekstur
|
||||||
|
|
||||||
Node->m_rootposition = Math3D::vector3( m_area.center.x, m_area.center.y, m_area.center.z ) ;
|
Node->m_rootposition = Math3D::vector3( m_area.center.x, m_area.center.y, m_area.center.z );
|
||||||
|
|
||||||
|
// since ground rectangle can be empty, we're doing lazy initialization of the geometry bank, when something may actually use it
|
||||||
|
// NOTE: this method is called for both subcell and cell, but subcells get first created and passed the handle from their parent
|
||||||
|
// thus, this effectively only gets executed for the 'parent' ground cells. Not the most elegant, but for now it'll do
|
||||||
|
if( m_geometrybank == NULL ) {
|
||||||
|
m_geometrybank = GfxRenderer.Create_Bank();
|
||||||
|
}
|
||||||
|
|
||||||
switch (Node->iType)
|
switch (Node->iType)
|
||||||
{
|
{
|
||||||
@@ -756,9 +763,7 @@ void TSubRect::LoadNodes()
|
|||||||
m_nVertexCount += n->iNumVerts;
|
m_nVertexCount += n->iNumVerts;
|
||||||
break;
|
break;
|
||||||
case TP_TRACTION:
|
case TP_TRACTION:
|
||||||
n->iVboPtr = m_nVertexCount; // nowy początek
|
n->hvTraction->create_geometry( m_geometrybank, n->m_rootposition );
|
||||||
n->iNumVerts = n->hvTraction->RaArrayPrepare(); // zliczenie wierzchołków
|
|
||||||
m_nVertexCount += n->iNumVerts;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
n = n->nNext2; // następny z sektora
|
n = n->nNext2; // następny z sektora
|
||||||
@@ -810,14 +815,7 @@ void TSubRect::LoadNodes()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TP_TRACTION:
|
default:
|
||||||
if( n->iNumVerts ) { // druty mogą być niewidoczne...?
|
|
||||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
|
||||||
n->hvTraction->RaArrayFill( m_pVNT + n->iVboPtr, n->m_rootposition );
|
|
||||||
#else
|
|
||||||
n->hvTraction->RaArrayFill( m_pVNT.data() + n->iVboPtr );
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
n = n->nNext2; // następny z sektora
|
n = n->nNext2; // następny z sektora
|
||||||
@@ -857,22 +855,25 @@ TGroundRect::~TGroundRect()
|
|||||||
|
|
||||||
void
|
void
|
||||||
TGroundRect::Init() {
|
TGroundRect::Init() {
|
||||||
|
// since ground rectangle can be empty, we're doing lazy initialization of the geometry bank, when something may actually use it
|
||||||
|
if( m_geometrybank == NULL ) {
|
||||||
|
m_geometrybank = GfxRenderer.Create_Bank();
|
||||||
|
}
|
||||||
|
|
||||||
pSubRects = new TSubRect[ iNumSubRects * iNumSubRects ];
|
pSubRects = new TSubRect[ iNumSubRects * iNumSubRects ];
|
||||||
float const subrectsize = 1000.0f / iNumSubRects;
|
float const subrectsize = 1000.0f / iNumSubRects;
|
||||||
for( int column = 0; column < iNumSubRects; ++column ) {
|
for( int column = 0; column < iNumSubRects; ++column ) {
|
||||||
for( int row = 0; row < iNumSubRects; ++row ) {
|
for( int row = 0; row < iNumSubRects; ++row ) {
|
||||||
auto &area = SafeGetRect(column, row)->m_area;
|
auto subcell = FastGetRect( column, row );
|
||||||
|
auto &area = subcell->m_area;
|
||||||
area.center =
|
area.center =
|
||||||
m_area.center
|
m_area.center
|
||||||
- glm::vec3( 500.0f, 0.0f, 500.0f ) // 'upper left' corner of rectangle
|
- glm::vec3( 500.0f, 0.0f, 500.0f ) // 'upper left' corner of rectangle
|
||||||
+ glm::vec3( subrectsize * 0.5f, 0.0f, subrectsize * 0.5f ) // center of sub-rectangle
|
+ glm::vec3( subrectsize * 0.5f, 0.0f, subrectsize * 0.5f ) // center of sub-rectangle
|
||||||
+ glm::vec3( subrectsize * column, 0.0f, subrectsize * row );
|
+ glm::vec3( subrectsize * column, 0.0f, subrectsize * row );
|
||||||
/*
|
|
||||||
// NOTE: the actual coordinates get swapped, as they're swapped in rest of the code :x
|
|
||||||
area.center = glm::vec3( area.center.z, area.center.y, area.center.x );
|
|
||||||
*/
|
|
||||||
area.radius = subrectsize * M_SQRT2;
|
area.radius = subrectsize * M_SQRT2;
|
||||||
|
// all subcells share the same geometry bank with their parent, to reduce buffer switching during render
|
||||||
|
subcell->m_geometrybank = m_geometrybank;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -1822,8 +1823,11 @@ void TGround::FirstInit()
|
|||||||
Current->InitNormals();
|
Current->InitNormals();
|
||||||
if (Current->iType != TP_DYNAMIC)
|
if (Current->iType != TP_DYNAMIC)
|
||||||
{ // pojazdów w ogóle nie dotyczy dodawanie do mapy
|
{ // pojazdów w ogóle nie dotyczy dodawanie do mapy
|
||||||
if (i == TP_EVLAUNCH ? Current->EvLaunch->IsGlobal() : false)
|
if( ( i == TP_EVLAUNCH )
|
||||||
srGlobal.NodeAdd(Current); // dodanie do globalnego obiektu
|
&& ( true == Current->EvLaunch->IsGlobal() ) ) {
|
||||||
|
// dodanie do globalnego obiektu
|
||||||
|
srGlobal.NodeAdd( Current );
|
||||||
|
}
|
||||||
else if (i == TP_TERRAIN)
|
else if (i == TP_TERRAIN)
|
||||||
{ // specjalne przetwarzanie terenu wczytanego z pliku E3D
|
{ // specjalne przetwarzanie terenu wczytanego z pliku E3D
|
||||||
TGroundRect *gr;
|
TGroundRect *gr;
|
||||||
@@ -1918,8 +1922,10 @@ bool TGround::Init(std::string File)
|
|||||||
if (!LastNode->Vertices)
|
if (!LastNode->Vertices)
|
||||||
SafeDelete(LastNode); // usuwamy nieprzezroczyste trójkąty terenu
|
SafeDelete(LastNode); // usuwamy nieprzezroczyste trójkąty terenu
|
||||||
}
|
}
|
||||||
else if ( ( LastNode->iType == TP_TRACTION ) && ( false == Global::bLoadTraction ) )
|
else if( ( LastNode->iType == TP_TRACTION )
|
||||||
SafeDelete(LastNode); // usuwamy druty, jeśli wyłączone
|
&& ( false == Global::bLoadTraction ) ) {
|
||||||
|
SafeDelete( LastNode ); // usuwamy druty, jeśli wyłączone
|
||||||
|
}
|
||||||
|
|
||||||
if (LastNode) // dopiero na koniec dopisujemy do tablic
|
if (LastNode) // dopiero na koniec dopisujemy do tablic
|
||||||
if (LastNode->iType != TP_DYNAMIC)
|
if (LastNode->iType != TP_DYNAMIC)
|
||||||
@@ -4371,11 +4377,9 @@ void TGround::TerrainWrite()
|
|||||||
m->iNumVerts +=
|
m->iNumVerts +=
|
||||||
Current->iNumVerts; // zwiększenie całkowitej ilości wierzchołków
|
Current->iNumVerts; // zwiększenie całkowitej ilości wierzchołków
|
||||||
break;
|
break;
|
||||||
case GL_TRIANGLE_STRIP: // na razie nie, bo trzeba przerabiać na pojedyncze
|
case GL_TRIANGLE_STRIP: // na razie nie, bo trzeba przerabiać na pojedyncze trójkąty
|
||||||
// trójkąty
|
|
||||||
break;
|
break;
|
||||||
case GL_TRIANGLE_FAN: // na razie nie, bo trzeba przerabiać na pojedyncze
|
case GL_TRIANGLE_FAN: // na razie nie, bo trzeba przerabiać na pojedyncze trójkąty
|
||||||
// trójkąty
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for (Current = Rects[i][j].nRootNode; Current; Current = Current->nNext2)
|
for (Current = Rects[i][j].nRootNode; Current; Current = Current->nNext2)
|
||||||
@@ -4383,15 +4387,10 @@ void TGround::TerrainWrite()
|
|||||||
switch (Current->iType)
|
switch (Current->iType)
|
||||||
{ // pętla po trójkątach - dopisywanie wierzchołków
|
{ // pętla po trójkątach - dopisywanie wierzchołków
|
||||||
case GL_TRIANGLES:
|
case GL_TRIANGLES:
|
||||||
// ver=sk->TrianglePtr(TTexturesManager::GetName(Current->TextureID).c_str(),Current->iNumVerts);
|
|
||||||
// //wskaźnik na początek
|
// //wskaźnik na początek
|
||||||
ver = sk->TrianglePtr(Current->TextureID, Current->iVboPtr,
|
ver = sk->TrianglePtr(Current->TextureID, Current->iVboPtr,
|
||||||
Current->Ambient, Current->Diffuse,
|
Current->Ambient, Current->Diffuse,
|
||||||
Current->Specular); // wskaźnik na początek
|
Current->Specular); // wskaźnik na początek
|
||||||
// WriteLog("Zapis "+AnsiString(Current->iNumVerts)+" trójkątów w
|
|
||||||
// ("+AnsiString(i)+","+AnsiString(j)+") od
|
|
||||||
// "+AnsiString(Current->iVboPtr)+" dla
|
|
||||||
// "+AnsiString(Current->TextureID));
|
|
||||||
Current->iVboPtr = -1; // bo to było tymczasowo używane
|
Current->iVboPtr = -1; // bo to było tymczasowo używane
|
||||||
for (k = 0; k < Current->iNumVerts; ++k)
|
for (k = 0; k < Current->iNumVerts; ++k)
|
||||||
{ // przepisanie współrzędnych
|
{ // przepisanie współrzędnych
|
||||||
@@ -4405,11 +4404,9 @@ void TGround::TerrainWrite()
|
|||||||
ver[k].texture.t = Current->Vertices[k].tv;
|
ver[k].texture.t = Current->Vertices[k].tv;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GL_TRIANGLE_STRIP: // na razie nie, bo trzeba przerabiać na pojedyncze
|
case GL_TRIANGLE_STRIP: // na razie nie, bo trzeba przerabiać na pojedyncze trójkąty
|
||||||
// trójkąty
|
|
||||||
break;
|
break;
|
||||||
case GL_TRIANGLE_FAN: // na razie nie, bo trzeba przerabiać na pojedyncze
|
case GL_TRIANGLE_FAN: // na razie nie, bo trzeba przerabiać na pojedyncze trójkąty
|
||||||
// trójkąty
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
58
Ground.h
58
Ground.h
@@ -11,6 +11,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "GL/glew.h"
|
#include "GL/glew.h"
|
||||||
|
#include "openglgeometrybank.h"
|
||||||
#include "VBO.h"
|
#include "VBO.h"
|
||||||
#include "Classes.h"
|
#include "Classes.h"
|
||||||
#include "ResourceManager.h"
|
#include "ResourceManager.h"
|
||||||
@@ -141,7 +142,7 @@ public:
|
|||||||
GLuint DisplayListID; // numer siatki DisplayLists
|
GLuint DisplayListID; // numer siatki DisplayLists
|
||||||
bool PROBLEND;
|
bool PROBLEND;
|
||||||
int iVboPtr; // indeks w buforze VBO
|
int iVboPtr; // indeks w buforze VBO
|
||||||
texture_manager::size_type TextureID; // główna (jedna) tekstura obiektu
|
texture_handle TextureID; // główna (jedna) tekstura obiektu
|
||||||
int iFlags; // tryb przezroczystości: 0x10-nieprz.,0x20-przezroczysty,0x30-mieszany
|
int iFlags; // tryb przezroczystości: 0x10-nieprz.,0x20-przezroczysty,0x30-mieszany
|
||||||
int Ambient[4], Diffuse[4], Specular[4]; // oświetlenie
|
int Ambient[4], Diffuse[4], Specular[4]; // oświetlenie
|
||||||
bool bVisible;
|
bool bVisible;
|
||||||
@@ -235,32 +236,38 @@ class TGroundRect : public TSubRect
|
|||||||
// Ra: 2012-02 doszły submodele terenu
|
// Ra: 2012-02 doszły submodele terenu
|
||||||
friend class opengl_renderer;
|
friend class opengl_renderer;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
TSubRect *pSubRects { nullptr };
|
||||||
int iLastDisplay; // numer klatki w której był ostatnio wyświetlany
|
int iLastDisplay; // numer klatki w której był ostatnio wyświetlany
|
||||||
TSubRect *pSubRects{ nullptr };
|
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static int iFrameNumber; // numer kolejny wyświetlanej klatki
|
|
||||||
TGroundNode *nTerrain{ nullptr }; // model terenu z E3D - użyć nRootMesh?
|
|
||||||
virtual ~TGroundRect();
|
virtual ~TGroundRect();
|
||||||
|
// pobranie wskaźnika do małego kwadratu, utworzenie jeśli trzeba
|
||||||
TSubRect * SafeGetRect(int iCol, int iRow)
|
TSubRect * SafeGetRect(int iCol, int iRow) {
|
||||||
{ // pobranie wskaźnika do małego kwadratu, utworzenie jeśli trzeba
|
if( !pSubRects ) {
|
||||||
if (!pSubRects)
|
// utworzenie małych kwadratów
|
||||||
Init(); // utworzenie małych kwadratów
|
Init();
|
||||||
|
}
|
||||||
return pSubRects + iRow * iNumSubRects + iCol; // zwrócenie właściwego
|
return pSubRects + iRow * iNumSubRects + iCol; // zwrócenie właściwego
|
||||||
};
|
};
|
||||||
TSubRect * FastGetRect(int iCol, int iRow)
|
// pobranie wskaźnika do małego kwadratu, bez tworzenia jeśli nie ma
|
||||||
{ // pobranie wskaźnika do małego kwadratu, bez tworzenia jeśli nie ma
|
TSubRect * FastGetRect(int iCol, int iRow) {
|
||||||
return (pSubRects ? pSubRects + iRow * iNumSubRects + iCol : NULL);
|
return (pSubRects ? pSubRects + iRow * iNumSubRects + iCol : NULL);
|
||||||
};
|
};
|
||||||
void Optimize()
|
// optymalizacja obiektów w sektorach
|
||||||
{ // optymalizacja obiektów w sektorach
|
void Optimize() {
|
||||||
if (pSubRects)
|
if( pSubRects ) {
|
||||||
for (int i = iNumSubRects * iNumSubRects - 1; i >= 0; --i)
|
for( int i = iNumSubRects * iNumSubRects - 1; i >= 0; --i ) {
|
||||||
pSubRects[i].Sort(); // optymalizacja obiektów w sektorach
|
// optymalizacja obiektów w sektorach
|
||||||
|
pSubRects[ i ].Sort();
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int iFrameNumber; // numer kolejny wyświetlanej klatki
|
||||||
|
TGroundNode *nTerrain { nullptr }; // model terenu z E3D - użyć nRootMesh?
|
||||||
};
|
};
|
||||||
|
|
||||||
class TGround
|
class TGround
|
||||||
@@ -269,7 +276,6 @@ class TGround
|
|||||||
|
|
||||||
vector3 CameraDirection; // zmienna robocza przy renderowaniu
|
vector3 CameraDirection; // zmienna robocza przy renderowaniu
|
||||||
int const *iRange = nullptr; // tabela widoczności
|
int const *iRange = nullptr; // tabela widoczności
|
||||||
// TGroundNode *nRootNode; //lista wszystkich węzłów
|
|
||||||
TGroundNode *nRootDynamic = nullptr; // lista pojazdów
|
TGroundNode *nRootDynamic = nullptr; // lista pojazdów
|
||||||
TGroundRect Rects[iNumRects][iNumRects]; // mapa kwadratów kilometrowych
|
TGroundRect Rects[iNumRects][iNumRects]; // mapa kwadratów kilometrowych
|
||||||
TEvent *RootEvent = nullptr; // lista zdarzeń
|
TEvent *RootEvent = nullptr; // lista zdarzeń
|
||||||
@@ -283,9 +289,7 @@ class TGround
|
|||||||
vector3 aRotate;
|
vector3 aRotate;
|
||||||
bool bInitDone = false;
|
bool bInitDone = false;
|
||||||
TGroundNode *nRootOfType[TP_LAST]; // tablica grupująca obiekty, przyspiesza szukanie
|
TGroundNode *nRootOfType[TP_LAST]; // tablica grupująca obiekty, przyspiesza szukanie
|
||||||
// TGroundNode *nLastOfType[TP_LAST]; //ostatnia
|
|
||||||
TSubRect srGlobal; // zawiera obiekty globalne (na razie wyzwalacze czasowe)
|
TSubRect srGlobal; // zawiera obiekty globalne (na razie wyzwalacze czasowe)
|
||||||
// int tracks,tracksfar; //liczniki torów
|
|
||||||
typedef std::unordered_map<std::string, TEvent *> event_map;
|
typedef std::unordered_map<std::string, TEvent *> event_map;
|
||||||
event_map m_eventmap;
|
event_map m_eventmap;
|
||||||
TNames<TGroundNode *> m_trackmap;
|
TNames<TGroundNode *> m_trackmap;
|
||||||
@@ -296,7 +300,6 @@ class TGround
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
bool bDynamicRemove = false; // czy uruchomić procedurę usuwania pojazdów
|
bool bDynamicRemove = false; // czy uruchomić procedurę usuwania pojazdów
|
||||||
TDynamicObject *LastDyn = nullptr; // ABu: paskudnie, ale na bardzo szybko moze jakos przejdzie...
|
|
||||||
|
|
||||||
TGround();
|
TGround();
|
||||||
~TGround();
|
~TGround();
|
||||||
@@ -311,17 +314,6 @@ class TGround
|
|||||||
TTraction * FindTraction(vector3 *Point, int &iConnection, TGroundNode *Exclude);
|
TTraction * FindTraction(vector3 *Point, int &iConnection, TGroundNode *Exclude);
|
||||||
TTraction * TractionNearestFind(vector3 &p, int dir, TGroundNode *n);
|
TTraction * TractionNearestFind(vector3 &p, int dir, TGroundNode *n);
|
||||||
TGroundNode * AddGroundNode(cParser *parser);
|
TGroundNode * AddGroundNode(cParser *parser);
|
||||||
bool AddGroundNode(double x, double z, TGroundNode *Node)
|
|
||||||
{
|
|
||||||
TSubRect *tmp = GetSubRect(x, z);
|
|
||||||
if (tmp)
|
|
||||||
{
|
|
||||||
tmp->NodeAdd(Node);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
void UpdatePhys(double dt, int iter); // aktualizacja fizyki stałym krokiem
|
void UpdatePhys(double dt, int iter); // aktualizacja fizyki stałym krokiem
|
||||||
bool Update(double dt, int iter); // aktualizacja przesunięć zgodna z FPS
|
bool Update(double dt, int iter); // aktualizacja przesunięć zgodna z FPS
|
||||||
void Update_Lights(); // updates scene lights array
|
void Update_Lights(); // updates scene lights array
|
||||||
|
|||||||
@@ -1228,9 +1228,9 @@ extract_value( std::string const &Key, std::string const &Input ) {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename _Type>
|
template <typename Type_>
|
||||||
bool
|
bool
|
||||||
extract_value( _Type &Variable, std::string const &Key, std::string const &Input, std::string const &Default ) {
|
extract_value( Type_ &Variable, std::string const &Key, std::string const &Input, std::string const &Default ) {
|
||||||
|
|
||||||
auto value = extract_value( Key, Input );
|
auto value = extract_value( Key, Input );
|
||||||
if( false == value.empty() ) {
|
if( false == value.empty() ) {
|
||||||
|
|||||||
177
Model3d.cpp
177
Model3d.cpp
@@ -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 const *TSubModel::ReplacableSkinId = NULL;
|
texture_handle 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;
|
||||||
@@ -117,20 +117,20 @@ TSubModel::~TSubModel()
|
|||||||
// wyświetlania
|
// wyświetlania
|
||||||
};
|
};
|
||||||
|
|
||||||
void TSubModel::TextureNameSet(const char *n)
|
void TSubModel::TextureNameSet(std::string const &Name)
|
||||||
{ // ustawienie nazwy submodelu, o
|
{ // ustawienie nazwy submodelu, o
|
||||||
// ile nie jest wczytany z E3D
|
// ile nie jest wczytany z E3D
|
||||||
if (iFlags & 0x0200)
|
if (iFlags & 0x0200)
|
||||||
{ // tylko jeżeli submodel zosta utworzony przez new
|
{ // tylko jeżeli submodel zosta utworzony przez new
|
||||||
pTexture = std::string(n);
|
pTexture = Name;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void TSubModel::NameSet(const char *n)
|
void TSubModel::NameSet(std::string const &Name)
|
||||||
{ // ustawienie nazwy submodelu, o ile
|
{ // ustawienie nazwy submodelu, o ile
|
||||||
// nie jest wczytany z E3D
|
// nie jest wczytany z E3D
|
||||||
if (iFlags & 0x0200)
|
if (iFlags & 0x0200)
|
||||||
pName = std::string(n);
|
pName = Name;
|
||||||
};
|
};
|
||||||
|
|
||||||
// int TSubModel::SeekFaceNormal(DWORD *Masks, int f,DWORD dwMask,vector3
|
// int TSubModel::SeekFaceNormal(DWORD *Masks, int f,DWORD dwMask,vector3
|
||||||
@@ -204,9 +204,6 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic)
|
|||||||
{ // Ra: VBO tworzone na poziomie modelu, a nie submodeli
|
{ // Ra: VBO tworzone na poziomie modelu, a nie submodeli
|
||||||
iNumVerts = 0;
|
iNumVerts = 0;
|
||||||
iVboPtr = Pos; // pozycja w VBO
|
iVboPtr = Pos; // pozycja w VBO
|
||||||
// TMaterialColorf Ambient,Diffuse,Specular;
|
|
||||||
// GLuint TextureID;
|
|
||||||
// char *extName;
|
|
||||||
if (!parser.expectToken("type:"))
|
if (!parser.expectToken("type:"))
|
||||||
Error("Model type parse failure!");
|
Error("Model type parse failure!");
|
||||||
{
|
{
|
||||||
@@ -224,22 +221,24 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic)
|
|||||||
};
|
};
|
||||||
parser.ignoreToken();
|
parser.ignoreToken();
|
||||||
std::string token;
|
std::string token;
|
||||||
// parser.getToken(token1); //ze zmianą na małe!
|
|
||||||
parser.getTokens(1, false); // nazwa submodelu bez zmieny na małe
|
parser.getTokens(1, false); // nazwa submodelu bez zmieny na małe
|
||||||
parser >> token;
|
parser >> token;
|
||||||
NameSet(token.c_str());
|
NameSet(token);
|
||||||
if (dynamic)
|
if (dynamic) {
|
||||||
{ // dla pojazdu, blokujemy załączone submodele, które mogą być
|
// dla pojazdu, blokujemy załączone submodele, które mogą być nieobsługiwane
|
||||||
// nieobsługiwane
|
if( ( token.size() >= 3 )
|
||||||
if ( (token.size() >= 3)
|
&& ( token.find( "_on" ) + 3 == token.length() ) ) {
|
||||||
&& (token.find("_on") + 3 == token.length())) // jeśli nazwa kończy się na "_on"
|
// jeśli nazwa kończy się na "_on" to domyślnie wyłączyć, żeby się nie nakładało z obiektem "_off"
|
||||||
iVisible = 0; // to domyślnie wyłączyć, żeby się nie nakładało z obiektem "_off"
|
iVisible = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// dla pozostałych modeli blokujemy zapalone światła, które mogą być nieobsługiwane
|
||||||
|
if( token.compare( 0, 8, "Light_On" ) == 0 ) {
|
||||||
|
// jeśli nazwa zaczyna się od "Light_On" to domyślnie wyłączyć, żeby się nie nakładało z obiektem "Light_Off"
|
||||||
|
iVisible = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else // dla pozostałych modeli blokujemy zapalone światła, które mogą być
|
|
||||||
// nieobsługiwane
|
|
||||||
if (token.compare(0, 8, "Light_On") == 0) // jeśli nazwa zaczyna się od "Light_On"
|
|
||||||
iVisible = 0; // to domyślnie wyłączyć, żeby się nie nakładało z obiektem
|
|
||||||
// "Light_Off"
|
|
||||||
|
|
||||||
if (parser.expectToken("anim:")) // Ra: ta informacja by się przydała!
|
if (parser.expectToken("anim:")) // Ra: ta informacja by się przydała!
|
||||||
{ // rodzaj animacji
|
{ // rodzaj animacji
|
||||||
@@ -590,7 +589,7 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic)
|
|||||||
return iNumVerts; // do określenia wielkości VBO
|
return iNumVerts; // do określenia wielkości VBO
|
||||||
};
|
};
|
||||||
|
|
||||||
int TSubModel::TriangleAdd(TModel3d *m, texture_manager::size_type tex, int tri)
|
int TSubModel::TriangleAdd(TModel3d *m, texture_handle tex, int tri)
|
||||||
{ // dodanie trójkątów do submodelu, używane
|
{ // dodanie trójkątów do submodelu, używane
|
||||||
// przy tworzeniu E3D terenu
|
// przy tworzeniu E3D terenu
|
||||||
TSubModel *s = this;
|
TSubModel *s = this;
|
||||||
@@ -644,6 +643,7 @@ basic_vertex *TSubModel::TrianglePtr(int tex, int pos, int *la, int *ld, int *ls
|
|||||||
return s->Vertices + pos; // wskaźnik na wolne miejsce w tabeli wierzchołków
|
return s->Vertices + pos; // wskaźnik na wolne miejsce w tabeli wierzchołków
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef EU07_USE_OLD_RENDERCODE
|
||||||
void TSubModel::DisplayLists()
|
void TSubModel::DisplayLists()
|
||||||
{ // utworznie po jednej skompilowanej liście dla
|
{ // utworznie po jednej skompilowanej liście dla
|
||||||
// każdego submodelu
|
// każdego submodelu
|
||||||
@@ -708,6 +708,7 @@ void TSubModel::DisplayLists()
|
|||||||
if (Next)
|
if (Next)
|
||||||
Next->DisplayLists();
|
Next->DisplayLists();
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
void TSubModel::InitialRotate(bool doit)
|
void TSubModel::InitialRotate(bool doit)
|
||||||
{ // konwersja układu współrzędnych na zgodny ze scenerią
|
{ // konwersja układu współrzędnych na zgodny ze scenerią
|
||||||
@@ -986,11 +987,6 @@ void TSubModel::RaAnimation(TAnimType a)
|
|||||||
break;
|
break;
|
||||||
case at_Billboard: // obrót w pionie do kamery
|
case at_Billboard: // obrót w pionie do kamery
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
matrix4x4 mat; // potrzebujemy współrzędne przesunięcia środka układu
|
|
||||||
// współrzędnych submodelu
|
|
||||||
glGetDoublev(GL_MODELVIEW_MATRIX, mat.getArray()); // pobranie aktualnej matrycy
|
|
||||||
*/
|
|
||||||
matrix4x4 mat; mat.OpenGL_Matrix( OpenGLMatrices.data_array( GL_MODELVIEW ) );
|
matrix4x4 mat; mat.OpenGL_Matrix( OpenGLMatrices.data_array( GL_MODELVIEW ) );
|
||||||
float3 gdzie = float3(mat[3][0], mat[3][1], mat[3][2]); // początek układu współrzędnych submodelu względem kamery
|
float3 gdzie = float3(mat[3][0], mat[3][1], mat[3][2]); // początek układu współrzędnych submodelu względem kamery
|
||||||
glLoadIdentity(); // macierz jedynkowa
|
glLoadIdentity(); // macierz jedynkowa
|
||||||
@@ -1090,6 +1086,7 @@ void TSubModel::ColorsSet(int *a, int *d, int *s)
|
|||||||
for (i = 0; i < 4; ++i)
|
for (i = 0; i < 4; ++i)
|
||||||
f4Specular[i] = s[i] / 255.0;
|
f4Specular[i] = s[i] / 255.0;
|
||||||
};
|
};
|
||||||
|
|
||||||
void TSubModel::ParentMatrix(float4x4 *m)
|
void TSubModel::ParentMatrix(float4x4 *m)
|
||||||
{ // pobranie transformacji względem wstawienia modelu
|
{ // pobranie transformacji względem wstawienia modelu
|
||||||
// jeśli nie zostało wykonane Init() (tzn. zaraz po wczytaniu T3D), to
|
// jeśli nie zostało wykonane Init() (tzn. zaraz po wczytaniu T3D), to
|
||||||
@@ -1107,68 +1104,41 @@ void TSubModel::ParentMatrix(float4x4 *m)
|
|||||||
// dla ostatniego może być potrzebny dodatkowy obrót, jeśli wczytano z T3D, a
|
// dla ostatniego może być potrzebny dodatkowy obrót, jeśli wczytano z T3D, a
|
||||||
// nie obrócono jeszcze
|
// nie obrócono jeszcze
|
||||||
};
|
};
|
||||||
float TSubModel::MaxY(const float4x4 &m)
|
|
||||||
{ // obliczenie maksymalnej wysokości,
|
|
||||||
// na początek ślizgu w pantografie
|
|
||||||
if (eType != 4)
|
|
||||||
return 0; // tylko dla trójkątów liczymy
|
|
||||||
if (iNumVerts < 1)
|
|
||||||
return 0;
|
|
||||||
/*
|
|
||||||
if (!Vertices)
|
|
||||||
return 0;
|
|
||||||
float y,
|
|
||||||
my = m[0][1] * Vertices[0].Point.x + m[1][1] * Vertices[0].Point.y +
|
|
||||||
m[2][1] * Vertices[0].Point.z + m[3][1];
|
|
||||||
for (int i = 1; i < iNumVerts; ++i)
|
|
||||||
{
|
|
||||||
y = m[0][1] * Vertices[i].Point.x + m[1][1] * Vertices[i].Point.y +
|
|
||||||
m[2][1] * Vertices[i].Point.z + m[3][1];
|
|
||||||
if (my < y)
|
|
||||||
my = y;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
float my =
|
|
||||||
m[ 0 ][ 1 ] * Vertices[ 0 ].position.x
|
|
||||||
+ m[ 1 ][ 1 ] * Vertices[ 0 ].position.y
|
|
||||||
+ m[ 2 ][ 1 ] * Vertices[ 0 ].position.z
|
|
||||||
+ m[ 3 ][ 1 ];
|
|
||||||
float y;
|
|
||||||
for( int i = 1; i < iNumVerts; ++i ) {
|
|
||||||
y =
|
|
||||||
m[ 0 ][ 1 ] * Vertices[ i ].position.x
|
|
||||||
+ m[ 1 ][ 1 ] * Vertices[ i ].position.y
|
|
||||||
+ m[ 2 ][ 1 ] * Vertices[ i ].position.z
|
|
||||||
+ m[ 3 ][ 1 ];
|
|
||||||
|
|
||||||
if( my < y ) { my = y; }
|
float TSubModel::MaxY( float4x4 const &m )
|
||||||
|
{ // obliczenie maksymalnej wysokości, na początek ślizgu w pantografie
|
||||||
|
if( eType != 4 ) {
|
||||||
|
// tylko dla trójkątów liczymy
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return my;
|
if( m_geometry == NULL ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto maxy { 0.0f };
|
||||||
|
for( auto const &vertex : GfxRenderer.Vertices( m_geometry ) ) {
|
||||||
|
|
||||||
|
maxy = std::max(
|
||||||
|
maxy,
|
||||||
|
m[ 0 ][ 1 ] * vertex.position.x
|
||||||
|
+ m[ 1 ][ 1 ] * vertex.position.y
|
||||||
|
+ m[ 2 ][ 1 ] * vertex.position.z
|
||||||
|
+ m[ 3 ][ 1 ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxy;
|
||||||
};
|
};
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
TModel3d::TModel3d()
|
TModel3d::TModel3d()
|
||||||
{
|
{
|
||||||
// Materials=NULL;
|
|
||||||
// MaterialsCount=0;
|
|
||||||
Root = NULL;
|
Root = NULL;
|
||||||
iFlags = 0;
|
iFlags = 0;
|
||||||
iSubModelsCount = 0;
|
iSubModelsCount = 0;
|
||||||
iModel = NULL; // tylko jak wczytany model binarny
|
iModel = NULL; // tylko jak wczytany model binarny
|
||||||
iNumVerts = 0; // nie ma jeszcze wierzchołków
|
iNumVerts = 0; // nie ma jeszcze wierzchołków
|
||||||
};
|
};
|
||||||
/*
|
|
||||||
TModel3d::TModel3d(char *FileName)
|
|
||||||
{
|
|
||||||
// Root=NULL;
|
|
||||||
// Materials=NULL;
|
|
||||||
// MaterialsCount=0;
|
|
||||||
Root=NULL;
|
|
||||||
SubModelsCount=0;
|
|
||||||
iFlags=0;
|
|
||||||
LoadFromFile(FileName);
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
TModel3d::~TModel3d()
|
TModel3d::~TModel3d()
|
||||||
{
|
{
|
||||||
// SafeDeleteArray(Materials);
|
// SafeDeleteArray(Materials);
|
||||||
@@ -1227,18 +1197,6 @@ TSubModel *TModel3d::GetFromName(const char *sName)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
TMaterial* TModel3d::GetMaterialFromName(char *sName)
|
|
||||||
{
|
|
||||||
AnsiString tmp=AnsiString(sName).Trim();
|
|
||||||
for (int i=0; i<MaterialsCount; i++)
|
|
||||||
if (strcmp(sName,Materials[i].Name.c_str())==0)
|
|
||||||
// if (Trim()==Materials[i].Name.tmp)
|
|
||||||
return Materials+i;
|
|
||||||
return Materials;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool TModel3d::LoadFromFile(std::string const &FileName, bool dynamic)
|
bool TModel3d::LoadFromFile(std::string const &FileName, bool dynamic)
|
||||||
{
|
{
|
||||||
// wczytanie modelu z pliku
|
// wczytanie modelu z pliku
|
||||||
@@ -1503,6 +1461,9 @@ void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
|
|||||||
#endif
|
#endif
|
||||||
Root = nullptr;
|
Root = nullptr;
|
||||||
float4x4 *tm = nullptr;
|
float4x4 *tm = nullptr;
|
||||||
|
if( m_geometrybank == NULL ) {
|
||||||
|
m_geometrybank = GfxRenderer.Create_Bank();
|
||||||
|
}
|
||||||
|
|
||||||
std::streampos end = s.tellg() + (std::streampos)size;
|
std::streampos end = s.tellg() + (std::streampos)size;
|
||||||
|
|
||||||
@@ -1536,7 +1497,6 @@ void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
|
|||||||
if( false == m_pVNT.empty() )
|
if( false == m_pVNT.empty() )
|
||||||
#endif
|
#endif
|
||||||
throw std::runtime_error("e3d: duplicated VNT chunk");
|
throw std::runtime_error("e3d: duplicated VNT chunk");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
size_t vt_cnt = size / 32;
|
size_t vt_cnt = size / 32;
|
||||||
iNumVerts = (int)vt_cnt;
|
iNumVerts = (int)vt_cnt;
|
||||||
@@ -1550,22 +1510,21 @@ void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
|
|||||||
for (size_t i = 0; i < vt_cnt; i++)
|
for (size_t i = 0; i < vt_cnt; i++)
|
||||||
m_pVNT[i].deserialize(s);
|
m_pVNT[i].deserialize(s);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// we rely on the SUB chunk coming before the vertex data, and on the overall vertex count matching the size of data in the chunk
|
// we rely on the SUB chunk coming before the vertex data, and on the overall vertex count matching the size of data in the chunk
|
||||||
// geometry associated with chunks isn't stored in the order the actual chunks are listed, so we need to sort that out first
|
// geometry associated with chunks isn't stored in the same order as the chunks themselves, so we need to sort that out first
|
||||||
std::vector< std::pair<int, int> > submodeloffsets;
|
std::vector< std::pair<int, int> > submodeloffsets;
|
||||||
submodeloffsets.reserve( iSubModelsCount );
|
submodeloffsets.reserve( iSubModelsCount );
|
||||||
for( int idx = 0; idx < iSubModelsCount; ++idx ) {
|
for( int submodelindex = 0; submodelindex < iSubModelsCount; ++submodelindex ) {
|
||||||
auto &submodel = Root[ idx ];
|
auto const &submodel = Root[ submodelindex ];
|
||||||
if( submodel.iNumVerts <= 0 ) { continue; }
|
if( submodel.iNumVerts <= 0 ) { continue; }
|
||||||
submodeloffsets.emplace_back( submodel.tVboPtr, idx );
|
submodeloffsets.emplace_back( submodel.tVboPtr, submodelindex );
|
||||||
}
|
}
|
||||||
std::sort(
|
std::sort(
|
||||||
submodeloffsets.begin(),
|
submodeloffsets.begin(),
|
||||||
submodeloffsets.end(),
|
submodeloffsets.end(),
|
||||||
[]( std::pair<int, int> const &Left, std::pair<int, int> const &Right ) {
|
[]( std::pair<int, int> const &Left, std::pair<int, int> const &Right ) {
|
||||||
return (Left.first) < (Right.first); } );
|
return (Left.first) < (Right.first); } );
|
||||||
// once sorted we can grab geometry for the chunks as they come
|
// once sorted we can grab geometry as it comes, and assign it to the chunks it belongs to
|
||||||
for( auto const &submodeloffset : submodeloffsets ) {
|
for( auto const &submodeloffset : submodeloffsets ) {
|
||||||
auto &submodel = Root[ submodeloffset.second ];
|
auto &submodel = Root[ submodeloffset.second ];
|
||||||
vertex_array vertices; vertices.resize( submodel.iNumVerts );
|
vertex_array vertices; vertices.resize( submodel.iNumVerts );
|
||||||
@@ -1584,7 +1543,7 @@ void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
submodel.m_chunk = m_geometry->create( vertices, type );
|
submodel.m_geometry = GfxRenderer.Insert( vertices, m_geometrybank, type );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1639,12 +1598,7 @@ void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
|
|||||||
for (size_t i = 0; (int)i < iSubModelsCount; ++i)
|
for (size_t i = 0; (int)i < iSubModelsCount; ++i)
|
||||||
{
|
{
|
||||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
||||||
Root[i].BinInit(
|
Root[i].BinInit( Root, tm, &Textures, &Names, dynamic );
|
||||||
Root, tm,
|
|
||||||
( Root[i].m_chunk ?
|
|
||||||
&m_geometry->data(Root[i].m_chunk)[0] :
|
|
||||||
nullptr ),
|
|
||||||
&Textures, &Names, dynamic);
|
|
||||||
#else
|
#else
|
||||||
Root[ i ].BinInit( Root, tm, (float8*)m_pVNT.data(), &Textures, &Names, dynamic );
|
Root[ i ].BinInit( Root, tm, (float8*)m_pVNT.data(), &Textures, &Names, dynamic );
|
||||||
#endif
|
#endif
|
||||||
@@ -1656,8 +1610,7 @@ void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TSubModel::BinInit(TSubModel *s, float4x4 *m, basic_vertex *v,
|
void TSubModel::BinInit(TSubModel *s, float4x4 *m, std::vector<std::string> *t, std::vector<std::string> *n, bool dynamic)
|
||||||
std::vector<std::string> *t, std::vector<std::string> *n, bool dynamic)
|
|
||||||
{ // ustawienie wskaźników w submodelu
|
{ // ustawienie wskaźników w submodelu
|
||||||
//m7todo: brzydko
|
//m7todo: brzydko
|
||||||
iVisible = 1; // tymczasowo używane
|
iVisible = 1; // tymczasowo używane
|
||||||
@@ -1720,7 +1673,6 @@ void TSubModel::BinInit(TSubModel *s, float4x4 *m, basic_vertex *v,
|
|||||||
iFlags &= ~0x0200; // wczytano z pliku binarnego (nie jest właścicielem tablic)
|
iFlags &= ~0x0200; // wczytano z pliku binarnego (nie jest właścicielem tablic)
|
||||||
|
|
||||||
iVboPtr = tVboPtr;
|
iVboPtr = tVboPtr;
|
||||||
Vertices = v;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void TModel3d::LoadFromBinFile(std::string const &FileName, bool dynamic)
|
void TModel3d::LoadFromBinFile(std::string const &FileName, bool dynamic)
|
||||||
@@ -1812,15 +1764,9 @@ void TModel3d::Init()
|
|||||||
SaveToBinFile(asBinary.c_str()); // utworzy tablicę (m_pVNT)
|
SaveToBinFile(asBinary.c_str()); // utworzy tablicę (m_pVNT)
|
||||||
asBinary = ""; // zablokowanie powtórnego zapisu
|
asBinary = ""; // zablokowanie powtórnego zapisu
|
||||||
}
|
}
|
||||||
if (iNumVerts)
|
#ifdef EU07_USE_OLD_DRAW_CODE
|
||||||
|
if (iNumVerts)
|
||||||
{
|
{
|
||||||
/* // NOTE: we will be applying distance factor dynamically during render,
|
|
||||||
// so we're leaving the defined ranges intact
|
|
||||||
if (Global::fDistanceFactor !=
|
|
||||||
1.0) // trochę zaoszczędzi czasu na modelach z wieloma submocelami
|
|
||||||
Root->AdjustDist(); // aktualizacja odległości faz LoD, zależnie od
|
|
||||||
// rozdzielczości pionowej oraz multisamplingu
|
|
||||||
*/
|
|
||||||
if (Global::bUseVBO)
|
if (Global::bUseVBO)
|
||||||
{
|
{
|
||||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
||||||
@@ -1844,10 +1790,9 @@ void TModel3d::Init()
|
|||||||
{ // przygotowanie skompilowanych siatek dla DisplayLists
|
{ // przygotowanie skompilowanych siatek dla DisplayLists
|
||||||
Root->DisplayLists(); // tworzenie skompilowanej listy dla submodelu
|
Root->DisplayLists(); // tworzenie skompilowanej listy dla submodelu
|
||||||
}
|
}
|
||||||
// if (Root->TextureID) //o ile ma teksturę
|
|
||||||
// Root->iFlags|=0x80; //konieczność ustawienia tekstury
|
|
||||||
}
|
}
|
||||||
}
|
#endif
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void TModel3d::BreakHierarhy()
|
void TModel3d::BreakHierarhy()
|
||||||
|
|||||||
21
Model3d.h
21
Model3d.h
@@ -112,8 +112,8 @@ private:
|
|||||||
TSubModel *Next;
|
TSubModel *Next;
|
||||||
TSubModel *Child;
|
TSubModel *Child;
|
||||||
intptr_t iVboPtr;
|
intptr_t iVboPtr;
|
||||||
geometrychunk_handle m_chunk; // geometry of the submodel
|
geometry_handle m_geometry; // geometry of the submodel
|
||||||
texture_manager::size_type TextureID; // numer tekstury, -1 wymienna, 0 brak
|
texture_handle TextureID; // numer tekstury, -1 wymienna, 0 brak
|
||||||
bool bWire; // nie używane, ale wczytywane
|
bool bWire; // nie używane, ale wczytywane
|
||||||
// short TexAlpha; //Ra: nie używane już
|
// short TexAlpha; //Ra: nie używane już
|
||||||
GLuint uiDisplayList; // roboczy numer listy wyświetlania
|
GLuint uiDisplayList; // roboczy numer listy wyświetlania
|
||||||
@@ -142,7 +142,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 const *ReplacableSkinId;
|
static texture_handle 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;
|
||||||
@@ -155,7 +155,7 @@ public:
|
|||||||
void NextAdd(TSubModel *SubModel);
|
void NextAdd(TSubModel *SubModel);
|
||||||
TSubModel * NextGet() { return Next; };
|
TSubModel * NextGet() { return Next; };
|
||||||
TSubModel * ChildGet() { return Child; };
|
TSubModel * ChildGet() { return Child; };
|
||||||
int TriangleAdd(TModel3d *m, texture_manager::size_type tex, int tri);
|
int TriangleAdd(TModel3d *m, texture_handle tex, int tri);
|
||||||
basic_vertex * TrianglePtr(int tex, int pos, int *la, int *ld, int *ls);
|
basic_vertex * TrianglePtr(int tex, int pos, int *la, int *ld, int *ls);
|
||||||
void SetRotate(float3 vNewRotateAxis, float fNewAngle);
|
void SetRotate(float3 vNewRotateAxis, float fNewAngle);
|
||||||
void SetRotateXYZ(vector3 vNewAngles);
|
void SetRotateXYZ(vector3 vNewAngles);
|
||||||
@@ -175,16 +175,17 @@ public:
|
|||||||
iFlags |= 0x4000;
|
iFlags |= 0x4000;
|
||||||
};
|
};
|
||||||
void InitialRotate(bool doit);
|
void InitialRotate(bool doit);
|
||||||
|
#ifdef EU07_USE_OLD_DRAW_CODE
|
||||||
void DisplayLists();
|
void DisplayLists();
|
||||||
void BinInit(TSubModel *s, float4x4 *m, basic_vertex *v,
|
#endif
|
||||||
std::vector<std::string> *t, std::vector<std::string> *n, bool dynamic);
|
void BinInit(TSubModel *s, float4x4 *m, std::vector<std::string> *t, std::vector<std::string> *n, bool dynamic);
|
||||||
void ReplacableSet(texture_manager::size_type const *r, int a)
|
void ReplacableSet(texture_handle const *r, int a)
|
||||||
{
|
{
|
||||||
ReplacableSkinId = r;
|
ReplacableSkinId = r;
|
||||||
iAlpha = a;
|
iAlpha = a;
|
||||||
};
|
};
|
||||||
void TextureNameSet(const char *n);
|
void TextureNameSet( std::string const &Name );
|
||||||
void NameSet(const char *n);
|
void NameSet( std::string const &Name );
|
||||||
// Ra: funkcje do budowania terenu z E3D
|
// Ra: funkcje do budowania terenu z E3D
|
||||||
int Flags() { return iFlags; };
|
int Flags() { return iFlags; };
|
||||||
void UnFlagNext() { iFlags &= 0x00FFFFFF; };
|
void UnFlagNext() { iFlags &= 0x00FFFFFF; };
|
||||||
@@ -202,7 +203,7 @@ public:
|
|||||||
return TextureID;
|
return TextureID;
|
||||||
}
|
}
|
||||||
void ParentMatrix(float4x4 *m);
|
void ParentMatrix(float4x4 *m);
|
||||||
float MaxY(const float4x4 &m);
|
float MaxY( float4x4 const &m );
|
||||||
void AdjustDist();
|
void AdjustDist();
|
||||||
|
|
||||||
void deserialize(std::istream&);
|
void deserialize(std::istream&);
|
||||||
|
|||||||
8
Names.h
8
Names.h
@@ -12,7 +12,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
template <typename _Type>
|
template <typename Type_>
|
||||||
class TNames {
|
class TNames {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -26,7 +26,7 @@ public:
|
|||||||
// methods:
|
// methods:
|
||||||
// dodanie obiektu z wskaźnikiem. updates data field if the object already exists. returns true for insertion, false for update
|
// dodanie obiektu z wskaźnikiem. updates data field if the object already exists. returns true for insertion, false for update
|
||||||
bool
|
bool
|
||||||
Add( int const Type, std::string const &Name, _Type Data ) {
|
Add( int const Type, std::string const &Name, Type_ Data ) {
|
||||||
|
|
||||||
auto lookup = find_map( Type ).emplace( Name, Data );
|
auto lookup = find_map( Type ).emplace( Name, Data );
|
||||||
if( lookup.second == false ) {
|
if( lookup.second == false ) {
|
||||||
@@ -40,7 +40,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// returns pointer associated with provided label, or nullptr if there's no match
|
// returns pointer associated with provided label, or nullptr if there's no match
|
||||||
_Type
|
Type_
|
||||||
Find( int const Type, std::string const &Name ) {
|
Find( int const Type, std::string const &Name ) {
|
||||||
|
|
||||||
auto const &map = find_map( Type );
|
auto const &map = find_map( Type );
|
||||||
@@ -51,7 +51,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// types:
|
// types:
|
||||||
typedef std::unordered_map<std::string, _Type> type_map;
|
typedef std::unordered_map<std::string, Type_> type_map;
|
||||||
typedef std::unordered_map<int, type_map> typemap_map;
|
typedef std::unordered_map<int, type_map> typemap_map;
|
||||||
|
|
||||||
// methods:
|
// methods:
|
||||||
|
|||||||
32
Texture.cpp
32
Texture.cpp
@@ -692,13 +692,9 @@ opengl_texture::downsize( GLuint const Format ) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
texture_manager::Init() {
|
|
||||||
}
|
|
||||||
|
|
||||||
// ustalenie numeru tekstury, wczytanie jeśli jeszcze takiej nie było
|
// ustalenie numeru tekstury, wczytanie jeśli jeszcze takiej nie było
|
||||||
texture_manager::size_type
|
texture_handle
|
||||||
texture_manager::GetTextureId( std::string Filename, std::string const &Dir, int const Filter, bool const Loadnow ) {
|
texture_manager::create( std::string Filename, std::string const &Dir, int const Filter, bool const Loadnow ) {
|
||||||
|
|
||||||
if( Filename.find( '|' ) != std::string::npos )
|
if( Filename.find( '|' ) != std::string::npos )
|
||||||
Filename.erase( Filename.find( '|' ) ); // po | może być nazwa kolejnej tekstury
|
Filename.erase( Filename.find( '|' ) ); // po | może być nazwa kolejnej tekstury
|
||||||
@@ -788,7 +784,7 @@ texture_manager::GetTextureId( std::string Filename, std::string const &Dir, int
|
|||||||
traits += '#';
|
traits += '#';
|
||||||
}
|
}
|
||||||
texture.traits = traits;
|
texture.traits = traits;
|
||||||
auto const textureindex = (texture_manager::size_type)m_textures.size();
|
auto const textureindex = (texture_handle)m_textures.size();
|
||||||
m_textures.emplace_back( texture );
|
m_textures.emplace_back( texture );
|
||||||
m_texturemappings.emplace( filename, textureindex );
|
m_texturemappings.emplace( filename, textureindex );
|
||||||
|
|
||||||
@@ -796,9 +792,9 @@ texture_manager::GetTextureId( std::string Filename, std::string const &Dir, int
|
|||||||
|
|
||||||
if( true == Loadnow ) {
|
if( true == Loadnow ) {
|
||||||
|
|
||||||
Texture( textureindex ).load();
|
texture_manager::texture( textureindex ).load();
|
||||||
#ifndef EU07_DEFERRED_TEXTURE_UPLOAD
|
#ifndef EU07_DEFERRED_TEXTURE_UPLOAD
|
||||||
Texture( textureindex ).create();
|
texture_manager::texture( textureindex ).create();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -806,7 +802,7 @@ texture_manager::GetTextureId( std::string Filename, std::string const &Dir, int
|
|||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
texture_manager::Bind( texture_manager::size_type const Id ) {
|
texture_manager::bind( texture_handle const Texture ) {
|
||||||
/*
|
/*
|
||||||
// NOTE: this optimization disabled for the time being, until the render code is reviewed
|
// NOTE: this optimization disabled for the time being, until the render code is reviewed
|
||||||
// having it active would lead to some terrain and spline chunks receiving wrong
|
// having it active would lead to some terrain and spline chunks receiving wrong
|
||||||
@@ -818,11 +814,11 @@ texture_manager::Bind( texture_manager::size_type const Id ) {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
// TODO: do binding in texture object, add support for other types
|
// TODO: do binding in texture object, add support for other types
|
||||||
if( Id != 0 ) {
|
if( Texture != 0 ) {
|
||||||
#ifndef EU07_DEFERRED_TEXTURE_UPLOAD
|
#ifndef EU07_DEFERRED_TEXTURE_UPLOAD
|
||||||
// NOTE: we could bind dedicated 'error' texture here if the id isn't valid
|
// NOTE: we could bind dedicated 'error' texture here if the id isn't valid
|
||||||
::glBindTexture( GL_TEXTURE_2D, Texture(Id).id );
|
::glBindTexture( GL_TEXTURE_2D, texture(Texture).id );
|
||||||
m_activetexture = Texture(Id).id;
|
m_activetexture = texture(Texture).id;
|
||||||
#else
|
#else
|
||||||
if( Texture( Id ).bind() == resource_state::good ) {
|
if( Texture( Id ).bind() == resource_state::good ) {
|
||||||
m_activetexture = Id;
|
m_activetexture = Id;
|
||||||
@@ -842,7 +838,7 @@ texture_manager::Bind( texture_manager::size_type const Id ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
texture_manager::Free() {
|
texture_manager::delete_textures() {
|
||||||
for( auto const &texture : m_textures ) {
|
for( auto const &texture : m_textures ) {
|
||||||
// usunięcie wszyskich tekstur (bez usuwania struktury)
|
// usunięcie wszyskich tekstur (bez usuwania struktury)
|
||||||
if( ( texture.id > 0 )
|
if( ( texture.id > 0 )
|
||||||
@@ -854,7 +850,7 @@ texture_manager::Free() {
|
|||||||
|
|
||||||
// debug performance string
|
// debug performance string
|
||||||
std::string
|
std::string
|
||||||
texture_manager::Info() const {
|
texture_manager::info() const {
|
||||||
|
|
||||||
// TODO: cache this data and update only during resource sweep
|
// TODO: cache this data and update only during resource sweep
|
||||||
std::size_t totaltexturecount{ m_textures.size() - 1 };
|
std::size_t totaltexturecount{ m_textures.size() - 1 };
|
||||||
@@ -892,8 +888,8 @@ texture_manager::Info() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// checks whether specified texture is in the texture bank. returns texture id, or npos.
|
// checks whether specified texture is in the texture bank. returns texture id, or npos.
|
||||||
texture_manager::size_type
|
texture_handle
|
||||||
texture_manager::find_in_databank( std::string const &Texturename ) {
|
texture_manager::find_in_databank( std::string const &Texturename ) const {
|
||||||
|
|
||||||
auto lookup = m_texturemappings.find( Texturename );
|
auto lookup = m_texturemappings.find( Texturename );
|
||||||
if( lookup != m_texturemappings.end() ) {
|
if( lookup != m_texturemappings.end() ) {
|
||||||
@@ -910,7 +906,7 @@ texture_manager::find_in_databank( std::string const &Texturename ) {
|
|||||||
|
|
||||||
// checks whether specified file exists.
|
// checks whether specified file exists.
|
||||||
std::string
|
std::string
|
||||||
texture_manager::find_on_disk( std::string const &Texturename ) {
|
texture_manager::find_on_disk( std::string const &Texturename ) const {
|
||||||
|
|
||||||
{
|
{
|
||||||
std::ifstream file( Texturename );
|
std::ifstream file( Texturename );
|
||||||
|
|||||||
68
Texture.h
68
Texture.h
@@ -62,7 +62,7 @@ private:
|
|||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::size_t texture_handle;
|
typedef int texture_handle;
|
||||||
|
|
||||||
class texture_manager {
|
class texture_manager {
|
||||||
|
|
||||||
@@ -70,68 +70,52 @@ private:
|
|||||||
typedef std::vector<opengl_texture> opengltexture_array;
|
typedef std::vector<opengl_texture> opengltexture_array;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// typedef opengltexture_array::size_type size_type;
|
|
||||||
typedef int size_type;
|
|
||||||
|
|
||||||
texture_manager();
|
texture_manager();
|
||||||
~texture_manager() { Free(); }
|
~texture_manager() { delete_textures(); }
|
||||||
|
|
||||||
size_type
|
texture_handle
|
||||||
GetTextureId( std::string Filename, std::string const &Dir, int const Filter = -1, bool const Loadnow = true );
|
create( std::string Filename, std::string const &Dir, int const Filter = -1, bool const Loadnow = true );
|
||||||
void
|
void
|
||||||
Bind( size_type const Id );
|
bind( texture_handle const Texture );
|
||||||
opengl_texture &
|
opengl_texture &
|
||||||
Texture( size_type const Id ) { return m_textures[ Id ]; }
|
texture( texture_handle const Texture ) { return m_textures[ Texture ]; }
|
||||||
void
|
|
||||||
Init();
|
|
||||||
void
|
|
||||||
Free();
|
|
||||||
// debug performance string
|
// debug performance string
|
||||||
std::string
|
std::string
|
||||||
Info() const;
|
info() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::unordered_map<std::string, size_type> index_map;
|
typedef std::unordered_map<std::string, std::size_t> index_map;
|
||||||
/*
|
|
||||||
opengltexture_array::size_type LoadFromFile(std::string name, int filter = -1);
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
bool LoadBMP( std::string const &fileName);
|
|
||||||
bool LoadTEX( std::string fileName );
|
|
||||||
bool LoadTGA( std::string fileName, int filter = -1 );
|
|
||||||
bool LoadDDS( std::string fileName, int filter = -1 );
|
|
||||||
*/
|
|
||||||
// checks whether specified texture is in the texture bank. returns texture id, or npos.
|
// checks whether specified texture is in the texture bank. returns texture id, or npos.
|
||||||
size_type find_in_databank( std::string const &Texturename );
|
texture_handle
|
||||||
|
find_in_databank( std::string const &Texturename ) const;
|
||||||
// checks whether specified file exists. returns name of the located file, or empty string.
|
// checks whether specified file exists. returns name of the located file, or empty string.
|
||||||
std::string find_on_disk( std::string const &Texturename );
|
std::string
|
||||||
/*
|
find_on_disk( std::string const &Texturename ) const;
|
||||||
void SetFiltering(int filter);
|
void
|
||||||
void SetFiltering(bool alpha, bool hash);
|
delete_textures();
|
||||||
GLuint CreateTexture(GLubyte *buff, GLint bpp, int width, int height, bool bHasAlpha,
|
|
||||||
bool bHash, bool bDollar = true, int filter = -1);
|
static const texture_handle npos{ 0 }; // should be -1, but the rest of the code uses -1 for something else
|
||||||
*/
|
|
||||||
static const size_type npos{ 0 }; // should be -1, but the rest of the code uses -1 for something else
|
|
||||||
opengltexture_array m_textures;
|
opengltexture_array m_textures;
|
||||||
index_map m_texturemappings;
|
index_map m_texturemappings;
|
||||||
size_type m_activetexture{ 0 }; // last i.e. currently bound texture
|
texture_handle m_activetexture{ 0 }; // last i.e. currently bound texture
|
||||||
};
|
};
|
||||||
|
|
||||||
// reduces provided data image to half of original size, using basic 2x2 average
|
// reduces provided data image to half of original size, using basic 2x2 average
|
||||||
template <typename _Colortype>
|
template <typename Colortype_>
|
||||||
void
|
void
|
||||||
downsample( std::size_t const Width, std::size_t const Height, char *Imagedata ) {
|
downsample( std::size_t const Width, std::size_t const Height, char *Imagedata ) {
|
||||||
|
|
||||||
_Colortype *destination = reinterpret_cast<_Colortype*>( Imagedata );
|
Colortype_ *destination = reinterpret_cast<Colortype_*>( Imagedata );
|
||||||
_Colortype *sampler = reinterpret_cast<_Colortype*>( Imagedata );
|
Colortype_ *sampler = reinterpret_cast<Colortype_*>( Imagedata );
|
||||||
|
|
||||||
_Colortype accumulator, color;
|
Colortype_ accumulator, color;
|
||||||
/*
|
/*
|
||||||
_Colortype color;
|
_Colortype color;
|
||||||
float component;
|
float component;
|
||||||
*/
|
*/
|
||||||
for( size_t row = 0; row < Height; row += 2, sampler += Width ) { // column movement advances us down another row
|
for( std::size_t row = 0; row < Height; row += 2, sampler += Width ) { // column movement advances us down another row
|
||||||
for( size_t column = 0; column < Width; column += 2, sampler += 2 ) {
|
for( std::size_t column = 0; column < Width; column += 2, sampler += 2 ) {
|
||||||
/*
|
/*
|
||||||
// straightforward, but won't work with byte data
|
// straightforward, but won't work with byte data
|
||||||
auto color = (
|
auto color = (
|
||||||
@@ -158,8 +142,8 @@ downsample( std::size_t const Width, std::size_t const Height, char *Imagedata )
|
|||||||
*destination++ = color;
|
*destination++ = color;
|
||||||
/*
|
/*
|
||||||
// "full" 8bit resolution
|
// "full" 8bit resolution
|
||||||
color = _Colortype(); component = 0;
|
color = Colortype_(); component = 0;
|
||||||
for( int idx = 0; idx < sizeof( _Colortype ); ++idx ) {
|
for( int idx = 0; idx < sizeof( Colortype_ ); ++idx ) {
|
||||||
|
|
||||||
component = (
|
component = (
|
||||||
(*sampler)[idx]
|
(*sampler)[idx]
|
||||||
|
|||||||
4
Track.h
4
Track.h
@@ -133,8 +133,8 @@ class TTrack : public Resource
|
|||||||
TTrack *trNext = nullptr; // odcinek od strony punktu 2 - to powinno być w segmencie
|
TTrack *trNext = nullptr; // odcinek od strony punktu 2 - to powinno być w segmencie
|
||||||
TTrack *trPrev = nullptr; // odcinek od strony punktu 1
|
TTrack *trPrev = nullptr; // odcinek od strony punktu 1
|
||||||
// McZapkie-070402: dodalem zmienne opisujace rozmiary tekstur
|
// McZapkie-070402: dodalem zmienne opisujace rozmiary tekstur
|
||||||
texture_manager::size_type TextureID1 = 0; // tekstura szyn albo nawierzchni
|
texture_handle TextureID1 = 0; // tekstura szyn albo nawierzchni
|
||||||
texture_manager::size_type TextureID2 = 0; // tekstura automatycznej podsypki albo pobocza
|
texture_handle TextureID2 = 0; // tekstura automatycznej podsypki albo pobocza
|
||||||
float fTexLength = 4.0f; // długość powtarzania tekstury w metrach
|
float fTexLength = 4.0f; // długość powtarzania tekstury w metrach
|
||||||
float fTexRatio1 = 1.0f; // proporcja boków tekstury nawierzchni (żeby zaoszczędzić na rozmiarach tekstur...)
|
float fTexRatio1 = 1.0f; // proporcja boków tekstury nawierzchni (żeby zaoszczędzić na rozmiarach tekstur...)
|
||||||
float fTexRatio2 = 1.0f; // proporcja boków tekstury chodnika (żeby zaoszczędzić na rozmiarach tekstur...)
|
float fTexRatio2 = 1.0f; // proporcja boków tekstury chodnika (żeby zaoszczędzić na rozmiarach tekstur...)
|
||||||
|
|||||||
625
Traction.cpp
625
Traction.cpp
@@ -18,7 +18,6 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "logs.h"
|
#include "logs.h"
|
||||||
#include "mctools.h"
|
#include "mctools.h"
|
||||||
#include "TractionPower.h"
|
#include "TractionPower.h"
|
||||||
#include "renderer.h"
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
/*
|
/*
|
||||||
@@ -91,274 +90,32 @@ jawnie nazwę sekcji, ewentualnie nazwę zasilacza (zostanie zastąpiona wskazan
|
|||||||
sekcji z sąsiedniego przęsła).
|
sekcji z sąsiedniego przęsła).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TTraction::TTraction()
|
std::size_t
|
||||||
{
|
TTraction::create_geometry( geometrybank_handle const &Bank, Math3D::vector3 const &Origin ) {
|
||||||
hvNext[ 0 ] = nullptr;
|
|
||||||
hvNext[ 1 ] = nullptr;
|
|
||||||
psPower[ 0 ] = nullptr;
|
|
||||||
psPower[ 1 ] = nullptr; // na początku zasilanie nie podłączone
|
|
||||||
iNext[ 0 ] = 0;
|
|
||||||
iNext[ 1 ] = 0;
|
|
||||||
fResistance[ 0 ] = -1.0;
|
|
||||||
fResistance[ 1 ] = -1.0; // trzeba dopiero policzyć
|
|
||||||
}
|
|
||||||
|
|
||||||
TTraction::~TTraction()
|
if( m_geometry != NULL ) {
|
||||||
{
|
return GfxRenderer.Vertices( m_geometry ).size() / 2;
|
||||||
if (!Global::bUseVBO)
|
|
||||||
glDeleteLists(uiDisplayList, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TTraction::Optimize( Math3D::vector3 const &Origin )
|
|
||||||
{
|
|
||||||
if (Global::bUseVBO)
|
|
||||||
return;
|
|
||||||
uiDisplayList = glGenLists(1);
|
|
||||||
glNewList(uiDisplayList, GL_COMPILE);
|
|
||||||
|
|
||||||
if (Wires != 0)
|
|
||||||
{
|
|
||||||
// Dlugosc odcinka trakcji 'Winger
|
|
||||||
double ddp = std::hypot(pPoint2.x - pPoint1.x, pPoint2.z - pPoint1.z);
|
|
||||||
if (Wires == 2)
|
|
||||||
WireOffset = 0;
|
|
||||||
// Przewoz jezdny 1 'Marcin
|
|
||||||
glBegin(GL_LINE_STRIP);
|
|
||||||
glVertex3f(
|
|
||||||
pPoint1.x - (pPoint2.z / ddp - pPoint1.z / ddp) * WireOffset - Origin.x,
|
|
||||||
pPoint1.y - Origin.y,
|
|
||||||
pPoint1.z - (-pPoint2.x / ddp + pPoint1.x / ddp) * WireOffset - Origin.z);
|
|
||||||
glVertex3f(
|
|
||||||
pPoint2.x - (pPoint2.z / ddp - pPoint1.z / ddp) * WireOffset - Origin.x,
|
|
||||||
pPoint2.y - Origin.y,
|
|
||||||
pPoint2.z - (-pPoint2.x / ddp + pPoint1.x / ddp) * WireOffset - Origin.z );
|
|
||||||
glEnd();
|
|
||||||
// Nie wiem co 'Marcin
|
|
||||||
Math3D::vector3 pt1, pt2, pt3, pt4, v1, v2;
|
|
||||||
v1 = pPoint4 - pPoint3;
|
|
||||||
v2 = pPoint2 - pPoint1;
|
|
||||||
float step = 0;
|
|
||||||
if (iNumSections > 0)
|
|
||||||
step = 1.0f / (float)iNumSections;
|
|
||||||
float f = step;
|
|
||||||
float mid = 0.5;
|
|
||||||
float t;
|
|
||||||
// Przewod nosny 'Marcin
|
|
||||||
if (Wires > 1)
|
|
||||||
{
|
|
||||||
glBegin(GL_LINE_STRIP);
|
|
||||||
glVertex3f(
|
|
||||||
pPoint3.x - Origin.x,
|
|
||||||
pPoint3.y - Origin.y,
|
|
||||||
pPoint3.z - Origin.z );
|
|
||||||
for (int i = 0; i < iNumSections - 1; ++i)
|
|
||||||
{
|
|
||||||
pt3 = pPoint3 + v1 * f;
|
|
||||||
t = (1 - std::fabs(f - mid) * 2);
|
|
||||||
if ((Wires < 4) || ((i != 0) && (i != iNumSections - 2)))
|
|
||||||
glVertex3f(
|
|
||||||
pt3.x - Origin.x,
|
|
||||||
pt3.y - std::sqrt(t) * fHeightDifference - Origin.y,
|
|
||||||
pt3.z - Origin.z );
|
|
||||||
f += step;
|
|
||||||
}
|
|
||||||
glVertex3f(
|
|
||||||
pPoint4.x - Origin.x,
|
|
||||||
pPoint4.y - Origin.y,
|
|
||||||
pPoint4.z - Origin.z );
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
// Drugi przewod jezdny 'Winger
|
|
||||||
if (Wires > 2)
|
|
||||||
{
|
|
||||||
glBegin(GL_LINE_STRIP);
|
|
||||||
glVertex3f(
|
|
||||||
pPoint1.x + (pPoint2.z / ddp - pPoint1.z / ddp) * WireOffset - Origin.x,
|
|
||||||
pPoint1.y - Origin.y,
|
|
||||||
pPoint1.z + (-pPoint2.x / ddp + pPoint1.x / ddp) * WireOffset - Origin.z );
|
|
||||||
glVertex3f(
|
|
||||||
pPoint2.x + (pPoint2.z / ddp - pPoint1.z / ddp) * WireOffset - Origin.x,
|
|
||||||
pPoint2.y - Origin.y,
|
|
||||||
pPoint2.z + (-pPoint2.x / ddp + pPoint1.x / ddp) * WireOffset - Origin.z );
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
f = step;
|
|
||||||
|
|
||||||
if (Wires == 4)
|
|
||||||
{
|
|
||||||
glBegin(GL_LINE_STRIP);
|
|
||||||
glVertex3f(
|
|
||||||
pPoint3.x - Origin.x,
|
|
||||||
pPoint3.y - 0.65f * fHeightDifference - Origin.y,
|
|
||||||
pPoint3.z - Origin.z );
|
|
||||||
for (int i = 0; i < iNumSections - 1; ++i)
|
|
||||||
{
|
|
||||||
pt3 = pPoint3 + v1 * f;
|
|
||||||
t = (1 - std::fabs(f - mid) * 2);
|
|
||||||
glVertex3f(
|
|
||||||
pt3.x - Origin.x,
|
|
||||||
pt3.y - std::sqrt( t ) * fHeightDifference - (
|
|
||||||
( ( i == 0 )
|
|
||||||
|| ( i == iNumSections - 2 ) ) ?
|
|
||||||
0.25f * fHeightDifference :
|
|
||||||
0.05 )
|
|
||||||
- Origin.y,
|
|
||||||
pt3.z - Origin.z );
|
|
||||||
f += step;
|
|
||||||
}
|
|
||||||
glVertex3f(
|
|
||||||
pPoint4.x - Origin.x,
|
|
||||||
pPoint4.y - 0.65f * fHeightDifference - Origin.y,
|
|
||||||
pPoint4.z - Origin.z );
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
f = step;
|
|
||||||
|
|
||||||
// Przewody pionowe (wieszaki) 'Marcin, poprawki na 2 przewody jezdne 'Winger
|
|
||||||
if (Wires != 1)
|
|
||||||
{
|
|
||||||
glBegin(GL_LINES);
|
|
||||||
for (int i = 0; i < iNumSections - 1; ++i)
|
|
||||||
{
|
|
||||||
float flo, flo1;
|
|
||||||
flo = (Wires == 4 ? 0.25f * fHeightDifference : 0);
|
|
||||||
flo1 = (Wires == 4 ? +0.05 : 0);
|
|
||||||
pt3 = pPoint3 + v1 * f;
|
|
||||||
pt4 = pPoint1 + v2 * f;
|
|
||||||
t = (1 - std::fabs(f - mid) * 2);
|
|
||||||
if ((i % 2) == 0)
|
|
||||||
{
|
|
||||||
glVertex3f(
|
|
||||||
pt3.x - Origin.x,
|
|
||||||
pt3.y - std::sqrt(t) * fHeightDifference - ((i == 0) || (i == iNumSections - 2) ? flo : flo1) - Origin.y,
|
|
||||||
pt3.z - Origin.z );
|
|
||||||
glVertex3f(
|
|
||||||
pt4.x - (pPoint2.z / ddp - pPoint1.z / ddp) * WireOffset - Origin.x,
|
|
||||||
pt4.y - Origin.y,
|
|
||||||
pt4.z - (-pPoint2.x / ddp + pPoint1.x / ddp) * WireOffset - Origin.z );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
glVertex3f(
|
|
||||||
pt3.x - Origin.x,
|
|
||||||
pt3.y - std::sqrt(t) * fHeightDifference - ((i == 0) || (i == iNumSections - 2) ? flo : flo1) - Origin.y,
|
|
||||||
pt3.z - Origin.z );
|
|
||||||
glVertex3f(
|
|
||||||
pt4.x + (pPoint2.z / ddp - pPoint1.z / ddp) * WireOffset - Origin.x,
|
|
||||||
pt4.y - Origin.y,
|
|
||||||
pt4.z + (-pPoint2.x / ddp + pPoint1.x / ddp) * WireOffset - Origin.z );
|
|
||||||
}
|
|
||||||
if ((Wires == 4) && ((i == 1) || (i == iNumSections - 3)))
|
|
||||||
{
|
|
||||||
glVertex3f(
|
|
||||||
pt3.x - Origin.x,
|
|
||||||
pt3.y - std::sqrt(t) * fHeightDifference - 0.05 - Origin.y,
|
|
||||||
pt3.z - Origin.z );
|
|
||||||
glVertex3f(
|
|
||||||
pt3.x - Origin.x,
|
|
||||||
pt3.y - std::sqrt(t) * fHeightDifference - Origin.y,
|
|
||||||
pt3.z - Origin.z );
|
|
||||||
}
|
|
||||||
f += step;
|
|
||||||
}
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
glEndList();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
/*
|
|
||||||
void TTraction::InitCenter(vector3 Angles, vector3 pOrigin)
|
|
||||||
{
|
|
||||||
pPosition= (pPoint2+pPoint1)*0.5f;
|
|
||||||
fSquaredRadius= SquareMagnitude((pPoint2-pPoint1)*0.5f);
|
|
||||||
} */
|
|
||||||
|
|
||||||
void TTraction::RenderDL(float mgn, Math3D::vector3 const &Origin ) // McZapkie: mgn to odleglosc od obserwatora
|
vertex_array vertices;
|
||||||
{
|
|
||||||
// McZapkie: ustalanie przezroczystosci i koloru linii:
|
|
||||||
if( Wires != 0 && !TestFlag( DamageFlag, 128 ) ) // rysuj jesli sa druty i nie zerwana
|
|
||||||
{
|
|
||||||
// setup
|
|
||||||
GfxRenderer.Bind( 0 );
|
|
||||||
if( !Global::bSmoothTraction ) {
|
|
||||||
// na liniach kiepsko wygląda - robi gradient
|
|
||||||
::glDisable( GL_LINE_SMOOTH );
|
|
||||||
}
|
|
||||||
float linealpha = 5000 * WireThickness / ( mgn + 1.0 ); //*WireThickness
|
|
||||||
linealpha = std::min( 1.2f, linealpha ); // zbyt grube nie są dobre
|
|
||||||
::glLineWidth( linealpha );
|
|
||||||
// McZapkie-261102: kolor zalezy od materialu i zasniedzenia
|
|
||||||
float
|
|
||||||
red{ 0.0f },
|
|
||||||
green{ 0.0f },
|
|
||||||
blue{ 0.0f };
|
|
||||||
wire_color( red, green, blue );
|
|
||||||
::glColor4f( red, green, blue, linealpha );
|
|
||||||
// draw code
|
|
||||||
if (!uiDisplayList)
|
|
||||||
Optimize( Origin ); // generowanie DL w miarę potrzeby
|
|
||||||
::glCallList(uiDisplayList);
|
|
||||||
// cleanup
|
|
||||||
::glLineWidth(1.0);
|
|
||||||
::glEnable(GL_LINE_SMOOTH);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// przygotowanie tablic do skopiowania do VBO (zliczanie wierzchołków)
|
double ddp = std::hypot( pPoint2.x - pPoint1.x, pPoint2.z - pPoint1.z );
|
||||||
int TTraction::RaArrayPrepare()
|
if( Wires == 2 )
|
||||||
{
|
|
||||||
// jezdny
|
|
||||||
iLines = 2;
|
|
||||||
// przewod nosny
|
|
||||||
if( Wires > 1 ) {
|
|
||||||
iLines += 2 + (
|
|
||||||
Wires < 4 ?
|
|
||||||
std::max( 0, iNumSections - 1 ) :
|
|
||||||
( iNumSections > 2 ?
|
|
||||||
std::max( 0, iNumSections - 1 - 2 ) :
|
|
||||||
std::max( 0, iNumSections - 1 - 1 ) ) );
|
|
||||||
}
|
|
||||||
// drugi przewod jezdny
|
|
||||||
if( Wires > 2 ) {
|
|
||||||
iLines += 2;
|
|
||||||
}
|
|
||||||
if( Wires == 4 ) {
|
|
||||||
iLines += 2 + std::max( 0, iNumSections - 1 );
|
|
||||||
}
|
|
||||||
// przewody pionowe (wieszaki)
|
|
||||||
if( Wires > 1 ) {
|
|
||||||
iLines += 2 * ( std::max( 0, iNumSections - 1 ) );
|
|
||||||
if( ( Wires == 4 )
|
|
||||||
&&( iNumSections > 0 ) ) {
|
|
||||||
iLines += (
|
|
||||||
iNumSections > 4 ?
|
|
||||||
4 :
|
|
||||||
2 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return iLines;
|
|
||||||
};
|
|
||||||
|
|
||||||
int TTraction::RaArrayFill(CVertNormTex *Vert, Math3D::vector3 const &Origin)
|
|
||||||
{ // wypełnianie tablic VBO
|
|
||||||
int debugvertexcount{ 0 };
|
|
||||||
|
|
||||||
double ddp = std::hypot(pPoint2.x - pPoint1.x, pPoint2.z - pPoint1.z);
|
|
||||||
if (Wires == 2)
|
|
||||||
WireOffset = 0;
|
WireOffset = 0;
|
||||||
// jezdny
|
// jezdny
|
||||||
Vert->x = pPoint1.x - ( pPoint2.z / ddp - pPoint1.z / ddp ) * WireOffset - Origin.x;
|
basic_vertex startvertex, endvertex;
|
||||||
Vert->y = pPoint1.y - Origin.y;
|
startvertex.position =
|
||||||
Vert->z = pPoint1.z - ( -pPoint2.x / ddp + pPoint1.x / ddp ) * WireOffset - Origin.z;
|
glm::vec3(
|
||||||
++Vert;
|
pPoint1.x - ( pPoint2.z / ddp - pPoint1.z / ddp ) * WireOffset - Origin.x,
|
||||||
++debugvertexcount;
|
pPoint1.y - Origin.y,
|
||||||
Vert->x = pPoint2.x - ( pPoint2.z / ddp - pPoint1.z / ddp ) * WireOffset - Origin.x;
|
pPoint1.z - ( -pPoint2.x / ddp + pPoint1.x / ddp ) * WireOffset - Origin.z );
|
||||||
Vert->y = pPoint2.y - Origin.y;
|
endvertex.position =
|
||||||
Vert->z = pPoint2.z - ( -pPoint2.x / ddp + pPoint1.x / ddp ) * WireOffset - Origin.z;
|
glm::vec3(
|
||||||
++Vert;
|
pPoint2.x - ( pPoint2.z / ddp - pPoint1.z / ddp ) * WireOffset - Origin.x,
|
||||||
++debugvertexcount;
|
pPoint2.y - Origin.y,
|
||||||
|
pPoint2.z - ( -pPoint2.x / ddp + pPoint1.x / ddp ) * WireOffset - Origin.z );
|
||||||
|
vertices.emplace_back( startvertex );
|
||||||
|
vertices.emplace_back( endvertex );
|
||||||
// Nie wiem co 'Marcin
|
// Nie wiem co 'Marcin
|
||||||
Math3D::vector3 pt1, pt2, pt3, pt4, v1, v2;
|
Math3D::vector3 pt1, pt2, pt3, pt4, v1, v2;
|
||||||
v1 = pPoint4 - pPoint3;
|
v1 = pPoint4 - pPoint3;
|
||||||
@@ -370,201 +127,152 @@ int TTraction::RaArrayFill(CVertNormTex *Vert, Math3D::vector3 const &Origin)
|
|||||||
float mid = 0.5;
|
float mid = 0.5;
|
||||||
float t;
|
float t;
|
||||||
// Przewod nosny 'Marcin
|
// Przewod nosny 'Marcin
|
||||||
if (Wires > 1)
|
if( Wires > 1 ) { // lina nośna w kawałkach
|
||||||
{ // lina nośna w kawałkach
|
startvertex.position =
|
||||||
Vert->x = pPoint3.x - Origin.x;
|
glm::vec3(
|
||||||
Vert->y = pPoint3.y - Origin.y;
|
pPoint3.x - Origin.x,
|
||||||
Vert->z = pPoint3.z - Origin.z;
|
pPoint3.y - Origin.y,
|
||||||
++Vert;
|
pPoint3.z - Origin.z );
|
||||||
++debugvertexcount;
|
for( int i = 0; i < iNumSections - 1; ++i ) {
|
||||||
for (int i = 0; i < iNumSections - 1; ++i)
|
|
||||||
{
|
|
||||||
pt3 = pPoint3 + v1 * f;
|
pt3 = pPoint3 + v1 * f;
|
||||||
t = (1 - std::fabs(f - mid) * 2);
|
t = ( 1 - std::fabs( f - mid ) * 2 );
|
||||||
if( ( Wires < 4 )
|
if( ( Wires < 4 )
|
||||||
|| ( ( i != 0 )
|
|| ( ( i != 0 )
|
||||||
&& ( i != iNumSections - 2 ) ) ) {
|
&& ( i != iNumSections - 2 ) ) ) {
|
||||||
Vert->x = pt3.x - Origin.x;
|
endvertex.position =
|
||||||
Vert->y = pt3.y - std::sqrt( t ) * fHeightDifference - Origin.y;
|
glm::vec3(
|
||||||
Vert->z = pt3.z - Origin.z;
|
pt3.x - Origin.x,
|
||||||
++Vert;
|
pt3.y - std::sqrt( t ) * fHeightDifference - Origin.y,
|
||||||
++debugvertexcount;
|
pt3.z - Origin.z );
|
||||||
|
vertices.emplace_back( startvertex );
|
||||||
|
vertices.emplace_back( endvertex );
|
||||||
|
startvertex = endvertex;
|
||||||
}
|
}
|
||||||
f += step;
|
f += step;
|
||||||
}
|
}
|
||||||
Vert->x = pPoint4.x - Origin.x;
|
endvertex.position =
|
||||||
Vert->y = pPoint4.y - Origin.y;
|
glm::vec3(
|
||||||
Vert->z = pPoint4.z - Origin.z;
|
pPoint4.x - Origin.x,
|
||||||
++Vert;
|
pPoint4.y - Origin.y,
|
||||||
++debugvertexcount;
|
pPoint4.z - Origin.z );
|
||||||
|
vertices.emplace_back( startvertex );
|
||||||
|
vertices.emplace_back( endvertex );
|
||||||
}
|
}
|
||||||
// Drugi przewod jezdny 'Winger
|
// Drugi przewod jezdny 'Winger
|
||||||
if (Wires > 2)
|
if( Wires > 2 ) {
|
||||||
{
|
startvertex.position =
|
||||||
Vert->x = pPoint1.x + (pPoint2.z / ddp - pPoint1.z / ddp) * WireOffset - Origin.x;
|
glm::vec3(
|
||||||
Vert->y = pPoint1.y - Origin.y;
|
pPoint1.x + ( pPoint2.z / ddp - pPoint1.z / ddp ) * WireOffset - Origin.x,
|
||||||
Vert->z = pPoint1.z + (-pPoint2.x / ddp + pPoint1.x / ddp) * WireOffset - Origin.z;
|
pPoint1.y - Origin.y,
|
||||||
++Vert;
|
pPoint1.z + ( -pPoint2.x / ddp + pPoint1.x / ddp ) * WireOffset - Origin.z );
|
||||||
++debugvertexcount;
|
endvertex.position =
|
||||||
Vert->x = pPoint2.x + (pPoint2.z / ddp - pPoint1.z / ddp) * WireOffset - Origin.x;
|
glm::vec3(
|
||||||
Vert->y = pPoint2.y - Origin.y;
|
pPoint2.x + ( pPoint2.z / ddp - pPoint1.z / ddp ) * WireOffset - Origin.x,
|
||||||
Vert->z = pPoint2.z + (-pPoint2.x / ddp + pPoint1.x / ddp) * WireOffset - Origin.z;
|
pPoint2.y - Origin.y,
|
||||||
++Vert;
|
pPoint2.z + ( -pPoint2.x / ddp + pPoint1.x / ddp ) * WireOffset - Origin.z );
|
||||||
++debugvertexcount;
|
vertices.emplace_back( startvertex );
|
||||||
|
vertices.emplace_back( endvertex );
|
||||||
}
|
}
|
||||||
|
|
||||||
f = step;
|
f = step;
|
||||||
|
|
||||||
if( Wires == 4 ) {
|
if( Wires == 4 ) {
|
||||||
Vert->x = pPoint3.x - Origin.x;
|
startvertex.position =
|
||||||
Vert->y = pPoint3.y - 0.65f * fHeightDifference - Origin.y;
|
glm::vec3(
|
||||||
Vert->z = pPoint3.z - Origin.z;
|
pPoint3.x - Origin.x,
|
||||||
++Vert;
|
pPoint3.y - 0.65f * fHeightDifference - Origin.y,
|
||||||
++debugvertexcount;
|
pPoint3.z - Origin.z );
|
||||||
for( int i = 0; i < iNumSections - 1; ++i ) {
|
for( int i = 0; i < iNumSections - 1; ++i ) {
|
||||||
pt3 = pPoint3 + v1 * f;
|
pt3 = pPoint3 + v1 * f;
|
||||||
t = ( 1 - std::fabs( f - mid ) * 2 );
|
t = ( 1 - std::fabs( f - mid ) * 2 );
|
||||||
Vert->x = pt3.x - Origin.x;
|
endvertex.position =
|
||||||
Vert->y = pt3.y - std::sqrt( t ) * fHeightDifference - (
|
glm::vec3(
|
||||||
( ( i == 0 )
|
pt3.x - Origin.x,
|
||||||
|| ( i == iNumSections - 2 ) ) ?
|
pt3.y - std::sqrt( t ) * fHeightDifference - (
|
||||||
0.25f * fHeightDifference :
|
( ( i == 0 )
|
||||||
0.05 )
|
|| ( i == iNumSections - 2 ) ) ?
|
||||||
- Origin.y;
|
0.25f * fHeightDifference :
|
||||||
Vert->z = pt3.z - Origin.z;
|
0.05 )
|
||||||
++Vert;
|
- Origin.y,
|
||||||
++debugvertexcount;
|
pt3.z - Origin.z );
|
||||||
|
vertices.emplace_back( startvertex );
|
||||||
|
vertices.emplace_back( endvertex );
|
||||||
|
startvertex = endvertex;
|
||||||
f += step;
|
f += step;
|
||||||
}
|
}
|
||||||
Vert->x = pPoint4.x - Origin.x;
|
endvertex.position =
|
||||||
Vert->y = pPoint4.y - 0.65f * fHeightDifference - Origin.y;
|
glm::vec3(
|
||||||
Vert->z = pPoint4.z - Origin.z;
|
pPoint4.x - Origin.x,
|
||||||
++Vert;
|
pPoint4.y - 0.65f * fHeightDifference - Origin.y,
|
||||||
++debugvertexcount;
|
pPoint4.z - Origin.z );
|
||||||
|
vertices.emplace_back( startvertex );
|
||||||
|
vertices.emplace_back( endvertex );
|
||||||
}
|
}
|
||||||
f = step;
|
f = step;
|
||||||
|
|
||||||
// Przewody pionowe (wieszaki) 'Marcin, poprawki na 2 przewody jezdne 'Winger
|
// Przewody pionowe (wieszaki) 'Marcin, poprawki na 2 przewody jezdne 'Winger
|
||||||
if (Wires > 1)
|
if( Wires > 1 ) {
|
||||||
{
|
for( int i = 0; i < iNumSections - 1; ++i ) {
|
||||||
for (int i = 0; i < iNumSections - 1; ++i)
|
|
||||||
{
|
|
||||||
float flo, flo1;
|
float flo, flo1;
|
||||||
flo = ( Wires == 4 ? 0.25f * fHeightDifference : 0 );
|
flo = ( Wires == 4 ? 0.25f * fHeightDifference : 0 );
|
||||||
flo1 = ( Wires == 4 ? +0.05 : 0 );
|
flo1 = ( Wires == 4 ? +0.05 : 0 );
|
||||||
pt3 = pPoint3 + v1 * f;
|
pt3 = pPoint3 + v1 * f;
|
||||||
pt4 = pPoint1 + v2 * f;
|
pt4 = pPoint1 + v2 * f;
|
||||||
t = (1 - std::fabs(f - mid) * 2);
|
t = ( 1 - std::fabs( f - mid ) * 2 );
|
||||||
|
|
||||||
if( ( i % 2 ) == 0 ) {
|
if( ( i % 2 ) == 0 ) {
|
||||||
Vert->x = pt3.x - Origin.x;
|
startvertex.position =
|
||||||
Vert->y = pt3.y - std::sqrt( t ) * fHeightDifference - ( ( i == 0 ) || ( i == iNumSections - 2 ) ? flo : flo1 ) - Origin.y;
|
glm::vec3(
|
||||||
Vert->z = pt3.z - Origin.z;
|
pt3.x - Origin.x,
|
||||||
++Vert;
|
pt3.y - std::sqrt( t ) * fHeightDifference - ( ( i == 0 ) || ( i == iNumSections - 2 ) ? flo : flo1 ) - Origin.y,
|
||||||
++debugvertexcount;
|
pt3.z - Origin.z );
|
||||||
Vert->x = pt4.x - ( pPoint2.z / ddp - pPoint1.z / ddp ) * WireOffset - Origin.x;
|
endvertex.position =
|
||||||
Vert->y = pt4.y - Origin.y;
|
glm::vec3(
|
||||||
Vert->z = pt4.z - ( -pPoint2.x / ddp + pPoint1.x / ddp ) * WireOffset - Origin.z;
|
pt4.x - ( pPoint2.z / ddp - pPoint1.z / ddp ) * WireOffset - Origin.x,
|
||||||
++Vert;
|
pt4.y - Origin.y,
|
||||||
++debugvertexcount;
|
pt4.z - ( -pPoint2.x / ddp + pPoint1.x / ddp ) * WireOffset - Origin.z );
|
||||||
|
vertices.emplace_back( startvertex );
|
||||||
|
vertices.emplace_back( endvertex );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Vert->x = pt3.x - Origin.x;
|
startvertex.position =
|
||||||
Vert->y = pt3.y - std::sqrt( t ) * fHeightDifference - ( ( i == 0 ) || ( i == iNumSections - 2 ) ? flo : flo1 ) - Origin.y;
|
glm::vec3(
|
||||||
Vert->z = pt3.z - Origin.z;
|
pt3.x - Origin.x,
|
||||||
++Vert;
|
pt3.y - std::sqrt( t ) * fHeightDifference - ( ( i == 0 ) || ( i == iNumSections - 2 ) ? flo : flo1 ) - Origin.y,
|
||||||
++debugvertexcount;
|
pt3.z - Origin.z );
|
||||||
Vert->x = pt4.x + ( pPoint2.z / ddp - pPoint1.z / ddp ) * WireOffset - Origin.x;
|
endvertex.position =
|
||||||
Vert->y = pt4.y - Origin.y;
|
glm::vec3(
|
||||||
Vert->z = pt4.z + ( -pPoint2.x / ddp + pPoint1.x / ddp ) * WireOffset - Origin.z;
|
pt4.x + ( pPoint2.z / ddp - pPoint1.z / ddp ) * WireOffset - Origin.x,
|
||||||
++Vert;
|
pt4.y - Origin.y,
|
||||||
++debugvertexcount;
|
pt4.z - ( -pPoint2.x / ddp + pPoint1.x / ddp ) * WireOffset - Origin.z );
|
||||||
|
vertices.emplace_back( startvertex );
|
||||||
|
vertices.emplace_back( endvertex );
|
||||||
}
|
}
|
||||||
if( ( ( Wires == 4 )
|
if( ( ( Wires == 4 )
|
||||||
&& ( ( i == 1 )
|
&& ( ( i == 1 )
|
||||||
|| ( i == iNumSections - 3 ) ) ) ) {
|
|| ( i == iNumSections - 3 ) ) ) ) {
|
||||||
Vert->x = pt3.x - Origin.x;
|
startvertex.position =
|
||||||
Vert->y = pt3.y - std::sqrt( t ) * fHeightDifference - 0.05 - Origin.y;
|
glm::vec3(
|
||||||
Vert->z = pt3.z - Origin.z;
|
pt3.x - Origin.x,
|
||||||
++Vert;
|
pt3.y - std::sqrt( t ) * fHeightDifference - 0.05 - Origin.y,
|
||||||
++debugvertexcount;
|
pt3.z - Origin.z );
|
||||||
Vert->x = pt3.x - Origin.x;
|
endvertex.position =
|
||||||
Vert->y = pt3.y - std::sqrt( t ) * fHeightDifference - Origin.y;
|
glm::vec3(
|
||||||
Vert->z = pt3.z - Origin.z;
|
pt3.x - Origin.x,
|
||||||
++Vert;
|
pt3.y - std::sqrt( t ) * fHeightDifference - Origin.y,
|
||||||
++debugvertexcount;
|
pt3.z - Origin.z );
|
||||||
|
vertices.emplace_back( startvertex );
|
||||||
|
vertices.emplace_back( endvertex );
|
||||||
}
|
}
|
||||||
f += step;
|
f += step;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return debugvertexcount;
|
|
||||||
};
|
|
||||||
|
|
||||||
void TTraction::RenderVBO(float mgn, int iPtr)
|
auto const elementcount = vertices.size() / 2;
|
||||||
{ // renderowanie z użyciem VBO
|
m_geometry = GfxRenderer.Insert( vertices, Bank, GL_LINES );
|
||||||
if (Wires != 0 && !TestFlag(DamageFlag, 128)) // rysuj jesli sa druty i nie zerwana
|
|
||||||
{
|
return elementcount;
|
||||||
// setup
|
}
|
||||||
GfxRenderer.Bind(0);
|
|
||||||
if( !Global::bSmoothTraction ) {
|
|
||||||
// na liniach kiepsko wygląda - robi gradient
|
|
||||||
::glDisable( GL_LINE_SMOOTH );
|
|
||||||
}
|
|
||||||
float linealpha = 5000 * WireThickness / (mgn + 1.0); //*WireThickness
|
|
||||||
linealpha = std::min( 1.2f, linealpha ); // zbyt grube nie są dobre
|
|
||||||
::glLineWidth(linealpha);
|
|
||||||
// McZapkie-261102: kolor zalezy od materialu i zasniedzenia
|
|
||||||
float
|
|
||||||
red{ 0.0f },
|
|
||||||
green{ 0.0f },
|
|
||||||
blue{ 0.0f };
|
|
||||||
wire_color( red, green, blue );
|
|
||||||
::glColor4f(red, green, blue, linealpha);
|
|
||||||
// draw code
|
|
||||||
// jezdny
|
|
||||||
::glDrawArrays( GL_LINE_STRIP, iPtr, 2 );
|
|
||||||
iPtr += 2;
|
|
||||||
// przewod nosny
|
|
||||||
if( Wires > 1 ) {
|
|
||||||
auto const piececount = 2 + (
|
|
||||||
Wires < 4 ?
|
|
||||||
std::max( 0 , iNumSections - 1 ) :
|
|
||||||
( iNumSections > 2 ?
|
|
||||||
std::max( 0, iNumSections - 1 - 2 ) :
|
|
||||||
std::max( 0, iNumSections - 1 - 1 ) ) );
|
|
||||||
::glDrawArrays( GL_LINE_STRIP, iPtr, piececount );
|
|
||||||
iPtr += piececount;
|
|
||||||
}
|
|
||||||
// drugi przewod jezdny
|
|
||||||
if( Wires > 2 ) {
|
|
||||||
::glDrawArrays( GL_LINE_STRIP, iPtr, 2 );
|
|
||||||
iPtr += 2;
|
|
||||||
}
|
|
||||||
if( Wires == 4 ) {
|
|
||||||
auto const piececount = 2 + std::max( 0, iNumSections - 1 );
|
|
||||||
::glDrawArrays( GL_LINE_STRIP, iPtr, piececount );
|
|
||||||
iPtr += piececount;
|
|
||||||
}
|
|
||||||
// przewody pionowe (wieszaki)
|
|
||||||
if( Wires != 1 ) {
|
|
||||||
auto piececount = 2 * std::max( 0, iNumSections - 1 );
|
|
||||||
if( ( Wires == 4 )
|
|
||||||
&& ( iNumSections > 0 ) ) {
|
|
||||||
piececount += (
|
|
||||||
iNumSections > 4 ?
|
|
||||||
4 :
|
|
||||||
2 );
|
|
||||||
}
|
|
||||||
if( piececount > 0 ) {
|
|
||||||
::glDrawArrays( GL_LINES, iPtr, piececount );
|
|
||||||
iPtr += piececount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// cleanup
|
|
||||||
::glLineWidth(1.0);
|
|
||||||
::glEnable(GL_LINE_SMOOTH);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
int TTraction::TestPoint(Math3D::vector3 *Point)
|
int TTraction::TestPoint(Math3D::vector3 *Point)
|
||||||
{ // sprawdzanie, czy przęsła można połączyć
|
{ // sprawdzanie, czy przęsła można połączyć
|
||||||
@@ -633,24 +341,10 @@ void TTraction::ResistanceCalc(int d, double r, TTractionPowerSource *ps)
|
|||||||
else
|
else
|
||||||
ps = psPower[d ^ 1]; // zasilacz od przeciwnej strony niż idzie analiza
|
ps = psPower[d ^ 1]; // zasilacz od przeciwnej strony niż idzie analiza
|
||||||
d = iNext[d]; // kierunek
|
d = iNext[d]; // kierunek
|
||||||
#ifdef EU07_USE_OLD_TRACTIONPOWER_CODE
|
|
||||||
if (DebugModeFlag) // tylko podczas testów
|
|
||||||
Material = 4; // pokazanie, że to przęsło ma podłączone zasilanie
|
|
||||||
#else
|
|
||||||
PowerState = 4;
|
PowerState = 4;
|
||||||
#endif
|
|
||||||
while( ( t != nullptr )
|
while( ( t != nullptr )
|
||||||
&& ( t->psPower[d] == nullptr ) ) // jeśli jest jakiś kolejny i nie ma ustalonego zasilacza
|
&& ( t->psPower[d] == nullptr ) ) // jeśli jest jakiś kolejny i nie ma ustalonego zasilacza
|
||||||
{ // ustawienie zasilacza i policzenie rezystancji zastępczej
|
{ // ustawienie zasilacza i policzenie rezystancji zastępczej
|
||||||
#ifdef EU07_USE_OLD_TRACTIONPOWER_CODE
|
|
||||||
if (DebugModeFlag) // tylko podczas testów
|
|
||||||
if (t->Material != 4) // przęsła zasilającego nie modyfikować
|
|
||||||
{
|
|
||||||
if (t->Material < 4)
|
|
||||||
t->Material = 4; // tymczasowo, aby zmieniła kolor
|
|
||||||
t->Material |= d ? 2 : 1; // kolor zależny od strony, z której jest zasilanie
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if( t->PowerState != 4 ) {
|
if( t->PowerState != 4 ) {
|
||||||
// przęsła zasilającego nie modyfikować
|
// przęsła zasilającego nie modyfikować
|
||||||
if( t->psPowered != nullptr ) {
|
if( t->psPowered != nullptr ) {
|
||||||
@@ -662,7 +356,6 @@ void TTraction::ResistanceCalc(int d, double r, TTractionPowerSource *ps)
|
|||||||
t->PowerState |= d ? 2 : 1;
|
t->PowerState |= d ? 2 : 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
t->psPower[d] = ps; // skopiowanie wskaźnika zasilacza od danej strony
|
t->psPower[d] = ps; // skopiowanie wskaźnika zasilacza od danej strony
|
||||||
t->fResistance[d] = r; // wpisanie rezystancji w kierunku tego zasilacza
|
t->fResistance[d] = r; // wpisanie rezystancji w kierunku tego zasilacza
|
||||||
r += t->fResistivity * Length3(t->vParametric); // doliczenie oporu kolejnego odcinka
|
r += t->fResistivity * Length3(t->vParametric); // doliczenie oporu kolejnego odcinka
|
||||||
@@ -749,44 +442,45 @@ double TTraction::VoltageGet(double u, double i)
|
|||||||
return 0.0; // gdy nie podłączony wcale?
|
return 0.0; // gdy nie podłączony wcale?
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
glm::vec3
|
||||||
TTraction::wire_color( float &Red, float &Green, float &Blue ) const {
|
TTraction::wire_color() const {
|
||||||
|
|
||||||
|
glm::vec3 color;
|
||||||
if( false == DebugModeFlag ) {
|
if( false == DebugModeFlag ) {
|
||||||
switch( Material ) { // Ra: kolory podzieliłem przez 2, bo po zmianie ambient za jasne były
|
switch( Material ) { // Ra: kolory podzieliłem przez 2, bo po zmianie ambient za jasne były
|
||||||
// trzeba uwzględnić kierunek świecenia Słońca - tylko ze Słońcem widać kolor
|
// trzeba uwzględnić kierunek świecenia Słońca - tylko ze Słońcem widać kolor
|
||||||
case 1: {
|
case 1: {
|
||||||
if( TestFlag( DamageFlag, 1 ) ) {
|
if( TestFlag( DamageFlag, 1 ) ) {
|
||||||
Red = 0.00000f;
|
color.r = 0.00000f;
|
||||||
Green = 0.32549f;
|
color.g = 0.32549f;
|
||||||
Blue = 0.2882353f; // zielona miedź
|
color.b = 0.2882353f; // zielona miedź
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Red = 0.35098f;
|
color.r = 0.35098f;
|
||||||
Green = 0.22549f;
|
color.g = 0.22549f;
|
||||||
Blue = 0.1f; // czerwona miedź
|
color.b = 0.1f; // czerwona miedź
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2: {
|
case 2: {
|
||||||
if( TestFlag( DamageFlag, 1 ) ) {
|
if( TestFlag( DamageFlag, 1 ) ) {
|
||||||
Red = 0.10f;
|
color.r = 0.10f;
|
||||||
Green = 0.10f;
|
color.g = 0.10f;
|
||||||
Blue = 0.10f; // czarne Al
|
color.b = 0.10f; // czarne Al
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Red = 0.25f;
|
color.r = 0.25f;
|
||||||
Green = 0.25f;
|
color.g = 0.25f;
|
||||||
Blue = 0.25f; // srebrne Al
|
color.b = 0.25f; // srebrne Al
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {break; }
|
default: {break; }
|
||||||
}
|
}
|
||||||
// w zaleźności od koloru swiatła
|
// w zaleźności od koloru swiatła
|
||||||
Red *= Global::DayLight.ambient[ 0 ];
|
color.r *= Global::DayLight.ambient[ 0 ];
|
||||||
Green *= Global::DayLight.ambient[ 1 ];
|
color.g *= Global::DayLight.ambient[ 1 ];
|
||||||
Blue *= Global::DayLight.ambient[ 2 ];
|
color.b *= Global::DayLight.ambient[ 2 ];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// tymczasowo pokazanie zasilanych odcinków
|
// tymczasowo pokazanie zasilanych odcinków
|
||||||
@@ -794,38 +488,39 @@ TTraction::wire_color( float &Red, float &Green, float &Blue ) const {
|
|||||||
|
|
||||||
case 1: {
|
case 1: {
|
||||||
// czerwone z podłączonym zasilaniem 1
|
// czerwone z podłączonym zasilaniem 1
|
||||||
Red = 1.0f;
|
color.r = 1.0f;
|
||||||
Green = 0.0f;
|
color.g = 0.0f;
|
||||||
Blue = 0.0f;
|
color.b = 0.0f;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2: {
|
case 2: {
|
||||||
// zielone z podłączonym zasilaniem 2
|
// zielone z podłączonym zasilaniem 2
|
||||||
Red = 0.0f;
|
color.r = 0.0f;
|
||||||
Green = 1.0f;
|
color.g = 1.0f;
|
||||||
Blue = 0.0f;
|
color.b = 0.0f;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 3: {
|
case 3: {
|
||||||
//żółte z podłączonym zasilaniem z obu stron
|
//żółte z podłączonym zasilaniem z obu stron
|
||||||
Red = 1.0f;
|
color.r = 1.0f;
|
||||||
Green = 1.0f;
|
color.g = 1.0f;
|
||||||
Blue = 0.0f;
|
color.b = 0.0f;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 4: {
|
case 4: {
|
||||||
// niebieskie z podłączonym zasilaniem
|
// niebieskie z podłączonym zasilaniem
|
||||||
Red = 0.5f;
|
color.r = 0.5f;
|
||||||
Green = 0.5f;
|
color.g = 0.5f;
|
||||||
Blue = 1.0f;
|
color.b = 1.0f;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: { break; }
|
default: { break; }
|
||||||
}
|
}
|
||||||
if( hvParallel ) { // jeśli z bieżnią wspólną, to dodatkowo przyciemniamy
|
if( hvParallel ) { // jeśli z bieżnią wspólną, to dodatkowo przyciemniamy
|
||||||
Red *= 0.6f;
|
color.r *= 0.6f;
|
||||||
Green *= 0.6f;
|
color.g *= 0.6f;
|
||||||
Blue *= 0.6f;
|
color.b *= 0.6f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return color;
|
||||||
|
}
|
||||||
|
|||||||
77
Traction.h
77
Traction.h
@@ -11,65 +11,47 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "GL/glew.h"
|
#include "GL/glew.h"
|
||||||
#include "VBO.h"
|
|
||||||
#include "dumb3d.h"
|
#include "dumb3d.h"
|
||||||
|
#include "openglgeometrybank.h"
|
||||||
|
|
||||||
class TTractionPowerSource;
|
class TTractionPowerSource;
|
||||||
|
|
||||||
class TTraction
|
class TTraction
|
||||||
{ // drut zasilający, dla wskaźników używać przedrostka "hv"
|
{ // drut zasilający, dla wskaźników używać przedrostka "hv"
|
||||||
private:
|
friend class opengl_renderer;
|
||||||
// vector3 vUp,vFront,vLeft;
|
|
||||||
// matrix4x4 mMatrix;
|
|
||||||
// matryca do wyliczania pozycji drutu w zależności od [X,Y,kąt] w scenerii:
|
|
||||||
// - x: odległość w bok (czy odbierak się nie zsunął)
|
|
||||||
// - y: przyjmuje wartość <0,1>, jeśli pod drutem (wzdłuż)
|
|
||||||
// - z: wysokość bezwzględna drutu w danym miejsu
|
|
||||||
public: // na razie
|
public: // na razie
|
||||||
TTractionPowerSource *psPower[2]; // najbliższe zasilacze z obu kierunków
|
TTractionPowerSource *psPower[ 2 ] { nullptr, nullptr }; // najbliższe zasilacze z obu kierunków
|
||||||
TTractionPowerSource *psPowered = nullptr; // ustawione tylko dla bezpośrednio zasilanego przęsła
|
TTractionPowerSource *psPowered { nullptr }; // ustawione tylko dla bezpośrednio zasilanego przęsła
|
||||||
TTraction *hvNext[2]; //łączenie drutów w sieć
|
TTraction *hvNext[ 2 ] { nullptr, nullptr }; //łączenie drutów w sieć
|
||||||
int iNext[2]; // do którego końca się łączy
|
int iNext[ 2 ] { 0, 0 }; // do którego końca się łączy
|
||||||
int iLast = 1; //że niby ostatni drut // ustawiony bit 0, jeśli jest ostatnim drutem w sekcji; bit1 - przedostatni
|
int iLast { 1 }; //że niby ostatni drut // ustawiony bit 0, jeśli jest ostatnim drutem w sekcji; bit1 - przedostatni
|
||||||
public:
|
public:
|
||||||
GLuint uiDisplayList = 0;
|
|
||||||
Math3D::vector3 pPoint1, pPoint2, pPoint3, pPoint4;
|
Math3D::vector3 pPoint1, pPoint2, pPoint3, pPoint4;
|
||||||
Math3D::vector3 vParametric; // współczynniki równania parametrycznego odcinka
|
Math3D::vector3 vParametric; // współczynniki równania parametrycznego odcinka
|
||||||
double fHeightDifference = 0.0; //,fMiddleHeight;
|
double fHeightDifference { 0.0 }; //,fMiddleHeight;
|
||||||
// int iCategory,iMaterial,iDamageFlag;
|
int iNumSections { 0 };
|
||||||
// float fU,fR,fMaxI,fWireThickness;
|
float NominalVoltage { 0.0f };
|
||||||
int iNumSections = 0;
|
float MaxCurrent { 0.0f };
|
||||||
int iLines = 0; // ilosc linii dla VBO
|
float fResistivity { 0.0f }; //[om/m], przeliczone z [om/km]
|
||||||
float NominalVoltage = 0.0;
|
DWORD Material { 0 }; // 1: Cu, 2: Al
|
||||||
float MaxCurrent = 0.0;
|
float WireThickness { 0.0f };
|
||||||
float fResistivity = 0.0; //[om/m], przeliczone z [om/km]
|
DWORD DamageFlag { 0 }; // 1: zasniedziale, 128: zerwana
|
||||||
DWORD Material = 0; // 1: Cu, 2: Al
|
int Wires { 2 };
|
||||||
float WireThickness = 0.0;
|
float WireOffset { 0.0f };
|
||||||
DWORD DamageFlag = 0; // 1: zasniedziale, 128: zerwana
|
|
||||||
int Wires = 2;
|
|
||||||
float WireOffset = 0.0;
|
|
||||||
std::string asPowerSupplyName; // McZapkie: nazwa podstacji trakcyjnej
|
std::string asPowerSupplyName; // McZapkie: nazwa podstacji trakcyjnej
|
||||||
TTractionPowerSource *psSection = nullptr; // zasilacz (opcjonalnie może to być pulpit sterujący EL2 w hali!)
|
TTractionPowerSource *psSection { nullptr }; // zasilacz (opcjonalnie może to być pulpit sterujący EL2 w hali!)
|
||||||
std::string asParallel; // nazwa przęsła, z którym może być bieżnia wspólna
|
std::string asParallel; // nazwa przęsła, z którym może być bieżnia wspólna
|
||||||
TTraction *hvParallel = nullptr; // jednokierunkowa i zapętlona lista przęseł ewentualnej bieżni wspólnej
|
TTraction *hvParallel { nullptr }; // jednokierunkowa i zapętlona lista przęseł ewentualnej bieżni wspólnej
|
||||||
float fResistance[2]; // rezystancja zastępcza do punktu zasilania (0: przęsło zasilane, <0: do policzenia)
|
float fResistance[ 2 ] { -1.0f, -1.0f }; // rezystancja zastępcza do punktu zasilania (0: przęsło zasilane, <0: do policzenia)
|
||||||
int iTries = 0;
|
int iTries { 0 };
|
||||||
int PowerState{ 0 }; // type of incoming power, if any
|
int PowerState { 0 }; // type of incoming power, if any
|
||||||
|
// visualization data
|
||||||
|
geometry_handle m_geometry;
|
||||||
|
|
||||||
void Optimize( Math3D::vector3 const &Origin );
|
// creates geometry data in specified geometry bank. returns: number of created elements, or NULL
|
||||||
|
// NOTE: deleting nodes doesn't currently release geometry data owned by the node. TODO: implement erasing individual geometry chunks and banks
|
||||||
TTraction();
|
std::size_t create_geometry( geometrybank_handle const &Bank, Math3D::vector3 const &Origin );
|
||||||
~TTraction();
|
|
||||||
|
|
||||||
// virtual void InitCenter(vector3 Angles, vector3 pOrigin);
|
|
||||||
// virtual bool Hit(double x, double z, vector3 &hitPoint, vector3 &hitDirection)
|
|
||||||
// { return TNode::Hit(x,z,hitPoint,hitDirection); };
|
|
||||||
// virtual bool Move(double dx, double dy, double dz) { return false; };
|
|
||||||
// virtual void SelectedRender();
|
|
||||||
void RenderDL(float mgn, Math3D::vector3 const &Origin );
|
|
||||||
int RaArrayPrepare();
|
|
||||||
int RaArrayFill( CVertNormTex *Vert, Math3D::vector3 const &Origin );
|
|
||||||
void RenderVBO(float mgn, int iPtr);
|
|
||||||
int TestPoint(Math3D::vector3 *Point);
|
int TestPoint(Math3D::vector3 *Point);
|
||||||
void Connect(int my, TTraction *with, int to);
|
void Connect(int my, TTraction *with, int to);
|
||||||
void Init();
|
void Init();
|
||||||
@@ -78,6 +60,7 @@ class TTraction
|
|||||||
void PowerSet(TTractionPowerSource *ps);
|
void PowerSet(TTractionPowerSource *ps);
|
||||||
double VoltageGet(double u, double i);
|
double VoltageGet(double u, double i);
|
||||||
private:
|
private:
|
||||||
void wire_color( float &Red, float &Green, float &Blue ) const;
|
glm::vec3 wire_color() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
4
VBO.cpp
4
VBO.cpp
@@ -12,6 +12,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "GL/glew.h"
|
#include "GL/glew.h"
|
||||||
#include "usefull.h"
|
#include "usefull.h"
|
||||||
#include "sn_utils.h"
|
#include "sn_utils.h"
|
||||||
|
#include "globals.h"
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
void CVertNormTex::deserialize(std::istream &s)
|
void CVertNormTex::deserialize(std::istream &s)
|
||||||
@@ -49,9 +50,6 @@ CMesh::CMesh()
|
|||||||
#endif
|
#endif
|
||||||
m_nVertexCount = -1;
|
m_nVertexCount = -1;
|
||||||
m_nVBOVertices = 0; // nie zarezerwowane
|
m_nVBOVertices = 0; // nie zarezerwowane
|
||||||
|
|
||||||
// TODO: bind proper subtype based on the settings
|
|
||||||
m_geometry = std::make_shared<opengl_vbogeometrybank>();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
CMesh::~CMesh()
|
CMesh::~CMesh()
|
||||||
|
|||||||
3
VBO.h
3
VBO.h
@@ -50,5 +50,6 @@ class CMesh
|
|||||||
#endif
|
#endif
|
||||||
unsigned int m_nVBOVertices; // numer VBO z wierzchołkami
|
unsigned int m_nVBOVertices; // numer VBO z wierzchołkami
|
||||||
|
|
||||||
std::shared_ptr<geometry_bank> m_geometry;
|
geometrybank_handle m_geometrybank;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
4
dumb3d.h
4
dumb3d.h
@@ -140,8 +140,8 @@ class matrix4x4
|
|||||||
for (int x = 0; x < 4; ++x)
|
for (int x = 0; x < 4; ++x)
|
||||||
(*this)(x)[y] = initArray[i++];
|
(*this)(x)[y] = initArray[i++];
|
||||||
}
|
}
|
||||||
template <typename _Type>
|
template <typename Type_>
|
||||||
void OpenGL_Matrix(_Type const *initArray)
|
void OpenGL_Matrix(Type_ const *initArray)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (int x = 0; x < 4; ++x)
|
for (int x = 0; x < 4; ++x)
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "openglgeometrybank.h"
|
#include "openglgeometrybank.h"
|
||||||
|
|
||||||
#include "sn_utils.h"
|
#include "sn_utils.h"
|
||||||
|
#include "logs.h"
|
||||||
|
#include "globals.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
basic_vertex::serialize( std::ostream &s ) {
|
basic_vertex::serialize( std::ostream &s ) {
|
||||||
@@ -45,23 +47,27 @@ basic_vertex::deserialize( std::istream &s ) {
|
|||||||
// generic geometry bank class, allows storage, update and drawing of geometry chunks
|
// generic geometry bank class, allows storage, update and drawing of geometry chunks
|
||||||
|
|
||||||
// creates a new geometry chunk of specified type from supplied vertex data. returns: handle to the chunk
|
// creates a new geometry chunk of specified type from supplied vertex data. returns: handle to the chunk
|
||||||
geometrychunk_handle
|
geometry_handle
|
||||||
geometry_bank::create( vertex_array &Vertices, int const Datatype ) {
|
geometry_bank::create( vertex_array &Vertices, int const Type ) {
|
||||||
|
|
||||||
if( true == Vertices.empty() ) { return NULL; }
|
if( true == Vertices.empty() ) { return geometry_handle( 0, 0 ); }
|
||||||
|
|
||||||
m_chunks.emplace_back( Vertices, Datatype );
|
m_chunks.emplace_back( Vertices, Type );
|
||||||
// NOTE: handle is effectively (index into chunk array + 1) this leaves value of 0 to serve as error/empty handle indication
|
// NOTE: handle is effectively (index into chunk array + 1) this leaves value of 0 to serve as error/empty handle indication
|
||||||
return m_chunks.size();
|
geometry_handle chunkhandle{ 0, m_chunks.size() };
|
||||||
|
// template method
|
||||||
|
create_( chunkhandle );
|
||||||
|
// all done
|
||||||
|
return chunkhandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
// replaces data of specified chunk with the supplied vertex data, starting from specified offset
|
// replaces data of specified chunk with the supplied vertex data, starting from specified offset
|
||||||
bool
|
bool
|
||||||
geometry_bank::replace( vertex_array &Vertices, geometrychunk_handle const Chunk, std::size_t const Offset ) {
|
geometry_bank::replace( vertex_array &Vertices, geometry_handle const &Geometry, std::size_t const Offset ) {
|
||||||
|
|
||||||
if( ( Chunk == 0 ) || ( Chunk > m_chunks.size() ) ) { return false; }
|
if( ( Geometry.chunk == 0 ) || ( Geometry.chunk > m_chunks.size() ) ) { return false; }
|
||||||
|
|
||||||
auto &chunk = m_chunks[ Chunk - 1 ];
|
auto &chunk = geometry_bank::chunk( Geometry );
|
||||||
|
|
||||||
if( ( Offset == 0 )
|
if( ( Offset == 0 )
|
||||||
&& ( Vertices.size() == chunk.vertices.size() ) ) {
|
&& ( Vertices.size() == chunk.vertices.size() ) ) {
|
||||||
@@ -75,61 +81,66 @@ geometry_bank::replace( vertex_array &Vertices, geometrychunk_handle const Chunk
|
|||||||
chunk.vertices.resize( Offset + Vertices.size(), basic_vertex() );
|
chunk.vertices.resize( Offset + Vertices.size(), basic_vertex() );
|
||||||
chunk.vertices.insert( std::end( chunk.vertices ), std::begin( Vertices ), std::end( Vertices ) );
|
chunk.vertices.insert( std::end( chunk.vertices ), std::begin( Vertices ), std::end( Vertices ) );
|
||||||
}
|
}
|
||||||
|
// template method
|
||||||
|
replace_( Geometry );
|
||||||
|
// all done
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
vertex_array &
|
// adds supplied vertex data at the end of specified chunk
|
||||||
geometry_bank::data( geometrychunk_handle const Chunk ) {
|
bool
|
||||||
|
geometry_bank::append( vertex_array &Vertices, geometry_handle const &Geometry ) {
|
||||||
|
|
||||||
return m_chunks.at( Chunk - 1 ).vertices;
|
if( ( Geometry.chunk == 0 ) || ( Geometry.chunk > m_chunks.size() ) ) { return false; }
|
||||||
|
|
||||||
|
return replace( Vertices, Geometry, geometry_bank::chunk( Geometry ).vertices.size() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// draws geometry stored in specified chunk
|
||||||
|
void
|
||||||
|
geometry_bank::draw( geometry_handle const &Geometry ) {
|
||||||
|
// template method
|
||||||
|
draw_( Geometry );
|
||||||
|
}
|
||||||
|
|
||||||
|
vertex_array const &
|
||||||
|
geometry_bank::vertices( geometry_handle const &Geometry ) const {
|
||||||
|
|
||||||
|
return geometry_bank::chunk( Geometry ).vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
// opengl vbo-based variant of the geometry bank
|
// opengl vbo-based variant of the geometry bank
|
||||||
|
|
||||||
GLuint opengl_vbogeometrybank::m_activebuffer{ NULL }; // buffer bound currently on the opengl end, if any
|
GLuint opengl_vbogeometrybank::m_activebuffer{ NULL }; // buffer bound currently on the opengl end, if any
|
||||||
|
|
||||||
// creates a new geometry chunk of specified type from supplied vertex data. returns: handle to the chunk
|
// create() subclass details
|
||||||
geometrychunk_handle
|
void
|
||||||
opengl_vbogeometrybank::create( vertex_array &Vertices, int const Datatype ) {
|
opengl_vbogeometrybank::create_( geometry_handle const &Geometry ) {
|
||||||
|
// adding a chunk means we'll be (re)building the buffer, which will fill the chunk records, amongst other things.
|
||||||
auto const handle = geometry_bank::create( Vertices, Datatype );
|
// thus we don't need to initialize the values here
|
||||||
if( handle == NULL ) {
|
|
||||||
// if we didn't get anything, bail early
|
|
||||||
return handle;
|
|
||||||
}
|
|
||||||
// adding a chunk means we'll be (re)building the buffer, which will fill the chunk records, amongst other things
|
|
||||||
// so we don't need to initialize the values here
|
|
||||||
m_chunkrecords.emplace_back( chunk_record() );
|
m_chunkrecords.emplace_back( chunk_record() );
|
||||||
// kiss the existing buffer goodbye, new overall data size means we'll be making a new one
|
// kiss the existing buffer goodbye, new overall data size means we'll be making a new one
|
||||||
delete_buffer();
|
delete_buffer();
|
||||||
|
|
||||||
return handle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// replaces data of specified chunk with the supplied vertex data, starting from specified offset
|
// replace() subclass details
|
||||||
bool
|
void
|
||||||
opengl_vbogeometrybank::replace( vertex_array &Vertices, geometrychunk_handle const Chunk, std::size_t const Offset ) {
|
opengl_vbogeometrybank::replace_( geometry_handle const &Geometry ) {
|
||||||
|
|
||||||
auto const result = geometry_bank::replace( Vertices, Chunk, Offset );
|
auto &chunkrecord = m_chunkrecords[ Geometry.chunk - 1 ];
|
||||||
if( false == result ) {
|
|
||||||
// if nothing happened we can bail out early
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
auto &chunkrecord = m_chunkrecords[ Chunk - 1 ];
|
|
||||||
chunkrecord.is_good = false;
|
chunkrecord.is_good = false;
|
||||||
// if the overall length of the chunk didn't change we can get away with reusing the old buffer...
|
// if the overall length of the chunk didn't change we can get away with reusing the old buffer...
|
||||||
if( m_chunks[ Chunk - 1 ].vertices.size() != chunkrecord.size ) {
|
if( geometry_bank::chunk( Geometry ).vertices.size() != chunkrecord.size ) {
|
||||||
// ...but otherwise we'll need to allocate a new one
|
// ...but otherwise we'll need to allocate a new one
|
||||||
// TBD: we could keep and reuse the old buffer also if the new chunk is smaller than the old one,
|
// TBD: we could keep and reuse the old buffer also if the new chunk is smaller than the old one,
|
||||||
// but it'd require some extra tracking and work to keep all chunks up to date; also wasting vram; may be not worth it?
|
// but it'd require some extra tracking and work to keep all chunks up to date; also wasting vram; may be not worth it?
|
||||||
delete_buffer();
|
delete_buffer();
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// draws geometry stored in specified chunk
|
// draw() subclass details
|
||||||
void
|
void
|
||||||
opengl_vbogeometrybank::draw( geometrychunk_handle const Chunk ) {
|
opengl_vbogeometrybank::draw_( geometry_handle const &Geometry ) {
|
||||||
|
|
||||||
if( m_buffer == NULL ) {
|
if( m_buffer == NULL ) {
|
||||||
// if there's no buffer, we'll have to make one
|
// if there's no buffer, we'll have to make one
|
||||||
@@ -138,13 +149,13 @@ opengl_vbogeometrybank::draw( geometrychunk_handle const Chunk ) {
|
|||||||
if( true == m_chunks.empty() ) { return; }
|
if( true == m_chunks.empty() ) { return; }
|
||||||
|
|
||||||
std::size_t datasize{ 0 };
|
std::size_t datasize{ 0 };
|
||||||
auto &chunkrecord = m_chunkrecords.begin();
|
auto chunkiterator = m_chunks.cbegin();
|
||||||
for( auto &chunk : m_chunks ) {
|
for( auto &chunkrecord : m_chunkrecords ) {
|
||||||
// fill all chunk records, based on the chunk data
|
// fill records for all chunks, based on the chunk data
|
||||||
chunkrecord->offset = datasize;
|
chunkrecord.offset = datasize;
|
||||||
chunkrecord->size = chunk.vertices.size();
|
chunkrecord.size = chunkiterator->vertices.size();
|
||||||
datasize += chunkrecord->size;
|
datasize += chunkrecord.size;
|
||||||
++chunkrecord;
|
++chunkiterator;
|
||||||
}
|
}
|
||||||
// the odds for all created chunks to get replaced with empty ones are quite low, but the possibility does exist
|
// the odds for all created chunks to get replaced with empty ones are quite low, but the possibility does exist
|
||||||
if( datasize == 0 ) { return; }
|
if( datasize == 0 ) { return; }
|
||||||
@@ -158,6 +169,12 @@ opengl_vbogeometrybank::draw( geometrychunk_handle const Chunk ) {
|
|||||||
datasize * sizeof( basic_vertex ),
|
datasize * sizeof( basic_vertex ),
|
||||||
nullptr,
|
nullptr,
|
||||||
GL_STATIC_DRAW );
|
GL_STATIC_DRAW );
|
||||||
|
if( ::glGetError() == GL_OUT_OF_MEMORY ) {
|
||||||
|
// TBD: throw a bad_alloc?
|
||||||
|
ErrorLog( "openGL error: out of memory; failed to create a geometry buffer" );
|
||||||
|
delete_buffer();
|
||||||
|
return;
|
||||||
|
}
|
||||||
m_buffercapacity = datasize;
|
m_buffercapacity = datasize;
|
||||||
}
|
}
|
||||||
// actual draw procedure starts here
|
// actual draw procedure starts here
|
||||||
@@ -165,8 +182,8 @@ opengl_vbogeometrybank::draw( geometrychunk_handle const Chunk ) {
|
|||||||
if( m_activebuffer != m_buffer ) {
|
if( m_activebuffer != m_buffer ) {
|
||||||
bind_buffer();
|
bind_buffer();
|
||||||
}
|
}
|
||||||
auto &chunkrecord = m_chunkrecords[ Chunk - 1 ];
|
auto &chunkrecord = m_chunkrecords[ Geometry.chunk - 1 ];
|
||||||
auto const &chunk = m_chunks[ Chunk - 1 ];
|
auto const &chunk = geometry_bank::chunk( Geometry );
|
||||||
if( false == chunkrecord.is_good ) {
|
if( false == chunkrecord.is_good ) {
|
||||||
// we may potentially need to upload new buffer data before we can draw it
|
// we may potentially need to upload new buffer data before we can draw it
|
||||||
::glBufferSubData(
|
::glBufferSubData(
|
||||||
@@ -216,3 +233,103 @@ opengl_vbogeometrybank::delete_buffer() {
|
|||||||
m_buffercapacity = 0;
|
m_buffercapacity = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// opengl display list based variant of the geometry bank
|
||||||
|
|
||||||
|
// create() subclass details
|
||||||
|
void
|
||||||
|
opengl_dlgeometrybank::create_( geometry_handle const &Geometry ) {
|
||||||
|
|
||||||
|
m_chunkrecords.emplace_back( chunk_record() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// replace() subclass details
|
||||||
|
void
|
||||||
|
opengl_dlgeometrybank::replace_( geometry_handle const &Geometry ) {
|
||||||
|
|
||||||
|
delete_list( Geometry );
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw() subclass details
|
||||||
|
void
|
||||||
|
opengl_dlgeometrybank::draw_( geometry_handle const &Geometry ) {
|
||||||
|
|
||||||
|
auto &chunkrecord = m_chunkrecords[ Geometry.chunk - 1 ];
|
||||||
|
if( chunkrecord.list == 0 ) {
|
||||||
|
// we don't have a list ready, so compile one
|
||||||
|
chunkrecord.list = ::glGenLists( 1 );
|
||||||
|
auto const &chunk = geometry_bank::chunk( Geometry );
|
||||||
|
::glNewList( chunkrecord.list, GL_COMPILE );
|
||||||
|
|
||||||
|
::glBegin( chunk.type );
|
||||||
|
// TODO: add specification of chunk vertex attributes
|
||||||
|
for( auto const &vertex : chunk.vertices ) {
|
||||||
|
::glNormal3fv( glm::value_ptr( vertex.normal ) );
|
||||||
|
::glTexCoord2fv( glm::value_ptr( vertex.texture ) );
|
||||||
|
::glVertex3fv( glm::value_ptr( vertex.position ) );
|
||||||
|
}
|
||||||
|
::glEnd();
|
||||||
|
::glEndList();
|
||||||
|
}
|
||||||
|
// with the list done we can just play it
|
||||||
|
::glCallList( chunkrecord.list );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
opengl_dlgeometrybank::delete_list( geometry_handle const &Geometry ) {
|
||||||
|
// NOTE: given it's our own internal method we trust it to be called with valid parameters
|
||||||
|
auto &chunkrecord = m_chunkrecords[ Geometry.chunk - 1 ];
|
||||||
|
::glDeleteLists( chunkrecord.list, 1 );
|
||||||
|
chunkrecord.list = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// geometry bank manager, holds collection of geometry banks
|
||||||
|
|
||||||
|
// creates a new geometry bank. returns: handle to the bank or NULL
|
||||||
|
geometrybank_handle
|
||||||
|
geometrybank_manager::create_bank() {
|
||||||
|
|
||||||
|
if( true == Global::bUseVBO ) { m_geometrybanks.emplace_back( std::make_shared<opengl_vbogeometrybank>() ); }
|
||||||
|
else { m_geometrybanks.emplace_back( std::make_shared<opengl_dlgeometrybank>() ); }
|
||||||
|
// NOTE: handle is effectively (index into chunk array + 1) this leaves value of 0 to serve as error/empty handle indication
|
||||||
|
return geometrybank_handle( m_geometrybanks.size(), 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// creates a new geometry chunk of specified type from supplied vertex data, in specified bank. returns: handle to the chunk or NULL
|
||||||
|
geometry_handle
|
||||||
|
geometrybank_manager::create_chunk( vertex_array &Vertices, geometrybank_handle const &Geometry, int const Type ) {
|
||||||
|
|
||||||
|
auto const newchunkhandle = bank( Geometry )->create( Vertices, Type );
|
||||||
|
|
||||||
|
if( newchunkhandle.chunk != 0 ) { return geometry_handle( Geometry.bank, newchunkhandle.chunk ); }
|
||||||
|
else { return geometry_handle( 0, 0 ); }
|
||||||
|
}
|
||||||
|
|
||||||
|
// replaces data of specified chunk with the supplied vertex data, starting from specified offset
|
||||||
|
bool
|
||||||
|
geometrybank_manager::replace( vertex_array &Vertices, geometry_handle const &Geometry, std::size_t const Offset ) {
|
||||||
|
|
||||||
|
return bank( Geometry )->replace( Vertices, Geometry, Offset );
|
||||||
|
}
|
||||||
|
|
||||||
|
// adds supplied vertex data at the end of specified chunk
|
||||||
|
bool
|
||||||
|
geometrybank_manager::append( vertex_array &Vertices, geometry_handle const &Geometry ) {
|
||||||
|
|
||||||
|
return bank( Geometry )->append( Vertices, Geometry );
|
||||||
|
}
|
||||||
|
// draws geometry stored in specified chunk
|
||||||
|
void
|
||||||
|
geometrybank_manager::draw( geometry_handle const &Geometry ) {
|
||||||
|
|
||||||
|
if( Geometry == NULL ) { return; }
|
||||||
|
|
||||||
|
return bank( Geometry )->draw( Geometry );
|
||||||
|
}
|
||||||
|
|
||||||
|
// provides direct access to vertex data of specfied chunk
|
||||||
|
vertex_array const &
|
||||||
|
geometrybank_manager::vertices( geometry_handle const &Geometry ) const {
|
||||||
|
|
||||||
|
return bank( Geometry )->vertices( Geometry );
|
||||||
|
}
|
||||||
|
|||||||
@@ -30,7 +30,23 @@ typedef std::vector<basic_vertex> vertex_array;
|
|||||||
|
|
||||||
// generic geometry bank class, allows storage, update and drawing of geometry chunks
|
// generic geometry bank class, allows storage, update and drawing of geometry chunks
|
||||||
|
|
||||||
typedef std::size_t geometrychunk_handle;
|
struct geometry_handle {
|
||||||
|
// constructors
|
||||||
|
geometry_handle() :
|
||||||
|
bank( 0 ), chunk( 0 )
|
||||||
|
{}
|
||||||
|
geometry_handle( std::uint32_t const Bank, std::uint32_t const Chunk ) :
|
||||||
|
bank( Bank ), chunk( Chunk )
|
||||||
|
{}
|
||||||
|
// methods
|
||||||
|
inline
|
||||||
|
operator std::uint32_t() const {
|
||||||
|
return bank << 12 | chunk; }
|
||||||
|
// members
|
||||||
|
std::uint32_t
|
||||||
|
bank : 20, // 1 mil banks
|
||||||
|
chunk : 12; // 4 k chunks per bank
|
||||||
|
};
|
||||||
|
|
||||||
class geometry_bank {
|
class geometry_bank {
|
||||||
|
|
||||||
@@ -41,27 +57,28 @@ public:
|
|||||||
|
|
||||||
// destructor:
|
// destructor:
|
||||||
virtual
|
virtual
|
||||||
~geometry_bank() { ; }
|
~geometry_bank() {}
|
||||||
|
|
||||||
// methods:
|
// methods:
|
||||||
// creates a new geometry chunk of specified type from supplied vertex data. returns: handle to the chunk or NULL
|
// creates a new geometry chunk of specified type from supplied vertex data. returns: handle to the chunk or NULL
|
||||||
virtual
|
geometry_handle
|
||||||
geometrychunk_handle
|
create( vertex_array &Vertices, int const Type );
|
||||||
create( vertex_array &Vertices, int const Datatype );
|
|
||||||
// replaces data of specified chunk with the supplied vertex data, starting from specified offset
|
// replaces data of specified chunk with the supplied vertex data, starting from specified offset
|
||||||
virtual
|
|
||||||
bool
|
bool
|
||||||
replace( vertex_array &Vertices, geometrychunk_handle const Chunk, std::size_t const Offset = 0 );
|
replace( vertex_array &Vertices, geometry_handle const &Geometry, std::size_t const Offset = 0 );
|
||||||
|
// adds supplied vertex data at the end of specified chunk
|
||||||
|
bool
|
||||||
|
append( vertex_array &Vertices, geometry_handle const &Geometry );
|
||||||
// draws geometry stored in specified chunk
|
// draws geometry stored in specified chunk
|
||||||
virtual
|
|
||||||
void
|
void
|
||||||
draw( geometrychunk_handle const Chunk ) = 0;
|
draw( geometry_handle const &Geometry );
|
||||||
// draws geometry stored in supplied list of chunks
|
// draws geometry stored in supplied list of chunks
|
||||||
template <typename _Iterator>
|
template <typename Iterator_>
|
||||||
void
|
void
|
||||||
draw( _Iterator First, _Iterator Last ) { while( First != Last ) { draw( *First ); ++First; } }
|
draw( Iterator_ First, Iterator_ Last ) { while( First != Last ) { draw( *First ); ++First; } }
|
||||||
vertex_array &
|
// provides direct access to vertex data of specfied chunk
|
||||||
data( geometrychunk_handle const Chunk );
|
vertex_array const &
|
||||||
|
vertices( geometry_handle const &Geometry ) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// types:
|
// types:
|
||||||
@@ -69,16 +86,34 @@ protected:
|
|||||||
int type; // kind of geometry used by the chunk
|
int type; // kind of geometry used by the chunk
|
||||||
vertex_array vertices; // geometry data
|
vertex_array vertices; // geometry data
|
||||||
|
|
||||||
geometry_chunk( vertex_array &Vertices, int const Datatype ) :
|
geometry_chunk( vertex_array &Vertices, int const Type ) :
|
||||||
vertices( Vertices ), type( Datatype )
|
vertices( Vertices ), type( Type )
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<geometry_chunk> geometrychunk_sequence;
|
typedef std::vector<geometry_chunk> geometrychunk_sequence;
|
||||||
|
|
||||||
|
// methods
|
||||||
|
inline
|
||||||
|
geometry_chunk &
|
||||||
|
chunk( geometry_handle const Geometry ) {
|
||||||
|
return m_chunks[ Geometry.chunk - 1 ]; }
|
||||||
|
inline
|
||||||
|
geometry_chunk const &
|
||||||
|
chunk( geometry_handle const Geometry ) const {
|
||||||
|
return m_chunks[ Geometry.chunk - 1 ]; }
|
||||||
|
|
||||||
// members:
|
// members:
|
||||||
geometrychunk_sequence m_chunks;
|
geometrychunk_sequence m_chunks;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// methods:
|
||||||
|
// create() subclass details
|
||||||
|
virtual void create_( geometry_handle const &Geometry ) = 0;
|
||||||
|
// replace() subclass details
|
||||||
|
virtual void replace_( geometry_handle const &Geometry ) = 0;
|
||||||
|
// draw() subclass details
|
||||||
|
virtual void draw_( geometry_handle const &Geometry ) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// opengl vbo-based variant of the geometry bank
|
// opengl vbo-based variant of the geometry bank
|
||||||
@@ -87,15 +122,8 @@ class opengl_vbogeometrybank : public geometry_bank {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// methods:
|
// methods:
|
||||||
// creates a new geometry chunk of specified type from supplied vertex data. returns: handle to the chunk or NULL
|
~opengl_vbogeometrybank() {
|
||||||
geometrychunk_handle
|
delete_buffer(); }
|
||||||
create( vertex_array &Vertices, int const Datatype );
|
|
||||||
// replaces data of specified chunk with the supplied vertex data, starting from specified offset
|
|
||||||
bool
|
|
||||||
replace( vertex_array &Vertices, geometrychunk_handle const Chunk, std::size_t const Offset = 0 );
|
|
||||||
// draws geometry stored in specified chunk
|
|
||||||
void
|
|
||||||
draw( geometrychunk_handle const Chunk );
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// types:
|
// types:
|
||||||
@@ -108,6 +136,15 @@ private:
|
|||||||
typedef std::vector<chunk_record> chunkrecord_sequence;
|
typedef std::vector<chunk_record> chunkrecord_sequence;
|
||||||
|
|
||||||
// methods:
|
// methods:
|
||||||
|
// create() subclass details
|
||||||
|
void
|
||||||
|
create_( geometry_handle const &Geometry );
|
||||||
|
// replace() subclass details
|
||||||
|
void
|
||||||
|
replace_( geometry_handle const &Geometry );
|
||||||
|
// draw() subclass details
|
||||||
|
void
|
||||||
|
draw_( geometry_handle const &Geometry );
|
||||||
void
|
void
|
||||||
bind_buffer();
|
bind_buffer();
|
||||||
void
|
void
|
||||||
@@ -120,3 +157,90 @@ private:
|
|||||||
chunkrecord_sequence m_chunkrecords; // helper data for all stored geometry chunks, in matching order
|
chunkrecord_sequence m_chunkrecords; // helper data for all stored geometry chunks, in matching order
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// opengl display list based variant of the geometry bank
|
||||||
|
|
||||||
|
class opengl_dlgeometrybank : public geometry_bank {
|
||||||
|
|
||||||
|
public:
|
||||||
|
// methods:
|
||||||
|
~opengl_dlgeometrybank() {
|
||||||
|
for( auto &chunkrecord : m_chunkrecords ) {
|
||||||
|
::glDeleteLists( chunkrecord.list, 1 ); } }
|
||||||
|
|
||||||
|
private:
|
||||||
|
// types:
|
||||||
|
struct chunk_record {
|
||||||
|
GLuint list{ 0 }; // display list associated with the chunk
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::vector<chunk_record> chunkrecord_sequence;
|
||||||
|
|
||||||
|
// methods:
|
||||||
|
// create() subclass details
|
||||||
|
void
|
||||||
|
create_( geometry_handle const &Geometry );
|
||||||
|
// replace() subclass details
|
||||||
|
void
|
||||||
|
replace_( geometry_handle const &Geometry );
|
||||||
|
// draw() subclass details
|
||||||
|
void
|
||||||
|
draw_( geometry_handle const &Geometry );
|
||||||
|
void
|
||||||
|
delete_list( geometry_handle const &Geometry );
|
||||||
|
|
||||||
|
// members:
|
||||||
|
chunkrecord_sequence m_chunkrecords; // helper data for all stored geometry chunks, in matching order
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// geometry bank manager, holds collection of geometry banks
|
||||||
|
|
||||||
|
typedef geometry_handle geometrybank_handle;
|
||||||
|
|
||||||
|
class geometrybank_manager {
|
||||||
|
|
||||||
|
public:
|
||||||
|
// methods:
|
||||||
|
// creates a new geometry bank. returns: handle to the bank or NULL
|
||||||
|
geometrybank_handle
|
||||||
|
create_bank();
|
||||||
|
// creates a new geometry chunk of specified type from supplied vertex data, in specified bank. returns: handle to the chunk or NULL
|
||||||
|
geometry_handle
|
||||||
|
create_chunk( vertex_array &Vertices, geometrybank_handle const &Geometry, int const Type );
|
||||||
|
// replaces data of specified chunk with the supplied vertex data, starting from specified offset
|
||||||
|
bool
|
||||||
|
replace( vertex_array &Vertices, geometry_handle const &Geometry, std::size_t const Offset = 0 );
|
||||||
|
// adds supplied vertex data at the end of specified chunk
|
||||||
|
bool
|
||||||
|
append( vertex_array &Vertices, geometry_handle const &Geometry );
|
||||||
|
// draws geometry stored in specified chunk
|
||||||
|
void
|
||||||
|
draw( geometry_handle const &Geometry );
|
||||||
|
// provides direct access to vertex data of specfied chunk
|
||||||
|
vertex_array const &
|
||||||
|
vertices( geometry_handle const &Geometry ) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// types:
|
||||||
|
typedef std::deque< std::shared_ptr<geometry_bank> > geometrybank_sequence;
|
||||||
|
|
||||||
|
// members:
|
||||||
|
geometrybank_sequence m_geometrybanks;
|
||||||
|
|
||||||
|
// methods
|
||||||
|
inline
|
||||||
|
bool
|
||||||
|
valid( geometry_handle const &Geometry ) {
|
||||||
|
return ( ( Geometry.bank != 0 )
|
||||||
|
&& ( Geometry.bank <= m_geometrybanks.size() ) ); }
|
||||||
|
inline
|
||||||
|
geometrybank_sequence::value_type &
|
||||||
|
bank( geometry_handle const Geometry ) {
|
||||||
|
return m_geometrybanks[ Geometry.bank - 1 ]; }
|
||||||
|
inline
|
||||||
|
geometrybank_sequence::value_type const &
|
||||||
|
bank( geometry_handle const Geometry ) const {
|
||||||
|
return m_geometrybanks[ Geometry.bank - 1 ]; }
|
||||||
|
|
||||||
|
};
|
||||||
@@ -109,39 +109,39 @@ public:
|
|||||||
pop_matrix() { m_stacks[ m_mode ].pop_matrix(); }
|
pop_matrix() { m_stacks[ m_mode ].pop_matrix(); }
|
||||||
void
|
void
|
||||||
load_identity() { m_stacks[ m_mode ].load_identity(); }
|
load_identity() { m_stacks[ m_mode ].load_identity(); }
|
||||||
template <typename _Type>
|
template <typename Type_>
|
||||||
void
|
void
|
||||||
rotate( _Type const Angle, _Type const X, _Type const Y, _Type const Z ) {
|
rotate( Type_ const Angle, Type_ const X, Type_ const Y, Type_ const Z ) {
|
||||||
m_stacks[ m_mode ].rotate(
|
m_stacks[ m_mode ].rotate(
|
||||||
static_cast<float>(Angle) * 0.0174532925f, // deg2rad
|
static_cast<float>(Angle) * 0.0174532925f, // deg2rad
|
||||||
glm::vec3(
|
glm::vec3(
|
||||||
static_cast<float>(X),
|
static_cast<float>(X),
|
||||||
static_cast<float>(Y),
|
static_cast<float>(Y),
|
||||||
static_cast<float>(Z) ) ); }
|
static_cast<float>(Z) ) ); }
|
||||||
template <typename _Type>
|
template <typename Type_>
|
||||||
void
|
void
|
||||||
translate( _Type const X, _Type const Y, _Type const Z ) {
|
translate( Type_ const X, Type_ const Y, Type_ const Z ) {
|
||||||
m_stacks[ m_mode ].translate(
|
m_stacks[ m_mode ].translate(
|
||||||
glm::vec3(
|
glm::vec3(
|
||||||
static_cast<float>( X ),
|
static_cast<float>( X ),
|
||||||
static_cast<float>( Y ),
|
static_cast<float>( Y ),
|
||||||
static_cast<float>( Z ) ) ); }
|
static_cast<float>( Z ) ) ); }
|
||||||
template <typename _Type>
|
template <typename Type_>
|
||||||
void
|
void
|
||||||
multiply( _Type const *Matrix ) {
|
multiply( Type_ const *Matrix ) {
|
||||||
m_stacks[ m_mode ].multiply(
|
m_stacks[ m_mode ].multiply(
|
||||||
glm::make_mat4( Matrix ) ); }
|
glm::make_mat4( Matrix ) ); }
|
||||||
template <typename _Type>
|
template <typename Type_>
|
||||||
void
|
void
|
||||||
perspective( _Type const Fovy, _Type const Aspect, _Type const Znear, _Type const Zfar ) {
|
perspective( Type_ const Fovy, Type_ const Aspect, Type_ const Znear, Type_ const Zfar ) {
|
||||||
m_stacks[ m_mode ].perspective(
|
m_stacks[ m_mode ].perspective(
|
||||||
static_cast<float>(Fovy) * 0.0174532925f, // deg2rad
|
static_cast<float>(Fovy) * 0.0174532925f, // deg2rad
|
||||||
static_cast<float>( Aspect ),
|
static_cast<float>( Aspect ),
|
||||||
static_cast<float>( Znear ),
|
static_cast<float>( Znear ),
|
||||||
static_cast<float>( Zfar ) ); }
|
static_cast<float>( Zfar ) ); }
|
||||||
template <typename _Type>
|
template <typename Type_>
|
||||||
void
|
void
|
||||||
look_at( _Type const Eyex, _Type const Eyey, _Type const Eyez, _Type const Centerx, _Type const Centery, _Type const Centerz, _Type const Upx, _Type const Upy, _Type const Upz ) {
|
look_at( Type_ const Eyex, Type_ const Eyey, Type_ const Eyez, Type_ const Centerx, Type_ const Centery, Type_ const Centerz, Type_ const Upx, Type_ const Upy, Type_ const Upz ) {
|
||||||
m_stacks[ m_mode ].look_at(
|
m_stacks[ m_mode ].look_at(
|
||||||
glm::vec3(
|
glm::vec3(
|
||||||
static_cast<float>( Eyex ),
|
static_cast<float>( Eyex ),
|
||||||
|
|||||||
8
parser.h
8
parser.h
@@ -32,9 +32,9 @@ class cParser //: public std::stringstream
|
|||||||
// destructor:
|
// destructor:
|
||||||
virtual ~cParser();
|
virtual ~cParser();
|
||||||
// methods:
|
// methods:
|
||||||
template <typename _Type>
|
template <typename Type_>
|
||||||
cParser&
|
cParser&
|
||||||
operator>>( _Type &Right );
|
operator>>( Type_ &Right );
|
||||||
template <>
|
template <>
|
||||||
cParser&
|
cParser&
|
||||||
operator>>( std::string &Right );
|
operator>>( std::string &Right );
|
||||||
@@ -107,9 +107,9 @@ class cParser //: public std::stringstream
|
|||||||
std::deque<std::string> tokens;
|
std::deque<std::string> tokens;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename _Type>
|
template<typename Type_>
|
||||||
cParser&
|
cParser&
|
||||||
cParser::operator>>( _Type &Right ) {
|
cParser::operator>>( Type_ &Right ) {
|
||||||
|
|
||||||
if( true == this->tokens.empty() ) { return *this; }
|
if( true == this->tokens.empty() ) { return *this; }
|
||||||
|
|
||||||
|
|||||||
200
renderer.cpp
200
renderer.cpp
@@ -142,10 +142,7 @@ opengl_renderer::Render() {
|
|||||||
::glLoadIdentity();
|
::glLoadIdentity();
|
||||||
|
|
||||||
if( World.InitPerformed() ) {
|
if( World.InitPerformed() ) {
|
||||||
/*
|
|
||||||
World.Camera.SetMatrix();
|
|
||||||
m_camera.update_frustum();
|
|
||||||
*/
|
|
||||||
glm::dmat4 worldcamera;
|
glm::dmat4 worldcamera;
|
||||||
World.Camera.SetMatrix( worldcamera );
|
World.Camera.SetMatrix( worldcamera );
|
||||||
m_camera.update_frustum( OpenGLMatrices.data( GL_PROJECTION ), worldcamera );
|
m_camera.update_frustum( OpenGLMatrices.data( GL_PROJECTION ), worldcamera );
|
||||||
@@ -182,15 +179,6 @@ opengl_renderer::Render( world_environment *Environment ) {
|
|||||||
::glDisable( GL_DEPTH_TEST );
|
::glDisable( GL_DEPTH_TEST );
|
||||||
::glDepthMask( GL_FALSE );
|
::glDepthMask( GL_FALSE );
|
||||||
::glPushMatrix();
|
::glPushMatrix();
|
||||||
/*
|
|
||||||
::glTranslatef( Global::pCameraPosition.x, Global::pCameraPosition.y, Global::pCameraPosition.z );
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
glm::mat4 worldcamera;
|
|
||||||
World.Camera.SetMatrix( worldcamera );
|
|
||||||
glLoadIdentity();
|
|
||||||
glMultMatrixf( glm::value_ptr( glm::mat4( glm::mat3( worldcamera ) ) ) );
|
|
||||||
*/
|
|
||||||
// setup fog
|
// setup fog
|
||||||
if( Global::fFogEnd > 0 ) {
|
if( Global::fFogEnd > 0 ) {
|
||||||
// fog setup
|
// fog setup
|
||||||
@@ -300,6 +288,63 @@ opengl_renderer::Render( world_environment *Environment ) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// geometry methods
|
||||||
|
// creates a new geometry bank. returns: handle to the bank or NULL
|
||||||
|
geometrybank_handle
|
||||||
|
opengl_renderer::Create_Bank() {
|
||||||
|
|
||||||
|
return m_geometry.create_bank();
|
||||||
|
}
|
||||||
|
|
||||||
|
// creates a new geometry chunk of specified type from supplied vertex data, in specified bank. returns: handle to the chunk or NULL
|
||||||
|
geometry_handle
|
||||||
|
opengl_renderer::Insert( vertex_array &Vertices, geometrybank_handle const &Geometry, int const Type ) {
|
||||||
|
|
||||||
|
return m_geometry.create_chunk( Vertices, Geometry, Type );
|
||||||
|
}
|
||||||
|
|
||||||
|
// replaces data of specified chunk with the supplied vertex data, starting from specified offset
|
||||||
|
bool
|
||||||
|
opengl_renderer::Replace( vertex_array &Vertices, geometry_handle const &Geometry, std::size_t const Offset ) {
|
||||||
|
|
||||||
|
return m_geometry.replace( Vertices, Geometry, Offset );
|
||||||
|
}
|
||||||
|
|
||||||
|
// adds supplied vertex data at the end of specified chunk
|
||||||
|
bool
|
||||||
|
opengl_renderer::Append( vertex_array &Vertices, geometry_handle const &Geometry ) {
|
||||||
|
|
||||||
|
return m_geometry.append( Vertices, Geometry );
|
||||||
|
}
|
||||||
|
|
||||||
|
// provides direct access to vertex data of specfied chunk
|
||||||
|
vertex_array const &
|
||||||
|
opengl_renderer::Vertices( geometry_handle const &Geometry ) const {
|
||||||
|
|
||||||
|
return m_geometry.vertices( Geometry );
|
||||||
|
}
|
||||||
|
|
||||||
|
// texture methods
|
||||||
|
texture_handle
|
||||||
|
opengl_renderer::GetTextureId( std::string Filename, std::string const &Dir, int const Filter, bool const Loadnow ) {
|
||||||
|
|
||||||
|
return m_textures.create( Filename, Dir, Filter, Loadnow );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
opengl_renderer::Bind( texture_handle const Texture ) {
|
||||||
|
// temporary until we separate the renderer
|
||||||
|
m_textures.bind( Texture );
|
||||||
|
}
|
||||||
|
|
||||||
|
opengl_texture &
|
||||||
|
opengl_renderer::Texture( texture_handle const Texture ) {
|
||||||
|
|
||||||
|
return m_textures.texture( Texture );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
opengl_renderer::Render( TGround *Ground ) {
|
opengl_renderer::Render( TGround *Ground ) {
|
||||||
|
|
||||||
@@ -698,16 +743,7 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
|||||||
double const squaredistance = SquareMagnitude( originoffset / Global::ZoomFactor );
|
double const squaredistance = SquareMagnitude( originoffset / Global::ZoomFactor );
|
||||||
Dynamic->ABuLittleUpdate( squaredistance ); // ustawianie zmiennych submodeli dla wspólnego modelu
|
Dynamic->ABuLittleUpdate( squaredistance ); // ustawianie zmiennych submodeli dla wspólnego modelu
|
||||||
::glPushMatrix();
|
::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
|
|
||||||
*/
|
|
||||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||||
::glMultMatrixd( Dynamic->mMatrix.getArray() );
|
::glMultMatrixd( Dynamic->mMatrix.getArray() );
|
||||||
|
|
||||||
@@ -773,14 +809,7 @@ opengl_renderer::Render( TModel3d *Model, material_data const *Material, double
|
|||||||
|
|
||||||
Model->Root->fSquareDist = Squaredistance; // zmienna globalna!
|
Model->Root->fSquareDist = Squaredistance; // zmienna globalna!
|
||||||
|
|
||||||
// TODO: unify the render code after generic buffers are in place
|
|
||||||
// setup
|
// setup
|
||||||
/*
|
|
||||||
if( Global::bUseVBO ) {
|
|
||||||
if( false == Model->StartVBO() )
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
Model->Root->ReplacableSet(
|
Model->Root->ReplacableSet(
|
||||||
( Material != nullptr ?
|
( Material != nullptr ?
|
||||||
Material->replacable_skins :
|
Material->replacable_skins :
|
||||||
@@ -793,9 +822,6 @@ opengl_renderer::Render( TModel3d *Model, material_data const *Material, double
|
|||||||
Render( Model->Root );
|
Render( Model->Root );
|
||||||
|
|
||||||
// post-render cleanup
|
// post-render cleanup
|
||||||
if( Global::bUseVBO ) {
|
|
||||||
// Model->EndVBO();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -812,7 +838,6 @@ opengl_renderer::Render( TModel3d *Model, material_data const *Material, Math3D:
|
|||||||
if( Angle.z != 0.0 )
|
if( Angle.z != 0.0 )
|
||||||
::glRotated( Angle.z, 0.0, 0.0, 1.0 );
|
::glRotated( Angle.z, 0.0, 0.0, 1.0 );
|
||||||
|
|
||||||
// auto const result = Render( Model, Material, SquareMagnitude( Position / Global::ZoomFactor ) ); // position is effectively camera offset
|
|
||||||
auto const result = Render( Model, Material, SquareMagnitude( Position ) ); // position is effectively camera offset
|
auto const result = Render( Model, Material, SquareMagnitude( Position ) ); // position is effectively camera offset
|
||||||
|
|
||||||
::glPopMatrix();
|
::glPopMatrix();
|
||||||
@@ -856,16 +881,8 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
|||||||
::glMaterialfv( GL_FRONT, GL_EMISSION, Submodel->f4Diffuse );
|
::glMaterialfv( GL_FRONT, GL_EMISSION, Submodel->f4Diffuse );
|
||||||
}
|
}
|
||||||
|
|
||||||
// main draw call. TODO: generic buffer base class, specialized for vbo, dl etc
|
// main draw call
|
||||||
if( Global::bUseVBO ) {
|
m_geometry.draw( Submodel->m_geometry );
|
||||||
/*
|
|
||||||
::glDrawArrays( Submodel->eType, Submodel->iVboPtr, Submodel->iNumVerts );
|
|
||||||
*/
|
|
||||||
Submodel->pRoot->m_geometry->draw( Submodel->m_chunk );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
::glCallList( Submodel->uiDisplayList );
|
|
||||||
}
|
|
||||||
|
|
||||||
// post-draw reset
|
// post-draw reset
|
||||||
if( Global::fLuminance < Submodel->fLight ) {
|
if( Global::fLuminance < Submodel->fLight ) {
|
||||||
@@ -900,16 +917,8 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
|||||||
::glDisable( GL_LIGHTING );
|
::glDisable( GL_LIGHTING );
|
||||||
::glEnable( GL_BLEND );
|
::glEnable( GL_BLEND );
|
||||||
|
|
||||||
// main draw call. TODO: generic buffer base class, specialized for vbo, dl etc
|
// main draw call
|
||||||
if( Global::bUseVBO ) {
|
m_geometry.draw( Submodel->m_geometry );
|
||||||
/*
|
|
||||||
::glDrawArrays( GL_POINTS, Submodel->iVboPtr, Submodel->iNumVerts );
|
|
||||||
*/
|
|
||||||
Submodel->pRoot->m_geometry->draw( Submodel->m_chunk );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
::glCallList( Submodel->uiDisplayList );
|
|
||||||
}
|
|
||||||
|
|
||||||
// post-draw reset
|
// post-draw reset
|
||||||
::glPopAttrib();
|
::glPopAttrib();
|
||||||
@@ -926,9 +935,11 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
|||||||
Bind( 0 );
|
Bind( 0 );
|
||||||
::glDisable( GL_LIGHTING );
|
::glDisable( GL_LIGHTING );
|
||||||
|
|
||||||
// main draw call. TODO: generic buffer base class, specialized for vbo, dl etc
|
// main draw call
|
||||||
if( Global::bUseVBO ) {
|
// TODO: add support for colour data draw mode
|
||||||
|
m_geometry.draw( Submodel->m_geometry );
|
||||||
/*
|
/*
|
||||||
|
if( Global::bUseVBO ) {
|
||||||
// NOTE: we're doing manual switch to color vbo setup, because there doesn't seem to be any convenient way available atm
|
// NOTE: we're doing manual switch to color vbo setup, because there doesn't seem to be any convenient way available atm
|
||||||
// TODO: implement easier way to go about it
|
// TODO: implement easier way to go about it
|
||||||
::glDisableClientState( GL_NORMAL_ARRAY );
|
::glDisableClientState( GL_NORMAL_ARRAY );
|
||||||
@@ -941,12 +952,11 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
|||||||
::glDisableClientState( GL_COLOR_ARRAY );
|
::glDisableClientState( GL_COLOR_ARRAY );
|
||||||
::glEnableClientState( GL_NORMAL_ARRAY );
|
::glEnableClientState( GL_NORMAL_ARRAY );
|
||||||
::glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
::glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
::glCallList( Submodel->uiDisplayList );
|
::glCallList( Submodel->uiDisplayList );
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
// post-draw reset
|
// post-draw reset
|
||||||
::glPopAttrib();
|
::glPopAttrib();
|
||||||
}
|
}
|
||||||
@@ -1094,18 +1104,39 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
|||||||
case TP_TRACTION: {
|
case TP_TRACTION: {
|
||||||
// TODO: unify the render code after generic buffers are in place
|
// TODO: unify the render code after generic buffers are in place
|
||||||
if( Node->bVisible ) {
|
if( Node->bVisible ) {
|
||||||
|
// rysuj jesli sa druty i nie zerwana
|
||||||
|
if( ( Node->hvTraction->Wires == 0 )
|
||||||
|
|| ( true == TestFlag( Node->hvTraction->DamageFlag, 128 ) ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// setup
|
// setup
|
||||||
::glPushMatrix();
|
::glPushMatrix();
|
||||||
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
||||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||||
|
|
||||||
|
Bind( NULL );
|
||||||
|
if( !Global::bSmoothTraction ) {
|
||||||
|
// na liniach kiepsko wygląda - robi gradient
|
||||||
|
::glDisable( GL_LINE_SMOOTH );
|
||||||
|
}
|
||||||
|
float const linealpha = static_cast<float>(
|
||||||
|
std::min(
|
||||||
|
1.2,
|
||||||
|
5000 * Node->hvTraction->WireThickness / ( distancesquared + 1.0 ) ) ); // zbyt grube nie są dobre
|
||||||
|
::glLineWidth( linealpha );
|
||||||
|
// McZapkie-261102: kolor zalezy od materialu i zasniedzenia
|
||||||
|
auto const color { Node->hvTraction->wire_color() };
|
||||||
|
::glColor4f( color.r, color.g, color.b, linealpha );
|
||||||
|
|
||||||
// render
|
// render
|
||||||
if( Global::bUseVBO ) {
|
m_geometry.draw( Node->hvTraction->m_geometry );
|
||||||
Node->hvTraction->RenderVBO( distancesquared, Node->iVboPtr );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Node->hvTraction->RenderDL( distancesquared, Node->m_rootposition );
|
|
||||||
}
|
|
||||||
// post-render cleanup
|
// post-render cleanup
|
||||||
|
::glLineWidth( 1.0 );
|
||||||
|
if( !Global::bSmoothTraction ) {
|
||||||
|
::glEnable( GL_LINE_SMOOTH );
|
||||||
|
}
|
||||||
|
|
||||||
::glPopMatrix();
|
::glPopMatrix();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1233,14 +1264,7 @@ opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
|
|||||||
double const squaredistance = SquareMagnitude( originoffset / Global::ZoomFactor );
|
double const squaredistance = SquareMagnitude( originoffset / Global::ZoomFactor );
|
||||||
Dynamic->ABuLittleUpdate( squaredistance ); // ustawianie zmiennych submodeli dla wspólnego modelu
|
Dynamic->ABuLittleUpdate( squaredistance ); // ustawianie zmiennych submodeli dla wspólnego modelu
|
||||||
::glPushMatrix();
|
::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
|
|
||||||
*/
|
|
||||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||||
::glMultMatrixd( Dynamic->mMatrix.getArray() );
|
::glMultMatrixd( Dynamic->mMatrix.getArray() );
|
||||||
|
|
||||||
@@ -1305,18 +1329,11 @@ opengl_renderer::Render_Alpha( TModel3d *Model, material_data const *Material, d
|
|||||||
|
|
||||||
Model->Root->fSquareDist = Squaredistance; // zmienna globalna!
|
Model->Root->fSquareDist = Squaredistance; // zmienna globalna!
|
||||||
|
|
||||||
// TODO: unify the render code after generic buffers are in place
|
|
||||||
// setup
|
// setup
|
||||||
/*
|
|
||||||
if( Global::bUseVBO ) {
|
|
||||||
if( false == Model->StartVBO() )
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
Model->Root->ReplacableSet(
|
Model->Root->ReplacableSet(
|
||||||
( Material != nullptr ?
|
( Material != nullptr ?
|
||||||
Material->replacable_skins :
|
Material->replacable_skins :
|
||||||
nullptr ),
|
nullptr ),
|
||||||
alpha );
|
alpha );
|
||||||
|
|
||||||
Model->Root->pRoot = Model;
|
Model->Root->pRoot = Model;
|
||||||
@@ -1325,11 +1342,7 @@ opengl_renderer::Render_Alpha( TModel3d *Model, material_data const *Material, d
|
|||||||
Render_Alpha( Model->Root );
|
Render_Alpha( Model->Root );
|
||||||
|
|
||||||
// post-render cleanup
|
// post-render cleanup
|
||||||
/*
|
|
||||||
if( Global::bUseVBO ) {
|
|
||||||
Model->EndVBO();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1345,7 +1358,6 @@ opengl_renderer::Render_Alpha( TModel3d *Model, material_data const *Material, M
|
|||||||
if( Angle.z != 0.0 )
|
if( Angle.z != 0.0 )
|
||||||
::glRotated( Angle.z, 0.0, 0.0, 1.0 );
|
::glRotated( Angle.z, 0.0, 0.0, 1.0 );
|
||||||
|
|
||||||
// auto const result = Render_Alpha( Model, Material, SquareMagnitude( Position / Global::ZoomFactor ) ); // position is effectively camera offset
|
|
||||||
auto const result = Render_Alpha( Model, Material, SquareMagnitude( Position ) ); // position is effectively camera offset
|
auto const result = Render_Alpha( Model, Material, SquareMagnitude( Position ) ); // position is effectively camera offset
|
||||||
|
|
||||||
::glPopMatrix();
|
::glPopMatrix();
|
||||||
@@ -1387,16 +1399,8 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
|||||||
::glMaterialfv( GL_FRONT, GL_EMISSION, Submodel->f4Diffuse );
|
::glMaterialfv( GL_FRONT, GL_EMISSION, Submodel->f4Diffuse );
|
||||||
}
|
}
|
||||||
|
|
||||||
// main draw call. TODO: generic buffer base class, specialized for vbo, dl etc
|
// main draw call
|
||||||
if( Global::bUseVBO ) {
|
m_geometry.draw( Submodel->m_geometry );
|
||||||
/*
|
|
||||||
::glDrawArrays( Submodel->eType, Submodel->iVboPtr, Submodel->iNumVerts );
|
|
||||||
*/
|
|
||||||
Submodel->pRoot->m_geometry->draw( Submodel->m_chunk );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
::glCallList( Submodel->uiDisplayList );
|
|
||||||
}
|
|
||||||
|
|
||||||
// post-draw reset
|
// post-draw reset
|
||||||
if( Global::fLuminance < Submodel->fLight ) {
|
if( Global::fLuminance < Submodel->fLight ) {
|
||||||
@@ -1554,7 +1558,7 @@ opengl_renderer::Update ( double const Deltatime ) {
|
|||||||
|
|
||||||
// TODO: add garbage collection and other less frequent works here
|
// TODO: add garbage collection and other less frequent works here
|
||||||
if( DebugModeFlag )
|
if( DebugModeFlag )
|
||||||
m_debuginfo = m_textures.Info();
|
m_debuginfo = m_textures.info();
|
||||||
};
|
};
|
||||||
|
|
||||||
// debug performance string
|
// debug performance string
|
||||||
|
|||||||
113
renderer.h
113
renderer.h
@@ -10,6 +10,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "GL/glew.h"
|
#include "GL/glew.h"
|
||||||
|
#include "openglgeometrybank.h"
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
#include "lightarray.h"
|
#include "lightarray.h"
|
||||||
#include "dumb3d.h"
|
#include "dumb3d.h"
|
||||||
@@ -120,71 +121,54 @@ public:
|
|||||||
// main draw call. returns false on error
|
// main draw call. returns false on error
|
||||||
bool
|
bool
|
||||||
Render();
|
Render();
|
||||||
bool
|
// render sub-methods, temporarily exposed until we complete migrating render code to the renderer
|
||||||
Render( world_environment *Environment );
|
|
||||||
bool
|
|
||||||
Render( TGround *Ground );
|
|
||||||
bool
|
|
||||||
Render( TGroundRect *Groundcell );
|
|
||||||
bool
|
|
||||||
Render( TSubRect *Groundsubcell );
|
|
||||||
bool
|
|
||||||
Render( TGroundNode *Node );
|
|
||||||
bool
|
bool
|
||||||
Render( TDynamicObject *Dynamic );
|
Render( TDynamicObject *Dynamic );
|
||||||
bool
|
|
||||||
Render( TModel3d *Model, material_data const *Material, double const Squaredistance );
|
|
||||||
bool
|
bool
|
||||||
Render( TModel3d *Model, material_data const *Material, Math3D::vector3 const &Position, Math3D::vector3 const &Angle );
|
Render( TModel3d *Model, material_data const *Material, Math3D::vector3 const &Position, Math3D::vector3 const &Angle );
|
||||||
|
bool
|
||||||
|
Render( TModel3d *Model, material_data const *Material, double const Squaredistance );
|
||||||
void
|
void
|
||||||
Render( TSubModel *Submodel );
|
Render( TSubModel *Submodel );
|
||||||
void
|
|
||||||
Render( TMemCell *Memcell );
|
|
||||||
bool
|
|
||||||
Render_Alpha( TGround *Ground );
|
|
||||||
bool
|
|
||||||
Render_Alpha( TSubRect *Groundsubcell );
|
|
||||||
bool
|
|
||||||
Render_Alpha( TGroundNode *Node );
|
|
||||||
bool
|
bool
|
||||||
Render_Alpha( TDynamicObject *Dynamic );
|
Render_Alpha( TDynamicObject *Dynamic );
|
||||||
bool
|
|
||||||
Render_Alpha( TModel3d *Model, material_data const *Material, double const Squaredistance );
|
|
||||||
bool
|
bool
|
||||||
Render_Alpha( TModel3d *Model, material_data const *Material, Math3D::vector3 const &Position, Math3D::vector3 const &Angle );
|
Render_Alpha( TModel3d *Model, material_data const *Material, Math3D::vector3 const &Position, Math3D::vector3 const &Angle );
|
||||||
void
|
bool
|
||||||
Render_Alpha( TSubModel *Submodel );
|
Render_Alpha( TModel3d *Model, material_data const *Material, double const Squaredistance );
|
||||||
// maintenance jobs
|
// maintenance jobs
|
||||||
void
|
void
|
||||||
Update( double const Deltatime);
|
Update( double const Deltatime );
|
||||||
void
|
|
||||||
Update_Lights( light_array const &Lights );
|
|
||||||
void
|
|
||||||
Disable_Lights();
|
|
||||||
inline
|
|
||||||
bool
|
|
||||||
Visible( TDynamicObject const *Dynamic ) const { return m_camera.visible( Dynamic ); }
|
|
||||||
// debug performance string
|
// debug performance string
|
||||||
std::string const &
|
std::string const &
|
||||||
Info() const;
|
Info() const;
|
||||||
|
// light methods
|
||||||
texture_manager::size_type
|
|
||||||
GetTextureId( std::string Filename, std::string const &Dir, int const Filter = -1, bool const Loadnow = true ) {
|
|
||||||
|
|
||||||
return m_textures.GetTextureId( Filename, Dir, Filter, Loadnow );
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Bind( texture_manager::size_type const Id ) {
|
Disable_Lights();
|
||||||
// temporary until we separate the renderer
|
// geometry methods
|
||||||
m_textures.Bind( Id );
|
// NOTE: hands-on geometry management is exposed as a temporary measure; ultimately all visualization data should be generated/handled automatically by the renderer itself
|
||||||
}
|
// creates a new geometry bank. returns: handle to the bank or NULL
|
||||||
|
geometrybank_handle
|
||||||
|
Create_Bank();
|
||||||
|
// creates a new geometry chunk of specified type from supplied vertex data, in specified bank. returns: handle to the chunk or NULL
|
||||||
|
geometry_handle
|
||||||
|
Insert( vertex_array &Vertices, geometrybank_handle const &Geometry, int const Type );
|
||||||
|
// replaces data of specified chunk with the supplied vertex data, starting from specified offset
|
||||||
|
bool
|
||||||
|
Replace( vertex_array &Vertices, geometry_handle const &Geometry, std::size_t const Offset = 0 );
|
||||||
|
// adds supplied vertex data at the end of specified chunk
|
||||||
|
bool
|
||||||
|
Append( vertex_array &Vertices, geometry_handle const &Geometry );
|
||||||
|
// provides direct access to vertex data of specfied chunk
|
||||||
|
vertex_array const &
|
||||||
|
Vertices( geometry_handle const &Geometry ) const;
|
||||||
|
// texture methods
|
||||||
|
texture_handle
|
||||||
|
GetTextureId( std::string Filename, std::string const &Dir, int const Filter = -1, bool const Loadnow = true );
|
||||||
|
void
|
||||||
|
Bind( texture_handle const Texture );
|
||||||
opengl_texture &
|
opengl_texture &
|
||||||
Texture( texture_manager::size_type const Id ) {
|
Texture( texture_handle const Texture );
|
||||||
|
|
||||||
return m_textures.Texture( Id );
|
|
||||||
}
|
|
||||||
|
|
||||||
// members
|
// members
|
||||||
GLenum static const sunlight{ GL_LIGHT0 };
|
GLenum static const sunlight{ GL_LIGHT0 };
|
||||||
@@ -200,20 +184,43 @@ private:
|
|||||||
// methods
|
// methods
|
||||||
bool
|
bool
|
||||||
Init_caps();
|
Init_caps();
|
||||||
|
bool
|
||||||
|
Render( world_environment *Environment );
|
||||||
|
bool
|
||||||
|
Render( TGround *Ground );
|
||||||
|
bool
|
||||||
|
Render( TGroundRect *Groundcell );
|
||||||
|
bool
|
||||||
|
Render( TSubRect *Groundsubcell );
|
||||||
|
bool
|
||||||
|
Render( TGroundNode *Node );
|
||||||
|
void
|
||||||
|
Render( TMemCell *Memcell );
|
||||||
|
bool
|
||||||
|
Render_Alpha( TGround *Ground );
|
||||||
|
bool
|
||||||
|
Render_Alpha( TSubRect *Groundsubcell );
|
||||||
|
bool
|
||||||
|
Render_Alpha( TGroundNode *Node );
|
||||||
|
void
|
||||||
|
Render_Alpha( TSubModel *Submodel );
|
||||||
|
void
|
||||||
|
Update_Lights( light_array const &Lights );
|
||||||
|
|
||||||
// members
|
// members
|
||||||
rendermode renderpass{ rendermode::color };
|
|
||||||
opengllight_array m_lights;
|
opengllight_array m_lights;
|
||||||
|
geometrybank_manager m_geometry;
|
||||||
texture_manager m_textures;
|
texture_manager m_textures;
|
||||||
opengl_camera m_camera;
|
opengl_camera m_camera;
|
||||||
|
rendermode renderpass{ rendermode::color };
|
||||||
float m_drawrange{ 2500.0f }; // current drawing range
|
float m_drawrange{ 2500.0f }; // current drawing range
|
||||||
float m_drawtime{ 1000.0f / 30.0f * 20.0f }; // start with presumed 'neutral' average of 30 fps
|
float m_drawtime{ 1000.0f / 30.0f * 20.0f }; // start with presumed 'neutral' average of 30 fps
|
||||||
double m_updateaccumulator{ 0.0 };
|
double m_updateaccumulator{ 0.0 };
|
||||||
std::string m_debuginfo;
|
std::string m_debuginfo;
|
||||||
GLFWwindow *m_window{ nullptr };
|
GLFWwindow *m_window{ nullptr };
|
||||||
texture_manager::size_type m_glaretextureid{ -1 };
|
texture_handle m_glaretextureid{ -1 };
|
||||||
texture_manager::size_type m_suntextureid{ -1 };
|
texture_handle m_suntextureid{ -1 };
|
||||||
texture_manager::size_type m_moontextureid{ -1 };
|
texture_handle m_moontextureid{ -1 };
|
||||||
GLUquadricObj *m_quadric; // helper object for drawing debug mode scene elements
|
GLUquadricObj *m_quadric; // helper object for drawing debug mode scene elements
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ private:
|
|||||||
GLuint m_fontbase{ (GLuint)-1 }; // numer DL dla znaków w napisach
|
GLuint m_fontbase{ (GLuint)-1 }; // numer DL dla znaków w napisach
|
||||||
float m_progress{ 0.0f }; // percentage of filled progres bar, to indicate lengthy operations.
|
float m_progress{ 0.0f }; // percentage of filled progres bar, to indicate lengthy operations.
|
||||||
float m_subtaskprogress{ 0.0f }; // percentage of filled progres bar, to indicate lengthy operations.
|
float m_subtaskprogress{ 0.0f }; // percentage of filled progres bar, to indicate lengthy operations.
|
||||||
texture_manager::size_type m_background; // path to texture used as the background. size depends on mAspect.
|
texture_handle m_background; // path to texture used as the background. size depends on mAspect.
|
||||||
std::vector<std::shared_ptr<ui_panel> > m_panels;
|
std::vector<std::shared_ptr<ui_panel> > m_panels;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
28
usefull.h
28
usefull.h
@@ -24,32 +24,32 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
#define MAKE_ID4(a,b,c,d) (((std::uint32_t)(d)<<24)|((std::uint32_t)(c)<<16)|((std::uint32_t)(b)<<8)|(std::uint32_t)(a))
|
#define MAKE_ID4(a,b,c,d) (((std::uint32_t)(d)<<24)|((std::uint32_t)(c)<<16)|((std::uint32_t)(b)<<8)|(std::uint32_t)(a))
|
||||||
|
|
||||||
template <typename _Type>
|
template <typename Type_>
|
||||||
void SafeDelete( _Type &Pointer ) {
|
void SafeDelete( Type_ &Pointer ) {
|
||||||
delete Pointer;
|
delete Pointer;
|
||||||
Pointer = nullptr;
|
Pointer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename _Type>
|
template <typename Type_>
|
||||||
void SafeDeleteArray( _Type &Pointer ) {
|
void SafeDeleteArray( Type_ &Pointer ) {
|
||||||
delete[] Pointer;
|
delete[] Pointer;
|
||||||
Pointer = nullptr;
|
Pointer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename _Type>
|
template <typename Type_>
|
||||||
_Type
|
Type_
|
||||||
clamp( _Type const Value, _Type const Min, _Type const Max ) {
|
clamp( Type_ const Value, Type_ const Min, Type_ const Max ) {
|
||||||
|
|
||||||
_Type value = Value;
|
Type_ value = Value;
|
||||||
if( value < Min ) { value = Min; }
|
if( value < Min ) { value = Min; }
|
||||||
if( value > Max ) { value = Max; }
|
if( value > Max ) { value = Max; }
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// keeps the provided value in specified range 0-Range, as if the range was circular buffer
|
// keeps the provided value in specified range 0-Range, as if the range was circular buffer
|
||||||
template <typename _Type>
|
template <typename Type_>
|
||||||
_Type
|
Type_
|
||||||
clamp_circular( _Type Value, _Type const Range = static_cast<_Type>(360) ) {
|
clamp_circular( Type_ Value, Type_ const Range = static_cast<Type_>(360) ) {
|
||||||
|
|
||||||
Value -= Range * (int)( Value / Range ); // clamp the range to 0-360
|
Value -= Range * (int)( Value / Range ); // clamp the range to 0-360
|
||||||
if( Value < 0.0 ) Value += Range;
|
if( Value < 0.0 ) Value += Range;
|
||||||
@@ -57,9 +57,9 @@ clamp_circular( _Type Value, _Type const Range = static_cast<_Type>(360) ) {
|
|||||||
return Value;
|
return Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename _Type>
|
template <typename Type_>
|
||||||
_Type
|
Type_
|
||||||
interpolate( _Type const First, _Type const Second, float const Factor ) {
|
interpolate( Type_ const First, Type_ const Second, float const Factor ) {
|
||||||
|
|
||||||
return ( First * ( 1.0f - Factor ) ) + ( Second * Factor );
|
return ( First * ( 1.0f - Factor ) ) + ( Second * Factor );
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user