iOS에서 우선 OpenGL에서 삼각형을 그리려면

15814 단어 Objective-COpenGL
내용은 GLKit 헬로 OpenGL 삼각형을 써 보자 에 코멘트를 더한 것입니다.



기본적으로 다음과 같은 흐름이 됩니다.

정점 정보 → 정점 처리 (버텍스 셰이더) → 드로잉 → 면 처리 (단편 셰이더) → 최종 출력

이번에는 정점 처리도 면 처리도 실시하고 있지 않습니다.
  • 우선 한 화면 어플리케이션을 작성한다.
  • 대상에 OpenGLES.framework 및 GLKit.framework를 추가합니다.
  • 코드를 다음과 같이 편집하여 xib를 제거한다.

  • AppDelegate.m
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        // Override point for customization after application launch.
        self.viewController = [[ViewController alloc] initWithNibName:nil bundle:nil];
        self.window.rootViewController = self.viewController;
        [self.window makeKeyAndVisible];
        return YES;
    }
    
  • 그런 다음 ViewController.h를 다음과 같이 편집합니다.

  • ViewController.h
    #import <UIKit/UIKit.h>
    #import <GLKit/GLKit.h>
    
    // 自身はGLKViewControllerとなり、self.viewがGLKViewとなる。
    // GLKViewにはglkView:drawInRect:メッセージが自動的に刺さってくるので、
    // <GLKViewDelegate>としている。
    @interface ViewController : GLKViewController <GLKViewDelegate>
    {
        GLuint vertexBufferID;
    }
    @property (strong, nonatomic) GLKBaseEffect *baseEffect;
    
    @end
    
  • 그런 다음 ViewController.m을 다음과 같이 편집합니다.

  • ViewController.m
    #import "ViewController.h"
    
    #define BUFFER_OFFSET(i) ((char *)NULL + (i))
    
    @implementation ViewController
    @synthesize baseEffect;
    
    typedef struct {
        GLKVector3 position;
    } Vertex;
    
    // 三角の座標
    // verticesはvertex(頂点)の複数形
    static const Vertex vertices[] =
    {
        {{-0.5f, -0.5f,  0.0}},
        {{ 0.5f, -0.5f,  0.0}},
        {{-0.5f,  0.5f,  0.0}}
    };
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        GLKView *view = (GLKView*)self.view;
    
        // OpenGL ES2を指定
        view.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
    
        // set context
        [EAGLContext setCurrentContext:view.context];
    
        // 三角形に白を設定
        self.baseEffect = [[GLKBaseEffect alloc] init];
        self.baseEffect.useConstantColor = GL_TRUE;
        self.baseEffect.constantColor = GLKVector4Make(1.0f, 1.0f, 1.0f, 1.0f);
    
        // 透明部分(背景)を黒に
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    
        /*
         ここからあとはGPUに頂点情報(vertices)を送っている
         */
        // GPUに点の情報を
        // vertexBufferIDという頂点バッファ・オブジェクト・ポインタを作成する
        glGenBuffers(1, &vertexBufferID);
    
        // バッファオブジェクトを有効にします
        // 頂点バッファオブジェクトの場合, 第1引数target には GL_ARRAY_BUFFER を指定します
        glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
    
        // バッファオブジェクトのメモリを確保し, そこにデータを転送します
        // 第1引数にはglBindBuffer() と同じものを指定します
        // 第2引数sizeには確保するメモリのサイズを byte で指定します
        // 第3引数dataは転送元のデータの配列を指定します
        // 第4引数usageにはバッファオブジェクトのメモリの使われ方のヒントを指定します
        // STATIC: メモリには一度しか書き込まれないが, 何回も使われる
        // DRAW: メモリの内容はアプリケーションプログラムから書き込まれ, OpenGL による描画データとして使用される
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    }
    
    #pragma mark - GLKView delegate
    - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
    {
        [self.baseEffect prepareToDraw];
    
        // 画面クリア
        glClear(GL_COLOR_BUFFER_BIT);
    
        // 頂点情報の位置を、頂点処理の変数に指定する(これを用いて描画を行う)
        // Attributeは位置、色、テクスチャなどをひっくるめた「頂点の属性」
        //    typedef enum {     GLKVertexAttribPosition,
        //        GLKVertexAttribNormal,
        //        GLKVertexAttribColor,
        //        GLKVertexAttribTexCoord0,
        //        GLKVertexAttribTexCoord1,
        //    } GLKVertexAttrib;
        glEnableVertexAttribArray(GLKVertexAttribPosition);
    
        // 頂点情報の格納場所と書式を頂点処理に教える
        // (void)glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
        // index には attribute 変数に割り当てられた index を指定する(ここでは位置)
        // size はデータの1頂点あたりの要素の数で, 1〜4 を指定する。2次元座標なら 2。
        // type には格納されているデータの形式を指定する
        // normalized はノーマライズされているか否か
        // stride には格納されているデータの間隔を byte で指定する。
        // 0 を指定したときは, データは密に並んでいるとみなされる。
        // pointer はバッファの先頭から最初の属性へのバイトオフセット。
        glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(0));
    
        // 図形を描く
        // (void)glDrawArrays(GLenum mode, GLint first, GLsizei count);
        // mode には描画する基本図形の種類を指定する
        // first には描画するデータの, 格納場所の先頭からの位置を指定する
        // count には描画するデータの数を指定する
        glDrawArrays(GL_TRIANGLES, 0, 3);
    }
    
    - (void)viewDidUnload
    {
        [super viewDidUnload];
    
        // current contextのbufferを消す
        GLKView *view = (GLKView *)self.view;
        [EAGLContext setCurrentContext:view.context];
        if (0 != vertexBufferID) {
            glDeleteBuffers(1, &vertexBufferID);
        }
    
        // contextを消す
        view.context = nil;
        [EAGLContext setCurrentContext:nil];
    }
    
    
    @end
    


    블로그를하고 있습니다 : PAPA-tronix!

    좋은 웹페이지 즐겨찾기