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

opengl 学习(三)-----着色器

着色器

  • 分类
  • demo
  • 效果
  • 解析
  • 教程

分类

OPengl C++

demo

#include "glad/glad.h"
#include "glfw3.h"
#include <iostream>
#include <cmath>
#include <vector>#include <string>
#include <fstream>
#include <sstream>using namespace std;/******************************************************/
class Shader
{
public:unsigned int ID;// constructor generates the shader on the fly// ------------------------------------------------------------------------Shader(const char* vertexPath, const char* fragmentPath){// 1. retrieve the vertex/fragment source code from filePathstd::string vertexCode;std::string fragmentCode;std::ifstream vShaderFile;std::ifstream fShaderFile;// ensure ifstream objects can throw exceptions:vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);try{// open filesvShaderFile.open(vertexPath);fShaderFile.open(fragmentPath);std::stringstream vShaderStream, fShaderStream;// read file's buffer contents into streamsvShaderStream << vShaderFile.rdbuf();fShaderStream << fShaderFile.rdbuf();// close file handlersvShaderFile.close();fShaderFile.close();// convert stream into stringvertexCode = vShaderStream.str();fragmentCode = fShaderStream.str();}catch (std::ifstream::failure& e){std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ: " << e.what() << std::endl;}const char* vShaderCode = vertexCode.c_str();const char* fShaderCode = fragmentCode.c_str();// 2. compile shadersunsigned int vertex, fragment;// vertex shadervertex = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertex, 1, &vShaderCode, NULL);glCompileShader(vertex);checkCompileErrors(vertex, "VERTEX");// fragment Shaderfragment = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragment, 1, &fShaderCode, NULL);glCompileShader(fragment);checkCompileErrors(fragment, "FRAGMENT");// shader ProgramID = glCreateProgram();glAttachShader(ID, vertex);glAttachShader(ID, fragment);glLinkProgram(ID);checkCompileErrors(ID, "PROGRAM");// delete the shaders as they're linked into our program now and no longer necessaryglDeleteShader(vertex);glDeleteShader(fragment);}// activate the shader// ------------------------------------------------------------------------void use(){glUseProgram(ID);}// utility uniform functions// ------------------------------------------------------------------------void setBool(const std::string& name, bool value) const{glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);}// ------------------------------------------------------------------------void setInt(const std::string& name, int value) const{glUniform1i(glGetUniformLocation(ID, name.c_str()), value);}// ------------------------------------------------------------------------void setFloat(const std::string& name, float value) const{glUniform1f(glGetUniformLocation(ID, name.c_str()), value);}private:// utility function for checking shader compilation/linking errors.// ------------------------------------------------------------------------void checkCompileErrors(unsigned int shader, std::string type){int success;char infoLog[1024];if (type != "PROGRAM"){glGetShaderiv(shader, GL_COMPILE_STATUS, &success);if (!success){glGetShaderInfoLog(shader, 1024, NULL, infoLog);std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;}}else{glGetProgramiv(shader, GL_LINK_STATUS, &success);if (!success){glGetProgramInfoLog(shader, 1024, NULL, infoLog);std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;}}}
};
/******************************************************/void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;int main()
{// glfw: initialize and configure// ------------------------------glfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);#ifdef __APPLE__glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif// glfw window creation// --------------------GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);if (window == NULL){std::cout << "Failed to create GLFW window" << std::endl;glfwTerminate();return -1;}glfwMakeContextCurrent(window);glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);// glad: load all OpenGL function pointers// ---------------------------------------if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){std::cout << "Failed to initialize GLAD" << std::endl;return -1;}// build and compile our shader program// ------------------------------------Shader ourShader("3.3.shader.vs", "3.3.shader.fs"); // you can name your shader files however you like// set up vertex data (and buffer(s)) and configure vertex attributes// ------------------------------------------------------------------float vertices[] = {// positions         // colors0.5f, -0.5f, 0.0f,  1.0f, 0.0f, 0.0f,  // bottom right-0.5f, -0.5f, 0.0f,  0.0f, 1.0f, 0.0f,  // bottom left0.0f,  0.5f, 0.0f,  0.0f, 0.0f, 1.0f   // top };unsigned int VBO, VAO;glGenVertexArrays(1, &VAO);glGenBuffers(1, &VBO);// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).glBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);// position attributeglVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);glEnableVertexAttribArray(0);// color attributeglVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));glEnableVertexAttribArray(1);// You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other// VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.// glBindVertexArray(0);// render loop// -----------while (!glfwWindowShouldClose(window)){// input// -----processInput(window);// render// ------glClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);// render the triangleourShader.use();glBindVertexArray(VAO);glDrawArrays(GL_TRIANGLES, 0, 3);// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)// -------------------------------------------------------------------------------glfwSwapBuffers(window);glfwPollEvents();}// optional: de-allocate all resources once they've outlived their purpose:// ------------------------------------------------------------------------glDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);// glfw: terminate, clearing all previously allocated GLFW resources.// ------------------------------------------------------------------glfwTerminate();return 0;
}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow* window)
{if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)glfwSetWindowShouldClose(window, true);
}// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{// make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays.glViewport(0, 0, width, height);
}
  • 3.3.shader.vs
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;out vec3 ourColor;void main()
{gl_Position = vec4(aPos, 1.0);ourColor = aColor;
}
  • 3.3.shader.fs
#version 330 core
out vec4 FragColor;in vec3 ourColor;void main()
{FragColor = vec4(ourColor, 1.0f);
}

效果

请添加图片描述

解析

教程

https://learnopengl-cn.github.io/01%20Getting%20started/05%20Shaders/

相关文章:

opengl 学习(三)-----着色器

着色器 分类demo效果解析教程 分类 OPengl C demo #include "glad/glad.h" #include "glfw3.h" #include <iostream> #include <cmath> #include <vector>#include <string> #include <fstream> #include <sstream>…...

电销平台架构的演变与升级

简介 信也科技电销平台承载了公司400多坐席的日常外呼任务&#xff0c;随着公司业务规模不断增长&#xff0c;业务复杂度不断提升&#xff0c;营销模式需要多样化&#xff0c;营销流程需要更加灵活。为了更好地赋能业务、提高客户转化率&#xff0c;电销平台不断升级优化&#…...

轻薄蓝牙工牌室内人员定位应用

在现代化企业管理的背景下&#xff0c;轻薄蓝牙工牌人员定位应用逐渐崭露头角&#xff0c;成为提升企业效率和安全性的重要工具。本文将从轻薄蓝牙工牌的定义、特点、应用场景以及未来发展趋势等方面&#xff0c;对其进行全面深入的探讨。 一、轻薄蓝牙工牌的定义与特点 轻薄…...

好物周刊#46:在线工具箱

https://github.com/cunyu1943 村雨遥的好物周刊&#xff0c;记录每周看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;每周五发布。 一、项目 1. twelvet 一款基于 Spring Cloud Alibaba 的权限管理系统&#xff0c;集成市面上流行库&#xff0c;可以作用为快…...

20240306-1-大数据的几个面试题目

面试题目 1. 相同URL 题目: 给定a、b两个文件&#xff0c;各存放50亿个url&#xff0c;每个url各占64字节&#xff0c;内存限制是4G&#xff0c;让你找出a、b文件共同的url&#xff1f; 方案1&#xff1a;估计每个文件的大小为50G64320G&#xff0c;远远大于内存限制的4G。所以…...

Vue中如何处理用户权限?

在前端开发中&#xff0c;处理用户权限是非常重要的一个方面。Vue作为一种流行的前端框架&#xff0c;提供了很多便捷的方式来管理用户权限。本文将介绍一些Vue中处理用户权限的方法 1. 使用路由守卫 Vue Router提供了一个功能强大的功能&#xff0c;即导航守卫&#xff08;N…...

【STM32】HAL库 CubeMX教程---基本定时器 定时

目录 一、基本定时器的作用 二、常用型号的TIM时钟频率 三、CubeMX配置 四、编写执行代码 实验目标&#xff1a; 通过CUbeMXHAL&#xff0c;配置TIM6&#xff0c;1s中断一次&#xff0c;闪烁LED。 一、基本定时器的作用 基本定时器&#xff0c;主要用于实现定时和计数功能…...

2024年最新整理腾讯云学生服务器价格、续费和购买流程

2024年腾讯云学生服务器优惠活动「云校园」&#xff0c;学生服务器优惠价格&#xff1a;轻量应用服务器2核2G学生价30元3个月、58元6个月、112元一年&#xff0c;轻量应用服务器4核8G配置191.1元3个月、352.8元6个月、646.8元一年&#xff0c;CVM云服务器2核4G配置842.4元一年&…...

【QT】重载的信号槽/槽函数做lambda表达式

重载的信号槽 函数指针&#xff1a; int fun(int a,long b) int (*funp)(int, long) fun; 实现回调函数就需要函数指针 信号重载 派生类槽函数发送两个信号 派生类给父类发两个信号 void (SubWidget::*mysigsub)() &SubWidget::sigSub;connect(&subw,mysigsub,t…...

C++之类(一)

1&#xff0c;封装 1.1 封装的引用 封装是C面向对象三大特性之一 封装的意义&#xff1a; 将属性和行为作为一个整体&#xff0c;表现生活中的事物 将属性和行为加以权限控制 1.1.1 封装意义一&#xff1a; 在设计类的时候&#xff0c;属性和行为写在一起&#xff0c;表…...

【工具类】repo是什么,repo常用命令,repo和git和git-repo的关系

1. repo 1. repo 1.1. repo是什么1.2. 安装1.3. repo 命令 1.3.1. repo help1.3.2. repo init1.3.3. repo sync1.3.4. repo upload1.3.5. repo start1.3.6. repo forall 1.4. mainfest 文件1.5. git-repo简介(非android repo)1.6. 参考资料 1.1. repo是什么 Repo 是一个 go…...

Java中可以实现的定时任务策略

Java中可以实现的定时任务策略 文章目录 Java中可以实现的定时任务策略自定义独立线程JDK提供的调度线程池-**ScheduledExecutorService**内核是Spring的Task执行调度quartz调度 #mermaid-svg-mQ9rPqk0Ds3ULnvD {font-family:"trebuchet ms",verdana,arial,sans-seri…...

【目标分类图像增强方法】

图像增强方法及其原理 目标分类图像增强是一种用于提高深度学习模型泛化能力的技术&#xff0c;通过在训练过程中对原始图像进行各种变换来增加模型所见数据的多样性。以下是几种常见的图像增强方法及其原理&#xff1a; 几何变换&#xff1a; 旋转&#xff08;Rotation&#…...

游戏盾如何应对微商城网站DDoS攻击

游戏盾如何应对微商城网站DDoS攻击&#xff1f;随着电子商务的快速发展&#xff0c;微商城网站已成为众多商家开展在线业务的重要平台。然而&#xff0c;与此同时&#xff0c;网络安全威胁也愈发严重。其中&#xff0c;分布式拒绝服务&#xff08;DDoS&#xff09;攻击是一种常…...

安卓手机如何使用JuiceSSH实现公网远程连接本地Linux服务器

文章目录 1. Linux安装cpolar2. 创建公网SSH连接地址3. JuiceSSH公网远程连接4. 固定连接SSH公网地址5. SSH固定地址连接测试 处于内网的虚拟机如何被外网访问呢?如何手机就能访问虚拟机呢? cpolarJuiceSSH 实现手机端远程连接Linux虚拟机(内网穿透,手机端连接Linux虚拟机) …...

钉钉群内自定义机器人发送消息功能实现

文章目录 钉钉群内自定义机器人发送消息功能实现1、设置webhook自定义机器人2、查看官方文档&#xff0c;使用open api3、编写业务代码4、发送成功结果如下 钉钉群内自定义机器人发送消息功能实现 1、设置webhook自定义机器人 设置关键词 添加完成后&#xff0c;获得改机器人的…...

网站维护3年15000元,贵不贵?市场价多少

一般来说&#xff0c;给公司做好网站上线之后&#xff0c;网站就进入了运维期间&#xff0c;某功力公司给客户收费3年15000元网站运维费用&#xff0c;到底高不高呢&#xff1f; 首先&#xff0c;来看看网站运维都有哪些项目 网站运维涉及多个项目和任务&#xff0c;包括但不限…...

ROS 2基础概念#5:执行器(Executor)| ROS 2学习笔记

在ROS 2中&#xff0c;Executor是一个核心概念&#xff0c;负责管理节点&#xff08;Node&#xff09;中的回调函数&#xff0c;如订阅消息的回调、服务请求的回调、定时器回调等。Executor决定了何时以及如何执行这些回调&#xff0c;从而在ROS 2系统中实现异步编程。 ROS 2 …...

Unity 动画(旧版-新版)

旧版 旧版-动画组件&#xff1a;Animation 窗口-动画 动画文件后缀: .anim 将制作后的动画拖动到Animation组件上 旧版的操作 using System.Collections; using System.Collections.Generic; using UnityEngine;public class c1 : MonoBehaviour {// Start is called before…...

Linux和Windows操作系统线程调度策略

本文介绍Linux和Windows操作系统线程调度策略。 不同的操作系统具有不同的线程调度策略&#xff0c;本文针对常见的操作系统&#xff08;Linux和Windows操作系统&#xff09;对其线程调度策略作简要说明&#xff0c;并不对其内在运行机制作详细介绍。 1.Linux操作系统线程调度…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述&#xff1a;海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而&#xff0c;目前该领域仍面临一个挑战&#xff0c;即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

FFmpeg:Windows系统小白安装及其使用

一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】&#xff0c;注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录&#xff08;即exe所在文件夹&#xff09;加入系统变量…...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作&#xff1a;验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化&#xff1a;测试aof和aof持久化机制&#xff0c;确保数据在开启后正确恢复。 事务&#xff1a;检查事务的原子性和回滚机制。 发布订阅&#xff1a;确保消息正确传递。 2、性…...

第7篇:中间件全链路监控与 SQL 性能分析实践

7.1 章节导读 在构建数据库中间件的过程中&#xff0c;可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中&#xff0c;必须做到&#xff1a; &#x1f50d; 追踪每一条 SQL 的生命周期&#xff08;从入口到数据库执行&#xff09;&#…...