Używanie wejść shadera wierzchołków w open GL

0

Witam! Czytam sobie książkę o open gl https://helion.pl/ksiazki/opengl-ksiega-eksperta-wydanie-vii-graham-sellers-richard-s-wright-jr-nicholas-ha,opglk7.htm#format/d (prędzej czytałem i oglądałem trochę internetowych tutoriali) i próbuje zmienić w moim programie, który właśnie używa internetowego sposobu (internetowego, bo książka pokazuje trochę inaczej) na wczytanie danych do shadera:

struct Vertex {
	struct Color {
		float r, g, b, a;
	} color;

	struct Position {
		float x, y;
	} position;

	struct UV {
		float u,v;
	} uv;
}
		if (vao == 0) {
			glCreateVertexArrays(1, &vao);
		}
		glBindVertexArray(vao);

		if (vbo == 0) {
			glCreateBuffers(1, &vbo);
		}
		glBindBuffer(GL_ARRAY_BUFFER, vbo);

		glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, position));
		glEnableVertexAttribArray(0);

		glVertexAttribPointer(1, 4, GL_FLOAT, GL_TRUE, sizeof(Vertex), (void*)offsetof(Vertex, color));
		glEnableVertexAttribArray(1);

		glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, uv));
		glEnableVertexAttribArray(2);

		glBindVertexArray(0);

na książkowy:

struct Vertex {
	float x, y, z;
	float r, g, b;
}


static const Vertex vertices[] = {...};

glCreateVertexArrays(1, &vao);

glCreateBuffers(1, &vbo);
glNamedBufferStorage(buffer, sizeof(vertices), vertices, 0);

glVertexArrayAttribBinding(vao, 0, 0);
glVertexArrayAttribFormat(vao, 0, 3, GL_FLOAT, GL_FALSE, offsetof(Vertex, x));
glEnableVertexArrayAttrib(0);

glVertexArrayAttribBinding(vao, 1, 0);
glVertexArrayAttribFormat(vao, 1, 3, GL_FLOAT, GL_FALSE, offsetof(Vertex, r));
glEnableVertexArrayAttrib(0);

glVertexArrayVertexBuffer(vao, 0, vbo);

Jak widać w kodzie "internetowym" nie mam obiektu Vertex jako w tej metodzie (w metodzie gdzie robie glBufferData();, glBufferSubData(); mam takowy), więc w jaki sposób wywołać metodę glNamedBufferStorage()?

Również metoda glVertexArrayVertexBuffer(vao, 0, vbo); ma dodatkowo w moim wywołaniu funkcji dodatkowe parametry offset i stride - w książce tego nie ma.

W jaki sposób mógłbym zmienić pierwszy kod na "książkowy"?

0

No proszę na ile sposobów można zrobić to samo, pierwszy sposób wydaje się łatwiejszy (bo drugiego nie znam).

W "internetowym" sposobie po prostu włączasz numer odpowiedniego atrybutu shadera : "glEnableVertexAttribArray(numer);" i ustalasz które wartości z ciągu liczb vertexa dotyczą tego atrybutu: "glVertexAttribPointer(1, 4, GL_FLOAT, GL_TRUE, sizeof(Vertex), (void*)offsetof(Vertex, color));" - czyli w tym przypadku 4 pierwsze liczby struktury Vertex.

Twój Vertex (internetowy) składa się z 8 liczb typu float (książkowy z 6 liczb float), w porządku kolor, pozycja, współrzędne tekstury.
Np werteks: 1.0f, 1.0f, 1.0f, 1.0f, 2.0f, 3.0f, 0.0f, 0.0f - cztery pierwsze liczby dotyczą koloru, dwie następne pozycji i dwie ostatnie współrzędnych tekstury - musisz poinformować shader które liczby czego dotyczą i to właśnie robisz za pomocą funkcji glVertexAttribPointer, lub za pomocą funkcji glVertexArrayAttribBinding i
glVertexArrayAttribFormat - popatrz sobie w dokumentacji jak działają te funkcje albo w książce, na pewno jest jakiś opis który parametr do czego w nich służy.

glNamedBufferStorage to najwyraźniej zamiennik dla glBufferData.

0

Funkcje glNamedBufferStorage, glVertexArrayAttribBinding i glVertexArrayAttribFormat wymagają OpenGL-a 4.5, co nie wydaje się rozsądne – mocno ograniczasz sobie kompatybilność odcinając się od starszych czy słabszych kart, zwłaszcza zintegrowanych. I nie mam na myśli 25-letnich…

Nie miałem z tym „sposobem” do czynienia, ale wychodzi na to, że
glNamedBufferStorage to takie inne glBufferData - ta druga funkcja operuje na zabindowanym (glBindBuffer) buforze, a w tej pierwszej bufor podajesz jako parametr.

glVertexArrayAttribBinding + glVertexArrayAttribFormat to taki inny glVertexAttribPointer (plus glBindVertexArray).

glVertexArrayVertexBuffer rzeczywiście ma pięć parametrów a nie trzy. Co myślał autor książki – nie wiem. Spróbuj podać 0 jako offset i sizeof(Vertex) jako stride.

Dziwna ta książka ogólnie - autor widocznie jest entuzjastą tych nowych "nikomu niepotrzebnych" funkcji.

0

Funkcje glNamedBufferStorage, glVertexArrayAttribBinding i glVertexArrayAttribFormat wymagają OpenGL-a 4.5, co nie wydaje się rozsądne – mocno ograniczasz sobie kompatybilność odcinając się od starszych czy słabszych kart, zwłaszcza zintegrowanych. I nie mam na myśli 25-letnich…

Rozumiem.

Zastanawia mnie jeszcze jedna sprawa, bo mówisz, że do użycia glVertexArrayAttribBinding i glVertexArrayAttribFormat potrzeba open gl 4.5, a kiedy wypisuje sobie glGetString(GL_VERSION); na ekranie - wychodzi 3.3, a te funkcje działają i tak.

Co prawda moja karta obsługuje najnowszego open gl, ale czy to znaczy, że powinny działać te metody skoro aplikacja chodzi na wersji 3.3?

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