3

What is the easiest, while being decently fast, way to draw a grid (say, 100 x 100) of scalar values as colors and vectors as lines from arrays of values in C++? Pure OpenGL? Something like this:

enter image description here

I am planning on using either basic OpenGL or SDL. This Windows program will be a real-time demonstration (not static image) and should be able to handle user (cursor) input. I do not think OpenGL alone can handle input.

qwr
  • 9,525
  • 5
  • 58
  • 102
  • 1
    Dont use c++ ... Is there a reason you need to? If its going to be quick and dirty use `python` with matplotlib, or matlab, or scilab? – Fantastic Mr Fox Nov 14 '15 at 00:07
  • @Ben I am doing some computationally intensive fluid modelling...though maybe numpy will work, I really do not think python is fast enough – qwr Nov 14 '15 at 00:09
  • OpenGL is quite inefficient when drawing lines. Just use GDI+. –  Nov 14 '15 at 00:11
  • C++ has no concept of graphics, drawing, etc. Yes there are libraries to do all those things, but you need to ask about those libraries, not just "c++". You haven't even said what platform you're on, what you want the output to do (is it a window? is it an image file?). – Adam Nov 14 '15 at 00:21
  • +1 on Python. Python is slow for numerical computation, but it's plenty fast for drawing a static image on screen. You also get ease of use and platform independence. – Adam Nov 14 '15 at 00:23
  • @Adam I have added some details – qwr Nov 14 '15 at 00:25
  • Do you're not asking how to draw an image, you're asking how to make a full-on GUI. I'll add "use javascript" to my answer. Alternatively you can use GLUT. If you read anything about creating a Windows GUI you'll quickly see why you're being steered away from C++. – Adam Nov 14 '15 at 00:47
  • @Adam I am clearly not trying to make a GUI, just get cursor position and click. – qwr Nov 14 '15 at 00:48
  • You're drawing a **G**raphic and having the **U**ser **I**nteract with it using the mouse. – Adam Nov 14 '15 at 00:59

2 Answers2

1

In OpenGL you can create the array of floats wich can be represents as bitmap image

float computations[10000][3] = {
  { 1, 0.5, 0.5 }, // ..... 100 elements in row
  //..............................
  // 100 rows
};

Than call OpenGL function

glDrawPixels(100 /*width*/, 100 /*height*/, GL_RGB, GL_FLOAT, computations);

or using glTexImage()

glTexImage(GL_TEXTURE_2D, 0, GL_RGB, 100 /*width*/, 100 /*height*/, GL_RGB, GL_FLOAT, computations);

But it is wery important to represent the the float data in the range of [0; 1].

for example this code draws 8x8 image

float pixels[64][3]= {
    { 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f },
    { 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f },
    { 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f },
    { 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f },
    { 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f },
    { 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f },
    { 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f },
    { 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f } };

void RenderScene(void)
{
    glClear(GL_COLOR_BUFFER_BIT);

    glRasterPos2i(0, 0);
    glDrawPixels(8, 8, GL_RGB, GL_FLOAT, pixels);

    glFlush();
}

the result will be

enter image description here

The result picture can be simply scaled using glPixelZoom or magnificated as texture filtration result.

here is example of texture loading.

glGenTextures(1, &g_nTexture);

glBindTexture(GL_TEXTURE_2D, g_nTexture);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 8, 8, 0, GL_RGB, GL_FLOAT, pixels);

glEnable(GL_TEXTURE_2D);

the result of filtering.

enter image description here

here you can see smooth color transition.

There are others ways to do that things with shaders.

Vectors may be drawn separately as single line with the cone on its end than positioned by affine transformations.

This all things will give acceptable level of performance for real time application and wide capabilities of human-machine interaction because OS will handle any OpenGL window as native with all OS events support.

Mykola
  • 3,343
  • 6
  • 23
  • 39
1

SDL_FillRect and SDL_RenderDrawLine are fast enough for this purpose.

qwr
  • 9,525
  • 5
  • 58
  • 102