用 C++ 绘制标量和矢量场的最简单方法?
Easiest way to draw a scalar and vector field with C++?
用 C++ 中的值数组绘制标量值作为颜色和向量作为线的网格(例如 100 x 100)的最简单且速度相当快的方法是什么?纯 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].
例如此代码绘制 8x8 图像
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);
筛选结果。
在这里你可以看到平滑的颜色过渡。
还有其他方法可以用着色器做这些事情。
矢量可以单独绘制为单线,其末端是圆锥体,而不是通过仿射变换定位。
这一切都将为实时应用程序和广泛的人机交互能力提供可接受的性能水平,因为 OS 将处理任何 OpenGL window 作为所有 OS 的原生活动支持。
SDL_FillRect and SDL_RenderDrawLine 足够快了。
用 C++ 中的值数组绘制标量值作为颜色和向量作为线的网格(例如 100 x 100)的最简单且速度相当快的方法是什么?纯 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].
例如此代码绘制 8x8 图像
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);
筛选结果。
在这里你可以看到平滑的颜色过渡。
还有其他方法可以用着色器做这些事情。
矢量可以单独绘制为单线,其末端是圆锥体,而不是通过仿射变换定位。
这一切都将为实时应用程序和广泛的人机交互能力提供可接受的性能水平,因为 OS 将处理任何 OpenGL window 作为所有 OS 的原生活动支持。
SDL_FillRect and SDL_RenderDrawLine 足够快了。