罗大柚OpenGL ES教程系列LessonOne(Part 2):绘制一个五角星

五角星的各顶点坐标如下图所示:

罗大柚OpenGL ES教程系列LessonOne(Part 2):绘制一个五角星_第1张图片

 

五角星一共有10个顶点,各顶点的坐标在上图中已经标注,下面给出各顶点坐标计算公式:

     #define PI3.1415926

double L1=0.2*cos(36*PI/180);
doubleL2=0.2*sin(36*PI/180);
doubleL3=0.2*cos(72*PI/180);
doubleL4=0.2*sin(72*PI/180);
doubleL5=L2*tan(72*PI/180);
doubleL6=L2/cos(72*PI/180);
doubleL7=L6*sin(54*PI/180);
double L8=L6*cos(54*PI/180)+0.2;

 

我们通过上面各点的位置关系,得到下面所示的顶点数据,然后我们采用索引的方式来绘制这个五角星,

 

// Thisdata type is used to store information for each vertex

typedef struct {

    GLKVector3  positionCoords;

}Vertex;

 

//eachvertex coordinates and indexes of the pentacle

static constVertexvertices[] =

{

    {-0.307768, -0.423607, 0.0},

    {-0.190211, -0.061803, 0.0},

    {-0.497980, 0.161803, 0.0},

    {-0.117557, 0.161803, 0.0},

    {0.0,       0.523607, 0.0},

    {0.117557,  0.161803, 0.0},

    {0.497980,  0.161803, 0.0},

    {0.190211, -0.061803, 0.0},

    {0.307768, -0.423607, 0.0},

    {0.0,      -0.2,      0.0}

};

 

 

const GLubyte Indices[]= {

    9,0,1,

    1,2,3,

    3,4,5,

    5,6,7,

    7,8,9,

    9,1,5,

    5,7,9,

    1,3,5

};

 

接下来就是写ViewDidLoad方法了:
/////////////////////////////////////////////////////////////////

//Called when the view controller's view is loaded

//Perform initialization before the view is asked to draw

- (void)viewDidLoad

{

    [super viewDidLoad];

   

    // Verify the type of view createdautomatically by the

    // Interface Builder storyboard

    GLKView *view = (GLKView *)self.view;

    NSAssert([view isKindOfClass:[GLKView class]],

             @"View controller'sview is not a GLKView");

   

    // Create an OpenGL ES 2.0 context andprovide it to the

    // view

    view.context = [[EAGLContextalloc]

                    initWithAPI:kEAGLRenderingAPIOpenGLES2];

   

    // Make the new context current

    [EAGLContext setCurrentContext:view.context];

   

    // Create a base effect that providesstandard OpenGL ES 2.0

    // Shading Language programs and setconstants to be used for

    // all subsequent rendering

    self.baseEffect = [[GLKBaseEffectalloc] init];

    self.baseEffect.useConstantColor =GL_TRUE;

    self.baseEffect.constantColor =GLKVector4Make(

                                                  1.0f, // Red

                                                  0.0f, // Green

                                                  0.0f, // Blue

                                                  1.0f);// Alpha

   

   

    // Set the background color stored in the currentcontext

    glClearColor(0.5f, 0.5f, 0.5f, 1.0f);//background color

   

    // setup VBOs

    glGenBuffers(1,               // 

                 &vertexBufferID);

    glBindBuffer(GL_ARRAY_BUFFER// STEP 2

                 vertexBufferID);

    glBufferData(                 // STEP 3

                 GL_ARRAY_BUFFER// Initialize buffer contents

                 sizeof(vertices),//Number of bytes to copy

                 vertices,        // Address of bytes to copy

                 GL_STATIC_DRAW); //

   

   

    //索引

    glGenBuffers(1, &indexBufferID);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,indexBufferID);

    glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(Indices),Indices, GL_STATIC_DRAW);

         

}

 

GLKit提供了绘制OpenGL图形的代理方法:

#pragma mask Delegate Method

- (void)glkView:(GLKView *)viewdrawInRect:(CGRect)rect

{

   

    [self.baseEffectprepareToDraw];

   

    // Clear Frame Buffer (erase previous drawing)

    glClear(GL_COLOR_BUFFER_BIT);

   

    // Enable use of positions from bound vertexbuffer

    glEnableVertexAttribArray(     // STEP 4

                              GLKVertexAttribPosition);

   

    glVertexAttribPointer(         // STEP 5

                          GLKVertexAttribPosition,

                          3,                   // three components per vertex

                          GL_FLOAT,           // data is floating point

                          GL_FALSE,           // no fixed point scaling

                          sizeof(Vertex),// nogaps in data

                          NULL);              // NULL tells GPU to start at

    // beginning of bound buffer

   

      //利用index来绘制五角星

 glDrawElements(GL_TRIANGLES,sizeof(Indices)/sizeof(Indices[0]),

                   GL_UNSIGNED_BYTE, 0);

}

 

最后写一下ViewDidUnload方法,我们的任务就完成了:

/////////////////////////////////////////////////////////////////

// Called when the view controller's view hasbeen unloaded

// Perform clean-up that is possible when youknow the view

// controller's view won't be asked to drawagain soon.

- (void)viewDidUnload

{

    [super viewDidUnload];

   

    // Make the view's context current

    GLKView *view = (GLKView *)self.view;

    [EAGLContext setCurrentContext:view.context];

   

    // Delete buffers that aren't needed whenview is unloaded

    if (0 != vertexBufferID)

    {

       glDeleteBuffers (1,         // STEP 7

                         &vertexBufferID);

       vertexBufferID = 0;

    }

   

    // Stop using the context created in-viewDidLoad

    ((GLKView *)self.view).context =nil;

    [EAGLContext setCurrentContext:nil];

}

 

 很简单很方便吧,这可都是GLKBaseEffect的好处,我们不需要写shader也能创建各种图形,下一篇将介绍如何在GLKit框架下绘制一个立方体,我们会使用VBO VAO以及VAO索引三种方式来分别绘制,如果你对VA VBO VAO都不懂,那你就要去拜访你亲戚度娘或者谷哥了。同样的,我们附上本教程源码的下载地址:

http://download.csdn.net/detail/luozhonglan/6985799


*************************************************************************************************************************************************************************

祝大家打码愉快

            --罗大柚

**************************************************************************************************************************************************************************

 


你可能感兴趣的