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

completed unification of render paths

This commit is contained in:
tmj-fstate
2017-06-13 18:13:49 +02:00
parent 22746bad21
commit 21680a5d30
19 changed files with 1040 additions and 1384 deletions

558
Track.cpp
View File

@@ -177,7 +177,6 @@ void TTrack::Init()
case tt_Cross: // tylko dla skrzyżowania dróg
SwitchExtension = std::make_shared<TSwitchExtension>( this, 6 ); // 6 po³¹czeñ
SwitchExtension->vPoints = nullptr; // brak tablicy punktów
SwitchExtension->iPoints = 0;
SwitchExtension->bPoints = false; // tablica punktów nie wypełniona
SwitchExtension->iRoads = 4; // domyślnie 4
break;
@@ -203,7 +202,9 @@ TTrack * TTrack::Create400m(int what, double dx)
TSubRect *r = Global::pGround->GetSubRect(tmp->pCenter.x, tmp->pCenter.z);
r->NodeAdd(tmp); // dodanie toru do segmentu
r->Sort(); //żeby wyświetlał tabor z dodanego toru
/*
r->Release(); // usunięcie skompilowanych zasobów
*/
return trk;
};
@@ -313,7 +314,9 @@ TTrack * TTrack::NullCreate(int dir)
if (tmp2)
r->NodeAdd(tmp2); // drugiego też
r->Sort(); //żeby wyświetlał tabor z dodanego toru
/*
r->Release(); // usunięcie skompilowanych zasobów
*/
return trk;
};
@@ -989,22 +992,6 @@ bool TTrack::AddDynamicObject(TDynamicObject *Dynamic)
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 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,
0.000) // 1mm więcej, żeby nie nachodziły tekstury?
};
/*
void TTrack::Compile(GLuint tex)
{
CVertNormTex *immediate{ nullptr };
basic_vertex *immediate{ nullptr };
// generowanie treści dla Display Lists - model proceduralny
if (!tex)
@@ -1656,14 +1643,16 @@ void TTrack::Compile(GLuint tex)
if (Global::bManageNodes)
glEndList();
};
*/
void TTrack::Release()
{
/*
if (DisplayListID)
glDeleteLists(DisplayListID, 1);
DisplayListID = 0;
*/
};
/*
void TTrack::Render()
{
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
}
};
*/
bool TTrack::CheckDynamicObject(TDynamicObject *Dynamic)
{ // sprawdzenie, czy pojazd jest przypisany do toru
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
}
};
/*
int TTrack::RaArrayPrepare()
{ // przygotowanie tablic do skopiowania do VBO (zliczanie wierzchołków)
if (bVisible) // o ile w ogóle widać
@@ -1803,16 +1792,6 @@ int TTrack::RaArrayPrepare()
+ SwitchExtension->Segments[ 4 ]->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
return ( ( TextureID1 ? SwitchExtension->iPoints + SwitchExtension->iRoads + 2 : 0 ) + ( TextureID2 ? SwitchExtension->iPoints * 6 : 0 ) );
}
@@ -1829,28 +1808,28 @@ int TTrack::RaArrayPrepare()
}
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
double fHTW = 0.5 * fabs(fTrackWidth);
double side = fabs(fTexWidth); // szerokść podsypki na zewnątrz szyny albo pobocza
double slop = fabs(fTexSlope); // brzeg zewnętrzny
double rozp = fHTW + side + slop; // brzeg zewnętrzny
double hypot1 = hypot(slop, fTexHeight1); // rozmiar pochylenia do liczenia normalnych
double const fHTW = 0.5 * std::fabs(fTrackWidth);
double const side = std::fabs(fTexWidth); // szerokść podsypki na zewnątrz szyny albo pobocza
double const slop = std::fabs(fTexSlope); // brzeg zewnętrzny
double const rozp = fHTW + side + slop; // brzeg zewnętrzny
double hypot1 = std::hypot(slop, fTexHeight1); // rozmiar pochylenia do liczenia normalnych
if (hypot1 == 0.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;
vector3 normal2;
if (iTrapezoid & 2) // ten bit oznacza, że istnieje odpowiednie pNext
{ // Ra: jest OK
fHTW2 = 0.5 * fabs(trNext->fTrackWidth); // połowa rozstawu/nawierzchni
side2 = fabs(trNext->fTexWidth);
slop2 = fabs(trNext->fTexSlope); // nie jest używane później
fHTW2 = 0.5 * std::fabs(trNext->fTrackWidth); // połowa rozstawu/nawierzchni
side2 = std::fabs(trNext->fTexWidth);
slop2 = std::fabs(trNext->fTexSlope); // nie jest używane później
rozp2 = fHTW2 + side2 + slop2;
fTexHeight2 = trNext->fTexHeight1;
hypot2 = hypot(slop2, fTexHeight2);
hypot2 = std::hypot(slop2, fTexHeight2);
if (hypot2 == 0.0)
hypot2 = 1.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);
else
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?
vector6 rpts1[24], rpts2[24], rpts3[24], rpts4[24];
int i;
for (i = 0; i < 12; ++i)
{
rpts1[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);
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);
rpts1[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);
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
for (i = 0; i < 12; ++i)
{
rpts1[12 + 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);
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);
rpts1[12 + 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);
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
{
case tt_Table: // obrotnica jak zwykły tor, tylko animacja dochodzi
SwitchExtension->iLeftVBO = Vert - Start; // indeks toru obrotnicy
case tt_Normal:
if (TextureID2)
{ // 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
}
}
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)
{ // szyny - generujemy dwie, najwyżej rysować się będzie jedną
Segment->RenderLoft(Vert, origin, rpts1, iTrapezoid ? -nnumPts : nnumPts, fTexLength);
Segment->RenderLoft(Vert, origin, rpts2, iTrapezoid ? -nnumPts : nnumPts, fTexLength);
vertex_array vertices;
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;
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)
{
rpts3[i] =
vector6(+(fHTW + iglica[i].x) * cos1 + iglica[i].y * sin1,
-(+fHTW + iglica[i].x) * sin1 + iglica[i].y * cos1, iglica[i].z);
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);
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);
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);
vector6(
(-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)
{ // nowa wersja z SPKS, ale odwrotnie lewa/prawa
vertex_array vertices;
if( TextureID1 ) {
SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, origin, rpts2, nnumPts, fTexLength );
SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, origin, rpts1, nnumPts, fTexLength, 1.0, 2 );
SwitchExtension->iLeftVBO = Vert - Start; // indeks lewej iglicy
SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, origin, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, SwitchExtension->fOffset2 );
// fixed parts
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, origin, rpts2, nnumPts, fTexLength );
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear();
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 ) {
SwitchExtension->iRightVBO = Vert - Start; // indeks prawej iglicy
SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, origin, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -fMaxOffset + SwitchExtension->fOffset1 );
SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, origin, rpts2, nnumPts, fTexLength, 1.0, 2 );
SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, origin, rpts1, nnumPts, fTexLength );
// fixed parts
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, origin, rpts1, nnumPts, fTexLength );
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
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
{ // lewa działa lepiej niż prawa
vertex_array vertices;
if( TextureID1 ) {
SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, origin, rpts1, nnumPts, fTexLength ); // lewa szyna normalna cała
SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, origin, rpts2, nnumPts, fTexLength, 1.0, 2 ); // prawa szyna za iglicą
SwitchExtension->iLeftVBO = Vert - Start; // indeks lewej iglicy
SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, origin, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -SwitchExtension->fOffset2 ); // prawa iglica
// fixed parts
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, origin, rpts1, nnumPts, fTexLength ); // lewa szyna normalna cała
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
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 ) {
SwitchExtension->iRightVBO = Vert - Start; // indeks prawej iglicy
SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, origin, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, fMaxOffset - SwitchExtension->fOffset1 ); // lewa iglica
SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, origin, rpts1, nnumPts, fTexLength, 1.0, 2 ); // lewa szyna za iglicą
SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, origin, rpts2, nnumPts, fTexLength ); // prawa szyna normalnie cała
// fixed parts
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, origin, rpts2, nnumPts, fTexLength ); // prawa szyna normalnie cała
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
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
{ // 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)
{ // 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
}
}
vertex_array vertices;
if( iTrapezoid ) // trapez albo przechyłki
{ // pobocza do trapezowatej nawierzchni - dodatkowe punkty z drugiej strony
// odcinka
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 ) ) {
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
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 ) ) {
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
// 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ć)
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)
{ // 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
SwitchExtension->vPoints = new vector3[SwitchExtension->iPoints + SwitchExtension->iRoads];
SwitchExtension->vPoints = new vector3[pointcount + SwitchExtension->iRoads];
}
vector3 *b =
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
// if (iTrapezoid) //trapez albo przechyłki
vertex_array vertices;
if (SwitchExtension->iRoads == 4)
{ // pobocza do trapezowatej nawierzchni - dodatkowe punkty z drugiej strony odcinka
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[ 3 ]->RenderLoft( Vert, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render );
SwitchExtension->Segments[ 4 ]->RenderLoft( Vert, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render );
SwitchExtension->Segments[ 5 ]->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 );
if( true == render ) {
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
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 {
// 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 ) ) {
SwitchExtension->Segments[ 2 ]->RenderLoft( Vert, 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)
SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render ); // z P1 do P2
SwitchExtension->Segments[ 2 ]->RenderLoft( vertices, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render ); // z P2 do P4
if( true == render ) {
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
}
if (TextureID1) {
if( TextureID1 ) {
vertex_array vertices;
// jeśli podana tekstura nawierzchni
// we start with a vertex in the middle...
Vert->normal.x = 0.0;
Vert->normal.y = 1.0;
Vert->normal.z = 0.0;
Vert->texture.s = 0.5;
Vert->texture.t = 0.5;
Vert->position.x = oxz.x - origin.x;
Vert->position.y = oxz.y - origin.y;
Vert->position.z = oxz.z - origin.z;
++Vert;
vertices.emplace_back(
glm::vec3{
oxz.x - origin.x,
oxz.y - origin.y,
oxz.z - origin.z },
glm::vec3{ 0.0f, 1.0f, 0.0f },
glm::vec2{ 0.5f, 0.5f } );
// ...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;
v = ( SwitchExtension->vPoints[ 0 ].z - oxz.z + origin.z ) / ( fTexRatio1 * fTexLength );
Vert->texture.s = cosa0 * u + sina0 * v + 0.5;
Vert->texture.t = -sina0 * u + cosa0 * v + 0.5;
Vert->position.x = SwitchExtension->vPoints[ 0 ].x;
Vert->position.y = SwitchExtension->vPoints[ 0 ].y;
Vert->position.z = SwitchExtension->vPoints[ 0 ].z;
++Vert;
// ...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;
vertices.emplace_back(
glm::vec3 {
SwitchExtension->vPoints[ 0 ].x,
SwitchExtension->vPoints[ 0 ].y,
SwitchExtension->vPoints[ 0 ].z },
glm::vec3{ 0.0f, 1.0f, 0.0f },
// mapowanie we współrzędnych scenerii
u = (SwitchExtension->vPoints[i].x - oxz.x + origin.x ) / fTexLength;
v = (SwitchExtension->vPoints[i].z - oxz.z + origin.z ) / (fTexRatio1 * fTexLength);
Vert->texture.s = cosa0 * u + sina0 * v + 0.5;
Vert->texture.t = -sina0 * u + cosa0 * v + 0.5;
Vert->position.x = SwitchExtension->vPoints[ i ].x;
Vert->position.y = SwitchExtension->vPoints[ i ].y;
Vert->position.z = SwitchExtension->vPoints[ i ].z;
++Vert;
glm::vec2{
cosa0 * u + sina0 * v + 0.5,
-sina0 * u + cosa0 * v + 0.5 } );
// ...then draw the precalculated rest
for (int i = pointcount + SwitchExtension->iRoads - 1; i >= 0; --i) {
// mapowanie we współrzędnych scenerii
u = ( SwitchExtension->vPoints[ i ].x - oxz.x + origin.x ) / fTexLength;
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;
} // 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
{ // 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)
{ // 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?)
vertex_array vertices;
vector6 rpts1[6],
rpts2[6]; // współrzędne przekroju i mapowania dla prawej i lewej strony
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[4] = vector6(bpts1[3].x - side2, bpts1[3].y, 0.5);
rpts2[5] = vector6(-rozp2, -fTexHeight2, 0.0); // prawy brzeg prawego pobocza
Segment->RenderLoft(Vert, origin, rpts1, -3, fTexLength);
Segment->RenderLoft(Vert, origin, rpts2, -3, fTexLength);
Segment->RenderLoft(vertices, origin, rpts1, -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
{ // pobocza zwykłe, brak przechyłki
Segment->RenderLoft(Vert, origin, rpts1, 3, fTexLength);
Segment->RenderLoft(Vert, origin, rpts2, 3, fTexLength);
Segment->RenderLoft(vertices, origin, rpts1, 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;
};
/*
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
// dla kolejnych tekstur!
// Ra 2014-07: trzeba wymienić GL_TRIANGLE_STRIP na GL_TRIANGLES i renderować trójkąty sektora dla kolejnych tekstur!
EnvironmentSet();
int seg;
switch( iCategoryFlag & 15 ) {
@@ -2568,7 +2678,7 @@ void TTrack::RaRenderVBO( int iPtr ) { // renderowanie z użyciem VBO
}
EnvironmentReset();
};
*/
void TTrack::EnvironmentSet()
{ // ustawienie zmienionego światła
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
// zwraca wskaźnik toru wymagającego dalszej animacji
if( SwitchExtension->pNextAnim )
SwitchExtension->pNextAnim = SwitchExtension->pNextAnim->RaAnimate( Vertexbuffer );
SwitchExtension->pNextAnim = SwitchExtension->pNextAnim->RaAnimate();
bool m = true; // animacja trwa
if (eType == tt_Switch) // dla zwrotnicy tylko szyny
{
@@ -2855,77 +2965,85 @@ TTrack * TTrack::RaAnimate(GLuint const Vertexbuffer)
m = false; // koniec animacji
}
}
if( ( Global::bUseVBO )
&& ( Vertexbuffer != -1 ) )
{ // dla OpenGL 1.4 odświeży się cały sektor, w późniejszych poprawiamy fragment
if (GLEW_VERSION_1_5) // dla OpenGL 1.4 to się nie wykona poprawnie
if (TextureID1) // Ra: !!!! tu jest do poprawienia
{ // iglice liczone tylko dla zwrotnic
vector6 rpts3[24], rpts4[24];
double fHTW = 0.5 * fabs(fTrackWidth);
double fHTW2 = fHTW; // Ra: na razie niech tak będzie
double cos1 = 1.0, sin1 = 0.0, cos2 = 1.0, sin2 = 0.0; // Ra: ...
for( int i = 0; i < 12; ++i ) {
// skip the geometry update if no geometry for this track was generated yet
if( ( ( TextureID1 != 0 )
|| ( TextureID2 != 0 ) )
&& ( ( false == Geometry1.empty() )
|| ( false == Geometry2.empty() ) ) ) {
// iglice liczone tylko dla zwrotnic
double fHTW = 0.5 * fabs( fTrackWidth );
double fHTW2 = fHTW; // Ra: na razie niech tak będzie
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)
{
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 ] =
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 );
}
// 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
auto const origin { pMyNode->m_rootposition };
vertex_array vertices;
// fetch current blade geometry
std::vector<CVertNormTex> bladesbuffer; bladesbuffer.resize( 2 * 2 * 24 ); // 2 blades, 2 segments each
/*
::glGetBufferSubData(
GL_ARRAY_BUFFER,
SwitchExtension->iLeftVBO * sizeof( CVertNormTex ),
bladesbuffer.size() * sizeof( CVertNormTex ),
bladesbuffer.data() );
*/
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 (SwitchExtension->RightSwitch)
{ // nowa wersja z SPKS, ale odwrotnie lewa/prawa
vertex_array vertices;
if( TextureID1 ) {
// left blade
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, origin, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, SwitchExtension->fOffset2 );
GfxRenderer.Replace( vertices, Geometry1[ 2 ] );
vertices.clear();
}
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 &&
SwitchExtension->CurrentIndex) // 0=zablokowana się nie animuje
{ // trzeba każdorazowo porównywać z kątem modelu
// SwitchExtension->fOffset1=SwitchExtension->pAnim?SwitchExtension->pAnim->AngleGet():0.0;
// //pobranie kąta z modelu
TAnimContainer *ac = SwitchExtension->pModel ?
SwitchExtension->pModel->GetContainer(NULL) :
NULL; // pobranie głównego submodelu
// if (ac) ac->EventAssign(SwitchExtension->evMinus); //event zakończenia animacji,
// trochę bez sensu tutaj
if (ac)
if ((ac->AngleGet() != SwitchExtension->fOffset) ||
!(ac->TransGet() ==
@@ -2947,22 +3065,26 @@ TTrack * TTrack::RaAnimate(GLuint const Vertexbuffer)
dynamic->Move( 0.000001 );
}
// kąty
/*
if (Global::bUseVBO)
{ // dla OpenGL 1.4 odświeży się cały sektor, w późniejszych poprawiamy fragment
// aktualizacja pojazdów na torze
if (GLEW_VERSION_1_5) // dla OpenGL 1.4 to się nie wykona poprawnie
{
int size = RaArrayPrepare(); // wielkość tabeli potrzebna dla tej obrotnicy
CVertNormTex *Vert = new CVertNormTex[size]; // bufor roboczy
// CVertNormTex *v=Vert; //zmieniane przez
basic_vertex *Vert = new basic_vertex[size]; // bufor roboczy
// basic_vertex *v=Vert; //zmieniane przez
RaArrayFill(Vert, Vert - SwitchExtension->iLeftVBO, size); // iLeftVBO powinno zostać niezmienione
::glBufferSubData(
GL_ARRAY_BUFFER, SwitchExtension->iLeftVBO * sizeof(CVertNormTex),
size * sizeof(CVertNormTex), Vert); // wysłanie fragmentu bufora VBO
GL_ARRAY_BUFFER, SwitchExtension->iLeftVBO * sizeof(basic_vertex),
size * sizeof(basic_vertex), Vert); // wysłanie fragmentu bufora VBO
}
}
else // gdy Display List
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
}
else