很久没更新博客了。额,一直想写这个来着。记得以前写过绘制三维标量场的文章,方法是找的渐变颜色纹理图片,然后用一维纹理坐标映射贴上去的。后面发现根本不需要去找图片,这种渐变色本来就是一种颜色空间的定义。请看hsv颜色模型,这种颜色模型类似于rgb,也是三个分量h(色调),s(饱和度),v(亮度)。h表示的绕圆锥的一周,也就是纯颜色的渐变,正是我们需要的东西。s表示从圆心到圆边缘的半径,0-1的范围,表示颜色纯度。v则是垂直的轴,表示亮度。如下图,我们要的就是绕圈一周的颜色渐变。
总体思路就是数值0-1,映射到hsv颜色空间的(0-360,1,255)。实现标量场的方法是,首先,将hsv的(0-360,1,255)转换为rgb,保存为一维数组。以该数组为数据,生成一维纹理,数值0-1作为纹理坐标,再贴图即可生成标量场。下面是用该方法生成标量场的相关代码。首先是构造一维纹理数组,然后用其生成1d纹理。
int CTexture::BuildColorMapTexture() { const int COLOR_SIZE = 240;//红到蓝 ImageRGBA colorMap(COLOR_SIZE, 1); for (int i = 0; i < COLOR_SIZE; ++i) { colorMap.pixel(i, 0) = Hsv2Rgb(i, 1, 255); } glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glGenTextures(1, &m;_uTexName); glBindTexture(GL_TEXTURE_1D, m_uTexName); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); //生成2d的Mipmap纹理 int nRet = gluBuild1DMipmaps(GL_TEXTURE_1D, 4, COLOR_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, colorMap.raw()); if (nRet != 0) { return 0; } return 1; }
hsv2rgb的代码如下,从网上可以随便找个修改。
PixelRGBA Hsv2Rgb(float H, float S, float V) { float R, G, B; int i; float f, p, q, t; if(S == 0) { // achromatic (grey) R = G = B = V; return V4B(R, G, B, 255); } H /= 60; // sector 0 to 5 i = floor( H ); f = H - i; // factorial part of h p = V * ( 1 - S ); q = V * ( 1 - S * f ); t = V * ( 1 - S * ( 1 - f ) ); switch( i ) { case 0: R = V; G = t; B = p; break; case 1: R = q; G = V; B = p; break; case 2: R = p; G = V; B = t; break; case 3: R = p; G = q; B = V; break; case 4: R = t; G = p; B = V; break; default: // case 5: R = V; G = p; B = q; break; } return V4B(R, G, B, 255); }
剩下的事情就是使用BuildColorMapTexture生成1d纹理,然后将数值作为1d纹理坐标设置好就行了。下面是相关的效果图:
颜色空间转换生成纹理:
渐变纹理贴图:
不同的方法效果有区别,原因可能是贴图的数据更精细,而且同一范围比如0-0.3对应的颜色就可能不一致。马上要毕业了,工作内容是游戏开发,以后估计不会再更新读研期间类似的文章的了。
您可能也喜欢: | ||||
使用GDI+加载多种格式的纹理 |
OpenGL如何使用长宽非2次方的纹理 |
纹理合成 |
OpenGL立即模式必须先指定纹理坐标 |
如何用OpenCV实现PCA降维 |
无觅 |