• OpenGL12-shader(GLSL)着色语言3-(属性参数)(代码已上传)


    上一个例程中,使用了uniform 类型的变量,uniform可以理解为全局变量,这一节中使用

    的是attribute类型的变量,翻译过来就是属性,他是与顶点绑定的,就意味着一个顶点可以

    有很多个属性(当然也可以没有),提出这个概念的原因是啥呢?我们先看下最早期的OpenGL

    早己的OpenGL定义的数据比较少,有顶点,法线,颜色,纹理(1.0版本),也就是说一个

    顶点可以传递给显卡的数据是有限的,没有办法在像显卡传递更多的数据参与计算,例如,现在

    游戏中比较流线的法线贴图(或者叫凹凸纹理)是做不到,为了满足这样的应用场合,提出了顶点

    属性这样一个概念,目的就是,传递更多的数据给显卡,参与计算,显示更好的效果。

         知道这个目的了,也就知道该咋用这个东西,看下面的定义:

    struct Vertex
    {
        //! 这里是颜色数据,可以通过OpenGL的glColorPonter来传递
        //! 这里我们通过另外的途径来传递(属性)
        float r, g, b, a;
        float x, y, z;
    };

    结构体中定义了颜色和顶点位置,但这一次,颜色数据不是通过OpenGL的函数进行传递,而是通过

    属性字段进行传递,用来展示如何使用这一系列的api。

                uniform float times;
                attribute vec4 attrColor;
                void main( void )
                {
                    float c = cos(times);
                    float s = sin(times);
                    vec4  temp = gl_Vertex;
                    temp.x = gl_Vertex.x * c - gl_Vertex.y * s;
                    temp.y = gl_Vertex.x * s + gl_Vertex.y * c;
                    gl_Position = gl_ModelViewProjectionMatrix * temp;
                    gl_FrontColor = attrColor; 
                }

    红色的是在上一个例程中多增加的部分,就是在应用层中用来传递顶点颜色使用的变量。

    _attrColor  =   glGetAttribLocationARB( _programObj, "attrColor" );

    应用层中,通过调用上面的函数,获取attrColor变量的句柄。当我们获取到句柄以后,就

    可以给他传递数据。但我们还是需要再做一些事情:如下所示:

    glUseProgramObjectARB( _programObj );
    

      该数据告诉显卡,下面我们要使用该程序(shader)去执行顶点的处理过程,如果要

    取消使用shader处理,则参数传递0取消定点过程处理,如下所示:

    glUseProgramObjectARB( 0 );

    接下来调用下面的函数启动属性索引。

    glEnableVertexAttribArray(_attrColor);

    启动这个属性(看名字,就知道是顶点属性数组)。当启用了这个属性以后,可以

    调用下面的api将应用层数据传递给shader了:

    glVertexAttribPointer(_attrColor,4,GL_FLOAT,GL_FALSE,sizeof(Vertex),g_cubeVertices);

    该函数的参数意义如下:

    第一个参数:属性的句柄(或者叫索引)

    第二个参数:是传递的数据元素的维度,在这里我们传递的是颜色,r,g,b,a四个,就是一个元素中含

    四个成员。

    第三个参数:是元素的类型:这个我用用的是float

    第四个参数:是否规格化,一般我们不做。传递GL_FALSE

    第五个参数:描述了元素之间的偏移量,就是对最后一个参数中数据的描述,当访问完第一组数据以后

    在下一个元素在什么位置,通过该变量进行计算。

    第六个参数:数据指针,这个传递的是实际的数据地址。当然如果我们使用了顶点缓冲区,就可以给0

    glVertexPointer(3,GL_FLOAT,sizeof(Vertex),&g_cubeVertices[0].x);

    这个函数是调用传统的OpenGL函数传递顶点数据给显卡。

    最后进行进行绘制。

    glDrawArrays( GL_QUADS, 0, 24 );

    该函数参数如下:

    第一个参数说明要绘制图元的类型,四边形。

    第二个参数说明从哪一个元素就行绘制

    第三个参数说明绘制元素的个数。

    渲染函数如下:

     glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    
     
                glMatrixMode( GL_MODELVIEW );
                glLoadIdentity();
                glTranslatef( 0.0f, 0.0f, -15 );
    
                static  float xxx = 0;
    
                glUseProgramObjectARB( 0 );
                glUniform1fARB(_times,xxx);
    
                xxx +=  0.01f;
                if (xxx > 3.14f)
                {
                    xxx =   0;
                }
                glEnableClientState(GL_VERTEX_ARRAY);
                glEnableVertexAttribArray(_attrColor);
                glVertexAttribPointer(_attrColor,4,GL_FLOAT,GL_FALSE,sizeof(Vertex),g_cubeVertices);
                glVertexPointer(3,GL_FLOAT,sizeof(Vertex),&g_cubeVertices[0].x);
                glDrawArrays( GL_QUADS, 0, 24 );
    
               
                SwapBuffers( _hDC );

    代码下载

  • 相关阅读:
    本周工作量统计
    第15周个人作业
    16周第一组作业
    排球比赛积分规则
    典型用户和场景
    我和计算机
    第18周冲刺
    16周个人作业
    Java中动态获取项目根目录的绝对路径
    Spring框架下类的初始化顺序
  • 原文地址:https://www.cnblogs.com/zhanglitong/p/3216131.html
Copyright © 2020-2023  润新知