Skip to content

Commit

Permalink
Fix size bugs, optimise iter
Browse files Browse the repository at this point in the history
  • Loading branch information
Jerboa-app committed Sep 7, 2024
1 parent 0456384 commit 9a322d7
Show file tree
Hide file tree
Showing 8 changed files with 433 additions and 154 deletions.
62 changes: 34 additions & 28 deletions examples/Shape/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ int main(int argv, char ** argc)
conf.COCOA_RETINA = true;
#endif
jGL::DesktopDisplay display(glm::ivec2(resX, resY), "Shape", conf);
display.setFrameLimit(30);
display.setFrameLimit(60);

glewInit();

glm::ivec2 res = display.frameBufferSize();
resX = res.x;
resY = res.y;

jGLInstance = std::move(std::make_unique<jGL::GL::OpenGLInstance>(res));

jGL::OrthoCam camera(resX, resY, glm::vec2(0.0,0.0));
Expand All @@ -33,19 +33,22 @@ int main(int argv, char ** argc)
jGLInstance->setTextProjection(glm::ortho(0.0,double(resX),0.0,double(resY)));
jGLInstance->setMSAA(1);

std::shared_ptr<jGL::ShapeRenderer> circles = jGLInstance->createShapeRenderer
(
32
);

std::vector<std::shared_ptr<jGL::Shape>> shapes;
std::vector<jGL::Transform> trans;

RNG rng;
uint64_t n = 1000000;

for (unsigned i = 0; i < 64; i++)
std::shared_ptr<jGL::ShapeRenderer> circles = jGLInstance->createShapeRenderer
(
n
);

shapes.reserve(n);
trans.reserve(n);
for (unsigned i = 0; i < n; i++)
{
trans.push_back(jGL::Transform(rng.nextFloat(), rng.nextFloat(), 0.0, 0.1f));
trans.push_back(jGL::Transform(rng.nextFloat(), rng.nextFloat(), 0.0, 0.001f));
shapes.push_back
(
std::make_shared<jGL::Shape>
Expand All @@ -70,6 +73,7 @@ int main(int argv, char ** argc)

double delta = 0.0;
double dt = 1.0/600.0;
jGL::ShapeRenderer::UpdateInfo uinfo;

while (display.isOpen())
{
Expand All @@ -79,40 +83,40 @@ int main(int argv, char ** argc)

jGLInstance->clear();

for (unsigned i = 0; i <shapes.size(); i++)
{
auto tr = circles->getTransform(std::to_string(i));
trans[i] = jGL::Transform
(
tr.x+dt*(rng.nextFloat()-0.5),
tr.y+dt*(rng.nextFloat()-0.5),
tr.theta,
tr.scaleX
);
}
// for (unsigned i = 0; i <shapes.size(); i++)
// {
// auto tr = circles->getTransform(std::to_string(i));
// trans[i] = jGL::Transform
// (
// tr.x+dt*(rng.nextFloat()-0.5),
// tr.y+dt*(rng.nextFloat()-0.5),
// tr.theta,
// tr.scaleX
// );
// }

circles->draw(shader);
circles->draw(shader, uinfo);

delta = 0.0;
for (int n = 0; n < 60; n++)
{
delta += deltas[n];
}
delta /= 60.0;

std::stringstream debugText;

double mouseX, mouseY;
display.mousePosition(mouseX,mouseY);

debugText << "Delta: " << fixedLengthNumber(delta,6)
<< " ( FPS: " << fixedLengthNumber(1.0/delta,4)
<< " ( FPS: " << fixedLengthNumber(1.0/delta,4)
<< ")\n"
<< "Render draw time: \n"
<< "Render draw time: \n"
<< " " << fixedLengthNumber(rdt, 6) << "\n"
<< "Mouse (" << fixedLengthNumber(mouseX,4)
<< ","
<< fixedLengthNumber(mouseY,4)
<< "Mouse (" << fixedLengthNumber(mouseX,4)
<< ","
<< fixedLengthNumber(mouseY,4)
<< ")\n";

jGLInstance->text(
Expand All @@ -138,7 +142,9 @@ int main(int argv, char ** argc)

deltas[frameId] = duration_cast<duration<double>>(tock-tic).count();
frameId = (frameId+1) % 60;

uinfo.colour = false;
uinfo.scale = false;

}

jGLInstance->finish();
Expand Down
34 changes: 13 additions & 21 deletions include/jGL/OpenGL/glShapeRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ namespace jGL::GL
{
/**
* @brief OpenGL implementation of ShapeRenderer.
*
*
*/
class glShapeRenderer : public ShapeRenderer
{

public:

/**
* @brief Construct a new glShapeRenderer.
*
*
* @param sizeHint hint at the number of shapes.
*/
glShapeRenderer(size_t sizeHint = 8)
Expand All @@ -37,24 +37,9 @@ namespace jGL::GL
freeGL();
}

/**
* @brief Draw with overriding render priority and shader.
*
* @param shader An glShader to draw all the Sprites with.
* @param ids Render priorities for the Sprites.
*/
void draw(std::shared_ptr<Shader> shader, std::multimap<RenderPriority, ShapeId> ids);

/**
* @brief Draw with overriding render priority.
*
* @param ids Render priorities for the Sprites.
*/
void draw(std::multimap<RenderPriority, ShapeId> ids) { draw(defaultShader, ids); }

/**
* @brief A vertex shader for any default shapes.
*
*
*/
static const char * shapeVertexShader;

Expand All @@ -72,15 +57,22 @@ namespace jGL::GL

private:

void draw
(
std::shared_ptr<Shader> shader,
std::vector<std::shared_ptr<Shape>> & shapes,
UpdateInfo info = UpdateInfo()
);

GLuint vao, a_position, a_xytheta, a_scale, a_colour;

float quad[6*4] =
float quad[6*4] =
{
// positions / texture coords
0.5f, 0.5f, 1.0f, 1.0f, // top right
0.5f, -0.5f, 1.0f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, 0.0f, // bottom left
-0.5f, 0.5f, 0.0f, 1.0f, // top left
-0.5f, 0.5f, 0.0f, 1.0f, // top left
-0.5f, -0.5f, 0.0f, 0.0f, // bottom left
0.5f, 0.5f, 1.0f, 1.0f // top right
};
Expand Down
11 changes: 7 additions & 4 deletions include/jGL/Vulkan/vkShapeRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@ namespace jGL::Vulkan
vkShapeRenderer(size_t sizeHint)
: ShapeRenderer(sizeHint)
{}

void draw(std::shared_ptr<Shader> shader, std::multimap<RenderPriority, ShapeId> ids){TODO("jGL::Vulkan::vkShape::draw");}
void draw(std::multimap<RenderPriority, ShapeId> ids) {TODO("jGL::Vulkan::vkShape::draw");}

protected:
void draw
(
std::shared_ptr<Shader> shader,
std::vector<std::shared_ptr<Shape>> & shapes,
UpdateInfo info = UpdateInfo()
){}
};
}

Expand Down
130 changes: 130 additions & 0 deletions include/jGL/priorityStore.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#ifndef PRIORITYSTORE_H
#define PRIORITYSTORE_H

#include <memory>
#include <vector>
#include <iterator>
#include <algorithm>
#include <unordered_map>
#include <map>
#include <cstdint>
#include <iostream>

typedef std::string ElementId;
typedef uint64_t Priority;

template <class T>
class PriorityStore
{
public:

struct Record
{
Record(T e, Priority p, ElementId i)
: element(e), p(p), id(i)
{}

T element;
Priority p;
ElementId id;
};

void add(T & element, ElementId id, Priority p = 0)
{
if (idToIndex.find(id) != idToIndex.end())
{
throw std::runtime_error("id: "+id+", already use in PriorityStore");
}

insert(Record(element, p, id));
}

void remove(ElementId id)
{
if (idToIndex.find(id) == idToIndex.end()){ return; }

auto pos = cache.begin();
std::advance(pos, idToIndex[id]);
if (pos != cache.end())
{
cache.erase(pos);
}
idToIndex.erase(id);
}

void clear()
{
idToIndex.clear();
cache.clear();
}

void updatePriority(ElementId id, Priority newPriority)
{
if (idToIndex.find(id) == idToIndex.end()){ return; }

Record element = cache[idToIndex[id]];
auto pos = cache.begin();
std::advance(pos, idToIndex[id]);
if (pos != cache.end())
{
cache.erase(pos);
}
idToIndex.erase(id);

element.p = newPriority;
insert(element);
}

T & operator [](ElementId id) { return cache[idToIndex[id]].element; }

typename std::vector<Record>::const_iterator begin() const { return cache.cbegin(); }
typename std::vector<Record>::const_iterator end() const { return cache.cend(); }

uint64_t size() const { return cache.size(); }

void reserve(uint64_t n)
{
idToIndex.reserve(n);
cache.reserve(n);
}

protected:

struct Ordering
{
bool operator()
(
const Record & l,
const Record & r
) const
{ return l.p < r.p; }
};

std::unordered_map<ElementId, uint64_t> idToIndex;
std::vector<Record> cache;

void insert(Record element)
{
if (cache.empty()) { cache.push_back(element); return; }
if (element.p <= cache.front().p) { cache.insert(cache.begin(), element); return; }
if (element.p >= cache.back().p) { cache.push_back(element); return; }

cache.insert
(
std::upper_bound(cache.begin(), cache.end(), element, Ordering()),
element
);

reindex();
}

void reindex()
{
for (uint64_t i = 0; i < cache.size(); i++)
{
idToIndex[cache[i].id] = i;
}
}
};

#endif /* PRIORITYSTORE_H */
Loading

0 comments on commit 9a322d7

Please sign in to comment.