OpenGL code interpretation, create shader, and use


    typedef GLint   attribute;
    typedef GLint   uniform;
    GLint _vHandle = -1;
    GLint _pHandle = -1;
    GLint _program = -1;
    uniform _color = -1;
    const char* vs = "void main()\
                        {\
                            gl_Position = ftransform();\
                        }";
    const char* ps = "uniform vec4 _color;\
	                    void main()\
	                    {\
	                        gl_FragColor = _color;\
	                    }";
    bool    result = false;
    do
    {
        //! 创建shader
        _vHandle = glCreateShader(GL_VERTEX_SHADER);
        _pHandle = glCreateShader(GL_FRAGMENT_SHADER);

        //! 指定shader的源代码
        glShaderSource(_vHandle, 1, (const GLchar**)&vs, 0);
        glShaderSource(_pHandle, 1, (const GLchar**)&ps, 0);

        //! 编译shader
        glCompileShader(_vHandle);
        GLint   status = 0;
        char    compileLog[1024] = { 0 };
        glGetShaderiv(_vHandle, GL_COMPILE_STATUS, &status);
        if (status == GL_FALSE)
        {
            glGetShaderInfoLog(_vHandle, sizeof(compileLog), 0, compileLog);
            assert(false && compileLog);
            break;
        }

        glCompileShader(_pHandle);

        glGetShaderiv(_pHandle, GL_COMPILE_STATUS, &status);
        if (status == GL_FALSE)
        {
            glGetShaderInfoLog(_pHandle, sizeof(compileLog), 0, compileLog);
            assert(false && compileLog);
            break;
        }
        //! 4创建程序
        _program = glCreateProgram();
        glAttachShader(_program, _vHandle);
        glAttachShader(_program, _pHandle);

        //! 5链接程序
        glLinkProgram(_program);

        glGetProgramiv(_program, GL_LINK_STATUS, &status);
        if (status == GL_FALSE)
        {
            glGetProgramInfoLog(_program, sizeof(compileLog), 0, compileLog);
            break;
        }
        result = true;

    } while (false);

    if (!result)
    {
        if (_vHandle != -1)
        {
            glDeleteShader(_vHandle);
        }
        if (_pHandle != -1)
        {
            glDeleteShader(_pHandle);
        }
        if (_program != -1)
        {
            glDeleteProgram(_program);
        }
        _vHandle = -1;
        _pHandle = -1;
        _program = -1;
    }
    //取得shader程序中uniform变量地址
    _color = glGetUniformLocation(_program, "_color");
    /*   一.可编程管线的shader执行过程:(shader代码是什么阶段被调用的)
           1.调用openglAPI时候输入最多的是顶点数据、纹理数据、矩阵变换数据等,当我们调用绘制方法(glDrawArrays等)时候,
           会把这些数据传入顶点shader,调用顶点着色器程序。
           2.顶点着色器的工作:把输入的三维空间点,输出到二维平面上:
           对顶点坐标进行模型变换(glTranslate、glRotate、glRotate)->(视图)观察变换(gluLookAt)->投影变换(gluPerspective/glOrtho)->视口变换(glViewport)
           2.顶点shader->图元装配->光栅化->片元着色器
           3.光栅化是指你要画一个图元时候,具体怎么把它画出来,如何填充每个像素
           */
    //! 指定以下的操作针对投影矩阵
    glMatrixMode(GL_PROJECTION);
    //! 将投影举证清空成单位矩阵
    glLoadIdentity();
    //产生一个投影矩阵并跟当前矩阵做乘法
    glOrtho(0, _width, _height, 0, -100, 100);
    glColor3f(1, 0, 1);
    Vertex  rect[] =
    {
        {10,    10,     0,  1,  0,  0},
        {110,   10,     0,  0,  1,  0},
        {10,    110,    0,  0,  0,  1},
        {110,   110,    0,  1,  0,  1},
    };
    //使用shader绘制
    glUseProgram(_program);
    //设置shader中uniform变量
    glUniform4f(_color, 0, 1, 0, 1);

    glColor3f(1, 0, 1);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glVertexPointer(3, GL_FLOAT, sizeof(Vertex), rect);
    glColorPointer(3, GL_FLOAT, sizeof(Vertex), &rect[0].r);
    //调用这个接口时,CPU会把顶点数据传入顶点着色器程序, 第三个参数4表示顶点数,也表示要执行四次顶点着色器程序
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    glUseProgram(0);

Guess you like

Origin blog.csdn.net/u012861978/article/details/126426825