Apple's OpenGL——Vertex Shader基础

本文深入探讨OpenGL Shader编程,重点介绍顶点着色器与片断着色器的功能及应用。通过具体代码示例,详细解释如何创建、编译、构建和连接Shader,以及数据如何从主机端传递至Shader端。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

OpenGL3.3以及更高版本将OpenGL本来与顶点着色器(Vertex Shader)和片断着色器(Fragment Shader)所对应的固定功能流水线部分的接口全都剔除掉了,取而代之的是这些着色器配置相关的接口。OpenGL3.3又添加了几何着色器(Geometry Shader)。目前最新的OpenGL4.1又添加了Tessellation(细分曲面),这里又有几个着色器被添加进去。OpenGL在最近两年里发展迅猛,一下子就从3.3跳到了4.1。我们目前所 使用的OpenGL Shading Language的版本是1.20。

  之前在这个贴中描述了如何创建创建着色器,并且对它们进行编译、构建、连接,以及如何把着色器源代码加入到应用的资源中。

  这里,我们将正式对着色器进行讲解。顶点着色器取代的是OpenGL固定功能流水线中对每个顶点的变换阶段。这部分的操作包括:顶点变换(投影变换、视图模型变换)、法线变换与规格化、纹理坐标生成、纹理坐标变换、光照、颜色材质应用。

  下面看一个简单的Vertex Shader的代码:
//
//  Shader.vsh
//  GLSLTest
//
//  Created by Zenny Chen on 4/11/10.
//  Copyright GreenGames Studio 2010. All rights reserved.
//

attributevec4position;
attributevec4color;
varying vec4 colorVarying;
uniform mat4 translate;
void main()
{
gl_Position = position * translate; //mat4(0.816, 0.433, 0.0, 0.0,  -0.5, 0.616, 0.0, 0.0,  0.0, 0.0, -0.5, 0.0,  0.0, 0.0, -0.5, 1.0);
    colorVarying = color;
}

  最上面两个attribute变量的数据是从主机端输入attribute在后期Shader Language版本中被废弃,取而代之的是in关键字。主机端通过以下接口把相关数据与vertex shader所对应的attribute变量进行绑定:

  1. void glBindAttribLocation( GLuint   program,
  2.   GLuint   index,
  3.   const GLchar *  name);

program:你已经构建好的shader程序
index:自己定义的一个id,与下面的name进行绑定
name:指定顶点着色器中所要绑定的变量名

  在我们的主机端程序中,与上述position变量进行绑定的代码为:
// attribute index
enum{
ATTRIB_VERTEX,
ATTRIB_COLOR,
NUM_ATTRIBUTES
};
glBindAttribLocation(program, ATTRIB_VERTEX, "position");

  与color绑定的代码为:
glBindAttribLocation(program, ATTRIB_COLOR, "color");

  这里要注意的是,顶点着色器是可以与主机端应用进行直接交互的。而片断着色器则不能与主机端程序进行直接交互。因此,我们可以把片断着色器所要用到的数据先通过顶点着色器输入进来,然后通过varying属性传给片断着色器(Fragment Shader)。注意,在以后版本中varying关键字也被废弃。取而代之的是在顶点着色器部分用out关键字,而在片断着色器中相应地使用in关键字。

  因此,attribute不仅仅是指顶点属性,也可以是颜色属性或用户自定义的一些变量,而我们用主机端的数据与这些attribute变量绑定时,都用glBindAttribLocation这一个接口。

  而我们通过以下接口把主机端的数据发送给Shader端:

  1. void glVertexAttribPointer( GLuint   index,
  2.   GLint   size,
  3.   GLenum   type,
  4.   GLboolean   normalized,
  5.   GLsizei   stride,
  6.   const GLvoid *   pointer);

index:我们刚才所指定的attribute变量所绑定的id。
size:指定每个元素有多少分量,可以是1,2,3,4
type:指定数据类型
normalized:指定定点数据是否被规格化
stride:相邻两个元素之间的跨度(字节数)
pointer:指向数组首地址

  下面将给出示例代码:

  首先定义顶点坐标和颜色值:
    static const GLfloat squareVertices[] = {
        -0.5f, -0.5f, 0.0f,
        0.5f, -0.5f, 0.0f,
        -0.5f0.5f, 0.0f,
        0.5f0.5f, 0.0f
    };

    static const GLubyte squareColors[] = {
        255, 255,   0, 255,
        0,   255, 255, 255,
        0,     0,   0,   0,
        255,   0, 255, 255,
    };

  然后,下面就是分别传送顶点坐标数据和颜色数据:
// Update attribute values
    glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, 0, 0, squareVertices);
glEnableVertexAttribArray(ATTRIB_VERTEX);
    glVertexAttribPointer(ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, 1, 0, squareColors);
glEnableVertexAttribArray(ATTRIB_COLOR);

  下面附赠完整的工程。

附件:  OpenGLShaderBasic.zip (34 K)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值