3

私は完全にアイデアがありません。

私は OpenGL ES 2.0 プログラミング ガイド ブックを持っています。Apple のテンプレート OpenGL ES 2.0 コードを持っています。次のページをフォローしました: http://open.gl/drawing

単純な三角形を描画できないようです。何が間違っているのかわかりません。

注: Apple のテンプレート コードと同様に、GLKView のサブクラスである GameViewController.xib ファイルもあります。

私の頂点シェーダー:

attribute vec4 position;

void main()
{
    gl_Position = position;
}

私のフラグメントシェーダー:

void main()
{
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}

私の GameViewController ヘッダー ファイル:

#import <UIKit/UIKit.h>
#import <GLKit/GLKit.h>

@interface GameViewController : GLKViewController

@end

私の GameViewController 実装ファイル:

#import "GameViewController.h"

const GLfloat vertices[] =
{
    0.0f, 0.5f,
    -0.5f, -0.5f,
    0.5f, -0.5f
};

// Class extension to keep data private
@interface GameViewController()
{        
    // vertex buffer object
    GLuint vbo;

    // vertex array object
    GLuint vao;

    // shader program
    GLuint shaderProgram;
}

@property (strong, nonatomic) EAGLContext *context;
@property (strong, nonatomic) GLKBaseEffect *effect;

@end

@implementation GameViewController

// setup our OpenGL context
-(void)viewDidLoad
{
    [super viewDidLoad];

    [self setupContext];

    // -------------------------------------------------------------
    // create a vertex array object that will hold
    // all the linking between attributes and vertex data
    // -------------------------------------------------------------
    [self createVertexArrayObject];

    [self createVertexBufferObject];

    [self loadShaders];

    [self checkErrors];
}

-(void)checkErrors
{
    GLenum error = glGetError();

    switch (error) {
        case GL_NO_ERROR:
            NSLog(@"No errors");
            break;
        case GL_INVALID_ENUM:
            NSLog(@"An unacceptable value is specified for an enumerated argument. The offending command is ignored and has no other side effect than to set the error flag.");
            break;
        case GL_INVALID_VALUE:
            NSLog(@"A numeric argument is out of range. The offending command is ignored and has no other side effect than to set the error flag.");
            break;
        case GL_INVALID_OPERATION:
            NSLog(@"The specified operation is not allowed in the current state. The offending command is ignored and has no other side effect than to set the error flag.");
            break;
        case GL_INVALID_FRAMEBUFFER_OPERATION:
            NSLog(@"The frameBuffer object is not complete. The offending command is ignored and has no other side effect than to set the error flag.");
            break;
        case GL_OUT_OF_MEMORY:
            NSLog(@"There is not enough memory left to execute the command. The state of the GL is undefined, except for the state of the error flags, after this error is recorded.");
            break;
        case GL_STACK_UNDERFLOW:
            NSLog(@"An attempt has been made to perform an operation that would cause an internal stack to underflow.");
            break;
        case GL_STACK_OVERFLOW:
            NSLog(@"An attempt has been made to perform an operation that would cause an internal stack to overflow.");
            break;
        default:
            break;
    }
}

#pragma mark - Setup Context -

-(void)setupContext
{
    self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];

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

    // tell our view the context is an OpenGL context
    GLKView *view = (GLKView *)self.view;
    view.context = self.context;
    view.drawableDepthFormat = GLKViewDrawableDepthFormat24;

    [EAGLContext setCurrentContext:self.context];

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

    glEnable(GL_DEPTH_TEST);
}

#pragma mark - Vertex Array Object Methods -

-(void)createVertexArrayObject
{
    glGenVertexArraysOES(1, &vao);
    glBindVertexArrayOES(vao);
}

#pragma mark - Create Vertex Buffer Object Method -

-(void)createVertexBufferObject;
{
    glGenBuffers(1, &vbo); // Generate 1 memory buffer for the VBO

    // Make our VBO the current buffer object to receive data
    glBindBuffer(GL_ARRAY_BUFFER, vbo);

    // -------------------------------------------------------------
    // Start copying data to our VBO
    //
    // GL_STATIC_DRAW will upload once and drawn many times
    // -------------------------------------------------------------
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

}

#pragma mark - Shader Code -

-(void)loadShaders
{
    // load both vertex shader and fragment shader
    GLuint vertexShader = [self compileVertexShader];
    GLuint fragmentShader = [self compileFragmentShader];

    // create a shader program from the vertex shader and fragment shader
    shaderProgram = [self combineVertexShader:vertexShader AndFragmentShader:fragmentShader];

    // linking vertex data and attributes
    GLint positionAttrib = glGetAttribLocation(shaderProgram, "position");

    glVertexAttribPointer(positionAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);

    glEnableVertexAttribArray(positionAttrib);
}

-(GLuint)compileVertexShader
{
    // get the path to the shader file as a C string
    const GLchar *vertexShaderPath = (GLchar *)[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]
                                                                          encoding:NSUTF8StringEncoding
                                                                             error:nil] UTF8String];

    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderPath, NULL);
    glCompileShader(vertexShader);

    // Checking if shader compiled properly
    GLint status;
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status);

    if(status == GL_TRUE)
    {
        NSLog(@"Vertex shader compiled correctly");
    }
    else
    {
        NSLog(@"Vertex shader compiled failed");
    }

    GLint logLength;
    glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &logLength);
    if (logLength > 0) {
        GLchar *log = (GLchar *)malloc(logLength);
        glGetShaderInfoLog(vertexShader, logLength, &logLength, log);
        NSLog(@"Vertex Shader compile log:\n%s", log);
        free(log);
    }

    return vertexShader;
}

-(GLuint)compileFragmentShader
{
    // get the path to the shader as a C string
    const GLchar *fragmentShaderPath = (GLchar *)[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]
                                                                          encoding:NSUTF8StringEncoding
                                                                             error:nil] UTF8String];

    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderPath, NULL);
    glCompileShader(fragmentShader);

    // Checking if shader compiled properly
    GLint status;
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &status);

    if(status == GL_TRUE)
    {
        NSLog(@"Fragment shader compiled correctly");
    }
    else
    {
        NSLog(@"Fragment shader compiled failed");
    }

    GLint logLength;
    glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &logLength);
    if (logLength > 0) {
        GLchar *log = (GLchar *)malloc(logLength);
        glGetShaderInfoLog(fragmentShader, logLength, &logLength, log);
        NSLog(@"Fragment Shader compile log:\n%s", log);
        free(log);
    }

    return fragmentShader;
}

-(void)linkProgram:(GLuint)paramShaderProgram
{
    // link shader to program now and become active shader program
    glLinkProgram(paramShaderProgram);

    GLint status;
    // test if the program linked correctly
    glGetProgramiv(paramShaderProgram, GL_LINK_STATUS, &status);

    if(status == GL_TRUE)
    {
        NSLog(@"Shader program linked correctly");
    }
    else
    {
        NSLog(@"Shader program linked failed");
    }
}

-(void)validateProgram:(GLuint)paramShaderProgram
{
    GLint status, logLength;

    glValidateProgram(paramShaderProgram);

    glGetProgramiv(paramShaderProgram, GL_VALIDATE_STATUS, &status);

    if(status == GL_TRUE)
    {
        NSLog(@"Shader program validated correctly");
    }
    else
    {
        NSLog(@"Shader program validate failed");
    }

    glGetProgramiv(paramShaderProgram, GL_INFO_LOG_LENGTH, &logLength);

    if(logLength > 0)
    {
        GLchar *log = (GLchar *)malloc(logLength);
        glGetProgramInfoLog(paramShaderProgram, logLength, &logLength, log);
        NSLog(@"Program validate log:\n%s", log);
        free(log);
    }
}

-(GLuint)combineVertexShader:(GLuint)paramVertexShader AndFragmentShader:(GLuint)paramFragmentShader
{
    GLuint newShaderProgram = glCreateProgram();

    glAttachShader(newShaderProgram, paramVertexShader);
    glAttachShader(newShaderProgram, paramFragmentShader);

    [self linkProgram:newShaderProgram];

    [self validateProgram:newShaderProgram];

    // start using shader now, will use the active shader program
    glUseProgram(newShaderProgram);

    return newShaderProgram;
}

#pragma mark - GLKViewController Render Delegate Methods -

-(void)setupViewport
{
    glViewport(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);

    self.effect.transform.projectionMatrix = GLKMatrix4MakeOrtho(-3, 3, -2, 2, 1, -1);
}

-(void)update
{
    [self setupViewport];
}

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

    [self.effect prepareToDraw];

    glDrawArrays(GL_TRIANGLES, 0, 3);
}

#pragma mark - Cleanup Memory -

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

    // delete vertex buffer object and vertex array object
    glDeleteBuffers(1, &vbo);
    glDeleteVertexArraysOES(1, &vao);

    // delete shader program
    if(shaderProgram)
    {
        glDeleteProgram(shaderProgram);
        shaderProgram = 0;
    }

    // unset OpenGL context
    if ([EAGLContext currentContext] == self.context)
    {
        [EAGLContext setCurrentContext:nil];
    }

    self.context = nil;
}

-(void)dealloc
{
    [self tearDownContext];
}

-(void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];

    if([self isViewLoaded] && self.view.window == nil)
    {
        self.view = nil;

        [self tearDownContext];

        if([EAGLContext currentContext] == self.context)
        {
            [EAGLContext setCurrentContext:nil];
        }

        self.context = nil;
    }

    // Dispose of any resources that can be recreated
}

@end

表示されるのは、色をクリアした灰色の背景画面だけです。

誰かが私が間違っていた場所を指摘できれば、それは素晴らしいことです.

編集

Ray のサイトに対する私の個人的な嫌悪感は脇に置いて、弾丸をかむことにしました。次のチュートリアルを実行しました。

http://www.raywenderlich.com/3664/opengl-es-2-0-for-iphone-tutorial

このチュートリアルでは、学習者が独自のフレーム バッファーとレンダー バッファーを作成し、それらを画面に表示するため、余分なボーナスである GLKit を使用しません。

これは GLKit を使用するよりも OpenGL ES 2.0 パイプラインに近いと思います。

Ricardo が示唆したように、現時点で GLKit を使用することは、その価値よりも理解するためのより多くの努力です。

また、Apple のテンプレート コードに従おうとするのではなく、上記の Ray の Web サイトのチュートリアル リンクを使用して、実際に動作するプログラムを作成することを強くお勧めします。

私の場合、Apple のテンプレート コードと本は矛盾が多すぎて、多くの時間を無駄にしました。

また、GLKit メソッドの使用にまだ興味がある人のために、GLKit を使用して解決しました。

解決策は、投影マトリックスの設定と、正しい頂点シェーダー位置属性の場所のバインドの組み合わせでした。

また、私が指摘したい非常に重要な注意事項は次のとおりです。

ターゲットのコピー バンドル リソースに頂点シェーダーとフラグメント シェーダーがあることを確認してください!

三角形が黒色になった時点で、フラグメント シェーダー ファイルに何を入力しても、三角形の色を変更できませんでした。問題は、これらのシェーダー ファイルがデフォルトでバンドル リソースにコピーされないことでした。

とにかく、私の作業中の更新されたコードは以下に完全に提供されています:

#import "GameViewController.h"

#define BUFFER_OFFSET(i) ((char *)NULL + (i))

// Uniform index.
enum
{
    UNIFORM_MODELVIEWPROJECTION_MATRIX,
    UNIFORM_NORMAL_MATRIX,
    NUM_UNIFORMS
};
GLint uniforms[NUM_UNIFORMS];

// Attribute index.
enum
{
    ATTRIB_VERTEX,
    ATTRIB_NORMAL,
    NUM_ATTRIBUTES
};


const GLfloat vertices[] =
{
    0.0f, 0.5f,
    -0.5f, -0.5f,
    0.5f, -0.5f
};

// Class extension to keep data private
@interface GameViewController()
{
    // vertex buffer object
    GLuint vbo;

    // vertex array object
    GLuint vao;

    // shader program
    GLuint shaderProgram;

    GLKMatrix4 modelViewProjectionMatrix;
    GLKMatrix3 normalMatrix;
}

@property (strong, nonatomic) EAGLContext *context;
@property (strong, nonatomic) GLKBaseEffect *effect;

@end

@implementation GameViewController

// setup our OpenGL context
-(void)viewDidLoad
{
    [super viewDidLoad];

    [self setupContext];

    [self loadShaders];

    // -------------------------------------------------------------
    // create a vertex array object that will hold
    // all the linking between attributes and vertex data
    // -------------------------------------------------------------
    [self createVertexArrayObject];

    [self createVertexBufferObject];

    [self linkAttributes];

    [self checkErrors];
}

-(void)checkErrors
{
    GLenum error = glGetError();

    switch (error) {
        case GL_NO_ERROR:
            NSLog(@"No errors");
            break;
        case GL_INVALID_ENUM:
            NSLog(@"An unacceptable value is specified for an enumerated argument. The offending command is ignored and has no other side effect than to set the error flag.");
            break;
        case GL_INVALID_VALUE:
            NSLog(@"A numeric argument is out of range. The offending command is ignored and has no other side effect than to set the error flag.");
            break;
        case GL_INVALID_OPERATION:
            NSLog(@"The specified operation is not allowed in the current state. The offending command is ignored and has no other side effect than to set the error flag.");
            break;
        case GL_INVALID_FRAMEBUFFER_OPERATION:
            NSLog(@"The frameBuffer object is not complete. The offending command is ignored and has no other side effect than to set the error flag.");
            break;
        case GL_OUT_OF_MEMORY:
            NSLog(@"There is not enough memory left to execute the command. The state of the GL is undefined, except for the state of the error flags, after this error is recorded.");
            break;
        case GL_STACK_UNDERFLOW:
            NSLog(@"An attempt has been made to perform an operation that would cause an internal stack to underflow.");
            break;
        case GL_STACK_OVERFLOW:
            NSLog(@"An attempt has been made to perform an operation that would cause an internal stack to overflow.");
            break;
        default:
            break;
    }
}

#pragma mark - Setup Context -

-(void)setupContext
{
    self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];

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

    // tell our view the context is an OpenGL context
    GLKView *view = (GLKView *)self.view;
    view.context = self.context;
    view.drawableDepthFormat = GLKViewDrawableDepthFormat24;

    [EAGLContext setCurrentContext:self.context];

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

    //glEnable(GL_DEPTH_TEST);
}

#pragma mark - Vertex Array Object Methods -

-(void)createVertexArrayObject
{
    glGenVertexArraysOES(1, &vao);
    glBindVertexArrayOES(vao);
}

#pragma mark - Create Vertex Buffer Object Method -

-(void)createVertexBufferObject;
{
    glGenBuffers(1, &vbo); // Generate 1 memory buffer for the VBO

    // Make our VBO the current buffer object to receive data
    glBindBuffer(GL_ARRAY_BUFFER, vbo);

    // -------------------------------------------------------------
    // Start copying data to our VBO
    //
    // GL_STATIC_DRAW will upload once and drawn many times
    // -------------------------------------------------------------
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
}

-(void)linkAttributes
{
    /*
    // linking vertex data and attributes
    GLint positionAttrib = glGetAttribLocation(shaderProgram, "position");
    glVertexAttribPointer(positionAttrib, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
    glEnableVertexAttribArray(positionAttrib);
    */

    glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
    glEnableVertexAttribArray(GLKVertexAttribPosition);

    glBindVertexArrayOES(0);
}

#pragma mark - Shader Code -

-(void)loadShaders
{
    shaderProgram = glCreateProgram();

    // load both vertex shader and fragment shader
    GLuint vertexShader = [self compileVertexShader];
    GLuint fragmentShader = [self compileFragmentShader];

    // create a shader program from the vertex shader and fragment shader
    [self combineVertexShader:vertexShader AndFragmentShader:fragmentShader];

    [self linkProgram:shaderProgram];


    // Release vertex and fragment shaders.
    if (vertexShader) {
        glDetachShader(shaderProgram, vertexShader);
        glDeleteShader(vertexShader);
    }
    if (fragmentShader) {
        glDetachShader(shaderProgram, fragmentShader);
        glDeleteShader(fragmentShader);
    }

    //NSLog(@"uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] before = %d", uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX]);

    uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(shaderProgram, "modelViewProjectionMatrix");

    //NSLog(@"uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] after = %d", uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX]);
}

-(GLuint)compileVertexShader
{
    // get the path to the shader file as a C string
    const GLchar *vertexShaderPath = (GLchar *)[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]
                                                                          encoding:NSUTF8StringEncoding
                                                                             error:nil] UTF8String];

    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderPath, NULL);
    glCompileShader(vertexShader);

    // Checking if shader compiled properly
    GLint status;
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status);

    if(status == GL_TRUE)
    {
        NSLog(@"Vertex shader compiled correctly");
    }
    else
    {
        NSLog(@"Vertex shader compiled failed");
    }

    GLint logLength;
    glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &logLength);
    if (logLength > 0) {
        GLchar *log = (GLchar *)malloc(logLength);
        glGetShaderInfoLog(vertexShader, logLength, &logLength, log);
        NSLog(@"Vertex Shader compile log:\n%s", log);
        free(log);
    }

    return vertexShader;
}

-(GLuint)compileFragmentShader
{
    // get the path to the shader as a C string
    const GLchar *fragmentShaderPath = (GLchar *)[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]
                                                                            encoding:NSUTF8StringEncoding
                                                                               error:nil] UTF8String];

    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderPath, NULL);
    glCompileShader(fragmentShader);

    // Checking if shader compiled properly
    GLint status;
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &status);

    if(status == GL_TRUE)
    {
        NSLog(@"Fragment shader compiled correctly");
    }
    else
    {
        NSLog(@"Fragment shader compiled failed");
    }

    GLint logLength;
    glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &logLength);
    if (logLength > 0) {
        GLchar *log = (GLchar *)malloc(logLength);
        glGetShaderInfoLog(fragmentShader, logLength, &logLength, log);
        NSLog(@"Fragment Shader compile log:\n%s", log);
        free(log);
    }

    return fragmentShader;
}

-(void)combineVertexShader:(GLuint)paramVertexShader AndFragmentShader:(GLuint)paramFragmentShader
{
    glAttachShader(shaderProgram, paramVertexShader);
    glAttachShader(shaderProgram, paramFragmentShader);

    glBindAttribLocation(shaderProgram, GLKVertexAttribPosition, "position");

    //[self validateProgram:shaderProgram];
}

-(void)linkProgram:(GLuint)paramShaderProgram
{
    // link shader to program now and become active shader program
    glLinkProgram(paramShaderProgram);

    GLint status;
    // test if the program linked correctly
    glGetProgramiv(paramShaderProgram, GL_LINK_STATUS, &status);

    if(status == GL_TRUE)
    {
        NSLog(@"Shader program linked correctly");
    }
    else
    {
        NSLog(@"Shader program linked failed");
    }

    GLint logLength;
    glGetProgramiv(shaderProgram, GL_INFO_LOG_LENGTH, &logLength);
    if (logLength > 0) {
        GLchar *log = (GLchar *)malloc(logLength);
        glGetProgramInfoLog(shaderProgram, logLength, &logLength, log);
        NSLog(@"Program link log:\n%s", log);
        free(log);
    }
}

-(void)validateProgram:(GLuint)paramShaderProgram
{
    GLint status, logLength;

    glValidateProgram(paramShaderProgram);

    glGetProgramiv(paramShaderProgram, GL_VALIDATE_STATUS, &status);

    if(status == GL_TRUE)
    {
        NSLog(@"Shader program validated correctly");
    }
    else
    {
        NSLog(@"Shader program validate failed");
    }

    glGetProgramiv(paramShaderProgram, GL_INFO_LOG_LENGTH, &logLength);

    if(logLength > 0)
    {
        GLchar *log = (GLchar *)malloc(logLength);
        glGetProgramInfoLog(paramShaderProgram, logLength, &logLength, log);
        NSLog(@"Program validate log:\n%s", log);
        free(log);
    }
}

#pragma mark - GLKViewController Render Delegate Methods -

-(void)setupViewport
{
    //float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);

    //GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 1.0f, -10.0f);
    GLKMatrix4 projectionMatrix = GLKMatrix4MakeOrtho(-1, 1, -1, 1, 1, -1);
    self.effect.transform.projectionMatrix = projectionMatrix;

    GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 0.0f);
    self.effect.transform.modelviewMatrix = modelViewMatrix;

    modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
    normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);

    glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, GL_FALSE, modelViewProjectionMatrix.m);
    glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, normalMatrix.m);
}

-(void)update
{
    [self setupViewport];
}

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

    glBindVertexArrayOES(vao);

    [self.effect prepareToDraw];

    glUseProgram(shaderProgram);

    glDrawArrays(GL_TRIANGLES, 0, 3);
}

#pragma mark - Cleanup Memory -

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

    // delete vertex buffer object and vertex array object
    glDeleteBuffers(1, &vbo);
    glDeleteVertexArraysOES(1, &vao);

    // delete shader program
    if(shaderProgram)
    {
        glDeleteProgram(shaderProgram);
        shaderProgram = 0;
    }

    // unset OpenGL context
    if ([EAGLContext currentContext] == self.context)
    {
        [EAGLContext setCurrentContext:nil];
    }

    self.context = nil;
}

-(void)dealloc
{
    [self tearDownContext];
}

-(void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];

    if([self isViewLoaded] && self.view.window == nil)
    {
        self.view = nil;

        [self tearDownContext];

        if([EAGLContext currentContext] == self.context)
        {
            [EAGLContext setCurrentContext:nil];
        }

        self.context = nil;
    }

    // Dispose of any resources that can be recreated
}

@end

それが他のみんなに役立つことを願っています。

4

1 に答える 1

2

Apple の OpenGL ES 2.0 テンプレート コードのことは忘れてください。あなたが初心者の場合、適切に理解するにはあまりにも多くのことが行われており、OpenGL ES 1.1 (GLKBaseEffect) と 2.0 (シェーダー) が混在しています。

アプリをゼロから作成し、GLKit とシェーダーの長所と短所を理解する方がよいでしょう。

このチュートリアルでは、GLKBaseEffect の固定パイプライン機能を使用して GLKit を紹介します。

さらに詳しい知識が必要で、iPhone 環境でシェーダーを使用する方法を学びたい場合は、次の本を強くお勧めします。

最終的には、GLKView を組み合わせてすべてのバッファー ボイラープレート コードをバイパスし、シェーダーを組み合わせてプログラムを最適に制御する必要があります。OpenGL ES の学習曲線は困難ですが、最初のこぶを乗り越えれば、物事はより明確になります。

于 2012-12-23T18:44:48.387 に答える