小视频app源码Android OpenGL ES 实现传送带特效

小视频app源码Android OpenGL ES 实现传送带特效的相关代码
Android 相机出图是 YUV 格式的,这里为了拷贝处理方便,先使用 OpenCV 将 YUV 图像转换为 RGBA 格式,当然为了追求性能直接使用 YUV 格式的图像问题也不大。

 

cv::Mat mati420 = cv::Mat(pImage->height * 3 / 2, pImage->width, CV_8UC1, pImage->ppPlane[0]);
cv::Mat matRgba = cv::Mat(m_SrcImage.height, m_SrcImage.width, CV_8UC4, m_SrcImage.ppPlane[0]);
cv::cvtColor(mati420, matRgba, CV_YUV2RGBA_I420);

 

用到的着色器程序就是简单的贴图:

 

复制代码
#version 300 es
layout(location = 0) in vec4 a_position;
layout(location = 1) in vec2 a_texCoord;
uniform mat4 u_MVPMatrix;
out vec2 v_texCoord;
void main()
{
gl_Position = u_MVPMatrix * a_position;
v_texCoord = a_texCoord;
}

#version 300 es
precision mediump float;
in vec2 v_texCoord;
layout(location = 0) out vec4 outColor;
uniform sampler2D u_texture;

void main()
{
outColor = texture(u_texture, v_texCoord);
}
复制代码

 

传送带的核心就是图像拷贝操作:

 

复制代码
memcpy(m_RenderImage.ppPlane[0], m_SrcImage.ppPlane[0], m_RenderImage.width * m_RenderImage.height * 4 / 2); //左侧预览区域像素拷贝

int bannerHeight = m_RenderImage.height / 2 / m_bannerNum;//一个 banner 的高(小竖条)
int bannerPixelsBufSize = m_RenderImage.width * bannerHeight * 4;//一个 banner 占用的图像内存

uint8 *pBuf = m_RenderImage.ppPlane[0] + m_RenderImage.width * m_RenderImage.height * 4 / 2; //传送带分界线

//从最右侧的竖条图像区域开始拷贝图像
for (int i = m_bannerNum - 1; i >= 1; --i) {
memcpy(pBuf + i*bannerPixelsBufSize, pBuf + (i - 1)*bannerPixelsBufSize, bannerPixelsBufSize);
}

//将来源区域的像素拷贝到竖条图像区域 0
memcpy(pBuf, pBuf - bannerPixelsBufSize, bannerPixelsBufSize);
复制代码

 

渲染操作:

 

复制代码
glUseProgram (m_ProgramObj);

glBindVertexArray(m_VaoId);

glUniformMatrix4fv(m_MVPMatLoc, 1, GL_FALSE, &m_MVPMatrix[0][0]);

//图像拷贝,传送带拷贝
memcpy(m_RenderImage.ppPlane[0], m_SrcImage.ppPlane[0], m_RenderImage.width * m_RenderImage.height * 4 / 2);
int bannerHeight = m_RenderImage.height / 2 / m_bannerNum;
int bannerPixelsBufSize = m_RenderImage.width * bannerHeight * 4;

uint8 *pBuf = m_RenderImage.ppPlane[0] + m_RenderImage.width * m_RenderImage.height * 4 / 2; //传送带分界线

for (int i = m_bannerNum - 1; i >= 1; --i) {
memcpy(pBuf + i*bannerPixelsBufSize, pBuf + (i - 1)*bannerPixelsBufSize, bannerPixelsBufSize);
}
memcpy(pBuf, pBuf - bannerPixelsBufSize, bannerPixelsBufSize);

//更新纹理
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_TextureId);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_RenderImage.width, m_RenderImage.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_RenderImage.ppPlane[0]);
glBindTexture(GL_TEXTURE_2D, GL_NONE);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_TextureId);
GLUtils::setInt(m_ProgramObj, "u_texture", 0);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (const void *)0);
glBindVertexArray(GL_NONE);
复制代码

 

 

以上就是小视频app源码Android OpenGL ES 实现传送带特效的相关代码, 更多内容欢迎关注之后的文章

posted @   云豹科技-苏凌霄  阅读(337)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示