Skip to content

Commit

Permalink
Shape(Ren.) has same api as Sprite(Ren.)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jerboa-app committed Aug 3, 2024
1 parent c39299c commit 5412b73
Show file tree
Hide file tree
Showing 9 changed files with 284 additions and 200 deletions.
24 changes: 15 additions & 9 deletions examples/Shape/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,18 @@ int main(int argv, char ** argc)
);

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

RNG rng;

for (unsigned i = 0; i < 64; i++)
{
trans.push_back(jGL::Transform(rng.nextFloat(), rng.nextFloat(), 0.0, 0.1f));
shapes.push_back
(
std::make_shared<jGL::Shape>
(
jGL::Transform(rng.nextFloat(), rng.nextFloat(), 0.0, 0.1f),
trans[i],
glm::vec4(rng.nextFloat(), rng.nextFloat(), rng.nextFloat(), 1.0)
)
);
Expand All @@ -58,7 +60,11 @@ int main(int argv, char ** argc)

circles->setProjection(camera.getVP());

std::shared_ptr<jGL::Shader> shader = std::make_shared<jGL::GL::glShader>(vertexShader, fragmentShader);
std::shared_ptr<jGL::Shader> shader = std::make_shared<jGL::GL::glShader>
(
jGL::GL::glShapeRenderer::shapeVertexShader,
jGL::GL::glShapeRenderer::ellipseFragmentShader
);

shader->use();

Expand All @@ -76,13 +82,13 @@ int main(int argv, char ** argc)
for (unsigned i = 0; i <shapes.size(); i++)
{
auto tr = circles->getTransform(std::to_string(i));
circles->getShape(std::to_string(i))->transform = jGL::Transform
(
tr.x+dt*(rng.nextFloat()-0.5),
tr.y+dt*(rng.nextFloat()-0.5),
tr.theta,
tr.scaleX
);
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);
Expand Down
31 changes: 0 additions & 31 deletions examples/Shape/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,35 +44,4 @@ std::string fixedLengthNumber(double x, unsigned length)
return dtrunc;
}

const char * vertexShader =
"#version 330\n"
"precision lowp float;\n"
"in vec4 a_position;\n"
"in vec4 a_offset;\n"
"in vec4 a_colour;\n"
"uniform mat4 proj;\n"
"out vec2 texCoord;\n"
"out vec4 colour;\n"
"void main(void){"
"vec2 pos = a_position.xy*a_offset.w;\n"
"float ct = cos(a_offset.z); float st = sin(a_offset.z);\n"
"mat2 rot = mat2(ct, -st, st, ct);\n"
"pos = rot*pos + a_offset.xy;\n"
"gl_Position = proj*vec4(pos,0.0,1.0);\n"
"texCoord = a_position.zw;\n"
"colour = a_colour;\n"
"}";

const char * fragmentShader =
"#version 330\n"
"precision lowp float;\n"
"in vec2 texCoord;\n"
"in vec4 colour;\n"
"out vec4 fragment;\n"
"void main(void){\n"
"vec2 c = texCoord-vec2(0.5,0.5);\n"
"if (dot(c,c) > 0.5*0.5) {discard;}\n"
"fragment = colour;\n"
"}";

#endif /* MAIN_H */
14 changes: 10 additions & 4 deletions examples/Sprite/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,14 +235,20 @@ int main(int argv, char ** argc)
2
);

std::vector<jGL::Transform> shapeTrans =
{
jGL::Transform(0.0, 0.0, 0.0, 1.0),
jGL::Transform(0.0, 0.0, 0.0, 1.0)
};

auto bbPi = std::make_shared<jGL::Shape>
(
jGL::Transform(0.0, 0.0, 0.0, 1.0),
shapeTrans[0],
glm::vec4(1.0, 0.0, 0.0, 0.3)
);
auto bbHeart = std::make_shared<jGL::Shape>
(
jGL::Transform(0.0, 0.0, 0.0, 1.0),
shapeTrans[1],
glm::vec4(1.0, 0.0, 0.0, 0.3)
);

Expand Down Expand Up @@ -279,13 +285,13 @@ int main(int argv, char ** argc)
float x = 0.0; float y = 0.0;
for (auto p : wbbPi.vertices) { x += p.x; y += p.y;}
float s = std::sqrt((wbbPi.vertices[1].x-wbbPi.vertices[0].x)*(wbbPi.vertices[1].x-wbbPi.vertices[0].x) + (wbbPi.vertices[1].y-wbbPi.vertices[0].y)*(wbbPi.vertices[1].y-wbbPi.vertices[0].y));
shapes->getShape("pi")->transform = jGL::Transform(x*0.25f, y*0.25f, trans["sPi"].theta ,s);
shapeTrans[0] = jGL::Transform(x*0.25f, y*0.25f, trans["sPi"].theta ,s);

jGL::WorldBoundingBox wbbHeart = sprites->getSprite("sHeart").getWorldBoundingBox();
x = 0.0; y = 0.0;
for (auto p : wbbHeart.vertices) { x += p.x; y += p.y;}
s = std::sqrt((wbbHeart.vertices[1].x-wbbHeart.vertices[0].x)*(wbbHeart.vertices[1].x-wbbHeart.vertices[0].x) + (wbbHeart.vertices[1].y-wbbHeart.vertices[0].y)*(wbbHeart.vertices[1].y-wbbHeart.vertices[0].y));
shapes->getShape("heart")->transform = jGL::Transform(x*0.25f, y*0.25f, trans["sHeart"].theta ,s);
shapeTrans[1] = jGL::Transform(x*0.25f, y*0.25f, trans["sHeart"].theta ,s);

sprites->draw();
shapes->draw();
Expand Down
93 changes: 55 additions & 38 deletions include/jGL/OpenGL/glShapeRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,28 @@

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)
: ShapeRenderer(sizeHint)
{
offsets = std::vector<float>(sizeHint*4+padShapes*4,0.0f);
colours = std::vector<float>(sizeHint*4+padShapes*4,0.0f);
xytheta = std::vector<float>(sizeHint*xythetaDim+padShapes*xythetaDim,0.0f);
scale = std::vector<float>(sizeHint*scaleDim+padShapes*scaleDim,0.0f);
colours = std::vector<float>(sizeHint*coloursDim+padShapes*coloursDim,0.0f);
initGL();
defaultShader = std::make_shared<glShader>(vertexShader, fragmentShader);
defaultShader = std::make_shared<glShader>(shapeVertexShader, rectangleFragmentShader);
defaultShader->use();
}

Expand All @@ -27,15 +37,42 @@ 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); }

void draw(std::shared_ptr<Shader> shader, std::vector<ShapeId> ids);
void draw(std::vector<ShapeId> ids) { draw(defaultShader, ids); }

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

/**
* @brief A fragment shader to draw rectangles.
* @remark Assume shapeVertexShader inputs
*/
static const char * rectangleFragmentShader;

/**
* @brief A fragment shader to draw ellipses.
* @remark Assume shapeVertexShader inputs
*/
static const char * ellipseFragmentShader;

private:

GLuint vao, a_position, a_offset, a_colour;
GLuint vao, a_position, a_xytheta, a_scale, a_colour;

float quad[6*4] =
{
Expand All @@ -48,8 +85,17 @@ namespace jGL::GL
0.5f, 0.5f, 1.0f, 1.0f // top right
};

std::vector<float> offsets; // offset x, y, theta, scale
std::vector<float> colours; // r, g, b, a
std::vector<float> xytheta;
size_t xythetaDim = 3;
size_t xythetaAttribtue = 1;

std::vector<float> scale;
size_t scaleDim = 2;
size_t scaleAttribtue = 2;

std::vector<float> colours;
size_t coloursDim = 4;
size_t coloursAttribtue = 3;

size_t padShapes = 8;

Expand All @@ -58,35 +104,6 @@ namespace jGL::GL

std::shared_ptr<Shader> defaultShader;

const char * vertexShader =
"#version " GLSL_VERSION "\n"
"precision lowp float; precision lowp int;\n"
"layout(location=0) in vec4 a_position;\n"
"layout(location=1) in vec4 a_offset;\n"
"layout(location=2) in vec4 a_colour;\n"
"uniform mat4 proj;\n"
"out vec2 texCoord;\n"
"out vec4 colour;\n"
"void main(){"
"vec2 pos = a_position.xy*a_offset.w;\n"
"float ct = cos(a_offset.z); float st = sin(a_offset.z);\n"
"mat2 rot = mat2(ct, -st, st, ct);\n"
"pos = rot*pos + a_offset.xy;\n"
"gl_Position = proj*vec4(pos,0.0,1.0);\n"
"texCoord = a_position.zw;\n"
"colour = a_colour;\n"
"}";

const char * fragmentShader =
"#version " GLSL_VERSION "\n"
"precision lowp float; precision lowp int;\n"
"in vec2 texCoord;\n"
"in vec4 colour;\n"
"layout(location=0) out vec4 fragment;\n"
"void main(){\n"
"fragment = colour;\n"
"}";

};
}

Expand Down
5 changes: 1 addition & 4 deletions include/jGL/Vulkan/vkShapeRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ namespace jGL::Vulkan

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

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


};
}

Expand Down
63 changes: 58 additions & 5 deletions include/jGL/shape.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,77 @@
#define SHAPE_H

#include <jGL/primitive.h>
#include <jGL/orthoCam.h>

namespace jGL
{
/**
* @brief A drawable shape
* @remark Detailed geometry is assumed defined in the shader. Circle and Rectangle are provided in ShapeRenderer.
*/
class Shape
{

public:

Shape()
{}

Shape(Transform tra, glm::vec4 c)
Shape(const Transform & tra, glm::vec4 c)
: transform(tra), colour(c)
{}

Transform transform;
const Transform & transform;
glm::vec4 colour;

/**
* @brief Get the WorldBoundingBox of the Shape.
*
* @return WorldBoundingBox
*/
WorldBoundingBox getWorldBoundingBox() const
{
WorldBoundingBox wbb =
{
{
glm::vec2(-0.5, -0.5),
glm::vec2(-0.5, 0.5),
glm::vec2(0.5, 0.5),
glm::vec2(0.5, -0.5)
}
};

float ct = std::cos(transform.theta); float st = std::sin(transform.theta);
glm::mat2 rot(ct, -st, st, ct);
glm::vec2 pos(transform.x, transform.y);
glm::vec2 scale(transform.scaleX, transform.scaleY);


for (uint8_t i = 0; i < wbb.vertices.size(); i++)
{
wbb.vertices[i] = rot*(wbb.vertices[i]*scale)+pos;
}

return wbb;
}

/**
* @brief Get the ScreenBoundingBox of the Shape.
*
* @param camera for projection to the screen.
* @return ScreenBoundingBox
*/
ScreenBoundingBox getScreenBoundingBox(const OrthoCam & camera)
{
WorldBoundingBox wbb = getWorldBoundingBox();
ScreenBoundingBox sbb;
glm::vec2 pos;
for (uint8_t i = 0; i < wbb.vertices.size(); i++)
{
pos = camera.worldToScreen(wbb.vertices[i].x, wbb.vertices[i].y);
sbb.vertices[i].x = uint16_t(pos.x);
sbb.vertices[i].y = uint16_t(pos.y);
}
return sbb;
}

};
}

Expand Down
Loading

0 comments on commit 5412b73

Please sign in to comment.