OpenGL繪制一個三角形


應該建立一個vertex shader文件和一個pixel shader文件,分別命名為shader.vsh和shader.fsh。

shader.vsh:

 

attribute vec3 position;   //入參,主程序會將數值傳入
void main()
{
    gl_Position = vec4(position,1);  //頂點經過投影變換變換后的位置
}

 

shader.fsh:

void main()
{
    gl_FragColor = vec4(0.5,0.5,0.5,1);   //頂點的顏色
}

ViewController.m中的代碼如下:

//
//  ViewController.m
//  OpenGL學習Demo
//
//  Created by 孫建飛 on 16/7/9.
//  Copyright © 2016年 sjf. All rights reserved.
//

#import "ViewController.h"

#import <OpenGLES/ES3/gl.h>
#import <OpenGLES/ES3/glext.h>

@interface ViewController ()
{
    EAGLContext *context; //EAGLContent是蘋果在ios平台下實現的opengles渲染層,用於渲染結果在目標surface上的更新。
    GLuint program;//????????
    GLuint vertexID;
  //  GLvoid *vec;
    
}
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    //三點的坐標:
    GLKVector3 vec[3]={
        {0.5,0.5,0},
        {-0.5,-0.5,0},
        {0.5,-0.5,0},
        
    };
    //初始化EAGLContext時指定ES版本號OPenGLES3
    context=[[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES3];
    if (!context) {
        NSLog(@"failed to create ES context !")
        ;
    }
    //
    GLKView *view=(GLKView *)self.view;
    view.context=context;
    view.drawableDepthFormat=GLKViewDrawableDepthFormat24;
    [EAGLContext setCurrentContext:context];
    glEnable(GL_DEPTH_TEST);//開啟深度測試,就是讓離你近的物體可以遮擋離你遠的物體
    glClearColor(0.1, 0.2, 0.3, 1); //設置surface的清除顏色,也就是渲染到屏幕上的背景色。
    //
    [self loadShaders];
    glEnable(GL_DEPTH_TEST);
    glClearColor(0.1, 0.2, 0.3, 1);
   // glGenVertexArrays(<#GLsizei n#>, <#GLuint *arrays#>)
    glGenVertexArrays(1, &vertexID);//生成一個vao對象
    glBindVertexArray(vertexID); //綁定vao
    GLuint bufferID;
    glGenBuffers(1, &bufferID);  //生成vbo
    //
    glBindBuffer(GL_ARRAY_BUFFER, bufferID);  //綁定
   // glBufferData(<#GLenum target#>, <#GLsizeiptr size#>, <#const GLvoid *data#>, <#GLenum usage#>)
    glBufferData(GL_ARRAY_BUFFER, sizeof(vec), vec, GL_STATIC_DRAW); //填充緩沖對象
    GLuint loc=glGetAttribLocation(program, "position");   //獲得shader里position變量的索引
    glEnableVertexAttribArray(loc);     //啟用這個索引
    glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, sizeof(GLKVector3), 0);  //設置這個索引需要填充的內容
    glBindVertexArray(0);   //釋放vao
    glBindBuffer(GL_ARRAY_BUFFER, 0);  //釋放vbo
}
//隱藏狀態欄
- (BOOL)prefersStatusBarHidden {
    return YES;
}
//
-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  //清除surface內容,恢復至初始狀態。
    glBindVertexArray(vertexID);
    glUseProgram(program);      //使用shader
    glDrawArrays(GL_TRIANGLES, 0, 3);     //繪制三角形
    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
/***************************加載shader***************************/
- (BOOL)loadShaders
{
    GLuint vertShader, fragShader;
    NSString *vertShaderPathname, *fragShaderPathname;
    
    // Create shader program.
    program = glCreateProgram();
    
    // Create and compile vertex shader.
    vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"shader" ofType:@"vsh"];
    if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
        NSLog(@"Failed to compile vertex shader");
        return NO;
    }
    
    // Create and compile fragment shader.
    fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"shader" ofType:@"fsh"];
    if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {
        NSLog(@"Failed to compile fragment shader");
        return NO;
    }
    
    // Attach vertex shader to program.
    glAttachShader(program, vertShader);
    
    // Attach fragment shader to program.
    glAttachShader(program, fragShader);
    
    // Link program.
    if (![self linkProgram:program]) {
        NSLog(@"Failed to link program: %d", program);
        
        if (vertShader) {
            glDeleteShader(vertShader);
            vertShader = 0;
        }
        if (fragShader) {
            glDeleteShader(fragShader);
            fragShader = 0;
        }
        if (program) {
            glDeleteProgram(program);
            program = 0;
        }
        
        return NO;
    }
    // Release vertex and fragment shaders.
    if (vertShader) {
        glDetachShader(program, vertShader);
        glDeleteShader(vertShader);
    }
    if (fragShader) {
        glDetachShader(program, fragShader);
        glDeleteShader(fragShader);
    }
    
    return YES;
}

- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file
{
    GLint status;
    const GLchar *source;
    
    source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
    if (!source) {
        NSLog(@"Failed to load vertex shader");
        return NO;
    }
    
    *shader = glCreateShader(type);
    glShaderSource(*shader, 1, &source, NULL);
    glCompileShader(*shader);
    
#if defined(DEBUG)
    GLint logLength;
    glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
    if (logLength > 0) {
        GLchar *log = (GLchar *)malloc(logLength);
        glGetShaderInfoLog(*shader, logLength, &logLength, log);
        NSLog(@"Shader compile log:\n%s", log);
        free(log);
    }
#endif
    
    glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
    if (status == 0) {
        glDeleteShader(*shader);
        return NO;
    }
    
    return YES;
}

- (BOOL)linkProgram:(GLuint)prog
{
    GLint status;
    glLinkProgram(prog);
    
#if defined(DEBUG)
    GLint logLength;
    glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
    if (logLength > 0) {
        GLchar *log = (GLchar *)malloc(logLength);
        glGetProgramInfoLog(prog, logLength, &logLength, log);
        NSLog(@"Program link log:\n%s", log);
        free(log);
    }
#endif
    
    glGetProgramiv(prog, GL_LINK_STATUS, &status);
    if (status == 0) {
        return NO;
    }
    
    return YES;
}

- (BOOL)validateProgram:(GLuint)prog
{
    GLint logLength, status;
    
    glValidateProgram(prog);
    glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
    if (logLength > 0) {
        GLchar *log = (GLchar *)malloc(logLength);
        glGetProgramInfoLog(prog, logLength, &logLength, log);
        NSLog(@"Program validate log:\n%s", log);
        free(log);
    }
    
    glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
    if (status == 0) {
        return NO;
    }
    
    return YES;
}

@end

運行后得到如下:

 參考文獻:

                http://blog.csdn.net/sx1989827/article/details/47974595


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM