OpenGL-ES 学习(13) ---- Shader 编译和程序对象

目录

概述

在本节中,我们提供创建 Shader对象,并且编译链接到一个程序对象的完整流程,主要内容如下:

  • Shader 和程序对象概述
  • 创建和编译Shader
  • 创建和链接程序对象
  • 设置和获取统一变量
  • 获取和设置属性
  • Shader 编译器和程序二进制代码

想要用 Shader 进行渲染,必须创建两个基本的对象:Shader 对象和程序对象(program object);它们之间的关系类似于C语言链接程序和编译器

  1. C语言对象将一段源代码生成目标对象
  2. C链接程序将对象文件链接为最后的文件

Shader 对象是包含多个 Shader 的对象,源代码提供给 Shader 对象,Shader 对象被编译为一个目标形式(类似于 obj 文件),编译之后,Shader 对象可以连接到一个程序对象,一个程序对象可以连接多个 Shader 对象 ,在 OpenGL-ES 中,每个程序对象必须连接到一个 Vertex Shader 对象和 Fragment Shader.

之后使用 Shader 进行渲染,步骤如下:

创建和编译Shader

创建和编译Shader使用的 API如下:
glCreateShader (GLenum type)
glDeleteShader(GLuint shader)

说明:创建/删除 VertexShader or FragmentShader ,返回新 Shaderhandle

glShaderSource (GLuint shader, GLsizei count, const GLchar const string, const GLint *length)

说明:指定 Shadersrc_code 源代码

glCompileShader (GLuint shader)

说明:编译 Shader

glGetShaderiv (GLuint shader,GLenum pname,GLint * params)

说明:检查 Shader 是否编译成功

glGetShaderInfoLog (GLuint shader,GLsizei maxLength,GLsizei *length,GLchar *infoLog)

说明:获取编译 Shader log 信息

链接程序对象

链接程序对象使用的 API 如下:

API 说明
glCreateProgram() 创建程序对象
glDeleteProgram() 删除程序对象
glAttachShader() Shader 对象连接到程序对象
glDetachShader() Shader 对象从程序对象分离
glLinkPrigram() 链接程序对象
glGetProgramiv 查询Shader 链接信息
glGetProgramInfoLog 获取程序信息日志

绘制一个最简单的三角形

绘制一个基本三角形,示例输入顶点坐标和颜色坐标如下:

c 复制代码
	//R G B A
	GLfloat color[4] = { 0.0f, 1.0f, 0.0f, 1.0f };
	// 3 vertices, with (x,y,z) per-vertex
	GLfloat vertexPos[3 * 3] = {
		1.0f,  0.0f, 0.0f, // v0
		0.0f, 1.0f, 0.0f, // v1
		0.0f, 0.0f, 1.0f  // v2
	};

vertexPos 数组表示的是三个顶点的三维坐标,OpenGL-ES 中使用的坐标系如下图所示:

示例代码

c 复制代码
#include "esUtil.h"

typedef struct
{
	GLuint programObject;
} UserData;

static int Init(ESContext *esContext)
{
	UserData *userData = esContext->userData;
	const char vShaderStr[] =
		"#version 300 es                            \n"
		"layout(location = 0) in vec4 a_position;   \n"
		"layout(location = 1) in vec4 a_color;      \n"
		"out vec4 v_color;                          \n"
		"void main()                                \n"
		"{                                          \n"
		"    v_color = a_color;                     \n"
		"    gl_Position = a_position;              \n"
		"}";

	const char fShaderStr[] =
		"#version 300 es            \n"
		"precision mediump float;   \n"
		"in vec4 v_color;           \n"
		"out vec4 o_fragColor;      \n"
		"void main()                \n"
		"{                          \n"
		"    o_fragColor = v_color; \n"
		"}";

	GLuint programObject;

	// Create the program object
	programObject = esLoadProgram(vShaderStr, fShaderStr);

	if (programObject == 0) {
		return GL_FALSE;
	}

	// Store the program object
	userData->programObject = programObject;

	// R G B A
	glClearColor(1.0f, 1.0f, 1.0f, 0.5f);
	return GL_TRUE;
}

static void Shutdown(ESContext *esContext)
{
	UserData *userData = esContext->userData;
	glDeleteProgram(userData->programObject);
}


static void Draw(ESContext *esContext)
{
	UserData *userData = esContext->userData;
	//R G B A
	GLfloat color[4] = { 0.0f, 1.0f, 0.0f, 1.0f };
	// 3 vertices, with (x,y,z) per-vertex
	GLfloat vertexPos[3 * 3] =
	{
		1.0f,  0.0f, 0.0f, // v0
		0.0f, 1.0f, 0.0f, // v1
		0.0f, 0.0f, 1.0f  // v2
	};

	glViewport(0, 0, esContext->width, esContext->height);

	glClear(GL_COLOR_BUFFER_BIT);
	glUseProgram(userData->programObject);

	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertexPos);
	glEnableVertexAttribArray(0);
	glVertexAttrib4fv(1, color);

	glDrawArrays(GL_TRIANGLES, 0, 3);
	glDisableVertexAttribArray(0);
}
相关推荐
西岸行者4 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意4 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码4 天前
嵌入式学习路线
学习
毛小茛4 天前
计算机系统概论——校验码
学习
babe小鑫4 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms4 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下4 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。4 天前
2026.2.25监控学习
学习
im_AMBER4 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J4 天前
从“Hello World“ 开始 C++
c语言·c++·学习