zoukankan      html  css  js  c++  java
  • iphone CGBitmapContextCreate()函数解释

    http://blog.sina.com.cn/s/blog_3e50cef401019cd2.html

    CGContextRef CGBitmapContextCreate (

      void *data,

      size_t width,

      size_t height,

      size_t bitsPerComponent,

      size_t bytesPerRow,

      CGColorSpaceRef colorspace,

      CGBitmapInfo bitmapInfo

      );

     参数data指向绘图操作被渲染的内存区域,这个内存区域大小应该为(bytesPerRow*height)个字节。如果对绘制操作被渲染的内存区域并无特别的要求,那么可以传递NULL给参数date。

       参数width代表被渲染内存区域的宽度。

       参数height代表被渲染内存区域的高度。

       参数bitsPerComponent被渲染内存区域中组件在屏幕每个像素点上需要使用的bits位,举例来说,如果使用32-bit像素和RGB颜色格式,那么RGBA颜色格式中每个组件在屏幕每个像素点上需要使用的bits位就为32/4=8。

       参数bytesPerRow代表被渲染内存区域中每行所使用的bytes位数。

       参数colorspace用于被渲染内存区域的“位图上下文”。

       参数bitmapInfo指定被渲染内存区域的“视图”是否包含一个alpha(透视)通道以及每个像素相应的位置,除此之外还可以指定组件式是浮点值还是整数值。

    网络上抄的一份代码:

    @implementation GLView

    #import <UIKit/UIKit.h>

    #import <QuartzCore/QuartzCore.h>

    #import <OpenGLES/ES2/gl.h>

    #import <OpenGLES/ES2/glext.h>

    #import <OpenGLES/ES1/gl.h>

    #import <OpenGLES/ES1/glext.h>

    @interface GLView : UIView {

    @private

        CAEAGLLayer *_eaglLayer;

        EAGLContext *_context;

        GLuint  _colorRenderBuffer;

        

        GLuint _position;

        GLuint _color;

    }

    @end

    #import "GLView.h"

    @implementation GLView

    // 设置LAYER class, 想要显示OPENGL的内容, 你需要把它缺省的layer设置为一个特殊的layer.

    + (Class)layerClass

    {

        return [CAEAGLLayer class];

    }

    // 设置layer为不透明, 缺省的话,CALayer是透明的, 透明的层对性能负荷很打,特别是Opengl的层.

    - (void)setupLayer

    {

        _eaglLayer = (CAEAGLLayer *)self.layer;

        _eaglLayer.opaque = YES;

    }

    // 创建content, 无论你需要OPENGL 帮你做什么 都需要这个EAGLContext, EAGLContext管理所以通过

    // opengl进行的draw的信息.

    - (void)setupContext

    {

        EAGLRenderingAPI api = kEAGLRenderingAPIOpenGLES1;

        _context = [[EAGLContext alloc] initWithAPI:api];

        if (!_context)

        {

         }

        

        if (![EAGLContext setCurrentContext:_context])

        {

            NSLog(@"Failed to set current context");

        }

    }

    // 创建render buffer(渲染缓冲)

    // renderbuffer用于存放渲染过的图像

    // glGenRenderbuffers创建一个renderbuffer,返回一个用于标记renderbuffer的名字_colorRenderBuffer;

    // 调用glBindRenderbuffer,告诉OPengl 刚创建的对象是GL_RENDERBUFFER类型的对象

    // 最后再分配空间

    - (void)setupRenderBuffer

    {

        glGenRenderbuffers(1, &_colorRenderBuffer);

        glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderBuffer);

        

        

        [_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:_eaglLayer];

    }

    // 创建一个FrameBuffer,(帧缓冲区)

    // 

    - (void)setupFrameBuffer

    {

        GLuint frameBuffer;

        glGenFramebuffers(1, &frameBuffer);

        glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);

        

        // 把刚创建的render buffer 依附到frame buffer的GL_COLOR_ATTACHMENT0位置上

        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 

                                  GL_RENDERBUFFER, _colorRenderBuffer);

    }

    // 在和vertextes shader打交道前, 先清理屏幕 显示另一种颜色.

    - (void)render

    {

        

        const GLfloat squareVertices[] = {

            -0.5f, -0.5f, 

            0.5f,  -0.5f,

            -0.5f,  0.5f,

            0.5f,   0.5f,

        };

        纹理的坐标系 左下为(0, 0)点

        const GLshort squarTextureCoords[] = {

            0, 0, // top left

            0, 1,

            1, 0,

            1, 1

        };

        

        [EAGLContext setCurrentContext:context];

        

        glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);

        glViewport(0, 0, backingWidth, backingHeight);

    //    // 告诉OPENGL 我们工作在投影模式下

        glMatrixMode(GL_PROJECTION);

    //    // 重置所有状态, 比如旋转 移动等

        glLoadIdentity();

        

        glEnable(GL_TEXTURE_2D);

        

        glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f);

    glMatrixMode(GL_MODELVIEW);

        

     // 设置一个RGBA颜色, 接下来会用这个颜色来涂抹全屏

        glClearColor(0.5f, 0.5f, 0.5f, 1.0f);

        glClear(GL_COLOR_BUFFER_BIT);

        

        glVertexPointer(2, GL_FLOAT, 0, squareVertices);

        glEnableClientState(GL_VERTEX_ARRAY);

        

        glTexCoordPointer(2, GL_SHORT, 0, squarTextureCoords);

        glEnableClientState(GL_TEXTURE_COORD_ARRAY);

        

       // GL_TRIANGLE_STRIP 最开始的两个顶点除非,然后遍历每个顶点,这些顶点将使用前两个顶点一齐组成三角形

        // GL_TRIANGLE_FAN 跳过开始的2个顶点, 然后遍历每个顶点,然后将这些顶点与他们前一个,以及数组的第一个顶点一齐组成三角

        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

        

        glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);

        [context presentRenderbuffer:GL_RENDERBUFFER_OES];

    }

    void)loadTexture

    {

        // 这个imageRef并不包含图片的数据

    // 注意:

    // 加载的图片大小必须是2的N次方

        CGImageRef imageRef = [[UIImage imageNamed:@"tile_floor.png"] CGImage];

        size_t width = CGImageGetWidth(imageRef);

        size_t height = CGImageGetHeight(imageRef);

        

        // RGBA个数, 每个像素4个字节

        GLubyte *textureData = (GLubyte *)malloc(width * height *4);

        CGContextRef textrureContext = CGBitmapContextCreate(

                                                     textureData, 

                                                     width, 

                                                     height, 

                                                     8, // 每个通道8位

                                                     width * 4, 

                                                              CGImageGetColorSpace(imageRef), 

                                                              kCGImageAlphaPremultipliedLast);

        CGContextDrawImage(textrureContext, CGRectMake(0, 0, width, height), imageRef);

        

        // 只需要一张纹理

        glGenTextures(1, &_texture[0]);

        

        // 激活纹理 新建的纹理名字加载到当期的纹理单元中

        glBindTexture(GL_TEXTURE_2D, _texture[0]);

        

        // 发送纹理数据到OPENGL

        // target 基本上都是GL_TEXTURE_2D

        // level 纹理的详细程序, 0表示允许图片的全部细节,

        // internal_format 和format必须相同 

        // border 必须始终为0 OPENGL es 不支持纹理边界

        // type 像素类型 每个像素占4个字节(无符号整形)

        // pixels 实际的图片数据指针

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,GL_UNSIGNED_BYTE, textureData);

        

        // 在和缩小(远矩离)的的时候 我们会把纹理缩小.如何处理(GL_LINEAR 是平滑的, GLNEAREST是选择嘴临近的纹理像素)

        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        glEnable(GL_TEXTURE_2D);

        

        // 

        free(textureData);

        CGContextRelease(textrureContext);

    }

    - (id)initWithFrame:(CGRect)frame

    {

        self = [super initWithFrame:frame];

        if (self) {

            [self setupLayer];

            [self setupContext];

            [self setupRenderBuffer];

            [self setupFrameBuffer];

          [self loadTexture];

            [self render];

            

        }

        return self;

    }

    - (void)dealloc

    {

        [_context release];

        _context = nil;

        

        [super dealloc];

    }

    @end

  • 相关阅读:
    freeswitch录音功能
    jdk安装
    maven阿里云镜像
    idea安装
    idea新建maven项目
    tomcat安装
    idea新建maven web项目
    idea新建java项目
    webpack使用
    ACE 安装指南及示例
  • 原文地址:https://www.cnblogs.com/xuejinhui/p/4383705.html
Copyright © 2011-2022 走看看