[新手学IOS]第九天:使用OpenGL ES 绘图

一般来说,绘图目前有两种方式,一种是Quartz绘图,另一种就是强大的OpenGL绘图了.

昨天刚和老师敲定 毕设题目:"使用OpenGL 实现巷道的设计与实现".哎,真的很巧.不过我今天练习了这个项目之后,我终于明白了,这个OpenGL 可真是复杂啊.

好了,闲话先到这,我们就从Quartz绘图到OpenGL绘图吧.

1.OpenGL ES 绘图很大部分都是上节的文件,除了我们的绘图文件 替换成了 BIDGLFunView.相应的,我们也需要把我们 的view所控制的类改为这个.同时,我们也导入了四个关于OpenGL ES 的API.

OpenGLES2DView

和Texture2D.

2.下面是我们定义的BIDGLFunView 的绘图类,通过这个类,我们基本就明白了OpenGL的复杂了.

首先是.h文件,多声明了一个属性.


@property(nonatomic,strong)Texture2D *sprite;这个属性主要是定义Image的.在viewdidload中就会发现.


#import "OpenGLES2DView.h"
#import "BIDCOstants.h"

@class Texture2D;
@interface BIDGLFunView : OpenGLES2DView

@property CGPoint firstTouch;
@property CGPoint lastTouch;
@property (nonatomic,strong)UIColor *currentColor;

@property BOOL useRandomColor;
@property ShapeType shapeType;

@property(nonatomic,strong)Texture2D *sprite;

@end

下面看看.m文件

我们引入了API,然后看到了sprite的初始化了么 ?

#import "BIDGLFunView.h"
#import "Texture2D.h"
#import "UIColor+BIDRandom.h"

@implementation BIDGLFunView

@synthesize lastTouch,firstTouch,currentColor,useRandomColor,shapeType,sprite;



- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        //firstTouch.x = 0;
        
        
        // Initialization code
    }
    return self;
}

-(id)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super initWithCoder:aDecoder]) {
        self.currentColor = [UIColor redColor];
        useRandomColor = NO;
        sprite = [[Texture2D alloc]initWithImage:[UIImage imageNamed:@"screen.png"]];
        
        glBindTexture(GL_TEXTURE_2D, sprite.name);
        //http://blog.csdn.net/houdy/article/details/125234
    }

    return  self;
}

Texture Object的主要思想是用Texture Object来维护某些纹理状态,在渲染阶段将Texture Object和某个Texture Target(OpenGL维护三个Texture Target:GL_TEXTURE_1D,GL_TEXTURE_2D,GL_TEXTURE_3D)绑定,此过程就相当于将此Texture Object维护的纹理状态选入到OpenGL状态机中,这样此Texture Object维护的状态才会起作用。
Texture Object维护的某些纹理状态包括:
   Texture image(s); //纹理图案
   Texture Parameter; //由glTexParameter*()函数控制的参数
注意:其他的纹理相关的状态,如Texture Environment和Texture coordinate generation mode并不包含在Texture Objects中。
每个Texture Object的标识符是用一个unsigned int值来表示的,为了确保每个Texture Object的“名字“是唯一的,OpenGL提供了glGenTexture()函数。每个Texture Object在创建的时候,需要调用glBindTexture()将Texture Object和Texture Target(GL_TEXTURE_1D, GL_TEXTURE_2D)连接起来,在使用Texture Object阶段,仍然需要调用glBindTexture()来"激活"此Texture Object.下面用代码演示如何使用Texture Object:
1.创建一个Texture Object:
  GLuint uiTextureID;
  glGenTexture( 1, &uiTextureID ); //第一个参数指定表明获取多少个连续的纹理标识符
  glBindTexture( GL_TEXTURE_2D, uiTextureID ); //

完整的链接已经放在代码里了,你可以点击查看.

3.下面就主要看看draw方法,就了解了两种绘图方法的区别之大了.

- (void)draw  {
    glLoadIdentity();
    
    glClearColor(0.78f, 0.78f, 0.78f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    
    CGColorRef color = currentColor.CGColor;
    const CGFloat *components = CGColorGetComponents(color);
    CGFloat red = components[0];
    CGFloat green = components[1];
    CGFloat blue = components[2];
    
    glColor4f(red,green, blue, 1.0);
    switch (shapeType) {
        case kLineShape: {
            glDisable(GL_TEXTURE_2D);
            GLfloat vertices[4];
            
            // Convert coordinates
            vertices[0] = firstTouch.x;
            vertices[1] = self.frame.size.height - firstTouch.y;
            vertices[2] = lastTouch.x;
            vertices[3] = self.frame.size.height - lastTouch.y;
            glLineWidth(2.0);
            glVertexPointer(2, GL_FLOAT, 0, vertices);
            glDrawArrays (GL_LINES, 0, 2);
            break;
        }
        case kRectShape: {
            glDisable(GL_TEXTURE_2D);
            // Calculate bounding rect and store in vertices
            GLfloat vertices[8];
            GLfloat minX = (firstTouch.x > lastTouch.x) ?
            lastTouch.x : firstTouch.x;
            GLfloat minY = (self.frame.size.height - firstTouch.y >
                            self.frame.size.height - lastTouch.y) ?
            self.frame.size.height - lastTouch.y :
            self.frame.size.height - firstTouch.y;
            GLfloat maxX = (firstTouch.x > lastTouch.x) ?
            firstTouch.x : lastTouch.x;
            GLfloat maxY = (self.frame.size.height - firstTouch.y >
                            self.frame.size.height - lastTouch.y) ?
            self.frame.size.height - firstTouch.y :
            self.frame.size.height - lastTouch.y;
            
            vertices[0] = maxX;
            vertices[1] = maxY;
            vertices[2] = minX;
            vertices[3] = maxY;
            vertices[4] = minX;
            vertices[5] = minY;
            vertices[6] = maxX;
            vertices[7] = minY;
            
            glVertexPointer (2, GL_FLOAT , 0, vertices);
            glDrawArrays (GL_TRIANGLE_FAN, 0, 4);
            break;
        }
        case kEllipseShape: {
            glDisable(GL_TEXTURE_2D);
            GLfloat vertices[720];
            
            GLfloat xradius = fabsf((firstTouch.x - lastTouch.x) / 2);
            GLfloat yradius = fabsf((firstTouch.y - lastTouch.y) / 2);
            for (int i = 0; i <= 720; i += 2) {
                GLfloat xOffset = (firstTouch.x > lastTouch.x) ?
                lastTouch.x + xradius : firstTouch.x + xradius;
                GLfloat yOffset = (firstTouch.y < lastTouch.y) ?
                self.frame.size.height - lastTouch.y + yradius : 
                self.frame.size.height - firstTouch.y + yradius;
                vertices[i] = (cos(degreesToRadian(i / 2))*xradius) + xOffset;
                vertices[i+1] = (sin(degreesToRadian(i / 2))*yradius) +
                yOffset;
            }
            
            glVertexPointer(2, GL_FLOAT , 0, vertices);
            glDrawArrays (GL_TRIANGLE_FAN, 0, 360);
            break;
        }
        case kImageShape:
            glEnable(GL_TEXTURE_2D);
            [sprite drawAtPoint:CGPointMake(lastTouch.x,
                                            self.frame.size.height - lastTouch.y)];
            break;
        default:
            break;
    }
    
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
    [context presentRenderbuffer:GL_RENDERBUFFER_OES];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    if (useRandomColor)
        self.currentColor = [UIColor randomColor];
    
    UITouch* touch = [[event touchesForView:self] anyObject];
    firstTouch = [touch locationInView:self];
    lastTouch = [touch locationInView:self];
    [self draw];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    
    UITouch *touch = [touches anyObject];
    lastTouch = [touch locationInView:self];
    
    [self draw];
    
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    lastTouch = [touch locationInView:self];
    
    [self draw];
}


下面的就是关于touch的操作了.不多解释了.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值