Cześć! Przy renderowaniu zobaczyłem, że jest ok. 40MB różnicy.
Gdy używam glMapBuffer ilość pamięci wynosi 60MB, gdy glMapBufferRange jest to ok. 100MB.

Czy da się w jakiś sposób zoptymalizować glMapBufferRange? Wydaje mi się, że daje za duży parametr length;

struct Vertex
	{
		Vector2 position;
		Color color; // GLubyte r, g, b, a;
		Vector2 uv;
	};
enum
	{   //Max num of objects
		MAX_SPRITES = 60000,
		//One sprite has got 4 vertices
		SPRITE_SIZE = sizeof(Vertex) * 4,
		//
		BUFFER_SIZE = SPRITE_SIZE * MAX_SPRITES,
		//One sprite has got 6 indices
		INDICES_SIZE = MAX_SPRITES * 6,

		POSITION_INDEX = 0,
		COLOR_INDEX = 1,
		UV_INDEX = 2,
	};

	class Sprite
	{
	public:
		Sprite(const Rect& destRect, const Rect& uvRect, const Color& color); // Rect -> float x, y, w, h
		~Sprite() = default;

	private:
		friend class Renderer2D;

		Rect destRect,
			 uvRect;

		Color color;
	};
	class Renderer2D
	{
	public:
		Renderer2D();
		~Renderer2D();

		void Create();
		void Begin();

		void Draw(const Sprite* sprite);
		void Render();

		inline int getIndexCount() const { return indexCount; }
	private:
		void End();

		GLuint vbo = 0,
			   vao = 0,
			   ebo = 0;
		GLsizei indexCount = 0;

		Vertex* mappedVertex = nullptr;
	};
Sprite::Sprite(const Rect& destRect, const Rect& uvRect, const Color& color) :
		destRect(destRect), uvRect(uvRect), color(color)
	{}

//->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

Renderer2D::Renderer2D() {}

	Renderer2D::~Renderer2D()
	{
#ifndef NDEBUG
		glBindVertexArray(0);
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
#endif
		glDeleteVertexArrays(1, &vao);
		glDeleteBuffers(1, &vbo);
		glDeleteBuffers(1, &ebo);
	}

	void Renderer2D::Create()
	{
		glGenVertexArrays(1, &vao);
		glBindVertexArray(vao);

		glGenBuffers(1, &vbo);
		glBindBuffer(GL_ARRAY_BUFFER, vbo);
		glBufferData(GL_ARRAY_BUFFER, BUFFER_SIZE, nullptr, GL_DYNAMIC_DRAW);

		glEnableVertexAttribArray(POSITION_INDEX);
		glEnableVertexAttribArray(COLOR_INDEX);
		glEnableVertexAttribArray(UV_INDEX);

		glVertexAttribPointer(POSITION_INDEX, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const void*)offsetof(Vertex, position));
		glVertexAttribPointer(COLOR_INDEX, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), (const void*)offsetof(Vertex, color));
		glVertexAttribPointer(UV_INDEX, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const void*)offsetof(Vertex, uv));

		int offset = 0;
		GLuint* indices = new GLuint[INDICES_SIZE];
		for (int i = 0; i < INDICES_SIZE; i += 6) {
			indices[i] = offset + 0;
			indices[i + 1] = offset + 1;
			indices[i + 2] = offset + 2;
			indices[i + 3] = offset + 2;
			indices[i + 4] = offset + 3;
			indices[i + 5] = offset + 0;

			offset += 4;
		}

		glGenBuffers(1, &ebo);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, INDICES_SIZE * sizeof(GLuint), nullptr, GL_STATIC_DRAW);
		glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, NULL, INDICES_SIZE * sizeof(GLuint), indices);

#ifndef NDEBUG
		glBindVertexArray(0);
#endif
	}

	void Renderer2D::Begin()
	{
		glBindBuffer(GL_ARRAY_BUFFER, vbo);
		//mappedVertex = (Vertex*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
		mappedVertex = (Vertex*)glMapBufferRange(GL_ARRAY_BUFFER,
			NULL,
			BUFFER_SIZE, // <- O tym mowa
			GL_MAP_WRITE_BIT |
			GL_MAP_INVALIDATE_BUFFER_BIT);
	}

	void Renderer2D::Draw(const Sprite* sprite)
	{
		mappedVertex->position = Vector2(sprite->destRect.x, sprite->destRect.y);
		mappedVertex->uv = Vector2(sprite->uvRect.x, sprite->uvRect.y);
		mappedVertex->color = sprite->color;
		mappedVertex++;

		mappedVertex->position = Vector2(sprite->destRect.x, sprite->destRect.y + sprite->destRect.h);
		mappedVertex->uv = Vector2(sprite->uvRect.x, sprite->uvRect.y + sprite->uvRect.h);
		mappedVertex->color = sprite->color;
		mappedVertex++;

		mappedVertex->position = Vector2(sprite->destRect.x + sprite->destRect.w, sprite->destRect.y + sprite->destRect.h);
		mappedVertex->uv = Vector2(sprite->uvRect.x + sprite->uvRect.w, sprite->uvRect.y + sprite->uvRect.h);
		mappedVertex->color = sprite->color;
		mappedVertex++;

		mappedVertex->position = Vector2(sprite->destRect.x + sprite->destRect.w, sprite->destRect.y);
		mappedVertex->uv = Vector2(sprite->uvRect.x + sprite->uvRect.w, sprite->uvRect.y);
		mappedVertex->color = sprite->color;
		mappedVertex++;

		indexCount += 6;
	}

	void Renderer2D::Render()
	{
		End(); 

		glBindVertexArray(vao);

		glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, NULL);

#ifndef NDEBUG
		glBindVertexArray(0);
#endif
		indexCount = 0;
	}

	void Renderer2D::End()
	{
		glUnmapBuffer(GL_ARRAY_BUFFER);

#ifndef NDEBUG
		glBindBuffer(GL_ARRAY_BUFFER, 0);
#endif
	}
int main(int argc, char*args[])
{
	Window window;
	{
		//Inicjuje SDL 
		//argumenty: major, minor
		window.Init(4, 6);
		//Tworzy okno
		//argumenty: name, w, h, flag
		window.Create("w", 1280, 720, NULL);
	}

	Camera2D camera;
	//Ortho projekcja
	//argumenty: left, right, bottom, top
	camera.Projection(0.0f, 1280.0f, 0.0f, 720.0f);

	Shader shader;
	{
		GLuint shaders[2] = {
			shader.CreateShader("vertex.shader", GL_VERTEX_SHADER),
			shader.CreateShader("fragment.shader", GL_FRAGMENT_SHADER)
		};  shader.CreateAndUseProgram(shaders, 2);
	}

	Renderer2D renderer; 
	renderer.Create();

	glClearColor(0.5, 0.5, 0.5, 1.0);

	SDL_Event event;
	bool quit = false;

	Sprite sprite(Rect(0.0f, 0.0f, 100.0f, 100.0f), Rect(0.0f, 0.0f, 1.0f, 1.0f), Color(255, 0, 255, 255));

	while (!quit) {
		while (SDL_PollEvent(&event)) {
			if (event.type == SDL_QUIT) {
				quit = true;
			}
		}

		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		{
			GLint u_camera = shader.GetUniformLocation("u_camera");
			glm::mat4 cameraMatrix = glm::mat4(1.0f);
			cameraMatrix = camera.getCameraMatrix();
			glUniformMatrix4fv(u_camera, 1, GL_FALSE, &(cameraMatrix[0][0]));
		}

		camera.Update();

		renderer.Begin();

		renderer.Draw(&sprite);

		renderer.Render();

		window.SwapBuffers();
	}

	return 0;
}