//nv12render.cpp
#include "nv12render.h"
#include <QOpenGLTexture>
#include <QDebug>
#include"debug.h"
#include"RKBaseFunc.h"
#include <sys/mman.h>
#if 1
void Nv12Render::initialize()
{
initializeOpenGLFunctions();
glClearColor(0.0f,0.0f,0.0f,1.0f);
glClear(GL_COLOR_BUFFER_BIT);
const char *vsrc = " \
attribute vec4 vertexIn; \
attribute vec4 textureIn; \
varying vec4 textureOut; \
void main(void) \
{ \
gl_Position = vertexIn; \
textureOut = textureIn; \
}";
//Hi3536的openGL ES2着色器必须要先设置精度
const char *fsrc = "\
precision mediump float; \
varying mediump vec4 textureOut; \
uniform sampler2D textureY; \
uniform sampler2D textureUV; \
void main(void) \
{\
vec3 yuv; \
vec3 rgb; \
yuv.x = texture2D(textureY, textureOut.st).r - 0.0625; \
yuv.y = texture2D(textureUV, textureOut.st).r - 0.5; \
yuv.z = texture2D(textureUV, textureOut.st).g - 0.5; \
rgb = mat3( 1, 1, 1, \
0, -0.39465, 2.03211, \
1.13983, -0.58060, 0) * yuv; \
gl_FragColor = vec4(rgb, 1); \
}";
program.addCacheableShaderFromSourceCode(QOpenGLShader::Vertex,vsrc);
program.addCacheableShaderFromSourceCode(QOpenGLShader::Fragment,fsrc);
program.link();
GLfloat points[]{
-1.0f, 1.0f,
1.0f, 1.0f,
1.0f, -1.0f,
-1.0f, -1.0f,
0.0f,0.0f,
1.0f,0.0f,
1.0f,1.0f,
0.0f,1.0f
};
vbo.create();
vbo.bind();
vbo.allocate(points,sizeof(points));
GLuint ids[2];
glGenTextures(2,ids);
idY = ids[0];
idUV = ids[1];
// 创建1个缓冲区
// glGenBuffers(1, &m_Buffer);
// glBindBuffer(GL_ARRAY_BUFFER, m_Buffer);
// glBufferData(GL_ARRAY_BUFFER, 1920*1088*3/2, NULL, GL_DYNAMIC_COPY);
// glBindBuffer(GL_ARRAY_BUFFER, 0);
#if 0
#if 1
m_pNV12Buffer = new unsigned char[1920*1088*3/2];
#else
#if 0
void* m_pFrameBuffer = CRKBaseFunc::RK_GetMPPBuffer(1920*1088*3/2);
//m_pNV12Buffer = (unsigned char*)CRKBaseFunc::RK_GetVideoBufferPtr(m_pFrameBuffer);
m_pNV12Buffer = (uint8_t *)mmap(0, 1920*1088*3/2, PROT_READ | PROT_WRITE, MAP_SHARED, CRKBaseFunc::RK_GetVideoBufferFd(m_pFrameBuffer), 0);
#else
m_pDrmMemCtrl = IDRMMemCtrl::Create();
RKDRM_MEM_INFO memInfo;
memset(&memInfo, 0, sizeof(RKDRM_MEM_INFO));
memInfo.nSize = 1920 * 1088 * 2;
m_pDrmMemCtrl->DRMAlloc(memInfo);
m_pNV12Buffer = (unsigned char*)memInfo.vitualPtr;
#endif
#endif
#endif
#if 1
m_pOpenglBuffer[0] = new QOpenGLBuffer(QOpenGLBuffer::PixelUnpackBuffer);
m_pOpenglBuffer[0]->create();
m_pOpenglBuffer[0]->bind();
m_pOpenglBuffer[0]->allocate(1920*1088);
m_pOpenglBuffer[0]->release();
m_pOpenglBuffer[1] = new QOpenGLBuffer(QOpenGLBuffer::PixelUnpackBuffer);
m_pOpenglBuffer[1]->create();
m_pOpenglBuffer[1]->bind();
m_pOpenglBuffer[1]->allocate(1920*1088/2);
m_pOpenglBuffer[1]->release();
#endif
}
#endif
void Nv12Render::render(uchar *nv12Ptr, int w, int h)
{
if(!nv12Ptr)return;
#if 0
memcpy(m_pNV12Buffer,nv12Ptr,1920*1088*3/2);
uchar* pNv12Data = m_pNV12Buffer;
// memset(pNv12Data,0,1920*1088*3/2);
#else
uchar* pNv12Data = nv12Ptr;
#endif
RAIITimer time123("Nv12Render::render");
// glClearColor(0.5f, 0.5f, 0.7f, 1.0f);
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// glDisable(GL_DEPTH_TEST);
program.bind();
vbo.bind();
program.enableAttributeArray("vertexIn");
program.enableAttributeArray("textureIn");
program.setAttributeBuffer("vertexIn",GL_FLOAT, 0, 2, 2*sizeof(GLfloat));
program.setAttributeBuffer("textureIn",GL_FLOAT,2 * 4 * sizeof(GLfloat),2,2*sizeof(GLfloat));
m_pOpenglBuffer[0]->bind();
void* buffer_data = m_pOpenglBuffer[0]->map(QOpenGLBuffer::ReadWrite);
memcpy(buffer_data,nv12Ptr,1920*1088);
m_pOpenglBuffer[0]->unmap();
glActiveTexture(GL_TEXTURE0 + 1); //测试发现使用"+ 0"会异常
glBindTexture(GL_TEXTURE_2D,idY);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// glTexImage2D(GL_TEXTURE_2D,0,GL_RED,w,h,0,GL_RED,GL_UNSIGNED_BYTE,pNv12Data);
glTexImage2D(GL_TEXTURE_2D,0,GL_RED,w,h,0,GL_RED,GL_UNSIGNED_BYTE,NULL);
m_pOpenglBuffer[1]->bind();
buffer_data = m_pOpenglBuffer[1]->map(QOpenGLBuffer::ReadWrite);
memcpy(buffer_data,nv12Ptr+1920*1088,1920*1088/2);
m_pOpenglBuffer[1]->unmap();
glActiveTexture(GL_TEXTURE0 + 0);
glBindTexture(GL_TEXTURE_2D,idUV);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// glTexImage2D(GL_TEXTURE_2D,0,GL_RG,w >> 1,h >> 1,0,GL_RG,GL_UNSIGNED_BYTE,pNv12Data + w*h);
glTexImage2D(GL_TEXTURE_2D,0,GL_RG,w >> 1,h >> 1,0,GL_RG,GL_UNSIGNED_BYTE,NULL);
program.setUniformValue("textureUV",0);
program.setUniformValue("textureY",1);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
m_pOpenglBuffer[0]->release();
m_pOpenglBuffer[1]->release();
program.disableAttributeArray("vertexIn");
program.disableAttributeArray("textureIn");
program.release();
}
qt pbo渲染方法
最新推荐文章于 2023-03-14 16:24:28 发布
该代码段展示了如何使用OpenGL ES在Hi3536平台上进行NV12纹理的渲染。首先,它初始化OpenGL环境,定义顶点和纹理坐标,编译和链接着色器。然后,通过内存映射或直接分配内存来处理NV12缓冲区。在渲染过程中,将NV12数据加载到OpenGL缓冲区,并创建及设置纹理,最后进行绘制操作。
摘要由CSDN通过智能技术生成