OpenGL ES 3.0 —— 2.著色器

在上一節(jié)中有介紹道OpenGL ES管線階段,在這一節(jié)主要介紹一下vertex shader和fragment shader。
簡單來說,在頂點處理階段會對傳入渲染管線的每個頂點執(zhí)行頂點著色器中的內(nèi)容,在光柵化過程中會對未被裁剪的頂點執(zhí)行片元著色器中的內(nèi)容(可以通過對紋理進行取樣或者使用其他技術來確定像素的顏色)。
著色器程序的創(chuàng)建與C/C++程序的創(chuàng)建相似。首先需要編寫著色器程序文本,其次將Shader源程序逐個編譯成Shader對象,之后將編譯好的Shader對象鏈接到一個單獨的程序對象中并將其載入到 GPU。
我們在項目中創(chuàng)建Shader.vsh和Shader.fsh兩個文件,分別添加如下代碼:

#version 300 es // 指定版本

in vec4 position;

void main()
{
    gl_Position = position;
}

··

#version 300 es
precision mediump float;  // 指定精度

out vec4 fragColor;

void main()
{
    fragColor = vec4(1.0,1.0,1.0,1.0); // 輸出白色
}

并在ViewController.mm中聲明以下幾個方法:

// 根據(jù)路徑讀取文件內(nèi)容
char* LoadAssetContent(const char*path)
{
    char*assetContent=nullptr;
    NSString*nsPath=[[NSBundle mainBundle] pathForResource:[NSString stringWithUTF8String:path] ofType:nil];
    NSData *data=[NSData dataWithContentsOfFile:nsPath];
    assetContent=new char[[data length]+1];
    memcpy(assetContent, [data bytes], [data length]);
    assetContent[[data length]]='\0';
    return assetContent;
}

// 根據(jù)代碼編譯著色器
GLuint CompileShader(GLenum shaderType,const char*code)
{
    //create shader object in gpu
    GLuint shader=glCreateShader(shaderType);
    //transform src to gpu & asign to the shader object
    glShaderSource(shader, 1, &code, NULL);
    glCompileShader(shader);
    GLint compileStatus=GL_TRUE;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
    if(compileStatus==GL_FALSE)
    {
        printf("compile shader error,shader code is : %s\n",code);
        char szBuffer[1024]={0};
        GLsizei logLen=0;
        glGetShaderInfoLog(shader, 1024, &logLen, szBuffer);
        printf("error log : %s\n",szBuffer);
        glDeleteShader(shader);
        return 0;
    }
    return shader;
}

// 根據(jù)編譯好的Shader鏈接程序
GLuint CreateGPUProgram(const char*vsCode,const char*fscode)
{
    GLuint program;
    //compile source code
    //.cpp .mm .m -> .o
    GLuint vsShader=CompileShader(GL_VERTEX_SHADER, vsCode);
    GLuint fsShader=CompileShader(GL_FRAGMENT_SHADER, fscode);
    //link .o -> executable file
    program=glCreateProgram();
    glAttachShader(program, vsShader);
    glAttachShader(program, fsShader);
    glLinkProgram(program);
    GLint programStatus=GL_TRUE;
    glGetProgramiv(program, GL_LINK_STATUS, &programStatus);
    if(GL_FALSE==programStatus)
    {
        printf("link program error!");
        char szBuffer[1024]={0};
        GLsizei logLen=0;
        glGetProgramInfoLog(program, 1024, &logLen, szBuffer);
        printf("link error : %s\n",szBuffer);
        glDeleteProgram(program);
        return 0;
    }
    return program;
}

聲明一個GLuint gpuProgram,執(zhí)行gpuProgram=CreateGPUProgram(LoadAssetContent("shader.vsh"),LoadAssetContent("shader.fsh"));,如果gpuProgram不等于0,意味著程序創(chuàng)建成功。

注:頂點著色器和片元著色器包含自建變量,如gl_Position(輸出頂點位置的剪裁坐標)和gl_PointSize(點精靈尺寸)。想要具體了解著色器自建變量可查閱OpenGL ES 3.0編程指南8.1和10.2。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容