计算机图形学-预告3

计算机图形学-预告3

首先先声明,代码是来自www.cs.unm.edu/~angel。在下这里指示添加一些注释或者说明以及把里面的English翻译成Chinese。有部分是参考其他博客。
这一部分主要是讲公共使用的文件的。

InitShader.cpp

// 读取文件,并且返回指针
static char* readShaderSource(const char* shaderFile)
{
    FILE* fp = fopen(shaderFile, "r");

    if ( fp == NULL )
    {
        return NULL;
    }

    fseek(fp, 0L, SEEK_END);
    long size = ftell(fp);

    fseek(fp, 0L, SEEK_SET);
    char* buf = new char[size + 1];
    fread(buf, 1, size, fp);

    buf[size] = '\0';
    fclose(fp);

    return buf;
}

//根据vShaderFile和fShaderFile创建GLSL program 对象
GLuint InitShader(const char* vShaderFile, const char* fShaderFile)
{

    //查看GLSL和OpenGL的版本
    const GLubyte *renderer = glGetString( GL_RENDERER );
    const GLubyte *vendor = glGetString( GL_VENDOR );
    const GLubyte *version = glGetString( GL_VERSION );
    const GLubyte *glslVersion =
        glGetString( GL_SHADING_LANGUAGE_VERSION );
    GLint major, minor;
    glGetIntegerv(GL_MAJOR_VERSION, &major);
    glGetIntegerv(GL_MINOR_VERSION, &minor);
    std::cout << "GL Vendor    :" << vendor << std::endl;
    std::cout << "GL Renderer  : " << renderer << std::endl;
    std::cout << "GL Version (string)  : " << version << std::endl;
    std::cout << "GL Version (integer) : " << major << "." << minor << std::endl;
    std::cout << "GLSL Version : " << glslVersion << std::endl;

    //构建信息数组
    struct Shader
    {
        const char*  filename;
        GLenum       type;
        GLchar*      source;
    }  shaders[2] =
    {
        { vShaderFile, GL_VERTEX_SHADER, NULL },
        { fShaderFile, GL_FRAGMENT_SHADER, NULL }
    };
    //创建着色器程序
    GLuint program = glCreateProgram();

    for ( int i = 0; i < 2; ++i )
    {
        Shader& s = shaders[i];
        s.source = readShaderSource( s.filename );
        if ( shaders[i].source == NULL )//文件读取失败
        {
            std::cerr << "Failed to read " << s.filename << std::endl;
            exit( EXIT_FAILURE );
        }
        //创建着色器对象:(片段着色器/顶点着色器)
        GLuint shader = glCreateShader( s.type );
        //把着色器源代码和着色器对象相关联
        glShaderSource( shader, 1, (const GLchar**) &s.source, NULL );
        //编译着色器对象
        glCompileShader( shader );

        GLint  compiled;
        //检查编译是否成功
        glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled );
        if ( !compiled )
        {
            std::cerr << s.filename << " failed to compile:" << std::endl;
            GLint  logSize;
            //得到编译日志长度
            glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &logSize );
            char* logMsg = new char[logSize];
            //得到日志信息并输出
            glGetShaderInfoLog( shader, logSize, NULL, logMsg );
            std::cerr << logMsg << std::endl;
            delete [] logMsg;

            exit( EXIT_FAILURE );
        }

        delete [] s.source;
        //将着色器程序链接到所创建的程序中
        glAttachShader( program, shader );
    }

    //将这些对象链接成一个可执行程序
    glLinkProgram(program);

    GLint  linked;
    //查询链接的结果
    glGetProgramiv( program, GL_LINK_STATUS, &linked );
    if ( !linked )//链接失败
    {
        std::cerr << "Shader program failed to link" << std::endl;
        GLint  logSize;
        //得到链接日志长度
        glGetProgramiv( program, GL_INFO_LOG_LENGTH, &logSize);
        char* logMsg = new char[logSize];
        //得到日志信息并输出
        glGetProgramInfoLog( program, logSize, NULL, logMsg );
        std::cerr << logMsg << std::endl;
        delete [] logMsg;

        exit( EXIT_FAILURE );
    }

    //链接成功,在OpenGL管线中使用渲染程序
    glUseProgram(program);

    return program;
}

关于VAO和VBO

  • VAO(顶点数组对象 Vertex Array Object)是一个包含一个或数个顶点缓冲区对象,一般存储一个可渲染物体的所有信息
  • VBO(缓冲区对象 Vertex Buffer Object)是指显卡内存中的一块高速内存缓冲区,用来存储顶点的所有信息

VBO是Vertex Buffer Object, VAO是Vertex Array Object。 VAO是OpenGL 3.0以后才引入的新东西,但是在2.0版本中做为扩展接口。

VBO其实就是显卡中的显存,为了提高渲染速度,可以将要绘制的顶点数据缓存在显存中,这样就不需要将要绘制的顶点数据重复从CPU发送到GPU, 浪费带宽资源。

而VAO则是一个容器,可以包括多个VBO, 它类似于以前的call list, 由于它进一步将VBO容于其中,所以绘制效率将在VBO的基础上更进一步。

一般在初始化数据的时候,会接触到。代码片段解释。

    // @{ 创建定点数组对象(初始化VAO)
    GLuint vao;
    glGenVertexArrays( 1, &vao );// 生成一个未用的VAO ID,存于变量vao中
    glBindVertexArray( vao ); // 创建id为vao的VAO,并绑定为当前VAO
    // }@
    // @{ 创建和初始化缓冲对象(生成VBO)
    GLuint buffer;
    glGenBuffers( 1, &buffer );// 生成一个未用的缓冲区对象ID,存于变量buffer中
    glBindBuffer( GL_ARRAY_BUFFER, buffer );// 创建id为buffer的Array Buffer对象,并绑定为当前Array Buffer对象
    // 为Buffer对象在GPU端申请空间,并提供数据
    glBufferData(
        GL_ARRAY_BUFFER,// Buffer类型
        sizeof(points),// 申请空间大小
        points,// 提供数据
        GL_STATIC_DRAW // 表明将如何使用Buffer的标志(GL_STATIC_DRAW含义是一次提供数据,多遍绘制)
    );
    // }@
    // Load shaders and use the resulting shader program
    GLuint program = InitShader( "vshader.glsl", "fshader.glsl" );
    glUseProgram( program ); // 使用该shader程序
    // 初始化着色器里面的顶点位置的变量
    // 获取shader程序中属性变量的位置(索引)
    GLuint loc = glGetAttribLocation( program, "vPosition" );
    // 启用顶点属性数组
    glEnableVertexAttribArray( loc );
    //事实上连接属性引索和缓冲区的方法
    // 为顶点属性数组提供数据(数据存放在之前buffer对象中)
    glVertexAttribPointer(
        loc,//属性变量引索
        2,//每个顶点属性的分量个数
        GL_FLOAT,//数组数据类型
        GL_FALSE,//是否进行归一化处理
        0,//在数组中相邻属性成员间的间隔(以字节为单位)
        BUFFER_OFFSET(0) // 第一个属性值在buffer中的偏移量
     );

具体关于VAO、VBO的数据传输,可以参考:
http://blog.csdn.net/qweewqpkn/article/details/46365405
http://blog.csdn.net/wanglang3081/article/details/8750358
http://blog.csdn.net/candycat1992/article/details/39676669
http://blog.csdn.net/csxiaoshui/article/details/23935079

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小明是我的

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值