前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Shader 入门:GLSL ES(简介和基本语法)

Shader 入门:GLSL ES(简介和基本语法)

作者头像
陈皮皮
发布2020-07-10 13:44:14
2.5K0
发布2020-07-10 13:44:14
举报
文章被收录于专栏:菜鸟小栈菜鸟小栈

前言

欢迎来到我的 Shader 入门系列文章,在本系列文章中我将和大家一起学习 Shader 相关知识,以便于我们阅读和编写 Shader。

我们将从 GLSL ES 开启我们的学习之路,本篇文章作为该系列的开篇,将给大家简单介绍 GLSL ES 并学习它的基本语法。

话不多说,我们开始吧!

> 在本系列文章中主要针对 GLSL ES 3.0 进行讲解

正文

简介

在正式学习 GLSL ES 之前,我们需要先大概了解下以下内容:

- OpenGL

OpenGL 全称为 Open Graphics Library(开放图形库)。

用于渲染 2D 或 3D 图像的跨语言跨平台的应用程序编程接口

- OpenGL ES

OpenGL ES 全称为 OpenGL for Embedded Systems(嵌入式系统开放图形库)。

OpenGL ES 是 OpenGL 的子集,主要针对嵌入式系统(设备)设计,去除了 Open GL 中非必要的特性。

- GLSL

GLSL 全称为 OpenGL Shading Language(OpenGL 着色语言),是一款在 OpenGL 着色器(Shader)中使用的编程语言。

- GLSL ES

GLSL ES 全称为 OpenGL ES Shading Language(OpenGL ES 着色语言),就是用于 OpenGL ES 着色器的编程语言。

基本语法

> GLSL(ES)作为一款类 C 语言,其同样也是强类型语言,基本语法和 C 语言相似。

· 基础

- 大小写敏感

- 表达式后面必须以;结束

—▼—

· 注释

单行注释:使用//开头的一行文字

代码语言:javascript
复制
// 我是单行注释

多行注释:使用/**/包裹多行文字

代码语言:javascript
复制
/*
我是第一行注释
我是第二行注释
*/

—▼—

· 变量

变量的命名可以使用英文 a-zA-Z、数字 0-9 和下划线 _,另外需注意以下几点:

- 不能以数字开头

- 不能以gl_开头

- 不能直接使用 GLSL 保留的名称

声明变量时必须指定类型,允许先声明后赋值:

代码语言:javascript
复制
int age = 18;
// 声明并赋值
float money;
// 声明不赋值
bool isMe;
// 先声明
isMe = true;
// 后赋值

一条表达式可以声明多个变量,需用,分隔:

代码语言:javascript
复制
int age, balance;
// 都不赋值
int a, b = 110;
// 同时赋值

—▼—

· 常量

在类型前面添加const关键字来声明常量,常量一但创建就不能更改:

代码语言:javascript
复制
const int AGE = 18;
// 声明常量必须赋值
AGE = 20;
// error! 常量不可以更改

—▼—

· 函数

定义函数时,如果函数有返回值,就需要指定返回值的类型,如果没有返回值,必须指定为空void

如果函数有参数,那么也需要指定参数的类型,如果没有参数则可以不填或者填入void(一般都不填)。

代码语言:javascript
复制
// 没有返回值没有参数的 main 函数
void main() {
    // ...
}
// 接收两个 int 类型参数并返回 int 类型的值的 sum 函数
int sum(int a, int b) {
    return a + b;
}

可以先声明后定义,可以声明多次但是只允许定义一次:

代码语言:javascript
复制
void foo();
// 首次声明
void foo();
// 允许重复声明
void foo() { ... }
// 定义

重载

重载函数允许你传入不同数量或不同类型的参数:

代码语言:javascript
复制
void foo(int value) { ... }
void foo(float value) { ... }
void foo(float value1, int value2) { ... }

—▼—

· 作用域

使用一对花括号{}包裹的区域即为一个作用域:

代码语言:javascript
复制
void foo() {
    int a = 0;
    {
        int b = 0;
    }
}

子域可以访问父域的成员,但是反过来不行:

代码语言:javascript
复制
void foo(int a) {
    {
        int a = a + 1; // 第二个 a 属于父域,不冲突
        int b = a; // 访问当前作用域的 a
    }
    int c = b; // Error! 当前作用域内不存在 b
    int d = a; // 当前作用域的参数 a
}

同一作用域内不允许成员名称重复

代码语言:javascript
复制
int age; // 声明为整型
float age; // Error! 冲突
void age(); // Error! 冲突

在同一作用域内不允许重复声明

代码语言:javascript
复制
int a; // 首次声明
int a; // Error! 不可以重复声明

相关资料

- OpenGL ES Registry(OpenGL ES 资料页) https://www.khronos.org/registry/OpenGL/index_es.php

- OpenGL ES 3 Quick Reference Card(OpenGL ES 3 快速参考卡片) https://www.khronos.org/files/opengles3-quick-reference-card.pdf

- GLSL ES Specification 3.00(GLSL ES 规范 3.0) https://www.khronos.org/registry/OpenGL/specs/es/3.0/GLSL_ES_Specification_3.00.pdf

- OpenGL ES 3.0 Online Reference Pages(OpenGL ES 3.0 在线参考页) https://www.khronos.org/registry/OpenGL-Refpages/es3.0/

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 菜鸟小栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档