How to draw a Pie chart using Irrlicht's 2D drawing API

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
SSJ17Vegeta
Posts: 19
Joined: Thu Nov 13, 2008 9:11 am

How to draw a Pie chart using Irrlicht's 2D drawing API

Post by SSJ17Vegeta »

The question is in the title :)

I'm trying to draw a Pie chart using IVideoDrivers's draw2D****** methods. Apart from drawing the initial circle with draw2DPolygon, I'm stuck :-/
I see there are methods like drawLine which could be useful at some point, but no methods like drawCurve, beginFill, endFill.

Have you guys tried something similar ?

I would consider using a GLSL shader, but only as a last resort (being a total genuine pixel-shader n00b).
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: How to draw a Pie chart using Irrlicht's 2D drawing API

Post by hendu »

Use a charting library and pass it as a texture? Otherwise you'll need to create it using the primitives available.
SSJ17Vegeta
Posts: 19
Joined: Thu Nov 13, 2008 9:11 am

Re: How to draw a Pie chart using Irrlicht's 2D drawing API

Post by SSJ17Vegeta »

Hi,

I've done just that. I started using GD (widely used in PhP applications and C headers available). I'm just having trouble with "passing it as a texture". From your post, I figured I should do something like that :

Code: Select all

 
gdImage* img = gdImageCreateTrueColor(w, h);
// Code that builds the image
int size = 0;
void* imagePtr = gdImageGdPtr(img, &size);
video::IImage* tx = Environment->getVideoDriver()->createImageFromData(video::ECF_R8G8B8, core::dimension2du(w, h), imagePtr, false, false);
video::ITexture* txChart = Environment->getVideoDriver()->addTexture("__internalChart", tx);
 
The result texture is all scrambled. I've tried with all ECF_R***** settings, to no avail.

The only solution I could figure is writing the output of GD's work into a PNG (on disk) and loading it using a standard IVideoDriver::getTexture.

Code: Select all

 
FILE* fp = fopen(temporaryPath.c_str(), "wb");
gdImagePng(img, fp);
fclose(fp);
video::ITexture* myTexture = Environment->getVideoDriver()->getTexture(temporaryPath);
 
That's not *very* problematic per se (this code runs when I create a specific window inside my GUI), it's just that the approach seems... wrong.

I saw that GD provides a gdImagePngPtr() function that provides a pointer to PNG data. Since Irrlicht supports PNG through loading a file, I wondered if I could load it into a texture directly from a void*.
Last edited by SSJ17Vegeta on Mon May 09, 2016 9:44 am, edited 1 time in total.
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: How to draw a Pie chart using Irrlicht's 2D drawing API

Post by hendu »

You have a mistake somewhere. Maybe the dimensions don't match (100x100 is kinda small? You should pass the same w and h), maybe the color format doesn't. Look up gd's docs on what the format is.
SSJ17Vegeta
Posts: 19
Joined: Thu Nov 13, 2008 9:11 am

Re: How to draw a Pie chart using Irrlicht's 2D drawing API

Post by SSJ17Vegeta »

Sorry, I made a small mistake while copy-pasting/adapting the code for forum readability, but the code was alright (anyway, just edited it :) ).

Unfortunately, the width and height were among the first things I had checked. GD's documentation indicates that gdImageGdPtr() 's data output is raw pixel information stored in a void*.

Do you confirm that IVideoDriver::createImageFromData is the way to go ?
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: How to draw a Pie chart using Irrlicht's 2D drawing API

Post by hendu »

Yes, that is the correct function. You need to look up what "raw pixel information" means to them.
SSJ17Vegeta
Posts: 19
Joined: Thu Nov 13, 2008 9:11 am

Re: How to draw a Pie chart using Irrlicht's 2D drawing API

Post by SSJ17Vegeta »

Sorry to dig up such an old topic ^^ But I gave up on GD (couldn't load pixel data into a texture, portability issues, trying to reduce external dependencies, lib doesn't seem to be maintained anymore, little to no community, etc.). I was thinking of using OpenGL functions to draw the chart directly, since I don't plan on using DirectX as a backend and OpenGL is already a requirement :)

Since I never tried using OpenGL directly (until now, Irrlicht's functions were enough for my needs), I searched a bit and found that I could do it with calling gluPartialDisk() in a GLUQuadric.

A bit of context first : I'm coding it in a custom GUI element (my game relies heavily on it).

So in the draw() method we have :

Code: Select all

 
const u32 m_width = this->AbsoluteRect.getWidth();
const u32 m_height = this->AbsoluteRect.getHeight();
const vector2di topLeft = this->AbsoluteRect.UpperLeftCorner;
 
// Prepare OpenGL view settings
glViewport(topLeft.X, topLeft.Y, m_width, m_height);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho(-0.5*m_width, 0.5*m_width, -0.5*m_height, 0.5*m_height, -1.0f, 1.0f);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
 
glScaled(0.6f, 0.6f, 0.0f);
glTranslated(0.0, 0.0, 0.0);
GLUquadric* glQuadric = gluNewQuadric();
 
const u8 len = dataProvider.size();
for (u8 i = 0; i < len; ++i)
{
      // Set color for the current data slice being drawn.
      glColor3ub(dataProvider[i].color.getRed(), dataProvider[i].color.getGreen(), dataProvider[i].color.getBlue());
      const f32 theAngle = (MAX_ANGLE / this->total) * dataProvider[i].value;
      // Draw each portion of the pie chart
      gluPartialDisk(glQuadric,  0, m_width / 2, slicesPerSegment, 1, lastAngle, theAngle);
      lastAngle += theAngle;
}
gluDeleteQuadric(glQuadric);
 
In a pure OpenGL example app, this code (with a few modifications obviously) seems to work, but when I use it in my irrlicht GUI element, nothing shows up. I'm probably missing something (big). is it "safe" to make openGL calls in a GUIElement's draw() method ?

The GUI element is correctly positioned (calling driver->draw2DRectangle using its AbsoluteRect coordinates works fine). Also tried writing in a texture and save it to disk to see if anything was written on it, but the texture is blank (transparent).
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: How to draw a Pie chart using Irrlicht's 2D drawing API

Post by hendu »

It is not safe to do raw GL calls unless you know what you're doing. Irr caches GL state, among other issues.
SSJ17Vegeta
Posts: 19
Joined: Thu Nov 13, 2008 9:11 am

Re: How to draw a Pie chart using Irrlicht's 2D drawing API

Post by SSJ17Vegeta »

Is there any Irrlicht equivalent function then ? I'd be happy to use whatever the engine provides x)
Mel
Competition winner
Posts: 2292
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

Re: How to draw a Pie chart using Irrlicht's 2D drawing API

Post by Mel »

Try drawing it on your own, it isn't that hard to write pixels into a memory image, and Irrlicht provides you with enough drawing primitives to raster the texture later :)

A pie chart is a set of pixels in which each pie slice is a representation of a proportion with regard a whole. You may create an image of the resolution you need, and get its data to write directly into it, Using the math.h function atan2() may provide an easy way to get you back the angle in which each pixel is drawn relative to a given center and having the proportions stored in a list you may compare the angle to know the color you have to write. Then, each pixel is restricted to a maximum distance from the center (the radius of the pie chart) and that draws the pie chart. Then, convert that image into a texture, and draw it as any other 2D image :)

Pro: You've done it on your own! :)
Con: Ineficient if you want to do fancy effects ^^U
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
Ovan
Posts: 70
Joined: Thu Dec 18, 2008 12:41 am
Contact:

Re: How to draw a Pie chart using Irrlicht's 2D drawing API

Post by Ovan »

http://irrlicht-fr.org/viewtopic.php?pid=11698#p11698 maybe ?
but if I remember each part of the pie is not calculated in "circle" but slide over a box ...
you may just calculate the difference
Post Reply