OpenGL efektywne wczytywanie z pliku .obj do VBO

0

Witam,

mam takie sobie struktury:

/**
 * Struktura to trzymania współrzędnych wierzchołka.
 */
typedef struct sVertexCoords {
	GLfloat x;
	GLfloat y;
	GLfloat z;
	
	sVertexCoords();
	sVertexCoords(const GLfloat*);
	
	bool operator ==(const sVertexCoords&) const;
	sVertexCoords& operator=(const sVertexCoords&);
} sVertexCoords;

/**
 * Tutaj trzymamy współrzędne tekstury.
 */
typedef struct sTexCoords {
	GLfloat u;
	GLfloat v;
	
	sTexCoords();
	sTexCoords(const GLfloat*);
	
	bool operator ==(const sTexCoords&) const;
	sTexCoords& operator=(const sTexCoords&);
} sTexCoords;

/**
 * A tutaj wektor normalnej.
 */
typedef struct sNormal {
	GLfloat x;
	GLfloat y;
	GLfloat z;
	
	sNormal();
	sNormal(const GLfloat*);
	
	bool operator ==(const sNormal&) const;
	sNormal& operator=(const sNormal&);
} sNormal;

/**
 * Zebrane dane dla całego jednego wierzchołka.
 */
typedef struct sVertex {
	sVertexCoords	vertexCoords;
	sTexCoords	textureCoords;
	sNormal		normalVector;
	
	sVertex();
	sVertex(const GLfloat*, const GLfloat*, const GLfloat*);
	sVertex(const GLfloat*, const GLfloat*);
	sVertex(const GLfloat*, const int&, const GLfloat*);
	
	bool operator ==(const sVertex&) const;
	sVertex& operator =(const sVertex&);
} sVertex;

Jedna taka struktura zajmuje 32 bajty, więc ok. Ja razie więcej tekstur nie potrzebuję. I teraz, mam sobie jakiś plik .obj. Jak można efektywnie wczytać cały obiekt z tego pliku, ale tak, żeby wykorzystać indeksowanie (wierzchołki współdzielone)? Mam sobie na przykład:

# Blender3D v249 OBJ File: 
# www.blender3d.org
mtllib bottom.mtl
v 11.750401 -0.000000 -9.920000
v 11.750401 0.000000 9.920001
v -11.750402 0.000000 9.919999
v -11.750398 -0.000000 -9.920005
vn 0.000000 1.000000 -0.000000
usemtl Material.001
s off
f 1//1 4//1 3//1
f 1//1 3//1 2//1

To jest jakieś tam podłoże, które na szybko wygenerowałem w Blenderze. Wczytuję sobie do tablicy wierzchołków wszystkie wierzchołki, potem tekstury (akurat tutaj nie ma), a do trzeciej tablicy - normalne. I w momencie, gdy pojawia mi się definicja face'a, muszę przeszukać cały wektor wierzchołków, żeby móc stwierdzić, czy robić push_back, czy rozszerzać tylko tablicę indeksów. Oczywiście, w przypadku takiego pliku to nie ma znaczenia, ale w przypadku większych obiektów, które mają po kilkanaście tysięcy fejsów, to już trochę trwa. Myślałem o std::map, ale szukam czegoś jeszcze bardziej efektywnego. Chyba, że można zrobić to jeszcze inaczej, na przykład na poziomie karty graficznej. Da się tak?
Z góry dzięki za odpowiedzi i pozdrawiam.

0
Garrappachc napisał(a)

W
I w momencie, gdy pojawia mi się definicja face'a, muszę przeszukać cały wektor wierzchołków, żeby móc stwierdzić, czy robić push_back, czy rozszerzać tylko tablicę indeksów.

Przyznam, że nie rozumiem. Przecież jak czytasz fejsy, to tam są same indeksy wierzchołków. Po co przeszukiwać wektor wierzchołków? Nie rozumiem o co chodzi.

0

Przepraszam, wyraziłem się rzeczywiście zbyt niejasno.
Jak wczytuję wierzchołki do VBO, to nie muszę wczytywać wszystkich wierzchołków. Weźmy taki kwadrat. Mamy współrzędne (0, 1), (1, 1), (0, 0), (1, 0). Załóżmy, że renderujemy używając tylko GL_TRIANGLES (GL_QUADS jest obecnie deprecated, gdyż są mało wydajne). W tym momencie możemy umieścić w buforze karty graficznej dwa trójkąty:
(0, 1), (1, 1), (0, 0) oraz (1, 1), (0, 0), (1, 0). W tym momencie do wyrenderowania prostego kwadratu wysyłamy aż sześć wierzchołków. Obecne standardy mówią o tzw. współdzieleniu wierzchołków. Czyli wysyłamy do karty graficznej jakieś-tam wierzchołki (wektor obiektów Vertex):

[0](0, 1)
[1](1, 1)
[2](0, 0)
[3](1, 0)

I mówimy: wyrenderuj mi dwa trójkąty ze współrzędnych o indeksach (0, 1, 2) oraz (1, 2, 3).
Problem leży w tym, że taki wierzchołek zawiera nie tylko informacje o położeniu, ale również informacje o koordynatach tekstury oraz normalną. Czyli nie możemy sobie stworzyć tablicy wierzchołków prosto z pliku, gdyż informacje o położeniu, teksturze i normalnej znajdują się w zupełnie innych miejscach. Czyli jak dostaję face:
f 1/2/3 4/5/6 7/8/9
Muszę sprawdzić, czy nie dostałem wcześniej wierzchołka 1/2/3, wierzchołka 4/5/6 i wierzchołka 7/8/9. Myślałem nad czymś takim, jak umieszczanie wierzchołków, koordynat tekstury i normalnych w innych miejscach w buforze karty graficznej, a potem utworzeniu po prostu trzech różnych tablic indeksów, ale okazuje się, że takie rozwiązanie jest już niewydajne przy renderowaniu.
Pozdrawiam.

1 użytkowników online, w tym zalogowanych: 0, gości: 1