Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- typedef unsigned int uint32;
- typedef unsigned long long uint;
- struct Vertex2D
- {
- Vertex2D(float x, float y, uint32 color)
- {
- position = { x, y };
- this->color = color;
- }
- Vector2<float> position;
- uint32 color;
- };
- struct Range
- {
- //Begin of the buffer
- uint begin = 0;
- GLsync sync = 0;
- };
- struct Renderer
- {
- Renderer() = default;
- ~Renderer()
- {
- glUnmapNamedBuffer(vbo);
- glDeleteBuffers(1, &vbo);
- glDeleteVertexArrays(1, &vao);
- }
- //triple buffering
- static const int bufferCount = 3;
- static const int quadVertexCount = 4;
- //First frame = 0; second frame = 1; third frame = 2; fourth = 0; fifth = 1; ... etc.
- int rangeIndex = 0;
- Range ranges[bufferCount];
- int waitCount = 0;
- void Create()
- {
- shader = shader.Create("assets/shaders/renderer.glsl");
- auto mapBit = GL_MAP_WRITE_BIT | GL_MAP_COHERENT_BIT | GL_MAP_PERSISTENT_BIT;
- glCreateVertexArrays(1, &vao);
- glBindVertexArray(vao);
- glGenBuffers(1, &vbo);
- glBindBuffer(GL_ARRAY_BUFFER, vbo);
- glNamedBufferStorage(vbo, bufferCount * 4 * sizeof(Vertex2D), nullptr, mapBit);
- glEnableVertexAttribArray(0);
- glEnableVertexAttribArray(1);
- glVertexAttribPointer(0, 2, GL_FLOAT, false, sizeof(Vertex2D), (const void*)offsetof(Vertex2D, position));
- glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, true, sizeof(Vertex2D), (const void*)offsetof(Vertex2D, color));
- mappedVertex = (Vertex2D*)glMapNamedBufferRange(vbo, NULL, bufferCount * quadVertexCount * sizeof(Vertex2D), mapBit);
- ranges[0].begin = 0;
- ranges[1].begin = quadVertexCount;
- ranges[2].begin = quadVertexCount * 2;
- }
- void LockBuffer(GLsync& syncObject)
- {
- if (syncObject) {
- glDeleteSync(syncObject);
- }
- syncObject = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
- }
- void WaitBuffer(GLsync& syncObject)
- {
- if (syncObject) {
- while (true) {
- auto waitReturn = glClientWaitSync(syncObject, GL_SYNC_FLUSH_COMMANDS_BIT, 1);
- if (waitReturn == GL_ALREADY_SIGNALED || waitReturn == GL_CONDITION_SATISFIED)
- return;
- waitCount++;
- }
- }
- }
- void Begin()
- {
- vertices.clear();
- }
- void FillRect(float x, float y, float w, float h, uint32 color)
- {
- vertices.push_back(Vertex2D(x, y, color));
- vertices.push_back(Vertex2D(x, y + h, color));
- vertices.push_back(Vertex2D(x + w, y + h, color));
- vertices.push_back(Vertex2D(x + w, y, color));
- }
- void Lock()
- {
- WaitBuffer(ranges[rangeIndex].sync);
- }
- void RenderPresent()
- {
- Lock();
- glBindVertexArray(vao);
- //Clear CPU data
- Begin();
- //Fill CPU data
- FillRect(10.0f, 10.0f, 50.0f, 50.0, 0xff00ffff);
- //Pass CPU data to the GPU
- memcpy(&mappedVertex[ranges[rangeIndex].begin], vertices.data(), sizeof(Vertex2D) * vertices.size());
- //Draw
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- //Clear old CPU data
- Begin();
- //Fill CPU data
- FillRect(10.0f, 60.0f, 50.0f, 50.0f, 0xffffffff);
- //Pass CPU data to the GPU
- memcpy(&mappedVertex[ranges[rangeIndex].begin], vertices.data(), sizeof(Vertex2D) * vertices.size());
- //Draw
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- Unlock();
- }
- void Unlock()
- {
- LockBuffer(ranges[rangeIndex].sync);
- rangeIndex = (rangeIndex + 1) % bufferCount;
- }
- Shader shader;
- GLuint vao;
- GLuint vbo;
- Vertex2D* mappedVertex = nullptr;
- std::vector<Vertex2D> vertices;
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement