如何通过在GPU中实现顶点的计算,且渲染多个视频时,每个视频都要保持原始的宽高比绘制,且选中某个视频,能绘制出这个视频的边框
两个步骤
实现所有纹理保持宽高比绘制
- 多个视频纹理渲染,都使用同一个由1和-1组合成的VBO,通过在着色器中修改顶点坐标。
- 通过uniform变量在着色器中重新计算顶点坐标
// 当前纹理宽高比
float curAspect = curTexSize.width / curTexSize.height;
// 主纹理宽高比
float mainAspect = mainTexSize.width / mainTexSize.height;
if (!mainAspect || !curAspect) {
return;
}
Size aspectRatio = Size(1, 1);
// 处理主视频纹理、画中画视频纹理宽高比问题,保持每个视频资源的原始宽高比
if (curTexSize > mainAspect) {
aspectRatio.width = 1;
aspectRatio.height = mainAspect/curTexSize;
// 保持宽高比不变,用于计算四个顶点
m_size.height *= mainAspect/curTexSize;
} else {
aspectRatio.width = curTexSize/mainAspect;
aspectRatio.height = 1;
// 保持宽高比不变,用于计算四个顶点
m_size.width *= curTexSize/mainAspect;
}
/// 通过中心点和宽高计算四个顶点
/// - Parameter angle: 旋转角度值
void upRotate(float angle) {
m_rotate = angle;
// 计算旋转后的四个点
float cosA = cos(angle);
float sinA = sin(angle);
// 左上,左和上需要减
float x1 = cosA * (-m_size.width/2) - sinA * (-m_size.height/2) + m_center.x;
float y1 = sinA * (-m_size.width/2) + cosA * (-m_size.height/2) + m_center.y;
// 右上
float x2 = cosA * (m_size.width/2) - sinA * (-m_size.height/2) + m_center.x;
float y2 = sinA * (m_size.width/2) + cosA * (-m_size.height/2) + m_center.y;
// 右下
float x3 = (cosA * (m_size.width/2)) - sinA * (m_size.height/2) + m_center.x;
float y3 = (sinA * (m_size.width/2)) + cosA * (m_size.height/2) + m_center.y;
// 左下
float x4 = (cosA * (-m_size.width/2)) - sinA * (m_size.height/2) + m_center.x;
float y4 = (sinA * (-m_size.width/2)) + cosA * (m_size.height/2) + m_center.y;
Vertex2_4 vertexs = Vertex2_4({x1,y1, x2,y2, x3,y3, x4,y4});
}
着色器代码如下
attribute vec4 position;
attribute vec4 inputTextureCoordinate;
varying vec2 textureCoordinate;
uniform vec2 move;
uniform float scale;
uniform float rotate;
uniform vec2 viewAspectRatio;
mat4 getTransform() {
// 平移
mat4 translateMat = mat4(1.0);
translateMat[3] = vec4(move.x, move.y, 0.0, 1.0);
// 旋转
mat4 rotateMat = mat4(1.0);
float c = cos(rotate);
float s = sin(rotate);
rotateMat[0] = vec4(c, -s, 0.0, 0.0);
rotateMat[1] = vec4(s, c, 0.0, 0.0);
// 等比缩放
mat4 scaleMat = mat4(1.0);
scaleMat[0][0] = scale;
scaleMat[1][1] = scale;
// 保持宽高比
mat4 arMat = mat4(1.0);
arMat[0][0] = viewAspectRatio.x;
arMat[1][1] = viewAspectRatio.y;
return translateMat * rotateMat * scaleMat * arMat;
}
void main() {
mat4 transform = getTransform();
gl_Position = transform * position;
textureCoordinate = inputTextureCoordinate.xy;
}