音视频

IOS FFmpeg零到自己的播放器2,OpenGL显示图片

2018-10-25  本文已影响0人  huisedediao

目标:用OpenGL ES展示一张图片。

本文Demo:https://github.com/huisedediao/OpenGLShowImg

基础概念:

基础内容看这个教程的第一篇和第二篇,作者大大写得非常详细:https://blog.csdn.net/column/details/opengl-es2-ios.html

这里主要补充下 创建纹理渲染纹理到屏幕 的过程

创建纹理

- (void)setupTexture
{
    //创建一个纹理对象
    glGenTextures(1, &_inputTexture);
    //绑定纹理对象(告诉openGL ES具体操作的是哪一个纹理对象)
    glBindTexture(GL_TEXTURE_2D, _inputTexture);
    
    //设置放大和缩小时像素是如何填充的(设置放大或者缩小时的过滤方式)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    
    //将s轴和t轴的坐标设置为GL_CLAMP_TO_EDGE类型,所有大于1的都设置为1,所有小于0的都设置为0
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    
    //将RGBA的数据放到上面创建的纹理对象上,这里最有一个参数传递是uint8_t数组类型的pixels,这里还没有渲染,传0
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)_frame->width, (GLsizei)_frame->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
    
    //解绑纹理
    glBindTexture(GL_TEXTURE_2D, 0);
}

渲染

- (void)render;
{
    if(_stopping){
        return;
    }

    if(self->_frame) {
        [self.openGLLock lock];
        if (!self.readyToRender || !self.shouldEnableOpenGL) {
            glFinish();
            [self.openGLLock unlock];
            return;
        }
        [self.openGLLock unlock];
        
        //绑定操作的上下文
        [EAGLContext setCurrentContext:self->_context];
        glBindFramebuffer(GL_FRAMEBUFFER, self->_displayFramebuffer);
        
        //规定窗口的大小
        glViewport(0, self->_backingHeight - self->_backingWidth - 75, self->_backingWidth, self->_backingWidth);
        //渲染数据
        [self renderFrame:self->_frame->pixels];
        
        glBindRenderbuffer(GL_RENDERBUFFER, self->_renderbuffer);
        
        //马上显示
        [self->_context presentRenderbuffer:GL_RENDERBUFFER];
    }
}

//这里渲染的是png解码后的数据
- (void)renderFrame:(uint8_t *)rgbaFrame;
{
    //使用显卡绘制程序
    glUseProgram(_filterProgram);
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
    glBindTexture(GL_TEXTURE_2D, _inputTexture);

    //将png解码后的数据装载到纹理上
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)_frame->width, (GLsizei)_frame->height,
                 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaFrame);
    
    static const GLfloat imageVertices[] = {
        -1.0f, -1.0f,
        1.0f, -1.0f,
        -1.0f,  1.0f,
        1.0f,  1.0f,
    };
    
    GLfloat noRotationTextureCoordinates[] = {
        0.0f, 1.0f,
        1.0f, 1.0f,
        0.0f, 0.0f,
        1.0f, 0.0f,
    };
    
    //设置物体坐标
    glVertexAttribPointer(_filterPositionAttribute, 2, GL_FLOAT, 0, 0, imageVertices);
    glEnableVertexAttribArray(_filterPositionAttribute);
    
    //设置纹理坐标
    glVertexAttribPointer(_filterTextureCoordinateAttribute, 2, GL_FLOAT, 0, 0, noRotationTextureCoordinates);
    glEnableVertexAttribArray(_filterTextureCoordinateAttribute);
    
    //指定将要绘制的纹理图像并且传递给对应的FragmentShader
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, _inputTexture);
    glUniform1i(_filterInputTextureUniform, 0);
    
    //执行绘制操作
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

觉得有收获的小伙伴,动动小手给个赞哦~

上一篇 下一篇

猜你喜欢

热点阅读