mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-19 09:59:18 +02:00
support for vertex data streams selection, t3d model loading fixes
This commit is contained in:
379
Model3d.cpp
379
Model3d.cpp
@@ -51,10 +51,14 @@ TSubModel::TSubModel()
|
||||
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);
|
||||
@@ -103,15 +107,19 @@ void TSubModel::FirstInit()
|
||||
|
||||
TSubModel::~TSubModel()
|
||||
{
|
||||
/*
|
||||
if (uiDisplayList)
|
||||
glDeleteLists(uiDisplayList, 1);
|
||||
*/
|
||||
if (iFlags & 0x0200)
|
||||
{ // wczytany z pliku tekstowego musi sam posprzątać
|
||||
// SafeDeleteArray(Indices);
|
||||
SafeDelete(Next);
|
||||
SafeDelete(Child);
|
||||
delete fMatrix; // własny transform trzeba usunąć (zawsze jeden)
|
||||
/*
|
||||
delete[] Vertices;
|
||||
*/
|
||||
}
|
||||
delete[] smLetter; // używany tylko roboczo dla TP_TEXT, do przyspieszenia
|
||||
// wyświetlania
|
||||
@@ -136,25 +144,20 @@ void TSubModel::NameSet(std::string const &Name)
|
||||
// int TSubModel::SeekFaceNormal(DWORD *Masks, int f,DWORD dwMask,vector3
|
||||
// *pt,GLVERTEX
|
||||
// *Vertices)
|
||||
int TSubModel::SeekFaceNormal(unsigned int *Masks, int f, unsigned int dwMask, glm::vec3 *pt,
|
||||
basic_vertex *Vertices)
|
||||
{ // szukanie punktu stycznego
|
||||
// do (pt), zwraca numer
|
||||
// wierzchołka, a nie trójkąta
|
||||
int iNumFaces = iNumVerts / 3; // bo maska powierzchni jest jedna na trójkąt
|
||||
// GLVERTEX *p; //roboczy wskaźnik
|
||||
basic_vertex *p; // roboczy wskaźnik
|
||||
for (int i = f; i < iNumFaces; ++i) // pętla po trójkątach, od trójkąta (f)
|
||||
if (Masks[i] & dwMask) // jeśli wspólna maska powierzchni
|
||||
{
|
||||
p = Vertices + 3 * i;
|
||||
if (p->position == *pt)
|
||||
return 3 * i;
|
||||
if ((++p)->position == *pt)
|
||||
return 3 * i + 1;
|
||||
if ((++p)->position == *pt)
|
||||
return 3 * i + 2;
|
||||
}
|
||||
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
|
||||
for( int faceidx = Startface; faceidx < facecount; ++faceidx ) {
|
||||
// pętla po trójkątach, od trójkąta (f)
|
||||
if( Masks[ faceidx ] & Mask ) {
|
||||
// jeśli wspólna maska powierzchni
|
||||
for( int vertexidx = 0; vertexidx < 2; ++vertexidx ) {
|
||||
if( Vertices[ 3 * faceidx + vertexidx ].position == Position ) {
|
||||
return 3 * faceidx + vertexidx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1; // nie znaleziono stycznego wierzchołka
|
||||
}
|
||||
|
||||
@@ -197,10 +200,12 @@ inline void readMatrix(cParser &parser, float4x4 &matrix)
|
||||
parser >> matrix(x)[y];
|
||||
};
|
||||
|
||||
int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic)
|
||||
int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic)
|
||||
{ // Ra: VBO tworzone na poziomie modelu, a nie submodeli
|
||||
iNumVerts = 0;
|
||||
/*
|
||||
iVboPtr = Pos; // pozycja w VBO
|
||||
*/
|
||||
if (!parser.expectToken("type:"))
|
||||
Error("Model type parse failure!");
|
||||
{
|
||||
@@ -329,13 +334,18 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic)
|
||||
{
|
||||
std::string discard;
|
||||
parser.getTokens(5, false);
|
||||
parser >> discard >> bWire >> discard >> fWireSize >> discard;
|
||||
Opacity = readIntAsDouble(parser,
|
||||
100.0f); // wymagane jest 0 dla szyb, 100 idzie w nieprzezroczyste
|
||||
parser
|
||||
>> discard >> bWire
|
||||
>> discard >> fWireSize
|
||||
>> discard;
|
||||
// wymagane jest 0 dla szyb, 100 idzie w nieprzezroczyste
|
||||
Opacity = readIntAsDouble(parser, 100.0f);
|
||||
if (Opacity > 1.0f)
|
||||
Opacity *= 0.01f; // w 2013 był błąd i aby go obejść, trzeba było wpisać 10000.0
|
||||
/*
|
||||
if ((Global::iConvertModels & 1) == 0) // dla zgodności wstecz
|
||||
Opacity = 0.0; // wszystko idzie w przezroczyste albo zależnie od tekstury
|
||||
*/
|
||||
if (!parser.expectToken("map:"))
|
||||
Error("Model map parse failure!");
|
||||
std::string texture = parser.getToken<std::string>();
|
||||
@@ -371,20 +381,19 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic)
|
||||
}
|
||||
else
|
||||
{ // jeśli tylko nazwa pliku, to dawać bieżącą ścieżkę do tekstur
|
||||
// asTexture=AnsiString(texture.c_str()); //zapamiętanie nazwy tekstury
|
||||
TextureNameSet(texture.c_str());
|
||||
if (texture.find_first_of("/\\") == texture.npos)
|
||||
texture.insert(0, Global::asCurrentTexturePath.c_str());
|
||||
if( texture.find_first_of( "/\\" ) == texture.npos ) {
|
||||
texture.insert( 0, Global::asCurrentTexturePath.c_str() );
|
||||
}
|
||||
TextureID = GfxRenderer.GetTextureId( texture, szTexturePath );
|
||||
// TexAlpha=TTexturesManager::GetAlpha(TextureID);
|
||||
// iFlags|=TexAlpha?0x20:0x10; //0x10-nieprzezroczysta, 0x20-przezroczysta
|
||||
iFlags |=
|
||||
( GfxRenderer.Texture(TextureID).has_alpha ?
|
||||
0x20 :
|
||||
0x10 ); // 0x10-nieprzezroczysta, 0x20-przezroczysta
|
||||
// renderowanie w cyklu przezroczystych tylko jeśli:
|
||||
// 1. Opacity=0 (przejściowo <1, czy tam <100) oraz
|
||||
// 2. tekstura ma przezroczystość
|
||||
iFlags |=
|
||||
( ( ( Opacity < 1.0 )
|
||||
&& ( GfxRenderer.Texture(TextureID).has_alpha ) ) ?
|
||||
0x20 :
|
||||
0x10 ); // 0x10-nieprzezroczysta, 0x20-przezroczysta
|
||||
};
|
||||
}
|
||||
else
|
||||
@@ -407,8 +416,6 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic)
|
||||
readMatrix(parser, *fMatrix); // wczytanie transform
|
||||
if (!fMatrix->IdentityIs())
|
||||
iFlags |= 0x8000; // transform niejedynkowy - trzeba go przechować
|
||||
int iNumFaces; // ilość trójkątów
|
||||
unsigned int *sg; // maski przynależności trójkątów do powierzchni
|
||||
if (eType < TP_ROTATOR)
|
||||
{ // wczytywanie wierzchołków
|
||||
parser.getTokens(2, false);
|
||||
@@ -423,11 +430,11 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic)
|
||||
{ // jeśli pierwszy znak jest gwiazdką, poszukać
|
||||
// submodelu o nazwie bez tej gwiazdki i wziąć z
|
||||
// niego wierzchołki
|
||||
Error("Verticles reference not yet supported!");
|
||||
Error("Vertices reference not yet supported!");
|
||||
}
|
||||
else
|
||||
{ // normalna lista wierzchołków
|
||||
iNumVerts = atoi(token.c_str());
|
||||
iNumVerts = std::atoi(token.c_str());
|
||||
if (iNumVerts % 3)
|
||||
{
|
||||
iNumVerts = 0;
|
||||
@@ -435,27 +442,31 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic)
|
||||
return 0;
|
||||
}
|
||||
// Vertices=new GLVERTEX[iNumVerts];
|
||||
if (iNumVerts)
|
||||
{
|
||||
if (iNumVerts) {
|
||||
/*
|
||||
Vertices = new basic_vertex[iNumVerts];
|
||||
iNumFaces = iNumVerts / 3;
|
||||
sg = new unsigned int[iNumFaces]; // maski powierzchni: 0 oznacza brak
|
||||
// użredniania wektorów normalnych
|
||||
int *wsp = new int[iNumVerts]; // z którego wierzchołka kopiować wektor
|
||||
// normalny
|
||||
*/
|
||||
Vertices.resize( iNumVerts );
|
||||
int facecount = iNumVerts / 3;
|
||||
/*
|
||||
unsigned int *sg; // maski przynależności trójkątów do powierzchni
|
||||
sg = new unsigned int[iNumFaces]; // maski powierzchni: 0 oznacza brak użredniania wektorów normalnych
|
||||
int *wsp = new int[iNumVerts]; // z którego wierzchołka kopiować wektor normalny
|
||||
*/
|
||||
std::vector<unsigned int> sg; sg.resize( facecount ); // maski przynależności trójkątów do powierzchni
|
||||
std::vector<int> wsp; wsp.resize( iNumVerts );// z którego wierzchołka kopiować wektor normalny
|
||||
int maska = 0;
|
||||
for (int i = 0; i < iNumVerts; i++)
|
||||
{ // Ra: z konwersją na układ scenerii - będzie wydajniejsze
|
||||
// wyświetlanie
|
||||
for (int i = 0; i < iNumVerts; ++i) {
|
||||
// Ra: z konwersją na układ scenerii - będzie wydajniejsze wyświetlanie
|
||||
wsp[i] = -1; // wektory normalne nie są policzone dla tego wierzchołka
|
||||
if ((i % 3) == 0)
|
||||
{ // jeśli będzie maska -1, to dalej będą
|
||||
// wierzchołki z wektorami normalnymi, podanymi
|
||||
// jawnie
|
||||
if ((i % 3) == 0) {
|
||||
// jeśli będzie maska -1, to dalej będą wierzchołki z wektorami normalnymi, podanymi jawnie
|
||||
maska = parser.getToken<int>(false); // maska powierzchni trójkąta
|
||||
sg[i / 3] = (maska == -1) ? 0 : maska; // dla maski -1 będzie 0,
|
||||
// czyli nie ma wspólnych
|
||||
// wektorów normalnych
|
||||
// dla maski -1 będzie 0, czyli nie ma wspólnych wektorów normalnych
|
||||
sg[i / 3] = (
|
||||
( maska == -1 ) ?
|
||||
0 :
|
||||
maska );
|
||||
}
|
||||
parser.getTokens(3, false);
|
||||
parser
|
||||
@@ -475,80 +486,77 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic)
|
||||
parser
|
||||
>> Vertices[i].texture.s
|
||||
>> Vertices[i].texture.t;
|
||||
if (i % 3 == 2) // jeżeli wczytano 3 punkty
|
||||
{
|
||||
if (Vertices[i].position == Vertices[i - 1].position
|
||||
if (i % 3 == 2) {
|
||||
// jeżeli wczytano 3 punkty
|
||||
if (Vertices[i ].position == Vertices[i - 1].position
|
||||
|| Vertices[i - 1].position == Vertices[i - 2].position
|
||||
|| Vertices[i - 2].position == Vertices[i].position)
|
||||
|| Vertices[i - 2].position == Vertices[i ].position)
|
||||
{ // jeżeli punkty się nakładają na siebie
|
||||
--iNumFaces; // o jeden trójkąt mniej
|
||||
--facecount; // o jeden trójkąt mniej
|
||||
iNumVerts -= 3; // czyli o 3 wierzchołki
|
||||
i -= 3; // wczytanie kolejnego w to miejsce
|
||||
WriteLog(std::string("Degenerated triangle ignored in: \"") + pName +
|
||||
"\", verticle " + std::to_string(i));
|
||||
WriteLog("Degenerated triangle ignored in: \"" + pName + "\", verticle " + std::to_string(i));
|
||||
}
|
||||
if (i > 0) // jeśli pierwszy trójkąt będzie zdegenerowany, to
|
||||
// zostanie usunięty i nie ma co sprawdzać
|
||||
if ((glm::length(Vertices[i].position - Vertices[i - 1].position) > 1000.0)
|
||||
|| (glm::length(Vertices[i - 1].position - Vertices[i - 2].position) > 1000.0)
|
||||
|| (glm::length(Vertices[i - 2].position - Vertices[i].position) > 1000.0))
|
||||
{ // jeżeli są dalej niż 2km od siebie //Ra 15-01:
|
||||
// obiekt wstawiany nie powinien być większy niż
|
||||
// 300m (trójkąty terenu w E3D mogą mieć 1.5km)
|
||||
--iNumFaces; // o jeden trójkąt mniej
|
||||
if (i > 0) {
|
||||
// jeśli pierwszy trójkąt będzie zdegenerowany, to zostanie usunięty i nie ma co sprawdzać
|
||||
if ((glm::length(Vertices[i ].position - Vertices[i - 1].position) > 1000.0)
|
||||
|| (glm::length(Vertices[i - 1].position - Vertices[i - 2].position) > 1000.0)
|
||||
|| (glm::length(Vertices[i - 2].position - Vertices[i ].position) > 1000.0)) {
|
||||
// jeżeli są dalej niż 2km od siebie //Ra 15-01:
|
||||
// obiekt wstawiany nie powinien być większy niż 300m (trójkąty terenu w E3D mogą mieć 1.5km)
|
||||
--facecount; // o jeden trójkąt mniej
|
||||
iNumVerts -= 3; // czyli o 3 wierzchołki
|
||||
i -= 3; // wczytanie kolejnego w to miejsce
|
||||
WriteLog(std::string("Too large triangle ignored in: \"") + pName +
|
||||
"\"");
|
||||
WriteLog( "Too large triangle ignored in: \"" + pName + "\"" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int i; // indeks dla trójkątów
|
||||
/*
|
||||
glm::vec3 *n = new glm::vec3[iNumFaces]; // tablica wektorów normalnych dla trójkątów
|
||||
for (i = 0; i < iNumFaces; ++i) // pętla po trójkątach - będzie
|
||||
// szybciej, jak wstępnie przeliczymy
|
||||
// normalne trójkątów
|
||||
n[i] = glm::normalize(
|
||||
glm::cross(
|
||||
Vertices[i * 3].position - Vertices[i * 3 + 1].position,
|
||||
Vertices[i * 3].position - Vertices[i * 3 + 2].position));
|
||||
int v; // indeks dla wierzchołków
|
||||
int f; // numer trójkąta stycznego
|
||||
glm::vec3 norm; // roboczy wektor normalny
|
||||
for (v = 0; v < iNumVerts; ++v)
|
||||
{ // pętla po wierzchołkach trójkątów
|
||||
if (wsp[v] >= 0) // jeśli już był liczony wektor normalny z użyciem
|
||||
// tego wierzchołka
|
||||
Vertices[v].normal =
|
||||
Vertices[wsp[v]].normal; // to wystarczy skopiować policzony wcześniej
|
||||
else
|
||||
{ // inaczej musimy dopiero policzyć
|
||||
i = v / 3; // numer trójkąta
|
||||
norm = glm::vec3(); // liczenie zaczynamy od zera
|
||||
f = v; // zaczynamy dodawanie wektorów normalnych od własnego
|
||||
while (f >= 0)
|
||||
{ // sumowanie z wektorem normalnym sąsiada (włącznie
|
||||
// ze sobą)
|
||||
wsp[f] = v; // informacja, że w tym wierzchołku jest już policzony
|
||||
// wektor normalny
|
||||
norm += n[f / 3];
|
||||
f = SeekFaceNormal(sg, f / 3 + 1, sg[i], &Vertices[v].position,
|
||||
Vertices); // i szukanie od kolejnego trójkąta
|
||||
*/
|
||||
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
|
||||
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::vec3 vertexnormal; // roboczy wektor normalny
|
||||
for (int vertexidx = 0; vertexidx < iNumVerts; ++vertexidx) {
|
||||
// pętla po wierzchołkach trójkątów
|
||||
if( wsp[ vertexidx ] >= 0 ) {
|
||||
// jeśli już był liczony wektor normalny z użyciem tego wierzchołka to wystarczy skopiować policzony wcześniej
|
||||
Vertices[ vertexidx ].normal = Vertices[ wsp[ vertexidx ] ].normal;
|
||||
}
|
||||
else {
|
||||
// inaczej musimy dopiero policzyć
|
||||
auto const faceidx = vertexidx / 3; // numer trójkąta
|
||||
vertexnormal = glm::vec3(); // liczenie zaczynamy od zera
|
||||
auto adjacenvertextidx = vertexidx; // zaczynamy dodawanie wektorów normalnych od własnego
|
||||
while (adjacenvertextidx >= 0) {
|
||||
// sumowanie z wektorem normalnym sąsiada (włącznie ze sobą)
|
||||
wsp[adjacenvertextidx] = vertexidx; // informacja, że w tym wierzchołku jest już policzony wektor normalny
|
||||
vertexnormal += facenormals[adjacenvertextidx / 3];
|
||||
// i szukanie od kolejnego trójkąta
|
||||
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[v].normal =
|
||||
glm::normalize(norm); // przepisanie do wierzchołka trójkąta
|
||||
// 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
|
||||
}
|
||||
}
|
||||
/*
|
||||
delete[] wsp;
|
||||
delete[] n;
|
||||
delete[] sg;
|
||||
*/
|
||||
}
|
||||
else // gdy brak wierzchołków
|
||||
{
|
||||
eType = TP_ROTATOR; // submodel pomocniczy, ma tylko macierz przekształcenia
|
||||
iVboPtr = iNumVerts = 0; // dla formalności
|
||||
/*iVboPtr =*/ iNumVerts = 0; // dla formalności
|
||||
}
|
||||
} // obsługa submodelu z własną listą wierzchołków
|
||||
}
|
||||
@@ -558,9 +566,13 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic)
|
||||
std::string discard;
|
||||
parser.getTokens(2, false);
|
||||
parser >> discard >> iNumVerts;
|
||||
/*
|
||||
// Vertices=new GLVERTEX[iNumVerts];
|
||||
Vertices = new basic_vertex[iNumVerts];
|
||||
int i, j;
|
||||
*/
|
||||
Vertices.resize( iNumVerts );
|
||||
int i;
|
||||
unsigned int color;
|
||||
for (i = 0; i < iNumVerts; ++i)
|
||||
{
|
||||
if (i % 3 == 0)
|
||||
@@ -572,13 +584,17 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic)
|
||||
>> Vertices[i].position.x
|
||||
>> Vertices[i].position.y
|
||||
>> Vertices[i].position.z
|
||||
>> j // zakodowany kolor
|
||||
>> color // zakodowany kolor
|
||||
>> discard;
|
||||
Vertices[i].normal.x = ((j) & 0xFF) / 255.0; // R
|
||||
Vertices[i].normal.y = ((j >> 8) & 0xFF) / 255.0; // G
|
||||
Vertices[i].normal.z = ((j >> 16) & 0xFF) / 255.0; // B
|
||||
Vertices[i].normal.x = ((color) & 0xff) / 255.0f; // R
|
||||
Vertices[i].normal.y = ((color >> 8) & 0xff) / 255.0f; // G
|
||||
Vertices[i].normal.z = ((color >> 16) & 0xff) / 255.0f; // B
|
||||
}
|
||||
}
|
||||
else if( eType == TP_FREESPOTLIGHT ) {
|
||||
// single light points only have single data point, duh
|
||||
Vertices.emplace_back();
|
||||
}
|
||||
// Visible=true; //się potem wyłączy w razie potrzeby
|
||||
// iFlags|=0x0200; //wczytano z pliku tekstowego (jest właścicielem tablic)
|
||||
if (iNumVerts < 1)
|
||||
@@ -615,9 +631,10 @@ int TSubModel::TriangleAdd(TModel3d *m, texture_handle tex, int tri)
|
||||
s->iNumVerts += tri; // aktualizacja ilości wierzchołków
|
||||
return s->iNumVerts - tri; // zwraca pozycję tych trójkątów w submodelu
|
||||
};
|
||||
|
||||
/*
|
||||
basic_vertex *TSubModel::TrianglePtr(int tex, int pos, glm::vec3 const &Ambient, glm::vec3 const &Diffuse, glm::vec3 const &Specular )
|
||||
{ // zwraca wskaźnik do wypełnienia tabeli wierzchołków, używane przy tworzeniu E3D terenu
|
||||
|
||||
TSubModel *s = this;
|
||||
while (s ? s->TextureID != tex : false)
|
||||
{ // szukanie submodelu o danej teksturze
|
||||
@@ -637,7 +654,7 @@ basic_vertex *TSubModel::TrianglePtr(int tex, int pos, glm::vec3 const &Ambient,
|
||||
s->ColorsSet(Ambient, Diffuse, Specular); // ustawienie kolorów świateł
|
||||
return s->Vertices + pos; // wskaźnik na wolne miejsce w tabeli wierzchołków
|
||||
};
|
||||
|
||||
*/
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
void TSubModel::DisplayLists()
|
||||
{ // utworznie po jednej skompilowanej liście dla
|
||||
@@ -709,10 +726,10 @@ void TSubModel::InitialRotate(bool doit)
|
||||
{ // konwersja układu współrzędnych na zgodny ze scenerią
|
||||
if (iFlags & 0xC000) // jeśli jest animacja albo niejednostkowy transform
|
||||
{ // niejednostkowy transform jest mnożony i wystarczy zabawy
|
||||
if (doit)
|
||||
{ // obrót lewostronny
|
||||
if (!fMatrix) // macierzy może nie być w dodanym "bananie"
|
||||
{
|
||||
if (doit) {
|
||||
// obrót lewostronny
|
||||
if (!fMatrix) {
|
||||
// macierzy może nie być w dodanym "bananie"
|
||||
fMatrix = new float4x4(); // tworzy macierz o przypadkowej zawartości
|
||||
fMatrix->Identity(); // a zaczynamy obracanie od jednostkowej
|
||||
}
|
||||
@@ -729,16 +746,18 @@ void TSubModel::InitialRotate(bool doit)
|
||||
{ // jak nie ma potomnych, można wymnożyć przez transform i wyjedynkować
|
||||
// go
|
||||
float4x4 *mat = GetMatrix(); // transform submodelu
|
||||
if (Vertices)
|
||||
{
|
||||
for (int i = 0; i < iNumVerts; ++i)
|
||||
Vertices[i].position = (*mat) * Vertices[i].position;
|
||||
(*mat)(3)[0] = (*mat)(3)[1] = (*mat)(3)[2] =
|
||||
0.0; // zerujemy przesunięcie przed obracaniem normalnych
|
||||
if (eType != TP_STARS) // gwiazdki mają kolory zamiast normalnych, to
|
||||
// ich wtedy nie ruszamy
|
||||
for (int i = 0; i < iNumVerts; ++i)
|
||||
Vertices[i].normal = glm::normalize((*mat) * Vertices[i].normal);
|
||||
if( false == Vertices.empty() ) {
|
||||
for( auto &vertex : Vertices ) {
|
||||
vertex.position = (*mat) * vertex.position;
|
||||
}
|
||||
// zerujemy przesunięcie przed obracaniem normalnych
|
||||
(*mat)(3)[0] = (*mat)(3)[1] = (*mat)(3)[2] = 0.0;
|
||||
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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
mat->Identity(); // jedynkowanie transformu po przeliczeniu wierzchołków
|
||||
iFlags &= ~0x8000; // transform jedynkowy
|
||||
@@ -748,23 +767,26 @@ void TSubModel::InitialRotate(bool doit)
|
||||
if (doit)
|
||||
{ // jeśli jest jednostkowy transform, to przeliczamy
|
||||
// wierzchołki, a mnożenie podajemy dalej
|
||||
double t;
|
||||
if (Vertices)
|
||||
for (int i = 0; i < iNumVerts; ++i)
|
||||
{
|
||||
Vertices[i].position.x = -Vertices[i].position.x; // zmiana znaku X
|
||||
t = Vertices[i].position.y; // zamiana Y i Z
|
||||
Vertices[i].position.y = Vertices[i].position.z;
|
||||
Vertices[i].position.z = t;
|
||||
float swapcopy;
|
||||
// if( false == Vertices.empty() ) {
|
||||
/*
|
||||
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;
|
||||
// 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[ i ].normal.x = -Vertices[ i ].normal.x; // zmiana znaku X
|
||||
t = Vertices[ i ].normal.y; // zamiana Y i Z
|
||||
Vertices[ i ].normal.y = Vertices[ i ].normal.z;
|
||||
Vertices[ i ].normal.z = t;
|
||||
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;
|
||||
}
|
||||
}
|
||||
// }
|
||||
if (Child)
|
||||
Child->InitialRotate(doit); // potomne ewentualnie obrócimy
|
||||
}
|
||||
@@ -1028,7 +1050,7 @@ void TSubModel::RaAnimation(TAnimType a)
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
void TSubModel::RaArrayFill(basic_vertex *Vert)
|
||||
{ // wypełnianie tablic VBO
|
||||
if (Child)
|
||||
@@ -1038,22 +1060,31 @@ void TSubModel::RaArrayFill(basic_vertex *Vert)
|
||||
Vert[ iVboPtr + i ].position = Vertices[ i ].position;
|
||||
Vert[ iVboPtr + i ].normal = Vertices[ i ].normal;
|
||||
Vert[ iVboPtr + i ].texture = Vertices[ i ].texture;
|
||||
/*
|
||||
Vert[iVboPtr + i].x = Vertices[i].position.x;
|
||||
Vert[iVboPtr + i].y = Vertices[i].position.y;
|
||||
Vert[iVboPtr + i].z = Vertices[i].position.z;
|
||||
Vert[iVboPtr + i].nx = Vertices[i].normal.x;
|
||||
Vert[iVboPtr + i].ny = Vertices[i].normal.y;
|
||||
Vert[iVboPtr + i].nz = Vertices[i].normal.z;
|
||||
Vert[iVboPtr + i].u = Vertices[i].texture.s;
|
||||
Vert[iVboPtr + i].v = Vertices[i].texture.t;
|
||||
*/
|
||||
}
|
||||
else if( eType == TP_FREESPOTLIGHT )
|
||||
Vert[ iVboPtr ].position = glm::vec3();
|
||||
if (Next)
|
||||
Next->RaArrayFill(Vert);
|
||||
};
|
||||
*/
|
||||
void
|
||||
TSubModel::create_geometry( geometrybank_handle const &Bank ) {
|
||||
|
||||
if( Child )
|
||||
Child->create_geometry( Bank );
|
||||
|
||||
if( false == Vertices.empty() ) {
|
||||
// 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 ?
|
||||
eType :
|
||||
GL_POINTS );
|
||||
m_geometry = GfxRenderer.Insert( Vertices, Bank, type );
|
||||
}
|
||||
|
||||
if( Next )
|
||||
Next->create_geometry( Bank );
|
||||
}
|
||||
|
||||
// NOTE: leftover from static distance factor adjustment.
|
||||
// TODO: get rid of it, once we have the dynamic adjustment code in place
|
||||
@@ -1285,9 +1316,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);
|
||||
*/
|
||||
if (TextureID <= 0)
|
||||
sn_utils::ls_int32(s, TextureID);
|
||||
else
|
||||
@@ -1324,7 +1356,7 @@ void TSubModel::serialize(std::ostream &s,
|
||||
s.put(0);
|
||||
}
|
||||
|
||||
void TModel3d::SaveToBinFile(char const *FileName)
|
||||
void TModel3d::SaveToBinFile(std::string const &FileName)
|
||||
{
|
||||
// TODO: re-implement!
|
||||
return;
|
||||
@@ -1637,10 +1669,12 @@ 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
|
||||
*/
|
||||
}
|
||||
else
|
||||
TextureID = iTexture;
|
||||
@@ -1662,8 +1696,9 @@ void TSubModel::BinInit(TSubModel *s, float4x4 *m, std::vector<std::string> *t,
|
||||
}
|
||||
|
||||
iFlags &= ~0x0200; // wczytano z pliku binarnego (nie jest właścicielem tablic)
|
||||
|
||||
/*
|
||||
iVboPtr = tVboPtr;
|
||||
*/
|
||||
};
|
||||
|
||||
void TModel3d::LoadFromBinFile(std::string const &FileName, bool dynamic)
|
||||
@@ -1702,7 +1737,7 @@ void TModel3d::LoadFromTextFile(std::string const &FileName, bool dynamic)
|
||||
break;
|
||||
}
|
||||
SubModel = new TSubModel();
|
||||
iNumVerts += SubModel->Load(parser, this, iNumVerts, dynamic);
|
||||
iNumVerts += SubModel->Load(parser, this, /*iNumVerts,*/ dynamic);
|
||||
|
||||
// będzie potrzebne do wyliczenia pozycji, np. pantografu
|
||||
SubModel->Parent = AddToNamed(parent.c_str(), SubModel);
|
||||
@@ -1752,37 +1787,15 @@ void TModel3d::Init()
|
||||
if (false == asBinary.empty()) // jeśli jest podana nazwa
|
||||
{
|
||||
if (Global::iConvertModels) // i włączony zapis
|
||||
SaveToBinFile(asBinary.c_str()); // utworzy tablicę (m_pVNT)
|
||||
SaveToBinFile( asBinary ); // utworzy tablicę (m_pVNT)
|
||||
asBinary = ""; // zablokowanie powtórnego zapisu
|
||||
}
|
||||
#ifdef EU07_USE_OLD_DRAW_CODE
|
||||
if (iNumVerts)
|
||||
{
|
||||
if (Global::bUseVBO)
|
||||
{
|
||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
||||
if (!m_pVNT) // jeśli nie ma jeszcze tablicy (wczytano z pliku tekstowego)
|
||||
#else
|
||||
if( m_pVNT.empty() )
|
||||
#endif
|
||||
{ // tworzenie tymczasowej tablicy z wierzchołkami całego modelu
|
||||
MakeArray(iNumVerts); // tworzenie tablic dla VBO
|
||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
||||
Root->RaArrayFill(m_pVNT); // wypełnianie tablicy
|
||||
#else
|
||||
Root->RaArrayFill( m_pVNT.data() ); // wypełnianie tablicy
|
||||
#endif
|
||||
BuildVBOs(); // tworzenie VBO i usuwanie tablicy z pamięci
|
||||
}
|
||||
else
|
||||
BuildVBOs(false); // tworzenie VBO bez usuwania tablicy z pamięci
|
||||
}
|
||||
else
|
||||
{ // przygotowanie skompilowanych siatek dla DisplayLists
|
||||
Root->DisplayLists(); // tworzenie skompilowanej listy dla submodelu
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (iNumVerts) {
|
||||
if( m_geometrybank == NULL ) {
|
||||
m_geometrybank = GfxRenderer.Create_Bank();
|
||||
}
|
||||
Root->create_geometry( m_geometrybank );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
19
Model3d.h
19
Model3d.h
@@ -112,12 +112,15 @@ private:
|
||||
|
||||
TSubModel *Next;
|
||||
TSubModel *Child;
|
||||
/*
|
||||
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
|
||||
// short TexAlpha; //Ra: nie używane już
|
||||
/*
|
||||
GLuint uiDisplayList; // roboczy numer listy wyświetlania
|
||||
*/
|
||||
float Opacity; // nie używane, ale wczytywane //m7todo: wywalić to
|
||||
float f_Angle;
|
||||
float3 v_RotateAxis;
|
||||
@@ -125,7 +128,10 @@ private:
|
||||
|
||||
public: // chwilowo
|
||||
float3 v_TransVector;
|
||||
/*
|
||||
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
|
||||
public:
|
||||
@@ -138,7 +144,7 @@ public:
|
||||
std::string pTexture; // robocza nazwa tekstury do zapisania w pliku binarnym
|
||||
std::string pName; // robocza nazwa
|
||||
private:
|
||||
int SeekFaceNormal(unsigned int *Masks, int f, unsigned int dwMask, glm::vec3 *pt, basic_vertex *Vertices);
|
||||
int SeekFaceNormal( std::vector<unsigned int> const &Masks, int const Startface, unsigned int const Mask, glm::vec3 const &Position, vertex_array const &Vertices );
|
||||
void RaAnimation(TAnimType a);
|
||||
|
||||
public:
|
||||
@@ -151,13 +157,15 @@ public:
|
||||
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 NextAdd(TSubModel *SubModel);
|
||||
TSubModel * NextGet() { return Next; };
|
||||
TSubModel * ChildGet() { return Child; };
|
||||
int TriangleAdd(TModel3d *m, texture_handle tex, int tri);
|
||||
/*
|
||||
basic_vertex * TrianglePtr(int tex, int pos, glm::vec3 const &Ambient, glm::vec3 const &Diffuse, glm::vec3 const &Specular );
|
||||
*/
|
||||
void SetRotate(float3 vNewRotateAxis, float fNewAngle);
|
||||
void SetRotateXYZ(vector3 vNewAngles);
|
||||
void SetRotateXYZ(float3 vNewAngles);
|
||||
@@ -168,7 +176,10 @@ 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 );
|
||||
int FlagsCheck();
|
||||
void WillBeAnimated()
|
||||
{
|
||||
@@ -241,7 +252,7 @@ public:
|
||||
void LoadFromTextFile(std::string const &FileName, bool dynamic);
|
||||
void LoadFromBinFile(std::string const &FileName, bool dynamic);
|
||||
bool LoadFromFile(std::string const &FileName, bool dynamic);
|
||||
void SaveToBinFile(char const *FileName);
|
||||
void SaveToBinFile(std::string const &FileName);
|
||||
void BreakHierarhy();
|
||||
int Flags() const { return iFlags; };
|
||||
void Init();
|
||||
|
||||
11
Texture.cpp
11
Texture.cpp
@@ -795,6 +795,8 @@ texture_manager::create( std::string Filename, std::string const &Dir, int const
|
||||
texture_manager::texture( textureindex ).load();
|
||||
#ifndef EU07_DEFERRED_TEXTURE_UPLOAD
|
||||
texture_manager::texture( textureindex ).create();
|
||||
// texture creation binds a different texture, force a re-bind on next use
|
||||
m_activetexture = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -803,16 +805,11 @@ texture_manager::create( std::string Filename, std::string const &Dir, int const
|
||||
|
||||
void
|
||||
texture_manager::bind( texture_handle const Texture ) {
|
||||
/*
|
||||
// NOTE: this optimization disabled for the time being, until the render code is reviewed
|
||||
// having it active would lead to some terrain and spline chunks receiving wrong
|
||||
// (the most recent?) texture, instead of the proper one. It'd also affect negatively
|
||||
// light point rendering.
|
||||
if( Id == m_activetexture ) {
|
||||
|
||||
if( Texture == m_activetexture ) {
|
||||
// don't bind again what's already active
|
||||
return;
|
||||
}
|
||||
*/
|
||||
// TODO: do binding in texture object, add support for other types
|
||||
if( Texture != 0 ) {
|
||||
#ifndef EU07_DEFERRED_TEXTURE_UPLOAD
|
||||
|
||||
201
Track.cpp
201
Track.cpp
@@ -1112,52 +1112,7 @@ void TTrack::RaAssign(TGroundNode *gn, TAnimModel *am, TEvent *done, TEvent *joi
|
||||
am->GetContainer(NULL)->EventAssign(done); // zdarzenie zakończenia animacji
|
||||
}
|
||||
};
|
||||
/*
|
||||
int TTrack::RaArrayPrepare()
|
||||
{ // przygotowanie tablic do skopiowania do VBO (zliczanie wierzchołków)
|
||||
if (bVisible) // o ile w ogóle widać
|
||||
switch (iCategoryFlag & 15)
|
||||
{
|
||||
case 1: // tor
|
||||
if (eType == tt_Switch) // dla zwrotnicy tylko szyny
|
||||
return 48 * ((TextureID1 ? SwitchExtension->Segments[0]->RaSegCount() : 0) +
|
||||
(TextureID2 ? SwitchExtension->Segments[1]->RaSegCount() : 0));
|
||||
else // dla toru podsypka plus szyny
|
||||
return (Segment->RaSegCount()) * ((TextureID1 ? 48 : 0) + (TextureID2 ? 8 : 0));
|
||||
case 2: // droga
|
||||
if (eType == tt_Cross) // tylko dla skrzyżowania dróg
|
||||
{ // specjalny sposób obliczania liczby wierzchołków w skrzyżowaniu
|
||||
if( SwitchExtension->iRoads == 3 ) {
|
||||
// mogą być tylko 3 drogi zamiast 4
|
||||
SwitchExtension->iPoints =
|
||||
SwitchExtension->Segments[ 0 ]->RaSegCount()
|
||||
+ SwitchExtension->Segments[ 1 ]->RaSegCount()
|
||||
+ SwitchExtension->Segments[ 2 ]->RaSegCount();
|
||||
}
|
||||
else {
|
||||
SwitchExtension->iPoints =
|
||||
SwitchExtension->Segments[ 2 ]->RaSegCount()
|
||||
+ SwitchExtension->Segments[ 3 ]->RaSegCount()
|
||||
+ SwitchExtension->Segments[ 4 ]->RaSegCount()
|
||||
+ SwitchExtension->Segments[ 5 ]->RaSegCount();
|
||||
}
|
||||
// each sub-segment covers only one side of the road, so it has points for single sideroad, if any
|
||||
return ( ( TextureID1 ? SwitchExtension->iPoints + SwitchExtension->iRoads + 2 : 0 ) + ( TextureID2 ? SwitchExtension->iPoints * 6 : 0 ) );
|
||||
}
|
||||
else // standardowo dla zwykłej drogi
|
||||
if (fTexHeight1 >= 0) // jeśli fTexHeight1<0, to są chodniki i może któregoś nie być
|
||||
return ( Segment->RaSegCount()) *
|
||||
((TextureID1 ? 4 : 0) + (TextureID2 ? 12 : 0)); // może nie być poziomego!
|
||||
else
|
||||
return (Segment->RaSegCount()) *
|
||||
((TextureID1 ? 4 : 0) +
|
||||
(TextureID2 ? (fTexWidth != 0.0 ? 6 : 0) + (fTexSlope != 0.0 ? 6 : 0) : 0));
|
||||
case 4: // rzeki do przemyślenia
|
||||
return (Segment->RaSegCount()) * ((TextureID1 ? 4 : 0) + (TextureID2 ? 12 : 0));
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
*/
|
||||
|
||||
// wypełnianie tablic VBO
|
||||
void TTrack::create_geometry( geometrybank_handle const &Bank ) {
|
||||
// Ra: trzeba rozdzielić szyny od podsypki, aby móc grupować wg tekstur
|
||||
@@ -1875,159 +1830,7 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
|
||||
}
|
||||
return;
|
||||
};
|
||||
/*
|
||||
void TTrack::RaRenderVBO( int iPtr ) { // renderowanie z użyciem VBO
|
||||
// Ra 2014-07: trzeba wymienić GL_TRIANGLE_STRIP na GL_TRIANGLES i renderować trójkąty sektora dla kolejnych tekstur!
|
||||
EnvironmentSet();
|
||||
int seg;
|
||||
switch( iCategoryFlag & 15 ) {
|
||||
case 1: {
|
||||
// tor
|
||||
if( eType == tt_Switch ) // dla zwrotnicy tylko szyny
|
||||
{
|
||||
int const bladesegmentcount = 2;
|
||||
if( TextureID1 ) {
|
||||
if( ( seg = SwitchExtension->Segments[ 0 ]->RaSegCount() ) > 0 ) {
|
||||
GfxRenderer.Bind( TextureID1 ); // szyny +
|
||||
::glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 24 * seg );
|
||||
iPtr += 24 * seg;
|
||||
::glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 24 * ( seg - bladesegmentcount ) );
|
||||
// NOTE: due to way blades bend need to render each segment separately, or some unwanted edges may show
|
||||
iPtr += 24 * ( seg - bladesegmentcount );
|
||||
for( int i = 0; i < bladesegmentcount; ++i ) {
|
||||
::glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 24 );
|
||||
iPtr += 24;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( TextureID2 ) {
|
||||
if( ( seg = SwitchExtension->Segments[ 1 ]->RaSegCount() ) > 0 ) {
|
||||
GfxRenderer.Bind( TextureID2 );
|
||||
// NOTE: due to way blades bend need to render each segment separately, or some unwanted edges may show
|
||||
for( int i = 0; i < bladesegmentcount; ++i ) {
|
||||
::glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 24 );
|
||||
iPtr += 24;
|
||||
}
|
||||
::glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 24 * ( seg - bladesegmentcount ) );
|
||||
iPtr += 24 * ( seg - bladesegmentcount );
|
||||
::glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 24 * seg );
|
||||
iPtr += 24 * seg;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // dla toru podsypka plus szyny
|
||||
{
|
||||
if( ( seg = Segment->RaSegCount() ) > 0 ) {
|
||||
if( TextureID2 ) {
|
||||
GfxRenderer.Bind( TextureID2 ); // podsypka
|
||||
glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 8 * seg );
|
||||
iPtr += 8 * seg; // pominięcie podsypki
|
||||
}
|
||||
if( TextureID1 ) {
|
||||
GfxRenderer.Bind( TextureID1 ); // szyny
|
||||
glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 24 * seg );
|
||||
iPtr += 24 * seg; // pominięcie lewej szyny
|
||||
glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 24 * seg );
|
||||
iPtr += 24 * seg;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
// droga
|
||||
switch( eType ) {
|
||||
case tt_Normal: {
|
||||
if( ( seg = Segment->RaSegCount() ) > 0 ) {
|
||||
if( TextureID1 ) {
|
||||
GfxRenderer.Bind( TextureID1 ); // nawierzchnia
|
||||
::glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 4 * seg );
|
||||
iPtr += 4 * seg;
|
||||
}
|
||||
if( TextureID2 ) {
|
||||
GfxRenderer.Bind( TextureID2 ); // pobocze
|
||||
if( fTexHeight1 >= 0.0 ) { // normalna droga z poboczem
|
||||
::glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 6 * seg );
|
||||
iPtr += 6 * seg; // pominięcie lewego pobocza
|
||||
::glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 6 * seg );
|
||||
iPtr += 6 * seg;
|
||||
}
|
||||
else { // z chodnikami o różnych szerokociach
|
||||
if( fTexWidth != 0.0 ) {
|
||||
::glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 6 * seg );
|
||||
iPtr += 6 * seg; // pominięcie lewego pobocza
|
||||
}
|
||||
if( fTexSlope != 0.0 ) {
|
||||
::glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 6 * seg );
|
||||
iPtr += 6 * seg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case tt_Cross: {
|
||||
if( (seg = SwitchExtension->iPoints) > 0 ) {
|
||||
if( TextureID2 ) {
|
||||
// sidewalks
|
||||
GfxRenderer.Bind( TextureID2 );
|
||||
if( fTexHeight1 != 0.0 ) {
|
||||
if( SwitchExtension->iRoads == 4 ) {
|
||||
::glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 6 * SwitchExtension->Segments[ 2 ]->RaSegCount() );
|
||||
iPtr += 6 * SwitchExtension->Segments[ 2 ]->RaSegCount();
|
||||
::glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 6 * SwitchExtension->Segments[ 3 ]->RaSegCount() );
|
||||
iPtr += 6 * SwitchExtension->Segments[ 3 ]->RaSegCount();
|
||||
::glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 6 * SwitchExtension->Segments[ 4 ]->RaSegCount() );
|
||||
iPtr += 6 * SwitchExtension->Segments[ 4 ]->RaSegCount();
|
||||
::glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 6 * SwitchExtension->Segments[ 5 ]->RaSegCount() );
|
||||
iPtr += 6 * SwitchExtension->Segments[ 5 ]->RaSegCount();
|
||||
}
|
||||
else {
|
||||
// presumed 3 roads otherwise, as we only support 3 & 4 road crossings
|
||||
::glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 6 * SwitchExtension->Segments[ 2 ]->RaSegCount() );
|
||||
iPtr += 6 * SwitchExtension->Segments[ 2 ]->RaSegCount();
|
||||
::glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 6 * SwitchExtension->Segments[ 1 ]->RaSegCount() );
|
||||
iPtr += 6 * SwitchExtension->Segments[ 1 ]->RaSegCount();
|
||||
::glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 6 * SwitchExtension->Segments[ 0 ]->RaSegCount() );
|
||||
iPtr += 6 * SwitchExtension->Segments[ 0 ]->RaSegCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
if( TextureID1 ) {
|
||||
// roads
|
||||
GfxRenderer.Bind( TextureID1 );
|
||||
::glDrawArrays( GL_TRIANGLE_FAN, iPtr, SwitchExtension->iPoints + SwitchExtension->iRoads + 2 );
|
||||
iPtr += SwitchExtension->iPoints;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: { break; }
|
||||
} //switch etype
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
// rzeki - jeszcze do przemyślenia
|
||||
if( ( seg = Segment->RaSegCount() ) > 0 ) {
|
||||
if( TextureID1 ) {
|
||||
GfxRenderer.Bind( TextureID1 ); // nawierzchnia
|
||||
glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 4 * seg );
|
||||
iPtr += 4 * seg;
|
||||
}
|
||||
if( TextureID2 ) {
|
||||
GfxRenderer.Bind( TextureID2 ); // pobocze
|
||||
glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 6 * seg );
|
||||
iPtr += 6 * seg; // pominięcie lewego pobocza
|
||||
glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 6 * seg );
|
||||
iPtr += 6 * seg;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
EnvironmentReset();
|
||||
};
|
||||
*/
|
||||
|
||||
void TTrack::EnvironmentSet()
|
||||
{ // ustawienie zmienionego światła
|
||||
glColor3f(1.0f, 1.0f, 1.0f); // Ra: potrzebne to?
|
||||
|
||||
@@ -48,11 +48,11 @@ basic_vertex::deserialize( std::istream &s ) {
|
||||
|
||||
// creates a new geometry chunk of specified type from supplied vertex data. returns: handle to the chunk
|
||||
geometry_handle
|
||||
geometry_bank::create( vertex_array &Vertices, unsigned int const Type, unsigned int const Streams ) {
|
||||
geometry_bank::create( vertex_array &Vertices, unsigned int const Type ) {
|
||||
|
||||
if( true == Vertices.empty() ) { return geometry_handle( 0, 0 ); }
|
||||
|
||||
m_chunks.emplace_back( Vertices, Type, Streams );
|
||||
m_chunks.emplace_back( Vertices, Type );
|
||||
// NOTE: handle is effectively (index into chunk array + 1) this leaves value of 0 to serve as error/empty handle indication
|
||||
geometry_handle chunkhandle { 0, static_cast<std::uint32_t>(m_chunks.size()) };
|
||||
// template method
|
||||
@@ -98,9 +98,9 @@ geometry_bank::append( vertex_array &Vertices, geometry_handle const &Geometry )
|
||||
|
||||
// draws geometry stored in specified chunk
|
||||
void
|
||||
geometry_bank::draw( geometry_handle const &Geometry ) {
|
||||
geometry_bank::draw( geometry_handle const &Geometry, unsigned int const Streams ) {
|
||||
// template method
|
||||
draw_( Geometry );
|
||||
draw_( Geometry, Streams );
|
||||
}
|
||||
|
||||
vertex_array const &
|
||||
@@ -111,7 +111,8 @@ geometry_bank::vertices( geometry_handle const &Geometry ) const {
|
||||
|
||||
// opengl vbo-based variant of the geometry bank
|
||||
|
||||
GLuint opengl_vbogeometrybank::m_activebuffer{ NULL }; // buffer bound currently on the opengl end, if any
|
||||
GLuint opengl_vbogeometrybank::m_activebuffer { NULL }; // buffer bound currently on the opengl end, if any
|
||||
unsigned int opengl_vbogeometrybank::m_activestreams { stream::none }; // currently enabled data type pointers
|
||||
|
||||
// create() subclass details
|
||||
void
|
||||
@@ -140,7 +141,7 @@ opengl_vbogeometrybank::replace_( geometry_handle const &Geometry ) {
|
||||
|
||||
// draw() subclass details
|
||||
void
|
||||
opengl_vbogeometrybank::draw_( geometry_handle const &Geometry ) {
|
||||
opengl_vbogeometrybank::draw_( geometry_handle const &Geometry, unsigned int const Streams ) {
|
||||
|
||||
if( m_buffer == NULL ) {
|
||||
// if there's no buffer, we'll have to make one
|
||||
@@ -152,6 +153,7 @@ opengl_vbogeometrybank::draw_( geometry_handle const &Geometry ) {
|
||||
auto chunkiterator = m_chunks.cbegin();
|
||||
for( auto &chunkrecord : m_chunkrecords ) {
|
||||
// fill records for all chunks, based on the chunk data
|
||||
chunkrecord.is_good = false; // if we're re-creating buffer, chunks might've been uploaded in the old one
|
||||
chunkrecord.offset = datasize;
|
||||
chunkrecord.size = chunkiterator->vertices.size();
|
||||
datasize += chunkrecord.size;
|
||||
@@ -193,6 +195,9 @@ opengl_vbogeometrybank::draw_( geometry_handle const &Geometry ) {
|
||||
chunk.vertices.data() );
|
||||
chunkrecord.is_good = true;
|
||||
}
|
||||
if( m_activestreams != Streams ) {
|
||||
bind_streams( Streams );
|
||||
}
|
||||
// ...render...
|
||||
::glDrawArrays( chunk.type, chunkrecord.offset, chunkrecord.size );
|
||||
// ...post-render cleanup
|
||||
@@ -208,16 +213,8 @@ void
|
||||
opengl_vbogeometrybank::bind_buffer() {
|
||||
|
||||
::glBindBuffer( GL_ARRAY_BUFFER, m_buffer );
|
||||
// TODO: allow specifying other vertex data setups
|
||||
::glVertexPointer( 3, GL_FLOAT, sizeof( basic_vertex ), static_cast<char *>( nullptr ) );
|
||||
::glNormalPointer( GL_FLOAT, sizeof( basic_vertex ), static_cast<char *>( nullptr ) + sizeof(float) * 3 ); // normalne
|
||||
::glTexCoordPointer( 2, GL_FLOAT, sizeof( basic_vertex ), static_cast<char *>( nullptr ) + 24 ); // wierzchołki
|
||||
// TODO: allow specifying other vertex data setups, either in the draw() parameters or during chunk or buffer creation
|
||||
::glEnableClientState( GL_VERTEX_ARRAY );
|
||||
::glEnableClientState( GL_NORMAL_ARRAY );
|
||||
::glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
|
||||
m_activebuffer = m_buffer;
|
||||
m_activestreams = stream::none;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -231,9 +228,47 @@ opengl_vbogeometrybank::delete_buffer() {
|
||||
}
|
||||
m_buffer = NULL;
|
||||
m_buffercapacity = 0;
|
||||
// NOTE: since we've deleted the buffer all chunks it held were rendered invalid as well
|
||||
// instead of clearing their state here we're delaying it until new buffer is created to avoid looping through chunk records twice
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
opengl_vbogeometrybank::bind_streams( unsigned int const Streams ) {
|
||||
|
||||
if( Streams & stream::position ) {
|
||||
::glVertexPointer( 3, GL_FLOAT, sizeof( basic_vertex ), static_cast<char *>( nullptr ) );
|
||||
::glEnableClientState( GL_VERTEX_ARRAY );
|
||||
}
|
||||
else {
|
||||
::glDisableClientState( GL_VERTEX_ARRAY );
|
||||
}
|
||||
// NOTE: normal and color streams share the data, making them effectively mutually exclusive
|
||||
if( Streams & stream::normal ) {
|
||||
::glNormalPointer( GL_FLOAT, sizeof( basic_vertex ), static_cast<char *>( nullptr ) + sizeof( float ) * 3 );
|
||||
::glEnableClientState( GL_NORMAL_ARRAY );
|
||||
}
|
||||
else {
|
||||
::glDisableClientState( GL_NORMAL_ARRAY );
|
||||
}
|
||||
if( Streams & stream::color ) {
|
||||
::glColorPointer( 3, GL_FLOAT, sizeof( basic_vertex ), static_cast<char *>( nullptr ) + sizeof( float ) * 3 );
|
||||
::glEnableClientState( GL_COLOR_ARRAY );
|
||||
}
|
||||
else {
|
||||
::glDisableClientState( GL_COLOR_ARRAY );
|
||||
}
|
||||
if( Streams & stream::texture ) {
|
||||
::glTexCoordPointer( 2, GL_FLOAT, sizeof( basic_vertex ), static_cast<char *>( nullptr ) + 24 );
|
||||
::glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
}
|
||||
else {
|
||||
::glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
}
|
||||
|
||||
m_activestreams = Streams;
|
||||
}
|
||||
|
||||
// opengl display list based variant of the geometry bank
|
||||
|
||||
// create() subclass details
|
||||
@@ -252,21 +287,25 @@ opengl_dlgeometrybank::replace_( geometry_handle const &Geometry ) {
|
||||
|
||||
// draw() subclass details
|
||||
void
|
||||
opengl_dlgeometrybank::draw_( geometry_handle const &Geometry ) {
|
||||
opengl_dlgeometrybank::draw_( geometry_handle const &Geometry, unsigned int const Streams ) {
|
||||
|
||||
auto &chunkrecord = m_chunkrecords[ Geometry.chunk - 1 ];
|
||||
if( chunkrecord.streams != Streams ) {
|
||||
delete_list( Geometry );
|
||||
}
|
||||
if( chunkrecord.list == 0 ) {
|
||||
// we don't have a list ready, so compile one
|
||||
chunkrecord.streams = Streams;
|
||||
chunkrecord.list = ::glGenLists( 1 );
|
||||
auto const &chunk = geometry_bank::chunk( Geometry );
|
||||
::glNewList( chunkrecord.list, GL_COMPILE );
|
||||
|
||||
::glBegin( chunk.type );
|
||||
// TODO: add specification of chunk vertex attributes
|
||||
for( auto const &vertex : chunk.vertices ) {
|
||||
::glNormal3fv( glm::value_ptr( vertex.normal ) );
|
||||
::glTexCoord2fv( glm::value_ptr( vertex.texture ) );
|
||||
::glVertex3fv( glm::value_ptr( vertex.position ) );
|
||||
if( Streams & stream::normal ) { ::glNormal3fv( glm::value_ptr( vertex.normal ) ); }
|
||||
else if( Streams & stream::color ) { ::glColor3fv( glm::value_ptr( vertex.normal ) ); }
|
||||
if( Streams & stream::texture ) { ::glTexCoord2fv( glm::value_ptr( vertex.texture ) ); }
|
||||
if( Streams & stream::position ) { ::glVertex3fv( glm::value_ptr( vertex.position ) ); }
|
||||
}
|
||||
::glEnd();
|
||||
::glEndList();
|
||||
@@ -279,8 +318,11 @@ void
|
||||
opengl_dlgeometrybank::delete_list( geometry_handle const &Geometry ) {
|
||||
// NOTE: given it's our own internal method we trust it to be called with valid parameters
|
||||
auto &chunkrecord = m_chunkrecords[ Geometry.chunk - 1 ];
|
||||
::glDeleteLists( chunkrecord.list, 1 );
|
||||
chunkrecord.list = 0;
|
||||
if( chunkrecord.list != 0 ) {
|
||||
::glDeleteLists( chunkrecord.list, 1 );
|
||||
chunkrecord.list = 0;
|
||||
}
|
||||
chunkrecord.streams = stream::none;
|
||||
}
|
||||
|
||||
// geometry bank manager, holds collection of geometry banks
|
||||
@@ -320,11 +362,11 @@ geometrybank_manager::append( vertex_array &Vertices, geometry_handle const &Geo
|
||||
}
|
||||
// draws geometry stored in specified chunk
|
||||
void
|
||||
geometrybank_manager::draw( geometry_handle const &Geometry ) {
|
||||
geometrybank_manager::draw( geometry_handle const &Geometry, unsigned int const Streams ) {
|
||||
|
||||
if( Geometry == NULL ) { return; }
|
||||
|
||||
return bank( Geometry )->draw( Geometry );
|
||||
return bank( Geometry )->draw( Geometry, Streams );
|
||||
}
|
||||
|
||||
// provides direct access to vertex data of specfied chunk
|
||||
|
||||
@@ -33,10 +33,11 @@ struct basic_vertex {
|
||||
|
||||
// data streams carried in a vertex
|
||||
enum stream {
|
||||
none = 0x0,
|
||||
position = 0x1,
|
||||
normal = 0x2,
|
||||
color = 0x4, // currently normal and colour streams are stored in the same slot, and mutually exclusive
|
||||
texture = 0x8
|
||||
normal = 0x2,
|
||||
color = 0x4, // currently normal and colour streams are stored in the same slot, and mutually exclusive
|
||||
texture = 0x8
|
||||
};
|
||||
|
||||
unsigned int const basic_streams { stream::position | stream::normal | stream::texture };
|
||||
@@ -87,7 +88,7 @@ public:
|
||||
// methods:
|
||||
// creates a new geometry chunk of specified type from supplied vertex data. returns: handle to the chunk or NULL
|
||||
geometry_handle
|
||||
create( vertex_array &Vertices, unsigned int const Type, unsigned int const Streams = stream::position | stream::normal | stream::texture );
|
||||
create( vertex_array &Vertices, unsigned int const Type );
|
||||
// replaces data of specified chunk with the supplied vertex data, starting from specified offset
|
||||
bool
|
||||
replace( vertex_array &Vertices, geometry_handle const &Geometry, std::size_t const Offset = 0 );
|
||||
@@ -96,11 +97,11 @@ public:
|
||||
append( vertex_array &Vertices, geometry_handle const &Geometry );
|
||||
// draws geometry stored in specified chunk
|
||||
void
|
||||
draw( geometry_handle const &Geometry );
|
||||
draw( geometry_handle const &Geometry, unsigned int const Streams = basic_streams );
|
||||
// draws geometry stored in supplied list of chunks
|
||||
template <typename Iterator_>
|
||||
void
|
||||
draw( Iterator_ First, Iterator_ Last ) { while( First != Last ) { draw( *First ); ++First; } }
|
||||
draw( Iterator_ First, Iterator_ Last, unsigned int const Streams = basic_streams ) { while( First != Last ) { draw( *First, Streams ); ++First; } }
|
||||
// provides direct access to vertex data of specfied chunk
|
||||
vertex_array const &
|
||||
vertices( geometry_handle const &Geometry ) const;
|
||||
@@ -108,12 +109,11 @@ public:
|
||||
protected:
|
||||
// types:
|
||||
struct geometry_chunk {
|
||||
unsigned int streams; // data streams carried by vertices
|
||||
unsigned int type; // kind of geometry used by the chunk
|
||||
vertex_array vertices; // geometry data
|
||||
|
||||
geometry_chunk( vertex_array &Vertices, unsigned int const Type, unsigned int const Streams ) :
|
||||
vertices( Vertices ), type( Type ), streams( Streams )
|
||||
geometry_chunk( vertex_array &Vertices, unsigned int const Type ) :
|
||||
vertices( Vertices ), type( Type )
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -139,7 +139,7 @@ private:
|
||||
// replace() subclass details
|
||||
virtual void replace_( geometry_handle const &Geometry ) = 0;
|
||||
// draw() subclass details
|
||||
virtual void draw_( geometry_handle const &Geometry ) = 0;
|
||||
virtual void draw_( geometry_handle const &Geometry, unsigned int const Streams ) = 0;
|
||||
};
|
||||
|
||||
// opengl vbo-based variant of the geometry bank
|
||||
@@ -154,7 +154,8 @@ public:
|
||||
static
|
||||
void
|
||||
reset() {
|
||||
m_activebuffer = 0; }
|
||||
m_activebuffer = 0;
|
||||
m_activestreams = stream::none; }
|
||||
|
||||
private:
|
||||
// types:
|
||||
@@ -175,15 +176,18 @@ private:
|
||||
replace_( geometry_handle const &Geometry );
|
||||
// draw() subclass details
|
||||
void
|
||||
draw_( geometry_handle const &Geometry );
|
||||
draw_( geometry_handle const &Geometry, unsigned int const Streams );
|
||||
void
|
||||
bind_buffer();
|
||||
void
|
||||
delete_buffer();
|
||||
void
|
||||
bind_streams( unsigned int const Streams );
|
||||
|
||||
// members:
|
||||
static GLuint m_activebuffer; // buffer bound currently on the opengl end, if any
|
||||
GLuint m_buffer{ NULL }; // id of the buffer holding data on the opengl end
|
||||
static unsigned int m_activestreams;
|
||||
GLuint m_buffer { NULL }; // id of the buffer holding data on the opengl end
|
||||
std::size_t m_buffercapacity{ 0 }; // total capacity of the last established buffer
|
||||
chunkrecord_sequence m_chunkrecords; // helper data for all stored geometry chunks, in matching order
|
||||
|
||||
@@ -202,7 +206,8 @@ public:
|
||||
private:
|
||||
// types:
|
||||
struct chunk_record {
|
||||
GLuint list{ 0 }; // display list associated with the chunk
|
||||
GLuint list { 0 }; // display list associated with the chunk
|
||||
unsigned int streams { 0 }; // stream combination used to generate the display list
|
||||
};
|
||||
|
||||
typedef std::vector<chunk_record> chunkrecord_sequence;
|
||||
@@ -216,7 +221,7 @@ private:
|
||||
replace_( geometry_handle const &Geometry );
|
||||
// draw() subclass details
|
||||
void
|
||||
draw_( geometry_handle const &Geometry );
|
||||
draw_( geometry_handle const &Geometry, unsigned int const Streams );
|
||||
void
|
||||
delete_list( geometry_handle const &Geometry );
|
||||
|
||||
@@ -247,12 +252,12 @@ public:
|
||||
append( vertex_array &Vertices, geometry_handle const &Geometry );
|
||||
// draws geometry stored in specified chunk
|
||||
void
|
||||
draw( geometry_handle const &Geometry );
|
||||
draw( geometry_handle const &Geometry, unsigned int const Streams = basic_streams );
|
||||
template <typename Iterator_>
|
||||
void
|
||||
draw( Iterator_ First, Iterator_ Last ) {
|
||||
draw( Iterator_ First, Iterator_ Last, unsigned int const Streams = basic_streams ) {
|
||||
while( First != Last ) {
|
||||
draw( *First );
|
||||
draw( *First, Streams );
|
||||
++First; } }
|
||||
// provides direct access to vertex data of specfied chunk
|
||||
vertex_array const &
|
||||
|
||||
25
renderer.cpp
25
renderer.cpp
@@ -157,7 +157,6 @@ opengl_renderer::Render() {
|
||||
// frustum tests are performed in 'world space' but after we set up frustum
|
||||
// we no longer need camera translation, only rotation
|
||||
::glMultMatrixd( glm::value_ptr( glm::dmat4( glm::dmat3( worldcamera ))));
|
||||
|
||||
Render( &World.Environment );
|
||||
Render( &World.Ground );
|
||||
|
||||
@@ -835,27 +834,8 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
||||
::glDisable( GL_LIGHTING );
|
||||
|
||||
// main draw call
|
||||
// TODO: add support for colour data draw mode
|
||||
m_geometry.draw( Submodel->m_geometry );
|
||||
/*
|
||||
if( Global::bUseVBO ) {
|
||||
// NOTE: we're doing manual switch to color vbo setup, because there doesn't seem to be any convenient way available atm
|
||||
// TODO: implement easier way to go about it
|
||||
::glDisableClientState( GL_NORMAL_ARRAY );
|
||||
::glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
::glEnableClientState( GL_COLOR_ARRAY );
|
||||
::glColorPointer( 3, GL_FLOAT, sizeof( basic_vertex ), static_cast<char *>( nullptr ) + 12 ); // kolory
|
||||
m_geometry.draw( Submodel->m_geometry, color_streams );
|
||||
|
||||
::glDrawArrays( GL_POINTS, Submodel->iVboPtr, Submodel->iNumVerts );
|
||||
|
||||
::glDisableClientState( GL_COLOR_ARRAY );
|
||||
::glEnableClientState( GL_NORMAL_ARRAY );
|
||||
::glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
}
|
||||
else {
|
||||
::glCallList( Submodel->uiDisplayList );
|
||||
}
|
||||
*/
|
||||
// post-draw reset
|
||||
::glPopAttrib();
|
||||
}
|
||||
@@ -986,9 +966,6 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
||||
// pozniej sprawdzamy czy jest wlaczony PROBLEND dla aktualnie renderowanego noda TRIANGLE,
|
||||
// wlasciwie dla kazdego node'a
|
||||
// i jezeli tak to odpowiedni GL_GREATER w przeciwnym wypadku standardowy 0.04
|
||||
/*
|
||||
Node->SetLastUsage( Timer::GetSimulationTime() );
|
||||
*/
|
||||
double const distancesquared = SquareMagnitude( ( Node->pCenter - Global::pCameraPosition ) / Global::ZoomFactor );
|
||||
if( ( distancesquared > ( Node->fSquareRadius * Global::fDistanceFactor ) )
|
||||
|| ( distancesquared < ( Node->fSquareMinRadius / Global::fDistanceFactor ) ) ) {
|
||||
|
||||
Reference in New Issue
Block a user