主要使用的是OpenGL的离屏渲染技术
实现热力图主要有两个大步骤:
1.运用OpenGL提供的渲染到纹理技术,先绘制离散点
2.采用多纹理采样根据离散点透明度,来映射一个彩色渐进色带,达到热力图的效果
1.渲染到纹理
创建纹理帧缓冲步骤如下:
width,height 和你的屏幕分辨率有关,由于纹理支持的最大Size 每个设备不同(一般1024x1024)
一般width,height 取 1/2 或者 1/4的屏幕长宽(根据具体的大小来定不要超过最大size)
1.创建帧缓冲
GLuint fid;
glGenFramebuffers(1, &fid);
2.创建纹理
GLuint txId;
glGenTextures(1, &txId);
glBindTexture(GL_TEXTURE_2D, mId);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
3.将纹理附着在帧缓冲上
glBindFramebuffer(GL_FRAMEBUFFER, fId);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texId, 0);
4.绘制信息到纹理上
glBindFramebuffer(GL_FRAMEBUFFER, mId);//切换到附着纹理的帧缓冲
glViewPort(0,0,width,height);
glClearColor(0,0,0,0);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);//必须是这个 , 源颜色与目标颜色累加(叠加点的透明度)
//..
//绘制离散点(坐标+颜色0xff000000) GL_POINTS
//...
glBindFramebuffer(GL_FRAMEBUFFER, 0);
shader程序如下:
"attribute vec4 inVertex;\
attribute vec4 inColor;\
uniform mat4 uWorldMatrix;\
uniform float uPointSize;\
varying vec4 oColor;\
void main(void)\
{\
gl_Position = uWorldMatrix * inVertex;\
gl_PointSize = uPointSize ;\
oColor = inColor;\
}";
"precision mediump float;\
uniform float u_weight;\
varying vec4 oColor;\
void main(void)\
{\
float a = length(gl_PointCoord * 2.0 - vec2(1.0));\
vec4 temp = oColor;\
temp.a = (1.0 - a) * u_weight;\
gl_FragColor = temp;\
}";
2.渲染到屏幕
1.中已经完成了热力图的离散点绘制生成的纹理图片,接下来需要使用这个生成的纹理,来进行和渐进色带进行映射
shader如下:
attribute vec4 inVertex;\
attribute vec2 inTexCoord;\
uniform mat4 uWorldMatrix;\
varying vec2 oUv;\
void main(void)\
{\
gl_Position = uWorldMatrix * inVertex;\
oUv = inTexCoord;\
}";
"precision highp float;\
uniform sampler2D uTextureCrood0;\
uniform sampler2D uTextureCrood1;\
varying vec2 oUv;\
void main()\
{\
vec4 clr1 = texture2D(uTextureCrood0,oUv) ;\
vec4 clr2 = texture2D(uTextureCrood1,vec2(clr1.a,0.5)) ;\
gl_FragColor = clr2 * clr1.a;\
}";
由shader可以看出,需要两个纹理单元,uTextureCrood0就是1中生成的纹理单元
uTextureCrood1则是一个渐进色带纹理可以参考用下面
渲染到屏幕 这里就不贴代码了,顶点缓存就是以屏幕四个角点构建的顶点(坐标+纹理坐标)
然后采样上述的两张纹理(这里y坐标可能需要取反,具体根据你构建的世界矩阵有关)
最终的效果大致如下:
划重点:
实现流程中最重要的就是第一步,第二步就是一个简单贴图到整个屏幕(记得开alpha混合)
第一步主要是根据每个离散点的alpha值的叠加,然后在二中shader的多重纹理采样根据一中生成纹理的
的每个像素点alpha值映射渐进色带中的颜色