open gl co wpisać w void* pointer w glVertexAttribPointer?

0

Cześć! Aktualnie uczę się o ładowaniu tekstur w open gl z

I nie wiem na jakiej zasadzie działa void * pointer glVertexAttribPointer

Wiem, że ustawia ono miejsce od którego chcemy brać zmienne. Tylko nie wiem co wpisać kiedy zamiast struktur jak

struct ColorRGBA8
{
	ColorRGBA8() : r(0), g(0), b(0), a(0) { }
	ColorRGBA8(GLubyte R, GLubyte G, GLubyte B, GLubyte A) :
		r(R), g(G), b(B), a(A) { }
	GLubyte r;
	GLubyte g;
	GLubyte b;
	GLubyte a;
};


struct UV
{
	float u, v;
};
struct Position
{
	float x;
	float y;
};
class Vertex
{
public:
	Vertex();
	Position position;

	ColorRGBA8 color;

	UV uv;

	void setUV(float u, float v);
	void setPosition(float x, float y);
	void setColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a);
};

będę miał jedną klasę

class Vertex{
    public:
            float x,y, u,v;
            GLubyte r,g,b,a;

        void setUV(float u, float v);
	void setPosition(float x, float y);
	void setColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a);
};

Oraz zastanawia mnie jeszcze czy naprawdę potrzeba nam aż 3 klas żeby ładować tekstury

enum class SortType
{
	NONE, FRONT_TO_BACK, BACK_TO_FRONT, TEXTURE
};

class Glyph
{
public:
	Glyph();
	GLuint texture;
	float w, h, depth;

	Vertex topLeft;
	Vertex topRight;
	Vertex bottomLeft;
	Vertex bottomRight;
private:
};

class RenderBatch
{
public:
	RenderBatch(GLuint Offset, GLuint NumVertices, GLuint Texture);
	~RenderBatch();
	GLuint offset;
	GLuint numVertices;
	GLuint texture;
private:
};

class SpriteBatch
{
public:
	SpriteBatch();
	~SpriteBatch();

	void Init();

	void Begin(SortType sort = SortType::TEXTURE);
	void End();

	void Draw(glm::vec4 destRect, glm::vec4 uvRect, GLuint texture, ColorRGBA8 color);

	void Render();
private:
	void CreateRenderBatches();
	void CreateVertex();
	GLuint vbo;
	GLuint vao;

	void Sort();
	static bool compereFrontToBack(Glyph *a, Glyph *b);
	static bool compereBackToFront(Glyph *a, Glyph *b);
	static bool compereTexture(Glyph *a, Glyph *b);

	std::vector<Glyph*> glyph;
	std::vector<RenderBatch> renderBatches;

	SortType sortType;
};
1

spróbuj 0

0

glVertexAttribPointer ustawia zmienne (dane werteksów) które mają być przesłane do shadera:

  1. parametr to "lokacja" zmiennej, można ją ustawić albo za pomocą layoutów (np 0, 1, 2...), albo za pomocą pobierania nazwy zmiennej, np masz shader:
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texcoord;

czyli wchodzą zmienne pozycja (wektor o trzech współrzędnych) i tekstura (wektor o dwóch współrzędnych), zmienne możesz ustawić tak:

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), (void*)(0*sizeof(GLfloat)));
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), (void*)(3*sizeof(GLfloat)));

lub tak:

GLint location1 = glGetAttribLocation(shader->getID(), "position");
glEnableVertexAttribArray(location1);
glVertexAttribPointer(location1, 3, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), (void*)0*sizeof(GLfloat)));
GLint location2 = glGetAttribLocation(shader->getID(), "texcoord");
glEnableVertexAttribArray(location2);
glVertexAttribPointer(location2, 2, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), (void*)3*sizeof(GLfloat)));
  1. parametr określa z ilu współrzędnych składa się wektor który przesyłasz (jak skalar to 1, jak wektor 2d to 2 jak wektor3d to 3 itd.)

  2. i 4. to nie pamiętam, coś tam se znaczą, można sprawdzić w dokumentacji albo wyczytać gdzieś.

  3. parametr to rozmiar zmiennych które wysyłasz, jak wysyłasz wektor 3d i 2d to łącznie masz 5 GLfloatów do wysłania.

  4. parametr to offset wysyłanej zmiennej, zmienną pozycję wysyłasz jako pierwszą więc masz zero, drugą zmienną texcoord wysyłasz po zmiennej position, dlatego wstawiasz takie dziwne: "(void*)3*sizeof(GLfloat)" żeby odszukać jego pozycję w pamięci.

Twoja klasa ma 2 zmienne określające pozycję, 2 zmienne określające współrzędne tekstury i 4 zmienne określające kolor, więc vec2 position, vec2 texcoord, vec4 color:

glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), (void*)(0*sizeof(GLfloat)));
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), (void*)(2*sizeof(GLfloat)));
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), (void*)(4*sizeof(GLfloat)));

tj może trochę inaczej wyglądać przez te glubyte, ale ja to bym zmienił na floaty.

0

Cześć! Aktualnie uczę się o ładowaniu tekstur w open gl

Przydałoby się zawsze podawać wersję OpenGL która cię interesuje, bo dużo rzeczy zmieniało się z wersji na wersję, a wbrew pozorom w praktyce rzadko używa się najnowszej.

I nie wiem na jakiej zasadzie działa void * pointer glVertexAttribPointer
Wiem, że ustawia ono miejsce od którego chcemy brać zmienne.

Jeśli nie używasz VBO (vertex buffer object) to jest to po prostu wskaźnik na dane.
Jeśli masz aktywne VBO to jest to offset wewnątrz VBO na początek danych które chcesz przekazać.

parametr to rozmiar zmiennych które wysyłasz, jak wysyłasz wektor 3d i 2d to łącznie masz 5 GLfloatów do wysłania.

Jest to tzw. stride, czyli odstęp w bajtach między dwiema sąsiadującymi danymi danego typu.

Funkcja glVertexAttribPointer wydaje się skomplikowana, ale dzięki temu pozwala na dowolny sposób zagospodarowania bufora:
Atrybuty poszczególnych wierzchołków można trzymać jako tablicę struktur (czyli np. pozycja, texcoord, kolor, pozycja texcoord, kolor itp.) albo jako osobne tablice (pozycja, pozycja, pozycja, ... texcoord, texcoord, texcoord, ... kolor, kolor, kolor, ...) a poszczególne atrybuty mogą być w dowolnej kolejności i ilości.

Proponuję zajrzeć do specyfikacji. Na przykład glspec31.pdf strony 24-25. Nie polecam najnowszych wersji specyfikacji bo są zaśmiecone i przez to nieczytelne.

Oraz zastanawia mnie jeszcze czy naprawdę potrzeba nam aż 3 klas żeby ładować tekstury

Nazwy tych klas sugerują, że to jest coś więcej niż tylko ładowanie tekstury…

0

Znaczy, w poradniku koleś pokazuje to jako wydłużona wersja zwykłej klasy która ładuje i rysuje tekstury. Zastanawia mnie czy jest sens robienia czegoś takiego, a czy nie lepiej byłoby mieć jedną klasę, która posiada wszystko

class Texture
{
public:
	//Ładowanie tekstury z pliku
   	void LoadFromFile(std::string filepath);
	//Rysowanie jej
	void Draw(destRect, uvRect, color);
	//tworzenie vbo, vao
	void CreateVertexArray();
private:
	GLuint texture;
	int w,h;
	//I inne potrzebne zmienne
};

Jeśli nie używasz VBO (vertex buffer object) to jest to po prostu wskaźnik na dane.
Jeśli masz aktywne VBO to jest to offset wewnątrz VBO na początek danych które chcesz przekazać.

Da się zrobić to bez vbo?

Przydałoby się zawsze podawać wersję OpenGL która cię interesuje, bo dużo rzeczy zmieniało się z wersji na wersję, a wbrew pozorom w praktyce rzadko >używa się najnowszej.

Racja 3.3 chyba... #version 330 core używam w shaderach

0
  1. jak to wersja 330 to bez vbo chyba nie da rady zrobić;
  2. zastanawia mnie po co ci CreateVertexArray w klasie tekstury, ta klasa powinna zawierać identyfikator tekstury, załadować obrazek, przekonwertować obrazek na format opengl (glTexImage2D), ustawić filtrowanie tekstur (glTexParameteri), ewentualnie ustawić tworzenie mipmap (glGenerateMipmap). VertexArray to raczej przydałby się do jakiejś klasy zarządzającej siatką modelu (narysować jakiś prostokąt albo sześcian).
    Z tego co tu opisałeś wynika że koleś w tutorialu od razu połączył klasę tekstury z klasą rysującą prostokąt z nałożonym na niego obrazkiem.
0

zastanawia mnie po co ci CreateVertexArray w klasie tekstury

Nie wiem w sumie. Dopiero się o tym uczę. Nie wiem jak powinny wyglądać takie klasy.

0

To zacznij od podstaw; https://learnopengl.com, dowiedz się co jak się robi a potem pomyśl jak to sensownie sobie rozbić na klasy, bo ten tutorial co masz trochę dziwny mi się wydaje, mało przejrzyste.

0

Da się zrobić to bez vbo?

Użycie VBO (czyli glGenBuffers, glBindBuffer, glBufferData itp.) jest wymagane w kontekstach "core". Nie jest wymagane w trybie "compatibility" – niezależnie od wersji.

Bez VBO wskaźnik na dane zamiast do glBufferData podaje się po prostu jako ostatni parametr glVertexAttribPointer.

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