qt pbo渲染方法

该代码段展示了如何使用OpenGL ES在Hi3536平台上进行NV12纹理的渲染。首先,它初始化OpenGL环境,定义顶点和纹理坐标,编译和链接着色器。然后,通过内存映射或直接分配内存来处理NV12缓冲区。在渲染过程中,将NV12数据加载到OpenGL缓冲区,并创建及设置纹理,最后进行绘制操作。
摘要由CSDN通过智能技术生成
//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();







}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sunxiaopengsun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值