Skip to content

Commit

Permalink
More graphics support
Browse files Browse the repository at this point in the history
  • Loading branch information
kunitoki committed May 3, 2024
1 parent 1b646f5 commit ce341b1
Show file tree
Hide file tree
Showing 16 changed files with 1,181 additions and 90 deletions.
159 changes: 88 additions & 71 deletions examples/graphics/source/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,94 @@

//==============================================================================

class CustomComponent : public juce::Component
{
public:
CustomComponent()
{
random.setSeedRandomly();
}

void paint (juce::Graphics& g, float frameRate) override
{
}

private:
juce::Random& random = juce::Random::getSystemRandom();
};

//==============================================================================

class CustomWindow : public juce::DocumentWindow
{
CustomComponent c;

public:
CustomWindow()
{
addAndMakeVisible (c);
}

void resized() override
{
c.setBounds (getLocalBounds());
}

void paint (juce::Graphics& g, float frameRate) override
{
double time = juce::Time::getMillisecondCounterHiRes() / 1000.0;

auto renderer = g.getRenderer();
auto factory = g.getFactory();

rive::float2 p[9];
for (int i = 0; i < 9; ++i)
p[i] = pts[i] + translate;

rive::RawPath rawPath;
rawPath.moveTo (p[0].x, p[0].y);
rawPath.cubicTo (p[1].x, p[1].y, p[2].x, p[2].y, p[3].x, p[3].y);
rive::float2 c0 = rive::simd::mix (p[3], p[4], rive::float2 (2 / 3.f));
rive::float2 c1 = rive::simd::mix (p[5], p[4], rive::float2 (2 / 3.f));
rawPath.cubicTo (c0.x, c0.y, c1.x, c1.y, p[5].x, p[5].y);
rawPath.cubicTo (p[6].x, p[6].y, p[7].x, p[7].y, p[8].x, p[8].y);
if (doClose)
rawPath.close();

auto path = factory->makeRenderPath (rawPath, rive::FillRule::nonZero);

auto fillPaint = factory->makeRenderPaint();
fillPaint->style (rive::RenderPaintStyle::fill);
fillPaint->color (-1);

auto strokePaint = factory->makeRenderPaint();
strokePaint->style (rive::RenderPaintStyle::stroke);
strokePaint->color (0x8000ffff);
strokePaint->thickness (strokeWidth);
strokePaint->join (join);
strokePaint->cap (cap);

renderer->drawPath (path.get(), fillPaint.get());
renderer->drawPath (path.get(), strokePaint.get());

// Draw the interactive points.
auto pointPaint = factory->makeRenderPaint();
pointPaint->style (rive::RenderPaintStyle::stroke);
pointPaint->color (0xff0000ff);
pointPaint->thickness (14);
pointPaint->cap (rive::StrokeCap::round);

auto pointPath = factory->makeEmptyRenderPath();
for (int i : { 1, 2, 4, 6, 7 })
{
rive::float2 pt = pts[i] + translate;
pointPath->moveTo (pt.x, pt.y);
}

renderer->drawPath (pointPath.get(), pointPaint.get());

updateFrameTime (time);
updateWindowTitle();
}

void mouseDown (const juce::MouseEvent& event) override
Expand All @@ -47,7 +130,7 @@ class CustomWindow : public juce::DocumentWindow
dragIdx = -1;
for (int i = 0; i < kNumInteractivePts; ++i)
{
if (rive::simd::all (rive::simd::abs (dragLastPos - (pts[i] + translate)) < 100))
if (rive::simd::all (rive::simd::abs (dragLastPos - (pts[i] + translate)) < 20))
{
dragIdx = i;
break;
Expand Down Expand Up @@ -92,7 +175,6 @@ class CustomWindow : public juce::DocumentWindow
forceAtomicMode = !forceAtomicMode;
fpsLastTime = 0;
fpsFrames = 0;
resized();
break;

case juce::KeyPress::textDKey:
Expand Down Expand Up @@ -144,93 +226,28 @@ class CustomWindow : public juce::DocumentWindow
}
}

void resized() override
{
auto [width, height] = getContentSize();

updateWindowTitle (width, height);
}

void paint (juce::Graphics& g, float frameRate) override
{
double time = juce::Time::getMillisecondCounterHiRes() / 1000.0;
auto [width, height] = getContentSize();
auto renderer = g.getRenderer();

rive::float2 p[9];
for (int i = 0; i < 9; ++i)
p[i] = pts[i] + translate;

rive::RawPath rawPath;
rawPath.moveTo (p[0].x, p[0].y);
rawPath.cubicTo (p[1].x, p[1].y, p[2].x, p[2].y, p[3].x, p[3].y);
rive::float2 c0 = rive::simd::mix (p[3], p[4], rive::float2 (2 / 3.f));
rive::float2 c1 = rive::simd::mix (p[5], p[4], rive::float2 (2 / 3.f));
rawPath.cubicTo (c0.x, c0.y, c1.x, c1.y, p[5].x, p[5].y);
rawPath.cubicTo (p[6].x, p[6].y, p[7].x, p[7].y, p[8].x, p[8].y);
if (doClose)
rawPath.close();

rive::Factory* factory = g.getFactory();
auto path = factory->makeRenderPath (rawPath, rive::FillRule::nonZero);

auto fillPaint = factory->makeRenderPaint();
fillPaint->style (rive::RenderPaintStyle::fill);
fillPaint->color (-1);

auto strokePaint = factory->makeRenderPaint();
strokePaint->style (rive::RenderPaintStyle::stroke);
strokePaint->color (0x8000ffff);
strokePaint->thickness (strokeWidth);
strokePaint->join (join);
strokePaint->cap (cap);

renderer->drawPath (path.get(), fillPaint.get());
renderer->drawPath (path.get(), strokePaint.get());

// Draw the interactive points.
auto pointPaint = factory->makeRenderPaint();
pointPaint->style (rive::RenderPaintStyle::stroke);
pointPaint->color (0xff0000ff);
pointPaint->thickness (14);
pointPaint->cap (rive::StrokeCap::round);

auto pointPath = factory->makeEmptyRenderPath();
for (int i : { 1, 2, 4, 6, 7 })
{
rive::float2 pt = pts[i] + translate;
pointPath->moveTo (pt.x, pt.y);
}

renderer->drawPath (pointPath.get(), pointPaint.get());

updateFrameTime (time, width, height);
}

void userTriedToCloseWindow() override
{
juce::JUCEApplication::getInstance()->systemRequestedQuit();
}

private:
void updateWindowTitle(int width, int height)
void updateWindowTitle()
{
juce::String title;

if (currentFps != 0)
title << "[" << currentFps << " FPS]";
title << "[" << juce::String (currentFps, 1) << " FPS]";

title << " | " << "YUP On Rive Renderer";

if (forceAtomicMode)
title << " (atomic)";

title << " | " << width << " x " << height;

setTitle (title);
}

void updateFrameTime (double time, int width, int height)
void updateFrameTime (double time)
{
++fpsFrames;

Expand All @@ -239,7 +256,7 @@ class CustomWindow : public juce::DocumentWindow
{
currentFps = fpsLastTime == 0 ? 0 : fpsFrames / fpsElapsed;

updateWindowTitle (width, height);
updateWindowTitle ();

fpsFrames = 0;
fpsLastTime = time;
Expand Down
8 changes: 6 additions & 2 deletions examples/render/source/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ class CustomWindow : public juce::DocumentWindow
--downRepeat;
break;

case juce::KeyPress::textZKey:
setFullScreen (!isFullScreen());
break;

case juce::KeyPress::upKey:
{
float oldScale = scale;
Expand Down Expand Up @@ -312,7 +316,7 @@ class CustomWindow : public juce::DocumentWindow
juce::String title;

if (fps != 0)
title << "[" << fps << " FPS]";
title << "[" << juce::String (fps, 1) << " FPS]";

if (instances > 1)
title << " (x" << instances << " instances)";
Expand Down Expand Up @@ -393,7 +397,7 @@ struct Application : juce::JUCEApplication
juce::Logger::outputDebugString ("Starting app " + commandLineParameters);

window = std::make_unique<CustomWindow>();
window->setSize ({ 1280, 866 });
window->centreWithSize ({ 1280, 866 });
window->setVisible (true);
}

Expand Down
144 changes: 144 additions & 0 deletions modules/yup_graphics/graphics/yup_Color.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/*
==============================================================================
This file is part of the YUP library.
Copyright (c) 2024 - kunitoki@gmail.com
YUP is an open source library subject to open-source licensing.
The code included in this file is provided under the terms of the ISC license
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
to use, copy, modify, and/or distribute this software for any purpose with or
without fee is hereby granted provided that the above copyright notice and
this permission notice appear in all copies.
YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/

namespace juce
{

//==============================================================================
class JUCE_API Color
{
public:
//==============================================================================
constexpr Color() noexcept = default;

constexpr Color (uint32 color) noexcept
: data (color)
{
}

constexpr Color (uint8 r, uint8 g, uint8 b) noexcept
: b (b)
, g (g)
, r (r)
, a (255)
{
}

constexpr Color (uint8 a, uint8 r, uint8 g, uint8 b) noexcept
: b (b)
, g (g)
, r (r)
, a (a)
{
}

//==============================================================================
constexpr uint32 getARGB() const noexcept
{
return data;
}

constexpr operator uint32() const noexcept
{
return data;
}

//==============================================================================
constexpr uint8 getAlpha() const noexcept
{
return a;
}

constexpr Color& setAlpha (uint8 alpha) noexcept
{
a = alpha;
return *this;
}

constexpr Color withAlpha (uint8 alpha) const noexcept
{
return Color (alpha, r, g, b);
}

//==============================================================================
constexpr uint8 getRed() const noexcept
{
return r;
}

constexpr Color& setRed (uint8 red) noexcept
{
r = red;
return *this;
}

constexpr Color withRed (uint8 red) const noexcept
{
return Color (a, red, g, b);
}

//==============================================================================
constexpr uint8 getGreen() const noexcept
{
return g;
}

constexpr Color& setGreen (uint8 green) noexcept
{
g = green;
return *this;
}

constexpr Color withGreen (uint8 green) const noexcept
{
return Color (a, r, green, b);
}

//==============================================================================
constexpr uint8 getBlue() const noexcept
{
return b;
}

constexpr Color& setBlue (uint8 blue) noexcept
{
b = blue;
return *this;
}

constexpr Color withBlue (uint8 blue) const noexcept
{
return Color (a, r, g, blue);
}

private:
union
{
struct
{
uint8 b, g, r, a;
};

uint32 data = 0xff000000;
};
};

} // namespace juce
Loading

0 comments on commit ce341b1

Please sign in to comment.