录十六

持之以恒

颜色渐变三角形

三角形的颜色,一直在片段着色器中写的,通过程序设置三角形绘制的颜色。

一、向量类定义

3D向量是图形学最基本的数据类型,为了进一步的学习,我们需要定义自己的向量类。下面是它的代码实现:

//三维向量类
template<typename N>
class Vector3
{
public:
    typedef N ValueType;

public:
    // 默认构造一个0向量
    Vector3();
     // 初始化函数
    Vector3(N xx, N yy, N zz);
    // 拷贝构造函数
    Vector3(const Vector3& vec);
    
public:
      N x, y, z;
};

template<typename N>
Vector3<N>::Vector3()  
{ 
    x = y = z = ValueType(0); 
}

template<typename N>
Vector3<N>::Vector3( N xx, N yy, N zz)
{
    x = xx; y = yy; z = zz;
}

template<typename N>
Vector3<N>::Vector3(const Vector3& vec)
{
    x = vec.x; y = vec.y; z = vec.z;
}

这个向量类是一个模板类,主要是为了根据不同的精度要求,方便我们定义所需精度的向量类型。这个向量类有x,y和z三个分量,它不仅可以用来表示3D向量,也可以表示3D点,或者RGB颜色等。

二、着色器之间传递数据

(1)顶点着色器源码:

//输入变量
attribute  vec4  vPosition;//顶点坐标
attribute  vec3  vColor;   //顶点颜色
uniform    mat4  matModel; //变换矩阵
//输出变量
varying vec3  varColor; //输出的颜色

void main()
{
    varColor = vColor;
    gl_Position = matModel * vPosition;
}

第3行:新增了一个顶点颜色的属性变量,vColor向量的x,y,z分量分别表示RGB三个通道的颜色值。

第7行:定义了一个类型为vec3的输出变量,前面的varying是易变变量的修饰符,表示我们声明了一个易变变量。

第10行:直接输出顶点颜色到varColor变量,没有做任何处理。

(1)片段着色器源码:

//输入变量
varying vec3  varColor;

void main()
{
  gl_FragColor = vec4(varColor, 1.0);
}

第2行:定义了一个vec3类型的输入变量,表示输入的RGB颜色。它的声明必须和顶点着色器中的声明完全保持一致,表示这个输入来自于顶点着色器的输出。

第6行:将varColor变量转换成vec4类型的变量,赋给内置变量gl_FragColor,作为片段着色器最终输出的颜色。在GLSL中没有默认的3维到4维的转换,因此需要添加一个w分量,进行明确的转换。新增的w分量表示颜色的透明度,1.0表示没有透明度。

易变变量是顶点着色器向片段着色器传递数据使用的。这里的数据传递不是简单的赋值操作。易变变量从顶点着色器输出之后,然后在图元范围内对每个片段进行插值,最后将插值好的数据传递给片段着色器中的易变变量。

三、绘制渐变三角形

使用3D向量类定义三角形的顶点数组和颜色数组,如下:

// 定义三角形的3个顶点坐标
Vector3f vVertices[] = { Vector3f( 0.0f,  0.5f, 0.0f),  //第1个点
                         Vector3f(-0.5f, -0.5f, 0.0f),  //第2个点
                         Vector3f( 0.5f, -0.5f, 0.0f)   //第3个点 
                       };

// 定义三角形的3个顶点颜色
Vector3f vColor[] = {  Vector3f(1.0f,  0.0f, 0.0f),  //第1个顶点的颜色,依次为rgb
                       Vector3f(0.0f,  1.0f, 0.0f),  //第2个顶点的颜色 
                       Vector3f(1.0f,  1.0f, 0.0f)   //第3个顶点的颜色 
                    };

在窗口类的场景渲染函数中,将三角形的顶点属性数据发送给传递顶点着色器,然后启用对应的顶点索引就可以,代码如下:

// 为顶点属性 指定 顶点数据
GL30::glVertexAttribPointer(m_posLoc,         //顶点属性的索引
                            3,                //顶点坐标有x,y,z三个分量
                            GL30::GL_FLOAT,   //顶点坐标的数据类型为float
                            GL_FALSE,         //顶点数组为float类型,无需规范化
                            3*sizeof(float),  //顶点之间的跨距为3个float大小
                            vVertices);       //顶点数组的指针

GL30::glVertexAttribPointer(m_clorLoc,        //顶点颜色的索引
                            3,                //顶点颜色有r,g,b三个分量
                            GL30::GL_FLOAT,   //顶点颜色的数据类型为float
                            GL_FALSE,         //顶点颜色为float类型,无需规范化
                            3*sizeof(float),  //顶点颜色之间的跨距为3个float大小
                            vColor);          //顶点数组的指针

// 启用顶点坐标的顶点索引
GL30::glEnableVertexAttribArray (m_posLoc);

// 启用顶点颜色的顶点索引
GL30::glEnableVertexAttribArray (m_clorLoc);

// 使用顶点绘制三角形
GL30::glDrawArrays ( GL30::GL_TRIANGLES, 0, 3 );

四、配套代码

无标题.jpg

源码下载:ColorGradient


发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

Copyright © 1999-2019, lu16.com, All Rights Reserved