opengl — самый простой способ нарисовать скалярное и векторное поле с C ++?

Какой самый простой, хотя и прилично быстрый, способ нарисовать сетку (скажем, 100 х 100) скалярных значений в виде цветов и векторов в виде линий из массивов значений в C ++? Чистый OpenGL? Что-то вроде этого:

введите описание изображения здесь

Я планирую использовать либо базовый OpenGL или SDL. Эта программа для Windows будет демонстрацией в реальном времени (не статичным изображением) и должна быть способна обрабатывать пользовательский ввод (курсор). Я не думаю, что один OpenGL может обрабатывать ввод.

3

Решение

В OpenGL вы можете создать массив с плавающей точкой, который может быть представлен как растровое изображение

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

Чем вызывать функцию OpenGL

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

или используя glTexImage()

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

Но очень важно представлять данные с плавающей запятой в диапазоне [0; 1].

например, этот код рисует изображение 8×8

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();
}

результат будет

введите описание изображения здесь

Полученное изображение можно просто масштабировать, используя glPixelZoom или увеличен как результат фильтрации текстуры.

Вот пример загрузки текстуры.

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);

результат фильтрации.

введите описание изображения здесь

Здесь вы можете увидеть плавный переход цвета.

Есть и другие способы сделать это с помощью шейдеров.

Векторы могут быть нарисованы отдельно в виде одной линии с конусом на конце, а не с помощью аффинных преобразований.

Все это даст приемлемый уровень производительности для приложений реального времени и широкие возможности взаимодействия человек-машина, поскольку ОС будет обрабатывать любое окно OpenGL как собственное с поддержкой всех событий ОС.

1

Другие решения

SDL_FillRect а также SDL_RenderDrawLine достаточно быстры для этого.

1

По вопросам рекламы [email protected]