Какой самый простой, хотя и прилично быстрый, способ нарисовать сетку (скажем, 100 х 100) скалярных значений в виде цветов и векторов в виде линий из массивов значений в C ++? Чистый OpenGL? Что-то вроде этого:
Я планирую использовать либо базовый OpenGL или SDL. Эта программа для Windows будет демонстрацией в реальном времени (не статичным изображением) и должна быть способна обрабатывать пользовательский ввод (курсор). Я не думаю, что один OpenGL может обрабатывать ввод.
В 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 как собственное с поддержкой всех событий ОС.
SDL_FillRect а также SDL_RenderDrawLine достаточно быстры для этого.