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

point light distance attenuation, partial unification of vbo/dl render paths

This commit is contained in:
tmj-fstate
2017-03-25 02:00:31 +01:00
parent df60a5230d
commit f8673a9f41
12 changed files with 562 additions and 569 deletions

View File

@@ -686,27 +686,19 @@ int TAnimModel::Flags()
//-----------------------------------------------------------------------------
// 2011-03-16 cztery nowe funkcje renderowania z możliwością pochylania obiektów
//-----------------------------------------------------------------------------
#ifdef EU07_USE_OLD_RENDERCODE
void TAnimModel::RenderDL(vector3 *vPosition)
{
RaAnimate(); // jednorazowe przeliczenie animacji
RaPrepare();
if( pModel ) // renderowanie rekurencyjne submodeli
#ifdef EU07_USE_OLD_RENDERCODE
pModel->Render(vPosition, &vAngle, ReplacableSkinId, iTexAlpha);
#else
GfxRenderer.Render( pModel, Material(), *vPosition, vAngle );
#endif
};
void TAnimModel::RenderAlphaDL(vector3 *vPosition)
{
RaPrepare();
if (pModel) // renderowanie rekurencyjne submodeli
#ifdef EU07_USE_OLD_RENDERCODE
pModel->RenderAlpha(vPosition, &vAngle, ReplacableSkinId, iTexAlpha);
#else
GfxRenderer.Render_Alpha( pModel, Material(), *vPosition, vAngle );
#endif
};
void TAnimModel::RenderVBO(vector3 *vPosition)
@@ -714,15 +706,27 @@ void TAnimModel::RenderVBO(vector3 *vPosition)
RaAnimate(); // jednorazowe przeliczenie animacji
RaPrepare();
if (pModel) // renderowanie rekurencyjne submodeli
pModel->RaRender(vPosition, &vAngle, Material()->replacable_skins, Material()->textures_alpha);
pModel->RaRender( vPosition, &vAngle, Material()->replacable_skins, Material()->textures_alpha );
};
void TAnimModel::RenderAlphaVBO(vector3 *vPosition)
{
RaPrepare();
if (pModel) // renderowanie rekurencyjne submodeli
pModel->RaRenderAlpha(vPosition, &vAngle, Material()->replacable_skins, Material()->textures_alpha);
pModel->RaRenderAlpha( vPosition, &vAngle, Material()->replacable_skins, Material()->textures_alpha );
};
#else
void TAnimModel::Render( vector3 *vPosition ) {
RaAnimate(); // jednorazowe przeliczenie animacji
RaPrepare();
if( pModel ) // renderowanie rekurencyjne submodeli
GfxRenderer.Render( pModel, Material(), *vPosition, vAngle );
};
void TAnimModel::RenderAlpha( vector3 *vPosition ) {
RaPrepare();
if( pModel ) // renderowanie rekurencyjne submodeli
GfxRenderer.Render_Alpha( pModel, Material(), *vPosition, vAngle );
};
#endif
//---------------------------------------------------------------------------
bool TAnimModel::TerrainLoaded()

View File

@@ -175,10 +175,16 @@ class TAnimModel
void RenderAlphaDL(vector3 pPosition = vector3(0, 0, 0), double fAngle = 0);
void RenderVBO(vector3 pPosition = vector3(0, 0, 0), double fAngle = 0);
void RenderAlphaVBO(vector3 pPosition = vector3(0, 0, 0), double fAngle = 0);
*/ void RenderDL(vector3 *vPosition);
*/
#ifdef EU07_USE_OLD_RENDERCODE
void RenderDL( vector3 *vPosition );
void RenderAlphaDL(vector3 *vPosition);
void RenderVBO(vector3 *vPosition);
void RenderAlphaVBO(vector3 *vPosition);
#else
void Render( vector3 *vPosition );
void RenderAlpha( vector3 *vPosition );
#endif
int Flags();
void RaAnglesSet(double a, double b, double c)
{

View File

@@ -289,161 +289,145 @@ void TGroundNode::RaRenderVBO()
glDrawArrays(iType, iVboPtr, iNumVerts); // Narysuj naraz wszystkie trójkąty
}
void TGroundNode::RenderVBO()
{ // renderowanie obiektu z VBO - faza nieprzezroczystych
double mgn = SquareMagnitude(pCenter - Global::pCameraPosition);
if ((mgn > fSquareRadius || (mgn < fSquareMinRadius)) &&
(iType != TP_EVLAUNCH)) // McZapkie-070602: nie rysuj odleglych obiektow ale sprawdzaj
// wyzwalacz zdarzen
return;
switch (iType)
{
case TP_TRACTION:
return;
case TP_TRACK:
if (iNumVerts)
pTrack->RaRenderVBO(iVboPtr);
return;
case TP_MODEL:
Model->RenderVBO(&pCenter);
return;
// case TP_SOUND: //McZapkie - dzwiek zapetlony w zaleznosci od odleglosci
// if ((pStaticSound->GetStatus()&DSBSTATUS_PLAYING)==DSBPLAY_LOOPING)
// {
// pStaticSound->Play(1,DSBPLAY_LOOPING,true,pStaticSound->vSoundPosition);
// pStaticSound->AdjFreq(1.0,Timer::GetDeltaTime());
// }
// return; //Ra: TODO sprawdzić, czy dźwięki nie są tylko w RenderHidden
case TP_MEMCELL:
return;
case TP_EVLAUNCH:
if (EvLaunch->Render())
if ((EvLaunch->dRadius < 0) || (mgn < EvLaunch->dRadius))
{
if (Global::shiftState && EvLaunch->Event2 != NULL)
Global::AddToQuery(EvLaunch->Event2, NULL);
else if (EvLaunch->Event1 != NULL)
Global::AddToQuery(EvLaunch->Event1, NULL);
}
return;
case GL_LINES:
case GL_LINE_STRIP:
case GL_LINE_LOOP:
if (iNumPts)
{
float linealpha = 255000 * fLineThickness / (mgn + 1.0);
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 ] );
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
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 ] );
GfxRenderer.Render( smTerrain );
#endif
glColor4ub(r, g, b, linealpha); // przezroczystosc dalekiej linii
// glDisable(GL_LIGHTING); //nie powinny świecić
glDrawArrays(iType, iVboPtr, iNumPts); // rysowanie linii
// glEnable(GL_LIGHTING);
}
}
double distancesquared = SquareMagnitude( pCenter - Global::pCameraPosition ) / Global::ZoomFactor;
if( ( distancesquared > ( fSquareRadius * Global::fDistanceFactor ) )
|| ( distancesquared < ( fSquareMinRadius / Global::fDistanceFactor ) ) ) {
return;
default:
if (iVboPtr >= 0)
RaRenderVBO();
};
return;
}
switch( iType ) {
case TP_TRACK: {
if( iNumVerts )
pTrack->RaRenderVBO( iVboPtr );
return;
}
case TP_MODEL: {
Model->Render( &pCenter );
return;
}
}
if( ( iFlags & 0x10 ) || ( fLineThickness < 0 ) ) {
if( ( iType == GL_LINES ) || ( iType == GL_LINE_STRIP ) || ( iType == GL_LINE_LOOP ) ) {
if( iNumPts ) {
float linealpha = 255000 * fLineThickness / ( distancesquared + 1.0 );
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
// glDisable(GL_LIGHTING); //nie powinny świecić
glDrawArrays( iType, iVboPtr, iNumPts ); // rysowanie linii
// glEnable(GL_LIGHTING);
}
}
// GL_TRIANGLE etc
else {
if( iVboPtr >= 0 ) {
RaRenderVBO();
}
}
SetLastUsage( Timer::GetSimulationTime() );
}
};
void TGroundNode::RenderAlphaVBO()
{ // renderowanie obiektu z VBO - faza przezroczystych
double mgn = SquareMagnitude(pCenter - Global::pCameraPosition);
float r, g, b;
if (mgn < fSquareMinRadius)
double distancesquared = SquareMagnitude( pCenter - Global::pCameraPosition ) / Global::ZoomFactor;
if( ( distancesquared > ( fSquareRadius * Global::fDistanceFactor ) )
|| ( distancesquared < ( fSquareMinRadius / Global::fDistanceFactor ) ) ) {
return;
if (mgn > fSquareRadius)
return;
#ifdef _PROBLEND
if ((PROBLEND)) // sprawdza, czy w nazwie nie ma @ //Q: 13122011 - Szociu: 27012012
{
glDisable(GL_BLEND);
glAlphaFunc(GL_GREATER, 0.45f); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f
};
#endif
switch (iType)
{
case TP_TRACTION:
if (bVisible)
{
#ifdef _PROBLEND
glEnable(GL_BLEND);
glAlphaFunc(GL_GREATER, 0.04f);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#endif
hvTraction->RenderVBO(mgn, iVboPtr);
}
switch( iType ) {
case TP_TRACTION: {
if( bVisible ) {
hvTraction->RenderVBO( distancesquared, iVboPtr );
}
return;
}
return;
case TP_MODEL:
#ifdef _PROBLEND
glEnable(GL_BLEND);
glAlphaFunc(GL_GREATER, 0.04f);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#endif
Model->RenderAlphaVBO(&pCenter);
return;
case GL_LINES:
case GL_LINE_STRIP:
case GL_LINE_LOOP:
if (iNumPts)
{
float linealpha = 255000 * fLineThickness / (mgn + 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
r = Diffuse[ 0 ] * Global::DayLight.ambient[ 0 ]; // w zaleznosci od koloru swiatla
g = Diffuse[ 1 ] * Global::DayLight.ambient[ 1 ];
b = Diffuse[ 2 ] * Global::DayLight.ambient[ 2 ];
#endif
glColor4ub(r, g, b, linealpha); // przezroczystosc dalekiej linii
// glDisable(GL_LIGHTING); //nie powinny świecić
glDrawArrays(iType, iVboPtr, iNumPts); // rysowanie linii
// glEnable(GL_LIGHTING);
#ifdef _PROBLEND
glEnable(GL_BLEND);
glAlphaFunc(GL_GREATER, 0.04f);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#endif
}
#ifdef _PROBLEND
glEnable(GL_BLEND);
glAlphaFunc(GL_GREATER, 0.04f);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#endif
return;
default:
if (iVboPtr >= 0)
{
RaRenderVBO();
#ifdef _PROBLEND
glEnable(GL_BLEND);
glAlphaFunc(GL_GREATER, 0.04f);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#endif
case TP_MODEL: {
Model->RenderAlpha( &pCenter );
return;
}
}
// TODO: sprawdzic czy jest potrzebny warunek fLineThickness < 0
if( ( iNumVerts && ( iFlags & 0x20 ) )
|| ( iNumPts && ( fLineThickness > 0 ) ) ) {
#ifdef _PROBLEND
glEnable(GL_BLEND);
glAlphaFunc(GL_GREATER, 0.04f);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if( ( PROBLEND ) ) // sprawdza, czy w nazwie nie ma @ //Q: 13122011 - Szociu: 27012012
{
glDisable( GL_BLEND );
glAlphaFunc( GL_GREATER, 0.45f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f
};
#endif
if( ( iType == GL_LINES )
|| ( iType == GL_LINE_STRIP )
|| ( iType == GL_LINE_LOOP ) ) {
if( iNumPts ) {
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
glDrawArrays( iType, iVboPtr, iNumPts ); // rysowanie linii
}
}
else {
if( iVboPtr >= 0 ) {
RaRenderVBO();
}
}
SetLastUsage( Timer::GetSimulationTime() );
}
#ifdef _PROBLEND
if( ( PROBLEND ) ) // sprawdza, czy w nazwie nie ma @ //Q: 13122011 - Szociu: 27012012
{
glEnable( GL_BLEND );
glAlphaFunc( GL_GREATER, 0.04f );
}
#endif
return;
}
void TGroundNode::Compile(bool many)
@@ -577,21 +561,26 @@ void TGroundNode::RenderDL()
GfxRenderer.Render( smTerrain );
#endif
}
// if (pTriGroup) if (pTriGroup!=this) return; //wyświetla go inny obiekt
double mgn = SquareMagnitude(pCenter - Global::pCameraPosition) / Global::ZoomFactor;
if ((mgn > fSquareRadius) || (mgn < fSquareMinRadius)) // McZapkie-070602: nie rysuj odleglych
// obiektow ale sprawdzaj wyzwalacz
// zdarzen
double distancesquared = SquareMagnitude(pCenter - Global::pCameraPosition) / Global::ZoomFactor;
if( ( distancesquared > ( fSquareRadius * Global::fDistanceFactor ) )
|| ( distancesquared < ( fSquareMinRadius / Global::fDistanceFactor ) ) ) {
return;
}
switch (iType)
{
case TP_TRACK:
return pTrack->Render();
case TP_MODEL:
return Model->RenderDL(&pCenter);
case TP_TRACK: {
pTrack->Render();
return;
}
case TP_MODEL: {
Model->Render( &pCenter );
return;
}
}
// TODO: sprawdzic czy jest potrzebny warunek fLineThickness < 0
// if ((iNumVerts&&(iFlags&0x10))||(iNumPts&&(fLineThickness<0)))
if ((iFlags & 0x10) || (fLineThickness < 0))
{
if (!DisplayListID || (iVersion != Global::iReCompile)) // Ra: wymuszenie rekompilacji
@@ -602,26 +591,31 @@ void TGroundNode::RenderDL()
};
if ((iType == GL_LINES) || (iType == GL_LINE_STRIP) || (iType == GL_LINE_LOOP))
// if (iNumPts)
{ // wszelkie linie są rysowane na samym końcu
float r, g, b;
if( iNumPts ) {
float linealpha = 255000 * fLineThickness / ( distancesquared + 1.0 );
if( linealpha > 255 )
linealpha = 255;
float r, g, b;
#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 ];
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 = Diffuse[ 0 ] * Global::DayLight.ambient[ 0 ]; // w zaleznosci od koloru swiatla
g = Diffuse[ 1 ] * Global::DayLight.ambient[ 1 ];
b = Diffuse[ 2 ] * Global::DayLight.ambient[ 2 ];
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, 1.0);
glCallList(DisplayListID);
// glColor4fv(Diffuse); //przywrócenie koloru
// glColor3ub(Diffuse[0],Diffuse[1],Diffuse[2]);
glColor4ub( r, g, b, linealpha ); // przezroczystosc dalekiej linii
glCallList( DisplayListID );
}
}
// GL_TRIANGLE etc
else
glCallList(DisplayListID);
SetLastUsage(Timer::GetSimulationTime());
};
};
@@ -642,30 +636,28 @@ void TGroundNode::RenderAlphaDL()
// wlasciwie dla kazdego node'a
// i jezeli tak to odpowiedni GL_GREATER w przeciwnym wypadku standardowy 0.04
// if (pTriGroup) if (pTriGroup!=this) return; //wyświetla go inny obiekt
double mgn = SquareMagnitude(pCenter - Global::pCameraPosition) / Global::ZoomFactor;
float r, g, b;
if (mgn < fSquareMinRadius)
return;
if (mgn > fSquareRadius)
return;
switch (iType)
{
case TP_TRACTION:
if (bVisible)
hvTraction->RenderDL(mgn);
return;
case TP_MODEL:
Model->RenderAlphaDL(&pCenter);
return;
case TP_TRACK:
// pTrack->RenderAlpha();
double distancesquared = SquareMagnitude( pCenter - Global::pCameraPosition ) / Global::ZoomFactor;
if( ( distancesquared > ( fSquareRadius * Global::fDistanceFactor ) )
|| ( distancesquared < ( fSquareMinRadius / Global::fDistanceFactor ) ) ) {
return;
}
switch( iType ) {
case TP_TRACTION: {
if( bVisible )
hvTraction->RenderDL( distancesquared );
return;
}
case TP_MODEL: {
Model->RenderAlpha( &pCenter );
return;
}
};
// TODO: sprawdzic czy jest potrzebny warunek fLineThickness < 0
if ((iNumVerts && (iFlags & 0x20)) || (iNumPts && (fLineThickness > 0)))
{
if( ( iNumVerts && ( iFlags & 0x20 ) )
|| ( iNumPts && ( fLineThickness > 0 ) ) ) {
#ifdef _PROBLEND
if ((PROBLEND)) // sprawdza, czy w nazwie nie ma @ //Q: 13122011 - Szociu: 27012012
{
@@ -680,35 +672,43 @@ void TGroundNode::RenderAlphaDL()
ResourceManager::Register(this);
};
// GL_LINE, GL_LINE_STRIP, GL_LINE_LOOP
if (iNumPts)
{
float linealpha = 255000 * fLineThickness / (mgn + 1.0);
if (linealpha > 255)
linealpha = 255;
if( ( iType == GL_LINES )
|| ( iType == GL_LINE_STRIP )
|| ( iType == GL_LINE_LOOP ) ) {
if( iNumPts ) {
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 ];
r = Diffuse[ 0 ] * Global::ambientDayLight[ 0 ]; // w zaleznosci od koloru swiatla
g = Diffuse[ 1 ] * Global::ambientDayLight[ 1 ];
b = Diffuse[ 2 ] * Global::ambientDayLight[ 2 ];
#else
r = Diffuse[ 0 ] * Global::DayLight.ambient[ 0 ]; // w zaleznosci od koloru swiatla
g = Diffuse[ 1 ] * Global::DayLight.ambient[ 1 ];
b = Diffuse[ 2 ] * Global::DayLight.ambient[ 2 ];
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
glCallList(DisplayListID);
glColor4ub( r, g, b, linealpha ); // przezroczystosc dalekiej linii
glCallList( DisplayListID );
}
}
// GL_TRIANGLE etc
else
glCallList(DisplayListID);
else {
glCallList( DisplayListID );
}
SetLastUsage(Timer::GetSimulationTime());
};
}
#ifdef _PROBLEND
if ((PROBLEND)) // sprawdza, czy w nazwie nie ma @ //Q: 13122011 - Szociu: 27012012
{
glEnable(GL_BLEND);
glAlphaFunc(GL_GREATER, 0.04f);
};
}
#endif
}

View File

@@ -646,7 +646,6 @@ void TSubModel::DisplayLists()
{
uiDisplayList = glGenLists(1);
glNewList(uiDisplayList, GL_COMPILE);
glColor3fv(f4Diffuse); // McZapkie-240702: zamiast ub
#ifdef USE_VERTEX_ARRAYS
// ShaXbee-121209: przekazywanie wierzcholkow hurtem
glVertexPointer(3, GL_DOUBLE, sizeof(GLVERTEX), &Vertices[0].Point.x);
@@ -675,43 +674,22 @@ void TSubModel::DisplayLists()
{
uiDisplayList = glGenLists(1);
glNewList(uiDisplayList, GL_COMPILE);
GfxRenderer.Bind(0);
// if (eType==smt_FreeSpotLight)
// {
// if (iFarAttenDecay==0)
// glColor3f(Diffuse[0],Diffuse[1],Diffuse[2]);
// }
// else
// TODO: poprawic zeby dzialalo
// glColor3f(f4Diffuse[0],f4Diffuse[1],f4Diffuse[2]);
glColorMaterial(GL_FRONT, GL_EMISSION);
glDisable(GL_LIGHTING); // Tolaris-030603: bo mu punkty swiecace sie blendowaly
glBegin(GL_POINTS);
glVertex3f( 0.0f, 0.0f, -0.05f ); // shift point towards the viewer, to avoid z-fighting with the light polygons
glEnd();
glEnable(GL_LIGHTING);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glMaterialfv(GL_FRONT, GL_EMISSION, emm2);
glEndList();
}
else if (eType == TP_STARS)
{ // punkty świecące dookólnie
uiDisplayList = glGenLists(1);
glNewList(uiDisplayList, GL_COMPILE);
GfxRenderer.Bind(0); // tekstury nie ma
glColorMaterial(GL_FRONT, GL_EMISSION);
// glDisable(GL_LIGHTING); // Tolaris-030603: bo mu punkty swiecace sie blendowaly
glBegin(GL_POINTS);
for (int i = 0; i < iNumVerts; i++)
{
glColor3f(Vertices[i].Normal.x, Vertices[i].Normal.y, Vertices[i].Normal.z);
// glVertex3dv(&Vertices[i].Point.x);
glVertex3fv(&Vertices[i].Point.x);
};
glEnd();
// glEnable(GL_LIGHTING);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glMaterialfv(GL_FRONT, GL_EMISSION, emm2);
glEndList();
}
// SafeDeleteArray(Vertices); //przy VBO muszą zostać do załadowania całego
@@ -1232,7 +1210,6 @@ void TSubModel::RenderAlphaDL()
if (iAlpha & iFlags & 0x2F000000)
Next->RenderAlphaDL();
}; // RenderAlpha
#endif
void TSubModel::RenderVBO()
{ // główna procedura renderowania przez VBO
@@ -1466,7 +1443,7 @@ void TSubModel::RenderAlphaVBO()
if (iAlpha & iFlags & 0x2F000000)
Next->RenderAlphaVBO();
}; // RaRenderAlpha
#endif
//---------------------------------------------------------------------------
void TSubModel::RaArrayFill(CVertNormTex *Vert)
@@ -2199,7 +2176,7 @@ void TModel3d::RenderAlpha(double fSquareDistance, texture_manager::size_type *R
Root->RenderAlphaDL();
}
};
#endif
void TModel3d::RaRender(double fSquareDistance, texture_manager::size_type const *ReplacableSkinId, int iAlpha)
{ // renderowanie specjalne, np. kabiny
iAlpha ^= 0x0F0F000F; // odwrócenie flag tekstur, aby wyłapać nieprzezroczyste
@@ -2229,7 +2206,7 @@ void TModel3d::RaRenderAlpha(double fSquareDistance, texture_manager::size_type
}
}
};
#endif
//-----------------------------------------------------------------------------
// 2011-03-16 cztery nowe funkcje renderowania z możliwością pochylania obiektów
//-----------------------------------------------------------------------------
@@ -2268,7 +2245,7 @@ void TModel3d::RenderAlpha(vector3 *vPosition, vector3 *vAngle, texture_manager:
Root->RenderAlphaDL();
glPopMatrix();
};
#endif
void TModel3d::RaRender(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type const *ReplacableSkinId, int iAlpha)
{ // nieprzezroczyste, VBO
glPushMatrix();
@@ -2310,7 +2287,7 @@ void TModel3d::RaRenderAlpha(vector3 *vPosition, vector3 *vAngle, texture_manage
}
glPopMatrix();
};
#endif
//-----------------------------------------------------------------------------
// 2012-02 funkcje do tworzenia terenu z E3D
@@ -2355,9 +2332,8 @@ void TModel3d::TerrainRenderVBO(int n)
TSubModel *r = Root;
while (r)
{
if (r->iVisible ==
n) // tylko jeśli ma być widoczny w danej ramce (problem dla 0==false)
r->RenderVBO(); // sub kolejne (Next) się nie wyrenderują
if (r->iVisible == n) // tylko jeśli ma być widoczny w danej ramce (problem dla 0==false)
GfxRenderer.Render(r); // sub kolejne (Next) się nie wyrenderują
r = r->NextGet();
}
EndVBO();

View File

@@ -258,9 +258,9 @@ public:
#ifdef EU07_USE_OLD_RENDERCODE
void RenderDL();
void RenderAlphaDL();
#endif
void RenderVBO();
void RenderAlphaVBO();
#endif
// inline matrix4x4* GetMatrix() {return dMatrix;};
inline float4x4 * GetMatrix()
{

View File

@@ -42,10 +42,12 @@ TSegment::~TSegment()
SafeDeleteArray(fTsBuffer);
};
bool TSegment::Init(vector3 NewPoint1, vector3 NewPoint2, double fNewStep, double fNewRoll1,
double fNewRoll2)
bool TSegment::Init(vector3 NewPoint1, vector3 NewPoint2, double fNewStep, double fNewRoll1, double fNewRoll2)
{ // wersja dla prostego - wyliczanie punktów kontrolnych
vector3 dir;
// NOTE: we're enforcing division also for straight track, to ensure dense enough mesh for per-vertex lighting
/*
if (fNewRoll1 == fNewRoll2)
{ // faktyczny prosty
dir = Normalize(NewPoint2 - NewPoint1); // wektor kierunku o długości 1
@@ -53,10 +55,13 @@ bool TSegment::Init(vector3 NewPoint1, vector3 NewPoint2, double fNewStep, doubl
false);
}
else
*/
{ // prosty ze zmienną przechyłką musi być segmentowany jak krzywe
dir = (NewPoint2 - NewPoint1) / 3.0; // punkty kontrolne prostego są w 1/3 długości
return TSegment::Init(NewPoint1, NewPoint1 + dir, NewPoint2 - dir, NewPoint2, fNewStep,
fNewRoll1, fNewRoll2, true);
return TSegment::Init(
NewPoint1, NewPoint1 + dir,
NewPoint2 - dir, NewPoint2,
fNewStep, fNewRoll1, fNewRoll2, true);
}
};
@@ -120,33 +125,24 @@ bool TSegment::Init(vector3 &NewPoint1, vector3 NewCPointOut, vector3 NewCPointI
fStoop = atan2((Point2.y - Point1.y),
fLength); // pochylenie toru prostego, żeby nie liczyć wielokrotnie
SafeDeleteArray(fTsBuffer);
/*
if ((bCurve) && (fStep > 0))
*/
// we're enforcing sub-division of even straight track, to have dense enough mesh for the spotlight to work with
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
// fStep=fLength/(double)(iSegCount-1); //wyrównanie podziału
fTsBuffer = new double[iSegCount + 1];
fTsBuffer[0] = 0; /* TODO : fix fTsBuffer */
while (s < fLength)
{
i++;
s += fStep;
if (s > fLength)
s = fLength;
fTsBuffer[i] = GetTFromS(s);
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
// fStep=fLength/(double)(iSegCount-1); //wyrównanie podziału
fTsBuffer = new double[ iSegCount + 1 ];
fTsBuffer[ 0 ] = 0; /* TODO : fix fTsBuffer */
while( s < fLength ) {
i++;
s += fStep;
if( s > fLength )
s = fLength;
fTsBuffer[ i ] = GetTFromS( s );
}
}
}
if (fLength > 500)
{ // tor ma pojemność 40 pojazdów, więc nie może być za długi
ErrorLog("Bad geometry: Length > 500m at " + Where(Point1));
// MessageBox(0,"Length>500","TSegment::Init",MB_OK);
return false;
}
return true;
}

189
Track.cpp
View File

@@ -541,8 +541,10 @@ void TTrack::Load(cParser *parser, vector3 pOrigin, std::string name)
p2.y += 0.18;
// na przechyłce doliczyć jeszcze pół przechyłki
}
if (fRadius != 0) // gdy podany promień
segsize = Min0R(5.0, 0.2 + fabs(fRadius) * 0.02); // do 250m - 5, potem 1 co 50m
if( fRadius != 0 ) // gdy podany promień
segsize = Min0R( 5.0, 0.2 + fabs( fRadius ) * 0.02 ); // do 250m - 5, potem 1 co 50m
else
segsize = 10.0; // for straights, 10m per segment works good enough
if ((((p1 + p1 + p2) / 3.0 - p1 - cp1).Length() < 0.02) ||
(((p1 + p2 + p2) / 3.0 - p2 + cp1).Length() < 0.02))
@@ -550,11 +552,9 @@ void TTrack::Load(cParser *parser, vector3 pOrigin, std::string name)
if ((cp1 == vector3(0, 0, 0)) &&
(cp2 == vector3(0, 0, 0))) // Ra: hm, czasem dla prostego są podane...
Segment->Init(p1, p2, segsize, r1,
r2); // gdy prosty, kontrolne wyliczane przy zmiennej przechyłce
Segment->Init(p1, p2, segsize, r1, r2); // gdy prosty, kontrolne wyliczane przy zmiennej przechyłce
else
Segment->Init(p1, cp1 + p1, cp2 + p2, p2, segsize, r1,
r2); // gdy łuk (ustawia bCurve=true)
Segment->Init(p1, cp1 + p1, cp2 + p2, p2, segsize, r1, r2); // gdy łuk (ustawia bCurve=true)
if ((r1 != 0) || (r2 != 0))
iTrapezoid = 1; // są przechyłki do uwzględniania w rysowaniu
if (eType == tt_Table) // obrotnica ma doklejkę
@@ -2395,124 +2395,89 @@ void TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start)
}
};
void TTrack::RaRenderVBO(int iPtr)
{ // renderowanie z użyciem VBO
void TTrack::RaRenderVBO( int iPtr ) { // renderowanie z użyciem VBO
// Ra 2014-07: trzeba wymienić GL_TRIANGLE_STRIP na GL_TRIANGLES i renderować trójkąty sektora
// dla kolejnych tekstur!
EnvironmentSet();
int seg;
int i;
switch (iCategoryFlag & 15)
{
case 1: // tor
if (eType == tt_Switch) // dla zwrotnicy tylko szyny
{
if (TextureID1)
if ((seg = SwitchExtension->Segments[0]->RaSegCount()) > 0)
{
GfxRenderer.Bind( TextureID1 ); // szyny +
for (i = 0; i < seg; ++i)
glDrawArrays(GL_TRIANGLE_STRIP, iPtr + 24 * i, 24);
iPtr += 24 * seg; // pominięcie lewej szyny
for (i = 0; i < seg; ++i)
glDrawArrays(GL_TRIANGLE_STRIP, iPtr + 24 * i, 24);
iPtr += 24 * seg; // pominięcie prawej szyny
}
if (TextureID2)
if ((seg = SwitchExtension->Segments[1]->RaSegCount()) > 0)
{
GfxRenderer.Bind( TextureID2 ); // szyny -
for (i = 0; i < seg; ++i)
glDrawArrays(GL_TRIANGLE_STRIP, iPtr + 24 * i, 24);
iPtr += 24 * seg; // pominięcie lewej szyny
for (i = 0; i < seg; ++i)
glDrawArrays(GL_TRIANGLE_STRIP, iPtr + 24 * i, 24);
}
}
else // dla toru podsypka plus szyny
{
if ((seg = Segment->RaSegCount()) > 0)
switch( iCategoryFlag & 15 ) {
case 1: // tor
if( eType == tt_Switch ) // dla zwrotnicy tylko szyny
{
if (TextureID2)
{
GfxRenderer.Bind( TextureID2 ); // podsypka
for (i = 0; i < seg; ++i)
glDrawArrays(GL_TRIANGLE_STRIP, iPtr + 8 * i, 8);
iPtr += 8 * seg; // pominięcie podsypki
}
if (TextureID1)
{
GfxRenderer.Bind( TextureID1 ); // szyny
for (i = 0; i < seg; ++i)
glDrawArrays(GL_TRIANGLE_STRIP, iPtr + 24 * i, 24);
iPtr += 24 * seg; // pominięcie lewej szyny
for (i = 0; i < seg; ++i)
glDrawArrays(GL_TRIANGLE_STRIP, iPtr + 24 * i, 24);
}
}
}
break;
case 2: // droga
if ((seg = Segment->RaSegCount()) > 0)
{
if (TextureID1)
{
GfxRenderer.Bind( TextureID1 ); // nawierzchnia
for (i = 0; i < seg; ++i)
{
glDrawArrays(GL_TRIANGLE_STRIP, iPtr, 4);
iPtr += 4;
}
}
if (TextureID2)
{
GfxRenderer.Bind( TextureID2 ); // pobocze
if (fTexHeight1 >= 0.0)
{ // normalna droga z poboczem
for (i = 0; i < seg; ++i)
glDrawArrays(GL_TRIANGLE_STRIP, iPtr + 6 * i, 6);
iPtr += 6 * seg; // pominięcie lewego pobocza
for (i = 0; i < seg; ++i)
glDrawArrays(GL_TRIANGLE_STRIP, iPtr + 6 * i, 6);
}
else
{ // z chodnikami o różnych szerokociach
if (fTexWidth != 0.0)
{
for (i = 0; i < seg; ++i)
glDrawArrays(GL_TRIANGLE_STRIP, iPtr + 6 * i, 6);
iPtr += 6 * seg; // pominięcie lewego pobocza
if( TextureID1 )
if( ( seg = SwitchExtension->Segments[ 0 ]->RaSegCount() ) > 0 ) {
GfxRenderer.Bind( TextureID1 ); // szyny +
glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 24 * seg );
iPtr += 24 * seg; // pominięcie lewej szyny
glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 24 * seg );
iPtr += 24 * seg; // pominięcie prawej szyny
}
if( TextureID2 )
if( ( seg = SwitchExtension->Segments[ 1 ]->RaSegCount() ) > 0 ) {
GfxRenderer.Bind( TextureID2 ); // szyny -
glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 24 * seg );
iPtr += 24 * seg; // pominięcie lewej szyny
glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 24 * seg );
}
}
else // dla toru podsypka plus szyny
{
if( ( seg = Segment->RaSegCount() ) > 0 ) {
if( TextureID2 ) {
GfxRenderer.Bind( TextureID2 ); // podsypka
glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 8 * seg );
iPtr += 8 * seg; // pominięcie podsypki
}
if( TextureID1 ) {
GfxRenderer.Bind( TextureID1 ); // szyny
glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 24 * seg );
iPtr += 24 * seg; // pominięcie lewej szyny
glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 24 * seg );
}
if (fTexSlope != 0.0)
for (i = 0; i < seg; ++i)
glDrawArrays(GL_TRIANGLE_STRIP, iPtr + 6 * i, 6);
}
}
}
break;
case 4: // rzeki - jeszcze do przemyślenia
if ((seg = Segment->RaSegCount()) > 0)
{
if (TextureID1)
{
GfxRenderer.Bind( TextureID1 ); // nawierzchnia
for (i = 0; i < seg; ++i)
{
glDrawArrays(GL_TRIANGLE_STRIP, iPtr, 4);
iPtr += 4;
break;
case 2: // droga
if( ( seg = Segment->RaSegCount() ) > 0 ) {
if( TextureID1 ) {
GfxRenderer.Bind( TextureID1 ); // nawierzchnia
glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 4 * seg );
iPtr += 4 * seg;
}
if( TextureID2 ) {
GfxRenderer.Bind( TextureID2 ); // pobocze
if( fTexHeight1 >= 0.0 ) { // normalna droga z poboczem
glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 6 * seg );
iPtr += 6 * seg; // pominięcie lewego pobocza
glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 6 * seg );
}
else { // z chodnikami o różnych szerokociach
if( fTexWidth != 0.0 ) {
glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 6 * seg );
iPtr += 6 * seg; // pominięcie lewego pobocza
}
if( fTexSlope != 0.0 )
glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 6 * seg );
}
}
}
if (TextureID2)
{
GfxRenderer.Bind( TextureID2 ); // pobocze
for (i = 0; i < seg; ++i)
glDrawArrays(GL_TRIANGLE_STRIP, iPtr + 6 * i, 6);
iPtr += 6 * seg; // pominięcie lewego pobocza
for (i = 0; i < seg; ++i)
glDrawArrays(GL_TRIANGLE_STRIP, iPtr + 6 * i, 6);
break;
case 4: // rzeki - jeszcze do przemyślenia
if( ( seg = Segment->RaSegCount() ) > 0 ) {
if( TextureID1 ) {
GfxRenderer.Bind( TextureID1 ); // nawierzchnia
glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 4 * seg );
iPtr += 4 * seg;
}
if( TextureID2 ) {
GfxRenderer.Bind( TextureID2 ); // pobocze
glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 6 * seg );
iPtr += 6 * seg; // pominięcie lewego pobocza
glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 6 * seg );
}
}
}
break;
break;
}
EnvironmentReset();
};

View File

@@ -1386,21 +1386,21 @@ TWorld::Render_Cab() {
}
#endif
#ifdef EU07_USE_OLD_RENDERCODE
if( Global::bUseVBO ) {
// renderowanie z użyciem VBO. NOTE: needs update, and eventual merge into single render path down the road
dynamic->mdKabina->RaRender( 0.0, dynamic->Material()->replacable_skins, dynamic->Material()->textures_alpha );
dynamic->mdKabina->RaRenderAlpha( 0.0, dynamic->Material()->replacable_skins, dynamic->Material()->textures_alpha );
}
else {
// renderowanie z Display List
#ifdef EU07_USE_OLD_RENDERCODE
// renderowanie z Display List
dynamic->mdKabina->Render( 0.0, dynamic->ReplacableSkinID, dynamic->iAlpha );
dynamic->mdKabina->RenderAlpha( 0.0, dynamic->ReplacableSkinID, dynamic->iAlpha );
#else
GfxRenderer.Render( dynamic->mdKabina, dynamic->Material(), 0.0 );
GfxRenderer.Render_Alpha( dynamic->mdKabina, dynamic->Material(), 0.0 );
#endif
}
#else
GfxRenderer.Render( dynamic->mdKabina, dynamic->Material(), 0.0 );
GfxRenderer.Render_Alpha( dynamic->mdKabina, dynamic->Material(), 0.0 );
#endif
#ifdef EU07_USE_OLD_LIGHTING_MODEL
// przywrócenie standardowych, bo zawsze są zmieniane
glLightfv( GL_LIGHT0, GL_AMBIENT, Global::ambientDayLight );

View File

@@ -205,6 +205,7 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
Dynamic->renderme = true;
// setup
TSubModel::iInstance = ( size_t )this; //żeby nie robić cudzych animacji
double squaredistance = SquareMagnitude( Global::pCameraPosition - Dynamic->vPosition ) / Global::ZoomFactor;
Dynamic->ABuLittleUpdate( squaredistance ); // ustawianie zmiennych submodeli dla wspólnego modelu
@@ -227,63 +228,34 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
Global::DayLight.apply_intensity( Dynamic->fShade );
}
// TODO: implement universal render path down the road
if( Global::bUseVBO ) {
// wersja VBO
if( Dynamic->mdLowPolyInt ) {
if( FreeFlyModeFlag ? true : !Dynamic->mdKabina || !Dynamic->bDisplayCab ) {
// enable cab light if needed
if( Dynamic->InteriorLightLevel > 0.0f ) {
// render
if( Dynamic->mdLowPolyInt ) {
// low poly interior
if( FreeFlyModeFlag ? true : !Dynamic->mdKabina || !Dynamic->bDisplayCab ) {
// enable cab light if needed
if( Dynamic->InteriorLightLevel > 0.0f ) {
// crude way to light the cabin, until we have something more complete in place
auto const cablight = Dynamic->InteriorLight * Dynamic->InteriorLightLevel;
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &cablight.x );
}
// crude way to light the cabin, until we have something more complete in place
auto const cablight = Dynamic->InteriorLight * Dynamic->InteriorLightLevel;
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &cablight.x );
}
Dynamic->mdLowPolyInt->RaRender( squaredistance, Dynamic->Material()->replacable_skins, Dynamic->Material()->textures_alpha );
Render( Dynamic->mdLowPolyInt, Dynamic->Material(), squaredistance );
if( Dynamic->InteriorLightLevel > 0.0f ) {
// reset the overall ambient
GLfloat ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient );
}
if( Dynamic->InteriorLightLevel > 0.0f ) {
// reset the overall ambient
GLfloat ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient );
}
}
Dynamic->mdModel->RaRender( squaredistance, Dynamic->Material()->replacable_skins, Dynamic->Material()->textures_alpha );
if( Dynamic->mdLoad ) // renderowanie nieprzezroczystego ładunku
Dynamic->mdLoad->RaRender( squaredistance, Dynamic->Material()->replacable_skins, Dynamic->Material()->textures_alpha );
}
else {
// wersja Display Lists
if( Dynamic->mdLowPolyInt ) {
// low poly interior
if( FreeFlyModeFlag ? true : !Dynamic->mdKabina || !Dynamic->bDisplayCab ) {
// enable cab light if needed
if( Dynamic->InteriorLightLevel > 0.0f ) {
// crude way to light the cabin, until we have something more complete in place
auto const cablight = Dynamic->InteriorLight * Dynamic->InteriorLightLevel;
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &cablight.x );
}
Render( Dynamic->mdLowPolyInt, Dynamic->Material(), squaredistance );
if( Dynamic->InteriorLightLevel > 0.0f ) {
// reset the overall ambient
GLfloat ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient );
}
}
}
Render( Dynamic->mdModel, Dynamic->Material(), squaredistance );
if( Dynamic->mdLoad ) // renderowanie nieprzezroczystego ładunku
Render( Dynamic->mdLoad, Dynamic->Material(), squaredistance );
}
Render( Dynamic->mdModel, Dynamic->Material(), squaredistance );
if( Dynamic->mdLoad ) // renderowanie nieprzezroczystego ładunku
Render( Dynamic->mdLoad, Dynamic->Material(), squaredistance );
// post-render cleanup
if( Dynamic->fShade > 0.0f ) {
// restore regular light level
Global::DayLight.apply_intensity();
@@ -312,15 +284,30 @@ opengl_renderer::Render( TModel3d *Model, material_data const *Material, double
}
Model->Root->fSquareDist = Squaredistance; // zmienna globalna!
// TODO: unify the render code after generic buffers are in place
// setup
if( Global::bUseVBO ) {
if( false == Model->StartVBO() )
return false;
}
Model->Root->ReplacableSet(
( Material != nullptr ?
Material->replacable_skins :
nullptr ),
alpha );
Model->Root->pRoot = Model;
// render
Render( Model->Root );
// post-render cleanup
if( Global::bUseVBO ) {
Model->EndVBO();
}
return true;
}
@@ -345,7 +332,7 @@ opengl_renderer::Render( TModel3d *Model, material_data const *Material, Math3D:
void
opengl_renderer::Render( TSubModel *Submodel ) {
// główna procedura renderowania przez DL
if( ( Submodel->iVisible )
&& ( TSubModel::fSquareDist >= ( Submodel->fSquareMinDist / Global::fDistanceFactor ) )
&& ( TSubModel::fSquareDist <= ( Submodel->fSquareMaxDist * Global::fDistanceFactor ) ) ) {
@@ -357,53 +344,113 @@ opengl_renderer::Render( TSubModel *Submodel ) {
if( Submodel->b_Anim )
Submodel->RaAnimation( Submodel->b_Anim );
}
if( Submodel->eType < TP_ROTATOR ) { // renderowanie obiektów OpenGL
if( Submodel->eType < TP_ROTATOR ) {
// renderowanie obiektów OpenGL
if( Submodel->iAlpha & Submodel->iFlags & 0x1F ) // rysuj gdy element nieprzezroczysty
{
if( Submodel->TextureID < 0 ) // && (ReplacableSkinId!=0))
// material configuration:
// textures...
if( Submodel->TextureID < 0 )
{ // zmienialne skóry
GfxRenderer.Bind( Submodel->ReplacableSkinId[ -Submodel->TextureID ] );
// TexAlpha=!(iAlpha&1); //zmiana tylko w przypadku wymienej tekstury
Bind( Submodel->ReplacableSkinId[ -Submodel->TextureID ] );
}
else
GfxRenderer.Bind( Submodel->TextureID ); // również 0
else {
// również 0
Bind( Submodel->TextureID );
}
::glColor3fv( Submodel->f4Diffuse ); // McZapkie-240702: zamiast ub
// ...luminance
if( Global::fLuminance < Submodel->fLight ) {
::glMaterialfv( GL_FRONT, GL_EMISSION, Submodel->f4Diffuse ); // zeby swiecilo na kolorowo
::glCallList( Submodel->uiDisplayList ); // tylko dla siatki
float4 const noemission( 0.0f, 0.0f, 0.0f, 1.0f );
::glMaterialfv( GL_FRONT, GL_EMISSION, &noemission.x );
// zeby swiecilo na kolorowo
::glMaterialfv( GL_FRONT, GL_EMISSION, Submodel->f4Diffuse );
}
// main draw call. TODO: generic buffer base class, specialized for vbo, dl etc
if( Global::bUseVBO ) {
::glDrawArrays( Submodel->eType, Submodel->iVboPtr, Submodel->iNumVerts );
}
else {
::glCallList( Submodel->uiDisplayList );
}
// post-draw reset
if( Global::fLuminance < Submodel->fLight ) {
// restore default (lack of) brightness
glm::vec4 const noemission( 0.0f, 0.0f, 0.0f, 1.0f );
::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( noemission ) );
}
else
::glCallList( Submodel->uiDisplayList ); // tylko dla siatki
}
}
else if( Submodel->eType == TP_FREESPOTLIGHT ) {
// wersja DL
/*
matrix4x4 modelview;
::glGetDoublev( GL_MODELVIEW_MATRIX, modelview.getArray() );
*/
matrix4x4 modelview; modelview.OpenGL_Matrix( OpenGLMatrices.data_array( GL_MODELVIEW ) );
// kąt między kierunkiem światła a współrzędnymi kamery
auto const lightcenter = modelview * vector3( 0.0, 0.0, 0.0 ); // pozycja punktu świecącego względem kamery
Submodel->fCosViewAngle = DotProduct( Normalize( modelview * vector3( 0.0, 0.0, -1.0 ) - lightcenter ), Normalize( -lightcenter ) );
auto const &modelview = OpenGLMatrices.data( GL_MODELVIEW );
auto const lightcenter = modelview * glm::vec4( 0.0f, 0.0f, -0.05f, 1.0f ); // pozycja punktu świecącego względem kamery
Submodel->fCosViewAngle = glm::dot( glm::normalize( modelview * glm::vec4( 0.0f, 0.0f, -1.0f, 1.0f ) - lightcenter ), glm::normalize( -lightcenter ) );
if( Submodel->fCosViewAngle > Submodel->fCosFalloffAngle ) // kąt większy niż maksymalny stożek swiatła
{
double Distdimm = 1.0;
if( Submodel->fCosViewAngle < Submodel->fCosHotspotAngle ) // zmniejszona jasność między Hotspot a Falloff
if( Submodel->fCosFalloffAngle < Submodel->fCosHotspotAngle )
Distdimm = 1.0 - ( Submodel->fCosHotspotAngle - Submodel->fCosViewAngle ) / ( Submodel->fCosHotspotAngle - Submodel->fCosFalloffAngle );
::glColor3f( Submodel->f4Diffuse[ 0 ] * Distdimm, Submodel->f4Diffuse[ 1 ] * Distdimm, Submodel->f4Diffuse[ 2 ] * Distdimm );
::glCallList( Submodel->uiDisplayList ); // wyświetlenie warunkowe
float lightlevel = 1.0f;
// view angle attenuation
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 ) );
if( lightlevel > 0.0f ) {
// material configuration:
::glPushAttrib( GL_ENABLE_BIT | GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_POINT_BIT );
Bind( 0 );
::glPointSize( std::max( 2.0f, 4.0f * distancefactor * anglefactor ) );
::glColor4f( Submodel->f4Diffuse[ 0 ], Submodel->f4Diffuse[ 1 ], Submodel->f4Diffuse[ 2 ], lightlevel * anglefactor );
::glDisable( GL_LIGHTING );
::glEnable( GL_BLEND );
// main draw call. TODO: generic buffer base class, specialized for vbo, dl etc
if( Global::bUseVBO ) {
::glDrawArrays( GL_POINTS, Submodel->iVboPtr, Submodel->iNumVerts );
}
else {
::glCallList( Submodel->uiDisplayList );
}
// post-draw reset
::glPopAttrib();
}
}
}
else if( Submodel->eType == TP_STARS ) {
// glDisable(GL_LIGHTING); //Tolaris-030603: bo mu punkty swiecace sie blendowaly
if( Global::fLuminance < Submodel->fLight ) {
::glMaterialfv( GL_FRONT, GL_EMISSION, Submodel->f4Diffuse ); // zeby swiecilo na kolorowo
::glCallList( Submodel->uiDisplayList ); // narysuj naraz wszystkie punkty z DL
float4 const noemission( 0.0f, 0.0f, 0.0f, 1.0f );
::glMaterialfv( GL_FRONT, GL_EMISSION, &noemission.x );
// material configuration:
::glPushAttrib( GL_ENABLE_BIT | GL_CURRENT_BIT );
Bind( 0 );
::glDisable( GL_LIGHTING );
// main draw call. TODO: generic buffer base class, specialized for vbo, dl etc
if( Global::bUseVBO ) {
// NOTE: we're doing manual switch to color vbo setup, because there doesn't seem to be any convenient way available atm
// TODO: implement easier way to go about it
::glDisableClientState( GL_NORMAL_ARRAY );
::glDisableClientState( GL_TEXTURE_COORD_ARRAY );
::glEnableClientState( GL_COLOR_ARRAY );
::glColorPointer( 3, GL_FLOAT, sizeof( CVertNormTex ), static_cast<char *>( nullptr ) + 12 ); // kolory
::glDrawArrays( GL_POINTS, Submodel->iVboPtr, Submodel->iNumVerts );
::glDisableClientState( GL_COLOR_ARRAY );
::glEnableClientState( GL_NORMAL_ARRAY );
::glEnableClientState( GL_TEXTURE_COORD_ARRAY );
}
else {
::glCallList( Submodel->uiDisplayList );
}
// post-draw reset
::glPopAttrib();
}
}
if( Submodel->Child != NULL )
@@ -429,7 +476,8 @@ opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
return false;
}
// setup
TSubModel::iInstance = ( size_t )this; //żeby nie robić cudzych animacji
double squaredistance = SquareMagnitude( Global::pCameraPosition - Dynamic->vPosition ) / Global::ZoomFactor;
Dynamic->ABuLittleUpdate( squaredistance ); // ustawianie zmiennych submodeli dla wspólnego modelu
@@ -444,61 +492,42 @@ opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
::glMultMatrixd( Dynamic->mMatrix.getArray() );
// TODO: implement universal render path down the road
if( Global::bUseVBO ) {
// wersja VBO
if( Dynamic->mdLowPolyInt ) {
if( FreeFlyModeFlag ? true : !Dynamic->mdKabina || !Dynamic->bDisplayCab ) {
// enable cab light if needed
if( Dynamic->InteriorLightLevel > 0.0f ) {
// crude way to light the cabin, until we have something more complete in place
auto const cablight = Dynamic->InteriorLight * Dynamic->InteriorLightLevel;
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &cablight.x );
}
Dynamic->mdLowPolyInt->RaRenderAlpha( squaredistance, Dynamic->Material()->replacable_skins, Dynamic->Material()->textures_alpha );
if( Dynamic->InteriorLightLevel > 0.0f ) {
// reset the overall ambient
GLfloat ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient );
}
}
}
Dynamic->mdModel->RaRenderAlpha( squaredistance, Dynamic->Material()->replacable_skins, Dynamic->Material()->textures_alpha );
if( Dynamic->mdLoad ) // renderowanie nieprzezroczystego ładunku
Dynamic->mdLoad->RaRenderAlpha( squaredistance, Dynamic->Material()->replacable_skins, Dynamic->Material()->textures_alpha );
if( Dynamic->fShade > 0.0f ) {
// change light level based on light level of the occupied track
Global::DayLight.apply_intensity( Dynamic->fShade );
}
else {
// wersja Display Lists
if( Dynamic->mdLowPolyInt ) {
// low poly interior
if( FreeFlyModeFlag ? true : !Dynamic->mdKabina || !Dynamic->bDisplayCab ) {
// enable cab light if needed
if( Dynamic->InteriorLightLevel > 0.0f ) {
// crude way to light the cabin, until we have something more complete in place
auto const cablight = Dynamic->InteriorLight * Dynamic->InteriorLightLevel;
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &cablight.x );
}
// render
if( Dynamic->mdLowPolyInt ) {
// low poly interior
if( FreeFlyModeFlag ? true : !Dynamic->mdKabina || !Dynamic->bDisplayCab ) {
// enable cab light if needed
if( Dynamic->InteriorLightLevel > 0.0f ) {
Render_Alpha( Dynamic->mdLowPolyInt, Dynamic->Material(), squaredistance );
// crude way to light the cabin, until we have something more complete in place
auto const cablight = Dynamic->InteriorLight * Dynamic->InteriorLightLevel;
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &cablight.x );
}
if( Dynamic->InteriorLightLevel > 0.0f ) {
// reset the overall ambient
GLfloat ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient );
}
Render_Alpha( Dynamic->mdLowPolyInt, Dynamic->Material(), squaredistance );
if( Dynamic->InteriorLightLevel > 0.0f ) {
// reset the overall ambient
GLfloat ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient );
}
}
}
Render_Alpha( Dynamic->mdModel, Dynamic->Material(), squaredistance );
Render_Alpha( Dynamic->mdModel, Dynamic->Material(), squaredistance );
if( Dynamic->mdLoad ) // renderowanie nieprzezroczystego ładunku
Render_Alpha( Dynamic->mdLoad, Dynamic->Material(), squaredistance );
if( Dynamic->mdLoad ) // renderowanie nieprzezroczystego ładunku
Render_Alpha( Dynamic->mdLoad, Dynamic->Material(), squaredistance );
// post-render cleanup
if( Dynamic->fShade > 0.0f ) {
// restore regular light level
Global::DayLight.apply_intensity();
}
::glPopMatrix();
@@ -524,14 +553,29 @@ opengl_renderer::Render_Alpha( TModel3d *Model, material_data const *Material, d
Model->Root->fSquareDist = Squaredistance; // zmienna globalna!
// TODO: unify the render code after generic buffers are in place
// setup
if( Global::bUseVBO ) {
if( false == Model->StartVBO() )
return false;
}
Model->Root->ReplacableSet(
( Material != nullptr ?
Material->replacable_skins :
nullptr ),
Material->replacable_skins :
nullptr ),
alpha );
Model->Root->pRoot = Model;
// render
Render_Alpha( Model->Root );
// post-render cleanup
if( Global::bUseVBO ) {
Model->EndVBO();
}
return true;
}
@@ -569,54 +613,60 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
Submodel->RaAnimation( Submodel->b_aAnim );
}
if( Submodel->eType < TP_ROTATOR ) { // renderowanie obiektów OpenGL
if( Submodel->eType < TP_ROTATOR ) {
// renderowanie obiektów OpenGL
if( Submodel->iAlpha & Submodel->iFlags & 0x2F ) // rysuj gdy element przezroczysty
{
if( Submodel->TextureID < 0 ) // && (ReplacableSkinId!=0))
{ // zmienialne skóry
GfxRenderer.Bind( Submodel->ReplacableSkinId[ -Submodel->TextureID ] );
// TexAlpha=iAlpha&1; //zmiana tylko w przypadku wymienej tekstury
// textures...
if( Submodel->TextureID < 0 ) { // zmienialne skóry
Bind( Submodel->ReplacableSkinId[ -Submodel->TextureID ] );
}
else
GfxRenderer.Bind( Submodel->TextureID ); // również 0
else {
// również 0
Bind( Submodel->TextureID );
}
::glColor3fv( Submodel->f4Diffuse ); // McZapkie-240702: zamiast ub
// ...luminance
if( Global::fLuminance < Submodel->fLight ) {
::glMaterialfv( GL_FRONT, GL_EMISSION, Submodel->f4Diffuse ); // zeby swiecilo na kolorowo
::glCallList( Submodel->uiDisplayList ); // tylko dla siatki
float4 const noemission( 0.0f, 0.0f, 0.0f, 1.0f );
::glMaterialfv( GL_FRONT, GL_EMISSION, &noemission.x );
// zeby swiecilo na kolorowo
::glMaterialfv( GL_FRONT, GL_EMISSION, Submodel->f4Diffuse );
}
// main draw call. TODO: generic buffer base class, specialized for vbo, dl etc
if( Global::bUseVBO ) {
::glDrawArrays( Submodel->eType, Submodel->iVboPtr, Submodel->iNumVerts );
}
else {
::glCallList( Submodel->uiDisplayList );
}
// post-draw reset
if( Global::fLuminance < Submodel->fLight ) {
// restore default (lack of) brightness
glm::vec4 const noemission( 0.0f, 0.0f, 0.0f, 1.0f );
::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( noemission ) );
}
else
::glCallList( Submodel->uiDisplayList ); // tylko dla siatki
}
}
else if( Submodel->eType == TP_FREESPOTLIGHT ) {
// dorobić aureolę!
if( Global::fLuminance < Submodel->fLight ) {
// NOTE: we're forced here to redo view angle calculations etc, because this data isn't instanced but stored along with the single mesh
// TODO: separate instance data from reusable geometry
/*
matrix4x4 modelview;
::glGetDoublev( GL_MODELVIEW_MATRIX, modelview.getArray() );
*/
/*
matrix4x4 modelview; modelview.OpenGL_Matrix( OpenGLMatrices.data_array( GL_MODELVIEW ) );
// kąt między kierunkiem światła a współrzędnymi kamery
auto const lightcenter = modelview * vector3( 0.0, 0.0, -0.05 ); // pozycja punktu świecącego względem kamery
Submodel->fCosViewAngle = DotProduct( Normalize( modelview * vector3( 0.0, 0.0, -1.0 ) - lightcenter ), Normalize( -lightcenter ) );
*/
auto const &modelview = OpenGLMatrices.data( GL_MODELVIEW );
auto const lightcenter = modelview * glm::vec4( 0.0f, 0.0f, -0.05f, 1.0f ); // pozycja punktu świecącego względem kamery
Submodel->fCosViewAngle = glm::dot( glm::normalize( modelview * glm::vec4( 0.0f, 0.0f, -1.0f, 1.0f ) - lightcenter ), glm::normalize( -lightcenter ) );
float glarelevel = 0.6f; // luminosity at night is at level of ~0.1, so the overall resulting transparency is ~0.5 at full 'brightness'
if( ( Submodel->fCosViewAngle > 0.0 ) && ( Submodel->fCosViewAngle > Submodel->fCosFalloffAngle ) ) {
if( Submodel->fCosViewAngle > Submodel->fCosFalloffAngle ) {
glarelevel *= ( Submodel->fCosViewAngle - Submodel->fCosFalloffAngle ) / ( 1.0 - Submodel->fCosFalloffAngle );
glarelevel *= ( Submodel->fCosViewAngle - Submodel->fCosFalloffAngle ) / ( 1.0f - Submodel->fCosFalloffAngle );
glarelevel = std::max( 0.0f, glarelevel - static_cast<float>(Global::fLuminance) );
if( glarelevel > 0.0f ) {
::glPushAttrib( GL_ENABLE_BIT | GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT );
Bind( m_glaretextureid );
::glColor4f( Submodel->f4Diffuse[ 0 ], Submodel->f4Diffuse[ 1 ], Submodel->f4Diffuse[ 2 ], glarelevel );
::glDisable( GL_LIGHTING );
@@ -627,8 +677,6 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
::glTranslatef( lightcenter.x, lightcenter.y, lightcenter.z ); // początek układu zostaje bez zmian
::glRotated( atan2( lightcenter.x, lightcenter.z ) * 180.0 / M_PI, 0.0, 1.0, 0.0 ); // jedynie obracamy w pionie o kąt
::glMaterialfv( GL_FRONT, GL_EMISSION, Submodel->f4Diffuse ); // zeby swiecilo na kolorowo
// TODO: turn the drawing instructions into a compiled call / array
::glBegin( GL_TRIANGLE_STRIP );
float const size = 2.5f;
@@ -646,9 +694,6 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
*/
::glEnd();
float4 const noemission( 0.0f, 0.0f, 0.0f, 1.0f );
::glMaterialfv( GL_FRONT, GL_EMISSION, &noemission.x );
::glPopMatrix();
::glPopAttrib();
}

View File

@@ -180,7 +180,8 @@ private:
typedef std::vector<opengl_light> opengllight_array;
// methods
bool Init_caps();
bool
Init_caps();
// members
rendermode renderpass{ rendermode::color };

12
sky.cpp
View File

@@ -39,21 +39,21 @@ void TSky::Render( float3 const &Tint )
GfxRenderer.Disable_Lights();
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &Tint.x );
#endif
if (Global::bUseVBO)
#ifdef EU07_USE_OLD_RENDERCODE
if( Global::bUseVBO )
{ // renderowanie z VBO
mdCloud->RaRender( 100, 0 );
mdCloud->RaRenderAlpha(100, 0);
}
else
{ // renderowanie z Display List
#ifdef EU07_USE_OLD_RENDERCODE
mdCloud->Render(100, 0);
mdCloud->RenderAlpha(100, 0);
#else
GfxRenderer.Render( mdCloud, nullptr, 100.0 );
GfxRenderer.Render_Alpha( mdCloud, nullptr, 100.0 );
#endif
}
#else
GfxRenderer.Render( mdCloud, nullptr, 100.0 );
GfxRenderer.Render_Alpha( mdCloud, nullptr, 100.0 );
#endif
#ifdef EU07_USE_OLD_LIGHTING_MODEL
glPopMatrix();
// TODO: re-implement this

View File

@@ -21,16 +21,16 @@ cStars::render() {
::glRotatef( -std::fmod( (float)Global::fTimeAngleDeg, 360.0f ), 0.0f, 1.0f, 0.0f ); // obrót dobowy osi OX
::glPointSize( 2.0f );
#ifdef EU07_USE_OLD_RENDERCODE
if( Global::bUseVBO ) {
m_stars.RaRender( 1.0, 0 );
}
else {
#ifdef EU07_USE_OLD_RENDERCODE
m_stars.Render( 1.0 );
#else
GfxRenderer.Render( &m_stars, nullptr, 1.0 );
#endif
}
#else
GfxRenderer.Render( &m_stars, nullptr, 1.0 );
#endif
::glPointSize( 3.0f );
::glPopMatrix();