mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 02:29:17 +02:00
completed unification of render paths
This commit is contained in:
557
Ground.cpp
557
Ground.cpp
@@ -247,82 +247,13 @@ void TGroundNode::InitNormals()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
void TGroundNode::RaRenderVBO()
|
|
||||||
{ // renderowanie z domyslnego bufora VBO
|
|
||||||
glColor3ub(Diffuse[0], Diffuse[1], Diffuse[2]);
|
|
||||||
GfxRenderer.Bind( TextureID ); // Ustaw aktywną teksturę
|
|
||||||
glDrawArrays(iType, iVboPtr, iNumVerts); // Narysuj naraz wszystkie trójkąty
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
void TGroundNode::Compile( glm::dvec3 const &Origin, bool const Multiple )
|
|
||||||
{ // tworzenie skompilowanej listy w wyświetlaniu DL
|
|
||||||
if (false == Multiple)
|
|
||||||
{ // obsługa pojedynczej listy
|
|
||||||
if (DisplayListID)
|
|
||||||
Release();
|
|
||||||
if (Global::bManageNodes)
|
|
||||||
{
|
|
||||||
DisplayListID = glGenLists(1);
|
|
||||||
glNewList(DisplayListID, GL_COMPILE);
|
|
||||||
iVersion = Global::iReCompile; // aktualna wersja siatek (do WireFrame)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((iType == GL_LINES) || (iType == GL_LINE_STRIP) || (iType == GL_LINE_LOOP))
|
|
||||||
{
|
|
||||||
glBegin(iType);
|
|
||||||
for (int i = 0; i < iNumPts; ++i)
|
|
||||||
glVertex3dv( glm::value_ptr( Points[i] - Origin ) );
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
else if (iType == GL_TRIANGLE_STRIP || iType == GL_TRIANGLE_FAN || iType == GL_TRIANGLES)
|
|
||||||
{ // jak nie linie, to trójkąty
|
|
||||||
// TODO: eliminate these calls, they're duplicated by setup part in the unified render function
|
|
||||||
#ifdef EU07_USE_OLD_RENDERCODE
|
|
||||||
::glColor3fv( glm::value_ptr( Diffuse ) );
|
|
||||||
GfxRenderer.Bind(TextureID);
|
|
||||||
#endif
|
|
||||||
glBegin(iType);
|
|
||||||
for (int i = 0; i < iNumVerts; ++i)
|
|
||||||
{
|
|
||||||
glNormal3fv( glm::value_ptr( Vertices[ i ].normal ) );
|
|
||||||
glTexCoord2fv( glm::value_ptr( Vertices[ i ].texture ) );
|
|
||||||
glVertex3dv( glm::value_ptr( Vertices[ i ].position - Origin ) );
|
|
||||||
}
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
else if (iType == TP_MESH)
|
|
||||||
{ // grupa ze wspólną teksturą - wrzucanie do wspólnego Display List
|
|
||||||
#ifdef EU07_USE_OLD_RENDERCODE
|
|
||||||
if (TextureID)
|
|
||||||
GfxRenderer.Bind(TextureID); // Ustaw aktywną teksturę
|
|
||||||
#endif
|
|
||||||
TGroundNode *n = nNode;
|
|
||||||
while (n ? n->TextureID == TextureID : false)
|
|
||||||
{ // wszystkie obiekty o tej samej testurze
|
|
||||||
switch (n->iType)
|
|
||||||
{ // poszczególne typy różnie się tworzy
|
|
||||||
case TP_TRACK:
|
|
||||||
case TP_DUMMYTRACK:
|
|
||||||
n->pTrack->Compile(TextureID); // dodanie trójkątów dla podanej tekstury
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
n = n->nNext3; // następny z listy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if (false == Multiple)
|
|
||||||
if (Global::bManageNodes)
|
|
||||||
glEndList();
|
|
||||||
};
|
|
||||||
|
|
||||||
void TGroundNode::Release()
|
void TGroundNode::Release()
|
||||||
{
|
{
|
||||||
if (DisplayListID)
|
if (DisplayListID)
|
||||||
glDeleteLists(DisplayListID, 1);
|
glDeleteLists(DisplayListID, 1);
|
||||||
DisplayListID = 0;
|
DisplayListID = 0;
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
void TGroundNode::RenderHidden()
|
void TGroundNode::RenderHidden()
|
||||||
{ // renderowanie obiektów niewidocznych
|
{ // renderowanie obiektów niewidocznych
|
||||||
double mgn = SquareMagnitude(pCenter - Global::pCameraPosition);
|
double mgn = SquareMagnitude(pCenter - Global::pCameraPosition);
|
||||||
@@ -354,8 +285,10 @@ void TGroundNode::RenderHidden()
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
TSubRect::~TSubRect()
|
TSubRect::~TSubRect()
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
if (Global::bManageNodes) // Ra: tu się coś sypie
|
if (Global::bManageNodes) // Ra: tu się coś sypie
|
||||||
ResourceManager::Unregister(this); // wyrejestrowanie ze sprzątacza
|
ResourceManager::Unregister(this); // wyrejestrowanie ze sprzątacza
|
||||||
|
*/
|
||||||
// TODO: usunąć obiekty z listy (nRootMesh), bo są one tworzone dla sektora
|
// TODO: usunąć obiekty z listy (nRootMesh), bo są one tworzone dla sektora
|
||||||
delete[] tTracks;
|
delete[] tTracks;
|
||||||
}
|
}
|
||||||
@@ -393,46 +326,22 @@ void TSubRect::NodeAdd(TGroundNode *Node)
|
|||||||
Node->pTrack->RaOwnerSet(this); // do którego sektora ma zgłaszać animację
|
Node->pTrack->RaOwnerSet(this); // do którego sektora ma zgłaszać animację
|
||||||
// NOTE: track merge/sort temporarily disabled to simplify unification of render code
|
// NOTE: track merge/sort temporarily disabled to simplify unification of render code
|
||||||
// TODO: refactor sorting as universal part of drawing process in the renderer
|
// TODO: refactor sorting as universal part of drawing process in the renderer
|
||||||
#ifdef EU07_USE_OLD_RENDERCODE
|
|
||||||
if( Global::bUseVBO ) {
|
|
||||||
Node->nNext3 = nRenderRect;
|
|
||||||
nRenderRect = Node;
|
|
||||||
} // VBO: do nieprzezroczystych z sektora
|
|
||||||
else {
|
|
||||||
Node->nNext3 = nRender;
|
|
||||||
nRender = Node;
|
|
||||||
} // DL: do nieprzezroczystych
|
|
||||||
#else
|
|
||||||
Node->nNext3 = nRenderRect;
|
Node->nNext3 = nRenderRect;
|
||||||
nRenderRect = Node;
|
nRenderRect = Node;
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
case GL_TRIANGLE_STRIP:
|
case GL_TRIANGLE_STRIP:
|
||||||
case GL_TRIANGLE_FAN:
|
case GL_TRIANGLE_FAN:
|
||||||
case GL_TRIANGLES:
|
case GL_TRIANGLES:
|
||||||
// Node->nNext3=nMeshed; nMeshed=Node; //do podzielenia potem
|
if (Node->iFlags & 0x20) {
|
||||||
if (Node->iFlags & 0x20) // czy jest przezroczyste?
|
// do przezroczystych z sektora
|
||||||
{
|
|
||||||
Node->nNext3 = nRenderRectAlpha;
|
Node->nNext3 = nRenderRectAlpha;
|
||||||
nRenderRectAlpha = Node;
|
nRenderRectAlpha = Node;
|
||||||
} // DL: do przezroczystych z sektora
|
}
|
||||||
#ifdef EU07_USE_OLD_RENDERCODE
|
|
||||||
else if (Global::bUseVBO)
|
|
||||||
{
|
|
||||||
Node->nNext3 = nRenderRect;
|
|
||||||
nRenderRect = Node;
|
|
||||||
} // VBO: do nieprzezroczystych z sektora
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Node->nNext3 = nRender;
|
|
||||||
nRender = Node;
|
|
||||||
} // DL: do nieprzezroczystych wszelakich
|
|
||||||
#else
|
|
||||||
else {
|
else {
|
||||||
|
// do nieprzezroczystych z sektora
|
||||||
Node->nNext3 = nRenderRect;
|
Node->nNext3 = nRenderRect;
|
||||||
nRenderRect = Node;
|
nRenderRect = Node;
|
||||||
} // do nieprzezroczystych z sektora
|
}
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
case TP_TRACTION:
|
case TP_TRACTION:
|
||||||
case GL_LINES:
|
case GL_LINES:
|
||||||
@@ -471,9 +380,11 @@ void TSubRect::NodeAdd(TGroundNode *Node)
|
|||||||
case TP_DYNAMIC:
|
case TP_DYNAMIC:
|
||||||
return; // tych nie dopisujemy wcale
|
return; // tych nie dopisujemy wcale
|
||||||
}
|
}
|
||||||
Node->nNext2 = nRootNode; // dopisanie do ogólnej listy
|
// dopisanie do ogólnej listy
|
||||||
|
Node->nNext2 = nRootNode;
|
||||||
nRootNode = Node;
|
nRootNode = Node;
|
||||||
++iNodeCount; // licznik obiektów
|
// licznik obiektów
|
||||||
|
++iNodeCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
// przygotowanie sektora do renderowania
|
// przygotowanie sektora do renderowania
|
||||||
@@ -516,8 +427,10 @@ TTrack * TSubRect::FindTrack(vector3 *Point, int &iConnection, TTrack *Exclude)
|
|||||||
|
|
||||||
bool TSubRect::RaTrackAnimAdd(TTrack *t)
|
bool TSubRect::RaTrackAnimAdd(TTrack *t)
|
||||||
{ // aktywacja animacji torów w VBO (zwrotnica, obrotnica)
|
{ // aktywacja animacji torów w VBO (zwrotnica, obrotnica)
|
||||||
if (m_nVertexCount < 0)
|
if( false == m_geometrycreated ) {
|
||||||
return true; // nie ma animacji, gdy nie widać
|
// nie ma animacji, gdy nie widać
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (tTrackAnim)
|
if (tTrackAnim)
|
||||||
tTrackAnim->RaAnimListAdd(t);
|
tTrackAnim->RaAnimListAdd(t);
|
||||||
else
|
else
|
||||||
@@ -531,22 +444,7 @@ void TSubRect::RaAnimate()
|
|||||||
// nie ma nic do animowania
|
// nie ma nic do animowania
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// crude way to mark whether a vbo is bound, for the vbo render path
|
tTrackAnim = tTrackAnim->RaAnimate(); // przeliczenie animacji kolejnego
|
||||||
// TODO: sort this shit out and re-arrange into something more elegant... eventually
|
|
||||||
GLuint vertexbuffer { static_cast<GLuint>(-1) };
|
|
||||||
if (Global::bUseVBO) {
|
|
||||||
// odświeżenie VBO sektora
|
|
||||||
if( GLEW_VERSION_1_5 ) {
|
|
||||||
// modyfikacje VBO są dostępne od OpenGL 1.5
|
|
||||||
vertexbuffer = m_nVBOVertices;
|
|
||||||
::glBindBuffer( GL_ARRAY_BUFFER, vertexbuffer );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// dla OpenGL 1.4 z GL_ARB_vertex_buffer_object odświeżenie całego sektora
|
|
||||||
Release(); // opróżnienie VBO sektora, aby się odświeżył z nowymi ustawieniami
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tTrackAnim = tTrackAnim->RaAnimate( vertexbuffer ); // przeliczenie animacji kolejnego
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TTraction * TSubRect::FindTraction(glm::dvec3 const &Point, int &iConnection, TTraction *Exclude)
|
TTraction * TSubRect::FindTraction(glm::dvec3 const &Point, int &iConnection, TTraction *Exclude)
|
||||||
@@ -562,126 +460,69 @@ TTraction * TSubRect::FindTraction(glm::dvec3 const &Point, int &iConnection, TT
|
|||||||
return NULL;
|
return NULL;
|
||||||
};
|
};
|
||||||
|
|
||||||
void TSubRect::LoadNodes()
|
// utworzenie siatek VBO dla wszystkich node w sektorze
|
||||||
{ // utworzenie siatek VBO dla wszystkich node w sektorze
|
void TSubRect::LoadNodes() {
|
||||||
if (m_nVertexCount >= 0)
|
|
||||||
return; // obiekty były już sprawdzone
|
if( true == m_geometrycreated ) {
|
||||||
m_nVertexCount = 0; //-1 oznacza, że nie sprawdzono listy obiektów
|
// obiekty były już sprawdzone
|
||||||
if (!nRootNode)
|
|
||||||
return;
|
return;
|
||||||
TGroundNode *n = nRootNode;
|
|
||||||
while (n)
|
|
||||||
{
|
|
||||||
switch (n->iType)
|
|
||||||
{
|
|
||||||
case GL_TRIANGLE_STRIP:
|
|
||||||
case GL_TRIANGLE_FAN:
|
|
||||||
case GL_TRIANGLES:
|
|
||||||
n->iVboPtr = m_nVertexCount; // nowy początek
|
|
||||||
m_nVertexCount += n->iNumVerts;
|
|
||||||
break;
|
|
||||||
case GL_LINES:
|
|
||||||
case GL_LINE_STRIP:
|
|
||||||
case GL_LINE_LOOP:
|
|
||||||
n->iVboPtr = m_nVertexCount; // nowy początek
|
|
||||||
m_nVertexCount += n->iNumPts; // miejsce w tablicach normalnych i teksturowania się zmarnuje...
|
|
||||||
break;
|
|
||||||
case TP_TRACK:
|
|
||||||
n->iVboPtr = m_nVertexCount; // nowy początek
|
|
||||||
n->iNumVerts = n->pTrack->RaArrayPrepare(); // zliczenie wierzchołków
|
|
||||||
m_nVertexCount += n->iNumVerts;
|
|
||||||
break;
|
|
||||||
case TP_TRACTION:
|
|
||||||
n->hvTraction->create_geometry( m_geometrybank, n->m_rootposition );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
n = n->nNext2; // następny z sektora
|
|
||||||
}
|
}
|
||||||
if (m_nVertexCount <= 0)
|
else {
|
||||||
return; // jeśli nie ma obiektów do wyświetlenia z VBO, to koniec
|
// mark it done for future checks
|
||||||
if (Global::bUseVBO)
|
m_geometrycreated = true;
|
||||||
{ // tylko liczenie wierzchołów, gdy nie ma VBO
|
}
|
||||||
|
|
||||||
MakeArray(m_nVertexCount);
|
auto *node { nRootNode };
|
||||||
|
while( node != nullptr ) {
|
||||||
n = nRootNode;
|
switch (node->iType) {
|
||||||
int i;
|
case GL_TRIANGLES: {
|
||||||
while (n)
|
vertex_array vertices;
|
||||||
{
|
for( std::size_t idx = 0; idx < node->iNumVerts; ++idx ) {
|
||||||
if (n->iVboPtr >= 0)
|
vertices.emplace_back(
|
||||||
switch (n->iType)
|
node->Vertices[ idx ].position - node->m_rootposition,
|
||||||
{
|
node->Vertices[ idx ].normal,
|
||||||
case GL_TRIANGLE_STRIP:
|
node->Vertices[ idx ].texture );
|
||||||
case GL_TRIANGLE_FAN:
|
|
||||||
case GL_TRIANGLES:
|
|
||||||
for (i = 0; i < n->iNumVerts; ++i)
|
|
||||||
{ // Ra: trójkąty można od razu wczytywać do takich tablic... to może poczekać
|
|
||||||
m_pVNT[ n->iVboPtr + i ].position = n->Vertices[ i ].position - n->m_rootposition;
|
|
||||||
/*
|
|
||||||
m_pVNT[n->iVboPtr + i].x = n->Vertices[i].position.x - n->m_rootposition.x;
|
|
||||||
m_pVNT[n->iVboPtr + i].y = n->Vertices[i].position.y - n->m_rootposition.y;
|
|
||||||
m_pVNT[n->iVboPtr + i].z = n->Vertices[i].position.z - n->m_rootposition.z;
|
|
||||||
*/
|
|
||||||
m_pVNT[ n->iVboPtr + i ].normal = n->Vertices[ i ].normal;
|
|
||||||
/*
|
|
||||||
m_pVNT[n->iVboPtr + i].nx = n->Vertices[i].normal.x;
|
|
||||||
m_pVNT[n->iVboPtr + i].ny = n->Vertices[i].normal.y;
|
|
||||||
m_pVNT[n->iVboPtr + i].nz = n->Vertices[i].normal.z;
|
|
||||||
*/
|
|
||||||
m_pVNT[ n->iVboPtr + i ].texture = n->Vertices[ i ].texture;
|
|
||||||
/*
|
|
||||||
m_pVNT[n->iVboPtr + i].u = n->Vertices[i].tu;
|
|
||||||
m_pVNT[n->iVboPtr + i].v = n->Vertices[i].tv;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case GL_LINES:
|
|
||||||
case GL_LINE_STRIP:
|
|
||||||
case GL_LINE_LOOP:
|
|
||||||
for (i = 0; i < n->iNumPts; ++i)
|
|
||||||
{
|
|
||||||
m_pVNT[ n->iVboPtr + i ].position = ( n->Points[ i ] - n->m_rootposition );
|
|
||||||
/*
|
|
||||||
glm::vec3(
|
|
||||||
n->Points[ i ].x - n->m_rootposition.x,
|
|
||||||
n->Points[ i ].y - n->m_rootposition.y,
|
|
||||||
n->Points[ i ].z - n->m_rootposition.z );
|
|
||||||
*/
|
|
||||||
// miejsce w tablicach normalnych i teksturowania się marnuje...
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TP_TRACK:
|
|
||||||
if( n->iNumVerts ) { // bo tory zabezpieczające są niewidoczne
|
|
||||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
|
||||||
n->pTrack->RaArrayFill( m_pVNT + n->iVboPtr, m_pVNT, std::min( n->iNumVerts, m_nVertexCount - n->iVboPtr ) );
|
|
||||||
#else
|
|
||||||
n->pTrack->RaArrayFill( m_pVNT.data() + n->iVboPtr, m_pVNT.data(), std::min( n->iNumVerts, m_nVertexCount - n->iVboPtr ) );
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
n = n->nNext2; // następny z sektora
|
node->m_geometry = GfxRenderer.Insert( vertices, m_geometrybank, GL_TRIANGLES );
|
||||||
|
SafeDeleteArray( node->Vertices );
|
||||||
|
node->iNumVerts = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GL_LINES: {
|
||||||
|
vertex_array vertices;
|
||||||
|
for( std::size_t idx = 0; idx < node->iNumPts; ++idx ) {
|
||||||
|
vertices.emplace_back(
|
||||||
|
node->Points[ idx ] - node->m_rootposition,
|
||||||
|
glm::vec3(),
|
||||||
|
glm::vec2() );
|
||||||
|
}
|
||||||
|
node->m_geometry = GfxRenderer.Insert( vertices, m_geometrybank, GL_LINES );
|
||||||
|
SafeDeleteArray( node->Vertices );
|
||||||
|
node->iNumPts = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TP_TRACK:
|
||||||
|
if( node->pTrack->bVisible ) { // bo tory zabezpieczające są niewidoczne
|
||||||
|
node->pTrack->create_geometry( m_geometrybank );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TP_TRACTION:
|
||||||
|
node->hvTraction->create_geometry( m_geometrybank, node->m_rootposition );
|
||||||
|
break;
|
||||||
|
default: { break; }
|
||||||
}
|
}
|
||||||
BuildVBOs();
|
node = node->nNext2; // następny z sektora
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
if (Global::bManageNodes)
|
if (Global::bManageNodes)
|
||||||
ResourceManager::Register(this); // dodanie do automatu zwalniającego pamięć
|
ResourceManager::Register(this); // dodanie do automatu zwalniającego pamięć
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
bool TSubRect::StartVBO()
|
|
||||||
{ // początek rysowania elementów z VBO w sektorze
|
|
||||||
SetLastUsage(Timer::GetSimulationTime()); // te z tyłu będą niepotrzebnie zwalniane
|
|
||||||
return CMesh::StartVBO();
|
|
||||||
};
|
|
||||||
|
|
||||||
void TSubRect::Release()
|
void TSubRect::Release()
|
||||||
{ // wirtualne zwolnienie zasobów przez sprzątacz albo destruktor
|
{ // wirtualne zwolnienie zasobów przez sprzątacz albo destruktor
|
||||||
if (Global::bUseVBO)
|
|
||||||
CMesh::Clear(); // usuwanie buforów
|
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
void TSubRect::RenderSounds()
|
void TSubRect::RenderSounds()
|
||||||
{ // aktualizacja dźwięków w pojazdach sektora (sektor może nie być wyświetlany)
|
{ // aktualizacja dźwięków w pojazdach sektora (sektor może nie być wyświetlany)
|
||||||
for (int j = 0; j < iTracks; ++j)
|
for (int j = 0; j < iTracks; ++j)
|
||||||
@@ -708,7 +549,7 @@ TGroundRect::Init() {
|
|||||||
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 subcell = FastGetRect( column, row );
|
auto subcell = FastGetSubRect( column, row );
|
||||||
auto &area = subcell->m_area;
|
auto &area = subcell->m_area;
|
||||||
area.center =
|
area.center =
|
||||||
m_area.center
|
m_area.center
|
||||||
@@ -734,8 +575,9 @@ TGround::TGround()
|
|||||||
nRootOfType[ i ] = nullptr; // zerowanie tablic wyszukiwania
|
nRootOfType[ i ] = nullptr; // zerowanie tablic wyszukiwania
|
||||||
}
|
}
|
||||||
::SecureZeroMemory( TempConnectionType, sizeof( TempConnectionType ) );
|
::SecureZeroMemory( TempConnectionType, sizeof( TempConnectionType ) );
|
||||||
|
/*
|
||||||
::SecureZeroMemory( pRendered, sizeof( pRendered ) );
|
::SecureZeroMemory( pRendered, sizeof( pRendered ) );
|
||||||
|
*/
|
||||||
// set bounding area information for ground rectangles
|
// set bounding area information for ground rectangles
|
||||||
float const rectsize = 1000.0f;
|
float const rectsize = 1000.0f;
|
||||||
glm::vec3 const worldcenter;
|
glm::vec3 const worldcenter;
|
||||||
@@ -876,9 +718,9 @@ void TGround::RaTriangleDivider(TGroundNode *node)
|
|||||||
return; // tylko pojedyncze trójkąty
|
return; // tylko pojedyncze trójkąty
|
||||||
if (node->iNumVerts != 3)
|
if (node->iNumVerts != 3)
|
||||||
return; // tylko gdy jeden trójkąt
|
return; // tylko gdy jeden trójkąt
|
||||||
double x0 = 1000.0 * floor(0.001 * node->pCenter.x) - 200.0;
|
double x0 = 1000.0 * std::floor(0.001 * node->pCenter.x) - 200.0;
|
||||||
double x1 = x0 + 1400.0;
|
double x1 = x0 + 1400.0;
|
||||||
double z0 = 1000.0 * floor(0.001 * node->pCenter.z) - 200.0;
|
double z0 = 1000.0 * std::floor(0.001 * node->pCenter.z) - 200.0;
|
||||||
double z1 = z0 + 1400.0;
|
double z1 = z0 + 1400.0;
|
||||||
if ((node->Vertices[0].position.x >= x0) && (node->Vertices[0].position.x <= x1) &&
|
if ((node->Vertices[0].position.x >= x0) && (node->Vertices[0].position.x <= x1) &&
|
||||||
(node->Vertices[0].position.z >= z0) && (node->Vertices[0].position.z <= z1) &&
|
(node->Vertices[0].position.z >= z0) && (node->Vertices[0].position.z <= z1) &&
|
||||||
@@ -999,7 +841,6 @@ void TGround::RaTriangleDivider(TGroundNode *node)
|
|||||||
TGroundNode * TGround::AddGroundNode(cParser *parser)
|
TGroundNode * TGround::AddGroundNode(cParser *parser)
|
||||||
{ // wczytanie wpisu typu "node"
|
{ // wczytanie wpisu typu "node"
|
||||||
std::string str, str1, str2, str3, str4, Skin, DriverType, asNodeName;
|
std::string str, str1, str2, str3, str4, Skin, DriverType, asNodeName;
|
||||||
int nv, i;
|
|
||||||
double tf, r, rmin, tf1, tf3;
|
double tf, r, rmin, tf1, tf3;
|
||||||
int int1;
|
int int1;
|
||||||
size_t int2;
|
size_t int2;
|
||||||
@@ -1415,7 +1256,7 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
tmp->nNode[0].iType = TP_MODEL; // pierwszy zawiera model (dla delete)
|
tmp->nNode[0].iType = TP_MODEL; // pierwszy zawiera model (dla delete)
|
||||||
tmp->nNode[0].Model = Global::pTerrainCompact;
|
tmp->nNode[0].Model = Global::pTerrainCompact;
|
||||||
tmp->nNode[0].iFlags = 0x200; // nie wyświetlany, ale usuwany
|
tmp->nNode[0].iFlags = 0x200; // nie wyświetlany, ale usuwany
|
||||||
for (i = 1; i < tmp->iCount; ++i)
|
for (std::size_t i = 1; i < tmp->iCount; ++i)
|
||||||
{ // a reszta to submodele
|
{ // a reszta to submodele
|
||||||
tmp->nNode[i].iType = TP_SUBMODEL; //
|
tmp->nNode[i].iType = TP_SUBMODEL; //
|
||||||
tmp->nNode[i].smTerrain = Global::pTerrainCompact->TerrainSquare(i - 1);
|
tmp->nNode[i].smTerrain = Global::pTerrainCompact->TerrainSquare(i - 1);
|
||||||
@@ -1498,19 +1339,20 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
#endif
|
#endif
|
||||||
tmp->TextureID = GfxRenderer.GetTextureId( str, szTexturePath );
|
tmp->TextureID = GfxRenderer.GetTextureId( str, szTexturePath );
|
||||||
tmp->iFlags = GfxRenderer.Texture(tmp->TextureID).has_alpha ? 0x220 : 0x210; // z usuwaniem
|
tmp->iFlags = GfxRenderer.Texture(tmp->TextureID).has_alpha ? 0x220 : 0x210; // z usuwaniem
|
||||||
if (((tmp->iType == GL_TRIANGLES) && (tmp->iFlags & 0x10)) ?
|
if( (tmp->iType == GL_TRIANGLES)
|
||||||
Global::pTerrainCompact->TerrainLoaded() :
|
&& (tmp->iFlags & 0x10)
|
||||||
false)
|
&& (Global::pTerrainCompact->TerrainLoaded()) ) {
|
||||||
{ // jeśli jest tekstura nieprzezroczysta, a teren załadowany, to pomijamy trójkąty
|
// jeśli jest tekstura nieprzezroczysta, a teren załadowany, to pomijamy trójkąty
|
||||||
do
|
do {
|
||||||
{ // pomijanie trójkątów
|
// pomijanie trójkątów
|
||||||
parser->getTokens();
|
parser->getTokens();
|
||||||
*parser >> token;
|
*parser >> token;
|
||||||
} while (token.compare("endtri") != 0);
|
} while (token.compare("endtri") != 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TGroundVertex vertex;
|
TGroundVertex vertex, vertex1, vertex2;
|
||||||
|
std::size_t vertexcount { 0 };
|
||||||
do {
|
do {
|
||||||
parser->getTokens( 8, false );
|
parser->getTokens( 8, false );
|
||||||
*parser
|
*parser
|
||||||
@@ -1522,14 +1364,6 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
>> vertex.normal.z
|
>> vertex.normal.z
|
||||||
>> vertex.texture.s
|
>> vertex.texture.s
|
||||||
>> vertex.texture.t;
|
>> vertex.texture.t;
|
||||||
/*
|
|
||||||
vertex.position.RotateZ( aRotate.z / 180 * M_PI );
|
|
||||||
vertex.position.RotateX( aRotate.x / 180 * M_PI );
|
|
||||||
vertex.position.RotateY( aRotate.y / 180 * M_PI );
|
|
||||||
vertex.normal.RotateZ( aRotate.z / 180 * M_PI );
|
|
||||||
vertex.normal.RotateX( aRotate.x / 180 * M_PI );
|
|
||||||
vertex.normal.RotateY( aRotate.y / 180 * M_PI );
|
|
||||||
*/
|
|
||||||
vertex.position = glm::rotateZ( vertex.position, aRotate.z / 180 * M_PI );
|
vertex.position = glm::rotateZ( vertex.position, aRotate.z / 180 * M_PI );
|
||||||
vertex.position = glm::rotateX( vertex.position, aRotate.x / 180 * M_PI );
|
vertex.position = glm::rotateX( vertex.position, aRotate.x / 180 * M_PI );
|
||||||
vertex.position = glm::rotateY( vertex.position, aRotate.y / 180 * M_PI );
|
vertex.position = glm::rotateY( vertex.position, aRotate.y / 180 * M_PI );
|
||||||
@@ -1538,19 +1372,52 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
vertex.normal = glm::rotateY( vertex.normal, static_cast<float>( aRotate.y / 180 * M_PI ) );
|
vertex.normal = glm::rotateY( vertex.normal, static_cast<float>( aRotate.y / 180 * M_PI ) );
|
||||||
vertex.position += glm::dvec3( pOrigin.x, pOrigin.y, pOrigin.z );
|
vertex.position += glm::dvec3( pOrigin.x, pOrigin.y, pOrigin.z );
|
||||||
tmp->pCenter += vertex.position;
|
tmp->pCenter += vertex.position;
|
||||||
|
// convert all data to gl_triangles to allow data merge for matching nodes
|
||||||
importedvertices.emplace_back( vertex );
|
switch( tmp->iType ) {
|
||||||
|
case GL_TRIANGLES: {
|
||||||
|
importedvertices.emplace_back( vertex );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GL_TRIANGLE_FAN: {
|
||||||
|
if( vertexcount == 0 ) { vertex1 = vertex; }
|
||||||
|
else if( vertexcount == 1 ) { vertex2 = vertex; }
|
||||||
|
else if( vertexcount >= 2 ) {
|
||||||
|
importedvertices.emplace_back( vertex1 );
|
||||||
|
importedvertices.emplace_back( vertex2 );
|
||||||
|
importedvertices.emplace_back( vertex );
|
||||||
|
vertex2 = vertex;
|
||||||
|
}
|
||||||
|
++vertexcount;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GL_TRIANGLE_STRIP: {
|
||||||
|
if( vertexcount == 0 ) { vertex1 = vertex; }
|
||||||
|
else if( vertexcount == 1 ) { vertex2 = vertex; }
|
||||||
|
else if( vertexcount >= 2 ) {
|
||||||
|
importedvertices.emplace_back( vertex1 );
|
||||||
|
importedvertices.emplace_back( vertex2 );
|
||||||
|
importedvertices.emplace_back( vertex );
|
||||||
|
vertex1 = vertex2;
|
||||||
|
vertex2 = vertex;
|
||||||
|
}
|
||||||
|
++vertexcount;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: { break; }
|
||||||
|
}
|
||||||
parser->getTokens();
|
parser->getTokens();
|
||||||
*parser >> token;
|
*parser >> token;
|
||||||
|
|
||||||
} while (token.compare("endtri") != 0);
|
} while (token.compare("endtri") != 0);
|
||||||
|
|
||||||
nv = (int)importedvertices.size();
|
tmp->iType = GL_TRIANGLES;
|
||||||
|
|
||||||
|
auto const nv = importedvertices.size();
|
||||||
tmp->Init(nv); // utworzenie tablicy wierzchołków
|
tmp->Init(nv); // utworzenie tablicy wierzchołków
|
||||||
tmp->pCenter /= (nv > 0 ? nv : 1);
|
tmp->pCenter /= (nv > 0 ? nv : 1);
|
||||||
|
|
||||||
r = 0;
|
r = 0;
|
||||||
for (int i = 0; i < nv; i++)
|
for (std::size_t i = 0; i < nv; ++i)
|
||||||
{
|
{
|
||||||
tmp->Vertices[i] = importedvertices[i];
|
tmp->Vertices[i] = importedvertices[i];
|
||||||
tf = SquareMagnitude( tmp->Vertices[ i ].position - tmp->pCenter );
|
tf = SquareMagnitude( tmp->Vertices[ i ].position - tmp->pCenter );
|
||||||
@@ -1571,8 +1438,10 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
>> tmp->Diffuse.b
|
>> tmp->Diffuse.b
|
||||||
>> tmp->fLineThickness;
|
>> tmp->fLineThickness;
|
||||||
tmp->Diffuse /= 255.0f;
|
tmp->Diffuse /= 255.0f;
|
||||||
TGroundVertex vertex;
|
|
||||||
i = 0;
|
TGroundVertex vertex, vertex0, vertex1;
|
||||||
|
std::size_t vertexcount{ 0 };
|
||||||
|
|
||||||
parser->getTokens();
|
parser->getTokens();
|
||||||
*parser >> token;
|
*parser >> token;
|
||||||
do {
|
do {
|
||||||
@@ -1581,32 +1450,64 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
*parser
|
*parser
|
||||||
>> vertex.position.y
|
>> vertex.position.y
|
||||||
>> vertex.position.z;
|
>> vertex.position.z;
|
||||||
/*
|
|
||||||
vertex.position.RotateZ( aRotate.z / 180 * M_PI );
|
|
||||||
vertex.position.RotateX( aRotate.x / 180 * M_PI );
|
|
||||||
vertex.position.RotateY( aRotate.y / 180 * M_PI );
|
|
||||||
*/
|
|
||||||
vertex.position = glm::rotateZ( vertex.position, aRotate.z / 180 * M_PI );
|
vertex.position = glm::rotateZ( vertex.position, aRotate.z / 180 * M_PI );
|
||||||
vertex.position = glm::rotateX( vertex.position, aRotate.x / 180 * M_PI );
|
vertex.position = glm::rotateX( vertex.position, aRotate.x / 180 * M_PI );
|
||||||
vertex.position = glm::rotateY( vertex.position, aRotate.y / 180 * M_PI );
|
vertex.position = glm::rotateY( vertex.position, aRotate.y / 180 * M_PI );
|
||||||
|
|
||||||
vertex.position += glm::dvec3( pOrigin.x, pOrigin.y, pOrigin.z );
|
vertex.position += glm::dvec3( pOrigin.x, pOrigin.y, pOrigin.z );
|
||||||
|
|
||||||
tmp->pCenter += vertex.position;
|
tmp->pCenter += vertex.position;
|
||||||
|
// convert all data to gl_lines to allow data merge for matching nodes
|
||||||
importedvertices.emplace_back( vertex );
|
switch( tmp->iType ) {
|
||||||
|
case GL_LINES: {
|
||||||
++i;
|
importedvertices.emplace_back( vertex );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GL_LINE_STRIP: {
|
||||||
|
if( vertexcount > 0 ) {
|
||||||
|
importedvertices.emplace_back( vertex1 );
|
||||||
|
importedvertices.emplace_back( vertex );
|
||||||
|
}
|
||||||
|
vertex1 = vertex;
|
||||||
|
++vertexcount;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GL_LINE_LOOP: {
|
||||||
|
if( vertexcount == 0 ) {
|
||||||
|
vertex0 = vertex;
|
||||||
|
vertex1 = vertex;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
importedvertices.emplace_back( vertex1 );
|
||||||
|
importedvertices.emplace_back( vertex );
|
||||||
|
}
|
||||||
|
vertex1 = vertex;
|
||||||
|
++vertexcount;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: { break; }
|
||||||
|
}
|
||||||
parser->getTokens();
|
parser->getTokens();
|
||||||
*parser >> token;
|
*parser >> token;
|
||||||
} while( token.compare( "endline" ) != 0 );
|
} while( token.compare( "endline" ) != 0 );
|
||||||
nv = i;
|
// add closing line for the loop
|
||||||
// tmp->Init(nv);
|
if( ( tmp->iType == GL_LINE_LOOP )
|
||||||
|
&& ( vertexcount > 2 ) ) {
|
||||||
|
importedvertices.emplace_back( vertex1 );
|
||||||
|
importedvertices.emplace_back( vertex0 );
|
||||||
|
}
|
||||||
|
if( importedvertices.size() % 2 != 0 ) {
|
||||||
|
ErrorLog( "Lines node specified odd number of vertices, encountered in file \"" + parser->Name() + "\"" );
|
||||||
|
importedvertices.pop_back();
|
||||||
|
}
|
||||||
|
tmp->iType = GL_LINES;
|
||||||
|
|
||||||
|
auto const nv = importedvertices.size();
|
||||||
tmp->Points = new glm::dvec3[ nv ];
|
tmp->Points = new glm::dvec3[ nv ];
|
||||||
tmp->iNumPts = nv;
|
tmp->iNumPts = nv;
|
||||||
tmp->pCenter /= ( nv > 0 ? nv : 1 );
|
tmp->pCenter /= ( nv > 0 ? nv : 1 );
|
||||||
for( int i = 0; i < nv; i++ )
|
for( std::size_t i = 0; i < nv; ++i ) {
|
||||||
tmp->Points[ i ] = importedvertices[ i ].position;
|
tmp->Points[ i ] = importedvertices[ i ].position;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1622,7 +1523,7 @@ TSubRect * TGround::FastGetSubRect(int iCol, int iRow)
|
|||||||
sc = iCol - bc * iNumSubRects;
|
sc = iCol - bc * iNumSubRects;
|
||||||
if ((br < 0) || (bc < 0) || (br >= iNumRects) || (bc >= iNumRects))
|
if ((br < 0) || (bc < 0) || (br >= iNumRects) || (bc >= iNumRects))
|
||||||
return NULL;
|
return NULL;
|
||||||
return (Rects[bc][br].FastGetRect(sc, sr));
|
return (Rects[bc][br].FastGetSubRect(sc, sr));
|
||||||
}
|
}
|
||||||
|
|
||||||
TSubRect * TGround::GetSubRect(int iCol, int iRow)
|
TSubRect * TGround::GetSubRect(int iCol, int iRow)
|
||||||
@@ -1634,7 +1535,7 @@ TSubRect * TGround::GetSubRect(int iCol, int iRow)
|
|||||||
sc = iCol - bc * iNumSubRects;
|
sc = iCol - bc * iNumSubRects;
|
||||||
if ((br < 0) || (bc < 0) || (br >= iNumRects) || (bc >= iNumRects))
|
if ((br < 0) || (bc < 0) || (br >= iNumRects) || (bc >= iNumRects))
|
||||||
return NULL; // jeśli poza mapą
|
return NULL; // jeśli poza mapą
|
||||||
return (Rects[bc][br].SafeGetRect(sc, sr)); // pobranie małego kwadratu
|
return (Rects[bc][br].SafeGetSubRect(sc, sr)); // pobranie małego kwadratu
|
||||||
}
|
}
|
||||||
|
|
||||||
TEvent * TGround::FindEvent(const std::string &asEventName)
|
TEvent * TGround::FindEvent(const std::string &asEventName)
|
||||||
@@ -1670,23 +1571,21 @@ void TGround::FirstInit()
|
|||||||
return; // Ra: żeby nie robiło się dwa razy
|
return; // Ra: żeby nie robiło się dwa razy
|
||||||
bInitDone = true;
|
bInitDone = true;
|
||||||
WriteLog("InitNormals");
|
WriteLog("InitNormals");
|
||||||
int i, j;
|
for (int type = 0; type < TP_LAST; ++type) {
|
||||||
for (i = 0; i < TP_LAST; ++i)
|
for (TGroundNode *Current = nRootOfType[type]; Current != nullptr; Current = Current->nNext) {
|
||||||
{
|
|
||||||
for (TGroundNode *Current = nRootOfType[i]; Current; Current = Current->nNext)
|
|
||||||
{
|
|
||||||
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 )
|
if( ( type == TP_EVLAUNCH )
|
||||||
&& ( true == Current->EvLaunch->IsGlobal() ) ) {
|
&& ( true == Current->EvLaunch->IsGlobal() ) ) {
|
||||||
// dodanie do globalnego obiektu
|
// dodanie do globalnego obiektu
|
||||||
srGlobal.NodeAdd( Current );
|
srGlobal.NodeAdd( Current );
|
||||||
}
|
}
|
||||||
else if (i == TP_TERRAIN)
|
else if (type == TP_TERRAIN)
|
||||||
{ // specjalne przetwarzanie terenu wczytanego z pliku E3D
|
{ // specjalne przetwarzanie terenu wczytanego z pliku E3D
|
||||||
TGroundRect *gr;
|
TGroundRect *gr;
|
||||||
for (j = 1; j < Current->iCount; ++j)
|
for (int j = 1; j < Current->iCount; ++j)
|
||||||
{ // od 1 do końca są zestawy trójkątów
|
{ // od 1 do końca są zestawy trójkątów
|
||||||
std::string xxxzzz = Current->nNode[j].smTerrain->pName; // pobranie nazwy
|
std::string xxxzzz = Current->nNode[j].smTerrain->pName; // pobranie nazwy
|
||||||
gr = GetRect(
|
gr = GetRect(
|
||||||
@@ -1706,6 +1605,7 @@ void TGround::FirstInit()
|
|||||||
// dodajemy do kwadratu kilometrowego
|
// dodajemy do kwadratu kilometrowego
|
||||||
// override visibility ranges, to ensure the content is drawn from far enough
|
// override visibility ranges, to ensure the content is drawn from far enough
|
||||||
// TODO: subclass NodeAdd() for the ground cell and specialize it, instead of this
|
// TODO: subclass NodeAdd() for the ground cell and specialize it, instead of this
|
||||||
|
// TODO: given their view ranges are the same, combine the geometry in single per-material nodes
|
||||||
Current->fSquareRadius = 50000.0 * 50000.0;
|
Current->fSquareRadius = 50000.0 * 50000.0;
|
||||||
Current->fSquareMinRadius = 0.0;
|
Current->fSquareMinRadius = 0.0;
|
||||||
GetRect( Current->pCenter.x, Current->pCenter.z )->NodeAdd( Current );
|
GetRect( Current->pCenter.x, Current->pCenter.z )->NodeAdd( Current );
|
||||||
@@ -1713,8 +1613,8 @@ void TGround::FirstInit()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < iNumRects; ++i)
|
for (std::size_t i = 0; i < iNumRects; ++i)
|
||||||
for (j = 0; j < iNumRects; ++j)
|
for (std::size_t j = 0; j < iNumRects; ++j)
|
||||||
Rects[i][j].Optimize(); // optymalizacja obiektów w sektorach
|
Rects[i][j].Optimize(); // optymalizacja obiektów w sektorach
|
||||||
|
|
||||||
WriteLog("InitNormals OK");
|
WriteLog("InitNormals OK");
|
||||||
@@ -1751,7 +1651,7 @@ bool TGround::Init(std::string File)
|
|||||||
|
|
||||||
std::stack<Math3D::vector3> OriginStack; // stos zagnieżdżenia origin
|
std::stack<Math3D::vector3> OriginStack; // stos zagnieżdżenia origin
|
||||||
|
|
||||||
TGroundNode *LastNode = NULL; // do użycia w trainset
|
TGroundNode *LastNode = nullptr; // do użycia w trainset
|
||||||
iNumNodes = 0;
|
iNumNodes = 0;
|
||||||
token = "";
|
token = "";
|
||||||
parser.getTokens();
|
parser.getTokens();
|
||||||
@@ -1763,64 +1663,76 @@ bool TGround::Init(std::string File)
|
|||||||
++processed;
|
++processed;
|
||||||
if( processed % 1000 == 0 )
|
if( processed % 1000 == 0 )
|
||||||
{
|
{
|
||||||
|
glfwPollEvents();
|
||||||
UILayer.set_progress( parser.getProgress(), parser.getFullProgress() );
|
UILayer.set_progress( parser.getProgress(), parser.getFullProgress() );
|
||||||
GfxRenderer.Render();
|
GfxRenderer.Render();
|
||||||
glfwPollEvents();
|
|
||||||
}
|
}
|
||||||
str = token;
|
str = token;
|
||||||
if (str == "node")
|
if (str == "node") {
|
||||||
{
|
// rozpoznanie węzła
|
||||||
LastNode = AddGroundNode(&parser); // rozpoznanie węzła
|
LastNode = AddGroundNode(&parser);
|
||||||
if (LastNode)
|
if (LastNode) {
|
||||||
{ // jeżeli przetworzony poprawnie
|
// jeżeli przetworzony poprawnie
|
||||||
if (LastNode->iType == GL_TRIANGLES)
|
switch( LastNode->iType ) {
|
||||||
{
|
// validate the new node
|
||||||
if (!LastNode->Vertices)
|
case GL_TRIANGLES: {
|
||||||
SafeDelete(LastNode); // usuwamy nieprzezroczyste trójkąty terenu
|
if( LastNode->Vertices == nullptr ) {
|
||||||
}
|
SafeDelete( LastNode );
|
||||||
else if( ( LastNode->iType == TP_TRACTION )
|
}
|
||||||
&& ( false == Global::bLoadTraction ) ) {
|
break;
|
||||||
SafeDelete( LastNode ); // usuwamy druty, jeśli wyłączone
|
}
|
||||||
|
case TP_TRACTION: {
|
||||||
|
if( false == Global::bLoadTraction ) {
|
||||||
|
// usuwamy druty, jeśli wyłączone
|
||||||
|
SafeDelete( LastNode );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LastNode) // dopiero na koniec dopisujemy do tablic
|
if( LastNode ) {
|
||||||
if (LastNode->iType != TP_DYNAMIC)
|
// dopiero na koniec dopisujemy do tablic
|
||||||
{ // jeśli nie jest pojazdem
|
if( LastNode->iType != TP_DYNAMIC ) {
|
||||||
// ostatni dodany dołączamy na końcu nowego
|
// jeśli nie jest pojazdem ostatni dodany dołączamy na końcu nowego
|
||||||
LastNode->nNext = nRootOfType[LastNode->iType];
|
LastNode->nNext = nRootOfType[ LastNode->iType ];
|
||||||
// ustawienie nowego na początku listy
|
// ustawienie nowego na początku listy
|
||||||
nRootOfType[LastNode->iType] = LastNode;
|
nRootOfType[ LastNode->iType ] = LastNode;
|
||||||
iNumNodes++;
|
++iNumNodes;
|
||||||
}
|
}
|
||||||
else
|
else { // jeśli jest pojazdem
|
||||||
{ // jeśli jest pojazdem
|
if( ( LastNode->DynamicObject->Mechanik != nullptr )
|
||||||
// if (!bInitDone) FirstInit(); //jeśli nie było w scenerii
|
&& ( LastNode->DynamicObject->Mechanik->Primary() ) ) {
|
||||||
if (LastNode->DynamicObject->Mechanik) // ale może być pasażer
|
// jeśli jest głównym (pasażer nie jest)
|
||||||
if (LastNode->DynamicObject->Mechanik
|
nTrainSetDriver = LastNode; // pojazd, któremu zostanie wysłany rozkład
|
||||||
->Primary()) // jeśli jest głównym (pasażer nie jest)
|
}
|
||||||
nTrainSetDriver =
|
|
||||||
LastNode; // pojazd, któremu zostanie wysłany rozkład
|
|
||||||
LastNode->nNext = nRootDynamic;
|
LastNode->nNext = nRootDynamic;
|
||||||
nRootDynamic = LastNode; // dopisanie z przodu do listy
|
nRootDynamic = LastNode; // dopisanie z przodu do listy
|
||||||
// if (bTrainSet && (LastNode?(LastNode->iType==TP_DYNAMIC):false))
|
|
||||||
if (nTrainSetNode) // jeżeli istnieje wcześniejszy TP_DYNAMIC
|
if( nTrainSetNode != nullptr ) {
|
||||||
|
// jeżeli istnieje wcześniejszy TP_DYNAMIC
|
||||||
nTrainSetNode->DynamicObject->AttachPrev(
|
nTrainSetNode->DynamicObject->AttachPrev(
|
||||||
LastNode->DynamicObject,
|
LastNode->DynamicObject,
|
||||||
TempConnectionType[iTrainSetWehicleNumber - 2]);
|
TempConnectionType[ iTrainSetWehicleNumber - 2 ] );
|
||||||
|
}
|
||||||
nTrainSetNode = LastNode; // ostatnio wczytany
|
nTrainSetNode = LastNode; // ostatnio wczytany
|
||||||
if (TempConnectionType[iTrainSetWehicleNumber - 1] ==
|
|
||||||
0) // jeśli sprzęg jest zerowy, to wysłać rozkład do składu
|
if( TempConnectionType[ iTrainSetWehicleNumber - 1 ] == 0 ) // jeśli sprzęg jest zerowy, to wysłać rozkład do składu
|
||||||
{ // powinien też tu wchodzić, gdy pojazd bez trainset
|
{ // powinien też tu wchodzić, gdy pojazd bez trainset
|
||||||
if (nTrainSetDriver) // pojazd, któremu zostanie wysłany rozkład
|
if( nTrainSetDriver ) // pojazd, któremu zostanie wysłany rozkład
|
||||||
{ // wysłanie komendy "Timetable" ustawia odpowiedni tryb jazdy
|
{ // wysłanie komendy "Timetable" ustawia odpowiedni tryb jazdy
|
||||||
nTrainSetDriver->DynamicObject->Mechanik->DirectionInitial();
|
nTrainSetDriver->DynamicObject->Mechanik->DirectionInitial();
|
||||||
nTrainSetDriver->DynamicObject->Mechanik->PutCommand(
|
nTrainSetDriver->DynamicObject->Mechanik->PutCommand(
|
||||||
"Timetable:" + asTrainName, fTrainSetVel, 0, NULL);
|
"Timetable:" + asTrainName,
|
||||||
nTrainSetDriver =
|
fTrainSetVel, 0,
|
||||||
NULL; // a przy "endtrainset" już wtedy nie potrzeba
|
nullptr );
|
||||||
|
nTrainSetDriver = nullptr; // a przy "endtrainset" już wtedy nie potrzeba
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1927,10 +1839,11 @@ bool TGround::Init(std::string File)
|
|||||||
RootEvent = tmp;
|
RootEvent = tmp;
|
||||||
if (!found)
|
if (!found)
|
||||||
{ // jeśli nazwa wystąpiła, to do kolejki i wyszukiwarki dodawany jest tylko pierwszy
|
{ // jeśli nazwa wystąpiła, to do kolejki i wyszukiwarki dodawany jest tylko pierwszy
|
||||||
if (RootEvent->Type != tp_Ignored)
|
if( ( RootEvent->Type != tp_Ignored )
|
||||||
if (RootEvent->asName.find(
|
&& ( RootEvent->asName.find( "onstart" ) != std::string::npos ) ) {
|
||||||
"onstart") != std::string::npos) // event uruchamiany automatycznie po starcie
|
// event uruchamiany automatycznie po starcie
|
||||||
AddToQuery(RootEvent, NULL); // dodanie do kolejki
|
AddToQuery( RootEvent, NULL ); // dodanie do kolejki
|
||||||
|
}
|
||||||
m_eventmap.emplace( tmp->asName, tmp ); // dodanie do wyszukiwarki
|
m_eventmap.emplace( tmp->asName, tmp ); // dodanie do wyszukiwarki
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
47
Ground.h
47
Ground.h
@@ -21,8 +21,6 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "Names.h"
|
#include "Names.h"
|
||||||
#include "lightarray.h"
|
#include "lightarray.h"
|
||||||
|
|
||||||
using namespace Math3D;
|
|
||||||
|
|
||||||
typedef int TGroundNodeType;
|
typedef int TGroundNodeType;
|
||||||
// Ra: zmniejszone liczby, aby zrobić tabelkę i zoptymalizować wyszukiwanie
|
// Ra: zmniejszone liczby, aby zrobić tabelkę i zoptymalizować wyszukiwanie
|
||||||
const int TP_MODEL = 10;
|
const int TP_MODEL = 10;
|
||||||
@@ -95,8 +93,14 @@ struct TGroundVertex
|
|||||||
texture = interpolate( v1.texture, v2.texture, static_cast<float>( factor ) );
|
texture = interpolate( v1.texture, v2.texture, static_cast<float>( factor ) );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
/*
|
||||||
class TGroundNode : public Resource
|
// ground node holding single, unique piece of 3d geometry. TBD, TODO: unify this with basic 3d model node
|
||||||
|
struct mesh_node {
|
||||||
|
std::vector<TGroundVertex> vertices;
|
||||||
|
geometry_handle geometry; // geometry prepared for drawing
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
class TGroundNode /*: public Resource*/
|
||||||
{ // obiekt scenerii
|
{ // obiekt scenerii
|
||||||
|
|
||||||
friend class opengl_renderer;
|
friend class opengl_renderer;
|
||||||
@@ -138,6 +142,9 @@ public:
|
|||||||
int iVersion; // wersja siatki (do wykonania rekompilacji)
|
int iVersion; // wersja siatki (do wykonania rekompilacji)
|
||||||
GLuint DisplayListID; // numer siatki DisplayLists
|
GLuint DisplayListID; // numer siatki DisplayLists
|
||||||
int iVboPtr; // indeks w buforze VBO
|
int iVboPtr; // indeks w buforze VBO
|
||||||
|
// NOTE: geometry handle is duplicated in (anim)model(3d), as well as in track and traction type nodes
|
||||||
|
// TODO: clean this up when node types are refactored into an inheritance/composition scheme
|
||||||
|
geometry_handle m_geometry; // geometry of the submodel
|
||||||
int iFlags; // tryb przezroczystości: 0x10-nieprz.,0x20-przezroczysty,0x30-mieszany
|
int iFlags; // tryb przezroczystości: 0x10-nieprz.,0x20-przezroczysty,0x30-mieszany
|
||||||
texture_handle TextureID; // główna (jedna) tekstura obiektu
|
texture_handle TextureID; // główna (jedna) tekstura obiektu
|
||||||
glm::vec3
|
glm::vec3
|
||||||
@@ -153,25 +160,10 @@ public:
|
|||||||
~TGroundNode();
|
~TGroundNode();
|
||||||
void Init(int n);
|
void Init(int n);
|
||||||
void InitNormals();
|
void InitNormals();
|
||||||
|
/*
|
||||||
// bool Disable();
|
|
||||||
inline TGroundNode * Find(const std::string &asNameToFind, TGroundNodeType iNodeType)
|
|
||||||
{ // wyszukiwanie czołgowe z typem
|
|
||||||
if ((iNodeType == iType) && (asNameToFind == asName))
|
|
||||||
return this;
|
|
||||||
else if (nNext)
|
|
||||||
return nNext->Find(asNameToFind, iNodeType);
|
|
||||||
return NULL;
|
|
||||||
};
|
|
||||||
|
|
||||||
void Compile(glm::dvec3 const &Origin, bool const Multiple = false);
|
|
||||||
void Release();
|
void Release();
|
||||||
|
*/
|
||||||
void RenderHidden(); // obsługa dźwięków i wyzwalaczy zdarzeń
|
void RenderHidden(); // obsługa dźwięków i wyzwalaczy zdarzeń
|
||||||
#ifdef EU07_USE_OLD_RENDERCODE
|
|
||||||
// (McZapkie-131202)
|
|
||||||
void RaRenderVBO(); // renderowanie (nieprzezroczystych) ze wspólnego VBO
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bounding_area {
|
struct bounding_area {
|
||||||
@@ -180,7 +172,7 @@ struct bounding_area {
|
|||||||
float radius { 0.0f }; // radius of the bounding sphere
|
float radius { 0.0f }; // radius of the bounding sphere
|
||||||
};
|
};
|
||||||
|
|
||||||
class TSubRect : public Resource, public CMesh
|
class TSubRect : /*public Resource,*/ public CMesh
|
||||||
{ // sektor składowy kwadratu kilometrowego
|
{ // sektor składowy kwadratu kilometrowego
|
||||||
public:
|
public:
|
||||||
bounding_area m_area;
|
bounding_area m_area;
|
||||||
@@ -209,12 +201,13 @@ class TSubRect : public Resource, public CMesh
|
|||||||
void LoadNodes(); // utworzenie VBO sektora
|
void LoadNodes(); // utworzenie VBO sektora
|
||||||
public:
|
public:
|
||||||
virtual ~TSubRect();
|
virtual ~TSubRect();
|
||||||
|
/*
|
||||||
virtual void Release(); // zwalnianie VBO sektora
|
virtual void Release(); // zwalnianie VBO sektora
|
||||||
|
*/
|
||||||
void NodeAdd(TGroundNode *Node); // dodanie obiektu do sektora na etapie rozdzielania na sektory
|
void NodeAdd(TGroundNode *Node); // dodanie obiektu do sektora na etapie rozdzielania na sektory
|
||||||
void Sort(); // optymalizacja obiektów w sektorze (sortowanie wg tekstur)
|
void Sort(); // optymalizacja obiektów w sektorze (sortowanie wg tekstur)
|
||||||
TTrack * FindTrack(vector3 *Point, int &iConnection, TTrack *Exclude);
|
TTrack * FindTrack(vector3 *Point, int &iConnection, TTrack *Exclude);
|
||||||
TTraction * FindTraction(glm::dvec3 const &Point, int &iConnection, TTraction *Exclude);
|
TTraction * FindTraction(glm::dvec3 const &Point, int &iConnection, TTraction *Exclude);
|
||||||
bool StartVBO(); // ustwienie VBO sektora dla (nRenderRect), (nRenderRectAlpha) i (nRenderWires)
|
|
||||||
bool RaTrackAnimAdd(TTrack *t); // zgłoszenie toru do animacji
|
bool RaTrackAnimAdd(TTrack *t); // zgłoszenie toru do animacji
|
||||||
void RaAnimate(); // przeliczenie animacji torów
|
void RaAnimate(); // przeliczenie animacji torów
|
||||||
void RenderSounds(); // dźwięki pojazdów z niewidocznych sektorów
|
void RenderSounds(); // dźwięki pojazdów z niewidocznych sektorów
|
||||||
@@ -244,7 +237,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
virtual ~TGroundRect();
|
virtual ~TGroundRect();
|
||||||
// pobranie wskaźnika do małego kwadratu, utworzenie jeśli trzeba
|
// pobranie wskaźnika do małego kwadratu, utworzenie jeśli trzeba
|
||||||
TSubRect * SafeGetRect(int iCol, int iRow) {
|
TSubRect * SafeGetSubRect(int iCol, int iRow) {
|
||||||
if( !pSubRects ) {
|
if( !pSubRects ) {
|
||||||
// utworzenie małych kwadratów
|
// utworzenie małych kwadratów
|
||||||
Init();
|
Init();
|
||||||
@@ -252,7 +245,7 @@ public:
|
|||||||
return pSubRects + iRow * iNumSubRects + iCol; // zwrócenie właściwego
|
return pSubRects + iRow * iNumSubRects + iCol; // zwrócenie właściwego
|
||||||
};
|
};
|
||||||
// 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) {
|
TSubRect * FastGetSubRect(int iCol, int iRow) {
|
||||||
return (pSubRects ? pSubRects + iRow * iNumSubRects + iCol : NULL);
|
return (pSubRects ? pSubRects + iRow * iNumSubRects + iCol : NULL);
|
||||||
};
|
};
|
||||||
// optymalizacja obiektów w sektorach
|
// optymalizacja obiektów w sektorach
|
||||||
@@ -282,7 +275,9 @@ class TGround
|
|||||||
*tmpEvent = nullptr,
|
*tmpEvent = nullptr,
|
||||||
*tmp2Event = nullptr,
|
*tmp2Event = nullptr,
|
||||||
*OldQRE = nullptr;
|
*OldQRE = nullptr;
|
||||||
|
/*
|
||||||
TSubRect *pRendered[1500]; // lista renderowanych sektorów
|
TSubRect *pRendered[1500]; // lista renderowanych sektorów
|
||||||
|
*/
|
||||||
int iNumNodes = 0;
|
int iNumNodes = 0;
|
||||||
vector3 pOrigin;
|
vector3 pOrigin;
|
||||||
vector3 aRotate;
|
vector3 aRotate;
|
||||||
@@ -293,6 +288,7 @@ class TGround
|
|||||||
event_map m_eventmap;
|
event_map m_eventmap;
|
||||||
TNames<TGroundNode *> m_trackmap;
|
TNames<TGroundNode *> m_trackmap;
|
||||||
light_array m_lights; // collection of dynamic light sources present in the scene
|
light_array m_lights; // collection of dynamic light sources present in the scene
|
||||||
|
bool PROBLEND;
|
||||||
|
|
||||||
private: // metody prywatne
|
private: // metody prywatne
|
||||||
bool EventConditon(TEvent *e);
|
bool EventConditon(TEvent *e);
|
||||||
@@ -351,7 +347,6 @@ class TGround
|
|||||||
private:
|
private:
|
||||||
void RaTriangleDivider(TGroundNode *node);
|
void RaTriangleDivider(TGroundNode *node);
|
||||||
void Navigate(std::string const &ClassName, UINT Msg, WPARAM wParam, LPARAM lParam);
|
void Navigate(std::string const &ClassName, UINT Msg, WPARAM wParam, LPARAM lParam);
|
||||||
bool PROBLEND;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void WyslijEvent(const std::string &e, const std::string &d);
|
void WyslijEvent(const std::string &e, const std::string &d);
|
||||||
|
|||||||
43
Model3d.cpp
43
Model3d.cpp
@@ -1041,7 +1041,7 @@ void TSubModel::RaAnimation(TAnimType a)
|
|||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
void TSubModel::RaArrayFill(CVertNormTex *Vert)
|
void TSubModel::RaArrayFill(basic_vertex *Vert)
|
||||||
{ // wypełnianie tablic VBO
|
{ // wypełnianie tablic VBO
|
||||||
if (Child)
|
if (Child)
|
||||||
Child->RaArrayFill(Vert);
|
Child->RaArrayFill(Vert);
|
||||||
@@ -1159,17 +1159,11 @@ TModel3d::~TModel3d()
|
|||||||
{
|
{
|
||||||
// SafeDeleteArray(Materials);
|
// SafeDeleteArray(Materials);
|
||||||
if (iFlags & 0x0200)
|
if (iFlags & 0x0200)
|
||||||
{ // wczytany z pliku tekstowego, submodele sprzątają
|
{ // wczytany z pliku tekstowego, submodele sprzątają same
|
||||||
// same
|
|
||||||
SafeDelete(Root); // submodele się usuną rekurencyjnie
|
SafeDelete(Root); // submodele się usuną rekurencyjnie
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // wczytano z pliku binarnego (jest właścicielem tablic)
|
{ // wczytano z pliku binarnego (jest właścicielem tablic)
|
||||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
|
||||||
m_pVNT = nullptr; // nie usuwać tego, bo wskazuje na iModel
|
|
||||||
#else
|
|
||||||
m_pVNT.clear();
|
|
||||||
#endif
|
|
||||||
Root = nullptr;
|
Root = nullptr;
|
||||||
delete[] iModel; // usuwamy cały wczytany plik i to wystarczy
|
delete[] iModel; // usuwamy cały wczytany plik i to wystarczy
|
||||||
}
|
}
|
||||||
@@ -1344,6 +1338,9 @@ void TSubModel::serialize(std::ostream &s,
|
|||||||
|
|
||||||
void TModel3d::SaveToBinFile(char const *FileName)
|
void TModel3d::SaveToBinFile(char const *FileName)
|
||||||
{
|
{
|
||||||
|
// TODO: re-implement!
|
||||||
|
return;
|
||||||
|
|
||||||
WriteLog("saving e3d model..");
|
WriteLog("saving e3d model..");
|
||||||
|
|
||||||
//m7todo: można by zoptymalizować robiąc unordered_map
|
//m7todo: można by zoptymalizować robiąc unordered_map
|
||||||
@@ -1379,18 +1376,20 @@ void TModel3d::SaveToBinFile(char const *FileName)
|
|||||||
sn_utils::ls_uint32(s, 8 + (uint32_t)transforms.size() * 64);
|
sn_utils::ls_uint32(s, 8 + (uint32_t)transforms.size() * 64);
|
||||||
for (size_t i = 0; i < transforms.size(); i++)
|
for (size_t i = 0; i < transforms.size(); i++)
|
||||||
transforms[i].serialize_float32(s);
|
transforms[i].serialize_float32(s);
|
||||||
|
/*
|
||||||
MakeArray(iNumVerts);
|
MakeArray(iNumVerts);
|
||||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
||||||
Root->RaArrayFill(m_pVNT);
|
Root->RaArrayFill(m_pVNT);
|
||||||
#else
|
#else
|
||||||
Root->RaArrayFill( m_pVNT.data() );
|
Root->RaArrayFill( m_pVNT.data() );
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
sn_utils::ls_uint32(s, MAKE_ID4('V', 'N', 'T', '0'));
|
sn_utils::ls_uint32(s, MAKE_ID4('V', 'N', 'T', '0'));
|
||||||
sn_utils::ls_uint32(s, 8 + iNumVerts * 32);
|
sn_utils::ls_uint32(s, 8 + iNumVerts * 32);
|
||||||
|
/*
|
||||||
for (size_t i = 0; i < (size_t)iNumVerts; i++)
|
for (size_t i = 0; i < (size_t)iNumVerts; i++)
|
||||||
m_pVNT[i].serialize(s);
|
m_pVNT[i].serialize(s);
|
||||||
|
*/
|
||||||
if (textures.size())
|
if (textures.size())
|
||||||
{
|
{
|
||||||
sn_utils::ls_uint32(s, MAKE_ID4('T', 'E', 'X', '0'));
|
sn_utils::ls_uint32(s, MAKE_ID4('T', 'E', 'X', '0'));
|
||||||
@@ -1470,11 +1469,6 @@ void TSubModel::deserialize(std::istream &s)
|
|||||||
|
|
||||||
void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
|
void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
|
||||||
{
|
{
|
||||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
|
||||||
m_pVNT = nullptr;
|
|
||||||
#else
|
|
||||||
m_pVNT.clear();
|
|
||||||
#endif
|
|
||||||
Root = nullptr;
|
Root = nullptr;
|
||||||
float4x4 *tm = nullptr;
|
float4x4 *tm = nullptr;
|
||||||
if( m_geometrybank == NULL ) {
|
if( m_geometrybank == NULL ) {
|
||||||
@@ -1507,19 +1501,16 @@ void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
|
|||||||
}
|
}
|
||||||
else if (type == MAKE_ID4('V', 'N', 'T', '0'))
|
else if (type == MAKE_ID4('V', 'N', 'T', '0'))
|
||||||
{
|
{
|
||||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
|
||||||
if (m_pVNT != nullptr)
|
|
||||||
#else
|
|
||||||
if( false == m_pVNT.empty() )
|
|
||||||
#endif
|
|
||||||
throw std::runtime_error("e3d: duplicated VNT chunk");
|
|
||||||
/*
|
/*
|
||||||
size_t vt_cnt = size / 32;
|
if (m_pVNT != nullptr)
|
||||||
|
throw std::runtime_error("e3d: duplicated VNT chunk");
|
||||||
|
|
||||||
|
size_t vt_cnt = size / 32;
|
||||||
iNumVerts = (int)vt_cnt;
|
iNumVerts = (int)vt_cnt;
|
||||||
m_nVertexCount = (int)vt_cnt;
|
m_nVertexCount = (int)vt_cnt;
|
||||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
||||||
assert( m_pVNT == nullptr );
|
assert( m_pVNT == nullptr );
|
||||||
m_pVNT = new CVertNormTex[vt_cnt];
|
m_pVNT = new basic_vertex[vt_cnt];
|
||||||
#else
|
#else
|
||||||
m_pVNT.resize( vt_cnt );
|
m_pVNT.resize( vt_cnt );
|
||||||
#endif
|
#endif
|
||||||
@@ -1613,13 +1604,9 @@ 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
|
|
||||||
Root[i].BinInit( Root, tm, &Textures, &Names, dynamic );
|
Root[i].BinInit( Root, tm, &Textures, &Names, dynamic );
|
||||||
#else
|
|
||||||
Root[ i ].BinInit( Root, tm, (float8*)m_pVNT.data(), &Textures, &Names, dynamic );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (Root[i].ChildGet())
|
if (Root[i].ChildGet())
|
||||||
Root[i].ChildGet()->Parent = &Root[i];
|
Root[i].ChildGet()->Parent = &Root[i];
|
||||||
if (Root[i].NextGet())
|
if (Root[i].NextGet())
|
||||||
Root[i].NextGet()->Parent = Root[i].Parent;
|
Root[i].NextGet()->Parent = Root[i].Parent;
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ public:
|
|||||||
TSubModel * GetFromName(char const *search, bool i = true);
|
TSubModel * GetFromName(char const *search, bool i = true);
|
||||||
inline float4x4 * GetMatrix() { return fMatrix; };
|
inline float4x4 * GetMatrix() { return fMatrix; };
|
||||||
inline void Hide() { iVisible = 0; };
|
inline void Hide() { iVisible = 0; };
|
||||||
void RaArrayFill(CVertNormTex *Vert);
|
void RaArrayFill(basic_vertex *Vert);
|
||||||
int FlagsCheck();
|
int FlagsCheck();
|
||||||
void WillBeAnimated()
|
void WillBeAnimated()
|
||||||
{
|
{
|
||||||
|
|||||||
113
Segment.cpp
113
Segment.cpp
@@ -319,16 +319,15 @@ vector3 TSegment::FastGetPoint(double t)
|
|||||||
return (bCurve ? RaInterpolate(t) : ((1.0 - t) * Point1 + (t)*Point2));
|
return (bCurve ? RaInterpolate(t) : ((1.0 - t) * Point1 + (t)*Point2));
|
||||||
}
|
}
|
||||||
|
|
||||||
int TSegment::RenderLoft( CVertNormTex* &Output, Math3D::vector3 const &Origin, const vector6 *ShapePoints, int iNumShapePoints, double fTextureLength, double Texturescale, int iSkip, int iEnd, double fOffsetX, vector3 **p, bool bRender)
|
bool TSegment::RenderLoft( vertex_array &Output, Math3D::vector3 const &Origin, const vector6 *ShapePoints, int iNumShapePoints, double fTextureLength, double Texturescale, int iSkip, int iEnd, double fOffsetX, vector3 **p, bool bRender)
|
||||||
{ // generowanie trójkątów dla odcinka trajektorii ruchu
|
{ // generowanie trójkątów dla odcinka trajektorii ruchu
|
||||||
// standardowo tworzy triangle_strip dla prostego albo ich zestaw dla łuku
|
// standardowo tworzy triangle_strip dla prostego albo ich zestaw dla łuku
|
||||||
// po modyfikacji - dla ujemnego (iNumShapePoints) w dodatkowych polach tabeli
|
// po modyfikacji - dla ujemnego (iNumShapePoints) w dodatkowych polach tabeli
|
||||||
// podany jest przekrój końcowy
|
// podany jest przekrój końcowy
|
||||||
// podsypka toru jest robiona za pomocą 6 punktów, szyna 12, drogi i rzeki na 3+2+3
|
// podsypka toru jest robiona za pomocą 6 punktów, szyna 12, drogi i rzeki na 3+2+3
|
||||||
int vertexcount{ 0 };
|
|
||||||
|
|
||||||
if( !fTsBuffer )
|
if( !fTsBuffer )
|
||||||
return vertexcount; // prowizoryczne zabezpieczenie przed wysypem - ustalić faktyczną przyczynę
|
return false; // prowizoryczne zabezpieczenie przed wysypem - ustalić faktyczną przyczynę
|
||||||
|
|
||||||
vector3 pos1, pos2, dir, parallel1, parallel2, pt, norm;
|
vector3 pos1, pos2, dir, parallel1, parallel2, pt, norm;
|
||||||
double s, step, fOffset, tv1, tv2, t, fEnd;
|
double s, step, fOffset, tv1, tv2, t, fEnd;
|
||||||
@@ -378,11 +377,6 @@ int TSegment::RenderLoft( CVertNormTex* &Output, Math3D::vector3 const &Origin,
|
|||||||
dir = FastGetDirection( t, fOffset ); // nowy wektor kierunku
|
dir = FastGetDirection( t, fOffset ); // nowy wektor kierunku
|
||||||
parallel2 = Normalize( vector3( -dir.z, 0.0, dir.x ) ); // wektor poprzeczny
|
parallel2 = Normalize( vector3( -dir.z, 0.0, dir.x ) ); // wektor poprzeczny
|
||||||
|
|
||||||
if( Output == nullptr ) {
|
|
||||||
// immediate mode
|
|
||||||
::glBegin( GL_TRIANGLE_STRIP );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( trapez ) {
|
if( trapez ) {
|
||||||
for( int j = 0; j < iNumShapePoints; ++j ) {
|
for( int j = 0; j < iNumShapePoints; ++j ) {
|
||||||
pt = parallel1 * ( jmm1 * ( ShapePoints[ j ].x - fOffsetX ) + m1 * ShapePoints[ j + iNumShapePoints ].x ) + pos1;
|
pt = parallel1 * ( jmm1 * ( ShapePoints[ j ].x - fOffsetX ) + m1 * ShapePoints[ j + iNumShapePoints ].x ) + pos1;
|
||||||
@@ -390,25 +384,12 @@ int TSegment::RenderLoft( CVertNormTex* &Output, Math3D::vector3 const &Origin,
|
|||||||
pt -= Origin;
|
pt -= Origin;
|
||||||
norm = ( jmm1 * ShapePoints[ j ].n.x + m1 * ShapePoints[ j + iNumShapePoints ].n.x ) * parallel1;
|
norm = ( jmm1 * ShapePoints[ j ].n.x + m1 * ShapePoints[ j + iNumShapePoints ].n.x ) * parallel1;
|
||||||
norm.y += jmm1 * ShapePoints[ j ].n.y + m1 * ShapePoints[ j + iNumShapePoints ].n.y;
|
norm.y += jmm1 * ShapePoints[ j ].n.y + m1 * ShapePoints[ j + iNumShapePoints ].n.y;
|
||||||
if( bRender ) { // skrzyżowania podczas łączenia siatek mogą nie renderować poboczy, ale potrzebować punktów
|
if( bRender ) {
|
||||||
if( Output == nullptr ) {
|
// skrzyżowania podczas łączenia siatek mogą nie renderować poboczy, ale potrzebować punktów
|
||||||
// immediate mode
|
Output.emplace_back(
|
||||||
::glNormal3f( norm.x, norm.y, norm.z );
|
glm::vec3 { pt.x, pt.y, pt.z },
|
||||||
::glTexCoord2f( (jmm1 * ShapePoints[ j ].z + m1 * ShapePoints[ j + iNumShapePoints ].z) / Texturescale, tv1 );
|
glm::vec3 { norm.x, norm.y, norm.z },
|
||||||
::glVertex3f( pt.x, pt.y, pt.z ); // pt nie mamy gdzie zapamiętać?
|
glm::vec2 { ( jmm1 * ShapePoints[ j ].z + m1 * ShapePoints[ j + iNumShapePoints ].z ) / Texturescale, tv1 } );
|
||||||
}
|
|
||||||
else {
|
|
||||||
Output->position.x = pt.x;
|
|
||||||
Output->position.y = pt.y;
|
|
||||||
Output->position.z = pt.z;
|
|
||||||
Output->normal.x = norm.x;
|
|
||||||
Output->normal.y = norm.y;
|
|
||||||
Output->normal.z = norm.z;
|
|
||||||
Output->texture.s = (jmm1 * ShapePoints[ j ].z + m1 * ShapePoints[ j + iNumShapePoints ].z) / Texturescale;
|
|
||||||
Output->texture.t = tv1;
|
|
||||||
++Output;
|
|
||||||
}
|
|
||||||
++vertexcount;
|
|
||||||
}
|
}
|
||||||
if( p ) // jeśli jest wskaźnik do tablicy
|
if( p ) // jeśli jest wskaźnik do tablicy
|
||||||
if( *p )
|
if( *p )
|
||||||
@@ -423,25 +404,12 @@ int TSegment::RenderLoft( CVertNormTex* &Output, Math3D::vector3 const &Origin,
|
|||||||
pt -= Origin;
|
pt -= Origin;
|
||||||
norm = ( jmm1 * ShapePoints[ j ].n.x + m1 * ShapePoints[ j + iNumShapePoints ].n.x ) * parallel2;
|
norm = ( jmm1 * ShapePoints[ j ].n.x + m1 * ShapePoints[ j + iNumShapePoints ].n.x ) * parallel2;
|
||||||
norm.y += jmm1 * ShapePoints[ j ].n.y + m1 * ShapePoints[ j + iNumShapePoints ].n.y;
|
norm.y += jmm1 * ShapePoints[ j ].n.y + m1 * ShapePoints[ j + iNumShapePoints ].n.y;
|
||||||
if( bRender ) { // skrzyżowania podczas łączenia siatek mogą nie renderować poboczy, ale potrzebować punktów
|
if( bRender ) {
|
||||||
if( Output == nullptr ) {
|
// skrzyżowania podczas łączenia siatek mogą nie renderować poboczy, ale potrzebować punktów
|
||||||
// immediate mode
|
Output.emplace_back(
|
||||||
::glNormal3f( norm.x, norm.y, norm.z );
|
glm::vec3 { pt.x, pt.y, pt.z },
|
||||||
::glTexCoord2f( (jmm2 * ShapePoints[ j ].z + m2 * ShapePoints[ j + iNumShapePoints ].z) / Texturescale, tv2 );
|
glm::vec3 { norm.x, norm.y, norm.z },
|
||||||
::glVertex3f( pt.x, pt.y, pt.z );
|
glm::vec2 { ( jmm2 * ShapePoints[ j ].z + m2 * ShapePoints[ j + iNumShapePoints ].z ) / Texturescale, tv2 } );
|
||||||
}
|
|
||||||
else {
|
|
||||||
Output->position.x = pt.x;
|
|
||||||
Output->position.y = pt.y;
|
|
||||||
Output->position.z = pt.z;
|
|
||||||
Output->normal.x = norm.x;
|
|
||||||
Output->normal.y = norm.y;
|
|
||||||
Output->normal.z = norm.z;
|
|
||||||
Output->texture.s = (jmm2 * ShapePoints[ j ].z + m2 * ShapePoints[ j + iNumShapePoints ].z) / Texturescale;
|
|
||||||
Output->texture.t = tv2;
|
|
||||||
++Output;
|
|
||||||
}
|
|
||||||
++vertexcount;
|
|
||||||
}
|
}
|
||||||
if( p ) // jeśli jest wskaźnik do tablicy
|
if( p ) // jeśli jest wskaźnik do tablicy
|
||||||
if( *p )
|
if( *p )
|
||||||
@@ -461,61 +429,30 @@ int TSegment::RenderLoft( CVertNormTex* &Output, Math3D::vector3 const &Origin,
|
|||||||
pt -= Origin;
|
pt -= Origin;
|
||||||
norm = ShapePoints[ j ].n.x * parallel1;
|
norm = ShapePoints[ j ].n.x * parallel1;
|
||||||
norm.y += ShapePoints[ j ].n.y;
|
norm.y += ShapePoints[ j ].n.y;
|
||||||
if( Output == nullptr ) {
|
|
||||||
// immediate mode
|
Output.emplace_back(
|
||||||
::glNormal3f( norm.x, norm.y, norm.z );
|
glm::vec3 { pt.x, pt.y, pt.z },
|
||||||
::glTexCoord2f( ShapePoints[ j ].z / Texturescale, tv1 );
|
glm::vec3 { norm.x, norm.y, norm.z },
|
||||||
::glVertex3f( pt.x, pt.y, pt.z ); // punkt na początku odcinka
|
glm::vec2 { ShapePoints[ j ].z / Texturescale, tv1 } );
|
||||||
}
|
|
||||||
else {
|
|
||||||
Output->position.x = pt.x;
|
|
||||||
Output->position.y = pt.y;
|
|
||||||
Output->position.z = pt.z;
|
|
||||||
Output->normal.x = norm.x;
|
|
||||||
Output->normal.y = norm.y;
|
|
||||||
Output->normal.z = norm.z;
|
|
||||||
Output->texture.s = ShapePoints[ j ].z / Texturescale;
|
|
||||||
Output->texture.t = tv1;
|
|
||||||
++Output;
|
|
||||||
}
|
|
||||||
++vertexcount;
|
|
||||||
|
|
||||||
pt = parallel2 * ShapePoints[ j ].x + pos2;
|
pt = parallel2 * ShapePoints[ j ].x + pos2;
|
||||||
pt.y += ShapePoints[ j ].y;
|
pt.y += ShapePoints[ j ].y;
|
||||||
pt -= Origin;
|
pt -= Origin;
|
||||||
norm = ShapePoints[ j ].n.x * parallel2;
|
norm = ShapePoints[ j ].n.x * parallel2;
|
||||||
norm.y += ShapePoints[ j ].n.y;
|
norm.y += ShapePoints[ j ].n.y;
|
||||||
if( Output == nullptr ) {
|
|
||||||
// immediate mode
|
Output.emplace_back(
|
||||||
::glNormal3f( norm.x, norm.y, norm.z );
|
glm::vec3 { pt.x, pt.y, pt.z },
|
||||||
::glTexCoord2f( ShapePoints[ j ].z / Texturescale, tv2 );
|
glm::vec3 { norm.x, norm.y, norm.z },
|
||||||
::glVertex3f( pt.x, pt.y, pt.z ); // punkt na końcu odcinka
|
glm::vec2 { ShapePoints[ j ].z / Texturescale, tv2 } );
|
||||||
}
|
|
||||||
else {
|
|
||||||
Output->position.x = pt.x;
|
|
||||||
Output->position.y = pt.y;
|
|
||||||
Output->position.z = pt.z;
|
|
||||||
Output->normal.x = norm.x;
|
|
||||||
Output->normal.y = norm.y;
|
|
||||||
Output->normal.z = norm.z;
|
|
||||||
Output->texture.s = ShapePoints[ j ].z / Texturescale;
|
|
||||||
Output->texture.t = tv2;
|
|
||||||
++Output;
|
|
||||||
}
|
|
||||||
++vertexcount;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( Output == nullptr ) {
|
|
||||||
// immediate mode
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
pos1 = pos2;
|
pos1 = pos2;
|
||||||
parallel1 = parallel2;
|
parallel1 = parallel2;
|
||||||
tv1 = tv2;
|
tv1 = tv2;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
return vertexcount;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void TSegment::Render()
|
void TSegment::Render()
|
||||||
|
|||||||
70
Segment.h
70
Segment.h
@@ -9,8 +9,10 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
#ifndef SegmentH
|
#ifndef SegmentH
|
||||||
#define SegmentH
|
#define SegmentH
|
||||||
|
/*
|
||||||
#include "VBO.h"
|
#include "VBO.h"
|
||||||
|
*/
|
||||||
|
#include "openglgeometrybank.h"
|
||||||
#include "dumb3d.h"
|
#include "dumb3d.h"
|
||||||
#include "Classes.h"
|
#include "Classes.h"
|
||||||
#include "usefull.h"
|
#include "usefull.h"
|
||||||
@@ -74,51 +76,35 @@ class TSegment
|
|||||||
bool bCurve = false;
|
bool bCurve = false;
|
||||||
TSegment(TTrack *owner);
|
TSegment(TTrack *owner);
|
||||||
~TSegment();
|
~TSegment();
|
||||||
bool Init(vector3 NewPoint1, vector3 NewPoint2, double fNewStep, double fNewRoll1 = 0,
|
bool Init(vector3 NewPoint1, vector3 NewPoint2, double fNewStep, double fNewRoll1 = 0, double fNewRoll2 = 0);
|
||||||
double fNewRoll2 = 0);
|
|
||||||
bool Init(vector3 &NewPoint1, vector3 NewCPointOut, vector3 NewCPointIn, vector3 &NewPoint2,
|
bool Init(vector3 &NewPoint1, vector3 NewCPointOut, vector3 NewCPointIn, vector3 &NewPoint2,
|
||||||
double fNewStep, double fNewRoll1 = 0, double fNewRoll2 = 0, bool bIsCurve = true);
|
double fNewStep, double fNewRoll1 = 0, double fNewRoll2 = 0, bool bIsCurve = true);
|
||||||
inline double ComputeLength(); // McZapkie-150503
|
inline double ComputeLength(); // McZapkie-150503
|
||||||
inline vector3 GetDirection1()
|
inline vector3 GetDirection1() {
|
||||||
{
|
return bCurve ? CPointOut - Point1 : CPointOut; };
|
||||||
return bCurve ? CPointOut - Point1 : CPointOut;
|
inline vector3 GetDirection2() {
|
||||||
};
|
return bCurve ? CPointIn - Point2 : CPointIn; };
|
||||||
inline vector3 GetDirection2()
|
|
||||||
{
|
|
||||||
return bCurve ? CPointIn - Point2 : CPointIn;
|
|
||||||
};
|
|
||||||
vector3 GetDirection(double fDistance);
|
vector3 GetDirection(double fDistance);
|
||||||
vector3 GetDirection()
|
vector3 GetDirection() {
|
||||||
{
|
return CPointOut; };
|
||||||
return CPointOut;
|
|
||||||
};
|
|
||||||
vector3 FastGetDirection(double fDistance, double fOffset);
|
vector3 FastGetDirection(double fDistance, double fOffset);
|
||||||
vector3 GetPoint(double fDistance);
|
vector3 GetPoint(double fDistance);
|
||||||
void RaPositionGet(double fDistance, vector3 &p, vector3 &a);
|
void RaPositionGet(double fDistance, vector3 &p, vector3 &a);
|
||||||
vector3 FastGetPoint(double t);
|
vector3 FastGetPoint(double t);
|
||||||
inline vector3 FastGetPoint_0()
|
inline vector3 FastGetPoint_0() {
|
||||||
{
|
return Point1; };
|
||||||
return Point1;
|
inline vector3 FastGetPoint_1() {
|
||||||
};
|
return Point2; };
|
||||||
inline vector3 FastGetPoint_1()
|
inline double GetRoll(double const Distance) {
|
||||||
{
|
return interpolate( fRoll1, fRoll2, Distance / fLength ); }
|
||||||
return Point2;
|
void GetRolls(double &r1, double &r2) {
|
||||||
};
|
// pobranie przechyłek (do generowania trójkątów)
|
||||||
inline double GetRoll(double const Distance)
|
|
||||||
{
|
|
||||||
return interpolate( fRoll1, fRoll2, Distance / fLength );
|
|
||||||
}
|
|
||||||
void GetRolls(double &r1, double &r2)
|
|
||||||
{ // pobranie przechyłek (do generowania trójkątów)
|
|
||||||
r1 = fRoll1;
|
r1 = fRoll1;
|
||||||
r2 = fRoll2;
|
r2 = fRoll2; }
|
||||||
}
|
bool RenderLoft( vertex_array &Output, Math3D::vector3 const &Origin, vector6 const *ShapePoints, int iNumShapePoints, double fTextureLength, double Texturescale = 1.0, int iSkip = 0, int iEnd = 0, double fOffsetX = 0.0, vector3 **p = nullptr, bool bRender = true);
|
||||||
int RenderLoft( CVertNormTex* &Output, Math3D::vector3 const &Origin, vector6 const *ShapePoints, int iNumShapePoints, double fTextureLength, double Texturescale = 1.0, int iSkip = 0, int iEnd = 0, double fOffsetX = 0.0, vector3 **p = nullptr, bool bRender = true);
|
|
||||||
void Render();
|
void Render();
|
||||||
inline double GetLength()
|
inline double GetLength() {
|
||||||
{
|
return fLength; };
|
||||||
return fLength;
|
|
||||||
};
|
|
||||||
void MoveMe(vector3 pPosition)
|
void MoveMe(vector3 pPosition)
|
||||||
{
|
{
|
||||||
Point1 += pPosition;
|
Point1 += pPosition;
|
||||||
@@ -129,14 +115,10 @@ class TSegment
|
|||||||
CPointOut += pPosition;
|
CPointOut += pPosition;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int RaSegCount()
|
int RaSegCount() {
|
||||||
{
|
return fTsBuffer ? iSegCount : 1; };
|
||||||
return fTsBuffer ? iSegCount : 1;
|
void AngleSet(int i, double a) {
|
||||||
};
|
fAngle[i] = a; };
|
||||||
void AngleSet(int i, double a)
|
|
||||||
{
|
|
||||||
fAngle[i] = a;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
558
Track.cpp
558
Track.cpp
@@ -177,7 +177,6 @@ void TTrack::Init()
|
|||||||
case tt_Cross: // tylko dla skrzyżowania dróg
|
case tt_Cross: // tylko dla skrzyżowania dróg
|
||||||
SwitchExtension = std::make_shared<TSwitchExtension>( this, 6 ); // 6 po³¹czeñ
|
SwitchExtension = std::make_shared<TSwitchExtension>( this, 6 ); // 6 po³¹czeñ
|
||||||
SwitchExtension->vPoints = nullptr; // brak tablicy punktów
|
SwitchExtension->vPoints = nullptr; // brak tablicy punktów
|
||||||
SwitchExtension->iPoints = 0;
|
|
||||||
SwitchExtension->bPoints = false; // tablica punktów nie wypełniona
|
SwitchExtension->bPoints = false; // tablica punktów nie wypełniona
|
||||||
SwitchExtension->iRoads = 4; // domyślnie 4
|
SwitchExtension->iRoads = 4; // domyślnie 4
|
||||||
break;
|
break;
|
||||||
@@ -203,7 +202,9 @@ TTrack * TTrack::Create400m(int what, double dx)
|
|||||||
TSubRect *r = Global::pGround->GetSubRect(tmp->pCenter.x, tmp->pCenter.z);
|
TSubRect *r = Global::pGround->GetSubRect(tmp->pCenter.x, tmp->pCenter.z);
|
||||||
r->NodeAdd(tmp); // dodanie toru do segmentu
|
r->NodeAdd(tmp); // dodanie toru do segmentu
|
||||||
r->Sort(); //żeby wyświetlał tabor z dodanego toru
|
r->Sort(); //żeby wyświetlał tabor z dodanego toru
|
||||||
|
/*
|
||||||
r->Release(); // usunięcie skompilowanych zasobów
|
r->Release(); // usunięcie skompilowanych zasobów
|
||||||
|
*/
|
||||||
return trk;
|
return trk;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -313,7 +314,9 @@ TTrack * TTrack::NullCreate(int dir)
|
|||||||
if (tmp2)
|
if (tmp2)
|
||||||
r->NodeAdd(tmp2); // drugiego też
|
r->NodeAdd(tmp2); // drugiego też
|
||||||
r->Sort(); //żeby wyświetlał tabor z dodanego toru
|
r->Sort(); //żeby wyświetlał tabor z dodanego toru
|
||||||
|
/*
|
||||||
r->Release(); // usunięcie skompilowanych zasobów
|
r->Release(); // usunięcie skompilowanych zasobów
|
||||||
|
*/
|
||||||
return trk;
|
return trk;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -989,22 +992,6 @@ bool TTrack::AddDynamicObject(TDynamicObject *Dynamic)
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
void TTrack::MoveMe(vector3 pPosition)
|
|
||||||
{ // to nie jest używane
|
|
||||||
if (SwitchExtension)
|
|
||||||
{
|
|
||||||
SwitchExtension->Segments[0]->MoveMe(1 * pPosition);
|
|
||||||
SwitchExtension->Segments[1]->MoveMe(1 * pPosition);
|
|
||||||
SwitchExtension->Segments[2]->MoveMe(3 * pPosition); // Ra: 3 razy?
|
|
||||||
SwitchExtension->Segments[3]->MoveMe(4 * pPosition);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Segment->MoveMe(pPosition);
|
|
||||||
};
|
|
||||||
ResourceManager::Unregister(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
const int numPts = 4;
|
const int numPts = 4;
|
||||||
const int nnumPts = 12;
|
const int nnumPts = 12;
|
||||||
|
|
||||||
@@ -1039,10 +1026,10 @@ const vector6 iglica[nnumPts] = // iglica - vextor3(x,y,mapowanie tekstury)
|
|||||||
vector6(-0.040, -0.180, 1.00, -1.000, 0.000,
|
vector6(-0.040, -0.180, 1.00, -1.000, 0.000,
|
||||||
0.000) // 1mm więcej, żeby nie nachodziły tekstury?
|
0.000) // 1mm więcej, żeby nie nachodziły tekstury?
|
||||||
};
|
};
|
||||||
|
/*
|
||||||
void TTrack::Compile(GLuint tex)
|
void TTrack::Compile(GLuint tex)
|
||||||
{
|
{
|
||||||
CVertNormTex *immediate{ nullptr };
|
basic_vertex *immediate{ nullptr };
|
||||||
|
|
||||||
// generowanie treści dla Display Lists - model proceduralny
|
// generowanie treści dla Display Lists - model proceduralny
|
||||||
if (!tex)
|
if (!tex)
|
||||||
@@ -1656,14 +1643,16 @@ void TTrack::Compile(GLuint tex)
|
|||||||
if (Global::bManageNodes)
|
if (Global::bManageNodes)
|
||||||
glEndList();
|
glEndList();
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
void TTrack::Release()
|
void TTrack::Release()
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
if (DisplayListID)
|
if (DisplayListID)
|
||||||
glDeleteLists(DisplayListID, 1);
|
glDeleteLists(DisplayListID, 1);
|
||||||
DisplayListID = 0;
|
DisplayListID = 0;
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
/*
|
||||||
void TTrack::Render()
|
void TTrack::Render()
|
||||||
{
|
{
|
||||||
if (bVisible) // Ra: tory są renderowane sektorami i nie ma sensu każdorazowo liczyć odległości
|
if (bVisible) // Ra: tory są renderowane sektorami i nie ma sensu każdorazowo liczyć odległości
|
||||||
@@ -1682,7 +1671,7 @@ void TTrack::Render()
|
|||||||
Release(); // zwrotnica w trakcie animacji do odrysowania
|
Release(); // zwrotnica w trakcie animacji do odrysowania
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
bool TTrack::CheckDynamicObject(TDynamicObject *Dynamic)
|
bool TTrack::CheckDynamicObject(TDynamicObject *Dynamic)
|
||||||
{ // sprawdzenie, czy pojazd jest przypisany do toru
|
{ // sprawdzenie, czy pojazd jest przypisany do toru
|
||||||
for( auto dynamic : Dynamics ) {
|
for( auto dynamic : Dynamics ) {
|
||||||
@@ -1774,7 +1763,7 @@ void TTrack::RaAssign(TGroundNode *gn, TAnimModel *am, TEvent *done, TEvent *joi
|
|||||||
am->GetContainer(NULL)->EventAssign(done); // zdarzenie zakończenia animacji
|
am->GetContainer(NULL)->EventAssign(done); // zdarzenie zakończenia animacji
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
/*
|
||||||
int TTrack::RaArrayPrepare()
|
int TTrack::RaArrayPrepare()
|
||||||
{ // przygotowanie tablic do skopiowania do VBO (zliczanie wierzchołków)
|
{ // przygotowanie tablic do skopiowania do VBO (zliczanie wierzchołków)
|
||||||
if (bVisible) // o ile w ogóle widać
|
if (bVisible) // o ile w ogóle widać
|
||||||
@@ -1803,16 +1792,6 @@ int TTrack::RaArrayPrepare()
|
|||||||
+ SwitchExtension->Segments[ 4 ]->RaSegCount()
|
+ SwitchExtension->Segments[ 4 ]->RaSegCount()
|
||||||
+ SwitchExtension->Segments[ 5 ]->RaSegCount();
|
+ SwitchExtension->Segments[ 5 ]->RaSegCount();
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
if (fTexHeight1 >= 0) {
|
|
||||||
// normalne pobocze, na razie się składa z
|
|
||||||
return ( ( TextureID1 ? SwitchExtension->iPoints + SwitchExtension->iRoads + 2 : 0 ) + ( TextureID2 ? SwitchExtension->iPoints * 12 : 0 ) );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// jeśli fTexHeight1<0, to są chodniki i może któregoś nie być
|
|
||||||
return ( ( TextureID1 ? SwitchExtension->iPoints + SwitchExtension->iRoads + 2 : 0 ) + ( TextureID2 ? SwitchExtension->iPoints * 6 : 0 ) );
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// each sub-segment covers only one side of the road, so it has points for single sideroad, if any
|
// each sub-segment covers only one side of the road, so it has points for single sideroad, if any
|
||||||
return ( ( TextureID1 ? SwitchExtension->iPoints + SwitchExtension->iRoads + 2 : 0 ) + ( TextureID2 ? SwitchExtension->iPoints * 6 : 0 ) );
|
return ( ( TextureID1 ? SwitchExtension->iPoints + SwitchExtension->iRoads + 2 : 0 ) + ( TextureID2 ? SwitchExtension->iPoints * 6 : 0 ) );
|
||||||
}
|
}
|
||||||
@@ -1829,28 +1808,28 @@ int TTrack::RaArrayPrepare()
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
void TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int const Vertexcount)
|
// wypełnianie tablic VBO
|
||||||
{ // wypełnianie tablic VBO
|
void TTrack::create_geometry( geometrybank_handle const &Bank ) {
|
||||||
// Ra: trzeba rozdzielić szyny od podsypki, aby móc grupować wg tekstur
|
// Ra: trzeba rozdzielić szyny od podsypki, aby móc grupować wg tekstur
|
||||||
double fHTW = 0.5 * fabs(fTrackWidth);
|
double const fHTW = 0.5 * std::fabs(fTrackWidth);
|
||||||
double side = fabs(fTexWidth); // szerokść podsypki na zewnątrz szyny albo pobocza
|
double const side = std::fabs(fTexWidth); // szerokść podsypki na zewnątrz szyny albo pobocza
|
||||||
double slop = fabs(fTexSlope); // brzeg zewnętrzny
|
double const slop = std::fabs(fTexSlope); // brzeg zewnętrzny
|
||||||
double rozp = fHTW + side + slop; // brzeg zewnętrzny
|
double const rozp = fHTW + side + slop; // brzeg zewnętrzny
|
||||||
double hypot1 = hypot(slop, fTexHeight1); // rozmiar pochylenia do liczenia normalnych
|
double hypot1 = std::hypot(slop, fTexHeight1); // rozmiar pochylenia do liczenia normalnych
|
||||||
if (hypot1 == 0.0)
|
if (hypot1 == 0.0)
|
||||||
hypot1 = 1.0;
|
hypot1 = 1.0;
|
||||||
vector3 normal1 = vector3(fTexSlope / hypot1, fTexHeight1 / hypot1, 0.0); // wektor normalny
|
vector3 normal1 { fTexSlope / hypot1, fTexHeight1 / hypot1, 0.0 }; // wektor normalny
|
||||||
double fHTW2, side2, slop2, rozp2, fTexHeight2, hypot2;
|
double fHTW2, side2, slop2, rozp2, fTexHeight2, hypot2;
|
||||||
vector3 normal2;
|
vector3 normal2;
|
||||||
if (iTrapezoid & 2) // ten bit oznacza, że istnieje odpowiednie pNext
|
if (iTrapezoid & 2) // ten bit oznacza, że istnieje odpowiednie pNext
|
||||||
{ // Ra: jest OK
|
{ // Ra: jest OK
|
||||||
fHTW2 = 0.5 * fabs(trNext->fTrackWidth); // połowa rozstawu/nawierzchni
|
fHTW2 = 0.5 * std::fabs(trNext->fTrackWidth); // połowa rozstawu/nawierzchni
|
||||||
side2 = fabs(trNext->fTexWidth);
|
side2 = std::fabs(trNext->fTexWidth);
|
||||||
slop2 = fabs(trNext->fTexSlope); // nie jest używane później
|
slop2 = std::fabs(trNext->fTexSlope); // nie jest używane później
|
||||||
rozp2 = fHTW2 + side2 + slop2;
|
rozp2 = fHTW2 + side2 + slop2;
|
||||||
fTexHeight2 = trNext->fTexHeight1;
|
fTexHeight2 = trNext->fTexHeight1;
|
||||||
hypot2 = hypot(slop2, fTexHeight2);
|
hypot2 = std::hypot(slop2, fTexHeight2);
|
||||||
if (hypot2 == 0.0)
|
if (hypot2 == 0.0)
|
||||||
hypot2 = 1.0;
|
hypot2 = 1.0;
|
||||||
normal2 = vector3(trNext->fTexSlope / hypot2, fTexHeight2 / hypot2, 0.0);
|
normal2 = vector3(trNext->fTexSlope / hypot2, fTexHeight2 / hypot2, 0.0);
|
||||||
@@ -1877,37 +1856,48 @@ void TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int cons
|
|||||||
Segment->GetRolls(roll1, roll2);
|
Segment->GetRolls(roll1, roll2);
|
||||||
else
|
else
|
||||||
roll1 = roll2 = 0.0; // dla zwrotnic
|
roll1 = roll2 = 0.0; // dla zwrotnic
|
||||||
double sin1 = sin(roll1), cos1 = cos(roll1), sin2 = sin(roll2), cos2 = cos(roll2);
|
double sin1 = std::sin(roll1), cos1 = std::cos(roll1), sin2 = std::sin(roll2), cos2 = std::cos(roll2);
|
||||||
// zwykla szyna: //Ra: czemu główki są asymetryczne na wysokości 0.140?
|
// zwykla szyna: //Ra: czemu główki są asymetryczne na wysokości 0.140?
|
||||||
vector6 rpts1[24], rpts2[24], rpts3[24], rpts4[24];
|
vector6 rpts1[24], rpts2[24], rpts3[24], rpts4[24];
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 12; ++i)
|
for (i = 0; i < 12; ++i)
|
||||||
{
|
{
|
||||||
rpts1[i] = vector6((fHTW + szyna[i].x) * cos1 + szyna[i].y * sin1,
|
rpts1[i] = vector6(
|
||||||
-(fHTW + szyna[i].x) * sin1 + szyna[i].y * cos1, szyna[i].z,
|
(fHTW + szyna[i].x) * cos1 + szyna[i].y * sin1,
|
||||||
+szyna[i].n.x * cos1 + szyna[i].n.y * sin1,
|
-(fHTW + szyna[i].x) * sin1 + szyna[i].y * cos1,
|
||||||
-szyna[i].n.x * sin1 + szyna[i].n.y * cos1, 0.0);
|
szyna[i].z,
|
||||||
rpts2[11 - i] = vector6((-fHTW - szyna[i].x) * cos1 + szyna[i].y * sin1,
|
szyna[i].n.x * cos1 + szyna[i].n.y * sin1,
|
||||||
-(-fHTW - szyna[i].x) * sin1 + szyna[i].y * cos1, szyna[i].z,
|
-szyna[i].n.x * sin1 + szyna[i].n.y * cos1,
|
||||||
-szyna[i].n.x * cos1 + szyna[i].n.y * sin1,
|
0.0);
|
||||||
+szyna[i].n.x * sin1 + szyna[i].n.y * cos1, 0.0);
|
rpts2[11 - i] = vector6(
|
||||||
|
(-fHTW - szyna[i].x) * cos1 + szyna[i].y * sin1,
|
||||||
|
-(-fHTW - szyna[i].x) * sin1 + szyna[i].y * cos1,
|
||||||
|
szyna[i].z,
|
||||||
|
-szyna[i].n.x * cos1 + szyna[i].n.y * sin1,
|
||||||
|
szyna[i].n.x * sin1 + szyna[i].n.y * cos1,
|
||||||
|
0.0);
|
||||||
}
|
}
|
||||||
if (iTrapezoid) // trapez albo przechyłki, to oddzielne punkty na końcu
|
if (iTrapezoid) // trapez albo przechyłki, to oddzielne punkty na końcu
|
||||||
for (i = 0; i < 12; ++i)
|
for (i = 0; i < 12; ++i)
|
||||||
{
|
{
|
||||||
rpts1[12 + i] = vector6((fHTW2 + szyna[i].x) * cos2 + szyna[i].y * sin2,
|
rpts1[12 + i] = vector6(
|
||||||
-(fHTW2 + szyna[i].x) * sin2 + szyna[i].y * cos2,
|
(fHTW2 + szyna[i].x) * cos2 + szyna[i].y * sin2,
|
||||||
szyna[i].z, +szyna[i].n.x * cos2 + szyna[i].n.y * sin2,
|
-(fHTW2 + szyna[i].x) * sin2 + szyna[i].y * cos2,
|
||||||
-szyna[i].n.x * sin2 + szyna[i].n.y * cos2, 0.0);
|
szyna[i].z,
|
||||||
rpts2[23 - i] = vector6((-fHTW2 - szyna[i].x) * cos2 + szyna[i].y * sin2,
|
szyna[i].n.x * cos2 + szyna[i].n.y * sin2,
|
||||||
-(-fHTW2 - szyna[i].x) * sin2 + szyna[i].y * cos2,
|
-szyna[i].n.x * sin2 + szyna[i].n.y * cos2,
|
||||||
szyna[i].z, -szyna[i].n.x * cos2 + szyna[i].n.y * sin2,
|
0.0);
|
||||||
+szyna[i].n.x * sin2 + szyna[i].n.y * cos2, 0.0);
|
rpts2[23 - i] = vector6(
|
||||||
|
(-fHTW2 - szyna[i].x) * cos2 + szyna[i].y * sin2,
|
||||||
|
-(-fHTW2 - szyna[i].x) * sin2 + szyna[i].y * cos2,
|
||||||
|
szyna[i].z,
|
||||||
|
-szyna[i].n.x * cos2 + szyna[i].n.y * sin2,
|
||||||
|
szyna[i].n.x * sin2 + szyna[i].n.y * cos2,
|
||||||
|
0.0);
|
||||||
}
|
}
|
||||||
switch (eType) // dalej zależnie od typu
|
switch (eType) // dalej zależnie od typu
|
||||||
{
|
{
|
||||||
case tt_Table: // obrotnica jak zwykły tor, tylko animacja dochodzi
|
case tt_Table: // obrotnica jak zwykły tor, tylko animacja dochodzi
|
||||||
SwitchExtension->iLeftVBO = Vert - Start; // indeks toru obrotnicy
|
|
||||||
case tt_Normal:
|
case tt_Normal:
|
||||||
if (TextureID2)
|
if (TextureID2)
|
||||||
{ // podsypka z podkładami jest tylko dla zwykłego toru
|
{ // podsypka z podkładami jest tylko dla zwykłego toru
|
||||||
@@ -1969,12 +1959,33 @@ void TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int cons
|
|||||||
bpts1[3] = vector6(-rozp, -fTexHeight1 - 0.18, 0.5 + map12, -normal1.x, -normal1.y, 0.0); // prawy skos
|
bpts1[3] = vector6(-rozp, -fTexHeight1 - 0.18, 0.5 + map12, -normal1.x, -normal1.y, 0.0); // prawy skos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Segment->RenderLoft(Vert, origin, bpts1, iTrapezoid ? -4 : 4, fTexLength);
|
vertex_array vertices;
|
||||||
|
Segment->RenderLoft(vertices, origin, bpts1, iTrapezoid ? -4 : 4, fTexLength);
|
||||||
|
if( ( Bank == 0 ) && ( false == Geometry2.empty() ) ) {
|
||||||
|
// special variant, replace existing data for a turntable track
|
||||||
|
GfxRenderer.Replace( vertices, Geometry2[ 0 ] );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (TextureID1)
|
if (TextureID1)
|
||||||
{ // szyny - generujemy dwie, najwyżej rysować się będzie jedną
|
{ // szyny - generujemy dwie, najwyżej rysować się będzie jedną
|
||||||
Segment->RenderLoft(Vert, origin, rpts1, iTrapezoid ? -nnumPts : nnumPts, fTexLength);
|
vertex_array vertices;
|
||||||
Segment->RenderLoft(Vert, origin, rpts2, iTrapezoid ? -nnumPts : nnumPts, fTexLength);
|
if( ( Bank == 0 ) && ( false == Geometry1.empty() ) ) {
|
||||||
|
Segment->RenderLoft( vertices, origin, rpts1, iTrapezoid ? -nnumPts : nnumPts, fTexLength );
|
||||||
|
GfxRenderer.Replace( vertices, Geometry1[ 0 ] );
|
||||||
|
vertices.clear(); // reuse the scratchpad
|
||||||
|
Segment->RenderLoft( vertices, origin, rpts2, iTrapezoid ? -nnumPts : nnumPts, fTexLength );
|
||||||
|
GfxRenderer.Replace( vertices, Geometry1[ 1 ] );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Segment->RenderLoft( vertices, origin, rpts1, iTrapezoid ? -nnumPts : nnumPts, fTexLength );
|
||||||
|
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
|
vertices.clear(); // reuse the scratchpad
|
||||||
|
Segment->RenderLoft( vertices, origin, rpts2, iTrapezoid ? -nnumPts : nnumPts, fTexLength );
|
||||||
|
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case tt_Switch: // dla zwrotnicy dwa razy szyny
|
case tt_Switch: // dla zwrotnicy dwa razy szyny
|
||||||
@@ -1984,47 +1995,85 @@ void TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int cons
|
|||||||
for (i = 0; i < 12; ++i)
|
for (i = 0; i < 12; ++i)
|
||||||
{
|
{
|
||||||
rpts3[i] =
|
rpts3[i] =
|
||||||
vector6(+(fHTW + iglica[i].x) * cos1 + iglica[i].y * sin1,
|
vector6(
|
||||||
-(+fHTW + iglica[i].x) * sin1 + iglica[i].y * cos1, iglica[i].z);
|
+( fHTW + iglica[i].x) * cos1 + iglica[i].y * sin1,
|
||||||
|
-(+fHTW + iglica[i].x) * sin1 + iglica[i].y * cos1,
|
||||||
|
iglica[i].z);
|
||||||
rpts3[i + 12] =
|
rpts3[i + 12] =
|
||||||
vector6(+(fHTW2 + szyna[i].x) * cos2 + szyna[i].y * sin2,
|
vector6(
|
||||||
-(+fHTW2 + szyna[i].x) * sin2 + iglica[i].y * cos2, szyna[i].z);
|
+( fHTW2 + szyna[i].x) * cos2 + szyna[i].y * sin2,
|
||||||
|
-(+fHTW2 + szyna[i].x) * sin2 + iglica[i].y * cos2,
|
||||||
|
szyna[i].z);
|
||||||
rpts4[11 - i] =
|
rpts4[11 - i] =
|
||||||
vector6((-fHTW - iglica[i].x) * cos1 + iglica[i].y * sin1,
|
vector6(
|
||||||
-(-fHTW - iglica[i].x) * sin1 + iglica[i].y * cos1, iglica[i].z);
|
(-fHTW - iglica[i].x) * cos1 + iglica[i].y * sin1,
|
||||||
|
-(-fHTW - iglica[i].x) * sin1 + iglica[i].y * cos1,
|
||||||
|
iglica[i].z);
|
||||||
rpts4[23 - i] =
|
rpts4[23 - i] =
|
||||||
vector6((-fHTW2 - szyna[i].x) * cos2 + szyna[i].y * sin2,
|
vector6(
|
||||||
-(-fHTW2 - szyna[i].x) * sin2 + iglica[i].y * cos2, szyna[i].z);
|
(-fHTW2 - szyna[i].x) * cos2 + szyna[i].y * sin2,
|
||||||
|
-(-fHTW2 - szyna[i].x) * sin2 + iglica[i].y * cos2,
|
||||||
|
szyna[i].z);
|
||||||
}
|
}
|
||||||
|
// TODO, TBD: change all track geometry to triangles, to allow packing data in less, larger buffers
|
||||||
if (SwitchExtension->RightSwitch)
|
if (SwitchExtension->RightSwitch)
|
||||||
{ // nowa wersja z SPKS, ale odwrotnie lewa/prawa
|
{ // nowa wersja z SPKS, ale odwrotnie lewa/prawa
|
||||||
|
vertex_array vertices;
|
||||||
if( TextureID1 ) {
|
if( TextureID1 ) {
|
||||||
SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, origin, rpts2, nnumPts, fTexLength );
|
// fixed parts
|
||||||
SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, origin, rpts1, nnumPts, fTexLength, 1.0, 2 );
|
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, origin, rpts2, nnumPts, fTexLength );
|
||||||
|
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
SwitchExtension->iLeftVBO = Vert - Start; // indeks lewej iglicy
|
vertices.clear();
|
||||||
SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, origin, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, SwitchExtension->fOffset2 );
|
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, origin, rpts1, nnumPts, fTexLength, 1.0, 2 );
|
||||||
|
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
|
vertices.clear();
|
||||||
|
// left blade
|
||||||
|
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, origin, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, SwitchExtension->fOffset2 );
|
||||||
|
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
|
vertices.clear();
|
||||||
}
|
}
|
||||||
if( TextureID2 ) {
|
if( TextureID2 ) {
|
||||||
SwitchExtension->iRightVBO = Vert - Start; // indeks prawej iglicy
|
// fixed parts
|
||||||
SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, origin, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -fMaxOffset + SwitchExtension->fOffset1 );
|
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, origin, rpts1, nnumPts, fTexLength );
|
||||||
SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, origin, rpts2, nnumPts, fTexLength, 1.0, 2 );
|
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, origin, rpts1, nnumPts, fTexLength );
|
vertices.clear();
|
||||||
|
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, origin, rpts2, nnumPts, fTexLength, 1.0, 2 );
|
||||||
|
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
|
vertices.clear();
|
||||||
|
// right blade
|
||||||
|
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, origin, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -fMaxOffset + SwitchExtension->fOffset1 );
|
||||||
|
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
|
vertices.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // lewa działa lepiej niż prawa
|
{ // lewa działa lepiej niż prawa
|
||||||
|
vertex_array vertices;
|
||||||
if( TextureID1 ) {
|
if( TextureID1 ) {
|
||||||
SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, origin, rpts1, nnumPts, fTexLength ); // lewa szyna normalna cała
|
// fixed parts
|
||||||
SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, origin, rpts2, nnumPts, fTexLength, 1.0, 2 ); // prawa szyna za iglicą
|
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, origin, rpts1, nnumPts, fTexLength ); // lewa szyna normalna cała
|
||||||
SwitchExtension->iLeftVBO = Vert - Start; // indeks lewej iglicy
|
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, origin, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -SwitchExtension->fOffset2 ); // prawa iglica
|
vertices.clear();
|
||||||
|
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, origin, rpts2, nnumPts, fTexLength, 1.0, 2 ); // prawa szyna za iglicą
|
||||||
|
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
|
vertices.clear();
|
||||||
|
// right blade
|
||||||
|
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, origin, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -SwitchExtension->fOffset2 );
|
||||||
|
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
|
vertices.clear();
|
||||||
}
|
}
|
||||||
if( TextureID2 ) {
|
if( TextureID2 ) {
|
||||||
SwitchExtension->iRightVBO = Vert - Start; // indeks prawej iglicy
|
// fixed parts
|
||||||
SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, origin, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, fMaxOffset - SwitchExtension->fOffset1 ); // lewa iglica
|
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, origin, rpts2, nnumPts, fTexLength ); // prawa szyna normalnie cała
|
||||||
SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, origin, rpts1, nnumPts, fTexLength, 1.0, 2 ); // lewa szyna za iglicą
|
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, origin, rpts2, nnumPts, fTexLength ); // prawa szyna normalnie cała
|
vertices.clear();
|
||||||
|
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, origin, rpts1, nnumPts, fTexLength, 1.0, 2 ); // lewa szyna za iglicą
|
||||||
|
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
|
vertices.clear();
|
||||||
|
// left blade
|
||||||
|
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, origin, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, fMaxOffset - SwitchExtension->fOffset1 );
|
||||||
|
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
|
vertices.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2059,7 +2108,9 @@ void TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int cons
|
|||||||
}
|
}
|
||||||
if (TextureID1) // jeśli podana była tekstura, generujemy trójkąty
|
if (TextureID1) // jeśli podana była tekstura, generujemy trójkąty
|
||||||
{ // tworzenie trójkątów nawierzchni szosy
|
{ // tworzenie trójkątów nawierzchni szosy
|
||||||
Segment->RenderLoft(Vert, origin, bpts1, iTrapezoid ? -2 : 2, fTexLength);
|
vertex_array vertices;
|
||||||
|
Segment->RenderLoft(vertices, origin, bpts1, iTrapezoid ? -2 : 2, fTexLength);
|
||||||
|
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
}
|
}
|
||||||
if (TextureID2)
|
if (TextureID2)
|
||||||
{ // pobocze drogi - poziome przy przechyłce (a może krawężnik i chodnik zrobić jak w Midtown Madness 2?)
|
{ // pobocze drogi - poziome przy przechyłce (a może krawężnik i chodnik zrobić jak w Midtown Madness 2?)
|
||||||
@@ -2136,22 +2187,31 @@ void TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int cons
|
|||||||
rpts2[5] = vector6(bpts1[3].x - side2, bpts1[3].y + h2l, 0.484375 - map2l); // lewy brzeg lewego chodnika
|
rpts2[5] = vector6(bpts1[3].x - side2, bpts1[3].y + h2l, 0.484375 - map2l); // lewy brzeg lewego chodnika
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
vertex_array vertices;
|
||||||
if( iTrapezoid ) // trapez albo przechyłki
|
if( iTrapezoid ) // trapez albo przechyłki
|
||||||
{ // pobocza do trapezowatej nawierzchni - dodatkowe punkty z drugiej strony
|
{ // pobocza do trapezowatej nawierzchni - dodatkowe punkty z drugiej strony
|
||||||
// odcinka
|
// odcinka
|
||||||
if( ( fTexHeight1 >= 0.0 ) || ( slop != 0.0 ) ) {
|
if( ( fTexHeight1 >= 0.0 ) || ( slop != 0.0 ) ) {
|
||||||
Segment->RenderLoft( Vert, origin, rpts1, -3, fTexLength ); // tylko jeśli jest z prawej
|
Segment->RenderLoft( vertices, origin, rpts1, -3, fTexLength ); // tylko jeśli jest z prawej
|
||||||
|
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
|
vertices.clear();
|
||||||
}
|
}
|
||||||
if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) {
|
if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) {
|
||||||
Segment->RenderLoft( Vert, origin, rpts2, -3, fTexLength ); // tylko jeśli jest z lewej
|
Segment->RenderLoft( vertices, origin, rpts2, -3, fTexLength ); // tylko jeśli jest z lewej
|
||||||
|
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
|
vertices.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { // pobocza zwykłe, brak przechyłki
|
else { // pobocza zwykłe, brak przechyłki
|
||||||
if( ( fTexHeight1 >= 0.0 ) || ( slop != 0.0 ) ) {
|
if( ( fTexHeight1 >= 0.0 ) || ( slop != 0.0 ) ) {
|
||||||
Segment->RenderLoft( Vert, origin, rpts1, 3, fTexLength );
|
Segment->RenderLoft( vertices, origin, rpts1, 3, fTexLength );
|
||||||
|
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
|
vertices.clear();
|
||||||
}
|
}
|
||||||
if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) {
|
if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) {
|
||||||
Segment->RenderLoft( Vert, origin, rpts2, 3, fTexLength );
|
Segment->RenderLoft( vertices, origin, rpts2, 3, fTexLength );
|
||||||
|
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
|
vertices.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2182,12 +2242,25 @@ void TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int cons
|
|||||||
p[3] = SwitchExtension->Segments[1]->FastGetPoint_0(); // Point4 - przy trzech drogach pokrywa się z Point1
|
p[3] = SwitchExtension->Segments[1]->FastGetPoint_0(); // Point4 - przy trzech drogach pokrywa się z Point1
|
||||||
// 2014-07: na początek rysować brzegi jak dla łuków
|
// 2014-07: na początek rysować brzegi jak dla łuków
|
||||||
// punkty brzegu nawierzchni uzyskujemy podczas renderowania boków (bez sensu, ale najszybciej było zrobić)
|
// punkty brzegu nawierzchni uzyskujemy podczas renderowania boków (bez sensu, ale najszybciej było zrobić)
|
||||||
int i; // ile punktów (może byc różna ilość punktów między drogami)
|
int pointcount;
|
||||||
|
if( SwitchExtension->iRoads == 3 ) {
|
||||||
|
// mogą być tylko 3 drogi zamiast 4
|
||||||
|
pointcount =
|
||||||
|
SwitchExtension->Segments[ 0 ]->RaSegCount()
|
||||||
|
+ SwitchExtension->Segments[ 1 ]->RaSegCount()
|
||||||
|
+ SwitchExtension->Segments[ 2 ]->RaSegCount();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pointcount =
|
||||||
|
SwitchExtension->Segments[ 2 ]->RaSegCount()
|
||||||
|
+ SwitchExtension->Segments[ 3 ]->RaSegCount()
|
||||||
|
+ SwitchExtension->Segments[ 4 ]->RaSegCount()
|
||||||
|
+ SwitchExtension->Segments[ 5 ]->RaSegCount();
|
||||||
|
}
|
||||||
if (!SwitchExtension->vPoints)
|
if (!SwitchExtension->vPoints)
|
||||||
{ // jeśli tablica punktów nie jest jeszcze utworzona, zliczamy punkty i tworzymy ją
|
{ // jeśli tablica punktów nie jest jeszcze utworzona, zliczamy punkty i tworzymy ją
|
||||||
// points were already counted during preparation stage
|
|
||||||
// we'll need to add couple extra points for the complete fan we'll build
|
// we'll need to add couple extra points for the complete fan we'll build
|
||||||
SwitchExtension->vPoints = new vector3[SwitchExtension->iPoints + SwitchExtension->iRoads];
|
SwitchExtension->vPoints = new vector3[pointcount + SwitchExtension->iRoads];
|
||||||
}
|
}
|
||||||
vector3 *b =
|
vector3 *b =
|
||||||
SwitchExtension->bPoints ?
|
SwitchExtension->bPoints ?
|
||||||
@@ -2272,22 +2345,50 @@ void TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool render = ( TextureID2 != 0 ); // renderować nie trzeba, ale trzeba wyznaczyć punkty brzegowe nawierzchni
|
bool render = ( TextureID2 != 0 ); // renderować nie trzeba, ale trzeba wyznaczyć punkty brzegowe nawierzchni
|
||||||
// if (iTrapezoid) //trapez albo przechyłki
|
vertex_array vertices;
|
||||||
if (SwitchExtension->iRoads == 4)
|
if (SwitchExtension->iRoads == 4)
|
||||||
{ // pobocza do trapezowatej nawierzchni - dodatkowe punkty z drugiej strony odcinka
|
{ // pobocza do trapezowatej nawierzchni - dodatkowe punkty z drugiej strony odcinka
|
||||||
if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) {
|
if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) {
|
||||||
SwitchExtension->Segments[ 2 ]->RenderLoft( Vert, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render );
|
SwitchExtension->Segments[ 2 ]->RenderLoft( vertices, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render );
|
||||||
SwitchExtension->Segments[ 3 ]->RenderLoft( Vert, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render );
|
if( true == render ) {
|
||||||
SwitchExtension->Segments[ 4 ]->RenderLoft( Vert, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render );
|
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
SwitchExtension->Segments[ 5 ]->RenderLoft( Vert, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render );
|
vertices.clear();
|
||||||
|
}
|
||||||
|
SwitchExtension->Segments[ 3 ]->RenderLoft( vertices, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render );
|
||||||
|
if( true == render ) {
|
||||||
|
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
|
vertices.clear();
|
||||||
|
}
|
||||||
|
SwitchExtension->Segments[ 4 ]->RenderLoft( vertices, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render );
|
||||||
|
if( true == render ) {
|
||||||
|
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
|
vertices.clear();
|
||||||
|
}
|
||||||
|
SwitchExtension->Segments[ 5 ]->RenderLoft( vertices, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render );
|
||||||
|
if( true == render ) {
|
||||||
|
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
|
vertices.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// punkt 3 pokrywa się z punktem 1, jak w zwrotnicy; połączenie 1->2 nie musi być prostoliniowe
|
// punkt 3 pokrywa się z punktem 1, jak w zwrotnicy; połączenie 1->2 nie musi być prostoliniowe
|
||||||
if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) {
|
if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) {
|
||||||
SwitchExtension->Segments[ 2 ]->RenderLoft( Vert, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render ); // z P2 do P4
|
SwitchExtension->Segments[ 2 ]->RenderLoft( vertices, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render ); // z P2 do P4
|
||||||
SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render ); // z P4 do P3=P1 (odwrócony)
|
if( true == render ) {
|
||||||
SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render ); // z P1 do P2
|
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
|
vertices.clear();
|
||||||
|
}
|
||||||
|
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render ); // z P4 do P3=P1 (odwrócony)
|
||||||
|
if( true == render ) {
|
||||||
|
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
|
vertices.clear();
|
||||||
|
}
|
||||||
|
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render ); // z P1 do P2
|
||||||
|
if( true == render ) {
|
||||||
|
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
|
vertices.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2299,47 +2400,47 @@ void TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int cons
|
|||||||
SwitchExtension->bPoints = true; // tablica punktów została wypełniona
|
SwitchExtension->bPoints = true; // tablica punktów została wypełniona
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TextureID1) {
|
if( TextureID1 ) {
|
||||||
|
vertex_array vertices;
|
||||||
// jeśli podana tekstura nawierzchni
|
// jeśli podana tekstura nawierzchni
|
||||||
// we start with a vertex in the middle...
|
// we start with a vertex in the middle...
|
||||||
Vert->normal.x = 0.0;
|
vertices.emplace_back(
|
||||||
Vert->normal.y = 1.0;
|
glm::vec3{
|
||||||
Vert->normal.z = 0.0;
|
oxz.x - origin.x,
|
||||||
Vert->texture.s = 0.5;
|
oxz.y - origin.y,
|
||||||
Vert->texture.t = 0.5;
|
oxz.z - origin.z },
|
||||||
Vert->position.x = oxz.x - origin.x;
|
glm::vec3{ 0.0f, 1.0f, 0.0f },
|
||||||
Vert->position.y = oxz.y - origin.y;
|
glm::vec2{ 0.5f, 0.5f } );
|
||||||
Vert->position.z = oxz.z - origin.z;
|
|
||||||
++Vert;
|
|
||||||
// ...and add one extra vertex to close the fan...
|
// ...and add one extra vertex to close the fan...
|
||||||
Vert->normal.x = 0.0;
|
|
||||||
Vert->normal.y = 1.0;
|
|
||||||
Vert->normal.z = 0.0;
|
|
||||||
// mapowanie we współrzędnych scenerii
|
|
||||||
u = ( SwitchExtension->vPoints[ 0 ].x - oxz.x + origin.x ) / fTexLength;
|
u = ( SwitchExtension->vPoints[ 0 ].x - oxz.x + origin.x ) / fTexLength;
|
||||||
v = ( SwitchExtension->vPoints[ 0 ].z - oxz.z + origin.z ) / ( fTexRatio1 * fTexLength );
|
v = ( SwitchExtension->vPoints[ 0 ].z - oxz.z + origin.z ) / ( fTexRatio1 * fTexLength );
|
||||||
Vert->texture.s = cosa0 * u + sina0 * v + 0.5;
|
vertices.emplace_back(
|
||||||
Vert->texture.t = -sina0 * u + cosa0 * v + 0.5;
|
glm::vec3 {
|
||||||
Vert->position.x = SwitchExtension->vPoints[ 0 ].x;
|
SwitchExtension->vPoints[ 0 ].x,
|
||||||
Vert->position.y = SwitchExtension->vPoints[ 0 ].y;
|
SwitchExtension->vPoints[ 0 ].y,
|
||||||
Vert->position.z = SwitchExtension->vPoints[ 0 ].z;
|
SwitchExtension->vPoints[ 0 ].z },
|
||||||
++Vert;
|
glm::vec3{ 0.0f, 1.0f, 0.0f },
|
||||||
// ...then draw the precalculated rest
|
|
||||||
for (i = SwitchExtension->iPoints + SwitchExtension->iRoads - 1; i >= 0; --i)
|
|
||||||
{
|
|
||||||
Vert->normal.x = 0.0;
|
|
||||||
Vert->normal.y = 1.0;
|
|
||||||
Vert->normal.z = 0.0;
|
|
||||||
// mapowanie we współrzędnych scenerii
|
// mapowanie we współrzędnych scenerii
|
||||||
u = (SwitchExtension->vPoints[i].x - oxz.x + origin.x ) / fTexLength;
|
glm::vec2{
|
||||||
v = (SwitchExtension->vPoints[i].z - oxz.z + origin.z ) / (fTexRatio1 * fTexLength);
|
cosa0 * u + sina0 * v + 0.5,
|
||||||
Vert->texture.s = cosa0 * u + sina0 * v + 0.5;
|
-sina0 * u + cosa0 * v + 0.5 } );
|
||||||
Vert->texture.t = -sina0 * u + cosa0 * v + 0.5;
|
// ...then draw the precalculated rest
|
||||||
Vert->position.x = SwitchExtension->vPoints[ i ].x;
|
for (int i = pointcount + SwitchExtension->iRoads - 1; i >= 0; --i) {
|
||||||
Vert->position.y = SwitchExtension->vPoints[ i ].y;
|
// mapowanie we współrzędnych scenerii
|
||||||
Vert->position.z = SwitchExtension->vPoints[ i ].z;
|
u = ( SwitchExtension->vPoints[ i ].x - oxz.x + origin.x ) / fTexLength;
|
||||||
++Vert;
|
v = ( SwitchExtension->vPoints[ i ].z - oxz.z + origin.z ) / ( fTexRatio1 * fTexLength );
|
||||||
|
vertices.emplace_back(
|
||||||
|
glm::vec3 {
|
||||||
|
SwitchExtension->vPoints[ i ].x,
|
||||||
|
SwitchExtension->vPoints[ i ].y,
|
||||||
|
SwitchExtension->vPoints[ i ].z },
|
||||||
|
glm::vec3{ 0.0f, 1.0f, 0.0f },
|
||||||
|
// mapowanie we współrzędnych scenerii
|
||||||
|
glm::vec2{
|
||||||
|
cosa0 * u + sina0 * v + 0.5,
|
||||||
|
-sina0 * u + cosa0 * v + 0.5 } );
|
||||||
}
|
}
|
||||||
|
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_FAN ) );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} // tt_cross
|
} // tt_cross
|
||||||
@@ -2378,11 +2479,13 @@ void TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int cons
|
|||||||
}
|
}
|
||||||
if (TextureID1) // jeśli podana była tekstura, generujemy trójkąty
|
if (TextureID1) // jeśli podana była tekstura, generujemy trójkąty
|
||||||
{ // tworzenie trójkątów nawierzchni szosy
|
{ // tworzenie trójkątów nawierzchni szosy
|
||||||
Segment->RenderLoft(Vert, origin, bpts1, iTrapezoid ? -2 : 2, fTexLength);
|
vertex_array vertices;
|
||||||
|
Segment->RenderLoft(vertices, origin, bpts1, iTrapezoid ? -2 : 2, fTexLength);
|
||||||
|
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
}
|
}
|
||||||
if (TextureID2)
|
if (TextureID2)
|
||||||
{ // pobocze drogi - poziome przy przechyłce (a może krawężnik i chodnik zrobić jak w
|
{ // pobocze drogi - poziome przy przechyłce (a może krawężnik i chodnik zrobić jak w Midtown Madness 2?)
|
||||||
// Midtown Madness 2?)
|
vertex_array vertices;
|
||||||
vector6 rpts1[6],
|
vector6 rpts1[6],
|
||||||
rpts2[6]; // współrzędne przekroju i mapowania dla prawej i lewej strony
|
rpts2[6]; // współrzędne przekroju i mapowania dla prawej i lewej strony
|
||||||
rpts1[0] = vector6(rozp, -fTexHeight1, 0.0); // lewy brzeg podstawy
|
rpts1[0] = vector6(rozp, -fTexHeight1, 0.0); // lewy brzeg podstawy
|
||||||
@@ -2400,13 +2503,21 @@ void TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int cons
|
|||||||
rpts2[3] = vector6(bpts1[3].x, bpts1[3].y, 1.0);
|
rpts2[3] = vector6(bpts1[3].x, bpts1[3].y, 1.0);
|
||||||
rpts2[4] = vector6(bpts1[3].x - side2, bpts1[3].y, 0.5);
|
rpts2[4] = vector6(bpts1[3].x - side2, bpts1[3].y, 0.5);
|
||||||
rpts2[5] = vector6(-rozp2, -fTexHeight2, 0.0); // prawy brzeg prawego pobocza
|
rpts2[5] = vector6(-rozp2, -fTexHeight2, 0.0); // prawy brzeg prawego pobocza
|
||||||
Segment->RenderLoft(Vert, origin, rpts1, -3, fTexLength);
|
Segment->RenderLoft(vertices, origin, rpts1, -3, fTexLength);
|
||||||
Segment->RenderLoft(Vert, origin, rpts2, -3, fTexLength);
|
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
|
vertices.clear();
|
||||||
|
Segment->RenderLoft(vertices, origin, rpts2, -3, fTexLength);
|
||||||
|
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
|
vertices.clear();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // pobocza zwykłe, brak przechyłki
|
{ // pobocza zwykłe, brak przechyłki
|
||||||
Segment->RenderLoft(Vert, origin, rpts1, 3, fTexLength);
|
Segment->RenderLoft(vertices, origin, rpts1, 3, fTexLength);
|
||||||
Segment->RenderLoft(Vert, origin, rpts2, 3, fTexLength);
|
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
|
vertices.clear();
|
||||||
|
Segment->RenderLoft(vertices, origin, rpts2, 3, fTexLength);
|
||||||
|
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||||
|
vertices.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2415,10 +2526,9 @@ void TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int cons
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
/*
|
||||||
void TTrack::RaRenderVBO( int iPtr ) { // renderowanie z użyciem VBO
|
void TTrack::RaRenderVBO( int iPtr ) { // renderowanie z użyciem VBO
|
||||||
// Ra 2014-07: trzeba wymienić GL_TRIANGLE_STRIP na GL_TRIANGLES i renderować trójkąty sektora
|
// Ra 2014-07: trzeba wymienić GL_TRIANGLE_STRIP na GL_TRIANGLES i renderować trójkąty sektora dla kolejnych tekstur!
|
||||||
// dla kolejnych tekstur!
|
|
||||||
EnvironmentSet();
|
EnvironmentSet();
|
||||||
int seg;
|
int seg;
|
||||||
switch( iCategoryFlag & 15 ) {
|
switch( iCategoryFlag & 15 ) {
|
||||||
@@ -2568,7 +2678,7 @@ void TTrack::RaRenderVBO( int iPtr ) { // renderowanie z użyciem VBO
|
|||||||
}
|
}
|
||||||
EnvironmentReset();
|
EnvironmentReset();
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
void TTrack::EnvironmentSet()
|
void TTrack::EnvironmentSet()
|
||||||
{ // ustawienie zmienionego światła
|
{ // ustawienie zmienionego światła
|
||||||
glColor3f(1.0f, 1.0f, 1.0f); // Ra: potrzebne to?
|
glColor3f(1.0f, 1.0f, 1.0f); // Ra: potrzebne to?
|
||||||
@@ -2822,11 +2932,11 @@ void TTrack::RaAnimListAdd(TTrack *t)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TTrack * TTrack::RaAnimate(GLuint const Vertexbuffer)
|
TTrack * TTrack::RaAnimate()
|
||||||
{ // wykonanie rekurencyjne animacji, wywoływane przed wyświetleniem sektora
|
{ // wykonanie rekurencyjne animacji, wywoływane przed wyświetleniem sektora
|
||||||
// zwraca wskaźnik toru wymagającego dalszej animacji
|
// zwraca wskaźnik toru wymagającego dalszej animacji
|
||||||
if( SwitchExtension->pNextAnim )
|
if( SwitchExtension->pNextAnim )
|
||||||
SwitchExtension->pNextAnim = SwitchExtension->pNextAnim->RaAnimate( Vertexbuffer );
|
SwitchExtension->pNextAnim = SwitchExtension->pNextAnim->RaAnimate();
|
||||||
bool m = true; // animacja trwa
|
bool m = true; // animacja trwa
|
||||||
if (eType == tt_Switch) // dla zwrotnicy tylko szyny
|
if (eType == tt_Switch) // dla zwrotnicy tylko szyny
|
||||||
{
|
{
|
||||||
@@ -2855,77 +2965,85 @@ TTrack * TTrack::RaAnimate(GLuint const Vertexbuffer)
|
|||||||
m = false; // koniec animacji
|
m = false; // koniec animacji
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( ( Global::bUseVBO )
|
// skip the geometry update if no geometry for this track was generated yet
|
||||||
&& ( Vertexbuffer != -1 ) )
|
if( ( ( TextureID1 != 0 )
|
||||||
{ // dla OpenGL 1.4 odświeży się cały sektor, w późniejszych poprawiamy fragment
|
|| ( TextureID2 != 0 ) )
|
||||||
if (GLEW_VERSION_1_5) // dla OpenGL 1.4 to się nie wykona poprawnie
|
&& ( ( false == Geometry1.empty() )
|
||||||
if (TextureID1) // Ra: !!!! tu jest do poprawienia
|
|| ( false == Geometry2.empty() ) ) ) {
|
||||||
{ // iglice liczone tylko dla zwrotnic
|
// iglice liczone tylko dla zwrotnic
|
||||||
vector6 rpts3[24], rpts4[24];
|
double fHTW = 0.5 * fabs( fTrackWidth );
|
||||||
double fHTW = 0.5 * fabs(fTrackWidth);
|
double fHTW2 = fHTW; // Ra: na razie niech tak będzie
|
||||||
double fHTW2 = fHTW; // Ra: na razie niech tak będzie
|
double cos1 = 1.0, sin1 = 0.0, cos2 = 1.0, sin2 = 0.0; // Ra: ...
|
||||||
double cos1 = 1.0, sin1 = 0.0, cos2 = 1.0, sin2 = 0.0; // Ra: ...
|
vector6 rpts3[ 24 ], rpts4[ 24 ];
|
||||||
for( int i = 0; i < 12; ++i ) {
|
for (int i = 0; i < 12; ++i)
|
||||||
|
{
|
||||||
|
rpts3[i] =
|
||||||
|
vector6(
|
||||||
|
+( fHTW + iglica[i].x) * cos1 + iglica[i].y * sin1,
|
||||||
|
-(+fHTW + iglica[i].x) * sin1 + iglica[i].y * cos1,
|
||||||
|
iglica[i].z);
|
||||||
|
rpts3[i + 12] =
|
||||||
|
vector6(
|
||||||
|
+( fHTW2 + szyna[i].x) * cos2 + szyna[i].y * sin2,
|
||||||
|
-(+fHTW2 + szyna[i].x) * sin2 + iglica[i].y * cos2,
|
||||||
|
szyna[i].z);
|
||||||
|
rpts4[11 - i] =
|
||||||
|
vector6(
|
||||||
|
(-fHTW - iglica[i].x) * cos1 + iglica[i].y * sin1,
|
||||||
|
-(-fHTW - iglica[i].x) * sin1 + iglica[i].y * cos1,
|
||||||
|
iglica[i].z);
|
||||||
|
rpts4[23 - i] =
|
||||||
|
vector6(
|
||||||
|
(-fHTW2 - szyna[i].x) * cos2 + szyna[i].y * sin2,
|
||||||
|
-(-fHTW2 - szyna[i].x) * sin2 + iglica[i].y * cos2,
|
||||||
|
szyna[i].z);
|
||||||
|
}
|
||||||
|
|
||||||
rpts3[ i ] =
|
auto const origin { pMyNode->m_rootposition };
|
||||||
vector6( +( fHTW + iglica[ i ].x ) * cos1 + iglica[ i ].y * sin1,
|
vertex_array vertices;
|
||||||
-( +fHTW + iglica[ i ].x ) * sin1 + iglica[ i ].y * cos1, iglica[ i ].z );
|
|
||||||
rpts3[ i + 12 ] =
|
|
||||||
vector6( +( fHTW2 + szyna[ i ].x ) * cos2 + szyna[ i ].y * sin2,
|
|
||||||
-( +fHTW2 + szyna[ i ].x ) * sin2 + iglica[ i ].y * cos2, szyna[ i ].z );
|
|
||||||
rpts4[ 11 - i ] =
|
|
||||||
vector6( ( -fHTW - iglica[ i ].x ) * cos1 + iglica[ i ].y * sin1,
|
|
||||||
-( -fHTW - iglica[ i ].x ) * sin1 + iglica[ i ].y * cos1, iglica[ i ].z );
|
|
||||||
rpts4[ 23 - i ] =
|
|
||||||
vector6( ( -fHTW2 - szyna[ i ].x ) * cos2 + szyna[ i ].y * sin2,
|
|
||||||
-( -fHTW2 - szyna[ i ].x ) * sin2 + iglica[ i ].y * cos2, szyna[ i ].z );
|
|
||||||
}
|
|
||||||
// NOTE: performance-wise it'd make much more sense to keep the most recent shape cached as part of switch extension,
|
|
||||||
// and only send updates when/if they take place, instead of the current back-and-forth
|
|
||||||
// TODO: implement optimized version
|
|
||||||
|
|
||||||
// fetch current blade geometry
|
if (SwitchExtension->RightSwitch)
|
||||||
std::vector<CVertNormTex> bladesbuffer; bladesbuffer.resize( 2 * 2 * 24 ); // 2 blades, 2 segments each
|
{ // nowa wersja z SPKS, ale odwrotnie lewa/prawa
|
||||||
/*
|
vertex_array vertices;
|
||||||
::glGetBufferSubData(
|
if( TextureID1 ) {
|
||||||
GL_ARRAY_BUFFER,
|
// left blade
|
||||||
SwitchExtension->iLeftVBO * sizeof( CVertNormTex ),
|
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, origin, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, SwitchExtension->fOffset2 );
|
||||||
bladesbuffer.size() * sizeof( CVertNormTex ),
|
GfxRenderer.Replace( vertices, Geometry1[ 2 ] );
|
||||||
bladesbuffer.data() );
|
vertices.clear();
|
||||||
*/
|
|
||||||
auto bladevertices = bladesbuffer.data();
|
|
||||||
auto const origin { pMyNode->m_rootposition };
|
|
||||||
if( SwitchExtension->RightSwitch ) { // nowa wersja z SPKS, ale odwrotnie lewa/prawa
|
|
||||||
SwitchExtension->Segments[ 0 ]->RenderLoft( bladevertices, origin, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, SwitchExtension->fOffset2 /*, true*/ );
|
|
||||||
SwitchExtension->Segments[ 1 ]->RenderLoft( bladevertices, origin, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -fMaxOffset + SwitchExtension->fOffset1 /*, true*/ );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SwitchExtension->Segments[ 0 ]->RenderLoft( bladevertices, origin, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -SwitchExtension->fOffset2 /*, true*/ ); // prawa iglica
|
|
||||||
SwitchExtension->Segments[ 1 ]->RenderLoft( bladevertices, origin, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, fMaxOffset - SwitchExtension->fOffset1 /*, true*/ ); // lewa iglica
|
|
||||||
}
|
|
||||||
// push back updated geometry
|
|
||||||
::glBufferSubData(
|
|
||||||
GL_ARRAY_BUFFER,
|
|
||||||
SwitchExtension->iLeftVBO * sizeof( CVertNormTex ),
|
|
||||||
bladesbuffer.size() * sizeof( CVertNormTex ),
|
|
||||||
bladesbuffer.data() );
|
|
||||||
}
|
}
|
||||||
|
if( TextureID2 ) {
|
||||||
|
// right blade
|
||||||
|
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, origin, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -fMaxOffset + SwitchExtension->fOffset1 );
|
||||||
|
GfxRenderer.Replace( vertices, Geometry2[ 2 ] );
|
||||||
|
vertices.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { // lewa działa lepiej niż prawa
|
||||||
|
vertex_array vertices;
|
||||||
|
if( TextureID1 ) {
|
||||||
|
// right blade
|
||||||
|
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, origin, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -SwitchExtension->fOffset2 );
|
||||||
|
GfxRenderer.Replace( vertices, Geometry1[ 2 ] );
|
||||||
|
vertices.clear();
|
||||||
|
}
|
||||||
|
if( TextureID2 ) {
|
||||||
|
// left blade
|
||||||
|
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, origin, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, fMaxOffset - SwitchExtension->fOffset1 );
|
||||||
|
GfxRenderer.Replace( vertices, Geometry2[ 2 ] );
|
||||||
|
vertices.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else // gdy Display List
|
|
||||||
Release(); // niszczenie skompilowanej listy, aby się wygenerowała nowa
|
|
||||||
}
|
}
|
||||||
else if (eType == tt_Table) // dla obrotnicy - szyny i podsypka
|
else if (eType == tt_Table) {
|
||||||
{
|
// dla obrotnicy - szyny i podsypka
|
||||||
if (SwitchExtension->pModel &&
|
if (SwitchExtension->pModel &&
|
||||||
SwitchExtension->CurrentIndex) // 0=zablokowana się nie animuje
|
SwitchExtension->CurrentIndex) // 0=zablokowana się nie animuje
|
||||||
{ // trzeba każdorazowo porównywać z kątem modelu
|
{ // trzeba każdorazowo porównywać z kątem modelu
|
||||||
// SwitchExtension->fOffset1=SwitchExtension->pAnim?SwitchExtension->pAnim->AngleGet():0.0;
|
|
||||||
// //pobranie kąta z modelu
|
// //pobranie kąta z modelu
|
||||||
TAnimContainer *ac = SwitchExtension->pModel ?
|
TAnimContainer *ac = SwitchExtension->pModel ?
|
||||||
SwitchExtension->pModel->GetContainer(NULL) :
|
SwitchExtension->pModel->GetContainer(NULL) :
|
||||||
NULL; // pobranie głównego submodelu
|
NULL; // pobranie głównego submodelu
|
||||||
// if (ac) ac->EventAssign(SwitchExtension->evMinus); //event zakończenia animacji,
|
|
||||||
// trochę bez sensu tutaj
|
|
||||||
if (ac)
|
if (ac)
|
||||||
if ((ac->AngleGet() != SwitchExtension->fOffset) ||
|
if ((ac->AngleGet() != SwitchExtension->fOffset) ||
|
||||||
!(ac->TransGet() ==
|
!(ac->TransGet() ==
|
||||||
@@ -2947,22 +3065,26 @@ TTrack * TTrack::RaAnimate(GLuint const Vertexbuffer)
|
|||||||
dynamic->Move( 0.000001 );
|
dynamic->Move( 0.000001 );
|
||||||
}
|
}
|
||||||
// kąty
|
// kąty
|
||||||
|
/*
|
||||||
if (Global::bUseVBO)
|
if (Global::bUseVBO)
|
||||||
{ // dla OpenGL 1.4 odświeży się cały sektor, w późniejszych poprawiamy fragment
|
{ // dla OpenGL 1.4 odświeży się cały sektor, w późniejszych poprawiamy fragment
|
||||||
// aktualizacja pojazdów na torze
|
// aktualizacja pojazdów na torze
|
||||||
if (GLEW_VERSION_1_5) // dla OpenGL 1.4 to się nie wykona poprawnie
|
if (GLEW_VERSION_1_5) // dla OpenGL 1.4 to się nie wykona poprawnie
|
||||||
{
|
{
|
||||||
int size = RaArrayPrepare(); // wielkość tabeli potrzebna dla tej obrotnicy
|
int size = RaArrayPrepare(); // wielkość tabeli potrzebna dla tej obrotnicy
|
||||||
CVertNormTex *Vert = new CVertNormTex[size]; // bufor roboczy
|
basic_vertex *Vert = new basic_vertex[size]; // bufor roboczy
|
||||||
// CVertNormTex *v=Vert; //zmieniane przez
|
// basic_vertex *v=Vert; //zmieniane przez
|
||||||
RaArrayFill(Vert, Vert - SwitchExtension->iLeftVBO, size); // iLeftVBO powinno zostać niezmienione
|
RaArrayFill(Vert, Vert - SwitchExtension->iLeftVBO, size); // iLeftVBO powinno zostać niezmienione
|
||||||
::glBufferSubData(
|
::glBufferSubData(
|
||||||
GL_ARRAY_BUFFER, SwitchExtension->iLeftVBO * sizeof(CVertNormTex),
|
GL_ARRAY_BUFFER, SwitchExtension->iLeftVBO * sizeof(basic_vertex),
|
||||||
size * sizeof(CVertNormTex), Vert); // wysłanie fragmentu bufora VBO
|
size * sizeof(basic_vertex), Vert); // wysłanie fragmentu bufora VBO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // gdy Display List
|
else // gdy Display List
|
||||||
Release(); // niszczenie skompilowanej listy, aby się wygenerowała nowa
|
Release(); // niszczenie skompilowanej listy, aby się wygenerowała nowa
|
||||||
|
*/
|
||||||
|
// NOTE: passing empty handle is a bit of a hack here. could be refactored into something more elegant
|
||||||
|
create_geometry( geometrybank_handle() );
|
||||||
} // animacja trwa nadal
|
} // animacja trwa nadal
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
138
Track.h
138
Track.h
@@ -15,8 +15,6 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "Segment.h"
|
#include "Segment.h"
|
||||||
#include "Texture.h"
|
#include "Texture.h"
|
||||||
|
|
||||||
class TEvent;
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
tt_Unknown,
|
tt_Unknown,
|
||||||
@@ -39,6 +37,7 @@ typedef enum
|
|||||||
} TEnvironmentType;
|
} TEnvironmentType;
|
||||||
// Ra: opracować alternatywny system cieni/świateł z definiowaniem koloru oświetlenia w halach
|
// Ra: opracować alternatywny system cieni/świateł z definiowaniem koloru oświetlenia w halach
|
||||||
|
|
||||||
|
class TEvent;
|
||||||
class TTrack;
|
class TTrack;
|
||||||
class TGroundNode;
|
class TGroundNode;
|
||||||
class TSubRect;
|
class TSubRect;
|
||||||
@@ -77,10 +76,10 @@ class TSwitchExtension
|
|||||||
};
|
};
|
||||||
struct
|
struct
|
||||||
{ // zmienne dla skrzyżowania
|
{ // zmienne dla skrzyżowania
|
||||||
vector3 *vPoints; // tablica wierzchołków nawierzchni, generowana przez pobocze
|
|
||||||
int iPoints; // liczba faktycznie użytych wierzchołków nawierzchni
|
|
||||||
bool bPoints; // czy utworzone?
|
|
||||||
int iRoads; // ile dróg się spotyka?
|
int iRoads; // ile dróg się spotyka?
|
||||||
|
vector3 *vPoints; // tablica wierzchołków nawierzchni, generowana przez pobocze
|
||||||
|
// int iPoints; // liczba faktycznie użytych wierzchołków nawierzchni
|
||||||
|
bool bPoints; // czy utworzone?
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
bool bMovement = false; // czy w trakcie animacji
|
bool bMovement = false; // czy w trakcie animacji
|
||||||
@@ -108,46 +107,48 @@ class TIsolated
|
|||||||
TIsolated();
|
TIsolated();
|
||||||
TIsolated(const std::string &n, TIsolated *i);
|
TIsolated(const std::string &n, TIsolated *i);
|
||||||
~TIsolated();
|
~TIsolated();
|
||||||
static TIsolated * Find(
|
static TIsolated * Find(const std::string &n); // znalezienie obiektu albo utworzenie nowego
|
||||||
const std::string &n); // znalezienie obiektu albo utworzenie nowego
|
|
||||||
void Modify(int i, TDynamicObject *o); // dodanie lub odjęcie osi
|
void Modify(int i, TDynamicObject *o); // dodanie lub odjęcie osi
|
||||||
bool Busy()
|
bool Busy() {
|
||||||
{
|
return (iAxles > 0); };
|
||||||
return (iAxles > 0);
|
static TIsolated * Root() {
|
||||||
};
|
return (pRoot); };
|
||||||
static TIsolated * Root()
|
TIsolated * Next() {
|
||||||
{
|
return (pNext); };
|
||||||
return (pRoot);
|
|
||||||
};
|
|
||||||
TIsolated * Next()
|
|
||||||
{
|
|
||||||
return (pNext);
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class TTrack : public Resource
|
// trajektoria ruchu - opakowanie
|
||||||
{ // trajektoria ruchu - opakowanie
|
class TTrack : public Resource {
|
||||||
private:
|
|
||||||
|
friend class opengl_renderer;
|
||||||
|
|
||||||
|
private:
|
||||||
|
TGroundNode * pMyNode = nullptr; // Ra: proteza, żeby tor znał swoją nazwę TODO: odziedziczyć TTrack z TGroundNode
|
||||||
|
TIsolated * pIsolated = nullptr; // obwód izolowany obsługujący zajęcia/zwolnienia grupy torów
|
||||||
std::shared_ptr<TSwitchExtension> SwitchExtension; // dodatkowe dane do toru, który jest zwrotnicą
|
std::shared_ptr<TSwitchExtension> SwitchExtension; // dodatkowe dane do toru, który jest zwrotnicą
|
||||||
std::shared_ptr<TSegment> Segment;
|
std::shared_ptr<TSegment> Segment;
|
||||||
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_handle TextureID1 = 0; // tekstura szyn albo nawierzchni
|
int iTrapezoid = 0; // 0-standard, 1-przechyłka, 2-trapez, 3-oba
|
||||||
texture_handle TextureID2 = 0; // tekstura automatycznej podsypki albo pobocza
|
double fRadiusTable[ 2 ]; // dwa promienie, drugi dla zwrotnicy
|
||||||
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...)
|
||||||
float fTexHeight1 = 0.6f; // wysokość brzegu względem trajektorii
|
float fTexHeight1 = 0.6f; // wysokość brzegu względem trajektorii
|
||||||
float fTexWidth = 0.9f; // szerokość boku
|
float fTexWidth = 0.9f; // szerokość boku
|
||||||
float fTexSlope = 0.9f;
|
float fTexSlope = 0.9f;
|
||||||
double fRadiusTable[ 2 ]; // dwa promienie, drugi dla zwrotnicy
|
/*
|
||||||
int iTrapezoid = 0; // 0-standard, 1-przechyłka, 2-trapez, 3-oba
|
|
||||||
GLuint DisplayListID = 0;
|
GLuint DisplayListID = 0;
|
||||||
TIsolated *pIsolated = nullptr; // obwód izolowany obsługujący zajęcia/zwolnienia grupy torów
|
*/
|
||||||
TGroundNode *
|
texture_handle TextureID1 = 0; // tekstura szyn albo nawierzchni
|
||||||
pMyNode = nullptr; // Ra: proteza, żeby tor znał swoją nazwę TODO: odziedziczyć TTrack z TGroundNode
|
texture_handle TextureID2 = 0; // tekstura automatycznej podsypki albo pobocza
|
||||||
public:
|
typedef std::vector<geometry_handle> geometryhandle_sequence;
|
||||||
|
geometryhandle_sequence Geometry1; // geometry chunks textured with texture 1
|
||||||
|
geometryhandle_sequence Geometry2; // geometry chunks textured with texture 2
|
||||||
|
|
||||||
|
public:
|
||||||
typedef std::deque<TDynamicObject *> dynamics_sequence;
|
typedef std::deque<TDynamicObject *> dynamics_sequence;
|
||||||
dynamics_sequence Dynamics;
|
dynamics_sequence Dynamics;
|
||||||
int iEvents = 0; // Ra: flaga informująca o obecności eventów
|
int iEvents = 0; // Ra: flaga informująca o obecności eventów
|
||||||
@@ -193,39 +194,30 @@ class TTrack : public Resource
|
|||||||
void Init();
|
void Init();
|
||||||
static TTrack * Create400m(int what, double dx);
|
static TTrack * Create400m(int what, double dx);
|
||||||
TTrack * NullCreate(int dir);
|
TTrack * NullCreate(int dir);
|
||||||
inline bool IsEmpty()
|
inline bool IsEmpty() {
|
||||||
{
|
return Dynamics.empty(); };
|
||||||
return Dynamics.empty();
|
|
||||||
};
|
|
||||||
void ConnectPrevPrev(TTrack *pNewPrev, int typ);
|
void ConnectPrevPrev(TTrack *pNewPrev, int typ);
|
||||||
void ConnectPrevNext(TTrack *pNewPrev, int typ);
|
void ConnectPrevNext(TTrack *pNewPrev, int typ);
|
||||||
void ConnectNextPrev(TTrack *pNewNext, int typ);
|
void ConnectNextPrev(TTrack *pNewNext, int typ);
|
||||||
void ConnectNextNext(TTrack *pNewNext, int typ);
|
void ConnectNextNext(TTrack *pNewNext, int typ);
|
||||||
inline double Length()
|
inline double Length() {
|
||||||
{
|
return Segment->GetLength(); };
|
||||||
return Segment->GetLength();
|
inline std::shared_ptr<TSegment> CurrentSegment() {
|
||||||
};
|
return Segment; };
|
||||||
inline std::shared_ptr<TSegment> CurrentSegment()
|
inline TTrack * CurrentNext() {
|
||||||
{
|
return (trNext); };
|
||||||
return Segment;
|
inline TTrack * CurrentPrev() {
|
||||||
};
|
return (trPrev); };
|
||||||
inline TTrack * CurrentNext()
|
|
||||||
{
|
|
||||||
return (trNext);
|
|
||||||
};
|
|
||||||
inline TTrack * CurrentPrev()
|
|
||||||
{
|
|
||||||
return (trPrev);
|
|
||||||
};
|
|
||||||
TTrack * Neightbour(int s, double &d);
|
TTrack * Neightbour(int s, double &d);
|
||||||
bool SetConnections(int i);
|
bool SetConnections(int i);
|
||||||
bool Switch(int i, double t = -1.0, double d = -1.0);
|
bool Switch(int i, double t = -1.0, double d = -1.0);
|
||||||
bool SwitchForced(int i, TDynamicObject *o);
|
bool SwitchForced(int i, TDynamicObject *o);
|
||||||
int CrossSegment(int from, int into);
|
int CrossSegment(int from, int into);
|
||||||
inline int GetSwitchState()
|
inline int GetSwitchState() {
|
||||||
{
|
return (
|
||||||
return (SwitchExtension ? SwitchExtension->CurrentIndex : -1);
|
SwitchExtension ?
|
||||||
};
|
SwitchExtension->CurrentIndex :
|
||||||
|
-1); };
|
||||||
void Load(cParser *parser, vector3 pOrigin, std::string name);
|
void Load(cParser *parser, vector3 pOrigin, std::string name);
|
||||||
bool AssignEvents(TEvent *NewEvent0, TEvent *NewEvent1, TEvent *NewEvent2);
|
bool AssignEvents(TEvent *NewEvent0, TEvent *NewEvent1, TEvent *NewEvent2);
|
||||||
bool AssignallEvents(TEvent *NewEvent0, TEvent *NewEvent1, TEvent *NewEvent2);
|
bool AssignallEvents(TEvent *NewEvent0, TEvent *NewEvent1, TEvent *NewEvent2);
|
||||||
@@ -233,44 +225,42 @@ class TTrack : public Resource
|
|||||||
bool CheckDynamicObject(TDynamicObject *Dynamic);
|
bool CheckDynamicObject(TDynamicObject *Dynamic);
|
||||||
bool AddDynamicObject(TDynamicObject *Dynamic);
|
bool AddDynamicObject(TDynamicObject *Dynamic);
|
||||||
bool RemoveDynamicObject(TDynamicObject *Dynamic);
|
bool RemoveDynamicObject(TDynamicObject *Dynamic);
|
||||||
void MoveMe(vector3 pPosition);
|
|
||||||
|
|
||||||
void Release();
|
void Release();
|
||||||
|
/*
|
||||||
void Compile(GLuint tex = 0);
|
void Compile(GLuint tex = 0);
|
||||||
|
|
||||||
void Render(); // renderowanie z Display Lists
|
void Render(); // renderowanie z Display Lists
|
||||||
int RaArrayPrepare(); // zliczanie rozmiaru dla VBO sektroa
|
int RaArrayPrepare(); // zliczanie rozmiaru dla VBO sektroa
|
||||||
void RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int const Vertexcount); // wypełnianie VBO
|
*/
|
||||||
|
void create_geometry(geometrybank_handle const &Bank); // wypełnianie VBO
|
||||||
|
/*
|
||||||
void RaRenderVBO(int iPtr); // renderowanie z VBO sektora
|
void RaRenderVBO(int iPtr); // renderowanie z VBO sektora
|
||||||
|
*/
|
||||||
void RenderDyn(); // renderowanie nieprzezroczystych pojazdów (oba tryby)
|
void RenderDyn(); // renderowanie nieprzezroczystych pojazdów (oba tryby)
|
||||||
void RenderDynAlpha(); // renderowanie przezroczystych pojazdów (oba tryby)
|
void RenderDynAlpha(); // renderowanie przezroczystych pojazdów (oba tryby)
|
||||||
void RenderDynSounds(); // odtwarzanie dźwięków pojazdów jest niezależne od ich
|
void RenderDynSounds(); // odtwarzanie dźwięków pojazdów jest niezależne od ich wyświetlania
|
||||||
// wyświetlania
|
|
||||||
|
|
||||||
void RaOwnerSet(TSubRect *o)
|
void RaOwnerSet(TSubRect *o) {
|
||||||
{
|
|
||||||
if (SwitchExtension)
|
if (SwitchExtension)
|
||||||
SwitchExtension->pOwner = o;
|
SwitchExtension->pOwner = o; };
|
||||||
};
|
|
||||||
bool InMovement(); // czy w trakcie animacji?
|
bool InMovement(); // czy w trakcie animacji?
|
||||||
void RaAssign(TGroundNode *gn, TAnimContainer *ac);
|
void RaAssign(TGroundNode *gn, TAnimContainer *ac);
|
||||||
void RaAssign(TGroundNode *gn, TAnimModel *am, TEvent *done, TEvent *joined);
|
void RaAssign(TGroundNode *gn, TAnimModel *am, TEvent *done, TEvent *joined);
|
||||||
void RaAnimListAdd(TTrack *t);
|
void RaAnimListAdd(TTrack *t);
|
||||||
TTrack * RaAnimate(GLuint const Vertexbuffer = -1);
|
TTrack * RaAnimate();
|
||||||
|
|
||||||
void RadioStop();
|
void RadioStop();
|
||||||
void AxleCounter(int i, TDynamicObject *o)
|
void AxleCounter(int i, TDynamicObject *o) {
|
||||||
{
|
|
||||||
if (pIsolated)
|
if (pIsolated)
|
||||||
pIsolated->Modify(i, o);
|
pIsolated->Modify(i, o); }; // dodanie lub odjęcie osi
|
||||||
}; // dodanie lub odjęcie osi
|
|
||||||
std::string IsolatedName();
|
std::string IsolatedName();
|
||||||
bool IsolatedEventsAssign(TEvent *busy, TEvent *free);
|
bool IsolatedEventsAssign(TEvent *busy, TEvent *free);
|
||||||
double WidthTotal();
|
double WidthTotal();
|
||||||
GLuint TextureGet(int i)
|
GLuint TextureGet(int i) {
|
||||||
{
|
return (
|
||||||
return i ? TextureID1 : TextureID2;
|
i ?
|
||||||
};
|
TextureID1 :
|
||||||
|
TextureID2 ); };
|
||||||
bool IsGroupable();
|
bool IsGroupable();
|
||||||
int TestPoint(vector3 *Point);
|
int TestPoint(vector3 *Point);
|
||||||
void MovedUp1(double dh);
|
void MovedUp1(double dh);
|
||||||
|
|||||||
@@ -358,7 +358,7 @@ void TTraction::ResistanceCalc(int d, double r, TTractionPowerSource *ps)
|
|||||||
}
|
}
|
||||||
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 * glm::dot(t->vParametric, t->vParametric ); // doliczenie oporu kolejnego odcinka
|
r += t->fResistivity * glm::length(t->vParametric); // doliczenie oporu kolejnego odcinka
|
||||||
p = t; // zapamiętanie dotychczasowego
|
p = t; // zapamiętanie dotychczasowego
|
||||||
t = p->hvNext[d ^ 1]; // podążanie w tę samą stronę
|
t = p->hvNext[d ^ 1]; // podążanie w tę samą stronę
|
||||||
d = p->iNext[d ^ 1];
|
d = p->iNext[d ^ 1];
|
||||||
@@ -367,8 +367,7 @@ void TTraction::ResistanceCalc(int d, double r, TTractionPowerSource *ps)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // podążanie w obu kierunkach, można by rekurencją, ale szkoda zasobów
|
{ // podążanie w obu kierunkach, można by rekurencją, ale szkoda zasobów
|
||||||
r = 0.5 * fResistivity *
|
r = 0.5 * fResistivity * glm::length(vParametric); // powiedzmy, że w zasilanym przęśle jest połowa
|
||||||
glm::dot(vParametric, vParametric ); // powiedzmy, że w zasilanym przęśle jest połowa
|
|
||||||
if (fResistance[0] == 0.0)
|
if (fResistance[0] == 0.0)
|
||||||
ResistanceCalc(0, r); // do tyłu (w stronę Point1)
|
ResistanceCalc(0, r); // do tyłu (w stronę Point1)
|
||||||
if (fResistance[1] == 0.0)
|
if (fResistance[1] == 0.0)
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class TTraction
|
|||||||
void Connect(int my, TTraction *with, int to);
|
void Connect(int my, TTraction *with, int to);
|
||||||
void Init();
|
void Init();
|
||||||
bool WhereIs();
|
bool WhereIs();
|
||||||
void ResistanceCalc(int d = -1, double r = 0, TTractionPowerSource *ps = NULL);
|
void ResistanceCalc(int d = -1, double r = 0, TTractionPowerSource *ps = nullptr);
|
||||||
void PowerSet(TTractionPowerSource *ps);
|
void PowerSet(TTractionPowerSource *ps);
|
||||||
double VoltageGet(double u, double i);
|
double VoltageGet(double u, double i);
|
||||||
private:
|
private:
|
||||||
|
|||||||
145
VBO.cpp
145
VBO.cpp
@@ -9,148 +9,3 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "VBO.h"
|
#include "VBO.h"
|
||||||
#include "GL/glew.h"
|
|
||||||
#include "usefull.h"
|
|
||||||
#include "sn_utils.h"
|
|
||||||
#include "globals.h"
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
void CVertNormTex::deserialize(std::istream &s)
|
|
||||||
{
|
|
||||||
x = sn_utils::ld_float32(s);
|
|
||||||
y = sn_utils::ld_float32(s);
|
|
||||||
z = sn_utils::ld_float32(s);
|
|
||||||
|
|
||||||
nx = sn_utils::ld_float32(s);
|
|
||||||
ny = sn_utils::ld_float32(s);
|
|
||||||
nz = sn_utils::ld_float32(s);
|
|
||||||
|
|
||||||
u = sn_utils::ld_float32(s);
|
|
||||||
v = sn_utils::ld_float32(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CVertNormTex::serialize(std::ostream &s)
|
|
||||||
{
|
|
||||||
sn_utils::ls_float32(s, x);
|
|
||||||
sn_utils::ls_float32(s, y);
|
|
||||||
sn_utils::ls_float32(s, z);
|
|
||||||
|
|
||||||
sn_utils::ls_float32(s, nx);
|
|
||||||
sn_utils::ls_float32(s, ny);
|
|
||||||
sn_utils::ls_float32(s, nz);
|
|
||||||
|
|
||||||
sn_utils::ls_float32(s, u);
|
|
||||||
sn_utils::ls_float32(s, v);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
CMesh::CMesh()
|
|
||||||
{ // utworzenie pustego obiektu
|
|
||||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
|
||||||
m_pVNT = nullptr;
|
|
||||||
#endif
|
|
||||||
m_nVertexCount = -1;
|
|
||||||
m_nVBOVertices = 0; // nie zarezerwowane
|
|
||||||
};
|
|
||||||
|
|
||||||
CMesh::~CMesh()
|
|
||||||
{ // usuwanie obiektu
|
|
||||||
Clear(); // zwolnienie zasobów
|
|
||||||
};
|
|
||||||
|
|
||||||
void CMesh::MakeArray(int n)
|
|
||||||
{ // tworzenie tablic
|
|
||||||
m_nVertexCount = n;
|
|
||||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
|
||||||
assert( m_pVNT == nullptr );
|
|
||||||
m_pVNT = new CVertNormTex[m_nVertexCount]; // przydzielenie pamięci dla tablicy
|
|
||||||
#else
|
|
||||||
m_pVNT.clear();
|
|
||||||
m_pVNT.resize( m_nVertexCount );
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
void CMesh::BuildVBOs(bool del)
|
|
||||||
{ // tworzenie VBO i kasowanie już niepotrzebnych tablic
|
|
||||||
// pobierz numer VBO oraz ustaw go jako aktywny
|
|
||||||
glGenBuffers(1, &m_nVBOVertices); // pobierz numer
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, m_nVBOVertices); // ustaw bufor jako aktualny
|
|
||||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, m_nVertexCount * sizeof(CVertNormTex), m_pVNT, GL_STATIC_DRAW);
|
|
||||||
#else
|
|
||||||
glBufferData( GL_ARRAY_BUFFER, m_nVertexCount * sizeof( CVertNormTex ), m_pVNT.data(), GL_STATIC_DRAW );
|
|
||||||
#endif
|
|
||||||
// WriteLog("Assigned VBO number "+AnsiString(m_nVBOVertices)+", vertices:
|
|
||||||
// "+AnsiString(m_nVertexCount));
|
|
||||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
|
||||||
if (del)
|
|
||||||
SafeDeleteArray(m_pVNT); // wierzchołki już się nie przydadzą
|
|
||||||
#else
|
|
||||||
m_pVNT.clear();
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
void CMesh::Clear()
|
|
||||||
{ // niewirtualne zwolnienie zasobów przez sprzątacz albo destruktor
|
|
||||||
// inna nazwa, żeby nie mieszało się z funkcją wirtualną sprzątacza
|
|
||||||
if (m_nVBOVertices) // jeśli było coś rezerwowane
|
|
||||||
{
|
|
||||||
glDeleteBuffers(1, &m_nVBOVertices); // Free The Memory
|
|
||||||
// WriteLog("Released VBO number "+AnsiString(m_nVBOVertices));
|
|
||||||
}
|
|
||||||
m_nVBOVertices = 0;
|
|
||||||
m_nVertexCount = -1; // do ponownego zliczenia
|
|
||||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
|
||||||
SafeDeleteArray(m_pVNT); // usuwanie tablic, gdy były użyte do Vertex Array
|
|
||||||
#else
|
|
||||||
m_pVNT.clear();
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
bool CMesh::StartVBO()
|
|
||||||
{ // początek rysowania elementów z VBO
|
|
||||||
|
|
||||||
if (m_nVertexCount <= 0)
|
|
||||||
return false; // nie ma nic do rysowania w ten sposób
|
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
|
||||||
glEnableClientState(GL_NORMAL_ARRAY);
|
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
if (m_nVBOVertices)
|
|
||||||
{
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER_ARB, m_nVBOVertices);
|
|
||||||
glVertexPointer( 3, GL_FLOAT, sizeof( CVertNormTex ), static_cast<char *>( nullptr ) ); // pozycje
|
|
||||||
glNormalPointer( GL_FLOAT, sizeof( CVertNormTex ), static_cast<char *>( nullptr ) + 12 ); // normalne
|
|
||||||
glTexCoordPointer( 2, GL_FLOAT, sizeof( CVertNormTex ), static_cast<char *>( nullptr ) + 24 ); // wierzchołki
|
|
||||||
return true; // można rysować z VBO
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool CMesh::StartColorVBO()
|
|
||||||
{ // początek rysowania punktów świecących z VBO
|
|
||||||
|
|
||||||
if (m_nVertexCount <= 0)
|
|
||||||
return false; // nie ma nic do rysowania w ten sposób
|
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
|
||||||
glEnableClientState(GL_COLOR_ARRAY);
|
|
||||||
if (m_nVBOVertices)
|
|
||||||
{
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, m_nVBOVertices);
|
|
||||||
glVertexPointer( 3, GL_FLOAT, sizeof( CVertNormTex ), static_cast<char *>( nullptr ) ); // pozycje
|
|
||||||
// glColorPointer(3,GL_UNSIGNED_BYTE,sizeof(CVertNormTex),((char*)NULL)+12); //kolory
|
|
||||||
glColorPointer( 3, GL_FLOAT, sizeof( CVertNormTex ), static_cast<char *>( nullptr ) + 12 ); // kolory
|
|
||||||
return true; // można rysować z VBO
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
void CMesh::EndVBO()
|
|
||||||
{ // koniec użycia VBO
|
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
|
||||||
glDisableClientState(GL_NORMAL_ARRAY);
|
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
glDisableClientState(GL_COLOR_ARRAY);
|
|
||||||
// glBindBuffer(GL_ARRAY_BUFFER,0); //takie coś psuje, mimo iż polecali użyć
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // Ra: to na przyszłość
|
|
||||||
};
|
|
||||||
|
|||||||
43
VBO.h
43
VBO.h
@@ -11,48 +11,9 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
#include "openglgeometrybank.h"
|
#include "openglgeometrybank.h"
|
||||||
|
|
||||||
#define EU07_USE_OLD_VERTEXBUFFER
|
class CMesh
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
class CVertNormTex
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
float x = 0.0; // X wierzchołka
|
|
||||||
float y = 0.0; // Y wierzchołka
|
|
||||||
float z = 0.0; // Z wierzchołka
|
|
||||||
float nx = 0.0; // X wektora normalnego
|
|
||||||
float ny = 0.0; // Y wektora normalnego
|
|
||||||
float nz = 0.0; // Z wektora normalnego
|
|
||||||
float u = 0.0; // U mapowania
|
|
||||||
float v = 0.0; // V mapowania
|
|
||||||
|
|
||||||
void deserialize(std::istream&);
|
|
||||||
void serialize(std::ostream&);
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
typedef basic_vertex CVertNormTex;
|
|
||||||
|
|
||||||
class CMesh
|
|
||||||
{ // wsparcie dla VBO
|
|
||||||
public:
|
|
||||||
CMesh();
|
|
||||||
~CMesh();
|
|
||||||
void MakeArray(int n); // tworzenie tablicy z elementami VNT
|
|
||||||
void BuildVBOs(bool del = true); // zamiana tablic na VBO
|
|
||||||
void Clear(); // zwolnienie zasobów
|
|
||||||
bool StartVBO();
|
|
||||||
void EndVBO();
|
|
||||||
bool StartColorVBO();
|
|
||||||
|
|
||||||
int m_nVertexCount; // liczba wierzchołków
|
|
||||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
|
||||||
CVertNormTex *m_pVNT;
|
|
||||||
#else
|
|
||||||
std::vector<CVertNormTex> m_pVNT;
|
|
||||||
#endif
|
|
||||||
unsigned int m_nVBOVertices; // numer VBO z wierzchołkami
|
|
||||||
|
|
||||||
geometrybank_handle m_geometrybank;
|
geometrybank_handle m_geometrybank;
|
||||||
|
bool m_geometrycreated { false };
|
||||||
};
|
};
|
||||||
|
|||||||
40
World.cpp
40
World.cpp
@@ -1267,7 +1267,7 @@ TWorld::Render_Cab() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TDynamicObject *dynamic = Train->Dynamic();
|
TDynamicObject *dynamic = Train->Dynamic();
|
||||||
TSubModel::iInstance = reinterpret_cast<size_t>( dynamic );
|
TSubModel::iInstance = reinterpret_cast<std::size_t>( dynamic );
|
||||||
|
|
||||||
if( ( true == FreeFlyModeFlag )
|
if( ( true == FreeFlyModeFlag )
|
||||||
|| ( false == dynamic->bDisplayCab )
|
|| ( false == dynamic->bDisplayCab )
|
||||||
@@ -1275,8 +1275,6 @@ TWorld::Render_Cab() {
|
|||||||
// ABu: Rendering kabiny jako ostatniej, zeby bylo widac przez szyby, tylko w widoku ze srodka
|
// ABu: Rendering kabiny jako ostatniej, zeby bylo widac przez szyby, tylko w widoku ze srodka
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
::glEnable( GL_LIGHTING ); // po renderowaniu drutów może być to wyłączone. TODO: have the wires render take care of its own shit
|
|
||||||
/*
|
/*
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
vector3 pos = dynamic->GetPosition(); // wszpółrzędne pojazdu z kabiną
|
vector3 pos = dynamic->GetPosition(); // wszpółrzędne pojazdu z kabiną
|
||||||
@@ -1651,7 +1649,7 @@ TWorld::Update_UI() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case( GLFW_KEY_F8 ) : {
|
case( GLFW_KEY_F8 ) : {
|
||||||
|
// gfx renderer data
|
||||||
uitextline1 =
|
uitextline1 =
|
||||||
"Draw range x " + to_string( Global::fDistanceFactor, 1 )
|
"Draw range x " + to_string( Global::fDistanceFactor, 1 )
|
||||||
+ "; FPS: " + to_string( Timer::GetFPS(), 2 );
|
+ "; FPS: " + to_string( Timer::GetFPS(), 2 );
|
||||||
@@ -1659,28 +1657,16 @@ TWorld::Update_UI() {
|
|||||||
uitextline1 += " (slowmotion " + to_string( Global::iSlowMotion ) + ")";
|
uitextline1 += " (slowmotion " + to_string( Global::iSlowMotion ) + ")";
|
||||||
}
|
}
|
||||||
uitextline1 +=
|
uitextline1 +=
|
||||||
", sectors: " + to_string( Ground.iRendered )
|
", sectors: " + std::to_string( GfxRenderer.m_drawcount )
|
||||||
+ "/" + to_string( Global::iSegmentsRendered )
|
+ "/" + std::to_string( Global::iSegmentsRendered )
|
||||||
+ "; FoV: " + to_string( Global::FieldOfView / Global::ZoomFactor, 1 );
|
+ "; FoV: " + to_string( Global::FieldOfView / Global::ZoomFactor, 1 );
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case( GLFW_KEY_F9 ) : {
|
|
||||||
// informacja o wersji, sposobie wyświetlania i błędach OpenGL
|
|
||||||
uitextline1 = "MaSzyna " + Global::asVersion; // informacja o wersji
|
|
||||||
if( Global::iMultiplayer ) {
|
|
||||||
uitextline1 += " (multiplayer mode is active)";
|
|
||||||
}
|
|
||||||
|
|
||||||
uitextline2 =
|
uitextline2 =
|
||||||
std::string("Rendering mode: ")
|
std::string( "Rendering mode: " )
|
||||||
+ ( Global::bUseVBO ?
|
+ ( Global::bUseVBO ?
|
||||||
"VBO" :
|
"VBO" :
|
||||||
"Display Lists" )
|
"Display Lists" )
|
||||||
+ ". "
|
+ ". ";
|
||||||
+ GfxRenderer.Info();
|
|
||||||
|
|
||||||
// dump last opengl error, if any
|
// dump last opengl error, if any
|
||||||
GLenum glerror = ::glGetError();
|
GLenum glerror = ::glGetError();
|
||||||
if( glerror != GL_NO_ERROR ) {
|
if( glerror != GL_NO_ERROR ) {
|
||||||
@@ -1689,10 +1675,22 @@ TWorld::Update_UI() {
|
|||||||
Global::LastGLError = std::to_string( glerror ) + " (" + glerrorstring + ")";
|
Global::LastGLError = std::to_string( glerror ) + " (" + glerrorstring + ")";
|
||||||
}
|
}
|
||||||
if( false == Global::LastGLError.empty() ) {
|
if( false == Global::LastGLError.empty() ) {
|
||||||
uitextline3 =
|
uitextline2 +=
|
||||||
"Last openGL error: "
|
"Last openGL error: "
|
||||||
+ Global::LastGLError;
|
+ Global::LastGLError;
|
||||||
}
|
}
|
||||||
|
// renderer stats
|
||||||
|
uitextline3 = GfxRenderer.Info();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case( GLFW_KEY_F9 ) : {
|
||||||
|
// informacja o wersji
|
||||||
|
uitextline1 = "MaSzyna " + Global::asVersion; // informacja o wersji
|
||||||
|
if( Global::iMultiplayer ) {
|
||||||
|
uitextline1 += " (multiplayer mode is active)";
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,13 +48,13 @@ basic_vertex::deserialize( std::istream &s ) {
|
|||||||
|
|
||||||
// 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
|
||||||
geometry_handle
|
geometry_handle
|
||||||
geometry_bank::create( vertex_array &Vertices, int const Type ) {
|
geometry_bank::create( vertex_array &Vertices, unsigned int const Type, unsigned int const Streams ) {
|
||||||
|
|
||||||
if( true == Vertices.empty() ) { return geometry_handle( 0, 0 ); }
|
if( true == Vertices.empty() ) { return geometry_handle( 0, 0 ); }
|
||||||
|
|
||||||
m_chunks.emplace_back( Vertices, Type );
|
m_chunks.emplace_back( Vertices, Type, Streams );
|
||||||
// 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
|
||||||
geometry_handle chunkhandle{ 0, m_chunks.size() };
|
geometry_handle chunkhandle { 0, static_cast<std::uint32_t>(m_chunks.size()) };
|
||||||
// template method
|
// template method
|
||||||
create_( chunkhandle );
|
create_( chunkhandle );
|
||||||
// all done
|
// all done
|
||||||
|
|||||||
@@ -18,14 +18,30 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct basic_vertex {
|
struct basic_vertex {
|
||||||
|
|
||||||
glm::vec3 position; // 3d space
|
glm::vec3 position; // 3d space
|
||||||
glm::vec3 normal; // 3d space
|
glm::vec3 normal; // 3d space
|
||||||
glm::vec2 texture; // uv space
|
glm::vec2 texture; // uv space
|
||||||
|
|
||||||
|
basic_vertex() = default;
|
||||||
|
basic_vertex( glm::vec3 const&Position, glm::vec3 const &Normal, glm::vec2 const &Texture ) :
|
||||||
|
position( Position ), normal( Normal ), texture( Texture )
|
||||||
|
{}
|
||||||
void serialize( std::ostream& );
|
void serialize( std::ostream& );
|
||||||
void deserialize( std::istream& );
|
void deserialize( std::istream& );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// data streams carried in a vertex
|
||||||
|
enum stream {
|
||||||
|
position = 0x1,
|
||||||
|
normal = 0x2,
|
||||||
|
color = 0x4, // currently normal and colour streams are stored in the same slot, and mutually exclusive
|
||||||
|
texture = 0x8
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned int const basic_streams { stream::position | stream::normal | stream::texture };
|
||||||
|
unsigned int const color_streams{ stream::position | stream::color | stream::texture };
|
||||||
|
|
||||||
typedef std::vector<basic_vertex> vertex_array;
|
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
|
||||||
@@ -40,12 +56,20 @@ struct geometry_handle {
|
|||||||
{}
|
{}
|
||||||
// methods
|
// methods
|
||||||
inline
|
inline
|
||||||
operator std::uint32_t() const {
|
operator std::uint64_t() const {
|
||||||
return bank << 12 | chunk; }
|
/*
|
||||||
|
return bank << 14 | chunk; }
|
||||||
|
*/
|
||||||
|
return bank << 32 | chunk; }
|
||||||
|
|
||||||
// members
|
// members
|
||||||
|
/*
|
||||||
std::uint32_t
|
std::uint32_t
|
||||||
bank : 20, // 1 mil banks
|
bank : 18, // 250k banks
|
||||||
chunk : 12; // 4 k chunks per bank
|
chunk : 14; // 16k chunks per bank
|
||||||
|
*/
|
||||||
|
std::uint32_t bank;
|
||||||
|
std::uint32_t chunk;
|
||||||
};
|
};
|
||||||
|
|
||||||
class geometry_bank {
|
class geometry_bank {
|
||||||
@@ -62,7 +86,7 @@ public:
|
|||||||
// 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
|
||||||
geometry_handle
|
geometry_handle
|
||||||
create( vertex_array &Vertices, int const Type );
|
create( vertex_array &Vertices, unsigned int const Type, unsigned int const Streams = stream::position | stream::normal | stream::texture );
|
||||||
// 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
|
||||||
replace( vertex_array &Vertices, geometry_handle const &Geometry, std::size_t const Offset = 0 );
|
replace( vertex_array &Vertices, geometry_handle const &Geometry, std::size_t const Offset = 0 );
|
||||||
@@ -83,11 +107,12 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
// types:
|
// types:
|
||||||
struct geometry_chunk {
|
struct geometry_chunk {
|
||||||
int type; // kind of geometry used by the chunk
|
unsigned int streams; // data streams carried by vertices
|
||||||
|
unsigned 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 Type ) :
|
geometry_chunk( vertex_array &Vertices, unsigned int const Type, unsigned int const Streams ) :
|
||||||
vertices( Vertices ), type( Type )
|
vertices( Vertices ), type( Type ), streams( Streams )
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -121,9 +146,14 @@ private:
|
|||||||
class opengl_vbogeometrybank : public geometry_bank {
|
class opengl_vbogeometrybank : public geometry_bank {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// methods:
|
// destructor
|
||||||
~opengl_vbogeometrybank() {
|
~opengl_vbogeometrybank() {
|
||||||
delete_buffer(); }
|
delete_buffer(); }
|
||||||
|
// methods:
|
||||||
|
static
|
||||||
|
void
|
||||||
|
reset() {
|
||||||
|
m_activebuffer = 0; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// types:
|
// types:
|
||||||
@@ -217,6 +247,12 @@ public:
|
|||||||
// draws geometry stored in specified chunk
|
// draws geometry stored in specified chunk
|
||||||
void
|
void
|
||||||
draw( geometry_handle const &Geometry );
|
draw( geometry_handle const &Geometry );
|
||||||
|
template <typename Iterator_>
|
||||||
|
void
|
||||||
|
draw( Iterator_ First, Iterator_ Last ) {
|
||||||
|
while( First != Last ) {
|
||||||
|
draw( *First );
|
||||||
|
++First; } }
|
||||||
// provides direct access to vertex data of specfied chunk
|
// provides direct access to vertex data of specfied chunk
|
||||||
vertex_array const &
|
vertex_array const &
|
||||||
vertices( geometry_handle const &Geometry ) const;
|
vertices( geometry_handle const &Geometry ) const;
|
||||||
|
|||||||
12
parser.cpp
12
parser.cpp
@@ -30,6 +30,9 @@ cParser::cParser( std::string const &Stream, buffertype const Type, std::string
|
|||||||
// mComments.insert(commentmap::value_type("--","\n")); //Ra: to chyba nie używane
|
// mComments.insert(commentmap::value_type("--","\n")); //Ra: to chyba nie używane
|
||||||
// store to calculate sub-sequent includes from relative path
|
// store to calculate sub-sequent includes from relative path
|
||||||
mPath = Path;
|
mPath = Path;
|
||||||
|
if( Type == buffertype::buffer_FILE ) {
|
||||||
|
mFile = Stream;
|
||||||
|
}
|
||||||
// reset pointers and attach proper type of buffer
|
// reset pointers and attach proper type of buffer
|
||||||
switch (Type)
|
switch (Type)
|
||||||
{
|
{
|
||||||
@@ -263,8 +266,15 @@ std::size_t cParser::count() {
|
|||||||
return count - 1;
|
return count - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void cParser::addCommentStyle( std::string const &Commentstart, std::string const &Commentend ) {
|
void cParser::addCommentStyle( std::string const &Commentstart, std::string const &Commentend ) {
|
||||||
|
|
||||||
mComments.insert( commentmap::value_type(Commentstart, Commentend) );
|
mComments.insert( commentmap::value_type(Commentstart, Commentend) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns name of currently open file, or empty string for text type stream
|
||||||
|
std::string
|
||||||
|
cParser::Name() {
|
||||||
|
|
||||||
|
if( mIncludeParser ) { return mIncludeParser->Name(); }
|
||||||
|
else { return mPath + mFile; }
|
||||||
|
}
|
||||||
|
|||||||
4
parser.h
4
parser.h
@@ -85,19 +85,21 @@ class cParser //: public std::stringstream
|
|||||||
static std::size_t countTokens( std::string const &Stream, std::string Path = "" );
|
static std::size_t countTokens( std::string const &Stream, std::string Path = "" );
|
||||||
// add custom definition of text which should be ignored when retrieving tokens
|
// add custom definition of text which should be ignored when retrieving tokens
|
||||||
void addCommentStyle( std::string const &Commentstart, std::string const &Commentend );
|
void addCommentStyle( std::string const &Commentstart, std::string const &Commentend );
|
||||||
|
// returns name of currently open file, or empty string for text type stream
|
||||||
|
std::string Name();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// methods:
|
// methods:
|
||||||
std::string readToken(bool ToLower = true, const char *Break = "\n\r\t ;");
|
std::string readToken(bool ToLower = true, const char *Break = "\n\r\t ;");
|
||||||
std::string readQuotes( char const Quote = '\"' );
|
std::string readQuotes( char const Quote = '\"' );
|
||||||
std::string readComment( std::string const &Break = "\n\r\t ;" );
|
std::string readComment( std::string const &Break = "\n\r\t ;" );
|
||||||
// std::string trtest;
|
|
||||||
bool findQuotes( std::string &String );
|
bool findQuotes( std::string &String );
|
||||||
bool trimComments( std::string &String );
|
bool trimComments( std::string &String );
|
||||||
std::size_t count();
|
std::size_t count();
|
||||||
// members:
|
// members:
|
||||||
bool LoadTraction; // load traction?
|
bool LoadTraction; // load traction?
|
||||||
std::istream *mStream; // relevant kind of buffer is attached on creation.
|
std::istream *mStream; // relevant kind of buffer is attached on creation.
|
||||||
|
std::string mFile; // name of the open file, if any
|
||||||
std::string mPath; // path to open stream, for relative path lookups.
|
std::string mPath; // path to open stream, for relative path lookups.
|
||||||
std::streamoff mSize; // size of open stream, for progress report.
|
std::streamoff mSize; // size of open stream, for progress report.
|
||||||
typedef std::map<std::string, std::string> commentmap;
|
typedef std::map<std::string, std::string> commentmap;
|
||||||
|
|||||||
564
renderer.cpp
564
renderer.cpp
@@ -39,7 +39,8 @@ opengl_camera::visible( TDynamicObject const *Dynamic ) const {
|
|||||||
static_cast<float>( Dynamic->MoverParameters->Dim.L ),
|
static_cast<float>( Dynamic->MoverParameters->Dim.L ),
|
||||||
static_cast<float>( Dynamic->MoverParameters->Dim.H ),
|
static_cast<float>( Dynamic->MoverParameters->Dim.H ),
|
||||||
static_cast<float>( Dynamic->MoverParameters->Dim.W ) );
|
static_cast<float>( Dynamic->MoverParameters->Dim.W ) );
|
||||||
float const radius = glm::length( diagonal ) * 0.5f;
|
// we're giving vehicles some extra padding, to allow for things like shared bogeys extending past the main body
|
||||||
|
float const radius = glm::length( diagonal ) * 0.65f;
|
||||||
|
|
||||||
return ( m_frustum.sphere_inside( Dynamic->GetPosition(), radius ) > 0.0f );
|
return ( m_frustum.sphere_inside( Dynamic->GetPosition(), radius ) > 0.0f );
|
||||||
}
|
}
|
||||||
@@ -47,10 +48,7 @@ opengl_camera::visible( TDynamicObject const *Dynamic ) const {
|
|||||||
bool
|
bool
|
||||||
opengl_renderer::Init( GLFWwindow *Window ) {
|
opengl_renderer::Init( GLFWwindow *Window ) {
|
||||||
|
|
||||||
if( false == Init_caps() ) {
|
if( false == Init_caps() ) { return false; }
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_window = Window;
|
m_window = Window;
|
||||||
|
|
||||||
@@ -111,11 +109,21 @@ opengl_renderer::Init( GLFWwindow *Window ) {
|
|||||||
}
|
}
|
||||||
// preload some common textures
|
// preload some common textures
|
||||||
WriteLog( "Loading common gfx data..." );
|
WriteLog( "Loading common gfx data..." );
|
||||||
m_glaretextureid = GetTextureId( "fx\\lightglare", szTexturePath );
|
m_glaretexture = GetTextureId( "fx\\lightglare", szTexturePath );
|
||||||
m_suntextureid = GetTextureId( "fx\\sun", szTexturePath );
|
m_suntexture = GetTextureId( "fx\\sun", szTexturePath );
|
||||||
m_moontextureid = GetTextureId( "fx\\moon", szTexturePath );
|
m_moontexture = GetTextureId( "fx\\moon", szTexturePath );
|
||||||
WriteLog( "...gfx data pre-loading done" );
|
WriteLog( "...gfx data pre-loading done" );
|
||||||
|
// prepare basic geometry chunks
|
||||||
|
auto const geometrybank = m_geometry.create_bank();
|
||||||
|
float const size = 2.5f;
|
||||||
|
m_billboardgeometry = m_geometry.create_chunk(
|
||||||
|
vertex_array{
|
||||||
|
{ { -size, size, 0.0f }, glm::vec3(), { 1.0f, 1.0f } },
|
||||||
|
{ { size, size, 0.0f }, glm::vec3(), { 0.0f, 1.0f } },
|
||||||
|
{ { -size, -size, 0.0f }, glm::vec3(), { 1.0f, 0.0f } },
|
||||||
|
{ { size, -size, 0.0f }, glm::vec3(), { 0.0f, 0.0f } } },
|
||||||
|
geometrybank,
|
||||||
|
GL_TRIANGLE_STRIP );
|
||||||
// prepare debug mode objects
|
// prepare debug mode objects
|
||||||
m_quadric = gluNewQuadric();
|
m_quadric = gluNewQuadric();
|
||||||
gluQuadricNormals( m_quadric, GLU_FLAT );
|
gluQuadricNormals( m_quadric, GLU_FLAT );
|
||||||
@@ -157,6 +165,7 @@ opengl_renderer::Render() {
|
|||||||
|
|
||||||
// accumulate last 20 frames worth of render time (cap at 1000 fps to prevent calculations going awry)
|
// accumulate last 20 frames worth of render time (cap at 1000 fps to prevent calculations going awry)
|
||||||
m_drawtime = std::max( 20.0f, 0.95f * m_drawtime + std::chrono::duration_cast<std::chrono::milliseconds>( ( std::chrono::steady_clock::now() - timestart ) ).count());
|
m_drawtime = std::max( 20.0f, 0.95f * m_drawtime + std::chrono::duration_cast<std::chrono::milliseconds>( ( std::chrono::steady_clock::now() - timestart ) ).count());
|
||||||
|
m_drawcount = m_drawqueue.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
UILayer.render();
|
UILayer.render();
|
||||||
@@ -189,6 +198,10 @@ opengl_renderer::Render( world_environment *Environment ) {
|
|||||||
else { ::glDisable( GL_FOG ); }
|
else { ::glDisable( GL_FOG ); }
|
||||||
|
|
||||||
Environment->m_skydome.Render();
|
Environment->m_skydome.Render();
|
||||||
|
if( true == Global::bUseVBO ) {
|
||||||
|
// skydome uses a custom vbo which could potentially confuse the main geometry system. hardly elegant but, eh
|
||||||
|
opengl_vbogeometrybank::reset();
|
||||||
|
}
|
||||||
Environment->m_stars.render();
|
Environment->m_stars.render();
|
||||||
|
|
||||||
float const duskfactor = 1.0f - clamp( std::abs( Environment->m_sun.getAngle() ), 0.0f, 12.0f ) / 12.0f;
|
float const duskfactor = 1.0f - clamp( std::abs( Environment->m_sun.getAngle() ), 0.0f, 12.0f ) / 12.0f;
|
||||||
@@ -213,7 +226,7 @@ opengl_renderer::Render( world_environment *Environment ) {
|
|||||||
auto const &modelview = OpenGLMatrices.data( GL_MODELVIEW );
|
auto const &modelview = OpenGLMatrices.data( GL_MODELVIEW );
|
||||||
// sun
|
// sun
|
||||||
{
|
{
|
||||||
Bind( m_suntextureid );
|
Bind( m_suntexture );
|
||||||
::glColor4f( suncolor.x, suncolor.y, suncolor.z, 1.0f );
|
::glColor4f( suncolor.x, suncolor.y, suncolor.z, 1.0f );
|
||||||
auto const sunvector = Environment->m_sun.getDirection();
|
auto const sunvector = Environment->m_sun.getDirection();
|
||||||
auto const sunposition = modelview * glm::vec4( sunvector.x, sunvector.y, sunvector.z, 1.0f );
|
auto const sunposition = modelview * glm::vec4( sunvector.x, sunvector.y, sunvector.z, 1.0f );
|
||||||
@@ -234,7 +247,7 @@ opengl_renderer::Render( world_environment *Environment ) {
|
|||||||
}
|
}
|
||||||
// moon
|
// moon
|
||||||
{
|
{
|
||||||
Bind( m_moontextureid );
|
Bind( m_moontexture );
|
||||||
float3 mooncolor( 255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f );
|
float3 mooncolor( 255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f );
|
||||||
::glColor4f( mooncolor.x, mooncolor.y, mooncolor.z, static_cast<GLfloat>( 1.0 - Global::fLuminance * 0.5 ) );
|
::glColor4f( mooncolor.x, mooncolor.y, mooncolor.z, static_cast<GLfloat>( 1.0 - Global::fLuminance * 0.5 ) );
|
||||||
|
|
||||||
@@ -412,7 +425,8 @@ opengl_renderer::Render( TGround *Ground ) {
|
|||||||
Global::FieldOfView / Global::ZoomFactor
|
Global::FieldOfView / Global::ZoomFactor
|
||||||
* std::max( 1.0f, (float)Global::ScreenWidth ) / std::max( 1.0f, (float)Global::ScreenHeight ) ) );
|
* std::max( 1.0f, (float)Global::ScreenWidth ) / std::max( 1.0f, (float)Global::ScreenHeight ) ) );
|
||||||
|
|
||||||
Ground->iRendered = 0; // ilość renderowanych sektorów
|
m_drawqueue.clear();
|
||||||
|
|
||||||
Math3D::vector3 direction;
|
Math3D::vector3 direction;
|
||||||
for( k = 0; k < Global::iSegmentsRendered; ++k ) // sektory w kolejności odległości
|
for( k = 0; k < Global::iSegmentsRendered; ++k ) // sektory w kolejności odległości
|
||||||
{ // przerobione na użycie SectorOrder
|
{ // przerobione na użycie SectorOrder
|
||||||
@@ -436,37 +450,14 @@ opengl_renderer::Render( TGround *Ground ) {
|
|||||||
if( ( tmp = Ground->FastGetSubRect( i + c, j + r ) ) != nullptr ) {
|
if( ( tmp = Ground->FastGetSubRect( i + c, j + r ) ) != nullptr ) {
|
||||||
if( tmp->iNodeCount ) {
|
if( tmp->iNodeCount ) {
|
||||||
// o ile są jakieś obiekty, bo po co puste sektory przelatywać
|
// o ile są jakieś obiekty, bo po co puste sektory przelatywać
|
||||||
Ground->pRendered[ Ground->iRendered++ ] = tmp; // tworzenie listy sektorów do renderowania
|
m_drawqueue.emplace_back( tmp );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while( ( i < 0 ) || ( j < 0 ) ); // są 4 przypadki, oprócz i=j=0
|
} while( ( i < 0 ) || ( j < 0 ) ); // są 4 przypadki, oprócz i=j=0
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
// dodać renderowanie terenu z E3D - jedno VBO jest używane dla całego modelu, chyba że jest ich więcej
|
for( auto subcell : m_drawqueue ) {
|
||||||
if( Global::bUseVBO ) {
|
Render( subcell );
|
||||||
if( ( Global::pTerrainCompact != nullptr )
|
|
||||||
&& ( Global::pTerrainCompact->pModel != nullptr ) ) {
|
|
||||||
#ifdef EU07_USE_OLD_RENDERCODE
|
|
||||||
Global::pTerrainCompact->TerrainRenderVBO( TGroundRect::iFrameNumber );
|
|
||||||
#endif
|
|
||||||
// TODO: remap geometry of terrain cells to allow camera-centric rendering
|
|
||||||
::glPushMatrix();
|
|
||||||
::glTranslated( -Global::pCameraPosition.x, -Global::pCameraPosition.y, -Global::pCameraPosition.z );
|
|
||||||
TSubModel *submodel = Global::pTerrainCompact->pModel->Root;
|
|
||||||
while( submodel != nullptr ) {
|
|
||||||
if( submodel->iVisible == TGroundRect::iFrameNumber ) {
|
|
||||||
// tylko jeśli ma być widoczny w danej ramce (problem dla 0==false)
|
|
||||||
Render( submodel ); // sub kolejne (Next) się nie wyrenderują
|
|
||||||
}
|
|
||||||
submodel = submodel->NextGet();
|
|
||||||
}
|
|
||||||
::glPopMatrix();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// renderowanie nieprzezroczystych
|
|
||||||
for( i = 0; i < Ground->iRendered; ++i ) {
|
|
||||||
Render( Ground->pRendered[ i ] );
|
|
||||||
}
|
}
|
||||||
// regular render takes care of all solid geometry present in the scene, thus we can launch alpha parts render here
|
// regular render takes care of all solid geometry present in the scene, thus we can launch alpha parts render here
|
||||||
return Render_Alpha( Ground );
|
return Render_Alpha( Ground );
|
||||||
@@ -478,69 +469,23 @@ opengl_renderer::Render( TGroundRect *Groundcell ) {
|
|||||||
|
|
||||||
bool result { false }; // will be true if we do any rendering
|
bool result { false }; // will be true if we do any rendering
|
||||||
|
|
||||||
// TODO: unify render paths
|
if( Groundcell->iLastDisplay != Groundcell->iFrameNumber ) {
|
||||||
if( Global::bUseVBO ) {
|
// tylko jezeli dany kwadrat nie był jeszcze renderowany
|
||||||
|
Groundcell->LoadNodes(); // ewentualne tworzenie siatek
|
||||||
|
|
||||||
if ( Groundcell->iLastDisplay != Groundcell->iFrameNumber) {
|
if( Groundcell->nRenderRect != nullptr ) {
|
||||||
// tylko jezeli dany kwadrat nie był jeszcze renderowany
|
// nieprzezroczyste trójkąty kwadratu kilometrowego
|
||||||
Groundcell->LoadNodes(); // ewentualne tworzenie siatek
|
for( TGroundNode *node = Groundcell->nRenderRect; node != nullptr; node = node->nNext3 ) {
|
||||||
|
Render( node );
|
||||||
if( ( Groundcell->nRenderRect != nullptr )
|
|
||||||
&& ( true == Groundcell->StartVBO() ) ) {
|
|
||||||
// nieprzezroczyste trójkąty kwadratu kilometrowego
|
|
||||||
for( TGroundNode *node = Groundcell->nRenderRect; node; node = node->nNext3 ) {
|
|
||||||
Render( node );
|
|
||||||
}
|
|
||||||
Groundcell->EndVBO();
|
|
||||||
}
|
}
|
||||||
if( Groundcell->nTerrain ) {
|
|
||||||
|
|
||||||
Render( Groundcell->nTerrain );
|
|
||||||
}
|
|
||||||
Groundcell->iLastDisplay = Groundcell->iFrameNumber; // drugi raz nie potrzeba
|
|
||||||
result = true;
|
|
||||||
}
|
}
|
||||||
|
if( Groundcell->nTerrain ) {
|
||||||
|
|
||||||
|
Render( Groundcell->nTerrain );
|
||||||
|
}
|
||||||
|
Groundcell->iLastDisplay = Groundcell->iFrameNumber; // drugi raz nie potrzeba
|
||||||
|
result = true;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// display list render path
|
|
||||||
::glPushMatrix();
|
|
||||||
auto const &cellorigin = Groundcell->m_area.center;
|
|
||||||
// TODO: unify all math objects
|
|
||||||
auto const originoffset = Math3D::vector3( cellorigin.x, cellorigin.y, cellorigin.z ) - Global::pCameraPosition;
|
|
||||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
|
||||||
|
|
||||||
if (Groundcell->iLastDisplay != Groundcell->iFrameNumber)
|
|
||||||
{ // tylko jezeli dany kwadrat nie był jeszcze renderowany
|
|
||||||
// for (TGroundNode* node=pRender;node;node=node->pNext3)
|
|
||||||
// node->Render(); //nieprzezroczyste trójkąty kwadratu kilometrowego
|
|
||||||
if ( Groundcell->nRender)
|
|
||||||
{ //łączenie trójkątów w jedną listę - trochę wioska
|
|
||||||
if (!Groundcell->nRender->DisplayListID || ( Groundcell->nRender->iVersion != Global::iReCompile))
|
|
||||||
{ // jeżeli nie skompilowany, kompilujemy wszystkie trójkąty w jeden
|
|
||||||
Groundcell->nRender->fSquareRadius = 5000.0 * 5000.0; // aby agregat nigdy nie znikał
|
|
||||||
Groundcell->nRender->DisplayListID = glGenLists(1);
|
|
||||||
glNewList( Groundcell->nRender->DisplayListID, GL_COMPILE);
|
|
||||||
Groundcell->nRender->iVersion = Global::iReCompile; // aktualna wersja siatek
|
|
||||||
auto const origin = glm::dvec3( Groundcell->m_area.center );
|
|
||||||
for (TGroundNode *node = Groundcell->nRender; node; node = node->nNext3) // następny tej grupy
|
|
||||||
node->Compile(origin, true);
|
|
||||||
glEndList();
|
|
||||||
}
|
|
||||||
Render( Groundcell->nRender ); // nieprzezroczyste trójkąty kwadratu kilometrowego
|
|
||||||
}
|
|
||||||
// submodels geometry is world-centric, so at least for the time being we need to pop the stack early
|
|
||||||
::glPopMatrix();
|
|
||||||
|
|
||||||
if( Groundcell->nTerrain ) { Render( Groundcell->nTerrain ); }
|
|
||||||
|
|
||||||
Groundcell->iLastDisplay = Groundcell->iFrameNumber; // drugi raz nie potrzeba
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
::glPopMatrix();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -551,32 +496,21 @@ opengl_renderer::Render( TSubRect *Groundsubcell ) {
|
|||||||
|
|
||||||
TGroundNode *node;
|
TGroundNode *node;
|
||||||
// nieprzezroczyste obiekty terenu
|
// nieprzezroczyste obiekty terenu
|
||||||
if( Global::bUseVBO ) {
|
for( node = Groundsubcell->nRenderRect; node != nullptr; node = node->nNext3 ) {
|
||||||
// vbo render path
|
Render( node );
|
||||||
if( Groundsubcell->StartVBO() ) {
|
|
||||||
for( node = Groundsubcell->nRenderRect; node; node = node->nNext3 ) {
|
|
||||||
if( node->iVboPtr >= 0 ) {
|
|
||||||
Render( node );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Groundsubcell->EndVBO();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// display list render path
|
|
||||||
for( node = Groundsubcell->nRenderRect; node; node = node->nNext3 ) {
|
|
||||||
Render( node ); // nieprzezroczyste obiekty terenu
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// nieprzezroczyste obiekty (oprócz pojazdów)
|
// nieprzezroczyste obiekty (oprócz pojazdów)
|
||||||
for( node = Groundsubcell->nRender; node; node = node->nNext3 )
|
for( node = Groundsubcell->nRender; node != nullptr; node = node->nNext3 ) {
|
||||||
Render( node );
|
Render( node );
|
||||||
|
}
|
||||||
// nieprzezroczyste z mieszanych modeli
|
// nieprzezroczyste z mieszanych modeli
|
||||||
for( node = Groundsubcell->nRenderMixed; node; node = node->nNext3 )
|
for( node = Groundsubcell->nRenderMixed; node != nullptr; node = node->nNext3 ) {
|
||||||
Render( node );
|
Render( node );
|
||||||
|
}
|
||||||
// nieprzezroczyste fragmenty pojazdów na torach
|
// nieprzezroczyste fragmenty pojazdów na torach
|
||||||
for( int j = 0; j < Groundsubcell->iTracks; ++j )
|
for( int j = 0; j < Groundsubcell->iTracks; ++j ) {
|
||||||
Groundsubcell->tTracks[ j ]->RenderDyn();
|
Groundsubcell->tTracks[ j ]->RenderDyn();
|
||||||
|
}
|
||||||
#ifdef EU07_SCENERY_EDITOR
|
#ifdef EU07_SCENERY_EDITOR
|
||||||
// memcells
|
// memcells
|
||||||
if( DebugModeFlag ) {
|
if( DebugModeFlag ) {
|
||||||
@@ -590,9 +524,9 @@ opengl_renderer::Render( TSubRect *Groundsubcell ) {
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
opengl_renderer::Render( TGroundNode *Node ) {
|
opengl_renderer::Render( TGroundNode *Node ) {
|
||||||
|
/*
|
||||||
Node->SetLastUsage( Timer::GetSimulationTime() );
|
Node->SetLastUsage( Timer::GetSimulationTime() );
|
||||||
|
*/
|
||||||
switch (Node->iType)
|
switch (Node->iType)
|
||||||
{ // obiekty renderowane niezależnie od odległości
|
{ // obiekty renderowane niezależnie od odległości
|
||||||
case TP_SUBMODEL:
|
case TP_SUBMODEL:
|
||||||
@@ -611,96 +545,58 @@ opengl_renderer::Render( TGroundNode *Node ) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (Node->iType)
|
switch (Node->iType) {
|
||||||
{
|
|
||||||
case TP_TRACK: {
|
|
||||||
|
|
||||||
if( Global::bUseVBO && ( Node->iNumVerts <= 0 ) ) {
|
case TP_TRACK: {
|
||||||
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 );
|
||||||
|
// render
|
||||||
// TODO: unify the render code after generic buffers are in place
|
Render( Node->pTrack );
|
||||||
if( Global::bUseVBO ) {
|
|
||||||
// vbo render path
|
|
||||||
Node->pTrack->RaRenderVBO( Node->iVboPtr );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// display list render path
|
|
||||||
Node->pTrack->Render();
|
|
||||||
}
|
|
||||||
// post-render cleanup
|
// post-render cleanup
|
||||||
::glPopMatrix();
|
::glPopMatrix();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case TP_MODEL: {
|
case TP_MODEL: {
|
||||||
Node->Model->Render( Node->pCenter - Global::pCameraPosition );
|
Node->Model->Render( Node->pCenter - Global::pCameraPosition );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case TP_MEMCELL: {
|
|
||||||
GfxRenderer.Render( Node->MemCell );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: sprawdzic czy jest potrzebny warunek fLineThickness < 0
|
case GL_LINES: {
|
||||||
if( ( Node->iFlags & 0x10 )
|
if( ( Node->m_geometry == NULL )
|
||||||
|| ( Node->fLineThickness < 0 ) ) {
|
|| ( Node->fLineThickness > 0.0 ) ) {
|
||||||
// TODO: unify the render code after generic buffers are in place
|
|
||||||
if( false == Global::bUseVBO ) {
|
|
||||||
// additional setup for display lists
|
|
||||||
if( ( Node->DisplayListID == 0 )
|
|
||||||
|| ( Node->iVersion != Global::iReCompile ) ) { // Ra: wymuszenie rekompilacji
|
|
||||||
Node->Compile(Node->m_rootposition);
|
|
||||||
if( Global::bManageNodes )
|
|
||||||
ResourceManager::Register( Node );
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if( ( Node->iType == GL_LINES )
|
|
||||||
|| ( Node->iType == GL_LINE_STRIP )
|
|
||||||
|| ( Node->iType == GL_LINE_LOOP ) ) {
|
|
||||||
// wszelkie linie są rysowane na samym końcu
|
|
||||||
if( Node->iNumPts ) {
|
|
||||||
// setup
|
|
||||||
// w zaleznosci od koloru swiatla
|
|
||||||
::glColor4fv(
|
|
||||||
glm::value_ptr(
|
|
||||||
glm::vec4(
|
|
||||||
Node->Diffuse * glm::make_vec3( Global::DayLight.ambient ),
|
|
||||||
std::min(
|
|
||||||
1.0,
|
|
||||||
1000.0 * Node->fLineThickness / ( distancesquared + 1.0 ) ) ) ) );
|
|
||||||
|
|
||||||
GfxRenderer.Bind( 0 );
|
|
||||||
|
|
||||||
// render
|
|
||||||
// TODO: unify the render code after generic buffers are in place
|
|
||||||
if( Global::bUseVBO ) {
|
|
||||||
::glPushMatrix();
|
|
||||||
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
|
||||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
|
||||||
::glDrawArrays( Node->iType, Node->iVboPtr, Node->iNumPts );
|
|
||||||
::glPopMatrix();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
::glCallList( Node->DisplayListID );
|
|
||||||
}
|
|
||||||
// post-render cleanup
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// setup
|
||||||
|
// w zaleznosci od koloru swiatla
|
||||||
|
::glColor4fv(
|
||||||
|
glm::value_ptr(
|
||||||
|
glm::vec4(
|
||||||
|
Node->Diffuse * glm::make_vec3( Global::DayLight.ambient ),
|
||||||
|
std::min(
|
||||||
|
1.0,
|
||||||
|
1000.0 * Node->fLineThickness / ( distancesquared + 1.0 ) ) ) ) );
|
||||||
|
|
||||||
|
GfxRenderer.Bind( 0 );
|
||||||
|
|
||||||
|
::glPushMatrix();
|
||||||
|
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
||||||
|
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||||
|
|
||||||
|
// render
|
||||||
|
m_geometry.draw( Node->m_geometry );
|
||||||
|
|
||||||
|
// post-render cleanup
|
||||||
|
::glPopMatrix();
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// GL_TRIANGLE etc
|
case GL_TRIANGLES: {
|
||||||
if( ( Global::bUseVBO ?
|
if( ( Node->m_geometry == NULL )
|
||||||
Node->iVboPtr < 0 :
|
|| ( ( Node->iFlags & 0x10 ) == 0 ) ) {
|
||||||
Node->DisplayListID == 0 ) ) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// setup
|
// setup
|
||||||
@@ -708,23 +604,25 @@ opengl_renderer::Render( TGroundNode *Node ) {
|
|||||||
|
|
||||||
Bind( Node->TextureID );
|
Bind( Node->TextureID );
|
||||||
|
|
||||||
|
::glPushMatrix();
|
||||||
|
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
||||||
|
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||||
|
|
||||||
// render
|
// render
|
||||||
// TODO: unify the render code after generic buffers are in place
|
m_geometry.draw( Node->m_geometry );
|
||||||
if( Global::bUseVBO ) {
|
|
||||||
// vbo render path
|
|
||||||
::glPushMatrix();
|
|
||||||
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
|
||||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
|
||||||
::glDrawArrays( Node->iType, Node->iVboPtr, Node->iNumVerts );
|
|
||||||
::glPopMatrix();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// display list render path
|
|
||||||
::glCallList( Node->DisplayListID );
|
|
||||||
}
|
|
||||||
// post-render cleanup
|
// post-render cleanup
|
||||||
|
::glPopMatrix();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case TP_MEMCELL: {
|
||||||
|
Render( Node->MemCell );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: { break; }
|
||||||
}
|
}
|
||||||
// in theory we shouldn't ever get here but, eh
|
// in theory we shouldn't ever get here but, eh
|
||||||
return false;
|
return false;
|
||||||
@@ -946,7 +844,7 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
|||||||
::glDisableClientState( GL_NORMAL_ARRAY );
|
::glDisableClientState( GL_NORMAL_ARRAY );
|
||||||
::glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
::glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||||
::glEnableClientState( GL_COLOR_ARRAY );
|
::glEnableClientState( GL_COLOR_ARRAY );
|
||||||
::glColorPointer( 3, GL_FLOAT, sizeof( CVertNormTex ), static_cast<char *>( nullptr ) + 12 ); // kolory
|
::glColorPointer( 3, GL_FLOAT, sizeof( basic_vertex ), static_cast<char *>( nullptr ) + 12 ); // kolory
|
||||||
|
|
||||||
::glDrawArrays( GL_POINTS, Submodel->iVboPtr, Submodel->iNumVerts );
|
::glDrawArrays( GL_POINTS, Submodel->iVboPtr, Submodel->iNumVerts );
|
||||||
|
|
||||||
@@ -978,6 +876,28 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
|||||||
Render( Submodel->Next ); // dalsze rekurencyjnie
|
Render( Submodel->Next ); // dalsze rekurencyjnie
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
opengl_renderer::Render( TTrack *Track ) {
|
||||||
|
|
||||||
|
if( ( Track->TextureID1 == 0 )
|
||||||
|
&& ( Track->TextureID2 == 0 ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Track->EnvironmentSet();
|
||||||
|
|
||||||
|
if( Track->TextureID1 != 0 ) {
|
||||||
|
Bind( Track->TextureID1 );
|
||||||
|
m_geometry.draw( std::begin( Track->Geometry1 ), std::end( Track->Geometry1 ) );
|
||||||
|
}
|
||||||
|
if( Track->TextureID2 != 0 ) {
|
||||||
|
Bind( Track->TextureID2 );
|
||||||
|
m_geometry.draw( std::begin( Track->Geometry2 ), std::end( Track->Geometry2 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
Track->EnvironmentReset();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
opengl_renderer::Render( TMemCell *Memcell ) {
|
opengl_renderer::Render( TMemCell *Memcell ) {
|
||||||
|
|
||||||
@@ -999,7 +919,6 @@ opengl_renderer::Render( TMemCell *Memcell ) {
|
|||||||
bool
|
bool
|
||||||
opengl_renderer::Render_Alpha( TGround *Ground ) {
|
opengl_renderer::Render_Alpha( TGround *Ground ) {
|
||||||
|
|
||||||
// legacy version of the code:
|
|
||||||
::glEnable( GL_BLEND );
|
::glEnable( GL_BLEND );
|
||||||
::glAlphaFunc( GL_GREATER, 0.04f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f
|
::glAlphaFunc( GL_GREATER, 0.04f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f
|
||||||
::glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
|
::glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||||
@@ -1007,54 +926,30 @@ opengl_renderer::Render_Alpha( TGround *Ground ) {
|
|||||||
TGroundNode *node;
|
TGroundNode *node;
|
||||||
TSubRect *tmp;
|
TSubRect *tmp;
|
||||||
// Ra: renderowanie progresywne - zależne od FPS oraz kierunku patrzenia
|
// Ra: renderowanie progresywne - zależne od FPS oraz kierunku patrzenia
|
||||||
for( int i = Ground->iRendered - 1; i >= 0; --i ) // od najdalszych
|
for( auto subcell = std::rbegin( m_drawqueue ); subcell != std::rend( m_drawqueue ); ++subcell ) {
|
||||||
{ // przezroczyste trójkąty w oddzielnym cyklu przed modelami
|
// przezroczyste trójkąty w oddzielnym cyklu przed modelami
|
||||||
tmp = Ground->pRendered[ i ];
|
tmp = *subcell;
|
||||||
if( Global::bUseVBO ) {
|
for( node = tmp->nRenderRectAlpha; node; node = node->nNext3 ) {
|
||||||
// vbo render path
|
Render_Alpha( node );
|
||||||
if( tmp->StartVBO() ) {
|
|
||||||
for( node = tmp->nRenderRectAlpha; node; node = node->nNext3 ) {
|
|
||||||
if( node->iVboPtr >= 0 ) {
|
|
||||||
Render_Alpha( node );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tmp->EndVBO();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// display list render path
|
|
||||||
for( node = tmp->nRenderRectAlpha; node; node = node->nNext3 ) {
|
|
||||||
Render_Alpha( node );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for( int i = Ground->iRendered - 1; i >= 0; --i ) // od najdalszych
|
for( auto subcell = std::rbegin( m_drawqueue ); subcell != std::rend( m_drawqueue ); ++subcell )
|
||||||
{ // renderowanie przezroczystych modeli oraz pojazdów
|
{ // renderowanie przezroczystych modeli oraz pojazdów
|
||||||
Render_Alpha( Ground->pRendered[ i ] );
|
Render_Alpha( *subcell );
|
||||||
}
|
}
|
||||||
|
|
||||||
::glDisable( GL_LIGHTING ); // linie nie powinny świecić
|
::glDisable( GL_LIGHTING ); // linie nie powinny świecić
|
||||||
|
|
||||||
for( int i = Ground->iRendered - 1; i >= 0; --i ) // od najdalszych
|
for( auto subcell = std::rbegin( m_drawqueue ); subcell != std::rend( m_drawqueue ); ++subcell ) {
|
||||||
{ // druty na końcu, żeby się nie robiły białe plamy na tle lasu
|
// druty na końcu, żeby się nie robiły białe plamy na tle lasu
|
||||||
tmp = Ground->pRendered[ i ];
|
tmp = *subcell;
|
||||||
if( Global::bUseVBO ) {
|
for( node = tmp->nRenderWires; node; node = node->nNext3 ) {
|
||||||
// vbo render path
|
Render_Alpha( node );
|
||||||
if( tmp->StartVBO() ) {
|
|
||||||
for( node = tmp->nRenderWires; node; node = node->nNext3 ) {
|
|
||||||
Render_Alpha( node );
|
|
||||||
}
|
|
||||||
tmp->EndVBO();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// display list render path
|
|
||||||
for( node = tmp->nRenderWires; node; node = node->nNext3 ) {
|
|
||||||
Render_Alpha( node ); // druty
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::glEnable( GL_LIGHTING );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1091,9 +986,9 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
|||||||
// pozniej sprawdzamy czy jest wlaczony PROBLEND dla aktualnie renderowanego noda TRIANGLE,
|
// pozniej sprawdzamy czy jest wlaczony PROBLEND dla aktualnie renderowanego noda TRIANGLE,
|
||||||
// wlasciwie dla kazdego node'a
|
// wlasciwie dla kazdego node'a
|
||||||
// i jezeli tak to odpowiedni GL_GREATER w przeciwnym wypadku standardowy 0.04
|
// i jezeli tak to odpowiedni GL_GREATER w przeciwnym wypadku standardowy 0.04
|
||||||
|
/*
|
||||||
Node->SetLastUsage( Timer::GetSimulationTime() );
|
Node->SetLastUsage( Timer::GetSimulationTime() );
|
||||||
|
*/
|
||||||
double const distancesquared = SquareMagnitude( ( Node->pCenter - Global::pCameraPosition ) / Global::ZoomFactor );
|
double const distancesquared = SquareMagnitude( ( Node->pCenter - Global::pCameraPosition ) / Global::ZoomFactor );
|
||||||
if( ( distancesquared > ( Node->fSquareRadius * Global::fDistanceFactor ) )
|
if( ( distancesquared > ( Node->fSquareRadius * Global::fDistanceFactor ) )
|
||||||
|| ( distancesquared < ( Node->fSquareMinRadius / Global::fDistanceFactor ) ) ) {
|
|| ( distancesquared < ( Node->fSquareMinRadius / Global::fDistanceFactor ) ) ) {
|
||||||
@@ -1103,7 +998,6 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
|||||||
switch (Node->iType)
|
switch (Node->iType)
|
||||||
{
|
{
|
||||||
case TP_TRACTION: {
|
case TP_TRACTION: {
|
||||||
// TODO: unify the render code after generic buffers are in place
|
|
||||||
if( Node->bVisible ) {
|
if( Node->bVisible ) {
|
||||||
// rysuj jesli sa druty i nie zerwana
|
// rysuj jesli sa druty i nie zerwana
|
||||||
if( ( Node->hvTraction->Wires == 0 )
|
if( ( Node->hvTraction->Wires == 0 )
|
||||||
@@ -1111,11 +1005,6 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// setup
|
// setup
|
||||||
::glPushMatrix();
|
|
||||||
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
|
||||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
|
||||||
|
|
||||||
Bind( NULL );
|
|
||||||
if( !Global::bSmoothTraction ) {
|
if( !Global::bSmoothTraction ) {
|
||||||
// na liniach kiepsko wygląda - robi gradient
|
// na liniach kiepsko wygląda - robi gradient
|
||||||
::glDisable( GL_LINE_SMOOTH );
|
::glDisable( GL_LINE_SMOOTH );
|
||||||
@@ -1129,16 +1018,23 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
|||||||
auto const color { Node->hvTraction->wire_color() };
|
auto const color { Node->hvTraction->wire_color() };
|
||||||
::glColor4f( color.r, color.g, color.b, linealpha );
|
::glColor4f( color.r, color.g, color.b, linealpha );
|
||||||
|
|
||||||
|
Bind( NULL );
|
||||||
|
|
||||||
|
::glPushMatrix();
|
||||||
|
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
||||||
|
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||||
|
|
||||||
// render
|
// render
|
||||||
m_geometry.draw( Node->hvTraction->m_geometry );
|
m_geometry.draw( Node->hvTraction->m_geometry );
|
||||||
|
|
||||||
// post-render cleanup
|
// post-render cleanup
|
||||||
|
::glPopMatrix();
|
||||||
|
|
||||||
::glLineWidth( 1.0 );
|
::glLineWidth( 1.0 );
|
||||||
if( !Global::bSmoothTraction ) {
|
if( !Global::bSmoothTraction ) {
|
||||||
::glEnable( GL_LINE_SMOOTH );
|
::glEnable( GL_LINE_SMOOTH );
|
||||||
}
|
}
|
||||||
|
|
||||||
::glPopMatrix();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1149,102 +1045,75 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
|||||||
Node->Model->RenderAlpha( Node->pCenter - Global::pCameraPosition );
|
Node->Model->RenderAlpha( Node->pCenter - Global::pCameraPosition );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: sprawdzic czy jest potrzebny warunek fLineThickness < 0
|
case GL_LINES: {
|
||||||
if( ( Node->iNumVerts && ( Node->iFlags & 0x20 ) )
|
if( ( Node->m_geometry == NULL )
|
||||||
|| ( Node->iNumPts && ( Node->fLineThickness > 0 ) ) ) {
|
|| ( Node->fLineThickness < 0.0 ) ) {
|
||||||
|
return false;
|
||||||
#ifdef _PROBLEND
|
|
||||||
if( ( Node->PROBLEND ) ) // sprawdza, czy w nazwie nie ma @ //Q: 13122011 - Szociu: 27012012
|
|
||||||
{
|
|
||||||
::glDisable( GL_BLEND );
|
|
||||||
::glAlphaFunc( GL_GREATER, 0.50f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
// TODO: unify the render code after generic buffers are in place
|
|
||||||
if( false == Global::bUseVBO ) {
|
|
||||||
// additional setup for display lists
|
|
||||||
if( ( Node->DisplayListID == 0 )
|
|
||||||
|| ( Node->iVersion != Global::iReCompile ) ) { // Ra: wymuszenie rekompilacji
|
|
||||||
Node->Compile(Node->m_rootposition);
|
|
||||||
if( Global::bManageNodes )
|
|
||||||
ResourceManager::Register( Node );
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
bool result( false );
|
|
||||||
|
|
||||||
if( ( Node->iType == GL_LINES )
|
|
||||||
|| ( Node->iType == GL_LINE_STRIP )
|
|
||||||
|| ( Node->iType == GL_LINE_LOOP ) ) {
|
|
||||||
// wszelkie linie są rysowane na samym końcu
|
|
||||||
if( Node->iNumPts ) {
|
|
||||||
// setup
|
|
||||||
::glPushMatrix();
|
|
||||||
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
|
||||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
|
||||||
// w zaleznosci od koloru swiatla
|
|
||||||
::glColor4fv(
|
|
||||||
glm::value_ptr(
|
|
||||||
glm::vec4(
|
|
||||||
Node->Diffuse * glm::make_vec3( Global::DayLight.ambient ),
|
|
||||||
std::min(
|
|
||||||
1.0,
|
|
||||||
1000.0 * Node->fLineThickness / ( distancesquared + 1.0 ) ) ) ) );
|
|
||||||
|
|
||||||
GfxRenderer.Bind( 0 );
|
|
||||||
|
|
||||||
// render
|
|
||||||
// TODO: unify the render code after generic buffers are in place
|
|
||||||
if( Global::bUseVBO ) {
|
|
||||||
::glDrawArrays( Node->iType, Node->iVboPtr, Node->iNumPts );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
::glCallList( Node->DisplayListID );
|
|
||||||
}
|
|
||||||
// post-render cleanup
|
|
||||||
::glPopMatrix();
|
|
||||||
result = true;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else {
|
|
||||||
// GL_TRIANGLE etc
|
|
||||||
// setup
|
// setup
|
||||||
|
// w zaleznosci od koloru swiatla
|
||||||
|
::glColor4fv(
|
||||||
|
glm::value_ptr(
|
||||||
|
glm::vec4(
|
||||||
|
Node->Diffuse * glm::make_vec3( Global::DayLight.ambient ),
|
||||||
|
std::min(
|
||||||
|
1.0,
|
||||||
|
1000.0 * Node->fLineThickness / ( distancesquared + 1.0 ) ) ) ) );
|
||||||
|
|
||||||
|
GfxRenderer.Bind( 0 );
|
||||||
|
|
||||||
::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 );
|
||||||
|
|
||||||
|
// render
|
||||||
|
m_geometry.draw( Node->m_geometry );
|
||||||
|
|
||||||
|
// post-render cleanup
|
||||||
|
::glPopMatrix();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
case GL_TRIANGLES: {
|
||||||
|
if( ( Node->m_geometry == NULL )
|
||||||
|
|| ( ( Node->iFlags & 0x20 ) == 0 ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// setup
|
||||||
|
#ifdef _PROBLEND
|
||||||
|
if( ( Node->PROBLEND ) ) // sprawdza, czy w nazwie nie ma @ //Q: 13122011 - Szociu: 27012012
|
||||||
|
{
|
||||||
|
::glDisable( GL_BLEND );
|
||||||
|
::glAlphaFunc( GL_GREATER, 0.50f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f
|
||||||
|
};
|
||||||
|
#endif
|
||||||
::glColor3fv( glm::value_ptr( Node->Diffuse ) );
|
::glColor3fv( glm::value_ptr( Node->Diffuse ) );
|
||||||
|
|
||||||
Bind( Node->TextureID );
|
Bind( Node->TextureID );
|
||||||
|
|
||||||
|
::glPushMatrix();
|
||||||
|
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
||||||
|
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||||
|
|
||||||
// render
|
// render
|
||||||
// TODO: unify the render code after generic buffers are in place
|
m_geometry.draw( Node->m_geometry );
|
||||||
if( Global::bUseVBO ) {
|
|
||||||
// vbo render path
|
|
||||||
if( Node->iVboPtr >= 0 ) {
|
|
||||||
::glDrawArrays( Node->iType, Node->iVboPtr, Node->iNumVerts );
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// display list render path
|
|
||||||
::glCallList( Node->DisplayListID );
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
// post-render cleanup
|
// post-render cleanup
|
||||||
::glPopMatrix();
|
::glPopMatrix();
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _PROBLEND
|
#ifdef _PROBLEND
|
||||||
if( ( Node->PROBLEND ) ) // sprawdza, czy w nazwie nie ma @ //Q: 13122011 - Szociu: 27012012
|
if( ( Node->PROBLEND ) ) // sprawdza, czy w nazwie nie ma @ //Q: 13122011 - Szociu: 27012012
|
||||||
{
|
{
|
||||||
::glEnable( GL_BLEND );
|
::glEnable( GL_BLEND );
|
||||||
::glAlphaFunc( GL_GREATER, 0.04f );
|
::glAlphaFunc( GL_GREATER, 0.04f );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return result;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: { break; }
|
||||||
}
|
}
|
||||||
// in theory we shouldn't ever get here but, eh
|
// in theory we shouldn't ever get here but, eh
|
||||||
return false;
|
return false;
|
||||||
@@ -1253,10 +1122,7 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
|||||||
bool
|
bool
|
||||||
opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
|
opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
|
||||||
|
|
||||||
if( false == Dynamic->renderme ) {
|
if( false == Dynamic->renderme ) { return false; }
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// setup
|
// setup
|
||||||
TSubModel::iInstance = ( size_t )this; //żeby nie robić cudzych animacji
|
TSubModel::iInstance = ( size_t )this; //żeby nie robić cudzych animacji
|
||||||
@@ -1426,10 +1292,10 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
|||||||
glarelevel = std::max( 0.0f, glarelevel - static_cast<float>(Global::fLuminance) );
|
glarelevel = std::max( 0.0f, glarelevel - static_cast<float>(Global::fLuminance) );
|
||||||
|
|
||||||
if( glarelevel > 0.0f ) {
|
if( glarelevel > 0.0f ) {
|
||||||
|
// setup
|
||||||
::glPushAttrib( GL_ENABLE_BIT | GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT );
|
::glPushAttrib( GL_ENABLE_BIT | GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT );
|
||||||
|
|
||||||
Bind( m_glaretextureid );
|
Bind( m_glaretexture );
|
||||||
::glColor4f( Submodel->f4Diffuse[ 0 ], Submodel->f4Diffuse[ 1 ], Submodel->f4Diffuse[ 2 ], glarelevel );
|
::glColor4f( Submodel->f4Diffuse[ 0 ], Submodel->f4Diffuse[ 1 ], Submodel->f4Diffuse[ 2 ], glarelevel );
|
||||||
::glDisable( GL_LIGHTING );
|
::glDisable( GL_LIGHTING );
|
||||||
::glBlendFunc( GL_SRC_ALPHA, GL_ONE );
|
::glBlendFunc( GL_SRC_ALPHA, GL_ONE );
|
||||||
@@ -1437,15 +1303,10 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
|||||||
::glPushMatrix();
|
::glPushMatrix();
|
||||||
::glLoadIdentity(); // macierz jedynkowa
|
::glLoadIdentity(); // macierz jedynkowa
|
||||||
::glTranslatef( lightcenter.x, lightcenter.y, lightcenter.z ); // początek układu zostaje bez zmian
|
::glTranslatef( lightcenter.x, lightcenter.y, lightcenter.z ); // początek układu zostaje bez zmian
|
||||||
::glRotated( atan2( lightcenter.x, lightcenter.z ) * 180.0 / M_PI, 0.0, 1.0, 0.0 ); // jedynie obracamy w pionie o kąt
|
::glRotated( std::atan2( lightcenter.x, lightcenter.z ) * 180.0 / M_PI, 0.0, 1.0, 0.0 ); // jedynie obracamy w pionie o kąt
|
||||||
|
|
||||||
// TODO: turn the drawing instructions into a compiled call / array
|
// main draw call
|
||||||
::glBegin( GL_TRIANGLE_STRIP );
|
m_geometry.draw( m_billboardgeometry );
|
||||||
float const size = 2.5f;
|
|
||||||
::glTexCoord2f( 1.0f, 1.0f ); ::glVertex3f( -size, size, 0.0f );
|
|
||||||
::glTexCoord2f( 0.0f, 1.0f ); ::glVertex3f( size, size, 0.0f );
|
|
||||||
::glTexCoord2f( 1.0f, 0.0f ); ::glVertex3f( -size, -size, 0.0f );
|
|
||||||
::glTexCoord2f( 0.0f, 0.0f ); ::glVertex3f( size, -size, 0.0f );
|
|
||||||
/*
|
/*
|
||||||
// NOTE: we could do simply...
|
// NOTE: we could do simply...
|
||||||
vec3 vertexPosition_worldspace =
|
vec3 vertexPosition_worldspace =
|
||||||
@@ -1454,8 +1315,7 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
|||||||
+ CameraUp_worldspace * squareVertices.y * BillboardSize.y;
|
+ CameraUp_worldspace * squareVertices.y * BillboardSize.y;
|
||||||
// ...etc instead IF we had easy access to camera's forward and right vectors. TODO: check if Camera matrix is accessible
|
// ...etc instead IF we had easy access to camera's forward and right vectors. TODO: check if Camera matrix is accessible
|
||||||
*/
|
*/
|
||||||
::glEnd();
|
// post-render cleanup
|
||||||
|
|
||||||
::glPopMatrix();
|
::glPopMatrix();
|
||||||
::glPopAttrib();
|
::glPopAttrib();
|
||||||
}
|
}
|
||||||
@@ -1557,8 +1417,12 @@ 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( true == DebugModeFlag ) {
|
||||||
m_debuginfo = m_textures.info();
|
m_debuginfo = m_textures.info();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_debuginfo.clear();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// debug performance string
|
// debug performance string
|
||||||
|
|||||||
21
renderer.h
21
renderer.h
@@ -172,6 +172,7 @@ public:
|
|||||||
|
|
||||||
// members
|
// members
|
||||||
GLenum static const sunlight{ GL_LIGHT0 };
|
GLenum static const sunlight{ GL_LIGHT0 };
|
||||||
|
std::size_t m_drawcount { 0 };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// types
|
// types
|
||||||
@@ -194,6 +195,8 @@ private:
|
|||||||
Render( TSubRect *Groundsubcell );
|
Render( TSubRect *Groundsubcell );
|
||||||
bool
|
bool
|
||||||
Render( TGroundNode *Node );
|
Render( TGroundNode *Node );
|
||||||
|
void
|
||||||
|
Render( TTrack *Track );
|
||||||
void
|
void
|
||||||
Render( TMemCell *Memcell );
|
Render( TMemCell *Memcell );
|
||||||
bool
|
bool
|
||||||
@@ -212,16 +215,18 @@ private:
|
|||||||
geometrybank_manager m_geometry;
|
geometrybank_manager m_geometry;
|
||||||
texture_manager m_textures;
|
texture_manager m_textures;
|
||||||
opengl_camera m_camera;
|
opengl_camera m_camera;
|
||||||
rendermode renderpass{ rendermode::color };
|
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_handle m_glaretextureid{ -1 };
|
texture_handle m_glaretexture { -1 };
|
||||||
texture_handle m_suntextureid{ -1 };
|
texture_handle m_suntexture { -1 };
|
||||||
texture_handle m_moontextureid{ -1 };
|
texture_handle m_moontexture { -1 };
|
||||||
|
geometry_handle m_billboardgeometry { 0, 0 };
|
||||||
GLUquadricObj *m_quadric; // helper object for drawing debug mode scene elements
|
GLUquadricObj *m_quadric; // helper object for drawing debug mode scene elements
|
||||||
|
std::vector< TSubRect* > m_drawqueue; // list of subcells to be drawn in current render pass
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user