zoukankan      html  css  js  c++  java
  • windows下3D文字

    windows下3D文字


    简单概述

    需要在每一帧的视频图像上面添加3D文字,文字可以自由移动位置,变换各种字体属性,还能进行一些简单动画。然后把处理好的视频图像传个下一个步骤去处理。做的过程中参考了GitHub上的一个开源项目[1],这个项目有一点内存泄露,需要修改一下。我们的项目主要思路利用opengl+freetype实现,首先使用freetype生成文字的3d顶点,然后使用曲面细分[2],生成更细致的顶点数据,接着计算顶点的法线,便于后面光照计算。渲染过程,首先把视频图像纹理绘制,然后开启混合,画上3d文字,这些都离屏渲染到一个Framebuffer,使用glBlitFramebuffer转移到 draw Framebuffer上,最后使用glReadPixels读取渲染后的图像数据。


    一、文字与图像的融合

    开始是先绘制的图像纹理,然后切换shader program,开启混合:

    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);
    

    结果在vs和mingw环境下都是只有视频图像,没有文字,接着我改了一下先绘制文字后面绘制视频图像,开启这种混合:glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA);,在vs和mingw都可以显示正常了。目前还没搞清楚为什么前一种情况,文字没有融合进去。


    二、离屏渲染

    项目中很多过程都是在cpu里面实现的,所以我们需要把3d文字进行离屏渲染,然后从GPU里面读到内存,这会消耗一定的性能。因为文字的字体大小可变,当放大时候,如果不进行抗锯齿处理,文字会很难看。生成read framebuffer和draw framebuffer,绘制后读取图像数据。

    //生成两个fbo
    enum {color , depth, buffer_count};
    GLuint back_buffers[buffer_count];
    int msaa_level = 4;
    glGenFramebuffers(1, &m_backfbo);
    glBindFramebuffer(GL_FRAMEBUFFER, m_backfbo);
    glGenRenderbuffers(buffer_count, back_buffers);
    glBindRenderbuffer(GL_RENDERBUFFER, back_buffers[color]);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, m_canvasWidth, m_canvasHeight);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,back_buffers[color]);
    
    glBindRenderbuffer(GL_RENDERBUFFER, back_buffers[depth]);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_canvasWidth,m_canvasHeight);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, back_buffers[depth]);
    
    GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if (status != GL_FRAMEBUFFER_COMPLETE)
    	std::cout << "frame buffer status fail
    ";
    
    GLuint render_buffers[buffer_count];
    glGenFramebuffers(1, &m_renderfbo);
    glBindFramebuffer(GL_FRAMEBUFFER, m_renderfbo);
    glGenRenderbuffers(buffer_count, render_buffers);
    glBindRenderbuffer(GL_RENDERBUFFER, render_buffers[color]);
    glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa_level, GL_RGBA8, m_canvasWidth, m_canvasHeight);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, render_buffers[color]);
    glBindRenderbuffer(GL_RENDERBUFFER, render_buffers[depth]);
    glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa_level,
    	GL_DEPTH_COMPONENT24, m_canvasWidth, m_canvasHeight);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, render_buffers[depth]);
    
    status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if (status != GL_FRAMEBUFFER_COMPLETE)
    	std::cout << "frame buffer status fail
    ";
    //....after draw
    
    glBindFramebuffer(GL_READ_FRAMEBUFFER, m_renderfbo);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_backfbo);
    glBlitFramebuffer(0, 0, m_canvasWidth, m_canvasHeight, 0, 0, m_canvasWidth, m_canvasHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
    glBindFramebuffer(GL_FRAMEBUFFER, m_backfbo);
    glReadPixels(0, 0, m_canvasWidth, m_canvasHeight, GL_RGBA, GL_UNSIGNED_BYTE, offscreen_image); //get offscreen image
    

    最后效果如下:
    avatar


    1. https://github.com/Xiangwk/Text3D_with_OpenGL ↩︎

    2. http://www.songho.ca/opengl/gl_tessellation.html ↩︎

  • 相关阅读:
    多重共性和VIF检验
    类和对象
    哈希桶
    第9章 硬件抽象层:HAL
    第10章 嵌入式Linux的调试技术
    第8章 让开发板发出声音:蜂鸣器驱动
    第7章 LED将为我闪烁:控制发光二极管
    第6章 第一个Linux驱动程序:统计单词个数
    第5章 搭建S3C6410开发板的测试环境
    第四章:源代码的下载与编译
  • 原文地址:https://www.cnblogs.com/song-jw/p/9214499.html
Copyright © 2011-2022 走看看