当前位置: 首页 > wzjs >正文

平谷区建设委员会网站手机在线制作网站

平谷区建设委员会网站,手机在线制作网站,编辑目录中的字体 wordpress,wordpress 日本主题文章目录 1.GLSL语言简介本节案例 code 1 2.GLSL的数据类型① 向量(Vector)- 向量重组示例- 向量重组禁忌 3.GLSL的输入输出本节案例 code 2 4.着色器示例5.Uniform本节案例 code 3 通过第一节 【OpenGL 001】Ubuntu 搭建 GLFW 环境及其相关测试 demo 想必已经搭建好了GLFW环境…

文章目录

      • 1.GLSL语言简介
        • @本节案例 code 1
      • 2.GLSL的数据类型
        • ① 向量(Vector)
          • - 向量重组示例
          • - 向量重组禁忌
      • 3.GLSL的输入输出
        • @本节案例 code 2
      • 4.着色器示例
      • 5.Uniform
        • @本节案例 code 3

通过第一节 【OpenGL 001】Ubuntu 搭建 GLFW 环境及其相关测试 demo 想必已经搭建好了GLFW环境,了解了 OpenGL 基础,这节开始通过 GLFW 对 OpenGL 进一步学习。


1.GLSL语言简介

上一节已经介绍过着色器,那么,着色器使用 GLSL(OpenGL Shading Language)语言编写,GLSL是一种类C语言,用于图形计算,包含了一些针对向量和矩阵操作的有用特性。

main函数是GLSL着色器的入口点,所有的着色操作都在这里进行。

① 以下是一个简单着色器的代码:

功能 - 顶点着色器的功能就是简单地接收顶点位置,并传递给GPU去绘制

// 指定GLSL的版本号,此处使用 3.30 核心版本,即 OpenGL 3.3 版本
#version 330 core// 输入顶点位置,通过vec3(三维向量)表示
layout(location = 0) in vec3 aPos;void main()
{// 把输入的顶点位置传给 gl_Position,这是GPU用来绘制的顶点位置// 将三维顶点位置转换成vec4gl_Position = vec4(aPos, 1.0);
}

对于顶点着色器,每个输入变量也叫顶点属性(Vertex Attribute)。

可声明的顶点属性是有上限的,它一般由硬件来决定。OpenGL确保至少有16个包含4分量的顶点属性可用,但是有些硬件或许允许更多的顶点属性,可以查询GL_MAX_VERTEX_ATTRIBS来获取具体的上限:

@本节案例 code 1

查询 GL_MAX_VERTEX_ATTRIBS:

#include <glad/glad.h>
#include <GLFW/glfw3.h>#include <iostream>int main()
{glfwInit();GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL); glfwMakeContextCurrent(window);if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){std::cout << "Failed to initialize GLAD" << std::endl;return -1;}int nrAttributes;glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &nrAttributes);std::cout << "Maximum nr of vertex attributes supported: " << nrAttributes << std::endl;glfwTerminate();return 0;
}

compile and run:

[jn@jn build]$ make
Consolidate compiler generated dependencies of target glfwTest
[ 33%] Building CXX object CMakeFiles/glfwTest.dir/main.cpp.o
[ 66%] Linking CXX executable glfwTest
[100%] Built target glfwTest
[jn@jn build]$ ./glfwTest
Maximum nr of vertex attributes supported: 16
[jn@jn build]$

2.GLSL的数据类型

GLSL中包含C等其它语言大部分的默认基础数据类型:int、float、double、uint和bool。
向量(Vector)和矩阵(Matrix)是GLSL的两种容器类型(用于数据存储的数据结构)。

① 向量(Vector)

GLSL中的向量是一个可以包含有2、3或者4个分量的容器,分量的类型可以是前面默认基础类型的任意一个。它们可以是下面的形式(n代表分量的数量):

类型含义
vecn包含 n 个 float 分量的默认向量
bvecn包含 n 个 bool 分量的向量
ivecn包含 n 个 int 分量的向量
uvecn包含 n 个 unsigned int 分量的向量
dvecn包含 n 个 double 分量的向量

一个向量的分量可以通过vec.x这种方式获取,这里x是指这个向量的第一个分量。你可以分别使用.x、.y、.z和.w来获取它们的第1、2、3、4个分量。GLSL也允许对颜色使用r,g,b,a,或是对纹理坐标使用stpq访问相同的分量。

- 向量重组示例

假设有一个四维向量 vec4,其分量分别为 (x, y, z, w)。以下是一些重组的示例:

可以如下这么做:

  • 提取和重组分量

    vec4 v = vec4(1.0, 2.0, 3.0, 4.0);
    vec3 v1 = v.xyz;   // 结果是 (1.0, 2.0, 3.0)
    vec2 v2 = v.xy;    // 结果是 (1.0, 2.0)
    
  • 重组分量

    vec4 v = vec4(1.0, 2.0, 3.0, 4.0);
    vec4 v1 = v.zwxy;  // 结果是 (3.0, 4.0, 1.0, 2.0)
    vec4 v2 = v.ywzx;  // 结果是 (2.0, 4.0, 1.0, 3.0)
    
  • 颜色分量重组

    vec4 color = vec4(0.5, 0.8, 0.3, 1.0);
    vec4 newColor = color.bgra;  // 结果是 (0.3, 1.0, 0.8, 0.5)
    

- 向量重组禁忌

不可以如下这么做:

vec4 v1 = vec4(1.0, 2.0, 3.0, 4.0);
vec3 v2 = vec3(5.0, 6.0, 7.0);// 错误:不能从 v1 和 v2 中直接组合一个新的向量
vec4 v3 = v1.xyzw + v2; // 这会引发错误,因为 v2 不是 vec4 类型

向量重组还不能

vec4 v = vec4(1.0, 2.0, 3.0, 4.0);// 错误:不能重组成 vec5,因为没有 vec5 类型
vec5 v2 = v.xyzw; // vec5 不存在

以及向量重组不能

vec3 v = vec3(1.0, 2.0, 3.0);// 错误: vec3 的重组不能包含重复的分量
vec4 v2 = v.xyzx; // 错误,因为 vec4 中不能有两个相同的分量

并且向量重组不能

vec4 v = vec4(1.0, 2.0, 3.0, 4.0);// 错误:重组不能处理条件逻辑
vec4 result = (v.x > 2.0) ? v.yzxw : v.zwxy; // 需要额外的条件处理

② 矩阵(Matrix)
矩阵是用于表示和处理图形变换的重要工具。矩阵在图形管线中的作用主要是进行各种空间变换,如模型变换、视图变换和投影变换。了解如何使用矩阵可以帮助实现更复杂和灵活的图形效果。后续用到的话,做更多介绍。

3.GLSL的输入输出

GLSL定义了in和out关键字来声明输入和输出数据。

顶点着色器的输入是从顶点数据中直接接收,另外顶点着色器使用location这一元数据指定输入变量。例如,layout (location = 0)。顶点着色器需要为其输入提供了额外的layout标识,这样才能把它链接到顶点数据。

layout (location = 0) 标识符可以省略,可以在OpenGL代码中使用glGetAttribLocation查询属性位置值。

@本节案例 code 2

见 vertexShaderSource ,省略 layout(location = 0) 和 layout(location = 1),然后使用 glGetAttribLocation 获取位置。

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <stdio.h>// Vertex and Fragment shader source code
const char* vertexShaderSource = R"(
#version 330 core
//layout(location = 0) in vec3 aPos; // Attribute 0
//layout(location = 1) in vec3 aColor; // Attribute 1
in vec3 aPos; // Attribute 0
in vec3 aColor; // Attribute 1out vec3 vertexColor;void main() {gl_Position = vec4(aPos, 1.0);vertexColor = aColor;
}
)";const char* fragmentShaderSource = R"(
#version 330 core
in vec3 vertexColor;out vec4 FragColor;void main() {FragColor = vec4(vertexColor, 1.0);
}
)";void framebuffer_size_callback(GLFWwindow* window, int width, int height) {glViewport(0, 0, width, height);
}GLuint compileShader(GLenum type, const char* source) {GLuint shader = glCreateShader(type);glShaderSource(shader, 1, &source, NULL);glCompileShader(shader);GLint success;GLchar infoLog[512];glGetShaderiv(shader, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(shader, 512, NULL, infoLog);fprintf(stderr, "Shader compilation failed: %s\n", infoLog);}return shader;
}GLuint createShaderProgram() {GLuint vertexShader = compileShader(GL_VERTEX_SHADER, vertexShaderSource);GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER, fragmentShaderSource);GLuint shaderProgram = glCreateProgram();glAttachShader(shaderProgram, vertexShader);glAttachShader(shaderProgram, fragmentShader);glLinkProgram(shaderProgram);GLint success;GLchar infoLog[512];glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);if (!success) {glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);fprintf(stderr, "Program linking failed: %s\n", infoLog);}glDeleteShader(vertexShader);glDeleteShader(fragmentShader);return shaderProgram;
}void setupVertexAttributes(GLuint shaderProgram, GLuint& VAO, GLuint& VBO, GLuint& EBO) {glUseProgram(shaderProgram);// Get vertex attribute locationsGLint posAttrib = glGetAttribLocation(shaderProgram, "aPos");GLint colorAttrib = glGetAttribLocation(shaderProgram, "aColor");// Vertex dataGLfloat vertices[] = {// positions        // colors0.5f,  0.5f, 0.0f,  1.0f, 0.0f, 0.0f, // top right0.5f, -0.5f, 0.0f,  0.0f, 1.0f, 0.0f, // bottom right-0.5f, -0.5f, 0.0f,  0.0f, 0.0f, 1.0f, // bottom left-0.5f,  0.5f, 0.0f,  1.0f, 1.0f, 1.0f  // top left };GLuint indices[] = {  // Note that we start from 0!0, 1, 3, // first triangle1, 2, 3  // second triangle};glGenVertexArrays(1, &VAO);glGenBuffers(1, &VBO);glGenBuffers(1, &EBO);glBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);// Set position attributeglVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);glEnableVertexAttribArray(posAttrib);// Set color attributeglVertexAttribPointer(colorAttrib, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));glEnableVertexAttribArray(colorAttrib);glBindVertexArray(0);
}int main() {// Initialize GLFWif (!glfwInit()) {fprintf(stderr, "Failed to initialize GLFW\n");return -1;}glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);// Create a windowed mode window and its OpenGL contextGLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Example", NULL, NULL);if (!window) {fprintf(stderr, "Failed to create GLFW window\n");glfwTerminate();return -1;}// Make the window's context currentglfwMakeContextCurrent(window);// Load OpenGL function pointers using gladif (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {fprintf(stderr, "Failed to initialize OpenGL context\n");return -1;}// Set the viewport size callbackglfwSetFramebufferSizeCallback(window, framebuffer_size_callback);// Compile and link shadersGLuint shaderProgram = createShaderProgram();// Setup vertex attributesGLuint VAO, VBO, EBO;setupVertexAttributes(shaderProgram, VAO, VBO, EBO);// Render loopwhile (!glfwWindowShouldClose(window)) {// Clear the color bufferglClear(GL_COLOR_BUFFER_BIT);// RenderglUseProgram(shaderProgram);glBindVertexArray(VAO);glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);// Swap buffersglfwSwapBuffers(window);// Poll for and process eventsglfwPollEvents();}// CleanupglDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);glDeleteBuffers(1, &EBO);glDeleteProgram(shaderProgram);glfwDestroyWindow(window);glfwTerminate();return 0;
}

Code 2 Result:
在这里插入图片描述

4.着色器示例

顶点着色器:

#version 330 core
layout (location = 0) in vec3 aPos; // 位置变量的属性位置值为0out vec4 vertexColor; // 为片段着色器指定一个颜色输出void main()
{gl_Position = vec4(aPos, 1.0); // 注意我们如何把一个vec3作为vec4的构造器的参数vertexColor = vec4(0.5, 0.0, 0.0, 1.0); // 把输出变量设置为暗红色
}

片段着色器:

#version 330 core
out vec4 FragColor;in vec4 vertexColor; // 从顶点着色器传来的输入变量(名称相同、类型相同)void main()
{FragColor = vertexColor;
}

5.Uniform

Uniform是另一种从我们的应用程序在 CPU 上传递数据到 GPU 上的着色器的方式,但uniform和顶点属性有些不同。首先,uniform是全局的(Global)。全局意味着uniform变量必须在每个着色器程序对象中都是独一无二的,而且它可以被着色器程序的任意着色器在任意阶段访问。第二,无论你把uniform值设置成什么,uniform会一直保存它们的数据,直到它们被重置或更新。

要在 GLSL 中声明 uniform,我们只需将 uniform 关键字添加到具有类型和名称的着色器中。从那时起,我们就可以在着色器中使用新声明的 uniform。我们来看看这次是否能通过uniform设置三角形的颜色:

#version 330 core
out vec4 FragColor;uniform vec4 ourColor; // 在OpenGL程序代码中设定这个变量void main()
{FragColor = ourColor;
}

在片段着色器中声明了一个uniform vec4的ourColor,并把片段着色器的输出颜色设置为uniform值的内容。因为uniform是全局变量,我们可以在任何着色器中定义它们,而无需通过顶点着色器作为中介。顶点着色器中不需要这个uniform,所以我们不用在那里定义它。

如果声明了一个uniform却在GLSL代码中没用过,编译器会静默移除这个变量,导致最后编译出的版本中并不会包含它,这可能导致几个非常麻烦的错误!

对于使用 uniform vec4 ourColor;,如下,获取该变量的着色器的uniform属性的索引位置。当得到uniform的索引/位置值后,我们就可以更新它的值了。这次我们不去给像素传递单独一个颜色,而是让它随着时间改变颜色:

float timeValue = glfwGetTime();
float greenValue = (sin(timeValue) / 2.0f) + 0.5f;
int vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");
glUseProgram(shaderProgram);
glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);

完整代码如下:

@本节案例 code 3
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <stdio.h>
#include <cmath> // For sin() function// Vertex and Fragment shader source code
const char* vertexShaderSource = R"(
#version 330 core
layout(location = 0) in vec3 aPos; // Attribute 0
layout(location = 1) in vec3 aColor; // Attribute 1out vec3 vertexColor;void main() {gl_Position = vec4(aPos, 1.0);vertexColor = aColor;
}
)";const char* fragmentShaderSource = R"(
#version 330 core
in vec3 vertexColor;out vec4 FragColor;uniform vec4 ourColor;void main() {FragColor = ourColor;
}
)";void framebuffer_size_callback(GLFWwindow* window, int width, int height) {glViewport(0, 0, width, height);
}GLuint compileShader(GLenum type, const char* source) {GLuint shader = glCreateShader(type);glShaderSource(shader, 1, &source, NULL);glCompileShader(shader);GLint success;GLchar infoLog[512];glGetShaderiv(shader, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(shader, 512, NULL, infoLog);fprintf(stderr, "Shader compilation failed: %s\n", infoLog);}return shader;
}GLuint createShaderProgram() {GLuint vertexShader = compileShader(GL_VERTEX_SHADER, vertexShaderSource);GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER, fragmentShaderSource);GLuint shaderProgram = glCreateProgram();glAttachShader(shaderProgram, vertexShader);glAttachShader(shaderProgram, fragmentShader);glLinkProgram(shaderProgram);GLint success;GLchar infoLog[512];glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);if (!success) {glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);fprintf(stderr, "Program linking failed: %s\n", infoLog);}glDeleteShader(vertexShader);glDeleteShader(fragmentShader);return shaderProgram;
}void setupVertexAttributes(GLuint& VAO, GLuint& VBO) {GLfloat vertices[] = {// positions        // colors0.5f,  0.5f, 0.0f,  1.0f, 0.0f, 0.0f, // top right0.5f, -0.5f, 0.0f,  0.0f, 1.0f, 0.0f, // bottom right-0.5f, -0.5f, 0.0f,  0.0f, 0.0f, 1.0f, // bottom left-0.5f,  0.5f, 0.0f,  1.0f, 1.0f, 1.0f  // top left };GLuint indices[] = {  // Note that we start from 0!0, 1, 3, // first triangle1, 2, 3  // second triangle};glGenVertexArrays(1, &VAO);glGenBuffers(1, &VBO);GLuint EBO;glGenBuffers(1, &EBO);glBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);// Set position attributeglVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);glEnableVertexAttribArray(0);// Set color attributeglVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));glEnableVertexAttribArray(1);glBindVertexArray(0);
}int main() {// Initialize GLFWif (!glfwInit()) {fprintf(stderr, "Failed to initialize GLFW\n");return -1;}glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);// Create a windowed mode window and its OpenGL contextGLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Dynamic Color Example", NULL, NULL);if (!window) {fprintf(stderr, "Failed to create GLFW window\n");glfwTerminate();return -1;}// Make the window's context currentglfwMakeContextCurrent(window);// Load OpenGL function pointers using gladif (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {fprintf(stderr, "Failed to initialize OpenGL context\n");return -1;}// Set the viewport size callbackglfwSetFramebufferSizeCallback(window, framebuffer_size_callback);// Compile and link shadersGLuint shaderProgram = createShaderProgram();// Setup vertex attributesGLuint VAO, VBO;setupVertexAttributes(VAO, VBO);// Render loopwhile (!glfwWindowShouldClose(window)) {// Clear the color bufferglClear(GL_COLOR_BUFFER_BIT);// Calculate dynamic green valuefloat timeValue = glfwGetTime();float greenValue = (sin(timeValue) / 2.0f) + 0.5f;// Use shader program and set uniform colorglUseProgram(shaderProgram);GLint vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);// RenderglBindVertexArray(VAO);glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);// Swap buffersglfwSwapBuffers(window);// Poll for and process eventsglfwPollEvents();}// CleanupglDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);glDeleteProgram(shaderProgram);glfwDestroyWindow(window);glfwTerminate();return 0;
}

Code Result 动态呼吸灯效果:
在这里插入图片描述

待续。。。

http://www.dtcms.com/wzjs/347495.html

相关文章:

  • wordpress付费下载插件排名怎么优化快
  • 巴中做网站的公司地推拉新app推广平台
  • 网站自己怎么建设廊坊首页霸屏优化
  • 哈尔滨网站开发建设公司电话搜一搜搜索
  • 大理网站建设沛宣宁波seo推广定制
  • 网站优化方案书百度指数 移民
  • python做的网站有哪些百度游戏风云榜
  • 嘉兴网站推广价格百度移动端点赞排名软件
  • 学院网站建设意义智慧教育
  • 网站怎么做才能让更多平台展现自己怎样推广呢
  • 关于加强公司 网站建设的通知哪里可以接广告
  • 山西省网站建设制作营销推广的作用
  • 好的网站建设案例郑州百度seo排名公司
  • 南通网站建设团队活动策划方案详细模板
  • 建设flash网站青岛网络seo公司
  • cms建设网站郑州网站制作公司
  • 网站建设 镇江万达自己开网店怎么运营
  • 做群头像的网站在线制作图片搜索识图入口
  • 成都定制网站建设排名优化公司口碑哪家好
  • 做衣服 网站关键词排名顾问
  • 丹东做网站seo外包公司报价
  • 如何配置php网站新媒体营销成功案例
  • 多语言网站怎么实现北京seo网络推广
  • 给公司做网站怎么弄技术培训机构排名前十
  • 十大网站免费网络营销平台的主要功能
  • 广州专业的做网站公司seo点击排名器
  • 车辆对比那个网站做的好电子商务网站建设与维护
  • 做ppt的软件怎样下载网站百度推广账户登录首页
  • 永久免费的wap建站平台百度关键词排名查询工具
  • 东莞网站网络百度推广400电话