Dlaczego sprite batch działa tak bardzo słabo w moim kodzie?

0

Witam! Obejrzałem i postanowiłem zastosować ten system w mojej aplikacji. Niestety zamiast 300 fpsów przy 60 tysiącach spritów, ja mam 20.

enum
	{ 
		RENDERER_MAX_SPRITES = 60000,
		RENDERER_SPRITE_SIZE = sizeof(Vertex) * 4,
		RENDERER_BUFFER_SIZE= RENDERER_SPRITE_SIZE * RENDERER_ MAX_SPRITES,
		RENDERER_INDICES_SIZE = RENDERER_MAX_SPRITES * 6,
	};

	class Sprite
	{
	public:
		Sprite(const Rectangle& rectangle, const ColorRGBA& color);
		~Sprite() = default;

	private:
		friend class Renderer2D;

		Vec2 position;
		Vec2 dimension;
		ColorRGBA color;
	};
	class SpriteBatch
	{
	public:
		SpriteBatch();
		~SpriteBatch();

		void Create();

		void Begin();
		void Draw(const Sprite* sprite);
		void End();
		void Flush();
	private:
		GLuint vao;
		GLuint vbo;
		GLuint ibo;
		int indexCount;
		
		Vertex* vertex;

		void SetupIndices(GLuint* indices);
	};
	Sprite::Sprite(const Rectangle& rectangle, const ColorRGBA& color) :
	{
		position = {rectangle.x, rectangle.y};
		dimension = {rectangle.w, rectangle.h};
		this->color = color;
	}

	SpriteBatch::SpriteBatch()
	{
		Create();
	}

	SpriteBatch::~SpriteBatch()
	{
		glDeleteBuffers(1, &vbo);
		glDeleteBuffers(1, &ibo);
		glDeleteVertexArrays(1, &vao);
	}
	
	void SpriteBatch::Create()
	{
		glCreateVertexArrays(1, &vao);
		glBindVertexArray(vao);

		glCreateBuffers(1, &vbo);
		glBindBuffer(GL_ARRAY_BUFFER, vbo);
		glNamedBufferData(vbo, RENDERER_BUFFER_SIZE, NULL, GL_DYNAMIC_DRAW);

		glVertexArrayAttribBinding(vao, 0, 0);
		glVertexArrayAttribFormat(vao, 0, 2, GL_FLOAT, GL_FALSE, 0);
		glEnableVertexArrayAttrib(vao, 0);

		glVertexArrayAttribBinding(vao, 1, 0);
		glVertexArrayAttribFormat(vao, 1, 4, GL_FLOAT, GL_TRUE, 4 * sizeof(GLfloat)));
		glEnableVertexArrayAttrib(vao, 1);

		glVertexArrayVertexBuffer(vao, 0, vbo, 0, sizeof(Vertex));

		glBindBuffer(GL_ARRAY_BUFFER, 0);

		GLuint* indices = new GLuint[RENDERER_INDICES_SIZE];
		SetupIndices(indices);

		glCreateBuffers(1, &ibo);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
		glNamedBufferData(ibo, RENDERER_INDICES_SIZE * sizeof(GLuint), indices, GL_STATIC_DRAW);

		glBindVertexArray(0);
	}

	void SpriteBatch::Begin()
	{
		vertex = (Vertex*)glMapNamedBuffer(vbo, GL_WRITE_ONLY);
	}

	void SpriteBatch::Draw(const Sprite* sprite)
	{
		vertex ->position = Vec2(sprite->position.x, sprite->position.y);
		vertex ->color = sprite->color;
		vertex ++;

		vertex ->position = Vec2(sprite->position.x, sprite->position.y + sprite->dimension.y);
		vertex ->color = sprite->color;
		vertex ++;

		vertex ->position = Vec2(sprite->position.x  + sprite->dimension.x, sprite->position.y + sprite->dimension.y);
		vertex ->color = sprite->color;
		vertex ++;

		vertex ->position = Vec2(sprite->position.x + sprite->dimension.x, sprite->position.y);
		vertex ->color = sprite->color;
		vertex ++;

		indexCount += 6;
		spriteSize += 1;
	}

	void SpriteBatch::Flush()
	{
		glBindVertexArray(vao);
		glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, NULL);
		glBindVertexArray(0);

		indexCount = 0;
	}
	
	void SpriteBatch::End()
	{
		glUnmapNamedBuffer(vbo);
	}

	void SpriteBatch::SetupIndices(GLuint* indices)
	{
		unsigned short offset = 0;
		for (GLuinti = 0; i < RENDERER_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;
		}
	}
int main(int argc, char* argv[])
{
	Window window;
	//Tworzy okno o nazwie OpenGLWindow z wymiarami 800x600 i opengl w wersji 4.6
	window.CreateWindow("OpenGLWindow", 800, 600, 4, 6);

	SpriteBatch spriteBatch;

	Camera camera;
	camera.Ortho(800.0f, 600.0f);

	Shader shader("Shader.vs.glsl", "Shader.fs.glsl");
	shader.UseProgram();

	glClearColor(1.0, 0.0, 0.0, 1.0);
	glViewport(0, 0, 800, 600);
	bool quit = false;

	srand(time(NULL);

	std::vector<Sprite*> sprites;
	for (float y = 0.0f; y < 9.0f; y += 0.05f) {
		for (float x = 0.0f; x < 16.0f; x += 0.05f) {
			sprites.push_back(new Sprite(Rectangle(x, y, 0.08f, 0.08f), Rectangle(0.0f, 0.0f, 1.0f, 1.0f), ColorRGBA((rand() % 1000 / 1000.0f) * 255, 0, 255, 255)));
		}
	}

	while(!quit)
	{
		while(window.PollEvent())
		{
			if(window.Quit())
			{
				quit = true;
			}
		}

		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		shader.Uniform4fv(shader.getLocation("camera", camera.Matrix());

		camera.Process();		

		spriteBatch.Begin();
		for(const auto& sprite:sprites)
			spriteBatch.renderer(sprite);
		spriteBatch.End();
		spriteBatch.Flush();

		window.Update();
	}
	return 0;
}

w jaki sposób zyskać tak duży przyrost fpsów? Użycie starszy odpowiedników typu glMapBuffer zamist glMapNamedBuffer niczego nie zmienia. FPSy się zgadzają w momencie gdy sprites.push_back() dam w komentarz. Czasami nawet komputer się ścina i robi "wrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr" i po chwili się odcina.

Specyfikacja:
i5 7600k
gtx 1080 armor oc
16 GB 3000MHz CL15
tomahawk z270
ssd adata nazwy nie pamiętam 240GB

0

A jaka jest konfiguracja twojego komputera?

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