羅大柚OpenGL ES教程系列LessonOne(Part 2):繪製一個五角星

五角星的各頂點座標如下圖所示:

 

五角星一共有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


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

祝大家打碼愉快

            --羅大柚

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

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章