mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 17:29: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 "world.h"
|
||||||
#include "uilayer.h"
|
#include "uilayer.h"
|
||||||
|
|
||||||
#define _PROBLEND 1
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
@@ -1283,18 +1282,16 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
*parser >> token;
|
*parser >> token;
|
||||||
}
|
}
|
||||||
str = 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->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)
|
if( (tmp->iType == GL_TRIANGLES)
|
||||||
&& (tmp->iFlags & 0x10)
|
&& (tmp->iFlags & 0x10)
|
||||||
&& (Global::pTerrainCompact->TerrainLoaded()) ) {
|
&& (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::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.normal = glm::rotateY( vertex.normal, static_cast<float>( aRotate.y / 180 * M_PI ) );
|
||||||
vertex.position += glm::dvec3( pOrigin.x, pOrigin.y, pOrigin.z );
|
vertex.position += glm::dvec3( pOrigin.x, pOrigin.y, pOrigin.z );
|
||||||
tmp->pCenter += vertex.position;
|
|
||||||
// convert all data to gl_triangles to allow data merge for matching nodes
|
// convert all data to gl_triangles to allow data merge for matching nodes
|
||||||
switch( tmp->iType ) {
|
switch( tmp->iType ) {
|
||||||
case GL_TRIANGLES: {
|
case GL_TRIANGLES: {
|
||||||
@@ -1370,6 +1366,10 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
|
|
||||||
auto const nv = importedvertices.size();
|
auto const nv = importedvertices.size();
|
||||||
tmp->Init(nv); // utworzenie tablicy wierzchołków
|
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);
|
tmp->pCenter /= (nv > 0 ? nv : 1);
|
||||||
|
|
||||||
r = 0;
|
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::rotateY( vertex.position, aRotate.y / 180 * M_PI );
|
||||||
|
|
||||||
vertex.position += glm::dvec3( pOrigin.x, pOrigin.y, pOrigin.z );
|
vertex.position += glm::dvec3( pOrigin.x, pOrigin.y, pOrigin.z );
|
||||||
tmp->pCenter += vertex.position;
|
|
||||||
// convert all data to gl_lines to allow data merge for matching nodes
|
// convert all data to gl_lines to allow data merge for matching nodes
|
||||||
switch( tmp->iType ) {
|
switch( tmp->iType ) {
|
||||||
case GL_LINES: {
|
case GL_LINES: {
|
||||||
@@ -1460,10 +1459,11 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
auto const nv = importedvertices.size();
|
auto const nv = importedvertices.size();
|
||||||
tmp->Points = new glm::dvec3[ nv ];
|
tmp->Points = new glm::dvec3[ nv ];
|
||||||
tmp->iNumPts = nv;
|
tmp->iNumPts = nv;
|
||||||
tmp->pCenter /= ( nv > 0 ? nv : 1 );
|
|
||||||
for( std::size_t i = 0; i < nv; ++i ) {
|
for( std::size_t i = 0; i < nv; ++i ) {
|
||||||
tmp->Points[ i ] = importedvertices[ i ].position;
|
tmp->Points[ i ] = importedvertices[ i ].position;
|
||||||
|
tmp->pCenter += importedvertices[ i ].position;
|
||||||
}
|
}
|
||||||
|
tmp->pCenter /= ( nv > 0 ? nv : 1 );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2
Ground.h
2
Ground.h
@@ -149,7 +149,6 @@ public:
|
|||||||
Diffuse{ 1.0f, 1.0f, 1.0f },
|
Diffuse{ 1.0f, 1.0f, 1.0f },
|
||||||
Specular{ 1.0f, 1.0f, 1.0f }; // oświetlenie
|
Specular{ 1.0f, 1.0f, 1.0f }; // oświetlenie
|
||||||
double fLineThickness; // McZapkie-120702: grubosc linii
|
double fLineThickness; // McZapkie-120702: grubosc linii
|
||||||
bool PROBLEND;
|
|
||||||
bool bVisible;
|
bool bVisible;
|
||||||
|
|
||||||
TGroundNode();
|
TGroundNode();
|
||||||
@@ -283,7 +282,6 @@ class TGround
|
|||||||
event_map m_eventmap;
|
event_map m_eventmap;
|
||||||
TNames<TGroundNode *> m_trackmap;
|
TNames<TGroundNode *> m_trackmap;
|
||||||
light_array m_lights; // collection of dynamic light sources present in the scene
|
light_array m_lights; // collection of dynamic light sources present in the scene
|
||||||
bool PROBLEND;
|
|
||||||
|
|
||||||
private: // metody prywatne
|
private: // metody prywatne
|
||||||
bool EventConditon(TEvent *e);
|
bool EventConditon(TEvent *e);
|
||||||
|
|||||||
218
Model3d.cpp
218
Model3d.cpp
@@ -42,69 +42,6 @@ std::string *TSubModel::pasText;
|
|||||||
// 0x3F3F003F - wszystkie wymienne tekstury używane w danym cyklu
|
// 0x3F3F003F - wszystkie wymienne tekstury używane w danym cyklu
|
||||||
// Ale w TModel3d okerśla przezroczystość tekstur wymiennych!
|
// 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()
|
TSubModel::~TSubModel()
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@@ -141,9 +78,6 @@ void TSubModel::NameSet(std::string const &Name)
|
|||||||
pName = 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)
|
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
|
{ // 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
|
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;
|
std::vector<glm::vec3> facenormals;
|
||||||
for( int i = 0; i < facecount; ++i ) {
|
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
|
// pętla po trójkątach - będzie szybciej, jak wstępnie przeliczymy normalne trójkątów
|
||||||
facenormals.emplace_back(
|
auto facenormal =
|
||||||
glm::normalize(
|
|
||||||
glm::cross(
|
glm::cross(
|
||||||
Vertices[ i * 3 ].position - Vertices[ i * 3 + 1 ].position,
|
Vertices[ i * 3 ].position - Vertices[ i * 3 + 1 ].position,
|
||||||
Vertices[ i * 3 ].position - Vertices[ i * 3 + 2 ].position ) ) );
|
Vertices[ i * 3 ].position - Vertices[ i * 3 + 2 ].position );
|
||||||
|
facenormals.emplace_back(
|
||||||
|
glm::length( facenormal ) > 0.0f ?
|
||||||
|
glm::normalize( facenormal ) :
|
||||||
|
glm::vec3() );
|
||||||
}
|
}
|
||||||
glm::vec3 vertexnormal; // roboczy wektor normalny
|
glm::vec3 vertexnormal; // roboczy wektor normalny
|
||||||
for (int vertexidx = 0; vertexidx < iNumVerts; ++vertexidx) {
|
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);
|
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
|
// 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 ) {
|
if( eType != TP_STARS ) {
|
||||||
// gwiazdki mają kolory zamiast normalnych, to ich wtedy nie ruszamy
|
// gwiazdki mają kolory zamiast normalnych, to ich wtedy nie ruszamy
|
||||||
for( auto &vertex : Vertices ) {
|
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( auto &vertex : Vertices ) {
|
||||||
*/
|
*/
|
||||||
for( int idx = 0; idx < iNumVerts; ++idx ) {
|
for( auto &vertex : Vertices ) {
|
||||||
Vertices[idx].position.x = -Vertices[idx].position.x; // zmiana znaku X
|
vertex.position.x = -vertex.position.x; // zmiana znaku X
|
||||||
swapcopy = Vertices[idx].position.y; // zamiana Y i Z
|
swapcopy = vertex.position.y; // zamiana Y i Z
|
||||||
Vertices[idx].position.y = Vertices[idx].position.z;
|
vertex.position.y = vertex.position.z;
|
||||||
Vertices[idx].position.z = swapcopy;
|
vertex.position.z = swapcopy;
|
||||||
// wektory normalne również trzeba przekształcić, bo się źle oświetlają
|
// wektory normalne również trzeba przekształcić, bo się źle oświetlają
|
||||||
if( eType != TP_STARS ) {
|
if( eType != TP_STARS ) {
|
||||||
// gwiazdki mają kolory zamiast normalnych, to // ich wtedy nie ruszamy
|
// gwiazdki mają kolory zamiast normalnych, to // ich wtedy nie ruszamy
|
||||||
Vertices[idx].normal.x = -Vertices[idx].normal.x; // zmiana znaku X
|
vertex.normal.x = -vertex.normal.x; // zmiana znaku X
|
||||||
swapcopy = Vertices[idx].normal.y; // zamiana Y i Z
|
swapcopy = vertex.normal.y; // zamiana Y i Z
|
||||||
Vertices[idx].normal.y = Vertices[idx].normal.z;
|
vertex.normal.y = vertex.normal.z;
|
||||||
Vertices[idx].normal.z = swapcopy;
|
vertex.normal.z = swapcopy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// }
|
// }
|
||||||
@@ -1050,30 +993,34 @@ void TSubModel::RaAnimation(TAnimType a)
|
|||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
/*
|
|
||||||
void TSubModel::RaArrayFill(basic_vertex *Vert)
|
void TSubModel::serialize_geometry( std::ostream &Output ) {
|
||||||
{ // wypełnianie tablic VBO
|
|
||||||
if (Child)
|
if( Child ) {
|
||||||
Child->RaArrayFill(Vert);
|
Child->serialize_geometry( Output );
|
||||||
if( ( eType < TP_ROTATOR ) || ( eType == TP_STARS ) )
|
}
|
||||||
for( int i = 0; i < iNumVerts; ++i ) {
|
if( m_geometry != NULL ) {
|
||||||
Vert[ iVboPtr + i ].position = Vertices[ i ].position;
|
for( auto const &vertex : GfxRenderer.Vertices( m_geometry ) ) {
|
||||||
Vert[ iVboPtr + i ].normal = Vertices[ i ].normal;
|
vertex.serialize( Output );
|
||||||
Vert[ iVboPtr + i ].texture = Vertices[ i ].texture;
|
}
|
||||||
|
}
|
||||||
|
if( Next ) {
|
||||||
|
Next->serialize_geometry( Output );
|
||||||
}
|
}
|
||||||
else if( eType == TP_FREESPOTLIGHT )
|
|
||||||
Vert[ iVboPtr ].position = glm::vec3();
|
|
||||||
if (Next)
|
|
||||||
Next->RaArrayFill(Vert);
|
|
||||||
};
|
};
|
||||||
*/
|
|
||||||
void
|
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 )
|
if( Child )
|
||||||
Child->create_geometry( Bank );
|
Child->create_geometry( Dataoffset, Bank );
|
||||||
|
|
||||||
if( false == Vertices.empty() ) {
|
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
|
// conveniently all relevant custom node types use GL_POINTS, or we'd have to determine the type on individual basis
|
||||||
auto type = (
|
auto type = (
|
||||||
eType < TP_ROTATOR ?
|
eType < TP_ROTATOR ?
|
||||||
@@ -1083,7 +1030,7 @@ TSubModel::create_geometry( geometrybank_handle const &Bank ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( Next )
|
if( Next )
|
||||||
Next->create_geometry( Bank );
|
Next->create_geometry( Dataoffset, Bank );
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: leftover from static distance factor adjustment.
|
// NOTE: leftover from static distance factor adjustment.
|
||||||
@@ -1140,19 +1087,16 @@ void TSubModel::ParentMatrix(float4x4 *m)
|
|||||||
// nie obrócono jeszcze
|
// nie obrócono jeszcze
|
||||||
};
|
};
|
||||||
|
|
||||||
float TSubModel::MaxY( float4x4 const &m )
|
// obliczenie maksymalnej wysokości, na początek ślizgu w pantografie
|
||||||
{ // obliczenie maksymalnej wysokości, na początek ślizgu w pantografie
|
float TSubModel::MaxY( float4x4 const &m ) {
|
||||||
if( eType != 4 ) {
|
|
||||||
// tylko dla trójkątów liczymy
|
// tylko dla trójkątów liczymy
|
||||||
return 0;
|
if( eType != 4 ) { return 0; }
|
||||||
}
|
|
||||||
if( m_geometry == NULL ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto maxy { 0.0f };
|
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 ) {
|
||||||
|
|
||||||
|
for( auto const &vertex : GfxRenderer.Vertices( m_geometry ) ) {
|
||||||
maxy = std::max(
|
maxy = std::max(
|
||||||
maxy,
|
maxy,
|
||||||
m[ 0 ][ 1 ] * vertex.position.x
|
m[ 0 ][ 1 ] * vertex.position.x
|
||||||
@@ -1160,6 +1104,18 @@ float TSubModel::MaxY( float4x4 const &m )
|
|||||||
+ m[ 2 ][ 1 ] * vertex.position.z
|
+ m[ 2 ][ 1 ] * vertex.position.z
|
||||||
+ m[ 3 ][ 1 ] );
|
+ 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;
|
return maxy;
|
||||||
};
|
};
|
||||||
@@ -1316,10 +1272,10 @@ void TSubModel::serialize(std::ostream &s,
|
|||||||
|
|
||||||
sn_utils::ls_int32(s, iFlags);
|
sn_utils::ls_int32(s, iFlags);
|
||||||
sn_utils::ls_int32(s, (int32_t)get_container_pos(transforms, *fMatrix));
|
sn_utils::ls_int32(s, (int32_t)get_container_pos(transforms, *fMatrix));
|
||||||
/*
|
|
||||||
sn_utils::ls_int32(s, iNumVerts);
|
sn_utils::ls_int32(s, iNumVerts);
|
||||||
sn_utils::ls_int32(s, (int)iVboPtr);
|
sn_utils::ls_int32(s, tVboPtr);
|
||||||
*/
|
|
||||||
if (TextureID <= 0)
|
if (TextureID <= 0)
|
||||||
sn_utils::ls_int32(s, TextureID);
|
sn_utils::ls_int32(s, TextureID);
|
||||||
else
|
else
|
||||||
@@ -1358,9 +1314,6 @@ void TSubModel::serialize(std::ostream &s,
|
|||||||
|
|
||||||
void TModel3d::SaveToBinFile(std::string const &FileName)
|
void TModel3d::SaveToBinFile(std::string const &FileName)
|
||||||
{
|
{
|
||||||
// TODO: re-implement!
|
|
||||||
return;
|
|
||||||
|
|
||||||
WriteLog("saving e3d model..");
|
WriteLog("saving e3d model..");
|
||||||
|
|
||||||
//m7todo: można by zoptymalizować robiąc unordered_map
|
//m7todo: można by zoptymalizować robiąc unordered_map
|
||||||
@@ -1396,20 +1349,11 @@ void TModel3d::SaveToBinFile(std::string const &FileName)
|
|||||||
sn_utils::ls_uint32(s, 8 + (uint32_t)transforms.size() * 64);
|
sn_utils::ls_uint32(s, 8 + (uint32_t)transforms.size() * 64);
|
||||||
for (size_t i = 0; i < transforms.size(); i++)
|
for (size_t i = 0; i < transforms.size(); i++)
|
||||||
transforms[i].serialize_float32(s);
|
transforms[i].serialize_float32(s);
|
||||||
/*
|
|
||||||
MakeArray(iNumVerts);
|
|
||||||
#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);
|
sn_utils::ls_uint32(s, 8 + iNumVerts * 32);
|
||||||
/*
|
Root->serialize_geometry( s );
|
||||||
for (size_t i = 0; i < (size_t)iNumVerts; i++)
|
|
||||||
m_pVNT[i].serialize(s);
|
|
||||||
*/
|
|
||||||
if (textures.size())
|
if (textures.size())
|
||||||
{
|
{
|
||||||
sn_utils::ls_uint32(s, MAKE_ID4('T', 'E', 'X', '0'));
|
sn_utils::ls_uint32(s, MAKE_ID4('T', 'E', 'X', '0'));
|
||||||
@@ -1555,6 +1499,7 @@ void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
|
|||||||
for( auto const &submodeloffset : submodeloffsets ) {
|
for( auto const &submodeloffset : submodeloffsets ) {
|
||||||
auto &submodel = Root[ submodeloffset.second ];
|
auto &submodel = Root[ submodeloffset.second ];
|
||||||
vertex_array vertices; vertices.resize( submodel.iNumVerts );
|
vertex_array vertices; vertices.resize( submodel.iNumVerts );
|
||||||
|
iNumVerts += submodel.iNumVerts;
|
||||||
for( auto &vertex : vertices ) {
|
for( auto &vertex : vertices ) {
|
||||||
vertex.deserialize( s );
|
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)
|
if (pTexture.find_last_of("/\\") == std::string::npos)
|
||||||
pTexture.insert(0, Global::asCurrentTexturePath);
|
pTexture.insert(0, Global::asCurrentTexturePath);
|
||||||
TextureID = GfxRenderer.GetTextureId(pTexture, szTexturePath);
|
TextureID = GfxRenderer.GetTextureId(pTexture, szTexturePath);
|
||||||
/*
|
if( ( iFlags & 0x30 ) == 0 ) {
|
||||||
|
// texture-alpha based fallback if for some reason we don't have opacity flag set yet
|
||||||
iFlags |=
|
iFlags |=
|
||||||
( GfxRenderer.Texture( TextureID ).has_alpha ?
|
( GfxRenderer.Texture( TextureID ).has_alpha ?
|
||||||
0x20 :
|
0x20 :
|
||||||
0x10 ); // 0x10-nieprzezroczysta, 0x20-przezroczysta
|
0x10 ); // 0x10-nieprzezroczysta, 0x20-przezroczysta
|
||||||
*/
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
TextureID = iTexture;
|
TextureID = iTexture;
|
||||||
@@ -1688,10 +1634,10 @@ void TSubModel::BinInit(TSubModel *s, float4x4 *m, std::vector<std::string> *t,
|
|||||||
iFlags |= 0x20;
|
iFlags |= 0x20;
|
||||||
}
|
}
|
||||||
// intercept and fix hotspot values if specified in degrees and not directly
|
// 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 ) );
|
fCosFalloffAngle = std::cos( DegToRad( 0.5f * fCosFalloffAngle ) );
|
||||||
}
|
}
|
||||||
if( fCosHotspotAngle > 1.0 ) {
|
if( fCosHotspotAngle > 1.0f ) {
|
||||||
fCosHotspotAngle = std::cos( DegToRad( 0.5f * fCosHotspotAngle ) );
|
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
|
Root->InitialRotate(true); // argumet określa, czy wykonać pierwotny obrót
|
||||||
}
|
}
|
||||||
iFlags |= Root->FlagsCheck() | 0x8000; // flagi całego modelu
|
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 (iNumVerts) {
|
||||||
if( m_geometrybank == NULL ) {
|
if( m_geometrybank == NULL ) {
|
||||||
m_geometrybank = GfxRenderer.Create_Bank();
|
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/.
|
http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef Model3dH
|
#pragma once
|
||||||
#define Model3dH
|
|
||||||
|
|
||||||
#include "GL/glew.h"
|
#include "GL/glew.h"
|
||||||
#include "Parser.h"
|
#include "Parser.h"
|
||||||
@@ -51,8 +50,6 @@ enum TAnimType // rodzaj animacji
|
|||||||
at_Undefined = 0x800000FF // animacja chwilowo nieokreślona
|
at_Undefined = 0x800000FF // animacja chwilowo nieokreślona
|
||||||
};
|
};
|
||||||
|
|
||||||
class TModel3d;
|
|
||||||
|
|
||||||
class TSubModel
|
class TSubModel
|
||||||
{ // klasa submodelu - pojedyncza siatka, punkt świetlny albo grupa punktów
|
{ // klasa submodelu - pojedyncza siatka, punkt świetlny albo grupa punktów
|
||||||
//m7todo: zrobić normalną serializację
|
//m7todo: zrobić normalną serializację
|
||||||
@@ -61,15 +58,16 @@ class TSubModel
|
|||||||
friend class TModel3d; // temporary workaround. TODO: clean up class content/hierarchy
|
friend class TModel3d; // temporary workaround. TODO: clean up class content/hierarchy
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int iNext;
|
int iNext{ NULL };
|
||||||
int iChild;
|
int iChild{ NULL };
|
||||||
int eType; // Ra: modele binarne dają więcej możliwości niż mesh złożony z trójkątów
|
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; // numer łańcucha z nazwą submodelu, albo -1 gdy anonimowy
|
int iName{ -1 }; // numer łańcucha z nazwą submodelu, albo -1 gdy anonimowy
|
||||||
public: // chwilowo
|
public: // chwilowo
|
||||||
TAnimType b_Anim;
|
TAnimType b_Anim{ at_None };
|
||||||
|
|
||||||
private:
|
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 0: =1 faza rysowania zależy od wymiennej tekstury 0
|
||||||
// bit 1: =1 faza rysowania zależy od wymiennej tekstury 1
|
// bit 1: =1 faza rysowania zależy od wymiennej tekstury 1
|
||||||
// bit 2: =1 faza rysowania zależy od wymiennej tekstury 2
|
// bit 2: =1 faza rysowania zależy od wymiennej tekstury 2
|
||||||
@@ -84,63 +82,62 @@ private:
|
|||||||
// bit 15: =1 wymagane przechowanie macierzy (transform niejedynkowy)
|
// bit 15: =1 wymagane przechowanie macierzy (transform niejedynkowy)
|
||||||
union
|
union
|
||||||
{ // transform, nie każdy submodel musi mieć
|
{ // 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 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 tVboPtr; // początek na liście wierzchołków albo indeksów
|
||||||
int iTexture; // numer nazwy tekstury, -1 wymienna, 0 brak
|
int iTexture{ 0 }; // numer nazwy tekstury, -1 wymienna, 0 brak
|
||||||
float fVisible; // próg jasności światła do załączenia submodelu
|
float fVisible{ 0.0f }; // próg jasności światła do załączenia submodelu
|
||||||
float fLight; // próg jasności światła do zadziałania selfillum
|
float fLight{ -1.0f }; // próg jasności światła do zadziałania selfillum
|
||||||
glm::vec4
|
glm::vec4
|
||||||
f4Ambient,
|
f4Ambient{ 1.0f,1.0f,1.0f,1.0f },
|
||||||
f4Diffuse,
|
f4Diffuse{ 1.0f,1.0f,1.0f,1.0f },
|
||||||
f4Specular,
|
f4Specular{ 0.0f,0.0f,0.0f,1.0f },
|
||||||
f4Emision;
|
f4Emision{ 1.0f,1.0f,1.0f,1.0f };
|
||||||
float fWireSize; // nie używane, ale wczytywane
|
float fWireSize{ 0.0f }; // nie używane, ale wczytywane
|
||||||
float fSquareMaxDist;
|
float fSquareMaxDist{ 10000.0f * 10000.0f };
|
||||||
float fSquareMinDist;
|
float fSquareMinDist{ 0.0f };
|
||||||
// McZapkie-050702: parametry dla swiatla:
|
// McZapkie-050702: parametry dla swiatla:
|
||||||
float fNearAttenStart;
|
float fNearAttenStart{ 40.0f };
|
||||||
float fNearAttenEnd;
|
float fNearAttenEnd{ 80.0f };
|
||||||
bool bUseNearAtten; // te 3 zmienne okreslaja rysowanie aureoli wokol zrodla swiatla
|
bool bUseNearAtten{ false }; // 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)
|
int iFarAttenDecay{ 0 }; // ta zmienna okresla typ zaniku natezenia swiatla (0:brak, 1,2: potega 1/R)
|
||||||
float fFarDecayRadius; // normalizacja j.w.
|
float fFarDecayRadius{ 100.0f }; // normalizacja j.w.
|
||||||
float fCosFalloffAngle; // cosinus kąta stożka pod którym widać światło
|
float fCosFalloffAngle{ 0.5f }; // 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 fCosHotspotAngle{ 0.3f }; // 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 fCosViewAngle{ 0.0f }; // cos kata pod jakim sie teraz patrzy
|
||||||
|
|
||||||
TSubModel *Next;
|
TSubModel *Next{ nullptr };
|
||||||
TSubModel *Child;
|
TSubModel *Child{ nullptr };
|
||||||
/*
|
/*
|
||||||
intptr_t iVboPtr;
|
intptr_t iVboPtr;
|
||||||
*/
|
*/
|
||||||
geometry_handle m_geometry; // geometry of the submodel
|
geometry_handle m_geometry{ NULL, NULL }; // geometry of the submodel
|
||||||
texture_handle TextureID; // numer tekstury, -1 wymienna, 0 brak
|
texture_handle TextureID{ NULL }; // numer tekstury, -1 wymienna, 0 brak
|
||||||
bool bWire; // nie używane, ale wczytywane
|
bool bWire{ false }; // nie używane, ale wczytywane
|
||||||
/*
|
/*
|
||||||
GLuint uiDisplayList; // roboczy numer listy wyświetlania
|
GLuint uiDisplayList; // roboczy numer listy wyświetlania
|
||||||
*/
|
*/
|
||||||
float Opacity; // nie używane, ale wczytywane //m7todo: wywalić to
|
float Opacity{ 1.0f };
|
||||||
float f_Angle;
|
float f_Angle{ 0.0f };
|
||||||
float3 v_RotateAxis;
|
float3 v_RotateAxis{ 0.0f, 0.0f, 0.0f };
|
||||||
float3 v_Angles;
|
float3 v_Angles { 0.0f, 0.0f, 0.0f };
|
||||||
|
|
||||||
public: // chwilowo
|
public: // chwilowo
|
||||||
float3 v_TransVector;
|
float3 v_TransVector{ 0.0f, 0.0f, 0.0f };
|
||||||
/*
|
/*
|
||||||
basic_vertex *Vertices; // roboczy wskaźnik - wczytanie T3D do VBO
|
basic_vertex *Vertices; // roboczy wskaźnik - wczytanie T3D do VBO
|
||||||
*/
|
*/
|
||||||
vertex_array Vertices;
|
vertex_array Vertices;
|
||||||
size_t iAnimOwner; // roboczy numer egzemplarza, który ustawił animację
|
size_t iAnimOwner{ NULL }; // roboczy numer egzemplarza, który ustawił animację
|
||||||
TAnimType b_aAnim; // kody animacji oddzielnie, bo zerowane
|
TAnimType b_aAnim{ at_None }; // kody animacji oddzielnie, bo zerowane
|
||||||
public:
|
public:
|
||||||
float4x4 *mAnimMatrix; // macierz do animacji kwaternionowych (należy do AnimContainer)
|
float4x4 *mAnimMatrix{ nullptr }; // macierz do animacji kwaternionowych (należy do AnimContainer)
|
||||||
public:
|
public:
|
||||||
TSubModel **
|
TSubModel **smLetter{ nullptr }; // wskaźnik na tablicę submdeli do generoania tekstu (docelowo zapisać do E3D)
|
||||||
smLetter; // wskaźnik na tablicę submdeli do generoania tekstu (docelowo zapisać do E3D)
|
TSubModel *Parent{ nullptr }; // nadrzędny, np. do wymnażania macierzy
|
||||||
TSubModel *Parent; // nadrzędny, np. do wymnażania macierzy
|
int iVisible{ 1 }; // roboczy stan widoczności
|
||||||
int iVisible; // roboczy stan widoczności
|
|
||||||
std::string pTexture; // robocza nazwa tekstury do zapisania w pliku binarnym
|
std::string pTexture; // robocza nazwa tekstury do zapisania w pliku binarnym
|
||||||
std::string pName; // robocza nazwa
|
std::string pName; // robocza nazwa
|
||||||
private:
|
private:
|
||||||
@@ -154,9 +151,7 @@ public:
|
|||||||
static double fSquareDist;
|
static double fSquareDist;
|
||||||
static TModel3d *pRoot;
|
static TModel3d *pRoot;
|
||||||
static std::string *pasText; // tekst dla wyświetlacza (!!!! do przemyślenia)
|
static std::string *pasText; // tekst dla wyświetlacza (!!!! do przemyślenia)
|
||||||
TSubModel();
|
|
||||||
~TSubModel();
|
~TSubModel();
|
||||||
void FirstInit();
|
|
||||||
int Load(cParser &Parser, TModel3d *Model, /*int Pos,*/ bool dynamic);
|
int Load(cParser &Parser, TModel3d *Model, /*int Pos,*/ bool dynamic);
|
||||||
void ChildAdd(TSubModel *SubModel);
|
void ChildAdd(TSubModel *SubModel);
|
||||||
void NextAdd(TSubModel *SubModel);
|
void NextAdd(TSubModel *SubModel);
|
||||||
@@ -176,10 +171,8 @@ public:
|
|||||||
TSubModel * GetFromName(char const *search, bool i = true);
|
TSubModel * GetFromName(char const *search, bool i = true);
|
||||||
inline float4x4 * GetMatrix() { return fMatrix; };
|
inline float4x4 * GetMatrix() { return fMatrix; };
|
||||||
inline void Hide() { iVisible = 0; };
|
inline void Hide() { iVisible = 0; };
|
||||||
/*
|
|
||||||
void RaArrayFill(basic_vertex *Vert);
|
void create_geometry( std::size_t &Dataoffset, geometrybank_handle const &Bank );
|
||||||
*/
|
|
||||||
void create_geometry( geometrybank_handle const &Bank );
|
|
||||||
int FlagsCheck();
|
int FlagsCheck();
|
||||||
void WillBeAnimated()
|
void WillBeAnimated()
|
||||||
{
|
{
|
||||||
@@ -187,9 +180,6 @@ public:
|
|||||||
iFlags |= 0x4000;
|
iFlags |= 0x4000;
|
||||||
};
|
};
|
||||||
void InitialRotate(bool doit);
|
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 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)
|
void ReplacableSet(texture_handle const *r, int a)
|
||||||
{
|
{
|
||||||
@@ -219,11 +209,13 @@ public:
|
|||||||
void AdjustDist();
|
void AdjustDist();
|
||||||
|
|
||||||
void deserialize(std::istream&);
|
void deserialize(std::istream&);
|
||||||
void TSubModel::serialize(std::ostream&,
|
void serialize(std::ostream&,
|
||||||
std::vector<TSubModel*>&,
|
std::vector<TSubModel*>&,
|
||||||
std::vector<std::string>&,
|
std::vector<std::string>&,
|
||||||
std::vector<std::string>&,
|
std::vector<std::string>&,
|
||||||
std::vector<float4x4>&);
|
std::vector<float4x4>&);
|
||||||
|
void serialize_geometry( std::ostream &Output );
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class TModel3d : public CMesh
|
class TModel3d : public CMesh
|
||||||
@@ -259,11 +251,7 @@ public:
|
|||||||
std::string NameGet() { return m_filename; };
|
std::string NameGet() { return m_filename; };
|
||||||
int TerrainCount();
|
int TerrainCount();
|
||||||
TSubModel * TerrainSquare(int n);
|
TSubModel * TerrainSquare(int n);
|
||||||
#ifdef EU07_USE_OLD_RENDERCODE
|
|
||||||
void TerrainRenderVBO(int n);
|
|
||||||
#endif
|
|
||||||
void deserialize(std::istream &s, size_t size, bool dynamic);
|
void deserialize(std::istream &s, size_t size, bool dynamic);
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -292,7 +292,7 @@ void TPythonScreenRenderer::updateTexture()
|
|||||||
WriteLog(buff);
|
WriteLog(buff);
|
||||||
#endif // _PY_INT_MORE_LOG
|
#endif // _PY_INT_MORE_LOG
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
glBindTexture(GL_TEXTURE_2D, _textureId);
|
GfxRenderer.Bind(_textureId);
|
||||||
// setup texture parameters
|
// setup texture parameters
|
||||||
if( GLEW_VERSION_1_4 ) {
|
if( GLEW_VERSION_1_4 ) {
|
||||||
|
|
||||||
|
|||||||
10
World.cpp
10
World.cpp
@@ -1651,15 +1651,13 @@ TWorld::Update_UI() {
|
|||||||
case( GLFW_KEY_F8 ) : {
|
case( GLFW_KEY_F8 ) : {
|
||||||
// gfx renderer data
|
// gfx renderer data
|
||||||
uitextline1 =
|
uitextline1 =
|
||||||
"Draw range x " + to_string( Global::fDistanceFactor, 1 )
|
"FoV: " + to_string( Global::FieldOfView / Global::ZoomFactor, 1 )
|
||||||
+ "; FPS: " + to_string( Timer::GetFPS(), 2 );
|
+ ", Draw range x " + to_string( Global::fDistanceFactor, 1 )
|
||||||
|
+ "; sectors: " + std::to_string( GfxRenderer.m_drawcount )
|
||||||
|
+ ", FPS: " + to_string( Timer::GetFPS(), 2 );
|
||||||
if( Global::iSlowMotion ) {
|
if( Global::iSlowMotion ) {
|
||||||
uitextline1 += " (slowmotion " + to_string( 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 =
|
uitextline2 =
|
||||||
std::string( "Rendering mode: " )
|
std::string( "Rendering mode: " )
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
|
|
||||||
void
|
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.x );
|
||||||
sn_utils::ls_float32( s, position.y );
|
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 ) :
|
basic_vertex( glm::vec3 const&Position, glm::vec3 const &Normal, glm::vec2 const &Texture ) :
|
||||||
position( Position ), normal( Normal ), texture( Texture )
|
position( Position ), normal( Normal ), texture( Texture )
|
||||||
{}
|
{}
|
||||||
void serialize( std::ostream& );
|
void serialize( std::ostream& ) const;
|
||||||
void deserialize( std::istream& );
|
void deserialize( std::istream& );
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -111,10 +111,12 @@ protected:
|
|||||||
struct geometry_chunk {
|
struct geometry_chunk {
|
||||||
unsigned int type; // kind of geometry used by the chunk
|
unsigned int type; // kind of geometry used by the chunk
|
||||||
vertex_array vertices; // geometry data
|
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 ) :
|
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;
|
typedef std::vector<geometry_chunk> geometrychunk_sequence;
|
||||||
|
|||||||
179
renderer.cpp
179
renderer.cpp
@@ -368,7 +368,14 @@ opengl_renderer::Render( TGround *Ground ) {
|
|||||||
++TGroundRect::iFrameNumber; // zwięszenie licznika ramek (do usuwniania nadanimacji)
|
++TGroundRect::iFrameNumber; // zwięszenie licznika ramek (do usuwniania nadanimacji)
|
||||||
|
|
||||||
Update_Lights( Ground->m_lights );
|
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 );
|
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 camerax = static_cast<int>( std::floor( cameraposition.x / 1000.0f ) + iNumRects / 2 );
|
||||||
int const cameraz = static_cast<int>( std::floor( cameraposition.z / 1000.0f ) + iNumRects / 2 );
|
int const 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 ) {
|
for( int row = originz; row <= originz + segmentcount; ++row ) {
|
||||||
|
|
||||||
auto *cell = &Ground->Rects[ column ][ 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 ) ) {
|
if( m_camera.visible( cell->m_area ) ) {
|
||||||
Render( cell );
|
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();
|
|
||||||
}
|
|
||||||
// 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 ) {
|
// draw queue was filled while rendering content of ground cells. now sort the nodes based on their distance to viewer...
|
||||||
node->RenderHidden();
|
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 );
|
||||||
}
|
}
|
||||||
// jeszcze dźwięki pojazdów by się przydały, również niewidocznych
|
// now hand the control over to the renderer of translucent parts, it'll do the rest
|
||||||
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
|
|
||||||
return Render_Alpha( Ground );
|
return Render_Alpha( Ground );
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: unify ground render code, until then old version is in place
|
|
||||||
bool
|
bool
|
||||||
opengl_renderer::Render( TGroundRect *Groundcell ) {
|
opengl_renderer::Render( TGroundRect *Groundcell ) {
|
||||||
|
|
||||||
@@ -484,6 +442,19 @@ opengl_renderer::Render( TGroundRect *Groundcell ) {
|
|||||||
}
|
}
|
||||||
Groundcell->iLastDisplay = Groundcell->iFrameNumber; // drugi raz nie potrzeba
|
Groundcell->iLastDisplay = Groundcell->iFrameNumber; // drugi raz nie potrzeba
|
||||||
result = true;
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -491,6 +462,9 @@ opengl_renderer::Render( TGroundRect *Groundcell ) {
|
|||||||
bool
|
bool
|
||||||
opengl_renderer::Render( TSubRect *Groundsubcell ) {
|
opengl_renderer::Render( TSubRect *Groundsubcell ) {
|
||||||
|
|
||||||
|
// oznaczanie aktywnych sektorów
|
||||||
|
Groundsubcell->LoadNodes();
|
||||||
|
|
||||||
Groundsubcell->RaAnimate(); // przeliczenia animacji torów w sektorze
|
Groundsubcell->RaAnimate(); // przeliczenia animacji torów w sektorze
|
||||||
|
|
||||||
TGroundNode *node;
|
TGroundNode *node;
|
||||||
@@ -906,23 +880,23 @@ opengl_renderer::Render_Alpha( TGround *Ground ) {
|
|||||||
TGroundNode *node;
|
TGroundNode *node;
|
||||||
TSubRect *tmp;
|
TSubRect *tmp;
|
||||||
// Ra: renderowanie progresywne - zależne od FPS oraz kierunku patrzenia
|
// Ra: renderowanie progresywne - zależne od FPS oraz kierunku patrzenia
|
||||||
for( 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
|
// przezroczyste trójkąty w oddzielnym cyklu przed modelami
|
||||||
tmp = *subcell;
|
tmp = subcellpair->second;
|
||||||
for( node = tmp->nRenderRectAlpha; node; node = node->nNext3 ) {
|
for( node = tmp->nRenderRectAlpha; node; node = node->nNext3 ) {
|
||||||
Render_Alpha( node );
|
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
|
{ // renderowanie przezroczystych modeli oraz pojazdów
|
||||||
Render_Alpha( *subcell );
|
Render_Alpha( subcellpair->second );
|
||||||
}
|
}
|
||||||
|
|
||||||
::glDisable( GL_LIGHTING ); // linie nie powinny świecić
|
::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
|
// 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 ) {
|
for( node = tmp->nRenderWires; node; node = node->nNext3 ) {
|
||||||
Render_Alpha( node );
|
Render_Alpha( node );
|
||||||
}
|
}
|
||||||
@@ -947,25 +921,9 @@ opengl_renderer::Render_Alpha( TSubRect *Groundsubcell ) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: legacy render system switch
|
|
||||||
#define _PROBLEND
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
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 );
|
double const distancesquared = SquareMagnitude( ( Node->pCenter - Global::pCameraPosition ) / Global::ZoomFactor );
|
||||||
if( ( distancesquared > ( Node->fSquareRadius * Global::fDistanceFactor ) )
|
if( ( distancesquared > ( Node->fSquareRadius * Global::fDistanceFactor ) )
|
||||||
|| ( distancesquared < ( Node->fSquareMinRadius / Global::fDistanceFactor ) ) ) {
|
|| ( distancesquared < ( Node->fSquareMinRadius / Global::fDistanceFactor ) ) ) {
|
||||||
@@ -1029,14 +987,15 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// setup
|
// setup
|
||||||
// w zaleznosci od koloru swiatla
|
auto const linewidth = clamp( 100.0 * Node->fLineThickness / ( distancesquared + 1.0 ), 1.0, 10.0 );
|
||||||
::glColor4fv(
|
::glColor4fv(
|
||||||
glm::value_ptr(
|
glm::value_ptr(
|
||||||
glm::vec4(
|
glm::vec4(
|
||||||
Node->Diffuse * glm::make_vec3( Global::DayLight.ambient ),
|
Node->Diffuse * glm::make_vec3( Global::DayLight.ambient ), // w zaleznosci od koloru swiatla
|
||||||
std::min(
|
std::min( 1.0, linewidth ) ) ) );
|
||||||
1.0,
|
if( linewidth > 1.0 ) {
|
||||||
1000.0 * Node->fLineThickness / ( distancesquared + 1.0 ) ) ) ) );
|
::glLineWidth( static_cast<float>(linewidth) );
|
||||||
|
}
|
||||||
|
|
||||||
GfxRenderer.Bind( 0 );
|
GfxRenderer.Bind( 0 );
|
||||||
|
|
||||||
@@ -1048,6 +1007,10 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
|||||||
m_geometry.draw( Node->m_geometry );
|
m_geometry.draw( Node->m_geometry );
|
||||||
|
|
||||||
// post-render cleanup
|
// post-render cleanup
|
||||||
|
if( linewidth > 1.0 ) {
|
||||||
|
::glLineWidth( 1.0f );
|
||||||
|
}
|
||||||
|
|
||||||
::glPopMatrix();
|
::glPopMatrix();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -1059,13 +1022,6 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// setup
|
// setup
|
||||||
#ifdef _PROBLEND
|
|
||||||
if( ( Node->PROBLEND ) ) // sprawdza, czy w nazwie nie ma @ //Q: 13122011 - Szociu: 27012012
|
|
||||||
{
|
|
||||||
::glDisable( GL_BLEND );
|
|
||||||
::glAlphaFunc( GL_GREATER, 0.50f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
::glColor3fv( glm::value_ptr( Node->Diffuse ) );
|
::glColor3fv( glm::value_ptr( Node->Diffuse ) );
|
||||||
|
|
||||||
Bind( Node->TextureID );
|
Bind( Node->TextureID );
|
||||||
@@ -1080,13 +1036,6 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
|||||||
// post-render cleanup
|
// post-render cleanup
|
||||||
::glPopMatrix();
|
::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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -182,6 +182,8 @@ private:
|
|||||||
|
|
||||||
typedef std::vector<opengl_light> opengllight_array;
|
typedef std::vector<opengl_light> opengllight_array;
|
||||||
|
|
||||||
|
typedef std::pair< double, TSubRect * > distancesubcell_pair;
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
bool
|
bool
|
||||||
Init_caps();
|
Init_caps();
|
||||||
@@ -226,7 +228,7 @@ private:
|
|||||||
texture_handle m_moontexture { -1 };
|
texture_handle m_moontexture { -1 };
|
||||||
geometry_handle m_billboardgeometry { 0, 0 };
|
geometry_handle m_billboardgeometry { 0, 0 };
|
||||||
GLUquadricObj *m_quadric; // helper object for drawing debug mode scene elements
|
GLUquadricObj *m_quadric; // helper object for drawing debug mode scene elements
|
||||||
std::vector< TSubRect* > m_drawqueue; // list of subcells to be drawn in current render pass
|
std::vector<distancesubcell_pair> m_drawqueue; // list of subcells to be drawn in current render pass
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user