mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 17:29: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()
|
void TSubModel::FirstInit()
|
||||||
{
|
{
|
||||||
eType = TP_ROTATOR;
|
eType = TP_ROTATOR;
|
||||||
|
/*
|
||||||
Vertices = NULL;
|
Vertices = NULL;
|
||||||
uiDisplayList = 0;
|
uiDisplayList = 0;
|
||||||
|
*/
|
||||||
iNumVerts = -1; // do sprawdzenia
|
iNumVerts = -1; // do sprawdzenia
|
||||||
|
/*
|
||||||
iVboPtr = -1;
|
iVboPtr = -1;
|
||||||
|
*/
|
||||||
fLight = -1.0; //świetcenie wyłączone
|
fLight = -1.0; //świetcenie wyłączone
|
||||||
v_RotateAxis = float3(0, 0, 0);
|
v_RotateAxis = float3(0, 0, 0);
|
||||||
v_TransVector = float3(0, 0, 0);
|
v_TransVector = float3(0, 0, 0);
|
||||||
@@ -103,15 +107,19 @@ void TSubModel::FirstInit()
|
|||||||
|
|
||||||
TSubModel::~TSubModel()
|
TSubModel::~TSubModel()
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
if (uiDisplayList)
|
if (uiDisplayList)
|
||||||
glDeleteLists(uiDisplayList, 1);
|
glDeleteLists(uiDisplayList, 1);
|
||||||
|
*/
|
||||||
if (iFlags & 0x0200)
|
if (iFlags & 0x0200)
|
||||||
{ // wczytany z pliku tekstowego musi sam posprzątać
|
{ // wczytany z pliku tekstowego musi sam posprzątać
|
||||||
// SafeDeleteArray(Indices);
|
// SafeDeleteArray(Indices);
|
||||||
SafeDelete(Next);
|
SafeDelete(Next);
|
||||||
SafeDelete(Child);
|
SafeDelete(Child);
|
||||||
delete fMatrix; // własny transform trzeba usunąć (zawsze jeden)
|
delete fMatrix; // własny transform trzeba usunąć (zawsze jeden)
|
||||||
|
/*
|
||||||
delete[] Vertices;
|
delete[] Vertices;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
delete[] smLetter; // używany tylko roboczo dla TP_TEXT, do przyspieszenia
|
delete[] smLetter; // używany tylko roboczo dla TP_TEXT, do przyspieszenia
|
||||||
// wyświetlania
|
// wyświetlania
|
||||||
@@ -136,25 +144,20 @@ void TSubModel::NameSet(std::string const &Name)
|
|||||||
// int TSubModel::SeekFaceNormal(DWORD *Masks, int f,DWORD dwMask,vector3
|
// int TSubModel::SeekFaceNormal(DWORD *Masks, int f,DWORD dwMask,vector3
|
||||||
// *pt,GLVERTEX
|
// *pt,GLVERTEX
|
||||||
// *Vertices)
|
// *Vertices)
|
||||||
int TSubModel::SeekFaceNormal(unsigned int *Masks, int f, unsigned int dwMask, glm::vec3 *pt,
|
int TSubModel::SeekFaceNormal(std::vector<unsigned int> const &Masks, int const Startface, unsigned int const Mask, glm::vec3 const &Position, vertex_array const &Vertices)
|
||||||
basic_vertex *Vertices)
|
{ // szukanie punktu stycznego do (pt), zwraca numer wierzchołka, a nie trójkąta
|
||||||
{ // szukanie punktu stycznego
|
int facecount = iNumVerts / 3; // bo maska powierzchni jest jedna na trójkąt
|
||||||
// do (pt), zwraca numer
|
for( int faceidx = Startface; faceidx < facecount; ++faceidx ) {
|
||||||
// wierzchołka, a nie trójkąta
|
// pętla po trójkątach, od trójkąta (f)
|
||||||
int iNumFaces = iNumVerts / 3; // bo maska powierzchni jest jedna na trójkąt
|
if( Masks[ faceidx ] & Mask ) {
|
||||||
// GLVERTEX *p; //roboczy wskaźnik
|
// jeśli wspólna maska powierzchni
|
||||||
basic_vertex *p; // roboczy wskaźnik
|
for( int vertexidx = 0; vertexidx < 2; ++vertexidx ) {
|
||||||
for (int i = f; i < iNumFaces; ++i) // pętla po trójkątach, od trójkąta (f)
|
if( Vertices[ 3 * faceidx + vertexidx ].position == Position ) {
|
||||||
if (Masks[i] & dwMask) // jeśli wspólna maska powierzchni
|
return 3 * faceidx + vertexidx;
|
||||||
{
|
}
|
||||||
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;
|
|
||||||
}
|
|
||||||
return -1; // nie znaleziono stycznego wierzchołka
|
return -1; // nie znaleziono stycznego wierzchołka
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,10 +200,12 @@ inline void readMatrix(cParser &parser, float4x4 &matrix)
|
|||||||
parser >> matrix(x)[y];
|
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
|
{ // Ra: VBO tworzone na poziomie modelu, a nie submodeli
|
||||||
iNumVerts = 0;
|
iNumVerts = 0;
|
||||||
|
/*
|
||||||
iVboPtr = Pos; // pozycja w VBO
|
iVboPtr = Pos; // pozycja w VBO
|
||||||
|
*/
|
||||||
if (!parser.expectToken("type:"))
|
if (!parser.expectToken("type:"))
|
||||||
Error("Model type parse failure!");
|
Error("Model type parse failure!");
|
||||||
{
|
{
|
||||||
@@ -329,13 +334,18 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic)
|
|||||||
{
|
{
|
||||||
std::string discard;
|
std::string discard;
|
||||||
parser.getTokens(5, false);
|
parser.getTokens(5, false);
|
||||||
parser >> discard >> bWire >> discard >> fWireSize >> discard;
|
parser
|
||||||
Opacity = readIntAsDouble(parser,
|
>> discard >> bWire
|
||||||
100.0f); // wymagane jest 0 dla szyb, 100 idzie w nieprzezroczyste
|
>> discard >> fWireSize
|
||||||
|
>> discard;
|
||||||
|
// wymagane jest 0 dla szyb, 100 idzie w nieprzezroczyste
|
||||||
|
Opacity = readIntAsDouble(parser, 100.0f);
|
||||||
if (Opacity > 1.0f)
|
if (Opacity > 1.0f)
|
||||||
Opacity *= 0.01f; // w 2013 był błąd i aby go obejść, trzeba było wpisać 10000.0
|
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
|
if ((Global::iConvertModels & 1) == 0) // dla zgodności wstecz
|
||||||
Opacity = 0.0; // wszystko idzie w przezroczyste albo zależnie od tekstury
|
Opacity = 0.0; // wszystko idzie w przezroczyste albo zależnie od tekstury
|
||||||
|
*/
|
||||||
if (!parser.expectToken("map:"))
|
if (!parser.expectToken("map:"))
|
||||||
Error("Model map parse failure!");
|
Error("Model map parse failure!");
|
||||||
std::string texture = parser.getToken<std::string>();
|
std::string texture = parser.getToken<std::string>();
|
||||||
@@ -371,20 +381,19 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // jeśli tylko nazwa pliku, to dawać bieżącą ścieżkę do tekstur
|
{ // 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());
|
TextureNameSet(texture.c_str());
|
||||||
if (texture.find_first_of("/\\") == texture.npos)
|
if( texture.find_first_of( "/\\" ) == texture.npos ) {
|
||||||
texture.insert(0, Global::asCurrentTexturePath.c_str());
|
texture.insert( 0, Global::asCurrentTexturePath.c_str() );
|
||||||
|
}
|
||||||
TextureID = GfxRenderer.GetTextureId( texture, szTexturePath );
|
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:
|
// renderowanie w cyklu przezroczystych tylko jeśli:
|
||||||
// 1. Opacity=0 (przejściowo <1, czy tam <100) oraz
|
// 1. Opacity=0 (przejściowo <1, czy tam <100) oraz
|
||||||
// 2. tekstura ma przezroczystość
|
// 2. tekstura ma przezroczystość
|
||||||
|
iFlags |=
|
||||||
|
( ( ( Opacity < 1.0 )
|
||||||
|
&& ( GfxRenderer.Texture(TextureID).has_alpha ) ) ?
|
||||||
|
0x20 :
|
||||||
|
0x10 ); // 0x10-nieprzezroczysta, 0x20-przezroczysta
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -407,8 +416,6 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic)
|
|||||||
readMatrix(parser, *fMatrix); // wczytanie transform
|
readMatrix(parser, *fMatrix); // wczytanie transform
|
||||||
if (!fMatrix->IdentityIs())
|
if (!fMatrix->IdentityIs())
|
||||||
iFlags |= 0x8000; // transform niejedynkowy - trzeba go przechować
|
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)
|
if (eType < TP_ROTATOR)
|
||||||
{ // wczytywanie wierzchołków
|
{ // wczytywanie wierzchołków
|
||||||
parser.getTokens(2, false);
|
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ć
|
{ // jeśli pierwszy znak jest gwiazdką, poszukać
|
||||||
// submodelu o nazwie bez tej gwiazdki i wziąć z
|
// submodelu o nazwie bez tej gwiazdki i wziąć z
|
||||||
// niego wierzchołki
|
// niego wierzchołki
|
||||||
Error("Verticles reference not yet supported!");
|
Error("Vertices reference not yet supported!");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // normalna lista wierzchołków
|
{ // normalna lista wierzchołków
|
||||||
iNumVerts = atoi(token.c_str());
|
iNumVerts = std::atoi(token.c_str());
|
||||||
if (iNumVerts % 3)
|
if (iNumVerts % 3)
|
||||||
{
|
{
|
||||||
iNumVerts = 0;
|
iNumVerts = 0;
|
||||||
@@ -435,27 +442,31 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// Vertices=new GLVERTEX[iNumVerts];
|
// Vertices=new GLVERTEX[iNumVerts];
|
||||||
if (iNumVerts)
|
if (iNumVerts) {
|
||||||
{
|
/*
|
||||||
Vertices = new basic_vertex[iNumVerts];
|
Vertices = new basic_vertex[iNumVerts];
|
||||||
iNumFaces = iNumVerts / 3;
|
*/
|
||||||
sg = new unsigned int[iNumFaces]; // maski powierzchni: 0 oznacza brak
|
Vertices.resize( iNumVerts );
|
||||||
// użredniania wektorów normalnych
|
int facecount = iNumVerts / 3;
|
||||||
int *wsp = new int[iNumVerts]; // z którego wierzchołka kopiować wektor
|
/*
|
||||||
// normalny
|
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;
|
int maska = 0;
|
||||||
for (int i = 0; i < iNumVerts; i++)
|
for (int i = 0; i < iNumVerts; ++i) {
|
||||||
{ // Ra: z konwersją na układ scenerii - będzie wydajniejsze
|
// Ra: z konwersją na układ scenerii - będzie wydajniejsze wyświetlanie
|
||||||
// wyświetlanie
|
|
||||||
wsp[i] = -1; // wektory normalne nie są policzone dla tego wierzchołka
|
wsp[i] = -1; // wektory normalne nie są policzone dla tego wierzchołka
|
||||||
if ((i % 3) == 0)
|
if ((i % 3) == 0) {
|
||||||
{ // jeśli będzie maska -1, to dalej będą
|
// jeśli będzie maska -1, to dalej będą wierzchołki z wektorami normalnymi, podanymi jawnie
|
||||||
// wierzchołki z wektorami normalnymi, podanymi
|
|
||||||
// jawnie
|
|
||||||
maska = parser.getToken<int>(false); // maska powierzchni trójkąta
|
maska = parser.getToken<int>(false); // maska powierzchni trójkąta
|
||||||
sg[i / 3] = (maska == -1) ? 0 : maska; // dla maski -1 będzie 0,
|
// dla maski -1 będzie 0, czyli nie ma wspólnych wektorów normalnych
|
||||||
// czyli nie ma wspólnych
|
sg[i / 3] = (
|
||||||
// wektorów normalnych
|
( maska == -1 ) ?
|
||||||
|
0 :
|
||||||
|
maska );
|
||||||
}
|
}
|
||||||
parser.getTokens(3, false);
|
parser.getTokens(3, false);
|
||||||
parser
|
parser
|
||||||
@@ -475,80 +486,77 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic)
|
|||||||
parser
|
parser
|
||||||
>> Vertices[i].texture.s
|
>> Vertices[i].texture.s
|
||||||
>> Vertices[i].texture.t;
|
>> Vertices[i].texture.t;
|
||||||
if (i % 3 == 2) // jeżeli wczytano 3 punkty
|
if (i % 3 == 2) {
|
||||||
{
|
// jeżeli wczytano 3 punkty
|
||||||
if (Vertices[i].position == Vertices[i - 1].position
|
if (Vertices[i ].position == Vertices[i - 1].position
|
||||||
|| Vertices[i - 1].position == Vertices[i - 2].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
|
{ // 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
|
iNumVerts -= 3; // czyli o 3 wierzchołki
|
||||||
i -= 3; // wczytanie kolejnego w to miejsce
|
i -= 3; // wczytanie kolejnego w to miejsce
|
||||||
WriteLog(std::string("Degenerated triangle ignored in: \"") + pName +
|
WriteLog("Degenerated triangle ignored in: \"" + pName + "\", verticle " + std::to_string(i));
|
||||||
"\", verticle " + std::to_string(i));
|
|
||||||
}
|
}
|
||||||
if (i > 0) // jeśli pierwszy trójkąt będzie zdegenerowany, to
|
if (i > 0) {
|
||||||
// zostanie usunięty i nie ma co sprawdzać
|
// 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)
|
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 - 1].position - Vertices[i - 2].position) > 1000.0)
|
||||||
|| (glm::length(Vertices[i - 2].position - Vertices[i].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:
|
// jeżeli są dalej niż 2km od siebie //Ra 15-01:
|
||||||
// obiekt wstawiany nie powinien być większy niż
|
// obiekt wstawiany nie powinien być większy niż 300m (trójkąty terenu w E3D mogą mieć 1.5km)
|
||||||
// 300m (trójkąty terenu w E3D mogą mieć 1.5km)
|
--facecount; // o jeden trójkąt mniej
|
||||||
--iNumFaces; // o jeden trójkąt mniej
|
|
||||||
iNumVerts -= 3; // czyli o 3 wierzchołki
|
iNumVerts -= 3; // czyli o 3 wierzchołki
|
||||||
i -= 3; // wczytanie kolejnego w to miejsce
|
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
|
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
|
std::vector<glm::vec3> facenormals;
|
||||||
// normalne trójkątów
|
for( int i = 0; i < facecount; ++i ) {
|
||||||
n[i] = glm::normalize(
|
// pętla po trójkątach - będzie szybciej, jak wstępnie przeliczymy normalne trójkątów
|
||||||
glm::cross(
|
facenormals.emplace_back(
|
||||||
Vertices[i * 3].position - Vertices[i * 3 + 1].position,
|
glm::normalize(
|
||||||
Vertices[i * 3].position - Vertices[i * 3 + 2].position));
|
glm::cross(
|
||||||
int v; // indeks dla wierzchołków
|
Vertices[ i * 3 ].position - Vertices[ i * 3 + 1 ].position,
|
||||||
int f; // numer trójkąta stycznego
|
Vertices[ i * 3 ].position - Vertices[ i * 3 + 2 ].position ) ) );
|
||||||
glm::vec3 norm; // roboczy wektor normalny
|
}
|
||||||
for (v = 0; v < iNumVerts; ++v)
|
glm::vec3 vertexnormal; // roboczy wektor normalny
|
||||||
{ // pętla po wierzchołkach trójkątów
|
for (int vertexidx = 0; vertexidx < iNumVerts; ++vertexidx) {
|
||||||
if (wsp[v] >= 0) // jeśli już był liczony wektor normalny z użyciem
|
// pętla po wierzchołkach trójkątów
|
||||||
// tego wierzchołka
|
if( wsp[ vertexidx ] >= 0 ) {
|
||||||
Vertices[v].normal =
|
// jeśli już był liczony wektor normalny z użyciem tego wierzchołka to wystarczy skopiować policzony wcześniej
|
||||||
Vertices[wsp[v]].normal; // to wystarczy skopiować policzony wcześniej
|
Vertices[ vertexidx ].normal = Vertices[ wsp[ vertexidx ] ].normal;
|
||||||
else
|
}
|
||||||
{ // inaczej musimy dopiero policzyć
|
else {
|
||||||
i = v / 3; // numer trójkąta
|
// inaczej musimy dopiero policzyć
|
||||||
norm = glm::vec3(); // liczenie zaczynamy od zera
|
auto const faceidx = vertexidx / 3; // numer trójkąta
|
||||||
f = v; // zaczynamy dodawanie wektorów normalnych od własnego
|
vertexnormal = glm::vec3(); // liczenie zaczynamy od zera
|
||||||
while (f >= 0)
|
auto adjacenvertextidx = vertexidx; // zaczynamy dodawanie wektorów normalnych od własnego
|
||||||
{ // sumowanie z wektorem normalnym sąsiada (włącznie
|
while (adjacenvertextidx >= 0) {
|
||||||
// ze sobą)
|
// sumowanie z wektorem normalnym sąsiada (włącznie ze sobą)
|
||||||
wsp[f] = v; // informacja, że w tym wierzchołku jest już policzony
|
wsp[adjacenvertextidx] = vertexidx; // informacja, że w tym wierzchołku jest już policzony wektor normalny
|
||||||
// wektor normalny
|
vertexnormal += facenormals[adjacenvertextidx / 3];
|
||||||
norm += n[f / 3];
|
// i szukanie od kolejnego trójkąta
|
||||||
f = SeekFaceNormal(sg, f / 3 + 1, sg[i], &Vertices[v].position,
|
adjacenvertextidx = SeekFaceNormal(sg, adjacenvertextidx / 3 + 1, sg[faceidx], Vertices[vertexidx].position, Vertices);
|
||||||
Vertices); // i szukanie od kolejnego trójkąta
|
|
||||||
}
|
}
|
||||||
// Ra 15-01: należało by jeszcze uwzględnić skalowanie wprowadzane
|
// Ra 15-01: należało by jeszcze uwzględnić skalowanie wprowadzane przez transformy, aby normalne po przeskalowaniu były jednostkowe
|
||||||
// przez transformy, aby normalne po przeskalowaniu były jednostkowe
|
Vertices[vertexidx].normal = glm::normalize(vertexnormal); // przepisanie do wierzchołka trójkąta
|
||||||
Vertices[v].normal =
|
|
||||||
glm::normalize(norm); // przepisanie do wierzchołka trójkąta
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
delete[] wsp;
|
delete[] wsp;
|
||||||
delete[] n;
|
delete[] n;
|
||||||
delete[] sg;
|
delete[] sg;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
else // gdy brak wierzchołków
|
else // gdy brak wierzchołków
|
||||||
{
|
{
|
||||||
eType = TP_ROTATOR; // submodel pomocniczy, ma tylko macierz przekształcenia
|
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
|
} // 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;
|
std::string discard;
|
||||||
parser.getTokens(2, false);
|
parser.getTokens(2, false);
|
||||||
parser >> discard >> iNumVerts;
|
parser >> discard >> iNumVerts;
|
||||||
|
/*
|
||||||
// Vertices=new GLVERTEX[iNumVerts];
|
// Vertices=new GLVERTEX[iNumVerts];
|
||||||
Vertices = new basic_vertex[iNumVerts];
|
Vertices = new basic_vertex[iNumVerts];
|
||||||
int i, j;
|
*/
|
||||||
|
Vertices.resize( iNumVerts );
|
||||||
|
int i;
|
||||||
|
unsigned int color;
|
||||||
for (i = 0; i < iNumVerts; ++i)
|
for (i = 0; i < iNumVerts; ++i)
|
||||||
{
|
{
|
||||||
if (i % 3 == 0)
|
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.x
|
||||||
>> Vertices[i].position.y
|
>> Vertices[i].position.y
|
||||||
>> Vertices[i].position.z
|
>> Vertices[i].position.z
|
||||||
>> j // zakodowany kolor
|
>> color // zakodowany kolor
|
||||||
>> discard;
|
>> discard;
|
||||||
Vertices[i].normal.x = ((j) & 0xFF) / 255.0; // R
|
Vertices[i].normal.x = ((color) & 0xff) / 255.0f; // R
|
||||||
Vertices[i].normal.y = ((j >> 8) & 0xFF) / 255.0; // G
|
Vertices[i].normal.y = ((color >> 8) & 0xff) / 255.0f; // G
|
||||||
Vertices[i].normal.z = ((j >> 16) & 0xFF) / 255.0; // B
|
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
|
// Visible=true; //się potem wyłączy w razie potrzeby
|
||||||
// iFlags|=0x0200; //wczytano z pliku tekstowego (jest właścicielem tablic)
|
// iFlags|=0x0200; //wczytano z pliku tekstowego (jest właścicielem tablic)
|
||||||
if (iNumVerts < 1)
|
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
|
s->iNumVerts += tri; // aktualizacja ilości wierzchołków
|
||||||
return s->iNumVerts - tri; // zwraca pozycję tych trójkątów w submodelu
|
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 )
|
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
|
{ // zwraca wskaźnik do wypełnienia tabeli wierzchołków, używane przy tworzeniu E3D terenu
|
||||||
|
|
||||||
TSubModel *s = this;
|
TSubModel *s = this;
|
||||||
while (s ? s->TextureID != tex : false)
|
while (s ? s->TextureID != tex : false)
|
||||||
{ // szukanie submodelu o danej teksturze
|
{ // 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ł
|
s->ColorsSet(Ambient, Diffuse, Specular); // ustawienie kolorów świateł
|
||||||
return s->Vertices + pos; // wskaźnik na wolne miejsce w tabeli wierzchołków
|
return s->Vertices + pos; // wskaźnik na wolne miejsce w tabeli wierzchołków
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
#ifdef EU07_USE_OLD_RENDERCODE
|
#ifdef EU07_USE_OLD_RENDERCODE
|
||||||
void TSubModel::DisplayLists()
|
void TSubModel::DisplayLists()
|
||||||
{ // utworznie po jednej skompilowanej liście dla
|
{ // 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ą
|
{ // konwersja układu współrzędnych na zgodny ze scenerią
|
||||||
if (iFlags & 0xC000) // jeśli jest animacja albo niejednostkowy transform
|
if (iFlags & 0xC000) // jeśli jest animacja albo niejednostkowy transform
|
||||||
{ // niejednostkowy transform jest mnożony i wystarczy zabawy
|
{ // niejednostkowy transform jest mnożony i wystarczy zabawy
|
||||||
if (doit)
|
if (doit) {
|
||||||
{ // obrót lewostronny
|
// obrót lewostronny
|
||||||
if (!fMatrix) // macierzy może nie być w dodanym "bananie"
|
if (!fMatrix) {
|
||||||
{
|
// macierzy może nie być w dodanym "bananie"
|
||||||
fMatrix = new float4x4(); // tworzy macierz o przypadkowej zawartości
|
fMatrix = new float4x4(); // tworzy macierz o przypadkowej zawartości
|
||||||
fMatrix->Identity(); // a zaczynamy obracanie od jednostkowej
|
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ć
|
{ // jak nie ma potomnych, można wymnożyć przez transform i wyjedynkować
|
||||||
// go
|
// go
|
||||||
float4x4 *mat = GetMatrix(); // transform submodelu
|
float4x4 *mat = GetMatrix(); // transform submodelu
|
||||||
if (Vertices)
|
if( false == Vertices.empty() ) {
|
||||||
{
|
for( auto &vertex : Vertices ) {
|
||||||
for (int i = 0; i < iNumVerts; ++i)
|
vertex.position = (*mat) * vertex.position;
|
||||||
Vertices[i].position = (*mat) * Vertices[i].position;
|
}
|
||||||
(*mat)(3)[0] = (*mat)(3)[1] = (*mat)(3)[2] =
|
// zerujemy przesunięcie przed obracaniem normalnych
|
||||||
0.0; // 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
|
if( eType != TP_STARS ) {
|
||||||
// ich wtedy nie ruszamy
|
// gwiazdki mają kolory zamiast normalnych, to ich wtedy nie ruszamy
|
||||||
for (int i = 0; i < iNumVerts; ++i)
|
for( auto &vertex : Vertices ) {
|
||||||
Vertices[i].normal = glm::normalize((*mat) * Vertices[i].normal);
|
vertex.normal = glm::normalize( ( *mat ) * vertex.normal );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mat->Identity(); // jedynkowanie transformu po przeliczeniu wierzchołków
|
mat->Identity(); // jedynkowanie transformu po przeliczeniu wierzchołków
|
||||||
iFlags &= ~0x8000; // transform jedynkowy
|
iFlags &= ~0x8000; // transform jedynkowy
|
||||||
@@ -748,23 +767,26 @@ void TSubModel::InitialRotate(bool doit)
|
|||||||
if (doit)
|
if (doit)
|
||||||
{ // jeśli jest jednostkowy transform, to przeliczamy
|
{ // jeśli jest jednostkowy transform, to przeliczamy
|
||||||
// wierzchołki, a mnożenie podajemy dalej
|
// wierzchołki, a mnożenie podajemy dalej
|
||||||
double t;
|
float swapcopy;
|
||||||
if (Vertices)
|
// if( false == Vertices.empty() ) {
|
||||||
for (int i = 0; i < iNumVerts; ++i)
|
/*
|
||||||
{
|
for( auto &vertex : Vertices ) {
|
||||||
Vertices[i].position.x = -Vertices[i].position.x; // zmiana znaku X
|
*/
|
||||||
t = Vertices[i].position.y; // zamiana Y i Z
|
for( int idx = 0; idx < iNumVerts; ++idx ) {
|
||||||
Vertices[i].position.y = Vertices[i].position.z;
|
Vertices[idx].position.x = -Vertices[idx].position.x; // zmiana znaku X
|
||||||
Vertices[i].position.z = t;
|
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ą
|
// 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[ i ].normal.x = -Vertices[ i ].normal.x; // zmiana znaku X
|
Vertices[idx].normal.x = -Vertices[idx].normal.x; // zmiana znaku X
|
||||||
t = Vertices[ i ].normal.y; // zamiana Y i Z
|
swapcopy = Vertices[idx].normal.y; // zamiana Y i Z
|
||||||
Vertices[ i ].normal.y = Vertices[ i ].normal.z;
|
Vertices[idx].normal.y = Vertices[idx].normal.z;
|
||||||
Vertices[ i ].normal.z = t;
|
Vertices[idx].normal.z = swapcopy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// }
|
||||||
if (Child)
|
if (Child)
|
||||||
Child->InitialRotate(doit); // potomne ewentualnie obrócimy
|
Child->InitialRotate(doit); // potomne ewentualnie obrócimy
|
||||||
}
|
}
|
||||||
@@ -1028,7 +1050,7 @@ void TSubModel::RaAnimation(TAnimType a)
|
|||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
void TSubModel::RaArrayFill(basic_vertex *Vert)
|
void TSubModel::RaArrayFill(basic_vertex *Vert)
|
||||||
{ // wypełnianie tablic VBO
|
{ // wypełnianie tablic VBO
|
||||||
if (Child)
|
if (Child)
|
||||||
@@ -1038,22 +1060,31 @@ void TSubModel::RaArrayFill(basic_vertex *Vert)
|
|||||||
Vert[ iVboPtr + i ].position = Vertices[ i ].position;
|
Vert[ iVboPtr + i ].position = Vertices[ i ].position;
|
||||||
Vert[ iVboPtr + i ].normal = Vertices[ i ].normal;
|
Vert[ iVboPtr + i ].normal = Vertices[ i ].normal;
|
||||||
Vert[ iVboPtr + i ].texture = Vertices[ i ].texture;
|
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 )
|
else if( eType == TP_FREESPOTLIGHT )
|
||||||
Vert[ iVboPtr ].position = glm::vec3();
|
Vert[ iVboPtr ].position = glm::vec3();
|
||||||
if (Next)
|
if (Next)
|
||||||
Next->RaArrayFill(Vert);
|
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.
|
// NOTE: leftover from static distance factor adjustment.
|
||||||
// TODO: get rid of it, once we have the dynamic adjustment code in place
|
// 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, 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, (int)iVboPtr);
|
||||||
|
*/
|
||||||
if (TextureID <= 0)
|
if (TextureID <= 0)
|
||||||
sn_utils::ls_int32(s, TextureID);
|
sn_utils::ls_int32(s, TextureID);
|
||||||
else
|
else
|
||||||
@@ -1324,7 +1356,7 @@ void TSubModel::serialize(std::ostream &s,
|
|||||||
s.put(0);
|
s.put(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TModel3d::SaveToBinFile(char const *FileName)
|
void TModel3d::SaveToBinFile(std::string const &FileName)
|
||||||
{
|
{
|
||||||
// TODO: re-implement!
|
// TODO: re-implement!
|
||||||
return;
|
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)
|
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);
|
||||||
|
/*
|
||||||
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;
|
||||||
@@ -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)
|
iFlags &= ~0x0200; // wczytano z pliku binarnego (nie jest właścicielem tablic)
|
||||||
|
/*
|
||||||
iVboPtr = tVboPtr;
|
iVboPtr = tVboPtr;
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
void TModel3d::LoadFromBinFile(std::string const &FileName, bool dynamic)
|
void TModel3d::LoadFromBinFile(std::string const &FileName, bool dynamic)
|
||||||
@@ -1702,7 +1737,7 @@ void TModel3d::LoadFromTextFile(std::string const &FileName, bool dynamic)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
SubModel = new TSubModel();
|
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
|
// będzie potrzebne do wyliczenia pozycji, np. pantografu
|
||||||
SubModel->Parent = AddToNamed(parent.c_str(), SubModel);
|
SubModel->Parent = AddToNamed(parent.c_str(), SubModel);
|
||||||
@@ -1752,37 +1787,15 @@ void TModel3d::Init()
|
|||||||
if (false == asBinary.empty()) // jeśli jest podana nazwa
|
if (false == asBinary.empty()) // jeśli jest podana nazwa
|
||||||
{
|
{
|
||||||
if (Global::iConvertModels) // i włączony zapis
|
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
|
asBinary = ""; // zablokowanie powtórnego zapisu
|
||||||
}
|
}
|
||||||
#ifdef EU07_USE_OLD_DRAW_CODE
|
if (iNumVerts) {
|
||||||
if (iNumVerts)
|
if( m_geometrybank == NULL ) {
|
||||||
{
|
m_geometrybank = GfxRenderer.Create_Bank();
|
||||||
if (Global::bUseVBO)
|
}
|
||||||
{
|
Root->create_geometry( m_geometrybank );
|
||||||
#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
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
19
Model3d.h
19
Model3d.h
@@ -112,12 +112,15 @@ private:
|
|||||||
|
|
||||||
TSubModel *Next;
|
TSubModel *Next;
|
||||||
TSubModel *Child;
|
TSubModel *Child;
|
||||||
|
/*
|
||||||
intptr_t iVboPtr;
|
intptr_t iVboPtr;
|
||||||
|
*/
|
||||||
geometry_handle m_geometry; // geometry of the submodel
|
geometry_handle m_geometry; // geometry of the submodel
|
||||||
texture_handle TextureID; // numer tekstury, -1 wymienna, 0 brak
|
texture_handle TextureID; // numer tekstury, -1 wymienna, 0 brak
|
||||||
bool bWire; // nie używane, ale wczytywane
|
bool bWire; // nie używane, ale wczytywane
|
||||||
// short TexAlpha; //Ra: nie używane już
|
/*
|
||||||
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; // nie używane, ale wczytywane //m7todo: wywalić to
|
||||||
float f_Angle;
|
float f_Angle;
|
||||||
float3 v_RotateAxis;
|
float3 v_RotateAxis;
|
||||||
@@ -125,7 +128,10 @@ private:
|
|||||||
|
|
||||||
public: // chwilowo
|
public: // chwilowo
|
||||||
float3 v_TransVector;
|
float3 v_TransVector;
|
||||||
|
/*
|
||||||
basic_vertex *Vertices; // roboczy wskaźnik - wczytanie T3D do VBO
|
basic_vertex *Vertices; // roboczy wskaźnik - wczytanie T3D do VBO
|
||||||
|
*/
|
||||||
|
vertex_array Vertices;
|
||||||
size_t iAnimOwner; // roboczy numer egzemplarza, który ustawił animację
|
size_t iAnimOwner; // roboczy numer egzemplarza, który ustawił animację
|
||||||
TAnimType b_aAnim; // kody animacji oddzielnie, bo zerowane
|
TAnimType b_aAnim; // kody animacji oddzielnie, bo zerowane
|
||||||
public:
|
public:
|
||||||
@@ -138,7 +144,7 @@ public:
|
|||||||
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:
|
||||||
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);
|
void RaAnimation(TAnimType a);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -151,13 +157,15 @@ public:
|
|||||||
TSubModel();
|
TSubModel();
|
||||||
~TSubModel();
|
~TSubModel();
|
||||||
void FirstInit();
|
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);
|
||||||
TSubModel * NextGet() { return Next; };
|
TSubModel * NextGet() { return Next; };
|
||||||
TSubModel * ChildGet() { return Child; };
|
TSubModel * ChildGet() { return Child; };
|
||||||
int TriangleAdd(TModel3d *m, texture_handle tex, int tri);
|
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 );
|
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 SetRotate(float3 vNewRotateAxis, float fNewAngle);
|
||||||
void SetRotateXYZ(vector3 vNewAngles);
|
void SetRotateXYZ(vector3 vNewAngles);
|
||||||
void SetRotateXYZ(float3 vNewAngles);
|
void SetRotateXYZ(float3 vNewAngles);
|
||||||
@@ -168,7 +176,10 @@ 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 RaArrayFill(basic_vertex *Vert);
|
||||||
|
*/
|
||||||
|
void create_geometry( geometrybank_handle const &Bank );
|
||||||
int FlagsCheck();
|
int FlagsCheck();
|
||||||
void WillBeAnimated()
|
void WillBeAnimated()
|
||||||
{
|
{
|
||||||
@@ -241,7 +252,7 @@ public:
|
|||||||
void LoadFromTextFile(std::string const &FileName, bool dynamic);
|
void LoadFromTextFile(std::string const &FileName, bool dynamic);
|
||||||
void LoadFromBinFile(std::string const &FileName, bool dynamic);
|
void LoadFromBinFile(std::string const &FileName, bool dynamic);
|
||||||
bool LoadFromFile(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();
|
void BreakHierarhy();
|
||||||
int Flags() const { return iFlags; };
|
int Flags() const { return iFlags; };
|
||||||
void Init();
|
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();
|
texture_manager::texture( textureindex ).load();
|
||||||
#ifndef EU07_DEFERRED_TEXTURE_UPLOAD
|
#ifndef EU07_DEFERRED_TEXTURE_UPLOAD
|
||||||
texture_manager::texture( textureindex ).create();
|
texture_manager::texture( textureindex ).create();
|
||||||
|
// texture creation binds a different texture, force a re-bind on next use
|
||||||
|
m_activetexture = 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -803,16 +805,11 @@ texture_manager::create( std::string Filename, std::string const &Dir, int const
|
|||||||
|
|
||||||
void
|
void
|
||||||
texture_manager::bind( texture_handle const Texture ) {
|
texture_manager::bind( texture_handle const Texture ) {
|
||||||
/*
|
|
||||||
// NOTE: this optimization disabled for the time being, until the render code is reviewed
|
if( Texture == m_activetexture ) {
|
||||||
// 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 ) {
|
|
||||||
// don't bind again what's already active
|
// don't bind again what's already active
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
// TODO: do binding in texture object, add support for other types
|
// TODO: do binding in texture object, add support for other types
|
||||||
if( Texture != 0 ) {
|
if( Texture != 0 ) {
|
||||||
#ifndef EU07_DEFERRED_TEXTURE_UPLOAD
|
#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
|
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
|
// wypełnianie tablic VBO
|
||||||
void TTrack::create_geometry( geometrybank_handle const &Bank ) {
|
void TTrack::create_geometry( geometrybank_handle const &Bank ) {
|
||||||
// Ra: trzeba rozdzielić szyny od podsypki, aby móc grupować wg tekstur
|
// 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;
|
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()
|
void TTrack::EnvironmentSet()
|
||||||
{ // ustawienie zmienionego światła
|
{ // ustawienie zmienionego światła
|
||||||
glColor3f(1.0f, 1.0f, 1.0f); // Ra: potrzebne to?
|
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
|
// creates a new geometry chunk of specified type from supplied vertex data. returns: handle to the chunk
|
||||||
geometry_handle
|
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 ); }
|
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
|
// 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()) };
|
geometry_handle chunkhandle { 0, static_cast<std::uint32_t>(m_chunks.size()) };
|
||||||
// template method
|
// template method
|
||||||
@@ -98,9 +98,9 @@ geometry_bank::append( vertex_array &Vertices, geometry_handle const &Geometry )
|
|||||||
|
|
||||||
// draws geometry stored in specified chunk
|
// draws geometry stored in specified chunk
|
||||||
void
|
void
|
||||||
geometry_bank::draw( geometry_handle const &Geometry ) {
|
geometry_bank::draw( geometry_handle const &Geometry, unsigned int const Streams ) {
|
||||||
// template method
|
// template method
|
||||||
draw_( Geometry );
|
draw_( Geometry, Streams );
|
||||||
}
|
}
|
||||||
|
|
||||||
vertex_array const &
|
vertex_array const &
|
||||||
@@ -111,7 +111,8 @@ geometry_bank::vertices( geometry_handle const &Geometry ) const {
|
|||||||
|
|
||||||
// opengl vbo-based variant of the geometry bank
|
// 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
|
// create() subclass details
|
||||||
void
|
void
|
||||||
@@ -140,7 +141,7 @@ opengl_vbogeometrybank::replace_( geometry_handle const &Geometry ) {
|
|||||||
|
|
||||||
// draw() subclass details
|
// draw() subclass details
|
||||||
void
|
void
|
||||||
opengl_vbogeometrybank::draw_( geometry_handle const &Geometry ) {
|
opengl_vbogeometrybank::draw_( geometry_handle const &Geometry, unsigned int const Streams ) {
|
||||||
|
|
||||||
if( m_buffer == NULL ) {
|
if( m_buffer == NULL ) {
|
||||||
// if there's no buffer, we'll have to make one
|
// 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();
|
auto chunkiterator = m_chunks.cbegin();
|
||||||
for( auto &chunkrecord : m_chunkrecords ) {
|
for( auto &chunkrecord : m_chunkrecords ) {
|
||||||
// fill records for all chunks, based on the chunk data
|
// 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.offset = datasize;
|
||||||
chunkrecord.size = chunkiterator->vertices.size();
|
chunkrecord.size = chunkiterator->vertices.size();
|
||||||
datasize += chunkrecord.size;
|
datasize += chunkrecord.size;
|
||||||
@@ -193,6 +195,9 @@ opengl_vbogeometrybank::draw_( geometry_handle const &Geometry ) {
|
|||||||
chunk.vertices.data() );
|
chunk.vertices.data() );
|
||||||
chunkrecord.is_good = true;
|
chunkrecord.is_good = true;
|
||||||
}
|
}
|
||||||
|
if( m_activestreams != Streams ) {
|
||||||
|
bind_streams( Streams );
|
||||||
|
}
|
||||||
// ...render...
|
// ...render...
|
||||||
::glDrawArrays( chunk.type, chunkrecord.offset, chunkrecord.size );
|
::glDrawArrays( chunk.type, chunkrecord.offset, chunkrecord.size );
|
||||||
// ...post-render cleanup
|
// ...post-render cleanup
|
||||||
@@ -208,16 +213,8 @@ void
|
|||||||
opengl_vbogeometrybank::bind_buffer() {
|
opengl_vbogeometrybank::bind_buffer() {
|
||||||
|
|
||||||
::glBindBuffer( GL_ARRAY_BUFFER, m_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_activebuffer = m_buffer;
|
||||||
|
m_activestreams = stream::none;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -231,9 +228,47 @@ opengl_vbogeometrybank::delete_buffer() {
|
|||||||
}
|
}
|
||||||
m_buffer = NULL;
|
m_buffer = NULL;
|
||||||
m_buffercapacity = 0;
|
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
|
// opengl display list based variant of the geometry bank
|
||||||
|
|
||||||
// create() subclass details
|
// create() subclass details
|
||||||
@@ -252,21 +287,25 @@ opengl_dlgeometrybank::replace_( geometry_handle const &Geometry ) {
|
|||||||
|
|
||||||
// draw() subclass details
|
// draw() subclass details
|
||||||
void
|
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 ];
|
auto &chunkrecord = m_chunkrecords[ Geometry.chunk - 1 ];
|
||||||
|
if( chunkrecord.streams != Streams ) {
|
||||||
|
delete_list( Geometry );
|
||||||
|
}
|
||||||
if( chunkrecord.list == 0 ) {
|
if( chunkrecord.list == 0 ) {
|
||||||
// we don't have a list ready, so compile one
|
// we don't have a list ready, so compile one
|
||||||
|
chunkrecord.streams = Streams;
|
||||||
chunkrecord.list = ::glGenLists( 1 );
|
chunkrecord.list = ::glGenLists( 1 );
|
||||||
auto const &chunk = geometry_bank::chunk( Geometry );
|
auto const &chunk = geometry_bank::chunk( Geometry );
|
||||||
::glNewList( chunkrecord.list, GL_COMPILE );
|
::glNewList( chunkrecord.list, GL_COMPILE );
|
||||||
|
|
||||||
::glBegin( chunk.type );
|
::glBegin( chunk.type );
|
||||||
// TODO: add specification of chunk vertex attributes
|
|
||||||
for( auto const &vertex : chunk.vertices ) {
|
for( auto const &vertex : chunk.vertices ) {
|
||||||
::glNormal3fv( glm::value_ptr( vertex.normal ) );
|
if( Streams & stream::normal ) { ::glNormal3fv( glm::value_ptr( vertex.normal ) ); }
|
||||||
::glTexCoord2fv( glm::value_ptr( vertex.texture ) );
|
else if( Streams & stream::color ) { ::glColor3fv( glm::value_ptr( vertex.normal ) ); }
|
||||||
::glVertex3fv( glm::value_ptr( vertex.position ) );
|
if( Streams & stream::texture ) { ::glTexCoord2fv( glm::value_ptr( vertex.texture ) ); }
|
||||||
|
if( Streams & stream::position ) { ::glVertex3fv( glm::value_ptr( vertex.position ) ); }
|
||||||
}
|
}
|
||||||
::glEnd();
|
::glEnd();
|
||||||
::glEndList();
|
::glEndList();
|
||||||
@@ -279,8 +318,11 @@ void
|
|||||||
opengl_dlgeometrybank::delete_list( geometry_handle const &Geometry ) {
|
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
|
// NOTE: given it's our own internal method we trust it to be called with valid parameters
|
||||||
auto &chunkrecord = m_chunkrecords[ Geometry.chunk - 1 ];
|
auto &chunkrecord = m_chunkrecords[ Geometry.chunk - 1 ];
|
||||||
::glDeleteLists( chunkrecord.list, 1 );
|
if( chunkrecord.list != 0 ) {
|
||||||
chunkrecord.list = 0;
|
::glDeleteLists( chunkrecord.list, 1 );
|
||||||
|
chunkrecord.list = 0;
|
||||||
|
}
|
||||||
|
chunkrecord.streams = stream::none;
|
||||||
}
|
}
|
||||||
|
|
||||||
// geometry bank manager, holds collection of geometry banks
|
// 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
|
// draws geometry stored in specified chunk
|
||||||
void
|
void
|
||||||
geometrybank_manager::draw( geometry_handle const &Geometry ) {
|
geometrybank_manager::draw( geometry_handle const &Geometry, unsigned int const Streams ) {
|
||||||
|
|
||||||
if( Geometry == NULL ) { return; }
|
if( Geometry == NULL ) { return; }
|
||||||
|
|
||||||
return bank( Geometry )->draw( Geometry );
|
return bank( Geometry )->draw( Geometry, Streams );
|
||||||
}
|
}
|
||||||
|
|
||||||
// provides direct access to vertex data of specfied chunk
|
// provides direct access to vertex data of specfied chunk
|
||||||
|
|||||||
@@ -33,10 +33,11 @@ struct basic_vertex {
|
|||||||
|
|
||||||
// data streams carried in a vertex
|
// data streams carried in a vertex
|
||||||
enum stream {
|
enum stream {
|
||||||
|
none = 0x0,
|
||||||
position = 0x1,
|
position = 0x1,
|
||||||
normal = 0x2,
|
normal = 0x2,
|
||||||
color = 0x4, // currently normal and colour streams are stored in the same slot, and mutually exclusive
|
color = 0x4, // currently normal and colour streams are stored in the same slot, and mutually exclusive
|
||||||
texture = 0x8
|
texture = 0x8
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned int const basic_streams { stream::position | stream::normal | stream::texture };
|
unsigned int const basic_streams { stream::position | stream::normal | stream::texture };
|
||||||
@@ -87,7 +88,7 @@ public:
|
|||||||
// methods:
|
// methods:
|
||||||
// creates a new geometry chunk of specified type from supplied vertex data. returns: handle to the chunk or NULL
|
// creates a new geometry chunk of specified type from supplied vertex data. returns: handle to the chunk or NULL
|
||||||
geometry_handle
|
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
|
// replaces data of specified chunk with the supplied vertex data, starting from specified offset
|
||||||
bool
|
bool
|
||||||
replace( vertex_array &Vertices, geometry_handle const &Geometry, std::size_t const Offset = 0 );
|
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 );
|
append( vertex_array &Vertices, geometry_handle const &Geometry );
|
||||||
// draws geometry stored in specified chunk
|
// draws geometry stored in specified chunk
|
||||||
void
|
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
|
// draws geometry stored in supplied list of chunks
|
||||||
template <typename Iterator_>
|
template <typename Iterator_>
|
||||||
void
|
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
|
// provides direct access to vertex data of specfied chunk
|
||||||
vertex_array const &
|
vertex_array const &
|
||||||
vertices( geometry_handle const &Geometry ) const;
|
vertices( geometry_handle const &Geometry ) const;
|
||||||
@@ -108,12 +109,11 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
// types:
|
// types:
|
||||||
struct geometry_chunk {
|
struct geometry_chunk {
|
||||||
unsigned int streams; // data streams carried by vertices
|
|
||||||
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
|
||||||
|
|
||||||
geometry_chunk( vertex_array &Vertices, unsigned int const Type, unsigned int const Streams ) :
|
geometry_chunk( vertex_array &Vertices, unsigned int const Type ) :
|
||||||
vertices( Vertices ), type( Type ), streams( Streams )
|
vertices( Vertices ), type( Type )
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -139,7 +139,7 @@ private:
|
|||||||
// replace() subclass details
|
// replace() subclass details
|
||||||
virtual void replace_( geometry_handle const &Geometry ) = 0;
|
virtual void replace_( geometry_handle const &Geometry ) = 0;
|
||||||
// draw() subclass details
|
// 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
|
// opengl vbo-based variant of the geometry bank
|
||||||
@@ -154,7 +154,8 @@ public:
|
|||||||
static
|
static
|
||||||
void
|
void
|
||||||
reset() {
|
reset() {
|
||||||
m_activebuffer = 0; }
|
m_activebuffer = 0;
|
||||||
|
m_activestreams = stream::none; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// types:
|
// types:
|
||||||
@@ -175,15 +176,18 @@ private:
|
|||||||
replace_( geometry_handle const &Geometry );
|
replace_( geometry_handle const &Geometry );
|
||||||
// draw() subclass details
|
// draw() subclass details
|
||||||
void
|
void
|
||||||
draw_( geometry_handle const &Geometry );
|
draw_( geometry_handle const &Geometry, unsigned int const Streams );
|
||||||
void
|
void
|
||||||
bind_buffer();
|
bind_buffer();
|
||||||
void
|
void
|
||||||
delete_buffer();
|
delete_buffer();
|
||||||
|
void
|
||||||
|
bind_streams( unsigned int const Streams );
|
||||||
|
|
||||||
// members:
|
// members:
|
||||||
static GLuint m_activebuffer; // buffer bound currently on the opengl end, if any
|
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
|
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
|
chunkrecord_sequence m_chunkrecords; // helper data for all stored geometry chunks, in matching order
|
||||||
|
|
||||||
@@ -202,7 +206,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
// types:
|
// types:
|
||||||
struct chunk_record {
|
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;
|
typedef std::vector<chunk_record> chunkrecord_sequence;
|
||||||
@@ -216,7 +221,7 @@ private:
|
|||||||
replace_( geometry_handle const &Geometry );
|
replace_( geometry_handle const &Geometry );
|
||||||
// draw() subclass details
|
// draw() subclass details
|
||||||
void
|
void
|
||||||
draw_( geometry_handle const &Geometry );
|
draw_( geometry_handle const &Geometry, unsigned int const Streams );
|
||||||
void
|
void
|
||||||
delete_list( geometry_handle const &Geometry );
|
delete_list( geometry_handle const &Geometry );
|
||||||
|
|
||||||
@@ -247,12 +252,12 @@ public:
|
|||||||
append( vertex_array &Vertices, geometry_handle const &Geometry );
|
append( vertex_array &Vertices, geometry_handle const &Geometry );
|
||||||
// draws geometry stored in specified chunk
|
// draws geometry stored in specified chunk
|
||||||
void
|
void
|
||||||
draw( geometry_handle const &Geometry );
|
draw( geometry_handle const &Geometry, unsigned int const Streams = basic_streams );
|
||||||
template <typename Iterator_>
|
template <typename Iterator_>
|
||||||
void
|
void
|
||||||
draw( Iterator_ First, Iterator_ Last ) {
|
draw( Iterator_ First, Iterator_ Last, unsigned int const Streams = basic_streams ) {
|
||||||
while( First != Last ) {
|
while( First != Last ) {
|
||||||
draw( *First );
|
draw( *First, Streams );
|
||||||
++First; } }
|
++First; } }
|
||||||
// provides direct access to vertex data of specfied chunk
|
// provides direct access to vertex data of specfied chunk
|
||||||
vertex_array const &
|
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
|
// frustum tests are performed in 'world space' but after we set up frustum
|
||||||
// we no longer need camera translation, only rotation
|
// we no longer need camera translation, only rotation
|
||||||
::glMultMatrixd( glm::value_ptr( glm::dmat4( glm::dmat3( worldcamera ))));
|
::glMultMatrixd( glm::value_ptr( glm::dmat4( glm::dmat3( worldcamera ))));
|
||||||
|
|
||||||
Render( &World.Environment );
|
Render( &World.Environment );
|
||||||
Render( &World.Ground );
|
Render( &World.Ground );
|
||||||
|
|
||||||
@@ -835,27 +834,8 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
|||||||
::glDisable( GL_LIGHTING );
|
::glDisable( GL_LIGHTING );
|
||||||
|
|
||||||
// main draw call
|
// main draw call
|
||||||
// TODO: add support for colour data draw mode
|
m_geometry.draw( Submodel->m_geometry, color_streams );
|
||||||
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
|
|
||||||
|
|
||||||
::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
|
// post-draw reset
|
||||||
::glPopAttrib();
|
::glPopAttrib();
|
||||||
}
|
}
|
||||||
@@ -986,9 +966,6 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
|||||||
// pozniej sprawdzamy czy jest wlaczony PROBLEND dla aktualnie renderowanego noda TRIANGLE,
|
// pozniej sprawdzamy czy jest wlaczony PROBLEND dla aktualnie renderowanego noda TRIANGLE,
|
||||||
// wlasciwie dla kazdego node'a
|
// wlasciwie dla kazdego node'a
|
||||||
// i jezeli tak to odpowiedni GL_GREATER w przeciwnym wypadku standardowy 0.04
|
// 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 );
|
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 ) ) ) {
|
||||||
|
|||||||
Reference in New Issue
Block a user