OpenGL01--基本概念

本文详细介绍了OpenGL中的着色器编程,包括顶点着色器和片段着色器的创建、源代码编写、编译与链接过程,以及使用GLSL语言进行空间变换和深度纹理可视化示例。

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

着色器

着色器(Shader)是用于控制图形渲染流程的程序,主要分为顶点着色器和片段着色器。源代码提供着色器对象,然后通过着色器对象被编译为一个目标形式(obj文件),编译之后,着色器对象可以连接到一个程序对象。程序对象可以连接多个着色器对象
获得链接之后着色器对象一般过程包括6个步骤

  • 创建一个顶点着色器对象和一个片段着色器对象
  • 将源代码连接到每个着色器对象
  • 编译着色器对象
  • 创建一个程序对象
  • 将编译后着色器对象连接到程序对象
  • 链接程序对象
// 创建和编译着色器程序 
	//顶点着色器
	unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
	glCompileShader(vertexShader);
	// 检查编译错误
	int success;
	char infoLog[512];
	glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
	if (!success) {
		glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
		std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
	}
	// 片段着色器
	unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
	glCompileShader(fragmentShader);
	// 检查编译错误
	glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
	if (!success) {
		glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
		std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
	}
	//着色器程序
	unsigned int shaderProgram = glCreateProgram();
	glAttachShader(shaderProgram, vertexShader);
	glAttachShader(shaderProgram, fragmentShader);
	glLinkProgram(shaderProgram);
	//链接错误检查
	glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
	if (!success) {
		glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
		std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
	}
	glDeleteShader(vertexShader);
	glDeleteShader(fragmentShader);
  • glCreateShader 创建着色器
  • glDeleteShader 删除着色器句柄
  • glShaderSource 用着色器源代码
  • glCompileShader 需要编译着色器对象句柄
  • glCreateProgram 创建程序对象
  • glDeleteProgram 删除的程序对象的句柄
  • glAttachShader 连接着色器和程序

GLSL语言

可以通过这篇博客学习GLSL语法GLSL

下面是我随便找到几个GLSL学习案例
1、如何在三角形上使用顶点颜色和简单矩阵变化

// 顶点着色器
#version 330 core

layout(location = 0) in vec3 aPos; // 从应用程序传入的顶点位置属性

void main()
{
    gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); // 设置裁剪坐标
    //把坐标放进数组里去
}

// 片段着色器
#version 330 core

out vec4 FragColor; // 输出颜色

void main()
{
    FragColor = vec4(1.0, 0.5, 0.2, 1.0); // 设置片段颜色为橙色
}

#version 330 core指定了GLSL的版本,layout(location = 0) in vec3 aPos;定义了一个输入变量,表示顶点位置。

2、较为空间复杂的变化

// 顶点着色器
#version 330 core //版本

layout(location = 0) in vec3 aPos;      // 顶点位置
layout(location = 1) in vec3 aColor;    // 顶点颜色

out vec3 ourColor;                      // 传递颜色给片段着色器

uniform mat4 model;                     // 模型矩阵
uniform mat4 view;                      // 视图矩阵
uniform mat4 projection;                // 投影矩阵

void main()
{
    gl_Position = projection * view * model * vec4(aPos, 1.0);
    ourColor = aColor;
}

// 片段着色器
#version 330 core

in vec3 ourColor;                       // 从顶点着色器传递的颜色

out vec4 FragColor;                     // 输出颜色

void main()
{
    FragColor = vec4(ourColor, 1.0);    // 将顶点颜色传递给片段颜色
}

layout(location = 1) in vec3 aColor; 定义了一个输入变量表示顶点颜色。
**out vec3 ourColor; **将颜色从顶点着色器传递到片段着色器。
**uniform mat4 model;, uniform mat4 view;, uniform mat4 projection; **定义了三个uniform变量,表示模型矩阵、视图矩阵和投影矩阵。
**gl_Position = projection * view * model * vec4(aPos, 1.0); **在顶点着色器中进行了矩阵变换。

3、深度纹理的可视化。该程序的主要目的是将深度纹理映射到屏幕上,以便可视化深度信息。

#version 330 core
out vec4 FragColor;

in vec2 TexCoords;

uniform sampler2D depthMap;
uniform float near_plane;
uniform float far_plane;

 //required when using a perspective projection matrix
float LinearizeDepth(float depth)
{
    float z = depth * 2.0 - 1.0; // Back to NDC 
    return (2.0 * near_plane * far_plane) / (far_plane + near_plane - z * (far_plane - near_plane));
}

void main()
{             
    float depthValue = texture(depthMap, TexCoords).r; // 将深度值转换回裁剪空间坐标
    //FragColor = vec4(vec3(LinearizeDepth(depthValue) / far_plane), 1.0); // perspective
    FragColor = vec4(vec3(depthValue), 1.0); // orthographic
}
  • out vec4 FragColor; 表示片段着色器的输出颜色。
  • in vec2 TexCoords; 表示从顶点着色器传递过来的纹理坐标。
  • uniform sampler2D depthMap; 是深度纹理的纹理单元。
  • uniform float near_plane; 和 uniform float far_plane; 是近平面和远平面的值,它们在LinearizeDepth函数中用于线性化深度值。

这个函数用于将深度值从非线性空间转换为线性空间,以更好地在屏幕上显示深度信息。在此之后,FragColor 将深度值映射到颜色输出。在当前的注释中,它使用 vec3(depthValue) 将深度值映射到RGB颜色通道。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

StreamCoding

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值