Draw a straight line using OpenGL ES in iPhone?

2019-03-17 02:11发布

问题:

Finally i tried to draw a line using OpenGL ES framework in XCode 4.2 for iPhone simple game app.I studied something about GLKView and GLKViewController to draw a line in iPhone. Here is my sample code that was i tried in my project,

@synthesize context = _context;
@synthesize effect = _effect;

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];

    if (!self.context) {
        NSLog(@"Failed to create ES context");
    }


    GLKView *view = (GLKView *)self.view;
    view.context = self.context;
    view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
    [EAGLContext setCurrentContext:self.context];

    //[self setupGL];
}

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    NSLog(@"DrawInRect Method");

    [EAGLContext setCurrentContext:self.context];

    // This method is calling multiple times....

    glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


   const GLfloat line[] = 
   {
        -0.5f, -0.5f, //point A 
        0.5f, -0.5f, //point B  
   };
   glVertexPointer(2, GL_FLOAT, 0, line);
   glEnableClientState(GL_VERTEX_ARRAY);
   glDrawArrays(GL_LINES, 0, 2);
}

When i run the project only the gray color only appearing in the screen, the line not showing. And also the - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect delegate is calling infinite time. Please guide me where i am doing wrong. Why the line not appearing or drawing? Can you please help? Am trying this 2 days. Thanks in advance.

回答1:

I'm rather a student of OpenGL ES 2.0 right now myself. I recommend first starting a new project in Xcode with the "OpenGL Game" template Apple provides.

Among other things, the Apple template code will include creation of a GLKBaseEffect, which provides some Shader functionality that seems to be required in order to be able to draw with OpenGL ES 2.0. (Without the GLKBaseEffect, you would need to use GLSL. The template provides an example of both with and without explicit GLSL Shader code.)

The template creates a "setupGL" function, which I modified to look like this:

- (void)setupGL
{
    [EAGLContext setCurrentContext:self.context];

    self.effect = [[[GLKBaseEffect alloc] init] autorelease];

    // Let's color the line
    self.effect.useConstantColor = GL_TRUE;

    // Make the line a cyan color
    self.effect.constantColor = GLKVector4Make(
        0.0f, // Red
        1.0f, // Green
        1.0f, // Blue
        1.0f);// Alpha
}

I was able to get the line to draw by including a few more steps. It all involves sending data over to the GPU to be processed. Here's my glkView:drawInRect function:

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Prepare the effect for rendering 
    [self.effect prepareToDraw];

    const GLfloat line[] = 
    {
        -1.0f, -1.5f, //point A 
        1.5f, -1.0f, //point B  
    };

    // Create an handle for a buffer object array
    GLuint bufferObjectNameArray; 

    // Have OpenGL generate a buffer name and store it in the buffer object array 
    glGenBuffers(1, &bufferObjectNameArray); 

    // Bind the buffer object array to the GL_ARRAY_BUFFER target buffer  
    glBindBuffer(GL_ARRAY_BUFFER, bufferObjectNameArray); 

    // Send the line data over to the target buffer in GPU RAM
    glBufferData(
        GL_ARRAY_BUFFER,   // the target buffer 
        sizeof(line),      // the number of bytes to put into the buffer
        line,              // a pointer to the data being copied 
        GL_STATIC_DRAW);   // the usage pattern of the data 

    // Enable vertex data to be fed down the graphics pipeline to be drawn
    glEnableVertexAttribArray(GLKVertexAttribPosition); 

    // Specify how the GPU looks up the data 
    glVertexAttribPointer(
        GLKVertexAttribPosition, // the currently bound buffer holds the data 
        2,                       // number of coordinates per vertex 
        GL_FLOAT,                // the data type of each component 
        GL_FALSE,                // can the data be scaled 
        2*4,                     // how many bytes per vertex (2 floats per vertex)
        NULL);                   // offset to the first coordinate, in this case 0 

    glDrawArrays(GL_LINES, 0, 2); // render 

}

Btw, I've been going through Learning OpenGL ES for iOS by Erik Buck, which you can buy in "Rough Cut" form through O'Reilly (an early form of the book since it is not going to be fully published until the end of the year). The book has a fair number of typos at this stage and no pictures, but I've still found it quite useful. The source code for the book seems to be very far along, which you can grab at his blog. The author also wrote the excellent book Cocoa Design Patterns.