zoukankan      html  css  js  c++  java
  • 第11月第14天 opengl yuv beginners-tutorials

    1.

    Here is some snippets of code from my project 'movie player for iOS'.

    1. fragment shader

    varying highp vec2 v_texcoord;  
    uniform sampler2D s_texture_y;  
    uniform sampler2D s_texture_u;  
    uniform sampler2D s_texture_v;   
    void main() {  
        highp float y = texture2D(s_texture_y, v_texcoord).r;  
        highp float u = texture2D(s_texture_u, v_texcoord).r - 0.5;  
        highp float v = texture2D(s_texture_v, v_texcoord).r - 0.5;  
        highp float r = y +             1.402 * v;  
        highp float g = y - 0.344 * u - 0.714 * v;  
        highp float b = y + 1.772 * u;  
        gl_FragColor = vec4(r,g,b,1.0);  
    }

    2. create textures from YUV420p frame

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);  
    glGenTextures(3, _textures);  
    const UInt8 *pixels[3] = { yuvFrame.luma.bytes, yuvFrame.chromaB.bytes, yuvFrame.chromaR.bytes };  
    const NSUInteger widths[3]  = { frameWidth, frameWidth / 2, frameWidth / 2 };  
    const NSUInteger heights[3] = { frameHeight, frameHeight / 2, frameHeight / 2 };  
    for (int i = 0; i < 3; ++i) {  
        glBindTexture(GL_TEXTURE_2D, _textures[i]);  
        glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, widths[i],heights[i],0,GL_LUMINANCE,GL_UNSIGNED_BYTE,pixels[i]);  
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);  
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);  
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);  
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);  
    }

    3. init vertices and texture coords

    static const GLfloat texCoords[] = { 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f };  
    static const GLfloat vertices[]= {-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f };

    4. render frame

    [EAGLContext setCurrentContext:_context];  
    glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer);  
    glViewport(0, 0, _backingWidth, _backingHeight);  
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);  
    glClear(GL_COLOR_BUFFER_BIT);  
    glUseProgram(_program);  
    for (int i = 0; i < 3; ++i) {  
        glActiveTexture(GL_TEXTURE0 + i);  
        glBindTexture(GL_TEXTURE_2D, _textures[i]);  
        glUniform1i(_uniformSamplers[i], i);  
    }  
    glVertexAttribPointer(ATTRIBUTE_VERTEX, 2, GL_FLOAT, 0, 0, vertices);  
    glEnableVertexAttribArray(ATTRIBUTE_VERTEX);  
    glVertexAttribPointer(ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, 0, 0, texCoords);  
    glEnableVertexAttribArray(ATTRIBUTE_TEXCOORD);  
    glBindRenderbuffer(GL_RENDERBUFFER, _renderbuffer);  
    [_context presentRenderbuffer:GL_RENDERBUFFER];

    The link to project on github.

    https://stackoverflow.com/questions/12428108/ios-how-to-draw-a-yuv-image-using-opengl

    补:

    1.

        /*
         The quad vertex data defines the region of 2D plane onto which we draw our pixel buffers.
         Vertex data formed using (-1,-1) and (1,1) as the bottom left and top right coordinates respectively, covers the entire screen.
         */
        GLfloat quadVertexData [] = {
            -1 * normalizedSamplingSize.width, -1 * normalizedSamplingSize.height,
                 normalizedSamplingSize.width, -1 * normalizedSamplingSize.height,
            -1 * normalizedSamplingSize.width, normalizedSamplingSize.height,
                 normalizedSamplingSize.width, normalizedSamplingSize.height,
        };
        
        // Update attribute values.
        glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, quadVertexData);
        glEnableVertexAttribArray(ATTRIB_VERTEX);
    
        /*
         The texture vertices are set up such that we flip the texture vertically. This is so that our top left origin buffers match OpenGL's bottom left texture coordinate system.
         */
        CGRect textureSamplingRect = CGRectMake(0, 0, 1, 1);
        GLfloat quadTextureData[] =  {
            CGRectGetMinX(textureSamplingRect), CGRectGetMaxY(textureSamplingRect),
            CGRectGetMaxX(textureSamplingRect), CGRectGetMaxY(textureSamplingRect),
            CGRectGetMinX(textureSamplingRect), CGRectGetMinY(textureSamplingRect),
            CGRectGetMaxX(textureSamplingRect), CGRectGetMinY(textureSamplingRect)
        };
        
        glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_FLOAT, 0, 0, quadTextureData);
        glEnableVertexAttribArray(ATTRIB_TEXCOORD);
        
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    quadVertexData 以屏幕中心点为坐标原点,左下、右下、左上这三个点画一个三角形,右下、左上、右上这三个点画一个三角形,合起来就是整个屏幕。如果改为{-0.5,-0.5,0.5,-0.5,-0.5,0.5,0.5,0.5}则以屏幕中心点为坐标原点画面缩小一倍。

    {
    -1,-1, //左下
    1,-1, //右下
    -1,1, //左上
    1,1 //右上
    }

    2.

    http://www.opengl-tutorial.org/cn/beginners-tutorials/tutorial-2-the-first-triangle/

  • 相关阅读:
    设计模式:Prototype 原型模式
    [C++STDlib基础]关于单字符的操作——C++标准库头文件<cctype>
    Android开发之简单的电子相册实现
    autotools入门笔记(二)——创建和使用静态库、动态库
    Dreamer 框架 比Struts2 更加灵活
    Redis集群明细文档
    【Servlet3.0新特性】第03节_文件上传
    POJ 3264 Balanced Lineup
    利用jquery对ajax操作,详解原理(附代码)
    C语言实现修改文本文件中的特定行
  • 原文地址:https://www.cnblogs.com/javastart/p/7357338.html
Copyright © 2011-2022 走看看