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;
}