I’m having a tough time resolving some mouse lag when using the OpenGLRenderer to display a simple rectangle on the screen. I’m following the example in the juce demo for doing 2D drawing into the OGL context, and had these results:
Here’s basically what I’m doing:
struct ScrollingRect { int x; int y; int height; };
struct ScrollingComponent : public Component, public OpenGLRenderer, public Timer
{
OpenGLContext openGLContext;
ScrollingComponent();
void timerCallback() override; //this is the Timer callback
void renderOpenGL() override; //this is the OpenGL render callback
//a few MouseListener functions and mouseRect updaters go here.
ScopedPointer<ScrollingRect> mouseRect;
std::vector<ScrollingRect> rectsToRender;
};
ScrollingComponent::ScrollingComponent()
{
openGLContext.setRenderer(this);
openGLContext.attachTo(*this);
openGLContext.setSwapInterval(0); //as fast as possible
startTimerHz(100);
}
void ScrollingComponent::timerCallback()
{
openGLContext.triggerRepaint(); //tell the OS to render an openGL frame.
}
void ScrollingComponent::mouseEnter(const juce::MouseEvent &event)
{
mouseRect = new ScrollingRect();
updateMouseRect(event.getPosition());
}
void ScrollingComponent::mouseExit(const juce::MouseEvent &event)
{
mouseRect = nullptr;
}
void ScrollingComponent::mouseMove(const juce::MouseEvent &event)
{
updateMouseRect(event.getPosition()); //capture mouse position and update the rect to be drawn where the cursor is
}
void ScrollingComponent::updateMouseRect(const Point<int> &p)
{
lastMousePos = p;
if( mouseRect != nullptr )
{
mouseRect->x = p.getX();
mouseRect->y = p.getY();
mouseRect->height = getW( mouseRect->y );
}
}
void ScrollingComponent::mouseDown(const juce::MouseEvent &event)
{
addMouseRect(event);
}
void ScrollingComponent::addMouseRect(const juce::MouseEvent &e)
{
ScopedLock sl(updateLock);
auto y = e.getMouseDownY();
int w = getW( y );
w = jmax(w, 5); //at least 10 pix wide
for( auto& rect : rectsToRender )
{
rect.x -= w; //make room for the new one
}
rectsToRender.push_back( *mouseRect );
}
//this is the callback that draws the openGL
void ScrollingComponent::renderOpenGL()
{
// Create an OpenGLGraphicsContext that will draw into this GL window..
const float desktopScale = openGLContext.getRenderingScale();
ScopedPointer<LowLevelGraphicsContext> glRenderer (createOpenGLGraphicsContext (openGLContext,
roundToInt (desktopScale * getWidth()),
roundToInt (desktopScale * getHeight())));
if (glRenderer != nullptr) //got the LowLevelGraphicsContext
{
ScopedLock sl(updateLock);
Graphics g(*glRenderer); //create a graphics context wrapper we can use to draw into the LowLevelGraphicsContext
render(g, desktopScale); //draw into the context
}
}
void ScrollingComponent::render(juce::Graphics &g, float desktopScale)
{
g.fillAll(Colours::white);
g.addTransform(AffineTransform::identity.scaled(desktopScale));
//now you can do whatever you need to do the usual paint(g) way.
//draw some horizontal lines
g.setColour(Colours::black);
for( int i = 0; i < 20; ++i )
{
if( (i > 3 && i < 7) || (i > 10 && i < 14) )
{
g.drawHorizontalLine( getHeight() * i / 20.f, 0, getWidth());
}
}
for( auto it = rectsToRender.begin(); it != rectsToRender.end(); )
{
if( it->x + it->height < 0 ) //it's off screen, so remove it
{
it = rectsToRender.erase(it);
}
else
{
++it;
}
}
g.setColour(Colours::blue);
for( auto& rect : rectsToRender )
{
rect.x -= 1; //shift one pixel to the left
if( rect.x + rect.height > 0 )
{
g.drawRect(rect.x, rect.y, rect.height, rect.height); //draw it.
}
}
if( mouseRect != nullptr ) //draw a rect at the mouse cursor
{
g.drawRect( mouseRect->x, mouseRect->y, mouseRect->height, mouseRect->height );
}
}
any ideas to get that rectangle that’s following the mouse cursor to not lag?