OpenGL Coverflow

@vishvesh

Slow is a nonsense. What is the computer of your friend ? the graphic card (because OpenGL work a lot with graphic card). And slow ? in fullscreen or windowed (you can resize the window). Sorry but it irritates me :evil:

Tested here, extremely fast … both in the starting window size and in full screen (1280x1024) … on

  • Sony VAIO Laptop - Dual Core 1.7GHz - 2GB RAM - Windows Vista
  • Dell Precision T7400 - Xeon 2.33GHz - 2GB RAM - Windows XP Pro
    Both with NVIDIA graphic cards.

Will test on my Mac soon (under Leopard).

Regards,
Max

His machine runs windows xp service pack 3, 1 GB RAM. Not sure about the processor. Hopefully i will get it working by today evening. Didn’t get enough time yesterday.

No problem man. I just sad that the two only guys that have tested the idea can’t use it :?

Have a good day :wink:

Regards,
Max

It’s actually 3 guys, The third one is impressed but hasn’t posted. I would have tried things out but I have moved onto Linux for work, so don’t get to spend too much time on windows. It’s really impressive.

Have shown the links to guys working on android, even they are impressed. :slight_smile:

androïd ? don’t know this sci-fi movie ? a James Cameron production no :lol:

Look at that, this is the first test of UI for my first product coming before spring :

And the full UI for the editor part :

The footer band (player) is clearly inspired by Songbirds application. But I work now with a women that is The Girl for designing my application and my website !!!

All with the GREAT JUCE API forever and ever :lol:

Regards,
Max

Are you displaying a webbrowsercomponent in the first image?

Based on the second image, it looks like the player isn’t ready yet. But the controllers look good, it has got itunes kind of feel to it. :slight_smile:

I meant Android Mobile OS. The programmers I spoke to are working on implement a similar feature for Android.

Looks like I have got a bug for you.
http://i50.tinypic.com/2lnverm.jpg

Unfortunately I still haven’t been able to get it working.

Generating the bug.

  1. Launch the application
  2. Click the maximize button
  3. Click the minimize button
  4. Select the application from the task bar(which will bring it back to maximize state)
  5. Click the maximize button(which would bring it to it’s original size)
  6. Move the application around, You can see the projection on one of the two ends

Hé,hé … no man, this is just à Look’n’Feel on the Juce ScrollBar in a Viewport.

Yes, the inspiration is from a old version of http://getsongbird.com/

The “iTunes-like” button are full vectorial allowing the resize of the bottom zone (from my own StretchableLayout classes), this is a smart static functions to do that :

//==============================================================================
#ifndef __TRANSPORT_BUTTONS_H__
#define __TRANSPORT_BUTTONS_H__
//==============================================================================
#define DRAWABLE_BUTTON_NORMAL 0
#define DRAWABLE_BUTTON_OVER 1
#define DRAWABLE_BUTTON_DOWN 2
//==============================================================================
#define TRANSPORT_BUTTON_PLAY 0
#define TRANSPORT_BUTTON_PAUSE 1
#define TRANSPORT_BUTTON_STOP 2
#define TRANSPORT_BUTTON_PREVIOUS 3
#define TRANSPORT_BUTTON_NEXT 4
//==============================================================================
static DrawablePath* getTransportSymbol (const int symbol)
{
	DrawablePath* const drawable = new DrawablePath ();
	Path path;
	switch (symbol)
	{
		case TRANSPORT_BUTTON_PLAY:
			{
				path.addTriangle (0.0f, 0.0f, 1.0f, 0.5f, 0.0f, 1.0f);
				path.applyTransform(path.getTransformToScaleToFit(0.35f, 0.33f, 0.37f, 0.37f, true, Justification::centred));
			}
			break;

		case TRANSPORT_BUTTON_PAUSE:
			{
				path.addRectangle (0.0f, 0.0f, 0.33f, 1.0f);
				path.addRectangle (0.66f, 0.0f, 0.33f, 1.0f);
				path.applyTransform(path.getTransformToScaleToFit(0.33f, 0.33f, 0.37f, 0.37f, true, Justification::centred));
			}
			break;
			
		case TRANSPORT_BUTTON_STOP:
			{
				path.addRectangle (0.0f, 0.0f, 1.0f, 1.0f);
				path.applyTransform(path.getTransformToScaleToFit(0.0f, 0.0f, 1.0f, 1.0f, true, Justification::centred));
			}
			break;
			
		case TRANSPORT_BUTTON_PREVIOUS: 
			{
				path.addRectangle (0.0f, 0.0f, 0.2f, 1.0f);
				path.addTriangle (0.2f, 0.5f, 0.6f, 0.0f, 0.6f, 1.0f);
				path.addTriangle (0.6f, 0.5f, 1.0f, 0.0f, 1.0f, 1.0f);
				path.applyTransform(path.getTransformToScaleToFit(0.29f, 0.36f, 0.41f, 0.32f, true, Justification::centred));
			}
			break;
			
		case TRANSPORT_BUTTON_NEXT:
			{
				path.addTriangle (0.0f, 0.0f, 0.4f, 0.5f, 0.0f, 1.0f);
				path.addTriangle (0.4f, 0.0f, 0.8f, 0.5f, 0.4f, 1.0f);
				path.addRectangle (0.8f, 0.0f, 0.2f, 1.0f);
				path.applyTransform(path.getTransformToScaleToFit(0.29f, 0.36f, 0.41f, 0.32f, true, Justification::centred));
			}
			break;

		default:
			break;
	}
	drawable->setPath (path);
	//drawable->setOutline (1.0f, Colours::grey);
	drawable->setSolidFill (Colours::black);
	return drawable;
}
//==============================================================================
static DrawablePath* getGradientCircle (const float x, const float y, const float w, const float h,
										const Colour& c1, const Colour& c2, const bool radius)
{
	Path path;
	path.addEllipse (x, y, w, h);

	DrawablePath* const back = new DrawablePath ();
	back->setPath (path);

	if (radius)
	{
		ColourGradient grad (c2, x+(w/2), y+(h/2), c1, 0, 0, true);
		grad.addColour (0.56f, c2);
		back->setFillBrush (GradientBrush (grad));
	}
	else
		back->setFillBrush (GradientBrush (c1, x, y, c2, x, h, false));

	return back;
}
//==============================================================================
static DrawableComposite* getDrawableButton (const int type, const int mode)
{
	float x,y,w,h;
	float p,d;

	x = 0.00f;
	y = 0.00f;
	w = 1.00f;
	h = 1.00f;
	p = 0.025f;
	d = p * 2;

	Colour backc11, backc12, backc21, backc22;
	Colour frontc1, frontc2, gradic1, gradic2;

	if (mode == DRAWABLE_BUTTON_NORMAL)
	{
		backc11 = Colours::grey.withMultipliedAlpha (0.0f);
		backc12 = Colours::grey.withMultipliedAlpha (0.75f);
		backc21 = Colours::black.withMultipliedAlpha (0.25f);
		backc22 = Colours::black.withMultipliedAlpha (0.65f);

		frontc1 = Colour(252,252,252);
		frontc2 = Colour(210,210,210).darker (0.5f);

		gradic1 = Colours::white.withMultipliedAlpha (0.75f);
		gradic2 = Colours::white.withMultipliedAlpha (0.0f);
	}
	else
	if (mode == DRAWABLE_BUTTON_OVER)
	{
		backc11 = Colours::grey.withMultipliedAlpha (0.0f);
		backc12 = Colours::grey.withMultipliedAlpha (0.75f);
		backc21 = Colours::black.withMultipliedAlpha (0.25f);
		backc22 = Colours::black.withMultipliedAlpha (0.65f);

		frontc1 = Colour(252,252,252);
		frontc2 = Colour(210,210,210);

		gradic1 = Colours::white.withMultipliedAlpha (0.75f);
		gradic2 = Colours::white.withMultipliedAlpha (0.0f);
	}
	else
	{
		backc11 = Colours::grey.withMultipliedAlpha (0.0f);
		backc12 = Colours::grey.withMultipliedAlpha (0.75f);
		backc21 = Colours::black.withMultipliedAlpha (0.25f);
		backc22 = Colours::black.withMultipliedAlpha (0.65f);

		frontc1 = Colours::darkgrey; //Colour(0x00000000);
		frontc2 = Colours::grey; //Colour(0x00000000);

		gradic1 = Colours::black.withMultipliedAlpha (0.75f);
		gradic2 = Colours::white.withMultipliedAlpha (0.0f);
	}

	DrawableComposite* const composite = new DrawableComposite();

	composite->insertDrawable (getGradientCircle (x, y, w, h, backc11, backc12, false));
	composite->insertDrawable (getGradientCircle (x+p, y+p, w-d, h-d, backc21, backc22, false));
	composite->insertDrawable (getGradientCircle (x+p+p, y+p+p, w-d-d, h-d-d, frontc1, frontc2, false));
	composite->insertDrawable (getGradientCircle (x+p+p+(p/4), y+p+p+(p/4), w-d-d-(d/4), h-d-d-(d/4), gradic1, gradic2, true));
	composite->insertDrawable (getTransportSymbol (type));

	return composite;
}
//==============================================================================
static DrawableButton* getDrawableTransportButton (const int type, const String& buttonName)
{
	DrawableButton *const button = new DrawableButton (buttonName, DrawableButton::ButtonStyle::ImageFitted);
	DrawableComposite* normal = getDrawableButton (type, DRAWABLE_BUTTON_NORMAL);
	DrawableComposite* over = getDrawableButton (type, DRAWABLE_BUTTON_OVER);
	DrawableComposite* down = getDrawableButton (type, DRAWABLE_BUTTON_DOWN);
	button->setImages (normal, over, down);
	delete normal; delete over; delete down;
	return button;
}
//==============================================================================
#endif 
//==============================================================================

I know man, my previous answer is just a bad joke :lol:

Regards,
Max

Thanks Max, you’ve been posting some impressive stuff! Nice job on the UI!

[quote=“vishvesh”]Looks like I have got a bug for you.
http://i50.tinypic.com/2lnverm.jpg

Unfortunately I still haven’t been able to get it working.[/quote]

Yes, this is a strange problem ? Don’t have time to search why because i’ve a lot of development to do. But I think it’s a OpenGL initialization problem. Maybe i call some texture loading not in time. If someone read that and found solution, you can post here and will update the project with a correction patch.

Sorry for you man :frowning:

Regards,
Max

Yes jules :wink: Thanks a lot … If the boss say that’s nice, I’m proud!

Regards,
Max

Hi! Very nice idea and perfect examlpe. But I’ve found some strange behavioral on my PC, it’s a Asus G1S with Windows XP + SP3. So, when i ran your example, precompeled (i’ve try build CoverFlow myself, the same results) .exe, i’ve notice that the CPU useage reaches 50% (dual core - 1 CPU its a 100%)… And it is strange, that 50% usage when i do not touch the app, e.g. not moving a mouse or dragging images in the cover. During application manipulation, CPU usage goes down, then it is going to 0 and then with a few seconds of IDLE reaches 50% (100% for single CPU).
May be i’m doing something wrong? :frowning:

Bye…

@alimjan

Take a look at the thread part of CoverFlowContext :

//=============================================================================
void CoverFlowContext::start ()
{
	startThread (5);
}
//=============================================================================
void CoverFlowContext::run ()
{
	while (!threadShouldExit())
	{
		Thread::sleep (jlimit(10, 100, roundFloatToInt(_threadLatency-(_ticks-_moveTicks))));

		/* MessageManagerLock is absolutly needed here ! 
		   because we call repaint() */
		const MessageManagerLock mmLock (Thread::getCurrentThread());

		if (!mmLock.lockWasGained())
			return; // another thread is trying to kill us;

		_ticks = Time::getMillisecondCounterHiRes ();

		/* refresh the OpenGL context */
		repaint ();

		// Compute distance between current cover and selected
        double dx = _selected - _current;

		if (dx != 0 && (_ticks-_moveTicks) > EFFECT_SPEED)
		{
			// Move the current cursor
			if (jabs(dx) > 0.001) 
			{
				_current += dx / 15;
			} 
			else 
			{
				_current = _selected;
			}

			// Record last tick
			_moveTicks = Time::getMillisecondCounterHiRes ();
		}

		if (_animSelected > 0) 
		{
			if (_ticks - _ticksSelected > EFFECT_SPEED_SELECTED) 
			{
				_animSelected += 5;
               // is the end of animation ?
               if (_animSelected > 100) 
				   _animSelected = 0;
               _ticksSelected = Time::getMillisecondCounterHiRes ();
			}
		}
	}
}
//=============================================================================

That use a intensive UI repaint. Maybe my computers are very powerfull (I think not) and don’t see a problem with that ? Don’t know ?

Regards,
Max

Hm… Strange to me :frowning: When minimizing the app, it is true that CPU usge goes down to 0. But when it is active, e.g. window active? In my tests i’m using ProcessExplorer from sysinternals.com. ProcessExplorer placed in background, Coverflow is on the foregraound, so i’m able to see CPU usage when manipulatin the app. So, hm, i guess i’m wrong… By the way, it is 4 threads i’ve notice in the Coverflow. May be some one else post their results?
Thx.

Surely some Juce & OpenGL thread. What are their names ? The only one I start myself is simply called “CoverFlow” :

//=============================================================================
CoverFlowContext::CoverFlowContext ()
:	Thread (T("CoverFlow")),

Regards,
Max

Thanks for reply. Names? Not checked, right now i’m on the different machine and OS… I remember that is offset of the Thread “routine” (that thread that ate so much) begans with 0xf… I’ll try to check more closely. maxprod, i saw some of your post with empressive UI (LookAndFeel) is that your design(code)? Would you be so kind to post a source code, if that is possible ? Or may be some snapshots? Thank you a lot.

[quote=“maxprod”][quote=“vishvesh”]Looks like I have got a bug for you.
http://i50.tinypic.com/2lnverm.jpg

Unfortunately I still haven’t been able to get it working.[/quote]

Yes, this is a strange problem ? Don’t have time to search why because i’ve a lot of development to do. But I think it’s a OpenGL initialization problem. Maybe i call some texture loading not in time. If someone read that and found solution, you can post here and will update the project with a correction patch.

Sorry for you man :frowning:

Regards,
Max[/quote]

The posts are growing at exponential rate now!!!

I intend to install Visual Studio and get working on this issue.

Yes, all of the UI are from my current work. For now, I don’t have a clear LookAndFeel to publish, first because I use multiple short LookAndFeel for some parts of the UI, and second because this is the actual look of my app. As i’ve say, I’ve found a good graphist (because I don’t like my own work :)) to design with me. When the UI will be redesign, I will publish some of my old code. If you need something in particular, maybe I can help you, but not more for the time.

Hé,hé … vishvesh ! You’re the man !!!

Regards,
Max

Hi Max,

OK, I still don’t have a working app, but I may have a (little) clue.
If I resize the app, I (sometimes) see a quick flash of an album cover image (it’s very brief - much less than a frame’s worth) - Does this help at all?

Could it be that the white “background” is over writing the display or “always on top” or something? -

Hi Dub,

There’s no white background filled by my app. But I have had this thing during coding. Maybe you can add a little temporisator (few seconds) in the CoverFlowContext constructor (or CoverFlowOpenGL, that’s the same). I’m pretty sure that come because OpenGL is long to init on certain graphics cards.

Let me know,
Regards,
Max