mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-18 03:09:18 +02:00
build 170617. frustum based ground sector culling, fully view range based draw range limit, support for line width parameter for lines
This commit is contained in:
30
Ground.cpp
30
Ground.cpp
@@ -39,7 +39,6 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "world.h"
|
||||
#include "uilayer.h"
|
||||
|
||||
#define _PROBLEND 1
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
extern "C"
|
||||
@@ -1283,18 +1282,16 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
||||
*parser >> token;
|
||||
}
|
||||
str = token;
|
||||
#ifdef _PROBLEND
|
||||
// PROBLEND Q: 13122011 - Szociu: 27012012
|
||||
PROBLEND = true; // domyslnie uruchomione nowe wyświetlanie
|
||||
tmp->PROBLEND = true; // odwolanie do tgroundnode, bo rendering jest w tej klasie
|
||||
if (str.find('@') != std::string::npos) // sprawdza, czy w nazwie tekstury jest znak "@"
|
||||
{
|
||||
PROBLEND = false; // jeśli jest, wyswietla po staremu
|
||||
tmp->PROBLEND = false;
|
||||
}
|
||||
#endif
|
||||
tmp->TextureID = GfxRenderer.GetTextureId( str, szTexturePath );
|
||||
tmp->iFlags = GfxRenderer.Texture(tmp->TextureID).has_alpha ? 0x220 : 0x210; // z usuwaniem
|
||||
|
||||
tmp->iFlags |= 200; // z usuwaniem
|
||||
// remainder of legacy 'problend' system -- geometry assigned a texture with '@' in its name is treated as translucent, opaque otherwise
|
||||
tmp->iFlags |= (
|
||||
( ( str.find( '@' ) != std::string::npos )
|
||||
&& ( true == GfxRenderer.Texture( tmp->TextureID ).has_alpha ) ) ?
|
||||
0x20 :
|
||||
0x10 );
|
||||
|
||||
if( (tmp->iType == GL_TRIANGLES)
|
||||
&& (tmp->iFlags & 0x10)
|
||||
&& (Global::pTerrainCompact->TerrainLoaded()) ) {
|
||||
@@ -1327,7 +1324,6 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
||||
vertex.normal = glm::rotateX( vertex.normal, static_cast<float>( aRotate.x / 180 * M_PI ) );
|
||||
vertex.normal = glm::rotateY( vertex.normal, static_cast<float>( aRotate.y / 180 * M_PI ) );
|
||||
vertex.position += glm::dvec3( pOrigin.x, pOrigin.y, pOrigin.z );
|
||||
tmp->pCenter += vertex.position;
|
||||
// convert all data to gl_triangles to allow data merge for matching nodes
|
||||
switch( tmp->iType ) {
|
||||
case GL_TRIANGLES: {
|
||||
@@ -1370,6 +1366,10 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
||||
|
||||
auto const nv = importedvertices.size();
|
||||
tmp->Init(nv); // utworzenie tablicy wierzchołków
|
||||
|
||||
for( std::size_t i = 0; i < nv; ++i ) {
|
||||
tmp->pCenter += importedvertices[ i ].position;
|
||||
}
|
||||
tmp->pCenter /= (nv > 0 ? nv : 1);
|
||||
|
||||
r = 0;
|
||||
@@ -1411,7 +1411,6 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
||||
vertex.position = glm::rotateY( vertex.position, aRotate.y / 180 * M_PI );
|
||||
|
||||
vertex.position += glm::dvec3( pOrigin.x, pOrigin.y, pOrigin.z );
|
||||
tmp->pCenter += vertex.position;
|
||||
// convert all data to gl_lines to allow data merge for matching nodes
|
||||
switch( tmp->iType ) {
|
||||
case GL_LINES: {
|
||||
@@ -1460,10 +1459,11 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
||||
auto const nv = importedvertices.size();
|
||||
tmp->Points = new glm::dvec3[ nv ];
|
||||
tmp->iNumPts = nv;
|
||||
tmp->pCenter /= ( nv > 0 ? nv : 1 );
|
||||
for( std::size_t i = 0; i < nv; ++i ) {
|
||||
tmp->Points[ i ] = importedvertices[ i ].position;
|
||||
tmp->pCenter += importedvertices[ i ].position;
|
||||
}
|
||||
tmp->pCenter /= ( nv > 0 ? nv : 1 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
2
Ground.h
2
Ground.h
@@ -149,7 +149,6 @@ public:
|
||||
Diffuse{ 1.0f, 1.0f, 1.0f },
|
||||
Specular{ 1.0f, 1.0f, 1.0f }; // oświetlenie
|
||||
double fLineThickness; // McZapkie-120702: grubosc linii
|
||||
bool PROBLEND;
|
||||
bool bVisible;
|
||||
|
||||
TGroundNode();
|
||||
@@ -283,7 +282,6 @@ class TGround
|
||||
event_map m_eventmap;
|
||||
TNames<TGroundNode *> m_trackmap;
|
||||
light_array m_lights; // collection of dynamic light sources present in the scene
|
||||
bool PROBLEND;
|
||||
|
||||
private: // metody prywatne
|
||||
bool EventConditon(TEvent *e);
|
||||
|
||||
244
Model3d.cpp
244
Model3d.cpp
@@ -42,69 +42,6 @@ std::string *TSubModel::pasText;
|
||||
// 0x3F3F003F - wszystkie wymienne tekstury używane w danym cyklu
|
||||
// Ale w TModel3d okerśla przezroczystość tekstur wymiennych!
|
||||
|
||||
TSubModel::TSubModel()
|
||||
{
|
||||
::SecureZeroMemory(this, sizeof(TSubModel)); // istotne przy zapisywaniu wersji binarnej
|
||||
FirstInit();
|
||||
};
|
||||
|
||||
void TSubModel::FirstInit()
|
||||
{
|
||||
eType = TP_ROTATOR;
|
||||
/*
|
||||
Vertices = NULL;
|
||||
uiDisplayList = 0;
|
||||
*/
|
||||
iNumVerts = -1; // do sprawdzenia
|
||||
/*
|
||||
iVboPtr = -1;
|
||||
*/
|
||||
fLight = -1.0; //świetcenie wyłączone
|
||||
v_RotateAxis = float3(0, 0, 0);
|
||||
v_TransVector = float3(0, 0, 0);
|
||||
f_Angle = 0;
|
||||
b_Anim = at_None;
|
||||
b_aAnim = at_None;
|
||||
fVisible = 0.0; // zawsze widoczne
|
||||
iVisible = 1;
|
||||
fMatrix = NULL; // to samo co iMatrix=0;
|
||||
Next = NULL;
|
||||
Child = NULL;
|
||||
TextureID = 0;
|
||||
// TexAlpha=false;
|
||||
iFlags = 0x0200; // bit 9=1: submodel został utworzony a nie ustawiony na
|
||||
// wczytany plik
|
||||
// TexHash=false;
|
||||
// Hits=NULL;
|
||||
// CollisionPts=NULL;
|
||||
// CollisionPtsCount=0;
|
||||
Opacity = 0.0f; // przy wczytywaniu modeli było dzielone przez 100...
|
||||
bWire = false;
|
||||
fWireSize = 0;
|
||||
fNearAttenStart = 40;
|
||||
fNearAttenEnd = 80;
|
||||
bUseNearAtten = false;
|
||||
iFarAttenDecay = 0;
|
||||
fFarDecayRadius = 100.0f;
|
||||
fCosFalloffAngle = 0.5f; // 120°?
|
||||
fCosHotspotAngle = 0.3f; // 145°?
|
||||
fCosViewAngle = 0;
|
||||
fSquareMaxDist = 10000 * 10000; // 10km
|
||||
fSquareMinDist = 0;
|
||||
iName = -1; // brak nazwy
|
||||
iTexture = 0; // brak tekstury
|
||||
// asName="";
|
||||
// asTexture="";
|
||||
pName = "";
|
||||
pTexture = "";
|
||||
f4Ambient[0] = f4Ambient[1] = f4Ambient[2] = f4Ambient[3] = 1.0; //{1,1,1,1};
|
||||
f4Diffuse[0] = f4Diffuse[1] = f4Diffuse[2] = f4Diffuse[3] = 1.0; //{1,1,1,1};
|
||||
f4Specular[0] = f4Specular[1] = f4Specular[2] = 0.0;
|
||||
f4Specular[3] = 1.0; //{0,0,0,1};
|
||||
f4Emision[0] = f4Emision[1] = f4Emision[2] = f4Emision[3] = 1.0;
|
||||
smLetter = NULL; // używany tylko roboczo dla TP_TEXT, do przyspieszenia wyświetlania
|
||||
};
|
||||
|
||||
TSubModel::~TSubModel()
|
||||
{
|
||||
/*
|
||||
@@ -141,9 +78,6 @@ void TSubModel::NameSet(std::string const &Name)
|
||||
pName = Name;
|
||||
};
|
||||
|
||||
// int TSubModel::SeekFaceNormal(DWORD *Masks, int f,DWORD dwMask,vector3
|
||||
// *pt,GLVERTEX
|
||||
// *Vertices)
|
||||
int TSubModel::SeekFaceNormal(std::vector<unsigned int> const &Masks, int const Startface, unsigned int const Mask, glm::vec3 const &Position, vertex_array const &Vertices)
|
||||
{ // szukanie punktu stycznego do (pt), zwraca numer wierzchołka, a nie trójkąta
|
||||
int facecount = iNumVerts / 3; // bo maska powierzchni jest jedna na trójkąt
|
||||
@@ -518,11 +452,14 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
|
||||
std::vector<glm::vec3> facenormals;
|
||||
for( int i = 0; i < facecount; ++i ) {
|
||||
// pętla po trójkątach - będzie szybciej, jak wstępnie przeliczymy normalne trójkątów
|
||||
auto facenormal =
|
||||
glm::cross(
|
||||
Vertices[ i * 3 ].position - Vertices[ i * 3 + 1 ].position,
|
||||
Vertices[ i * 3 ].position - Vertices[ i * 3 + 2 ].position );
|
||||
facenormals.emplace_back(
|
||||
glm::normalize(
|
||||
glm::cross(
|
||||
Vertices[ i * 3 ].position - Vertices[ i * 3 + 1 ].position,
|
||||
Vertices[ i * 3 ].position - Vertices[ i * 3 + 2 ].position ) ) );
|
||||
glm::length( facenormal ) > 0.0f ?
|
||||
glm::normalize( facenormal ) :
|
||||
glm::vec3() );
|
||||
}
|
||||
glm::vec3 vertexnormal; // roboczy wektor normalny
|
||||
for (int vertexidx = 0; vertexidx < iNumVerts; ++vertexidx) {
|
||||
@@ -544,7 +481,10 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
|
||||
adjacenvertextidx = SeekFaceNormal(sg, adjacenvertextidx / 3 + 1, sg[faceidx], Vertices[vertexidx].position, Vertices);
|
||||
}
|
||||
// Ra 15-01: należało by jeszcze uwzględnić skalowanie wprowadzane przez transformy, aby normalne po przeskalowaniu były jednostkowe
|
||||
Vertices[vertexidx].normal = glm::normalize(vertexnormal); // przepisanie do wierzchołka trójkąta
|
||||
Vertices[ vertexidx ].normal = (
|
||||
glm::length( vertexnormal ) > 0.0f ?
|
||||
glm::normalize( vertexnormal ) :
|
||||
glm::vec3() ); // przepisanie do wierzchołka trójkąta
|
||||
}
|
||||
}
|
||||
/*
|
||||
@@ -755,7 +695,10 @@ void TSubModel::InitialRotate(bool doit)
|
||||
if( eType != TP_STARS ) {
|
||||
// gwiazdki mają kolory zamiast normalnych, to ich wtedy nie ruszamy
|
||||
for( auto &vertex : Vertices ) {
|
||||
vertex.normal = glm::normalize( ( *mat ) * vertex.normal );
|
||||
vertex.normal = (
|
||||
glm::length( vertex.normal ) > 0.0f ?
|
||||
glm::normalize( ( *mat ) * vertex.normal ) :
|
||||
glm::vec3() );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -772,18 +715,18 @@ void TSubModel::InitialRotate(bool doit)
|
||||
/*
|
||||
for( auto &vertex : Vertices ) {
|
||||
*/
|
||||
for( int idx = 0; idx < iNumVerts; ++idx ) {
|
||||
Vertices[idx].position.x = -Vertices[idx].position.x; // zmiana znaku X
|
||||
swapcopy = Vertices[idx].position.y; // zamiana Y i Z
|
||||
Vertices[idx].position.y = Vertices[idx].position.z;
|
||||
Vertices[idx].position.z = swapcopy;
|
||||
for( auto &vertex : Vertices ) {
|
||||
vertex.position.x = -vertex.position.x; // zmiana znaku X
|
||||
swapcopy = vertex.position.y; // zamiana Y i Z
|
||||
vertex.position.y = vertex.position.z;
|
||||
vertex.position.z = swapcopy;
|
||||
// wektory normalne również trzeba przekształcić, bo się źle oświetlają
|
||||
if( eType != TP_STARS ) {
|
||||
// gwiazdki mają kolory zamiast normalnych, to // ich wtedy nie ruszamy
|
||||
Vertices[idx].normal.x = -Vertices[idx].normal.x; // zmiana znaku X
|
||||
swapcopy = Vertices[idx].normal.y; // zamiana Y i Z
|
||||
Vertices[idx].normal.y = Vertices[idx].normal.z;
|
||||
Vertices[idx].normal.z = swapcopy;
|
||||
vertex.normal.x = -vertex.normal.x; // zmiana znaku X
|
||||
swapcopy = vertex.normal.y; // zamiana Y i Z
|
||||
vertex.normal.y = vertex.normal.z;
|
||||
vertex.normal.z = swapcopy;
|
||||
}
|
||||
}
|
||||
// }
|
||||
@@ -1050,30 +993,34 @@ void TSubModel::RaAnimation(TAnimType a)
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/*
|
||||
void TSubModel::RaArrayFill(basic_vertex *Vert)
|
||||
{ // wypełnianie tablic VBO
|
||||
if (Child)
|
||||
Child->RaArrayFill(Vert);
|
||||
if( ( eType < TP_ROTATOR ) || ( eType == TP_STARS ) )
|
||||
for( int i = 0; i < iNumVerts; ++i ) {
|
||||
Vert[ iVboPtr + i ].position = Vertices[ i ].position;
|
||||
Vert[ iVboPtr + i ].normal = Vertices[ i ].normal;
|
||||
Vert[ iVboPtr + i ].texture = Vertices[ i ].texture;
|
||||
|
||||
void TSubModel::serialize_geometry( std::ostream &Output ) {
|
||||
|
||||
if( Child ) {
|
||||
Child->serialize_geometry( Output );
|
||||
}
|
||||
if( m_geometry != NULL ) {
|
||||
for( auto const &vertex : GfxRenderer.Vertices( m_geometry ) ) {
|
||||
vertex.serialize( Output );
|
||||
}
|
||||
else if( eType == TP_FREESPOTLIGHT )
|
||||
Vert[ iVboPtr ].position = glm::vec3();
|
||||
if (Next)
|
||||
Next->RaArrayFill(Vert);
|
||||
}
|
||||
if( Next ) {
|
||||
Next->serialize_geometry( Output );
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
void
|
||||
TSubModel::create_geometry( geometrybank_handle const &Bank ) {
|
||||
TSubModel::create_geometry( std::size_t &Dataoffset, geometrybank_handle const &Bank ) {
|
||||
|
||||
// data offset is used to determine data offset of each submodel into single shared geometry bank
|
||||
// (the offsets are part of legacy system which we now need to work around for backward compatibility)
|
||||
|
||||
if( Child )
|
||||
Child->create_geometry( Bank );
|
||||
Child->create_geometry( Dataoffset, Bank );
|
||||
|
||||
if( false == Vertices.empty() ) {
|
||||
tVboPtr = static_cast<int>( Dataoffset );
|
||||
Dataoffset += Vertices.size();
|
||||
// conveniently all relevant custom node types use GL_POINTS, or we'd have to determine the type on individual basis
|
||||
auto type = (
|
||||
eType < TP_ROTATOR ?
|
||||
@@ -1083,7 +1030,7 @@ TSubModel::create_geometry( geometrybank_handle const &Bank ) {
|
||||
}
|
||||
|
||||
if( Next )
|
||||
Next->create_geometry( Bank );
|
||||
Next->create_geometry( Dataoffset, Bank );
|
||||
}
|
||||
|
||||
// NOTE: leftover from static distance factor adjustment.
|
||||
@@ -1140,25 +1087,34 @@ void TSubModel::ParentMatrix(float4x4 *m)
|
||||
// nie obrócono jeszcze
|
||||
};
|
||||
|
||||
float TSubModel::MaxY( float4x4 const &m )
|
||||
{ // obliczenie maksymalnej wysokości, na początek ślizgu w pantografie
|
||||
if( eType != 4 ) {
|
||||
// tylko dla trójkątów liczymy
|
||||
return 0;
|
||||
}
|
||||
if( m_geometry == NULL ) {
|
||||
return 0;
|
||||
}
|
||||
// obliczenie maksymalnej wysokości, na początek ślizgu w pantografie
|
||||
float TSubModel::MaxY( float4x4 const &m ) {
|
||||
// tylko dla trójkątów liczymy
|
||||
if( eType != 4 ) { return 0; }
|
||||
|
||||
auto maxy { 0.0f };
|
||||
for( auto const &vertex : GfxRenderer.Vertices( m_geometry ) ) {
|
||||
// binary and text models invoke this function at different stages, either after or before geometry data was sent to the geometry manager
|
||||
if( m_geometry != NULL ) {
|
||||
|
||||
maxy = std::max(
|
||||
maxy,
|
||||
m[ 0 ][ 1 ] * vertex.position.x
|
||||
+ m[ 1 ][ 1 ] * vertex.position.y
|
||||
+ m[ 2 ][ 1 ] * vertex.position.z
|
||||
+ m[ 3 ][ 1 ] );
|
||||
for( auto const &vertex : GfxRenderer.Vertices( m_geometry ) ) {
|
||||
maxy = std::max(
|
||||
maxy,
|
||||
m[ 0 ][ 1 ] * vertex.position.x
|
||||
+ m[ 1 ][ 1 ] * vertex.position.y
|
||||
+ m[ 2 ][ 1 ] * vertex.position.z
|
||||
+ m[ 3 ][ 1 ] );
|
||||
}
|
||||
}
|
||||
else if( false == Vertices.empty() ) {
|
||||
|
||||
for( auto const &vertex : Vertices ) {
|
||||
maxy = std::max(
|
||||
maxy,
|
||||
m[ 0 ][ 1 ] * vertex.position.x
|
||||
+ m[ 1 ][ 1 ] * vertex.position.y
|
||||
+ m[ 2 ][ 1 ] * vertex.position.z
|
||||
+ m[ 3 ][ 1 ] );
|
||||
}
|
||||
}
|
||||
|
||||
return maxy;
|
||||
@@ -1316,10 +1272,10 @@ void TSubModel::serialize(std::ostream &s,
|
||||
|
||||
sn_utils::ls_int32(s, iFlags);
|
||||
sn_utils::ls_int32(s, (int32_t)get_container_pos(transforms, *fMatrix));
|
||||
/*
|
||||
|
||||
sn_utils::ls_int32(s, iNumVerts);
|
||||
sn_utils::ls_int32(s, (int)iVboPtr);
|
||||
*/
|
||||
sn_utils::ls_int32(s, tVboPtr);
|
||||
|
||||
if (TextureID <= 0)
|
||||
sn_utils::ls_int32(s, TextureID);
|
||||
else
|
||||
@@ -1358,9 +1314,6 @@ void TSubModel::serialize(std::ostream &s,
|
||||
|
||||
void TModel3d::SaveToBinFile(std::string const &FileName)
|
||||
{
|
||||
// TODO: re-implement!
|
||||
return;
|
||||
|
||||
WriteLog("saving e3d model..");
|
||||
|
||||
//m7todo: można by zoptymalizować robiąc unordered_map
|
||||
@@ -1396,20 +1349,11 @@ void TModel3d::SaveToBinFile(std::string const &FileName)
|
||||
sn_utils::ls_uint32(s, 8 + (uint32_t)transforms.size() * 64);
|
||||
for (size_t i = 0; i < transforms.size(); i++)
|
||||
transforms[i].serialize_float32(s);
|
||||
/*
|
||||
MakeArray(iNumVerts);
|
||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
||||
Root->RaArrayFill(m_pVNT);
|
||||
#else
|
||||
Root->RaArrayFill( m_pVNT.data() );
|
||||
#endif
|
||||
*/
|
||||
sn_utils::ls_uint32(s, MAKE_ID4('V', 'N', 'T', '0'));
|
||||
|
||||
sn_utils::ls_uint32(s, MAKE_ID4('V', 'N', 'T', '0'));
|
||||
sn_utils::ls_uint32(s, 8 + iNumVerts * 32);
|
||||
/*
|
||||
for (size_t i = 0; i < (size_t)iNumVerts; i++)
|
||||
m_pVNT[i].serialize(s);
|
||||
*/
|
||||
Root->serialize_geometry( s );
|
||||
|
||||
if (textures.size())
|
||||
{
|
||||
sn_utils::ls_uint32(s, MAKE_ID4('T', 'E', 'X', '0'));
|
||||
@@ -1555,6 +1499,7 @@ void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
|
||||
for( auto const &submodeloffset : submodeloffsets ) {
|
||||
auto &submodel = Root[ submodeloffset.second ];
|
||||
vertex_array vertices; vertices.resize( submodel.iNumVerts );
|
||||
iNumVerts += submodel.iNumVerts;
|
||||
for( auto &vertex : vertices ) {
|
||||
vertex.deserialize( s );
|
||||
}
|
||||
@@ -1669,12 +1614,13 @@ void TSubModel::BinInit(TSubModel *s, float4x4 *m, std::vector<std::string> *t,
|
||||
if (pTexture.find_last_of("/\\") == std::string::npos)
|
||||
pTexture.insert(0, Global::asCurrentTexturePath);
|
||||
TextureID = GfxRenderer.GetTextureId(pTexture, szTexturePath);
|
||||
/*
|
||||
iFlags |=
|
||||
( GfxRenderer.Texture( TextureID ).has_alpha ?
|
||||
0x20 :
|
||||
0x10 ); // 0x10-nieprzezroczysta, 0x20-przezroczysta
|
||||
*/
|
||||
if( ( iFlags & 0x30 ) == 0 ) {
|
||||
// texture-alpha based fallback if for some reason we don't have opacity flag set yet
|
||||
iFlags |=
|
||||
( GfxRenderer.Texture( TextureID ).has_alpha ?
|
||||
0x20 :
|
||||
0x10 ); // 0x10-nieprzezroczysta, 0x20-przezroczysta
|
||||
}
|
||||
}
|
||||
else
|
||||
TextureID = iTexture;
|
||||
@@ -1688,10 +1634,10 @@ void TSubModel::BinInit(TSubModel *s, float4x4 *m, std::vector<std::string> *t,
|
||||
iFlags |= 0x20;
|
||||
}
|
||||
// intercept and fix hotspot values if specified in degrees and not directly
|
||||
if( fCosFalloffAngle > 1.0 ) {
|
||||
if( fCosFalloffAngle > 1.0f ) {
|
||||
fCosFalloffAngle = std::cos( DegToRad( 0.5f * fCosFalloffAngle ) );
|
||||
}
|
||||
if( fCosHotspotAngle > 1.0 ) {
|
||||
if( fCosHotspotAngle > 1.0f ) {
|
||||
fCosHotspotAngle = std::cos( DegToRad( 0.5f * fCosHotspotAngle ) );
|
||||
}
|
||||
|
||||
@@ -1784,17 +1730,17 @@ void TModel3d::Init()
|
||||
Root->InitialRotate(true); // argumet określa, czy wykonać pierwotny obrót
|
||||
}
|
||||
iFlags |= Root->FlagsCheck() | 0x8000; // flagi całego modelu
|
||||
if (false == asBinary.empty()) // jeśli jest podana nazwa
|
||||
{
|
||||
if (Global::iConvertModels) // i włączony zapis
|
||||
SaveToBinFile( asBinary ); // utworzy tablicę (m_pVNT)
|
||||
asBinary = ""; // zablokowanie powtórnego zapisu
|
||||
}
|
||||
if (iNumVerts) {
|
||||
if( m_geometrybank == NULL ) {
|
||||
m_geometrybank = GfxRenderer.Create_Bank();
|
||||
}
|
||||
Root->create_geometry( m_geometrybank );
|
||||
std::size_t dataoffset = 0;
|
||||
Root->create_geometry( dataoffset, m_geometrybank );
|
||||
}
|
||||
if( ( Global::iConvertModels > 0 )
|
||||
&& ( false == asBinary.empty() ) ) {
|
||||
SaveToBinFile( asBinary );
|
||||
asBinary = ""; // zablokowanie powtórnego zapisu
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
110
Model3d.h
110
Model3d.h
@@ -7,8 +7,7 @@ obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef Model3dH
|
||||
#define Model3dH
|
||||
#pragma once
|
||||
|
||||
#include "GL/glew.h"
|
||||
#include "Parser.h"
|
||||
@@ -51,8 +50,6 @@ enum TAnimType // rodzaj animacji
|
||||
at_Undefined = 0x800000FF // animacja chwilowo nieokreślona
|
||||
};
|
||||
|
||||
class TModel3d;
|
||||
|
||||
class TSubModel
|
||||
{ // klasa submodelu - pojedyncza siatka, punkt świetlny albo grupa punktów
|
||||
//m7todo: zrobić normalną serializację
|
||||
@@ -61,15 +58,16 @@ class TSubModel
|
||||
friend class TModel3d; // temporary workaround. TODO: clean up class content/hierarchy
|
||||
|
||||
private:
|
||||
int iNext;
|
||||
int iChild;
|
||||
int eType; // Ra: modele binarne dają więcej możliwości niż mesh złożony z trójkątów
|
||||
int iName; // numer łańcucha z nazwą submodelu, albo -1 gdy anonimowy
|
||||
int iNext{ NULL };
|
||||
int iChild{ NULL };
|
||||
int eType{ TP_ROTATOR }; // Ra: modele binarne dają więcej możliwości niż mesh złożony z trójkątów
|
||||
int iName{ -1 }; // numer łańcucha z nazwą submodelu, albo -1 gdy anonimowy
|
||||
public: // chwilowo
|
||||
TAnimType b_Anim;
|
||||
TAnimType b_Anim{ at_None };
|
||||
|
||||
private:
|
||||
int iFlags; // flagi informacyjne:
|
||||
int iFlags{ 0x0200 }; // bit 9=1: submodel został utworzony a nie ustawiony na wczytany plik
|
||||
// flagi informacyjne:
|
||||
// bit 0: =1 faza rysowania zależy od wymiennej tekstury 0
|
||||
// bit 1: =1 faza rysowania zależy od wymiennej tekstury 1
|
||||
// bit 2: =1 faza rysowania zależy od wymiennej tekstury 2
|
||||
@@ -84,63 +82,62 @@ private:
|
||||
// bit 15: =1 wymagane przechowanie macierzy (transform niejedynkowy)
|
||||
union
|
||||
{ // transform, nie każdy submodel musi mieć
|
||||
float4x4 *fMatrix; // pojedyncza precyzja wystarcza
|
||||
float4x4 *fMatrix = nullptr; // pojedyncza precyzja wystarcza
|
||||
int iMatrix; // w pliku binarnym jest numer matrycy
|
||||
};
|
||||
int iNumVerts; // ilość wierzchołków (1 dla FreeSpotLight)
|
||||
int iNumVerts{ -1 }; // ilość wierzchołków (1 dla FreeSpotLight)
|
||||
int tVboPtr; // początek na liście wierzchołków albo indeksów
|
||||
int iTexture; // numer nazwy tekstury, -1 wymienna, 0 brak
|
||||
float fVisible; // próg jasności światła do załączenia submodelu
|
||||
float fLight; // próg jasności światła do zadziałania selfillum
|
||||
int iTexture{ 0 }; // numer nazwy tekstury, -1 wymienna, 0 brak
|
||||
float fVisible{ 0.0f }; // próg jasności światła do załączenia submodelu
|
||||
float fLight{ -1.0f }; // próg jasności światła do zadziałania selfillum
|
||||
glm::vec4
|
||||
f4Ambient,
|
||||
f4Diffuse,
|
||||
f4Specular,
|
||||
f4Emision;
|
||||
float fWireSize; // nie używane, ale wczytywane
|
||||
float fSquareMaxDist;
|
||||
float fSquareMinDist;
|
||||
f4Ambient{ 1.0f,1.0f,1.0f,1.0f },
|
||||
f4Diffuse{ 1.0f,1.0f,1.0f,1.0f },
|
||||
f4Specular{ 0.0f,0.0f,0.0f,1.0f },
|
||||
f4Emision{ 1.0f,1.0f,1.0f,1.0f };
|
||||
float fWireSize{ 0.0f }; // nie używane, ale wczytywane
|
||||
float fSquareMaxDist{ 10000.0f * 10000.0f };
|
||||
float fSquareMinDist{ 0.0f };
|
||||
// McZapkie-050702: parametry dla swiatla:
|
||||
float fNearAttenStart;
|
||||
float fNearAttenEnd;
|
||||
bool bUseNearAtten; // te 3 zmienne okreslaja rysowanie aureoli wokol zrodla swiatla
|
||||
int iFarAttenDecay; // ta zmienna okresla typ zaniku natezenia swiatla (0:brak, 1,2: potega 1/R)
|
||||
float fFarDecayRadius; // normalizacja j.w.
|
||||
float fCosFalloffAngle; // cosinus kąta stożka pod którym widać światło
|
||||
float fCosHotspotAngle; // cosinus kąta stożka pod którym widać aureolę i zwiększone natężenie światła
|
||||
float fCosViewAngle; // cos kata pod jakim sie teraz patrzy
|
||||
float fNearAttenStart{ 40.0f };
|
||||
float fNearAttenEnd{ 80.0f };
|
||||
bool bUseNearAtten{ false }; // te 3 zmienne okreslaja rysowanie aureoli wokol zrodla swiatla
|
||||
int iFarAttenDecay{ 0 }; // ta zmienna okresla typ zaniku natezenia swiatla (0:brak, 1,2: potega 1/R)
|
||||
float fFarDecayRadius{ 100.0f }; // normalizacja j.w.
|
||||
float fCosFalloffAngle{ 0.5f }; // cosinus kąta stożka pod którym widać światło
|
||||
float fCosHotspotAngle{ 0.3f }; // cosinus kąta stożka pod którym widać aureolę i zwiększone natężenie światła
|
||||
float fCosViewAngle{ 0.0f }; // cos kata pod jakim sie teraz patrzy
|
||||
|
||||
TSubModel *Next;
|
||||
TSubModel *Child;
|
||||
TSubModel *Next{ nullptr };
|
||||
TSubModel *Child{ nullptr };
|
||||
/*
|
||||
intptr_t iVboPtr;
|
||||
*/
|
||||
geometry_handle m_geometry; // geometry of the submodel
|
||||
texture_handle TextureID; // numer tekstury, -1 wymienna, 0 brak
|
||||
bool bWire; // nie używane, ale wczytywane
|
||||
geometry_handle m_geometry{ NULL, NULL }; // geometry of the submodel
|
||||
texture_handle TextureID{ NULL }; // numer tekstury, -1 wymienna, 0 brak
|
||||
bool bWire{ false }; // nie używane, ale wczytywane
|
||||
/*
|
||||
GLuint uiDisplayList; // roboczy numer listy wyświetlania
|
||||
*/
|
||||
float Opacity; // nie używane, ale wczytywane //m7todo: wywalić to
|
||||
float f_Angle;
|
||||
float3 v_RotateAxis;
|
||||
float3 v_Angles;
|
||||
float Opacity{ 1.0f };
|
||||
float f_Angle{ 0.0f };
|
||||
float3 v_RotateAxis{ 0.0f, 0.0f, 0.0f };
|
||||
float3 v_Angles { 0.0f, 0.0f, 0.0f };
|
||||
|
||||
public: // chwilowo
|
||||
float3 v_TransVector;
|
||||
float3 v_TransVector{ 0.0f, 0.0f, 0.0f };
|
||||
/*
|
||||
basic_vertex *Vertices; // roboczy wskaźnik - wczytanie T3D do VBO
|
||||
*/
|
||||
vertex_array Vertices;
|
||||
size_t iAnimOwner; // roboczy numer egzemplarza, który ustawił animację
|
||||
TAnimType b_aAnim; // kody animacji oddzielnie, bo zerowane
|
||||
size_t iAnimOwner{ NULL }; // roboczy numer egzemplarza, który ustawił animację
|
||||
TAnimType b_aAnim{ at_None }; // kody animacji oddzielnie, bo zerowane
|
||||
public:
|
||||
float4x4 *mAnimMatrix; // macierz do animacji kwaternionowych (należy do AnimContainer)
|
||||
float4x4 *mAnimMatrix{ nullptr }; // macierz do animacji kwaternionowych (należy do AnimContainer)
|
||||
public:
|
||||
TSubModel **
|
||||
smLetter; // wskaźnik na tablicę submdeli do generoania tekstu (docelowo zapisać do E3D)
|
||||
TSubModel *Parent; // nadrzędny, np. do wymnażania macierzy
|
||||
int iVisible; // roboczy stan widoczności
|
||||
TSubModel **smLetter{ nullptr }; // wskaźnik na tablicę submdeli do generoania tekstu (docelowo zapisać do E3D)
|
||||
TSubModel *Parent{ nullptr }; // nadrzędny, np. do wymnażania macierzy
|
||||
int iVisible{ 1 }; // roboczy stan widoczności
|
||||
std::string pTexture; // robocza nazwa tekstury do zapisania w pliku binarnym
|
||||
std::string pName; // robocza nazwa
|
||||
private:
|
||||
@@ -154,9 +151,7 @@ public:
|
||||
static double fSquareDist;
|
||||
static TModel3d *pRoot;
|
||||
static std::string *pasText; // tekst dla wyświetlacza (!!!! do przemyślenia)
|
||||
TSubModel();
|
||||
~TSubModel();
|
||||
void FirstInit();
|
||||
int Load(cParser &Parser, TModel3d *Model, /*int Pos,*/ bool dynamic);
|
||||
void ChildAdd(TSubModel *SubModel);
|
||||
void NextAdd(TSubModel *SubModel);
|
||||
@@ -176,10 +171,8 @@ public:
|
||||
TSubModel * GetFromName(char const *search, bool i = true);
|
||||
inline float4x4 * GetMatrix() { return fMatrix; };
|
||||
inline void Hide() { iVisible = 0; };
|
||||
/*
|
||||
void RaArrayFill(basic_vertex *Vert);
|
||||
*/
|
||||
void create_geometry( geometrybank_handle const &Bank );
|
||||
|
||||
void create_geometry( std::size_t &Dataoffset, geometrybank_handle const &Bank );
|
||||
int FlagsCheck();
|
||||
void WillBeAnimated()
|
||||
{
|
||||
@@ -187,9 +180,6 @@ public:
|
||||
iFlags |= 0x4000;
|
||||
};
|
||||
void InitialRotate(bool doit);
|
||||
#ifdef EU07_USE_OLD_DRAW_CODE
|
||||
void DisplayLists();
|
||||
#endif
|
||||
void BinInit(TSubModel *s, float4x4 *m, std::vector<std::string> *t, std::vector<std::string> *n, bool dynamic);
|
||||
void ReplacableSet(texture_handle const *r, int a)
|
||||
{
|
||||
@@ -219,11 +209,13 @@ public:
|
||||
void AdjustDist();
|
||||
|
||||
void deserialize(std::istream&);
|
||||
void TSubModel::serialize(std::ostream&,
|
||||
void serialize(std::ostream&,
|
||||
std::vector<TSubModel*>&,
|
||||
std::vector<std::string>&,
|
||||
std::vector<std::string>&,
|
||||
std::vector<float4x4>&);
|
||||
void serialize_geometry( std::ostream &Output );
|
||||
|
||||
};
|
||||
|
||||
class TModel3d : public CMesh
|
||||
@@ -259,11 +251,7 @@ public:
|
||||
std::string NameGet() { return m_filename; };
|
||||
int TerrainCount();
|
||||
TSubModel * TerrainSquare(int n);
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
void TerrainRenderVBO(int n);
|
||||
#endif
|
||||
void deserialize(std::istream &s, size_t size, bool dynamic);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
|
||||
@@ -292,7 +292,7 @@ void TPythonScreenRenderer::updateTexture()
|
||||
WriteLog(buff);
|
||||
#endif // _PY_INT_MORE_LOG
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glBindTexture(GL_TEXTURE_2D, _textureId);
|
||||
GfxRenderer.Bind(_textureId);
|
||||
// setup texture parameters
|
||||
if( GLEW_VERSION_1_4 ) {
|
||||
|
||||
|
||||
10
World.cpp
10
World.cpp
@@ -1651,15 +1651,13 @@ TWorld::Update_UI() {
|
||||
case( GLFW_KEY_F8 ) : {
|
||||
// gfx renderer data
|
||||
uitextline1 =
|
||||
"Draw range x " + to_string( Global::fDistanceFactor, 1 )
|
||||
+ "; FPS: " + to_string( Timer::GetFPS(), 2 );
|
||||
"FoV: " + to_string( Global::FieldOfView / Global::ZoomFactor, 1 )
|
||||
+ ", Draw range x " + to_string( Global::fDistanceFactor, 1 )
|
||||
+ "; sectors: " + std::to_string( GfxRenderer.m_drawcount )
|
||||
+ ", FPS: " + to_string( Timer::GetFPS(), 2 );
|
||||
if( Global::iSlowMotion ) {
|
||||
uitextline1 += " (slowmotion " + to_string( Global::iSlowMotion ) + ")";
|
||||
}
|
||||
uitextline1 +=
|
||||
", sectors: " + std::to_string( GfxRenderer.m_drawcount )
|
||||
+ "/" + std::to_string( Global::iSegmentsRendered )
|
||||
+ "; FoV: " + to_string( Global::FieldOfView / Global::ZoomFactor, 1 );
|
||||
|
||||
uitextline2 =
|
||||
std::string( "Rendering mode: " )
|
||||
|
||||
@@ -15,7 +15,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "globals.h"
|
||||
|
||||
void
|
||||
basic_vertex::serialize( std::ostream &s ) {
|
||||
basic_vertex::serialize( std::ostream &s ) const {
|
||||
|
||||
sn_utils::ls_float32( s, position.x );
|
||||
sn_utils::ls_float32( s, position.y );
|
||||
|
||||
@@ -27,7 +27,7 @@ struct basic_vertex {
|
||||
basic_vertex( glm::vec3 const&Position, glm::vec3 const &Normal, glm::vec2 const &Texture ) :
|
||||
position( Position ), normal( Normal ), texture( Texture )
|
||||
{}
|
||||
void serialize( std::ostream& );
|
||||
void serialize( std::ostream& ) const;
|
||||
void deserialize( std::istream& );
|
||||
};
|
||||
|
||||
@@ -111,10 +111,12 @@ protected:
|
||||
struct geometry_chunk {
|
||||
unsigned int type; // kind of geometry used by the chunk
|
||||
vertex_array vertices; // geometry data
|
||||
|
||||
// NOTE: constructor doesn't copy provided vertex data, but moves it
|
||||
geometry_chunk( vertex_array &Vertices, unsigned int const Type ) :
|
||||
vertices( Vertices ), type( Type )
|
||||
{}
|
||||
type( Type )
|
||||
{
|
||||
vertices.swap( Vertices );
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<geometry_chunk> geometrychunk_sequence;
|
||||
|
||||
181
renderer.cpp
181
renderer.cpp
@@ -368,7 +368,14 @@ opengl_renderer::Render( TGround *Ground ) {
|
||||
++TGroundRect::iFrameNumber; // zwięszenie licznika ramek (do usuwniania nadanimacji)
|
||||
|
||||
Update_Lights( Ground->m_lights );
|
||||
/*
|
||||
|
||||
m_drawqueue.clear();
|
||||
|
||||
// rednerowanie globalnych (nie za często?)
|
||||
for( TGroundNode *node = Ground->srGlobal.nRenderHidden; node; node = node->nNext3 ) {
|
||||
node->RenderHidden();
|
||||
}
|
||||
|
||||
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 );
|
||||
@@ -380,89 +387,40 @@ opengl_renderer::Render( TGround *Ground ) {
|
||||
for( int row = originz; row <= originz + segmentcount; ++row ) {
|
||||
|
||||
auto *cell = &Ground->Rects[ column ][ row ];
|
||||
|
||||
for( int subcellcolumn = 0; subcellcolumn < iNumSubRects; ++subcellcolumn ) {
|
||||
for( int subcellrow = 0; subcellrow < iNumSubRects; ++subcellrow ) {
|
||||
auto subcell = cell->FastGetSubRect( subcellcolumn, subcellrow );
|
||||
if( subcell == nullptr ) { continue; }
|
||||
// renderowanie obiektów aktywnych a niewidocznych
|
||||
for( auto node = subcell->nRenderHidden; node; node = node->nNext3 ) {
|
||||
node->RenderHidden();
|
||||
}
|
||||
// jeszcze dźwięki pojazdów by się przydały, również niewidocznych
|
||||
subcell->RenderSounds();
|
||||
}
|
||||
}
|
||||
|
||||
if( m_camera.visible( cell->m_area ) ) {
|
||||
Render( cell );
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
Ground->CameraDirection.x = std::sin( Global::pCameraRotation ); // wektor kierunkowy
|
||||
Ground->CameraDirection.z = std::cos( Global::pCameraRotation );
|
||||
TGroundNode *node;
|
||||
// rednerowanie globalnych (nie za często?)
|
||||
for( node = Ground->srGlobal.nRenderHidden; node; node = node->nNext3 ) {
|
||||
node->RenderHidden();
|
||||
|
||||
// draw queue was filled while rendering content of ground cells. now sort the nodes based on their distance to viewer...
|
||||
std::sort(
|
||||
std::begin( m_drawqueue ),
|
||||
std::end( m_drawqueue ),
|
||||
[]( distancesubcell_pair const &Left, distancesubcell_pair const &Right ) {
|
||||
return ( Left.first ) < ( Right.first ); } );
|
||||
// ...then render the opaque content of the visible subcells.
|
||||
for( auto subcellpair : m_drawqueue ) {
|
||||
Render( subcellpair.second );
|
||||
}
|
||||
// renderowanie czołgowe dla obiektów aktywnych a niewidocznych
|
||||
int n = 2 * iNumSubRects; //(2*==2km) promień wyświetlanej mapy w sektorach
|
||||
int c = Ground->GetColFromX( Global::pCameraPosition.x );
|
||||
int r = Ground->GetRowFromZ( Global::pCameraPosition.z );
|
||||
TSubRect *tmp;
|
||||
int i, j, k;
|
||||
for( j = r - n; j <= r + n; ++j ) {
|
||||
for( i = c - n; i <= c + n; ++i ) {
|
||||
if( ( tmp = Ground->FastGetSubRect( i, j ) ) != nullptr ) {
|
||||
// oznaczanie aktywnych sektorów
|
||||
tmp->LoadNodes();
|
||||
|
||||
for( node = tmp->nRenderHidden; node; node = node->nNext3 ) {
|
||||
node->RenderHidden();
|
||||
}
|
||||
// jeszcze dźwięki pojazdów by się przydały, również niewidocznych
|
||||
tmp->RenderSounds();
|
||||
}
|
||||
}
|
||||
}
|
||||
// renderowanie progresywne - zależne od FPS oraz kierunku patrzenia
|
||||
// pre-calculate camera view span
|
||||
double const fieldofviewcosine =
|
||||
std::cos(
|
||||
std::max(
|
||||
// vertical...
|
||||
Global::FieldOfView / Global::ZoomFactor,
|
||||
// ...or horizontal, whichever is bigger
|
||||
Global::FieldOfView / Global::ZoomFactor
|
||||
* std::max( 1.0f, (float)Global::ScreenWidth ) / std::max( 1.0f, (float)Global::ScreenHeight ) ) );
|
||||
|
||||
m_drawqueue.clear();
|
||||
|
||||
Math3D::vector3 direction;
|
||||
for( k = 0; k < Global::iSegmentsRendered; ++k ) // sektory w kolejności odległości
|
||||
{ // przerobione na użycie SectorOrder
|
||||
i = SectorOrder[ k ].x; // na starcie oba >=0
|
||||
j = SectorOrder[ k ].y;
|
||||
do {
|
||||
// pierwszy przebieg: j<=0, i>=0; drugi: j>=0, i<=0; trzeci: j<=0, i<=0 czwarty: j>=0, i>=0;
|
||||
if( j <= 0 )
|
||||
i = -i;
|
||||
j = -j; // i oraz j musi być zmienione wcześniej, żeby continue działało
|
||||
direction = Math3D::vector3( i, 0, j ); // wektor od kamery do danego sektora
|
||||
if( Math3D::LengthSquared3( direction ) > 5 ) // te blisko są zawsze wyświetlane
|
||||
{
|
||||
direction = Math3D::SafeNormalize( direction ); // normalizacja
|
||||
if( Ground->CameraDirection.x * direction.x + Ground->CameraDirection.z * direction.z < 0.5 )
|
||||
continue; // pomijanie sektorów poza kątem patrzenia
|
||||
}
|
||||
// kwadrat kilometrowy nie zawsze, bo szkoda FPS
|
||||
Render( &Ground->Rects[ ( i + c ) / iNumSubRects ][ ( j + r ) / iNumSubRects ] );
|
||||
|
||||
if( ( tmp = Ground->FastGetSubRect( i + c, j + r ) ) != nullptr ) {
|
||||
if( tmp->iNodeCount ) {
|
||||
// o ile są jakieś obiekty, bo po co puste sektory przelatywać
|
||||
m_drawqueue.emplace_back( tmp );
|
||||
}
|
||||
}
|
||||
} while( ( i < 0 ) || ( j < 0 ) ); // są 4 przypadki, oprócz i=j=0
|
||||
}
|
||||
|
||||
for( auto subcell : m_drawqueue ) {
|
||||
Render( subcell );
|
||||
}
|
||||
// regular render takes care of all solid geometry present in the scene, thus we can launch alpha parts render here
|
||||
// now hand the control over to the renderer of translucent parts, it'll do the rest
|
||||
return Render_Alpha( Ground );
|
||||
}
|
||||
|
||||
// TODO: unify ground render code, until then old version is in place
|
||||
bool
|
||||
opengl_renderer::Render( TGroundRect *Groundcell ) {
|
||||
|
||||
@@ -484,6 +442,19 @@ opengl_renderer::Render( TGroundRect *Groundcell ) {
|
||||
}
|
||||
Groundcell->iLastDisplay = Groundcell->iFrameNumber; // drugi raz nie potrzeba
|
||||
result = true;
|
||||
|
||||
// add the subcells of the cell to the draw queue
|
||||
if( Groundcell->pSubRects != nullptr ) {
|
||||
for( std::size_t subcellindex = 0; subcellindex < iNumSubRects * iNumSubRects; ++subcellindex ) {
|
||||
auto subcell = Groundcell->pSubRects + subcellindex;
|
||||
if( subcell->iNodeCount ) {
|
||||
// o ile są jakieś obiekty, bo po co puste sektory przelatywać
|
||||
m_drawqueue.emplace_back(
|
||||
( Global::pCameraPosition - glm::dvec3( subcell->m_area.center ) ).LengthSquared(),
|
||||
subcell );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -491,6 +462,9 @@ opengl_renderer::Render( TGroundRect *Groundcell ) {
|
||||
bool
|
||||
opengl_renderer::Render( TSubRect *Groundsubcell ) {
|
||||
|
||||
// oznaczanie aktywnych sektorów
|
||||
Groundsubcell->LoadNodes();
|
||||
|
||||
Groundsubcell->RaAnimate(); // przeliczenia animacji torów w sektorze
|
||||
|
||||
TGroundNode *node;
|
||||
@@ -906,23 +880,23 @@ opengl_renderer::Render_Alpha( TGround *Ground ) {
|
||||
TGroundNode *node;
|
||||
TSubRect *tmp;
|
||||
// Ra: renderowanie progresywne - zależne od FPS oraz kierunku patrzenia
|
||||
for( auto subcell = std::rbegin( m_drawqueue ); subcell != std::rend( m_drawqueue ); ++subcell ) {
|
||||
for( auto subcellpair = std::rbegin( m_drawqueue ); subcellpair != std::rend( m_drawqueue ); ++subcellpair ) {
|
||||
// przezroczyste trójkąty w oddzielnym cyklu przed modelami
|
||||
tmp = *subcell;
|
||||
tmp = subcellpair->second;
|
||||
for( node = tmp->nRenderRectAlpha; node; node = node->nNext3 ) {
|
||||
Render_Alpha( node );
|
||||
}
|
||||
}
|
||||
for( auto subcell = std::rbegin( m_drawqueue ); subcell != std::rend( m_drawqueue ); ++subcell )
|
||||
for( auto subcellpair = std::rbegin( m_drawqueue ); subcellpair != std::rend( m_drawqueue ); ++subcellpair )
|
||||
{ // renderowanie przezroczystych modeli oraz pojazdów
|
||||
Render_Alpha( *subcell );
|
||||
Render_Alpha( subcellpair->second );
|
||||
}
|
||||
|
||||
::glDisable( GL_LIGHTING ); // linie nie powinny świecić
|
||||
|
||||
for( auto subcell = std::rbegin( m_drawqueue ); subcell != std::rend( m_drawqueue ); ++subcell ) {
|
||||
for( auto subcellpair = std::rbegin( m_drawqueue ); subcellpair != std::rend( m_drawqueue ); ++subcellpair ) {
|
||||
// druty na końcu, żeby się nie robiły białe plamy na tle lasu
|
||||
tmp = *subcell;
|
||||
tmp = subcellpair->second;
|
||||
for( node = tmp->nRenderWires; node; node = node->nNext3 ) {
|
||||
Render_Alpha( node );
|
||||
}
|
||||
@@ -947,25 +921,9 @@ opengl_renderer::Render_Alpha( TSubRect *Groundsubcell ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 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
|
||||
double const distancesquared = SquareMagnitude( ( Node->pCenter - Global::pCameraPosition ) / Global::ZoomFactor );
|
||||
if( ( distancesquared > ( Node->fSquareRadius * Global::fDistanceFactor ) )
|
||||
|| ( distancesquared < ( Node->fSquareMinRadius / Global::fDistanceFactor ) ) ) {
|
||||
@@ -1029,14 +987,15 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
||||
return false;
|
||||
}
|
||||
// setup
|
||||
// w zaleznosci od koloru swiatla
|
||||
auto const linewidth = clamp( 100.0 * Node->fLineThickness / ( distancesquared + 1.0 ), 1.0, 10.0 );
|
||||
::glColor4fv(
|
||||
glm::value_ptr(
|
||||
glm::vec4(
|
||||
Node->Diffuse * glm::make_vec3( Global::DayLight.ambient ),
|
||||
std::min(
|
||||
1.0,
|
||||
1000.0 * Node->fLineThickness / ( distancesquared + 1.0 ) ) ) ) );
|
||||
Node->Diffuse * glm::make_vec3( Global::DayLight.ambient ), // w zaleznosci od koloru swiatla
|
||||
std::min( 1.0, linewidth ) ) ) );
|
||||
if( linewidth > 1.0 ) {
|
||||
::glLineWidth( static_cast<float>(linewidth) );
|
||||
}
|
||||
|
||||
GfxRenderer.Bind( 0 );
|
||||
|
||||
@@ -1048,6 +1007,10 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
||||
m_geometry.draw( Node->m_geometry );
|
||||
|
||||
// post-render cleanup
|
||||
if( linewidth > 1.0 ) {
|
||||
::glLineWidth( 1.0f );
|
||||
}
|
||||
|
||||
::glPopMatrix();
|
||||
|
||||
return true;
|
||||
@@ -1059,13 +1022,6 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
||||
return false;
|
||||
}
|
||||
// setup
|
||||
#ifdef _PROBLEND
|
||||
if( ( Node->PROBLEND ) ) // sprawdza, czy w nazwie nie ma @ //Q: 13122011 - Szociu: 27012012
|
||||
{
|
||||
::glDisable( GL_BLEND );
|
||||
::glAlphaFunc( GL_GREATER, 0.50f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f
|
||||
};
|
||||
#endif
|
||||
::glColor3fv( glm::value_ptr( Node->Diffuse ) );
|
||||
|
||||
Bind( Node->TextureID );
|
||||
@@ -1080,13 +1036,6 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
||||
// post-render cleanup
|
||||
::glPopMatrix();
|
||||
|
||||
#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 true;
|
||||
}
|
||||
|
||||
|
||||
@@ -182,6 +182,8 @@ private:
|
||||
|
||||
typedef std::vector<opengl_light> opengllight_array;
|
||||
|
||||
typedef std::pair< double, TSubRect * > distancesubcell_pair;
|
||||
|
||||
// methods
|
||||
bool
|
||||
Init_caps();
|
||||
@@ -226,7 +228,7 @@ private:
|
||||
texture_handle m_moontexture { -1 };
|
||||
geometry_handle m_billboardgeometry { 0, 0 };
|
||||
GLUquadricObj *m_quadric; // helper object for drawing debug mode scene elements
|
||||
std::vector< TSubRect* > m_drawqueue; // list of subcells to be drawn in current render pass
|
||||
std::vector<distancesubcell_pair> m_drawqueue; // list of subcells to be drawn in current render pass
|
||||
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user