CGBitmapContextCreate()的使用方法

来源:互联网 发布:壁虎java 编辑:程序博客网 时间:2024/05/09 13:03

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 allocinitWithAPI: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 bufferGL_COLOR_ATTACHMENT0位置上

    glFramebufferRenderbuffer(GL_FRAMEBUFFERGL_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[] = {

        00// top left

        01,

        10,

        11

    };

    

    [EAGLContext setCurrentContext:context];

    

    glBindFramebufferOES(GL_FRAMEBUFFER_OESdefaultFramebuffer);

    glViewport(00backingWidthbackingHeight);

 

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

    glMatrixMode(GL_PROJECTION);

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

    glLoadIdentity();

    

    glEnable(GL_TEXTURE_2D);

    

    glOrthof(-1.0f1.0f, -1.5f1.5f, -1.0f1.0f);

glMatrixMode(GL_MODELVIEW);

    

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

    glClearColor(0.5f0.5f0.5f1.0f);

    glClear(GL_COLOR_BUFFER_BIT);

    

    glVertexPointer(2GL_FLOAT0, squareVertices);

    glEnableClientState(GL_VERTEX_ARRAY);

    

    glTexCoordPointer(2GL_SHORT0, squarTextureCoords);

    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    

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

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

    glDrawArrays(GL_TRIANGLE_STRIP04);

    

    glBindRenderbufferOES(GL_RENDERBUFFER_OEScolorRenderbuffer);

    [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(00, 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_2D0GL_RGBA, width, height, 0GL_RGBA,GL_UNSIGNED_BYTE, textureData);

    

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

    glTexParameterf(GL_TEXTURE_2DGL_TEXTURE_MIN_FILTERGL_LINEAR);

    glTexParameterf(GL_TEXTURE_2DGL_TEXTURE_MAG_FILTERGL_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

原创粉丝点击