mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
build 170511. crossroad generation for vbo render path. partial unification of generation and render functions for tracks and ground nodes
This commit is contained in:
@@ -230,9 +230,7 @@ bool TSpeedPos::Update(vector3 *p, vector3 *dir, double &len)
|
||||
if( fDist < 50.0 ) {
|
||||
// old sceneries use trick of placing 'helper' semaphores underground, which can lead to vehicles running over them instead of stopping in front of them
|
||||
// to account for it at short distances we redo distance calculation on 2d plane
|
||||
fDist = glm::dot(
|
||||
glm::vec3( v.x, 0.0, v.z ),
|
||||
glm::vec3( dir->x, 0.0, dir->z ) );
|
||||
fDist = glm::length( glm::vec3( v.x, 0.0, v.z ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
205
Ground.cpp
205
Ground.cpp
@@ -290,16 +290,13 @@ void TGroundNode::RaRenderVBO()
|
||||
glDrawArrays(iType, iVboPtr, iNumVerts); // Narysuj naraz wszystkie trójkąty
|
||||
}
|
||||
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
void TGroundNode::RenderVBO() { // renderowanie obiektu z VBO - faza nieprzezroczystych
|
||||
|
||||
switch( iType ) { // obiekty renderowane niezależnie od odległości
|
||||
case TP_SUBMODEL:
|
||||
TSubModel::fSquareDist = 0;
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
return smTerrain->RenderDL();
|
||||
#else
|
||||
GfxRenderer.Render( smTerrain );
|
||||
#endif
|
||||
}
|
||||
|
||||
double distancesquared = SquareMagnitude( pCenter - Global::pCameraPosition ) / Global::ZoomFactor;
|
||||
@@ -334,15 +331,9 @@ void TGroundNode::RenderVBO() { // renderowanie obiektu z VBO - faza nieprzezroc
|
||||
if( linealpha > 255 )
|
||||
linealpha = 255;
|
||||
float r, g, b;
|
||||
#ifdef EU07_USE_OLD_LIGHTING_MODEL
|
||||
r = floor( Diffuse[ 0 ] * Global::ambientDayLight[ 0 ] ); // w zaleznosci od koloru swiatla
|
||||
g = floor( Diffuse[ 1 ] * Global::ambientDayLight[ 1 ] );
|
||||
b = floor( Diffuse[ 2 ] * Global::ambientDayLight[ 2 ] );
|
||||
#else
|
||||
r = floor( Diffuse[ 0 ] * Global::DayLight.ambient[ 0 ] ); // w zaleznosci od koloru swiatla
|
||||
g = floor( Diffuse[ 1 ] * Global::DayLight.ambient[ 1 ] );
|
||||
b = floor( Diffuse[ 2 ] * Global::DayLight.ambient[ 2 ] );
|
||||
#endif
|
||||
glColor4ub( r, g, b, linealpha ); // przezroczystosc dalekiej linii
|
||||
GfxRenderer.Bind( 0 );
|
||||
|
||||
@@ -436,6 +427,8 @@ void TGroundNode::RenderAlphaVBO()
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void TGroundNode::Compile(bool many)
|
||||
{ // tworzenie skompilowanej listy w wyświetlaniu DL
|
||||
if (!many)
|
||||
@@ -451,49 +444,28 @@ void TGroundNode::Compile(bool many)
|
||||
}
|
||||
if ((iType == GL_LINES) || (iType == GL_LINE_STRIP) || (iType == GL_LINE_LOOP))
|
||||
{
|
||||
#ifdef USE_VERTEX_ARRAYS
|
||||
glVertexPointer(3, GL_DOUBLE, sizeof(vector3), &Points[0].x);
|
||||
glDrawArrays(iType, 0, iNumPts);
|
||||
#else
|
||||
glBegin(iType);
|
||||
for (int i = 0; i < iNumPts; i++)
|
||||
glVertex3dv(&Points[i].x);
|
||||
glEnd();
|
||||
#endif
|
||||
}
|
||||
else if (iType == GL_TRIANGLE_STRIP || iType == GL_TRIANGLE_FAN || iType == GL_TRIANGLES)
|
||||
{ // jak nie linie, to trójkąty
|
||||
TGroundNode *tri = this;
|
||||
do
|
||||
{ // pętla po obiektach w grupie w celu połączenia siatek
|
||||
#ifdef USE_VERTEX_ARRAYS
|
||||
glVertexPointer(3, GL_DOUBLE, sizeof(TGroundVertex), &tri->Vertices[0].Point.x);
|
||||
glNormalPointer(GL_DOUBLE, sizeof(TGroundVertex), &tri->Vertices[0].Normal.x);
|
||||
glTexCoordPointer(2, GL_FLOAT, sizeof(TGroundVertex), &tri->Vertices[0].tu);
|
||||
#endif
|
||||
// TODO: eliminate these calls, they're duplicated by setup part in the unified render function
|
||||
glColor3ub(tri->Diffuse[0], tri->Diffuse[1], tri->Diffuse[2]);
|
||||
GfxRenderer.Bind(Global::bWireFrame ? 0 : tri->TextureID);
|
||||
#ifdef USE_VERTEX_ARRAYS
|
||||
glDrawArrays(Global::bWireFrame ? GL_LINE_LOOP : tri->iType, 0, tri->iNumVerts);
|
||||
#else
|
||||
|
||||
glBegin(Global::bWireFrame ? GL_LINE_LOOP : tri->iType);
|
||||
for (int i = 0; i < tri->iNumVerts; i++)
|
||||
{
|
||||
glNormal3d(tri->Vertices[i].Normal.x, tri->Vertices[i].Normal.y,
|
||||
tri->Vertices[i].Normal.z);
|
||||
glNormal3dv(&tri->Vertices[i].Normal.x);
|
||||
glTexCoord2f(tri->Vertices[i].tu, tri->Vertices[i].tv);
|
||||
glVertex3dv(&tri->Vertices[i].Point.x);
|
||||
};
|
||||
glEnd();
|
||||
#endif
|
||||
/*
|
||||
if (tri->pTriGroup) //jeśli z grupy
|
||||
{tri=tri->pNext2; //następny w sektorze
|
||||
while (tri?!tri->pTriGroup:false) tri=tri->pNext2; //szukamy kolejnego należącego do
|
||||
grupy
|
||||
}
|
||||
else
|
||||
*/
|
||||
tri = NULL; // a jak nie, to koniec
|
||||
} while (tri);
|
||||
}
|
||||
@@ -552,17 +524,14 @@ void TGroundNode::RenderHidden()
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
void TGroundNode::RenderDL()
|
||||
{ // wyświetlanie obiektu przez Display List
|
||||
switch (iType)
|
||||
{ // obiekty renderowane niezależnie od odległości
|
||||
case TP_SUBMODEL:
|
||||
TSubModel::fSquareDist = 0;
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
return smTerrain->RenderDL();
|
||||
#else
|
||||
GfxRenderer.Render( smTerrain );
|
||||
#endif
|
||||
}
|
||||
|
||||
double distancesquared = SquareMagnitude(pCenter - Global::pCameraPosition) / Global::ZoomFactor;
|
||||
@@ -605,15 +574,9 @@ void TGroundNode::RenderDL()
|
||||
if( linealpha > 255 )
|
||||
linealpha = 255;
|
||||
float r, g, b;
|
||||
#ifdef EU07_USE_OLD_LIGHTING_MODEL
|
||||
r = floor( Diffuse[ 0 ] * Global::ambientDayLight[ 0 ] ); // w zaleznosci od koloru swiatla
|
||||
g = floor( Diffuse[ 1 ] * Global::ambientDayLight[ 1 ] );
|
||||
b = floor( Diffuse[ 2 ] * Global::ambientDayLight[ 2 ] );
|
||||
#else
|
||||
r = floor( Diffuse[ 0 ] * Global::DayLight.ambient[ 0 ] ); // w zaleznosci od koloru swiatla
|
||||
g = floor( Diffuse[ 1 ] * Global::DayLight.ambient[ 1 ] );
|
||||
b = floor( Diffuse[ 2 ] * Global::DayLight.ambient[ 2 ] );
|
||||
#endif
|
||||
glColor4ub( r, g, b, linealpha ); // przezroczystosc dalekiej linii
|
||||
GfxRenderer.Bind( 0 );
|
||||
|
||||
@@ -689,15 +652,9 @@ void TGroundNode::RenderAlphaDL()
|
||||
float linealpha = 255000 * fLineThickness / ( distancesquared + 1.0 );
|
||||
if (linealpha > 255)
|
||||
linealpha = 255;
|
||||
#ifdef EU07_USE_OLD_LIGHTING_MODEL
|
||||
r = Diffuse[ 0 ] * Global::ambientDayLight[ 0 ]; // w zaleznosci od koloru swiatla
|
||||
g = Diffuse[ 1 ] * Global::ambientDayLight[ 1 ];
|
||||
b = Diffuse[ 2 ] * Global::ambientDayLight[ 2 ];
|
||||
#else
|
||||
float r = Diffuse[ 0 ] * Global::DayLight.ambient[ 0 ]; // w zaleznosci od koloru swiatla
|
||||
float g = Diffuse[ 1 ] * Global::DayLight.ambient[ 1 ];
|
||||
float b = Diffuse[ 2 ] * Global::DayLight.ambient[ 2 ];
|
||||
#endif
|
||||
glColor4ub( r, g, b, linealpha ); // przezroczystosc dalekiej linii
|
||||
GfxRenderer.Bind( 0 );
|
||||
|
||||
@@ -720,6 +677,7 @@ void TGroundNode::RenderAlphaDL()
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------ Podstawowy pojemnik terenu - sektor -----------------------
|
||||
@@ -1093,8 +1051,7 @@ void TSubRect::LoadNodes()
|
||||
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...
|
||||
m_nVertexCount += n->iNumPts; // miejsce w tablicach normalnych i teksturowania się zmarnuje...
|
||||
break;
|
||||
case TP_TRACK:
|
||||
n->iVboPtr = m_nVertexCount; // nowy początek
|
||||
@@ -1180,10 +1137,10 @@ void TSubRect::RenderDL()
|
||||
{ // renderowanie nieprzezroczystych (DL)
|
||||
TGroundNode *node;
|
||||
RaAnimate(); // przeliczenia animacji torów w sektorze
|
||||
for (node = nRender; node; node = node->nNext3)
|
||||
node->RenderDL(); // nieprzezroczyste obiekty (oprócz pojazdów)
|
||||
for( node = nRender; node; node = node->nNext3 )
|
||||
GfxRenderer.Render( node ); // nieprzezroczyste obiekty (oprócz pojazdów)
|
||||
for (node = nRenderMixed; node; node = node->nNext3)
|
||||
node->RenderDL(); // nieprzezroczyste z mieszanych modeli
|
||||
GfxRenderer.Render( node ); // nieprzezroczyste z mieszanych modeli
|
||||
for (int j = 0; j < iTracks; ++j)
|
||||
tTracks[j]->RenderDyn(); // nieprzezroczyste fragmenty pojazdów na torach
|
||||
#ifdef EU07_SCENERY_EDITOR
|
||||
@@ -1237,13 +1194,10 @@ void TSubRect::RenderDL()
|
||||
void TSubRect::RenderAlphaDL()
|
||||
{ // renderowanie przezroczystych modeli oraz pojazdów (DL)
|
||||
TGroundNode *node;
|
||||
for (node = nRenderMixed; node; node = node->nNext3)
|
||||
node->RenderAlphaDL(); // przezroczyste z mieszanych modeli
|
||||
for (node = nRenderAlpha; node; node = node->nNext3)
|
||||
node->RenderAlphaDL(); // przezroczyste modele
|
||||
// for (node=tmp->nRender;node;node=node->nNext3)
|
||||
// if (node->iType==TP_TRACK)
|
||||
// node->pTrack->RenderAlpha(); //przezroczyste fragmenty pojazdów na torach
|
||||
for( node = nRenderMixed; node; node = node->nNext3 )
|
||||
GfxRenderer.Render_Alpha( node ); // przezroczyste z mieszanych modeli
|
||||
for( node = nRenderAlpha; node; node = node->nNext3 )
|
||||
GfxRenderer.Render_Alpha( node ); // przezroczyste modele
|
||||
for (int j = 0; j < iTracks; ++j)
|
||||
tTracks[j]->RenderDynAlpha(); // przezroczyste fragmenty pojazdów na torach
|
||||
};
|
||||
@@ -1255,15 +1209,15 @@ void TSubRect::RenderVBO()
|
||||
LoadNodes(); // czemu tutaj?
|
||||
if (StartVBO())
|
||||
{
|
||||
for (node = nRenderRect; node; node = node->nNext3)
|
||||
if (node->iVboPtr >= 0)
|
||||
node->RenderVBO(); // nieprzezroczyste obiekty terenu
|
||||
for( node = nRenderRect; node; node = node->nNext3 )
|
||||
if( node->iVboPtr >= 0 )
|
||||
GfxRenderer.Render( node ); // nieprzezroczyste obiekty terenu
|
||||
EndVBO();
|
||||
}
|
||||
for (node = nRender; node; node = node->nNext3)
|
||||
node->RenderVBO(); // nieprzezroczyste obiekty (oprócz pojazdów)
|
||||
for( node = nRender; node; node = node->nNext3 )
|
||||
GfxRenderer.Render( node ); // nieprzezroczyste obiekty (oprócz pojazdów)
|
||||
for (node = nRenderMixed; node; node = node->nNext3)
|
||||
node->RenderVBO(); // nieprzezroczyste z mieszanych modeli
|
||||
GfxRenderer.Render( node ); // nieprzezroczyste z mieszanych modeli
|
||||
for (int j = 0; j < iTracks; ++j)
|
||||
tTracks[j]->RenderDyn(); // nieprzezroczyste fragmenty pojazdów na torach
|
||||
#ifdef EU07_SCENERY_EDITOR
|
||||
@@ -1279,13 +1233,10 @@ void TSubRect::RenderVBO()
|
||||
void TSubRect::RenderAlphaVBO()
|
||||
{ // renderowanie przezroczystych modeli oraz pojazdów (VBO)
|
||||
TGroundNode *node;
|
||||
for (node = nRenderMixed; node; node = node->nNext3)
|
||||
node->RenderAlphaVBO(); // przezroczyste z mieszanych modeli
|
||||
for (node = nRenderAlpha; node; node = node->nNext3)
|
||||
node->RenderAlphaVBO(); // przezroczyste modele
|
||||
// for (node=tmp->nRender;node;node=node->nNext3)
|
||||
// if (node->iType==TP_TRACK)
|
||||
// node->pTrack->RenderAlpha(); //przezroczyste fragmenty pojazdów na torach
|
||||
for( node = nRenderMixed; node; node = node->nNext3 )
|
||||
GfxRenderer.Render_Alpha( node ); // przezroczyste z mieszanych modeli
|
||||
for( node = nRenderAlpha; node; node = node->nNext3 )
|
||||
GfxRenderer.Render_Alpha( node ); // przezroczyste modele
|
||||
for (int j = 0; j < iTracks; ++j)
|
||||
tTracks[j]->RenderDynAlpha(); // przezroczyste fragmenty pojazdów na torach
|
||||
};
|
||||
@@ -1300,8 +1251,6 @@ void TSubRect::RenderSounds()
|
||||
//---------------------------------------------------------------------------
|
||||
int TGroundRect::iFrameNumber = 0; // licznik wyświetlanych klatek
|
||||
|
||||
//TGroundRect::TGroundRect( float3 const &Position, float const Radius = 1000.0f * M_SQRT2 ) :
|
||||
|
||||
TGroundRect::~TGroundRect()
|
||||
{
|
||||
SafeDeleteArray(pSubRects);
|
||||
@@ -1343,50 +1292,12 @@ void TGroundRect::RenderDL()
|
||||
node->Compile(true);
|
||||
glEndList();
|
||||
}
|
||||
nRender->RenderDL(); // nieprzezroczyste trójkąty kwadratu kilometrowego
|
||||
GfxRenderer.Render( nRender ); // nieprzezroczyste trójkąty kwadratu kilometrowego
|
||||
}
|
||||
if (nRootMesh)
|
||||
nRootMesh->RenderDL();
|
||||
if( nRootMesh )
|
||||
GfxRenderer.Render( nRootMesh );
|
||||
iLastDisplay = iFrameNumber; // drugi raz nie potrzeba
|
||||
}
|
||||
/*
|
||||
float width = 500.0f;
|
||||
float height = 50.0f;
|
||||
float3 vTopLeftFront( m_area.center.x - width, m_area.center.y + height, m_area.center.z + width );
|
||||
float3 vTopLeftBack( m_area.center.x - width, m_area.center.y + height, m_area.center.z - width );
|
||||
float3 vTopRightBack( m_area.center.x + width, m_area.center.y + height, m_area.center.z - width );
|
||||
float3 vTopRightFront( m_area.center.x + width, m_area.center.y + height, m_area.center.z + width );
|
||||
|
||||
float3 vBottom_LeftFront( m_area.center.x - width, m_area.center.y - height, m_area.center.z + width );
|
||||
float3 vBottom_LeftBack( m_area.center.x - width, m_area.center.y - height, m_area.center.z - width );
|
||||
float3 vBottomRightBack( m_area.center.x + width, m_area.center.y - height, m_area.center.z - width );
|
||||
float3 vBottomRightFront( m_area.center.x + width, m_area.center.y - height, m_area.center.z + width );
|
||||
|
||||
glDisable( GL_LIGHTING );
|
||||
glDisable( GL_TEXTURE_2D );
|
||||
glColor3ub( 0, 255, 255 );
|
||||
glBegin( GL_LINE_LOOP );
|
||||
glVertex3fv( &vTopLeftFront.x );
|
||||
glVertex3fv( &vTopLeftBack.x );
|
||||
glVertex3fv( &vTopRightBack.x );
|
||||
glVertex3fv( &vTopRightFront.x );
|
||||
glEnd();
|
||||
glBegin( GL_LINE_LOOP );
|
||||
glVertex3fv( &vBottom_LeftFront.x );
|
||||
glVertex3fv( &vBottom_LeftBack.x );
|
||||
glVertex3fv( &vBottomRightBack.x );
|
||||
glVertex3fv( &vBottomRightFront.x );
|
||||
glEnd();
|
||||
glBegin( GL_LINES );
|
||||
glVertex3fv( &vTopLeftFront.x ); glVertex3fv( &vBottom_LeftFront.x );
|
||||
glVertex3fv( &vTopLeftBack.x ); glVertex3fv( &vBottom_LeftBack.x );
|
||||
glVertex3fv( &vTopRightBack.x ); glVertex3fv( &vBottomRightBack.x );
|
||||
glVertex3fv( &vTopRightFront.x ); glVertex3fv( &vBottomRightFront.x );
|
||||
glEnd();
|
||||
glColor3ub( 255, 255, 255 );
|
||||
glEnable( GL_TEXTURE_2D );
|
||||
glEnable( GL_LIGHTING );
|
||||
*/
|
||||
};
|
||||
|
||||
void TGroundRect::RenderVBO()
|
||||
@@ -1410,46 +1321,8 @@ void TGroundRect::RenderVBO()
|
||||
//---------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void TGround::MoveGroundNode(vector3 pPosition)
|
||||
{ // Ra: to wymaga gruntownej reformy
|
||||
/*
|
||||
TGroundNode *Current;
|
||||
for (Current=RootNode;Current!=NULL;Current=Current->Next)
|
||||
Current->MoveMe(pPosition);
|
||||
|
||||
TGroundRect *Rectx=new TGroundRect; //kwadrat kilometrowy
|
||||
for(int i=0;i<iNumRects;i++)
|
||||
for(int j=0;j<iNumRects;j++)
|
||||
Rects[i][j]=*Rectx; //kopiowanie zawartości do każdego kwadratu
|
||||
delete Rectx;
|
||||
for (Current=RootNode;Current!=NULL;Current=Current->Next)
|
||||
{//rozłożenie obiektów na mapie
|
||||
if (Current->iType!=TP_DYNAMIC)
|
||||
{//pojazdów to w ogóle nie dotyczy
|
||||
if ((Current->iType!=GL_TRIANGLES)&&(Current->iType!=GL_TRIANGLE_STRIP)?true //~czy trójkąt?
|
||||
:(Current->iFlags&0x20)?true //~czy teksturę ma nieprzezroczystą?
|
||||
//:(Current->iNumVerts!=3)?true //~czy tylko jeden trójkąt?
|
||||
:(Current->fSquareMinRadius!=0.0)?true //~czy widoczny z bliska?
|
||||
:(Current->fSquareRadius<=90000.0)) //~czy widoczny z daleka?
|
||||
GetSubRect(Current->pCenter.x,Current->pCenter.z)->AddNode(Current);
|
||||
else //dodajemy do kwadratu kilometrowego
|
||||
GetRect(Current->pCenter.x,Current->pCenter.z)->AddNode(Current);
|
||||
}
|
||||
}
|
||||
for (Current=RootDynamic;Current!=NULL;Current=Current->Next)
|
||||
{
|
||||
Current->pCenter+=pPosition;
|
||||
Current->DynamicObject->UpdatePos();
|
||||
}
|
||||
for (Current=RootDynamic;Current!=NULL;Current=Current->Next)
|
||||
Current->DynamicObject->MoverParameters->Physic_ReActivation();
|
||||
*/
|
||||
}
|
||||
|
||||
std::vector<TGroundVertex> TempVerts;
|
||||
/*
|
||||
TGroundVertex TempVerts[ 10000 ]; // tu wczytywane s¹ trójk¹ty
|
||||
*/
|
||||
|
||||
BYTE TempConnectionType[ 200 ]; // Ra: sprzêgi w sk³adzie; ujemne, gdy odwrotnie
|
||||
|
||||
TGround::TGround()
|
||||
@@ -4856,8 +4729,8 @@ bool TGround::RenderAlphaDL(vector3 pPosition)
|
||||
for (i = iRendered - 1; i >= 0; --i) // od najdalszych
|
||||
{ // przezroczyste trójkąty w oddzielnym cyklu przed modelami
|
||||
tmp = pRendered[i];
|
||||
for (node = tmp->nRenderRectAlpha; node; node = node->nNext3)
|
||||
node->RenderAlphaDL(); // przezroczyste modele
|
||||
for( node = tmp->nRenderRectAlpha; node; node = node->nNext3 )
|
||||
GfxRenderer.Render_Alpha( node ); // przezroczyste modele
|
||||
}
|
||||
for (i = iRendered - 1; i >= 0; --i) // od najdalszych
|
||||
{ // renderowanie przezroczystych modeli oraz pojazdów
|
||||
@@ -4867,8 +4740,8 @@ bool TGround::RenderAlphaDL(vector3 pPosition)
|
||||
for (i = iRendered - 1; i >= 0; --i) // od najdalszych
|
||||
{ // druty na końcu, żeby się nie robiły białe plamy na tle lasu
|
||||
tmp = pRendered[i];
|
||||
for (node = tmp->nRenderWires; node; node = node->nNext3)
|
||||
node->RenderAlphaDL(); // druty
|
||||
for( node = tmp->nRenderWires; node; node = node->nNext3 )
|
||||
GfxRenderer.Render_Alpha( node ); // druty
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -4954,9 +4827,9 @@ bool TGround::RenderAlphaVBO(vector3 pPosition)
|
||||
tmp->LoadNodes(); // ewentualne tworzenie siatek
|
||||
if (tmp->StartVBO())
|
||||
{
|
||||
for (node = tmp->nRenderRectAlpha; node; node = node->nNext3)
|
||||
if (node->iVboPtr >= 0)
|
||||
node->RenderAlphaVBO(); // nieprzezroczyste obiekty terenu
|
||||
for( node = tmp->nRenderRectAlpha; node; node = node->nNext3 )
|
||||
if( node->iVboPtr >= 0 )
|
||||
GfxRenderer.Render_Alpha( node ); // nieprzezroczyste obiekty terenu
|
||||
tmp->EndVBO();
|
||||
}
|
||||
}
|
||||
@@ -4968,8 +4841,8 @@ bool TGround::RenderAlphaVBO(vector3 pPosition)
|
||||
tmp = pRendered[i];
|
||||
if (tmp->StartVBO())
|
||||
{
|
||||
for (node = tmp->nRenderWires; node; node = node->nNext3)
|
||||
node->RenderAlphaVBO(); // przezroczyste modele
|
||||
for( node = tmp->nRenderWires; node; node = node->nNext3 )
|
||||
GfxRenderer.Render_Alpha( node ); // przezroczyste modele
|
||||
tmp->EndVBO();
|
||||
}
|
||||
}
|
||||
|
||||
45
Ground.h
45
Ground.h
@@ -101,8 +101,11 @@ class TSubRect; // sektor (aktualnie 200m×200m, ale może być zmieniony)
|
||||
|
||||
class TGroundNode : public Resource
|
||||
{ // obiekt scenerii
|
||||
private:
|
||||
public:
|
||||
|
||||
friend class opengl_renderer;
|
||||
|
||||
private:
|
||||
public:
|
||||
TGroundNodeType iType; // typ obiektu
|
||||
union
|
||||
{ // Ra: wskażniki zależne od typu - zrobić klasy dziedziczone zamiast
|
||||
@@ -130,12 +133,7 @@ class TGroundNode : public Resource
|
||||
};
|
||||
vector3 pCenter; // współrzędne środka do przydzielenia sektora
|
||||
|
||||
union
|
||||
{
|
||||
// double fAngle; //kąt obrotu dla modelu
|
||||
double fLineThickness; // McZapkie-120702: grubosc linii
|
||||
// int Status; //McZapkie-170303: status dzwieku
|
||||
};
|
||||
double fLineThickness; // McZapkie-120702: grubosc linii
|
||||
double fSquareRadius; // kwadrat widoczności do
|
||||
double fSquareMinRadius; // kwadrat widoczności od
|
||||
// TGroundNode *nMeshGroup; //Ra: obiekt grupujący trójkąty w TSubRect dla tekstury
|
||||
@@ -174,12 +172,8 @@ class TGroundNode : public Resource
|
||||
void Release();
|
||||
|
||||
void RenderHidden(); // obsługa dźwięków i wyzwalaczy zdarzeń
|
||||
void RenderDL(); // renderowanie nieprzezroczystych w Display Lists
|
||||
void RenderAlphaDL(); // renderowanie przezroczystych w Display Lists
|
||||
// (McZapkie-131202)
|
||||
void RaRenderVBO(); // renderowanie (nieprzezroczystych) ze wspólnego VBO
|
||||
void RenderVBO(); // renderowanie nieprzezroczystych z własnego VBO
|
||||
void RenderAlphaVBO(); // renderowanie przezroczystych z (własnego) VBO
|
||||
|
||||
};
|
||||
|
||||
@@ -313,9 +307,6 @@ class TGround
|
||||
public:
|
||||
bool bDynamicRemove = false; // czy uruchomić procedurę usuwania pojazdów
|
||||
TDynamicObject *LastDyn = nullptr; // ABu: paskudnie, ale na bardzo szybko moze jakos przejdzie...
|
||||
// TTrain *pTrain;
|
||||
// double fVDozwolona;
|
||||
// bool bTrabil;
|
||||
|
||||
TGround();
|
||||
~TGround();
|
||||
@@ -329,7 +320,6 @@ class TGround
|
||||
TTrack * FindTrack(vector3 Point, int &iConnection, TGroundNode *Exclude);
|
||||
TTraction * FindTraction(vector3 *Point, int &iConnection, TGroundNode *Exclude);
|
||||
TTraction * TractionNearestFind(vector3 &p, int dir, TGroundNode *n);
|
||||
// TGroundNode* CreateGroundNode();
|
||||
TGroundNode * AddGroundNode(cParser *parser);
|
||||
bool AddGroundNode(double x, double z, TGroundNode *Node)
|
||||
{
|
||||
@@ -342,11 +332,6 @@ class TGround
|
||||
else
|
||||
return false;
|
||||
};
|
||||
// bool Include(TQueryParserComp *Parser);
|
||||
// TGroundNode* GetVisible(AnsiString asName);
|
||||
TGroundNode * GetNode(std::string asName);
|
||||
bool AddDynamic(TGroundNode *Node);
|
||||
void MoveGroundNode(vector3 pPosition);
|
||||
void UpdatePhys(double dt, int iter); // aktualizacja fizyki stałym krokiem
|
||||
bool Update(double dt, int iter); // aktualizacja przesunięć zgodna z FPS
|
||||
void Update_Lights(); // updates scene lights array
|
||||
@@ -358,23 +343,6 @@ class TGround
|
||||
bool RenderVBO(vector3 pPosition);
|
||||
bool RenderAlphaVBO(vector3 pPosition);
|
||||
bool CheckQuery();
|
||||
// GetRect(double x, double z) { return
|
||||
// &(Rects[int(x/fSubRectSize+fHalfNumRects)][int(z/fSubRectSize+fHalfNumRects)]); };
|
||||
/*
|
||||
int GetRowFromZ(double z) { return (z/fRectSize+fHalfNumRects); };
|
||||
int GetColFromX(double x) { return (x/fRectSize+fHalfNumRects); };
|
||||
int GetSubRowFromZ(double z) { return (z/fSubRectSize+fHalfNumSubRects); };
|
||||
int GetSubColFromX(double x) { return (x/fSubRectSize+fHalfNumSubRects); };
|
||||
*/
|
||||
/*
|
||||
inline TGroundNode* FindGroundNode(const AnsiString &asNameToFind )
|
||||
{
|
||||
if (RootNode)
|
||||
return (RootNode->Find( asNameToFind ));
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
*/
|
||||
TGroundNode * DynamicFindAny(std::string asNameToFind);
|
||||
TGroundNode * DynamicFind(std::string asNameToFind);
|
||||
void DynamicList(bool all = false);
|
||||
@@ -419,7 +387,6 @@ class TGround
|
||||
void WyslijNamiary(TGroundNode *t);
|
||||
void WyslijParam(int nr, int fl);
|
||||
void WyslijUszkodzenia(const std::string &t, char fl);
|
||||
void WyslijPojazdy(int nr); // -> skladanie wielu pojazdow
|
||||
void WyslijObsadzone(); // -> skladanie wielu pojazdow
|
||||
void RadioStop(vector3 pPosition);
|
||||
TDynamicObject * DynamicNearest(vector3 pPosition, double distance = 20.0,
|
||||
|
||||
887
Segment.cpp
887
Segment.cpp
@@ -19,12 +19,6 @@ http://mozilla.org/MPL/2.0/.
|
||||
|
||||
// 101206 Ra: trapezoidalne drogi
|
||||
// 110806 Ra: odwrócone mapowanie wzdłuż - Point1 == 1.0
|
||||
|
||||
float Interpolate( float const First, float const Second, float const Factor ) {
|
||||
|
||||
return ( First * ( 1.0f - Factor ) ) + ( Second * Factor );
|
||||
}
|
||||
|
||||
std::string Where(vector3 p)
|
||||
{ // zamiana współrzędnych na tekst, używana w błędach
|
||||
return std::to_string(p.x) + " " + std::to_string(p.y) + " " + std::to_string(p.z);
|
||||
@@ -122,15 +116,14 @@ bool TSegment::Init(vector3 &NewPoint1, vector3 NewCPointOut, vector3 NewCPointI
|
||||
// MessageBox(0,"Length<=0","TSegment::Init",MB_OK);
|
||||
return false; // zerowe nie mogą być
|
||||
}
|
||||
fStoop = atan2((Point2.y - Point1.y),
|
||||
fLength); // pochylenie toru prostego, żeby nie liczyć wielokrotnie
|
||||
fStoop = std::atan2((Point2.y - Point1.y), fLength); // pochylenie toru prostego, żeby nie liczyć wielokrotnie
|
||||
SafeDeleteArray(fTsBuffer);
|
||||
|
||||
if( ( bCurve ) && ( fStep > 0 ) ) {
|
||||
if( fStep > 0 ) { // Ra: prosty dostanie podział, jak ma różną przechyłkę na końcach
|
||||
double s = 0;
|
||||
int i = 0;
|
||||
iSegCount = ceil( fLength / fStep ); // potrzebne do VBO
|
||||
iSegCount = static_cast<int>( std::ceil( fLength / fStep )); // potrzebne do VBO
|
||||
// fStep=fLength/(double)(iSegCount-1); //wyrównanie podziału
|
||||
fTsBuffer = new double[ iSegCount + 1 ];
|
||||
fTsBuffer[ 0 ] = 0; /* TODO : fix fTsBuffer */
|
||||
@@ -324,408 +317,213 @@ vector3 TSegment::FastGetPoint(double t)
|
||||
return (bCurve ? RaInterpolate(t) : ((1.0 - t) * Point1 + (t)*Point2));
|
||||
}
|
||||
|
||||
void TSegment::RenderLoft(const vector6 *ShapePoints, int iNumShapePoints, double fTextureLength,
|
||||
int iSkip, int iQualityFactor, vector3 **p, bool bRender)
|
||||
void TSegment::RenderLoft( CVertNormTex* &Output, const vector6 *ShapePoints, int iNumShapePoints, double fTextureLength, double Texturescale, int iSkip, int iEnd, double fOffsetX, bool Onlypositions, vector3 **p, bool bRender)
|
||||
{ // generowanie trójkątów dla odcinka trajektorii ruchu
|
||||
// standardowo tworzy triangle_strip dla prostego albo ich zestaw dla łuku
|
||||
// po modyfikacji - dla ujemnego (iNumShapePoints) w dodatkowych polach tabeli
|
||||
// podany jest przekrój końcowy
|
||||
// podsypka toru jest robiona za pomocą 6 punktów, szyna 12, drogi i rzeki na 3+2+3
|
||||
if (iQualityFactor < 1)
|
||||
iQualityFactor = 1; // co który segment ma być uwzględniony
|
||||
if( !fTsBuffer )
|
||||
return; // prowizoryczne zabezpieczenie przed wysypem - ustalić faktyczną przyczynę
|
||||
|
||||
vector3 pos1, pos2, dir, parallel1, parallel2, pt, norm;
|
||||
double s, step, fOffset, tv1, tv2, t;
|
||||
int i, j;
|
||||
bool trapez = iNumShapePoints < 0; // sygnalizacja trapezowatości
|
||||
iNumShapePoints = abs(iNumShapePoints);
|
||||
if (bCurve)
|
||||
{
|
||||
double m1, jmm1, m2, jmm2; // pozycje względne na odcinku 0...1 (ale nie parametr Beziera)
|
||||
tv1 = 1.0; // Ra: to by można było wyliczać dla odcinka, wyglądało by lepiej
|
||||
step = fStep * iQualityFactor;
|
||||
s = fStep * iSkip; // iSkip - ile odcinków z początku pominąć
|
||||
i = iSkip; // domyślnie 0
|
||||
if (!fTsBuffer)
|
||||
return; // prowizoryczne zabezpieczenie przed wysypem - ustalić faktyczną przyczynę
|
||||
if (i > iSegCount)
|
||||
return; // prowizoryczne zabezpieczenie przed wysypem - ustalić faktyczną przyczynę
|
||||
t = fTsBuffer[i]; // tabela watości t dla segmentów
|
||||
fOffset = 0.1 / fLength; // pierwsze 10cm
|
||||
pos1 = FastGetPoint(t); // wektor początku segmentu
|
||||
dir = FastGetDirection(t, fOffset); // wektor kierunku
|
||||
// parallel1=Normalize(CrossProduct(dir,vector3(0,1,0))); //wektor poprzeczny
|
||||
parallel1 = Normalize(vector3(-dir.z, 0.0, dir.x)); // wektor poprzeczny
|
||||
m2 = s / fLength;
|
||||
jmm2 = 1.0 - m2;
|
||||
while (s < fLength)
|
||||
{
|
||||
// step=SquareMagnitude(Global::GetCameraPosition()+pos);
|
||||
i += iQualityFactor; // kolejny punkt łamanej
|
||||
s += step; // końcowa pozycja segmentu [m]
|
||||
m1 = m2;
|
||||
jmm1 = jmm2; // stara pozycja
|
||||
m2 = s / fLength;
|
||||
jmm2 = 1.0 - m2; // nowa pozycja
|
||||
if (s > fLength - 0.5) // Ra: -0.5 żeby nie robiło cieniasa na końcu
|
||||
{ // gdy przekroczyliśmy koniec - stąd dziury w torach...
|
||||
step -= (s - fLength); // jeszcze do wyliczenia mapowania potrzebny
|
||||
s = fLength;
|
||||
i = iSegCount; // 20/5 ma dawać 4
|
||||
m2 = 1.0;
|
||||
jmm2 = 0.0;
|
||||
}
|
||||
while (tv1 < 0.0)
|
||||
tv1 += 1.0; // przestawienie mapowania
|
||||
tv2 = tv1 - step / fTextureLength; // mapowanie na końcu segmentu
|
||||
t = fTsBuffer[i]; // szybsze od GetTFromS(s);
|
||||
pos2 = FastGetPoint(t);
|
||||
dir = FastGetDirection(t, fOffset); // nowy wektor kierunku
|
||||
// parallel2=CrossProduct(dir,vector3(0,1,0)); //wektor poprzeczny
|
||||
parallel2 = Normalize(vector3(-dir.z, 0.0, dir.x)); // wektor poprzeczny
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
if (trapez)
|
||||
for (j = 0; j < iNumShapePoints; j++)
|
||||
{
|
||||
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;
|
||||
pt = parallel1 *
|
||||
(jmm1 * ShapePoints[j].x + m1 * ShapePoints[j + iNumShapePoints].x) +
|
||||
pos1;
|
||||
pt.y += jmm1 * ShapePoints[j].y + m1 * ShapePoints[j + iNumShapePoints].y;
|
||||
if (bRender)
|
||||
{ // skrzyżowania podczas łączenia siatek mogą nie renderować poboczy, ale
|
||||
// potrzebować punktów
|
||||
glNormal3f(norm.x, norm.y, norm.z);
|
||||
glTexCoord2f(
|
||||
jmm1 * ShapePoints[j].z + m1 * ShapePoints[j + iNumShapePoints].z, tv1);
|
||||
glVertex3f(pt.x, pt.y, pt.z); // pt nie mamy gdzie zapamiętać?
|
||||
}
|
||||
// BUG: things blow up badly in the following part in 64bit version on baltyk.scn
|
||||
// TODO: sort this mess out when the time comes to reorganize spline generation
|
||||
if( p ) // jeśli jest wskaźnik do tablicy
|
||||
if (*p)
|
||||
if (!j) // to dla pierwszego punktu
|
||||
{
|
||||
*(*p) = pt;
|
||||
(*p)++;
|
||||
} // zapamiętanie brzegu jezdni
|
||||
// dla trapezu drugi koniec ma inne współrzędne
|
||||
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;
|
||||
pt = parallel2 *
|
||||
(jmm2 * ShapePoints[j].x + m2 * ShapePoints[j + iNumShapePoints].x) +
|
||||
pos2;
|
||||
pt.y += jmm2 * ShapePoints[j].y + m2 * ShapePoints[j + iNumShapePoints].y;
|
||||
if (bRender)
|
||||
{ // skrzyżowania podczas łączenia siatek mogą nie renderować poboczy, ale
|
||||
// potrzebować punktów
|
||||
glNormal3f(norm.x, norm.y, norm.z);
|
||||
glTexCoord2f(
|
||||
jmm2 * ShapePoints[j].z + m2 * ShapePoints[j + iNumShapePoints].z, tv2);
|
||||
glVertex3f(pt.x, pt.y, pt.z);
|
||||
}
|
||||
if (p) // jeśli jest wskaźnik do tablicy
|
||||
if (*p)
|
||||
if (!j) // to dla pierwszego punktu
|
||||
if (i == iSegCount)
|
||||
{
|
||||
*(*p) = pt;
|
||||
(*p)++;
|
||||
} // zapamiętanie brzegu jezdni
|
||||
}
|
||||
else
|
||||
for (j = 0; j < iNumShapePoints; j++)
|
||||
{ //łuk z jednym profilem
|
||||
norm = ShapePoints[j].n.x * parallel1;
|
||||
norm.y += ShapePoints[j].n.y;
|
||||
pt = parallel1 * ShapePoints[j].x + pos1;
|
||||
pt.y += ShapePoints[j].y;
|
||||
glNormal3f(norm.x, norm.y, norm.z);
|
||||
glTexCoord2f(ShapePoints[j].z, tv1);
|
||||
glVertex3f(pt.x, pt.y, pt.z); // punkt na początku odcinka
|
||||
norm = ShapePoints[j].n.x * parallel2;
|
||||
norm.y += ShapePoints[j].n.y;
|
||||
pt = parallel2 * ShapePoints[j].x + pos2;
|
||||
pt.y += ShapePoints[j].y;
|
||||
glNormal3f(norm.x, norm.y, norm.z);
|
||||
glTexCoord2f(ShapePoints[j].z, tv2);
|
||||
glVertex3f(pt.x, pt.y, pt.z); // punkt na końcu odcinka
|
||||
}
|
||||
glEnd();
|
||||
pos1 = pos2;
|
||||
parallel1 = parallel2;
|
||||
tv1 = tv2;
|
||||
double s, step, fOffset, tv1, tv2, t, fEnd;
|
||||
bool const trapez = iNumShapePoints < 0; // sygnalizacja trapezowatości
|
||||
iNumShapePoints = std::abs( iNumShapePoints );
|
||||
fTextureLength *= Texturescale;
|
||||
|
||||
double m1, jmm1, m2, jmm2; // pozycje względne na odcinku 0...1 (ale nie parametr Beziera)
|
||||
step = fStep;
|
||||
tv1 = 1.0; // Ra: to by można było wyliczać dla odcinka, wyglądało by lepiej
|
||||
s = fStep * iSkip; // iSkip - ile odcinków z początku pominąć
|
||||
int i = iSkip; // domyślnie 0
|
||||
t = fTsBuffer[ i ]; // tabela wattości t dla segmentów
|
||||
// BUG: length of spline can be 0, we should skip geometry generation for such cases
|
||||
fOffset = 0.1 / fLength; // pierwsze 10cm
|
||||
pos1 = FastGetPoint( t ); // wektor początku segmentu
|
||||
dir = FastGetDirection( t, fOffset ); // wektor kierunku
|
||||
parallel1 = Normalize( vector3( -dir.z, 0.0, dir.x ) ); // wektor poprzeczny
|
||||
if( iEnd == 0 )
|
||||
iEnd = iSegCount;
|
||||
fEnd = fLength * double( iEnd ) / double( iSegCount );
|
||||
m2 = s / fEnd;
|
||||
jmm2 = 1.0 - m2;
|
||||
while( i < iEnd ) {
|
||||
|
||||
++i; // kolejny punkt łamanej
|
||||
s += step; // końcowa pozycja segmentu [m]
|
||||
m1 = m2;
|
||||
jmm1 = jmm2; // stara pozycja
|
||||
m2 = s / fEnd;
|
||||
jmm2 = 1.0 - m2; // nowa pozycja
|
||||
if( i == iEnd ) { // gdy przekroczyliśmy koniec - stąd dziury w torach...
|
||||
step -= ( s - fEnd ); // jeszcze do wyliczenia mapowania potrzebny
|
||||
s = fEnd;
|
||||
m2 = 1.0;
|
||||
jmm2 = 0.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
#ifdef EU07_USE_OLD_LIGHTING_MODEL
|
||||
{ // gdy prosty, nie modyfikujemy wektora kierunkowego i poprzecznego
|
||||
pos1 = FastGetPoint((fStep * iSkip) / fLength);
|
||||
pos2 = FastGetPoint_1();
|
||||
dir = GetDirection();
|
||||
// parallel1=Normalize(CrossProduct(dir,vector3(0,1,0)));
|
||||
parallel1 = Normalize(vector3(-dir.z, 0.0, dir.x)); // wektor poprzeczny
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
if (trapez)
|
||||
for (j = 0; j < iNumShapePoints; j++)
|
||||
{
|
||||
norm = ShapePoints[j].n.x * parallel1;
|
||||
norm.y += ShapePoints[j].n.y;
|
||||
pt = parallel1 * ShapePoints[j].x + pos1;
|
||||
pt.y += ShapePoints[j].y;
|
||||
glNormal3f(norm.x, norm.y, norm.z);
|
||||
glTexCoord2f(ShapePoints[j].z, 0);
|
||||
glVertex3f(pt.x, pt.y, pt.z);
|
||||
// dla trapezu drugi koniec ma inne współrzędne względne
|
||||
norm = ShapePoints[j + iNumShapePoints].n.x * parallel1;
|
||||
norm.y += ShapePoints[j + iNumShapePoints].n.y;
|
||||
pt = parallel1 * ShapePoints[j + iNumShapePoints].x + pos2; // odsunięcie
|
||||
pt.y += ShapePoints[j + iNumShapePoints].y; // wysokość
|
||||
glNormal3f(norm.x, norm.y, norm.z);
|
||||
glTexCoord2f(ShapePoints[j + iNumShapePoints].z, fLength / fTextureLength);
|
||||
glVertex3f(pt.x, pt.y, pt.z);
|
||||
|
||||
if( false == Onlypositions ) {
|
||||
while( tv1 < 0.0 ) {
|
||||
tv1 += 1.0;
|
||||
}
|
||||
else
|
||||
for (j = 0; j < iNumShapePoints; j++)
|
||||
{
|
||||
norm = ShapePoints[j].n.x * parallel1;
|
||||
norm.y += ShapePoints[j].n.y;
|
||||
pt = parallel1 * ShapePoints[j].x + pos1;
|
||||
pt.y += ShapePoints[j].y;
|
||||
glNormal3f(norm.x, norm.y, norm.z);
|
||||
glTexCoord2f(ShapePoints[j].z, 0);
|
||||
glVertex3f(pt.x, pt.y, pt.z);
|
||||
pt = parallel1 * ShapePoints[j].x + pos2;
|
||||
pt.y += ShapePoints[j].y;
|
||||
glNormal3f(norm.x, norm.y, norm.z);
|
||||
glTexCoord2f(ShapePoints[j].z, fLength / fTextureLength);
|
||||
glVertex3f(pt.x, pt.y, pt.z);
|
||||
tv2 = tv1 - step / fTextureLength; // mapowanie na końcu segmentu
|
||||
}
|
||||
|
||||
t = fTsBuffer[ i ]; // szybsze od GetTFromS(s);
|
||||
pos2 = FastGetPoint( t );
|
||||
dir = FastGetDirection( t, fOffset ); // nowy wektor kierunku
|
||||
parallel2 = Normalize( vector3( -dir.z, 0.0, dir.x ) ); // wektor poprzeczny
|
||||
|
||||
if( Output == nullptr ) {
|
||||
// immediate mode
|
||||
::glBegin( GL_TRIANGLE_STRIP );
|
||||
}
|
||||
|
||||
if( trapez ) {
|
||||
for( int j = 0; j < iNumShapePoints; ++j ) {
|
||||
pt = parallel1 * ( jmm1 * ( ShapePoints[ j ].x - fOffsetX ) + m1 * ShapePoints[ j + iNumShapePoints ].x ) + pos1;
|
||||
pt.y += jmm1 * ShapePoints[ j ].y + m1 * ShapePoints[ j + iNumShapePoints ].y;
|
||||
if( false == Onlypositions ) {
|
||||
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;
|
||||
}
|
||||
if( bRender ) { // skrzyżowania podczas łączenia siatek mogą nie renderować poboczy, ale potrzebować punktów
|
||||
if( Output == nullptr ) {
|
||||
// immediate mode
|
||||
if( false == Onlypositions ) {
|
||||
::glNormal3f( norm.x, norm.y, norm.z );
|
||||
::glTexCoord2f( (jmm1 * ShapePoints[ j ].z + m1 * ShapePoints[ j + iNumShapePoints ].z) / Texturescale, tv1 );
|
||||
}
|
||||
::glVertex3f( pt.x, pt.y, pt.z ); // pt nie mamy gdzie zapamiętać?
|
||||
}
|
||||
else {
|
||||
Output->x = pt.x;
|
||||
Output->y = pt.y;
|
||||
Output->z = pt.z;
|
||||
if( false == Onlypositions ) {
|
||||
Output->nx = norm.x;
|
||||
Output->ny = norm.y;
|
||||
Output->nz = norm.z;
|
||||
Output->u = (jmm1 * ShapePoints[ j ].z + m1 * ShapePoints[ j + iNumShapePoints ].z) / Texturescale;
|
||||
Output->v = tv1;
|
||||
}
|
||||
++Output;
|
||||
}
|
||||
}
|
||||
if( p ) // jeśli jest wskaźnik do tablicy
|
||||
if( *p )
|
||||
if( !j ) // to dla pierwszego punktu
|
||||
{
|
||||
*( *p ) = pt;
|
||||
( *p )++;
|
||||
} // zapamiętanie brzegu jezdni
|
||||
// dla trapezu drugi koniec ma inne współrzędne
|
||||
pt = parallel2 * ( jmm2 * ( ShapePoints[ j ].x - fOffsetX ) + m2 * ShapePoints[ j + iNumShapePoints ].x ) + pos2;
|
||||
pt.y += jmm2 * ShapePoints[ j ].y + m2 * ShapePoints[ j + iNumShapePoints ].y;
|
||||
if( false == Onlypositions ) {
|
||||
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;
|
||||
}
|
||||
if( bRender ) { // skrzyżowania podczas łączenia siatek mogą nie renderować poboczy, ale potrzebować punktów
|
||||
if( Output == nullptr ) {
|
||||
// immediate mode
|
||||
if( false == Onlypositions ) {
|
||||
::glNormal3f( norm.x, norm.y, norm.z );
|
||||
::glTexCoord2f( (jmm2 * ShapePoints[ j ].z + m2 * ShapePoints[ j + iNumShapePoints ].z) / Texturescale, tv2 );
|
||||
}
|
||||
::glVertex3f( pt.x, pt.y, pt.z );
|
||||
}
|
||||
else {
|
||||
Output->x = pt.x;
|
||||
Output->y = pt.y;
|
||||
Output->z = pt.z;
|
||||
if( false == Onlypositions ) {
|
||||
Output->nx = norm.x;
|
||||
Output->ny = norm.y;
|
||||
Output->nz = norm.z;
|
||||
Output->u = (jmm2 * ShapePoints[ j ].z + m2 * ShapePoints[ j + iNumShapePoints ].z) / Texturescale;
|
||||
Output->v = tv2;
|
||||
}
|
||||
++Output;
|
||||
}
|
||||
}
|
||||
if( p ) // jeśli jest wskaźnik do tablicy
|
||||
if( *p )
|
||||
if( !j ) // to dla pierwszego punktu
|
||||
if( i == iSegCount ) {
|
||||
*( *p ) = pt;
|
||||
( *p )++;
|
||||
} // zapamiętanie brzegu jezdni
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
#else
|
||||
{
|
||||
Math3D::vector3 const pos0 = FastGetPoint( ( fStep * iSkip ) / fLength );
|
||||
Math3D::vector3 const pos1 = FastGetPoint_1();
|
||||
dir = GetDirection();
|
||||
Math3D::vector3 const parallel = Normalize( vector3( -dir.z, 0.0, dir.x ) ); // wektor poprzeczny
|
||||
|
||||
Math3D::vector3 startnormal0, startnormal1, endnormal0, endnormal1;
|
||||
Math3D::vector3 startvertex0, startvertex1, endvertex0, endvertex1;
|
||||
float startuv0, startuv1, enduv0, enduv1;
|
||||
|
||||
for( j = 0; j < iNumShapePoints - 1; ++j ) {
|
||||
|
||||
startnormal0 = ShapePoints[ j ].n.x * parallel;
|
||||
startnormal0.y += ShapePoints[ j ].n.y;
|
||||
startvertex0 = parallel * ShapePoints[ j ].x + pos0;
|
||||
startvertex0.y += ShapePoints[ j ].y;
|
||||
startuv0 = ShapePoints[ j ].z;
|
||||
startnormal1 = ShapePoints[ j + 1 ].n.x * parallel;
|
||||
startnormal1.y += ShapePoints[ j + 1 ].n.y;
|
||||
startvertex1 = parallel * ShapePoints[ j + 1 ].x + pos0;
|
||||
startvertex1.y += ShapePoints[ j + 1 ].y;
|
||||
startuv1 = ShapePoints[ j + 1 ].z;
|
||||
|
||||
if( trapez == false ) {
|
||||
// single profile throughout
|
||||
endnormal0 = startnormal0;
|
||||
endvertex0 = startvertex0 + ( pos1 - pos0 );
|
||||
enduv0 = startuv0;
|
||||
endnormal1 = startnormal1;
|
||||
endvertex1 = startvertex1 + ( pos1 - pos0 );
|
||||
enduv1 = startuv1;
|
||||
}
|
||||
else {
|
||||
// end profile is different
|
||||
endnormal0 = ShapePoints[ j + iNumShapePoints ].n.x * parallel;
|
||||
endnormal0.y += ShapePoints[ j + iNumShapePoints ].n.y;
|
||||
endvertex0 = parallel * ShapePoints[ j + iNumShapePoints ].x + pos1; // odsunięcie
|
||||
endvertex0.y += ShapePoints[ j + iNumShapePoints ].y; // wysokość
|
||||
enduv0 = ShapePoints[ j + iNumShapePoints ].z;
|
||||
endnormal1 = ShapePoints[ j + iNumShapePoints + 1 ].n.x * parallel;
|
||||
endnormal1.y += ShapePoints[ j + iNumShapePoints + 1 ].n.y;
|
||||
endvertex1 = parallel * ShapePoints[ j + iNumShapePoints + 1 ].x + pos1; // odsunięcie
|
||||
endvertex1.y += ShapePoints[ j + iNumShapePoints + 1 ].y; // wysokość
|
||||
enduv1 = ShapePoints[ j + iNumShapePoints + 1 ].z;
|
||||
}
|
||||
// now build strips, lerping from start to endpoint
|
||||
step = 10.0; // arbitrary segment size for straights
|
||||
float s = 0.0,
|
||||
t = 0.0,
|
||||
uv = 0.0;
|
||||
glBegin( GL_TRIANGLE_STRIP );
|
||||
while( s < fLength ) {
|
||||
|
||||
t = s / fLength;
|
||||
uv = s / fTextureLength;
|
||||
|
||||
auto const normal1lerp = Interpolate( startnormal1, endnormal1, t );
|
||||
glNormal3dv( &normal1lerp.x );
|
||||
auto const uv1lerp = Interpolate( startuv1, enduv1, t );
|
||||
glTexCoord2f( uv1lerp, uv );
|
||||
auto const vertex1lerp = Interpolate( startvertex1, endvertex1, t );
|
||||
glVertex3dv( &vertex1lerp.x );
|
||||
|
||||
auto const normal0lerp = Interpolate( startnormal0, endnormal0, t );
|
||||
glNormal3dv( &normal0lerp.x );
|
||||
auto const uv0lerp = Interpolate( startuv0, enduv0, t );
|
||||
glTexCoord2f( uv0lerp, uv );
|
||||
auto const vertex0lerp = Interpolate( startvertex0, endvertex0, t );
|
||||
glVertex3dv( &vertex0lerp.x );
|
||||
|
||||
s += step;
|
||||
}
|
||||
// add ending vertex pair if needed
|
||||
glNormal3dv( &endnormal1.x );
|
||||
glTexCoord2f( enduv1, fLength / fTextureLength );
|
||||
glVertex3dv( &endvertex1.x );
|
||||
glNormal3dv( &endnormal0.x );
|
||||
glTexCoord2f( enduv0, fLength / fTextureLength );
|
||||
glVertex3dv( &endvertex0.x );
|
||||
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
void TSegment::RenderSwitchRail(const vector6 *ShapePoints1, const vector6 *ShapePoints2,
|
||||
int iNumShapePoints, double fTextureLength, int iSkip,
|
||||
double fOffsetX)
|
||||
{ // tworzenie siatki trójkątów dla iglicy
|
||||
vector3 pos1, pos2, dir, parallel1, parallel2, pt;
|
||||
double a1, a2, s, step, offset, tv1, tv2, t, t2step, oldt2;
|
||||
int i, j;
|
||||
if (bCurve)
|
||||
{ // dla toru odchylonego
|
||||
// t2= 0;
|
||||
t2step = 1 / double(iSkip); // przesunięcie tekstury?
|
||||
oldt2 = 1;
|
||||
tv1 = 1.0;
|
||||
step = fStep; // długść segmentu
|
||||
s = 0;
|
||||
i = 0;
|
||||
t = fTsBuffer[i]; // wartość t krzywej Beziera dla początku
|
||||
a1 = 0;
|
||||
// step= fStep/fLength;
|
||||
offset = 0.1 / fLength; // około 10cm w sensie parametru t
|
||||
pos1 = FastGetPoint(t); // współrzędne dla parmatru t
|
||||
// dir= GetDirection1();
|
||||
dir = FastGetDirection(t, offset); // wektor wzdłużny
|
||||
// parallel1=Normalize(CrossProduct(dir,vector3(0,1,0))); //poprzeczny?
|
||||
parallel1 = Normalize(vector3(-dir.z, 0.0, dir.x)); // wektor poprzeczny
|
||||
|
||||
while (s < fLength && i < iSkip)
|
||||
{
|
||||
// step= SquareMagnitude(Global::GetCameraPosition()+pos);
|
||||
// t2= oldt2+t2step;
|
||||
i++;
|
||||
s += step;
|
||||
|
||||
if (s > fLength)
|
||||
{
|
||||
step -= (s - fLength);
|
||||
s = fLength;
|
||||
}
|
||||
|
||||
while (tv1 < 0.0)
|
||||
tv1 += 1.0;
|
||||
tv2 = tv1 - step / fTextureLength;
|
||||
|
||||
t = fTsBuffer[i];
|
||||
pos2 = FastGetPoint(t);
|
||||
dir = FastGetDirection(t, offset);
|
||||
// parallel2=Normalize(CrossProduct(dir,vector3(0,1,0)));
|
||||
parallel2 = Normalize(vector3(-dir.z, 0.0, dir.x)); // wektor poprzeczny
|
||||
|
||||
a2 = double(i) / (iSkip);
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
for (j = 0; j < iNumShapePoints; j++)
|
||||
{ // po dwa punkty trapezu
|
||||
pt = parallel1 *
|
||||
(ShapePoints1[j].x * a1 + (ShapePoints2[j].x - fOffsetX) * (1.0 - a1)) +
|
||||
pos1;
|
||||
pt.y += ShapePoints1[j].y * a1 + ShapePoints2[j].y * (1.0 - a1);
|
||||
glNormal3f(0.0f, 1.0f, 0.0f);
|
||||
glTexCoord2f(ShapePoints1[j].z * a1 + ShapePoints2[j].z * (1.0 - a1), tv1);
|
||||
glVertex3f(pt.x, pt.y, pt.z);
|
||||
|
||||
pt = parallel2 *
|
||||
(ShapePoints1[j].x * a2 + (ShapePoints2[j].x - fOffsetX) * (1.0 - a2)) +
|
||||
pos2;
|
||||
pt.y += ShapePoints1[j].y * a2 + ShapePoints2[j].y * (1.0 - a2);
|
||||
glNormal3f(0.0f, 1.0f, 0.0f);
|
||||
glTexCoord2f(ShapePoints1[j].z * a2 + ShapePoints2[j].z * (1.0 - a2), tv2);
|
||||
glVertex3f(pt.x, pt.y, pt.z);
|
||||
for( int j = 0; j < iNumShapePoints; ++j ) {
|
||||
//łuk z jednym profilem
|
||||
pt = parallel1 * ( ShapePoints[ j ].x - fOffsetX ) + pos1;
|
||||
pt.y += ShapePoints[ j ].y;
|
||||
if( false == Onlypositions ) {
|
||||
norm = ShapePoints[ j ].n.x * parallel1;
|
||||
norm.y += ShapePoints[ j ].n.y;
|
||||
}
|
||||
if( Output == nullptr ) {
|
||||
// immediate mode
|
||||
if( false == Onlypositions ) {
|
||||
::glNormal3f( norm.x, norm.y, norm.z );
|
||||
::glTexCoord2f( ShapePoints[ j ].z / Texturescale, tv1 );
|
||||
}
|
||||
::glVertex3f( pt.x, pt.y, pt.z ); // punkt na początku odcinka
|
||||
}
|
||||
else {
|
||||
Output->x = pt.x;
|
||||
Output->y = pt.y;
|
||||
Output->z = pt.z;
|
||||
if( false == Onlypositions ) {
|
||||
Output->nx = norm.x;
|
||||
Output->ny = norm.y;
|
||||
Output->nz = norm.z;
|
||||
Output->u = ShapePoints[ j ].z / Texturescale;
|
||||
Output->v = tv1;
|
||||
}
|
||||
++Output;
|
||||
}
|
||||
pt = parallel2 * ShapePoints[ j ].x + pos2;
|
||||
pt.y += ShapePoints[ j ].y;
|
||||
if( false == Onlypositions ) {
|
||||
norm = ShapePoints[ j ].n.x * parallel2;
|
||||
norm.y += ShapePoints[ j ].n.y;
|
||||
}
|
||||
if( Output == nullptr ) {
|
||||
// immediate mode
|
||||
if( false == Onlypositions ) {
|
||||
::glNormal3f( norm.x, norm.y, norm.z );
|
||||
::glTexCoord2f( ShapePoints[ j ].z / Texturescale, tv2 );
|
||||
}
|
||||
::glVertex3f( pt.x, pt.y, pt.z ); // punkt na końcu odcinka
|
||||
}
|
||||
else {
|
||||
Output->x = pt.x;
|
||||
Output->y = pt.y;
|
||||
Output->z = pt.z;
|
||||
if( false == Onlypositions ) {
|
||||
Output->nx = norm.x;
|
||||
Output->ny = norm.y;
|
||||
Output->nz = norm.z;
|
||||
Output->u = ShapePoints[ j ].z / Texturescale;
|
||||
Output->v = tv2;
|
||||
}
|
||||
++Output;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( Output == nullptr ) {
|
||||
// immediate mode
|
||||
glEnd();
|
||||
pos1 = pos2;
|
||||
parallel1 = parallel2;
|
||||
tv1 = tv2;
|
||||
a1 = a2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // dla toru prostego
|
||||
tv1 = 1.0;
|
||||
s = 0;
|
||||
i = 0;
|
||||
// pos1= FastGetPoint( (5*iSkip)/fLength );
|
||||
pos1 = FastGetPoint_0();
|
||||
dir = GetDirection();
|
||||
// parallel1=CrossProduct(dir,vector3(0,1,0));
|
||||
parallel1 = Normalize(vector3(-dir.z, 0.0, dir.x)); // wektor poprzeczny
|
||||
|
||||
step = 5;
|
||||
a1 = 0;
|
||||
|
||||
while (i < iSkip)
|
||||
{
|
||||
// step= SquareMagnitude(Global::GetCameraPosition()+pos);
|
||||
i++;
|
||||
s += step;
|
||||
|
||||
if (s > fLength)
|
||||
{
|
||||
step -= (s - fLength);
|
||||
s = fLength;
|
||||
}
|
||||
|
||||
while (tv1 < 0.0)
|
||||
tv1 += 1.0;
|
||||
|
||||
tv2 = tv1 - step / fTextureLength;
|
||||
|
||||
t = s / fLength;
|
||||
pos2 = FastGetPoint(t);
|
||||
|
||||
a2 = double(i) / (iSkip);
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
for (j = 0; j < iNumShapePoints; j++)
|
||||
{
|
||||
pt = parallel1 *
|
||||
(ShapePoints1[j].x * a1 + (ShapePoints2[j].x - fOffsetX) * (1.0 - a1)) +
|
||||
pos1;
|
||||
pt.y += ShapePoints1[j].y * a1 + ShapePoints2[j].y * (1.0 - a1);
|
||||
glNormal3f(0.0f, 1.0f, 0.0f);
|
||||
glTexCoord2f((ShapePoints1[j].z), tv1);
|
||||
glVertex3f(pt.x, pt.y, pt.z);
|
||||
|
||||
pt = parallel1 *
|
||||
(ShapePoints1[j].x * a2 + (ShapePoints2[j].x - fOffsetX) * (1.0 - a2)) +
|
||||
pos2;
|
||||
pt.y += ShapePoints1[j].y * a2 + ShapePoints2[j].y * (1.0 - a2);
|
||||
glNormal3f(0.0f, 1.0f, 0.0f);
|
||||
glTexCoord2f(ShapePoints2[j].z, tv2);
|
||||
glVertex3f(pt.x, pt.y, pt.z);
|
||||
}
|
||||
glEnd();
|
||||
pos1 = pos2;
|
||||
pos1 = pos2;
|
||||
parallel1 = parallel2;
|
||||
if( false == Onlypositions ) {
|
||||
tv1 = tv2;
|
||||
a1 = a2;
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -778,301 +576,4 @@ void TSegment::Render()
|
||||
}
|
||||
}
|
||||
|
||||
void TSegment::RaRenderLoft(CVertNormTex *&Vert, const vector6 *ShapePoints, int iNumShapePoints,
|
||||
double fTextureLength, int iSkip, int iEnd, double fOffsetX)
|
||||
{ // generowanie trójkątów dla odcinka trajektorii ruchu
|
||||
// standardowo tworzy triangle_strip dla prostego albo ich zestaw dla łuku
|
||||
// po modyfikacji - dla ujemnego (iNumShapePoints) w dodatkowych polach tabeli
|
||||
// podany jest przekrój końcowy
|
||||
// podsypka toru jest robiona za pomocą 6 punktów, szyna 12, drogi i rzeki na 3+2+3
|
||||
// na użytek VBO strip dla łuków jest tworzony wzdłuż
|
||||
// dla skróconego odcinka (iEnd<iSegCount), ShapePoints dotyczy
|
||||
// końców skróconych, a nie całości (to pod kątem iglic jest)
|
||||
vector3 pos1, pos2, dir, parallel1, parallel2, pt, norm;
|
||||
double s, step, fOffset, tv1, tv2, t, fEnd;
|
||||
int i, j;
|
||||
bool trapez = iNumShapePoints < 0; // sygnalizacja trapezowatości
|
||||
iNumShapePoints = abs(iNumShapePoints);
|
||||
if (bCurve)
|
||||
{
|
||||
double m1, jmm1, m2, jmm2; // pozycje względne na odcinku 0...1 (ale nie parametr Beziera)
|
||||
step = fStep;
|
||||
tv1 = 1.0; // Ra: to by można było wyliczać dla odcinka, wyglądało by lepiej
|
||||
s = fStep * iSkip; // iSkip - ile odcinków z początku pominąć
|
||||
i = iSkip; // domyślnie 0
|
||||
t = fTsBuffer[i]; // tabela wattości t dla segmentów
|
||||
// BUG: length of spline can be 0, we should skip geometry generation for such cases
|
||||
fOffset = 0.1 / fLength; // pierwsze 10cm
|
||||
pos1 = FastGetPoint(t); // wektor początku segmentu
|
||||
dir = FastGetDirection(t, fOffset); // wektor kierunku
|
||||
// parallel1=Normalize(CrossProduct(dir,vector3(0,1,0))); //wektor prostopadły
|
||||
parallel1 = Normalize(vector3(-dir.z, 0.0, dir.x)); // wektor poprzeczny
|
||||
if (iEnd == 0)
|
||||
iEnd = iSegCount;
|
||||
fEnd = fLength * double(iEnd) / double(iSegCount);
|
||||
m2 = s / fEnd;
|
||||
jmm2 = 1.0 - m2;
|
||||
while (i < iEnd)
|
||||
{
|
||||
++i; // kolejny punkt łamanej
|
||||
s += step; // końcowa pozycja segmentu [m]
|
||||
m1 = m2;
|
||||
jmm1 = jmm2; // stara pozycja
|
||||
m2 = s / fEnd;
|
||||
jmm2 = 1.0 - m2; // nowa pozycja
|
||||
if (i == iEnd)
|
||||
{ // gdy przekroczyliśmy koniec - stąd dziury w torach...
|
||||
step -= (s - fEnd); // jeszcze do wyliczenia mapowania potrzebny
|
||||
s = fEnd;
|
||||
// i=iEnd; //20/5 ma dawać 4
|
||||
m2 = 1.0;
|
||||
jmm2 = 0.0;
|
||||
}
|
||||
while (tv1 < 0.0)
|
||||
tv1 += 1.0;
|
||||
tv2 = tv1 - step / fTextureLength; // mapowanie na końcu segmentu
|
||||
t = fTsBuffer[i]; // szybsze od GetTFromS(s);
|
||||
pos2 = FastGetPoint(t);
|
||||
dir = FastGetDirection(t, fOffset); // nowy wektor kierunku
|
||||
// parallel2=Normalize(CrossProduct(dir,vector3(0,1,0)));
|
||||
parallel2 = Normalize(vector3(-dir.z, 0.0, dir.x)); // wektor poprzeczny
|
||||
if (trapez)
|
||||
for (j = 0; j < iNumShapePoints; j++)
|
||||
{ // współrzędne początku
|
||||
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;
|
||||
pt = parallel1 * (jmm1 * (ShapePoints[j].x - fOffsetX) +
|
||||
m1 * ShapePoints[j + iNumShapePoints].x) +
|
||||
pos1;
|
||||
pt.y += jmm1 * ShapePoints[j].y + m1 * ShapePoints[j + iNumShapePoints].y;
|
||||
Vert->nx = norm.x; // niekoniecznie tak
|
||||
Vert->ny = norm.y;
|
||||
Vert->nz = norm.z;
|
||||
Vert->u = jmm1 * ShapePoints[j].z + m1 * ShapePoints[j + iNumShapePoints].z;
|
||||
Vert->v = tv1;
|
||||
Vert->x = pt.x;
|
||||
Vert->y = pt.y;
|
||||
Vert->z = pt.z; // punkt na początku odcinka
|
||||
Vert++;
|
||||
// dla trapezu drugi koniec ma inne współrzędne względne
|
||||
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;
|
||||
pt = parallel2 * (jmm2 * (ShapePoints[j].x - fOffsetX) +
|
||||
m2 * ShapePoints[j + iNumShapePoints].x) +
|
||||
pos2;
|
||||
pt.y += jmm2 * ShapePoints[j].y + m2 * ShapePoints[j + iNumShapePoints].y;
|
||||
Vert->nx = norm.x; // niekoniecznie tak
|
||||
Vert->ny = norm.y;
|
||||
Vert->nz = norm.z;
|
||||
Vert->u = jmm2 * ShapePoints[j].z + m2 * ShapePoints[j + iNumShapePoints].z;
|
||||
Vert->v = tv2;
|
||||
Vert->x = pt.x;
|
||||
Vert->y = pt.y;
|
||||
Vert->z = pt.z; // punkt na końcu odcinka
|
||||
Vert++;
|
||||
}
|
||||
else
|
||||
for (j = 0; j < iNumShapePoints; j++)
|
||||
{ // współrzędne początku
|
||||
norm = ShapePoints[j].n.x * parallel1;
|
||||
norm.y += ShapePoints[j].n.y;
|
||||
pt = parallel1 * (ShapePoints[j].x - fOffsetX) + pos1;
|
||||
pt.y += ShapePoints[j].y;
|
||||
Vert->nx = norm.x; // niekoniecznie tak
|
||||
Vert->ny = norm.y;
|
||||
Vert->nz = norm.z;
|
||||
Vert->u = ShapePoints[j].z;
|
||||
Vert->v = tv1;
|
||||
Vert->x = pt.x;
|
||||
Vert->y = pt.y;
|
||||
Vert->z = pt.z; // punkt na początku odcinka
|
||||
Vert++;
|
||||
norm = ShapePoints[j].n.x * parallel2;
|
||||
norm.y += ShapePoints[j].n.y;
|
||||
pt = parallel2 * ShapePoints[j].x + pos2;
|
||||
pt.y += ShapePoints[j].y;
|
||||
Vert->nx = norm.x; // niekoniecznie tak
|
||||
Vert->ny = norm.y;
|
||||
Vert->nz = norm.z;
|
||||
Vert->u = ShapePoints[j].z;
|
||||
Vert->v = tv2;
|
||||
Vert->x = pt.x;
|
||||
Vert->y = pt.y;
|
||||
Vert->z = pt.z; // punkt na końcu odcinka
|
||||
Vert++;
|
||||
}
|
||||
pos1 = pos2;
|
||||
parallel1 = parallel2;
|
||||
tv1 = tv2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // gdy prosty
|
||||
pos1 = FastGetPoint((fStep * iSkip) / fLength);
|
||||
pos2 = FastGetPoint_1();
|
||||
dir = GetDirection();
|
||||
// parallel1=Normalize(CrossProduct(dir,vector3(0,1,0)));
|
||||
parallel1 = Normalize(vector3(-dir.z, 0.0, dir.x)); // wektor poprzeczny
|
||||
if (trapez)
|
||||
for (j = 0; j < iNumShapePoints; j++)
|
||||
{
|
||||
norm = ShapePoints[j].n.x * parallel1;
|
||||
norm.y += ShapePoints[j].n.y;
|
||||
pt = parallel1 * (ShapePoints[j].x - fOffsetX) + pos1;
|
||||
pt.y += ShapePoints[j].y;
|
||||
Vert->nx = norm.x; // niekoniecznie tak
|
||||
Vert->ny = norm.y;
|
||||
Vert->nz = norm.z;
|
||||
Vert->u = ShapePoints[j].z;
|
||||
Vert->v = 0;
|
||||
Vert->x = pt.x;
|
||||
Vert->y = pt.y;
|
||||
Vert->z = pt.z; // punkt na początku odcinka
|
||||
Vert++;
|
||||
// dla trapezu drugi koniec ma inne współrzędne
|
||||
norm = ShapePoints[j + iNumShapePoints].n.x * parallel1;
|
||||
norm.y += ShapePoints[j + iNumShapePoints].n.y;
|
||||
pt = parallel1 * (ShapePoints[j + iNumShapePoints].x - fOffsetX) +
|
||||
pos2; // odsunięcie
|
||||
pt.y += ShapePoints[j + iNumShapePoints].y; // wysokość
|
||||
Vert->nx = norm.x; // niekoniecznie tak
|
||||
Vert->ny = norm.y;
|
||||
Vert->nz = norm.z;
|
||||
Vert->u = ShapePoints[j + iNumShapePoints].z;
|
||||
Vert->v = fLength / fTextureLength;
|
||||
Vert->x = pt.x;
|
||||
Vert->y = pt.y;
|
||||
Vert->z = pt.z; // punkt na końcu odcinka
|
||||
Vert++;
|
||||
}
|
||||
else
|
||||
for (j = 0; j < iNumShapePoints; j++)
|
||||
{
|
||||
norm = ShapePoints[j].n.x * parallel1;
|
||||
norm.y += ShapePoints[j].n.y;
|
||||
pt = parallel1 * (ShapePoints[j].x - fOffsetX) + pos1;
|
||||
pt.y += ShapePoints[j].y;
|
||||
Vert->nx = norm.x; // niekoniecznie tak
|
||||
Vert->ny = norm.y;
|
||||
Vert->nz = norm.z;
|
||||
Vert->u = ShapePoints[j].z;
|
||||
Vert->v = 0;
|
||||
Vert->x = pt.x;
|
||||
Vert->y = pt.y;
|
||||
Vert->z = pt.z; // punkt na początku odcinka
|
||||
Vert++;
|
||||
pt = parallel1 * (ShapePoints[j].x - fOffsetX) + pos2;
|
||||
pt.y += ShapePoints[j].y;
|
||||
Vert->nx = norm.x; // niekoniecznie tak
|
||||
Vert->ny = norm.y;
|
||||
Vert->nz = norm.z;
|
||||
Vert->u = ShapePoints[j].z;
|
||||
Vert->v = fLength / fTextureLength;
|
||||
Vert->x = pt.x;
|
||||
Vert->y = pt.y;
|
||||
Vert->z = pt.z; // punkt na końcu odcinka
|
||||
Vert++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void TSegment::RaAnimate(CVertNormTex *&Vert, const vector6 *ShapePoints, int iNumShapePoints,
|
||||
double fTextureLength, int iSkip, int iEnd, double fOffsetX)
|
||||
{ // jak wyżej, tylko z pominięciem mapowania i braku trapezowania
|
||||
vector3 pos1, pos2, dir, parallel1, parallel2, pt;
|
||||
double s, step, fOffset, t, fEnd;
|
||||
int i, j;
|
||||
bool trapez = iNumShapePoints < 0; // sygnalizacja trapezowatości
|
||||
iNumShapePoints = abs(iNumShapePoints);
|
||||
if (bCurve)
|
||||
{
|
||||
double m1, jmm1, m2, jmm2; // pozycje względne na odcinku 0...1 (ale nie parametr Beziera)
|
||||
step = fStep;
|
||||
s = fStep * iSkip; // iSkip - ile odcinków z początku pominąć
|
||||
i = iSkip; // domyślnie 0
|
||||
t = fTsBuffer[i]; // tabela wattości t dla segmentów
|
||||
fOffset = 0.1 / fLength; // pierwsze 10cm
|
||||
pos1 = FastGetPoint(t); // wektor początku segmentu
|
||||
dir = FastGetDirection(t, fOffset); // wektor kierunku
|
||||
// parallel1=Normalize(CrossProduct(dir,vector3(0,1,0))); //wektor prostopadły
|
||||
parallel1 = Normalize(vector3(-dir.z, 0.0, dir.x)); // wektor poprzeczny
|
||||
if (iEnd == 0)
|
||||
iEnd = iSegCount;
|
||||
fEnd = fLength * double(iEnd) / double(iSegCount);
|
||||
m2 = s / fEnd;
|
||||
jmm2 = 1.0 - m2;
|
||||
while (i < iEnd)
|
||||
{
|
||||
++i; // kolejny punkt łamanej
|
||||
s += step; // końcowa pozycja segmentu [m]
|
||||
m1 = m2;
|
||||
jmm1 = jmm2; // stara pozycja
|
||||
m2 = s / fEnd;
|
||||
jmm2 = 1.0 - m2; // nowa pozycja
|
||||
if (i == iEnd)
|
||||
{ // gdy przekroczyliśmy koniec - stąd dziury w torach...
|
||||
step -= (s - fEnd); // jeszcze do wyliczenia mapowania potrzebny
|
||||
s = fEnd;
|
||||
// i=iEnd; //20/5 ma dawać 4
|
||||
m2 = 1.0;
|
||||
jmm2 = 0.0;
|
||||
}
|
||||
t = fTsBuffer[i]; // szybsze od GetTFromS(s);
|
||||
pos2 = FastGetPoint(t);
|
||||
dir = FastGetDirection(t, fOffset); // nowy wektor kierunku
|
||||
// parallel2=Normalize(CrossProduct(dir,vector3(0,1,0)));
|
||||
parallel2 = Normalize(vector3(-dir.z, 0.0, dir.x)); // wektor poprzeczny
|
||||
if (trapez)
|
||||
for (j = 0; j < iNumShapePoints; j++)
|
||||
{ // współrzędne początku
|
||||
pt = parallel1 * (jmm1 * (ShapePoints[j].x - fOffsetX) +
|
||||
m1 * ShapePoints[j + iNumShapePoints].x) +
|
||||
pos1;
|
||||
pt.y += jmm1 * ShapePoints[j].y + m1 * ShapePoints[j + iNumShapePoints].y;
|
||||
Vert->x = pt.x;
|
||||
Vert->y = pt.y;
|
||||
Vert->z = pt.z; // punkt na początku odcinka
|
||||
Vert++;
|
||||
// dla trapezu drugi koniec ma inne współrzędne
|
||||
pt = parallel2 * (jmm2 * (ShapePoints[j].x - fOffsetX) +
|
||||
m2 * ShapePoints[j + iNumShapePoints].x) +
|
||||
pos2;
|
||||
pt.y += jmm2 * ShapePoints[j].y + m2 * ShapePoints[j + iNumShapePoints].y;
|
||||
Vert->x = pt.x;
|
||||
Vert->y = pt.y;
|
||||
Vert->z = pt.z; // punkt na końcu odcinka
|
||||
Vert++;
|
||||
}
|
||||
pos1 = pos2;
|
||||
parallel1 = parallel2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // gdy prosty
|
||||
pos1 = FastGetPoint((fStep * iSkip) / fLength);
|
||||
pos2 = FastGetPoint_1();
|
||||
dir = GetDirection();
|
||||
// parallel1=Normalize(CrossProduct(dir,vector3(0,1,0)));
|
||||
parallel1 = Normalize(vector3(-dir.z, 0.0, dir.x)); // wektor poprzeczny
|
||||
if (trapez)
|
||||
for (j = 0; j < iNumShapePoints; j++)
|
||||
{
|
||||
pt = parallel1 * (ShapePoints[j].x - fOffsetX) + pos1;
|
||||
pt.y += ShapePoints[j].y;
|
||||
Vert->x = pt.x;
|
||||
Vert->y = pt.y;
|
||||
Vert->z = pt.z; // punkt na początku odcinka
|
||||
Vert++;
|
||||
pt = parallel1 * (ShapePoints[j + iNumShapePoints].x - fOffsetX) +
|
||||
pos2; // odsunięcie
|
||||
pt.y += ShapePoints[j + iNumShapePoints].y; // wysokość
|
||||
Vert->x = pt.x;
|
||||
Vert->y = pt.y;
|
||||
Vert->z = pt.z; // punkt na końcu odcinka
|
||||
Vert++;
|
||||
}
|
||||
}
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
23
Segment.h
23
Segment.h
@@ -13,6 +13,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "VBO.h"
|
||||
#include "dumb3d.h"
|
||||
#include "Classes.h"
|
||||
#include "usefull.h"
|
||||
|
||||
using namespace Math3D;
|
||||
|
||||
@@ -61,8 +62,6 @@ class TSegment
|
||||
double fDirection = 0.0; // Ra: kąt prostego w planie; dla łuku kąt od Point1
|
||||
double fStoop = 0.0; // Ra: kąt wzniesienia; dla łuku od Point1
|
||||
vector3 vA, vB, vC; // współczynniki wielomianów trzeciego stopnia vD==Point1
|
||||
// TSegment *pPrev; //odcinek od strony punktu 1 - w segmencie, żeby nie skakać na zwrotnicach
|
||||
// TSegment *pNext; //odcinek od strony punktu 2
|
||||
TTrack *pOwner = nullptr; // wskaźnik na właściciela
|
||||
double fAngle[2]; // kąty zakończenia drogi na przejazdach
|
||||
|
||||
@@ -71,12 +70,8 @@ class TSegment
|
||||
double GetTFromS(double s);
|
||||
vector3 RaInterpolate(double t);
|
||||
vector3 RaInterpolate0(double t);
|
||||
// TSegment *segNeightbour[2]; //sąsiednie odcinki - musi być przeniesione z Track
|
||||
// int iNeightbour[2]; //do którego końca doczepiony
|
||||
public:
|
||||
bool bCurve = false;
|
||||
// int iShape; //Ra: flagi kształtu dadzą więcej możliwości optymalizacji
|
||||
// (0-Bezier,1-prosty,2/3-łuk w lewo/prawo,6/7-przejściowa w lewo/prawo)
|
||||
TSegment(TTrack *owner);
|
||||
~TSegment();
|
||||
bool Init(vector3 NewPoint1, vector3 NewPoint2, double fNewStep, double fNewRoll1 = 0,
|
||||
@@ -109,21 +104,16 @@ class TSegment
|
||||
{
|
||||
return Point2;
|
||||
};
|
||||
inline double GetRoll(double s)
|
||||
inline double GetRoll(double const Distance)
|
||||
{
|
||||
s /= fLength;
|
||||
return ((1.0 - s) * fRoll1 + s * fRoll2);
|
||||
return interpolate( fRoll1, fRoll2, Distance / fLength );
|
||||
}
|
||||
void GetRolls(double &r1, double &r2)
|
||||
{ // pobranie przechyłek (do generowania trójkątów)
|
||||
r1 = fRoll1;
|
||||
r2 = fRoll2;
|
||||
}
|
||||
void RenderLoft(const vector6 *ShapePoints, int iNumShapePoints, double fTextureLength,
|
||||
int iSkip = 0, int iQualityFactor = 1, vector3 **p = NULL, bool bRender = true);
|
||||
void RenderSwitchRail(const vector6 *ShapePoints1, const vector6 *ShapePoints2,
|
||||
int iNumShapePoints, double fTextureLength, int iSkip = 0,
|
||||
double fOffsetX = 0.0f);
|
||||
void RenderLoft( CVertNormTex* &Output, const vector6 *ShapePoints, int iNumShapePoints, double fTextureLength, double Texturescale = 1.0, int iSkip = 0, int iEnd = 0, double fOffsetX = 0.0, bool Onlypositions = false, vector3 **p = nullptr, bool bRender = true);
|
||||
void Render();
|
||||
inline double GetLength()
|
||||
{
|
||||
@@ -143,15 +133,10 @@ class TSegment
|
||||
{
|
||||
return fTsBuffer ? iSegCount : 1;
|
||||
};
|
||||
void RaRenderLoft(CVertNormTex *&Vert, const vector6 *ShapePoints, int iNumShapePoints,
|
||||
double fTextureLength, int iSkip = 0, int iEnd = 0, double fOffsetX = 0.0);
|
||||
void RaAnimate(CVertNormTex *&Vert, const vector6 *ShapePoints, int iNumShapePoints,
|
||||
double fTextureLength, int iSkip = 0, int iEnd = 0, double fOffsetX = 0.0);
|
||||
void AngleSet(int i, double a)
|
||||
{
|
||||
fAngle[i] = a;
|
||||
};
|
||||
void Rollment(double w1, double w2); // poprawianie przechyłki
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
8
dumb3d.h
8
dumb3d.h
@@ -104,14 +104,8 @@ class vector3
|
||||
return &x;
|
||||
}
|
||||
|
||||
// union
|
||||
// {
|
||||
// struct
|
||||
// {
|
||||
double x, y, z;
|
||||
// };
|
||||
// scalar_t e[3];
|
||||
// };
|
||||
|
||||
bool inline Equal(vector3 *v)
|
||||
{ // sprawdzenie odległości punktów
|
||||
if (std::fabs(x - v->x) > 0.02)
|
||||
|
||||
305
renderer.cpp
305
renderer.cpp
@@ -11,8 +11,11 @@ http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include "renderer.h"
|
||||
#include "globals.h"
|
||||
#include "timer.h"
|
||||
#include "world.h"
|
||||
#include "dynobj.h"
|
||||
#include "animmodel.h"
|
||||
#include "traction.h"
|
||||
#include "uilayer.h"
|
||||
#include "logs.h"
|
||||
#include "usefull.h"
|
||||
@@ -31,11 +34,11 @@ bool
|
||||
opengl_camera::visible( TDynamicObject const *Dynamic ) const {
|
||||
|
||||
// sphere test is faster than AABB, so we'll use it here
|
||||
float3 diagonal(
|
||||
Dynamic->MoverParameters->Dim.L,
|
||||
Dynamic->MoverParameters->Dim.H,
|
||||
Dynamic->MoverParameters->Dim.W );
|
||||
float const radius = diagonal.Length() * 0.5f;
|
||||
glm::vec3 diagonal(
|
||||
static_cast<float>( Dynamic->MoverParameters->Dim.L ),
|
||||
static_cast<float>( Dynamic->MoverParameters->Dim.H ),
|
||||
static_cast<float>( Dynamic->MoverParameters->Dim.W ) );
|
||||
float const radius = glm::length( diagonal ) * 0.5f;
|
||||
|
||||
return ( m_frustum.sphere_inside( Dynamic->GetPosition(), radius ) > 0.0f );
|
||||
}
|
||||
@@ -183,7 +186,7 @@ opengl_renderer::Render( world_environment *Environment ) {
|
||||
if( Global::fFogEnd > 0 ) {
|
||||
// fog setup
|
||||
::glFogfv( GL_FOG_COLOR, Global::FogColor );
|
||||
::glFogf( GL_FOG_DENSITY, 1.0f / Global::fFogEnd );
|
||||
::glFogf( GL_FOG_DENSITY, static_cast<GLfloat>( 1.0 / Global::fFogEnd ) );
|
||||
::glEnable( GL_FOG );
|
||||
}
|
||||
else { ::glDisable( GL_FOG ); }
|
||||
@@ -236,7 +239,7 @@ opengl_renderer::Render( world_environment *Environment ) {
|
||||
{
|
||||
Bind( m_moontextureid );
|
||||
float3 mooncolor( 255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f );
|
||||
::glColor4f( mooncolor.x, mooncolor.y, mooncolor.z, 1.0f - Global::fLuminance * 0.5f );
|
||||
::glColor4f( mooncolor.x, mooncolor.y, mooncolor.z, static_cast<GLfloat>( 1.0 - Global::fLuminance * 0.5 ) );
|
||||
|
||||
auto const moonvector = Environment->m_moon.getDirection();
|
||||
auto const moonposition = modelview * glm::vec4( moonvector.x, moonvector.y, moonvector.z, 1.0f );
|
||||
@@ -296,9 +299,9 @@ opengl_renderer::Render( TGround *Ground ) {
|
||||
glEnable( GL_LIGHTING );
|
||||
glColor3f( 1.0f, 1.0f, 1.0f );
|
||||
|
||||
float3 const cameraposition = float3( Global::pCameraPosition.x, Global::pCameraPosition.y, Global::pCameraPosition.z );
|
||||
int const camerax = std::floor( cameraposition.x / 1000.0f ) + iNumRects / 2;
|
||||
int const cameraz = std::floor( cameraposition.z / 1000.0f ) + iNumRects / 2;
|
||||
glm::vec3 const cameraposition( Global::pCameraPosition.x, Global::pCameraPosition.y, Global::pCameraPosition.z );
|
||||
int const camerax = static_cast<int>( std::floor( cameraposition.x / 1000.0f ) + iNumRects / 2 );
|
||||
int const cameraz = static_cast<int>( std::floor( cameraposition.z / 1000.0f ) + iNumRects / 2 );
|
||||
int const segmentcount = 2 * static_cast<int>(std::ceil( m_drawrange * Global::fDistanceFactor / 1000.0f ));
|
||||
int const originx = std::max( 0, camerax - segmentcount / 2 );
|
||||
int const originz = std::max( 0, cameraz - segmentcount / 2 );
|
||||
@@ -317,15 +320,133 @@ opengl_renderer::Render( TGround *Ground ) {
|
||||
}
|
||||
|
||||
bool
|
||||
opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
||||
opengl_renderer::Render( TGroundNode *Node ) {
|
||||
|
||||
if( false == m_camera.visible( Dynamic ) ) {
|
||||
Node->SetLastUsage( Timer::GetSimulationTime() );
|
||||
|
||||
Dynamic->renderme = false;
|
||||
switch (Node->iType)
|
||||
{ // obiekty renderowane niezależnie od odległości
|
||||
case TP_SUBMODEL:
|
||||
TSubModel::fSquareDist = 0;
|
||||
Render( Node->smTerrain );
|
||||
return true;
|
||||
}
|
||||
|
||||
double const distancesquared = SquareMagnitude( ( Node->pCenter - Global::pCameraPosition ) / Global::ZoomFactor );
|
||||
if( ( distancesquared > ( Node->fSquareRadius * Global::fDistanceFactor ) )
|
||||
|| ( distancesquared < ( Node->fSquareMinRadius / Global::fDistanceFactor ) ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Dynamic->renderme = true;
|
||||
switch (Node->iType)
|
||||
{
|
||||
case TP_TRACK: {
|
||||
// TODO: unify the render code after generic buffers are in place
|
||||
if( Global::bUseVBO ) {
|
||||
if( Node->iNumVerts ) {
|
||||
Node->pTrack->RaRenderVBO( Node->iVboPtr );
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Node->pTrack->Render();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case TP_MODEL: {
|
||||
Node->Model->Render( &Node->pCenter );
|
||||
return true;
|
||||
}
|
||||
case TP_MEMCELL: {
|
||||
GfxRenderer.Render( Node->MemCell );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: sprawdzic czy jest potrzebny warunek fLineThickness < 0
|
||||
if( ( Node->iFlags & 0x10 )
|
||||
|| ( Node->fLineThickness < 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();
|
||||
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
|
||||
::glColor4ub(
|
||||
static_cast<GLubyte>( std::floor( Node->Diffuse[ 0 ] * Global::DayLight.ambient[ 0 ] ) ),
|
||||
static_cast<GLubyte>( std::floor( Node->Diffuse[ 1 ] * Global::DayLight.ambient[ 1 ] ) ),
|
||||
static_cast<GLubyte>( std::floor( Node->Diffuse[ 2 ] * Global::DayLight.ambient[ 2 ] ) ),
|
||||
static_cast<GLubyte>( std::min( 255.0, 255000 * 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 );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// GL_TRIANGLE etc
|
||||
// setup
|
||||
::glColor3ub(
|
||||
static_cast<GLubyte>( Node->Diffuse[ 0 ] ),
|
||||
static_cast<GLubyte>( Node->Diffuse[ 1 ] ),
|
||||
static_cast<GLubyte>( Node->Diffuse[ 2 ] ) );
|
||||
|
||||
Bind( Node->TextureID );
|
||||
|
||||
// render
|
||||
// TODO: unify the render code after generic buffers are in place
|
||||
if( Global::bUseVBO ) {
|
||||
// vbo render path
|
||||
if( Node->iVboPtr >= 0 ) {
|
||||
::glDrawArrays( Node->iType, Node->iVboPtr, Node->iNumVerts );
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// display list render path
|
||||
::glCallList( Node->DisplayListID );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// in theory we shouldn't ever get here but, eh
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
||||
|
||||
Dynamic->renderme = m_camera.visible( Dynamic );
|
||||
if( false == Dynamic->renderme ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// setup
|
||||
TSubModel::iInstance = ( size_t )this; //żeby nie robić cudzych animacji
|
||||
@@ -517,7 +638,7 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
||||
float const anglefactor = ( Submodel->fCosViewAngle - Submodel->fCosFalloffAngle ) / ( 1.0f - Submodel->fCosFalloffAngle );
|
||||
// distance attenuation. NOTE: since it's fixed pipeline with built-in gamma correction we're using linear attenuation
|
||||
// we're capping how much effect the distance attenuation can have, otherwise the lights get too tiny at regular distances
|
||||
float const distancefactor = std::max( 0.5, ( Submodel->fSquareMaxDist - TSubModel::fSquareDist ) / ( Submodel->fSquareMaxDist * Global::fDistanceFactor ) );
|
||||
float const distancefactor = static_cast<float>( std::max( 0.5, ( Submodel->fSquareMaxDist - TSubModel::fSquareDist ) / ( Submodel->fSquareMaxDist * Global::fDistanceFactor ) ) );
|
||||
|
||||
if( lightlevel > 0.0f ) {
|
||||
// material configuration:
|
||||
@@ -609,6 +730,146 @@ opengl_renderer::Render( TMemCell *Memcell ) {
|
||||
::glPopAttrib();
|
||||
}
|
||||
|
||||
// NOTE: legacy render system switch
|
||||
#define _PROBLEND
|
||||
|
||||
bool
|
||||
opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
||||
|
||||
// SPOSOB NA POZBYCIE SIE RAMKI DOOKOLA TEXTURY ALPHA DLA OBIEKTOW ZAGNIEZDZONYCH W SCN JAKO
|
||||
// NODE
|
||||
|
||||
// W GROUND.H dajemy do klasy TGroundNode zmienna bool PROBLEND to samo robimy w klasie TGround
|
||||
// nastepnie podczas wczytywania textury dla TRIANGLES w TGround::AddGroundNode
|
||||
// sprawdzamy czy w nazwie jest @ i wg tego
|
||||
// ustawiamy PROBLEND na true dla wlasnie wczytywanego trojkata (kazdy trojkat jest osobnym
|
||||
// nodem)
|
||||
// nastepnie podczas renderowania w bool TGroundNode::RenderAlpha()
|
||||
// na poczatku ustawiamy standardowe GL_GREATER = 0.04
|
||||
// pozniej sprawdzamy czy jest wlaczony PROBLEND dla aktualnie renderowanego noda TRIANGLE,
|
||||
// wlasciwie dla kazdego node'a
|
||||
// i jezeli tak to odpowiedni GL_GREATER w przeciwnym wypadku standardowy 0.04
|
||||
|
||||
Node->SetLastUsage( Timer::GetSimulationTime() );
|
||||
|
||||
double const distancesquared = SquareMagnitude( ( Node->pCenter - Global::pCameraPosition ) / Global::ZoomFactor );
|
||||
if( ( distancesquared > ( Node->fSquareRadius * Global::fDistanceFactor ) )
|
||||
|| ( distancesquared < ( Node->fSquareMinRadius / Global::fDistanceFactor ) ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (Node->iType)
|
||||
{
|
||||
case TP_TRACTION: {
|
||||
// TODO: unify the render code after generic buffers are in place
|
||||
if( Node->bVisible ) {
|
||||
if( Global::bUseVBO ) {
|
||||
Node->hvTraction->RenderVBO( distancesquared, Node->iVboPtr );
|
||||
}
|
||||
else {
|
||||
Node->hvTraction->RenderDL( distancesquared );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
case TP_MODEL: {
|
||||
Node->Model->RenderAlpha( &Node->pCenter );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: sprawdzic czy jest potrzebny warunek fLineThickness < 0
|
||||
if( ( Node->iNumVerts && ( Node->iFlags & 0x20 ) )
|
||||
|| ( Node->iNumPts && ( Node->fLineThickness > 0 ) ) ) {
|
||||
|
||||
#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();
|
||||
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
|
||||
// w zaleznosci od koloru swiatla
|
||||
::glColor4ub(
|
||||
static_cast<GLubyte>( std::floor( Node->Diffuse[ 0 ] * Global::DayLight.ambient[ 0 ] ) ),
|
||||
static_cast<GLubyte>( std::floor( Node->Diffuse[ 1 ] * Global::DayLight.ambient[ 1 ] ) ),
|
||||
static_cast<GLubyte>( std::floor( Node->Diffuse[ 2 ] * Global::DayLight.ambient[ 2 ] ) ),
|
||||
static_cast<GLubyte>( std::min( 255.0, 255000 * 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 );
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// GL_TRIANGLE etc
|
||||
// setup
|
||||
::glColor3ub(
|
||||
static_cast<GLubyte>( Node->Diffuse[ 0 ] ),
|
||||
static_cast<GLubyte>( Node->Diffuse[ 1 ] ),
|
||||
static_cast<GLubyte>( Node->Diffuse[ 2 ] ) );
|
||||
|
||||
Bind( Node->TextureID );
|
||||
|
||||
// render
|
||||
// TODO: unify the render code after generic buffers are in place
|
||||
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
|
||||
#ifdef _PROBLEND
|
||||
if( ( Node->PROBLEND ) ) // sprawdza, czy w nazwie nie ma @ //Q: 13122011 - Szociu: 27012012
|
||||
{
|
||||
::glEnable( GL_BLEND );
|
||||
::glAlphaFunc( GL_GREATER, 0.04f );
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
// in theory we shouldn't ever get here but, eh
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
|
||||
|
||||
@@ -978,12 +1239,12 @@ opengl_renderer::Update_Lights( light_array const &Lights ) {
|
||||
if( environment > 0.0f ) {
|
||||
luminance *= environment;
|
||||
}
|
||||
renderlight->diffuse[ 0 ] = std::max( 0.0, scenelight.color.x - luminance );
|
||||
renderlight->diffuse[ 1 ] = std::max( 0.0, scenelight.color.y - luminance );
|
||||
renderlight->diffuse[ 2 ] = std::max( 0.0, scenelight.color.z - luminance );
|
||||
renderlight->ambient[ 0 ] = std::max( 0.0, scenelight.color.x * scenelight.intensity - luminance);
|
||||
renderlight->ambient[ 1 ] = std::max( 0.0, scenelight.color.y * scenelight.intensity - luminance );
|
||||
renderlight->ambient[ 2 ] = std::max( 0.0, scenelight.color.z * scenelight.intensity - luminance );
|
||||
renderlight->diffuse[ 0 ] = static_cast<GLfloat>( std::max( 0.0, scenelight.color.x - luminance ) );
|
||||
renderlight->diffuse[ 1 ] = static_cast<GLfloat>( std::max( 0.0, scenelight.color.y - luminance ) );
|
||||
renderlight->diffuse[ 2 ] = static_cast<GLfloat>( std::max( 0.0, scenelight.color.z - luminance ) );
|
||||
renderlight->ambient[ 0 ] = static_cast<GLfloat>( std::max( 0.0, scenelight.color.x * scenelight.intensity - luminance) );
|
||||
renderlight->ambient[ 1 ] = static_cast<GLfloat>( std::max( 0.0, scenelight.color.y * scenelight.intensity - luminance ) );
|
||||
renderlight->ambient[ 2 ] = static_cast<GLfloat>( std::max( 0.0, scenelight.color.z * scenelight.intensity - luminance ) );
|
||||
/*
|
||||
// NOTE: we have no simple way to determine whether the lights are falling on objects located in darker environment
|
||||
// until this issue is resolved we're disabling reduction of light strenght based on the global luminance
|
||||
@@ -994,7 +1255,7 @@ opengl_renderer::Update_Lights( light_array const &Lights ) {
|
||||
renderlight->ambient[ 1 ] = std::max( 0.0f, scenelight.color.y * scenelight.intensity );
|
||||
renderlight->ambient[ 2 ] = std::max( 0.0f, scenelight.color.z * scenelight.intensity );
|
||||
*/
|
||||
::glLightf( renderlight->id, GL_LINEAR_ATTENUATION, (0.25f * scenelight.count) / std::pow( scenelight.count, 2 ) * (scenelight.owner->DimHeadlights ? 1.25f : 1.0f) );
|
||||
::glLightf( renderlight->id, GL_LINEAR_ATTENUATION, static_cast<GLfloat>( (0.25 * scenelight.count) / std::pow( scenelight.count, 2 ) * (scenelight.owner->DimHeadlights ? 1.25 : 1.0) ) );
|
||||
::glEnable( renderlight->id );
|
||||
|
||||
renderlight->apply_intensity();
|
||||
|
||||
@@ -124,6 +124,8 @@ public:
|
||||
Render( world_environment *Environment );
|
||||
bool
|
||||
Render( TGround *Ground );
|
||||
bool
|
||||
Render( TGroundNode *Node );
|
||||
bool
|
||||
Render( TDynamicObject *Dynamic );
|
||||
bool
|
||||
@@ -134,6 +136,8 @@ public:
|
||||
Render( TSubModel *Submodel );
|
||||
void
|
||||
Render( TMemCell *Memcell );
|
||||
bool
|
||||
Render_Alpha( TGroundNode *Node );
|
||||
bool
|
||||
Render_Alpha( TDynamicObject *Dynamic );
|
||||
bool
|
||||
|
||||
Reference in New Issue
Block a user