OpenGL 着色器类的源码

devtools/2024/9/22 18:40:39/

编写、编译、管理着色器是件麻烦事。在着色器主题的最后,我们会写一个类来让我们的生活轻松一点,它可以从硬盘读取着色器,然后编译并链接它们,并对它们进行错误检测,这就变得很好用了。这也会让你了解该如何封装目前所学的知识到一个抽象对象中。

我们会把着色器类全部放在在头文件里,主要是为了学习用途,当然也方便移植。

我们使用C++文件流读取着色器内容,储存到几个string对象里
下一步,我们需要编译和链接着色器。注意,我们也将检查编译/链接是否失败,如果失败则打印编译时错误,调试的时候这些错误输出会及其重要(你总会需要这些错误日志的)
#ifndef SHADER_H
#define SHADER_H#include <glad/glad.h>
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>class Shader
{
public:unsigned int ID; // 着色器程序的ID// 构造函数,接受顶点和片段着色器的文件路径,生成着色器程序Shader(const char* vertexPath, const char* fragmentPath){// 1. 从文件路径中读取顶点/片段着色器的源代码std::string vertexCode;std::string fragmentCode;std::ifstream vShaderFile;std::ifstream fShaderFile;// 确保 ifstream 对象可以抛出异常:vShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);fShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);try {// 打开文件vShaderFile.open(vertexPath);fShaderFile.open(fragmentPath);std::stringstream vShaderStream, fShaderStream;// 读取文件缓冲内容到字符串流中vShaderStream << vShaderFile.rdbuf();fShaderStream << fShaderFile.rdbuf();// 关闭文件句柄vShaderFile.close();fShaderFile.close();// 将字符串流转换为字符串vertexCode   = vShaderStream.str();fragmentCode = fShaderStream.str();}catch (std::ifstream::failure& e){std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ: " << e.what() << std::endl;}// 将源代码转换为 C 字符串const char* vShaderCode = vertexCode.c_str();const char* fShaderCode = fragmentCode.c_str();// 2. 编译着色器unsigned int vertex, fragment;// 顶点着色器vertex = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertex, 1, &vShaderCode, NULL);glCompileShader(vertex);checkCompileErrors(vertex, "VERTEX");// 片段着色器fragment = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragment, 1, &fShaderCode, NULL);glCompileShader(fragment);checkCompileErrors(fragment, "FRAGMENT");// 着色器程序ID = glCreateProgram();glAttachShader(ID, vertex);glAttachShader(ID, fragment);glLinkProgram(ID);checkCompileErrors(ID, "PROGRAM");// 着色器已经链接到程序中,不再需要,删除它们glDeleteShader(vertex);glDeleteShader(fragment);}// 激活着色器程序void use() { glUseProgram(ID); }// 实用的 uniform 设置函数void setBool(const std::string &name, bool value) const{         // 设置布尔型 uniform 变量glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value); }void setInt(const std::string &name, int value) const{ // 设置整型 uniform 变量glUniform1i(glGetUniformLocation(ID, name.c_str()), value); }void setFloat(const std::string &name, float value) const{ // 设置浮点型 uniform 变量glUniform1f(glGetUniformLocation(ID, name.c_str()), value); }private:// 实用函数,用于检查着色器编译/链接错误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;}}}
};#endif

http://www.ppmy.cn/devtools/115598.html

相关文章

【JavaEE】多线程编程引入——认识Thread类

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯&#xff0c;你们的点赞收藏是我前进最大的动力&#xff01;&#xff01;希望本文内容能帮到你&#xff01; 目录 引入&#xff1a; 一&#xff1a;Thread类 1&#xff1a;Thread类可以直接调用 2&#xff1a;run方法 &a…

signalR和WebSocket的区别是什么

SignalR和WebSocket都是用于实现实时双向通信的技术&#xff0c;但它们在多个方面存在区别。以下是它们之间的主要区别&#xff1a; 1. 技术层次与协议支持 WebSocket&#xff1a; 是一种在单个TCP连接上进行全双工通信的协议。它是HTML5规范的一部分&#xff0c;提供了浏览器…

网络安全等保培训 ppt

网络安全等级保护怎么做&#xff1f;

Apache SeaTunnel Zeta引擎源码解析(三) Server端接收任务的执行流程

作者&#xff1a;刘乃杰 编辑整理&#xff1a;曾辉 引入 本系列文章是基于 Apache SeaTunnel 2.3.6版本&#xff0c;围绕Zeta引擎给大家介绍其任务是如何从提交到运行的全流程&#xff0c;希望通过这篇文档&#xff0c;对刚刚上手SeaTunnel的朋友提供一些帮助。 我们整体的文…

基于深度学习的智能电网优化

基于深度学习的智能电网优化是一种结合先进人工智能技术和电网管理的策略&#xff0c;旨在提高电力系统的效率、稳定性和可持续性。智能电网&#xff08;Smart Grid&#xff09;利用深度学习等技术来处理复杂的电力需求数据、生成精准的电力负载预测、优化电力调度、提高故障检…

全面解析流量态势感知与网络性能监控:IT运维中的核心技术

在现代IT运维中&#xff0c;网络的稳定性和业务的连续性是企业赖以生存的基石。随着数字化转型的深入&#xff0c;网络流量日益复杂&#xff0c;安全威胁愈加严峻&#xff0c;运维人员不仅需要确保网络的顺畅运行&#xff0c;还必须及时发现潜在风险并快速响应。流量态势感知与…

轻掺杂漏极(LDD)技术

轻掺杂漏极&#xff08;LDD&#xff09;是一种低能量、低电流的注入工艺&#xff0c;通过该工艺在栅极附近形成浅结&#xff0c;以减少靠近漏极处的垂直电场。对于亚微米MOSFET来说&#xff0c;LDD是必需的&#xff0c;以便抑制热电子效应&#xff0c;这种效应会导致器件退化并…

《DevOps实践指南》笔记-Part 2

一篇文章显得略长&#xff0c;本文对应第3-4章。前言、第1-2章请参考Part 1&#xff1b;第5-6章、附录、认证考试、参考资源等内容&#xff0c;请参考Part 3。 流动的技术实践 持续交付&#xff1a;降低在生产环境中部署和发布变更的风险。包括&#xff1a;打好自动化部署流水…