OpenGL 自定义着色器(Shaders)

自定义着色器类

声明

#pragma once#include<string>class Shaders
{
public:Shaders(const char* vertexPath, const char* fragmentPath);~Shaders();std::string vertexString;std::string fragmentString;const char* vertexSource;const char* fragmentSource;unsigned int ID; // shaderProgram 的idvoid use();
private:void checkCompileErrors(unsigned int id, std::string type);};

源文件

#include "Shaders.h"
#include<fstream>
#include<iostream>
#include<sstream>
#define GLEW_STATIC // 这个一定要加不然报错 静态链接库
#include<GL/glew.h>
#include<GLFW/glfw3.h>Shaders::Shaders(const char* vertexPath, const char* fragmentPath ) {std::ifstream vertexFile;std::ifstream fragmentFile;std::stringstream vertexSStream;std::stringstream fragmentSStream;vertexFile.open(vertexPath);fragmentFile.open(fragmentPath);vertexFile.exceptions(std::ifstream::failbit || std::ifstream::badbit);fragmentFile.exceptions(std::ifstream::failbit || std::ifstream::badbit);try {if (!vertexFile.is_open() || !fragmentFile.is_open()) {throw std::exception("open file error");}//  将 输入流的内容输出给 stringstreamvertexSStream << vertexFile.rdbuf();fragmentSStream << fragmentFile.rdbuf();vertexString = vertexSStream.str();fragmentString = fragmentSStream.str();vertexSource = vertexString.c_str();fragmentSource = fragmentString.c_str();unsigned int vertex, fragment;// 创建这个着色器vertex = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertex, 1, &vertexSource, NULL);// 编译glCompileShader(vertex);checkCompileErrors(vertex, "VERTEX");fragment = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragment, 1, &fragmentSource, NULL);// 编译glCompileShader(fragment);checkCompileErrors(fragment, "FRAGMENT");//创建一个着色器程序对象ID = glCreateProgram();// 将之前编译的着色器附加到程序对象上glAttachShader(ID, vertex);glAttachShader(ID, fragment);// 用glLinkProgram链接它们glLinkProgram(ID);checkCompileErrors(ID, "PROGRAM");//删除着色器glDeleteShader(vertex);glDeleteShader(fragment);}catch (const std::exception& ex) {std::cout << ex.what() << std::endl;}
}
void Shaders::use() {glUseProgram(ID);
}
void Shaders::checkCompileErrors(unsigned int id, std::string type) {int success;char infoLog[512];if (type != "PROGRAM") {glGetShaderiv(id, GL_COMPILE_STATUS,&success);if (!success) {glGetShaderInfoLog(id, 512, NULL, infoLog);std::cout << "shader compile error:" << infoLog << std::endl;}}else {glGetProgramiv(id, GL_LINK_STATUS, &success);if (!success) {glGetProgramInfoLog(id, 512, NULL, infoLog);std::cout << "program compile error:" << infoLog << std::endl;}}
}
Shaders::~Shaders() {}

程序入口

#define GLEW_STATIC // 这个一定要加不然报错 静态链接库
#include<GL/glew.h>
#include<GLFW/glfw3.h>
#include<iostream>
#include "Shaders.h"
using namespace std;
void processInput(GLFWwindow);
void processInput(GLFWwindow* window) {//如果键盘输入esc 则触发 退出if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {// 设置 要求退出glfwSetWindowShouldClose(window, true);}
}
// 逆时针方向绘制  默认情况下,逆时针的顶点连接顺序被定义为三角形的正
// 逆时针或顺时针都是相对于观察者方向的
float vertices[] {-0.5f, 0.5f, 0.0f, 1.0f, 0,0, // 左上角 0  0.5f, -0.5f, 0.0f, 0,1.0f,0, // 右下角 10.5f, 0.5f, 0.0f, 0,0,1.0f,  // 右上角 2// 第二个三角形//0.5f, -0.5f, 0.0f,  // 右下角-0.5f, -0.5f, 0.0f , 1.0f,0,1.0f // 左下角  3//-0.5f, 0.5f, 0.0f   // 左上角
};
// 使用索引来减小画点的开销 (未用索引缓冲对象时,每个点都需要画一次(即使重复了))
unsigned int indices[] {0,1,2, //第一个三角形的索引1,3,0 //第二个三角形的索引
};int main() {// 初始化GLFWglfwInit();// 提示 我们使用的版本是3.3// 主版本glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);// 次版本glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);// 简介glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);// 创建一个窗口对象GLFWwindow* window = glfwCreateWindow(800, 600, "Test window", NULL, NULL);if (window == NULL) {cout << "open window failed." << endl;// 终止 glfwglfwTerminate();}// 绑定window到上下文对象 创建完窗口我们就可以通知GLFW将我们窗口的上下文设置为当前线程的主上下文了glfwMakeContextCurrent(window);glewExperimental = true;// GLEW_OK 0//init GLEWif (glewInit() != GLEW_OK) {cout << "glew init failed." << endl;// 终止 glfwglfwTerminate();return -1;}// OpenGL渲染窗口的尺寸大小 // glViewport函数前两个参数控制窗口左下角的位置。第三个和第四个参数控制渲染窗口的宽度和高度(像素)glViewport(0, 0, 800, 600);// 设置剔除 (opegl默认正面背面都显示(不剔除))//glEnable(GL_CULL_FACE);// 剔除背面 GL_BACK 剔除正面 GL_FRONT//glCullFace(GL_BACK);// 线框模式 //第一个参数表示我们打算将其应用到所有的三角形的正面和背面,第二个参数告诉我们用线来绘制//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);//VAO对象unsigned int VAO;// 生成一个VAO对象 这个方法可以生成多个 由第一个参数决定glGenVertexArrays(1, &VAO);// 绑定 VAOglBindVertexArray(VAO);unsigned int VBO; //如果多个可以用 VBO[]数组 这个方法可以生成多个 由第一个参数决定glGenBuffers(1, &VBO);//将新创建的缓冲绑定到 GL_ARRAY_BUFFER目标上glBindBuffer(GL_ARRAY_BUFFER, VBO);// glBufferData 是一个专门用来把用户定义的数据复制到当前绑定缓冲的函数// GL_STATIC_DRAW 数据不会或几乎不会改变。glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);unsigned int EBO;glGenBuffers(1, &EBO);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);Shaders* shaders = new Shaders("./vertexSource.txt", "./fragmentSource.txt");// glVertexAttribPointer函数告诉OpenGL该如何解析顶点数据(应用到逐个顶点属性上)// 从 0号栏位 开始 将数据每三个为一组 单位为float 每次跳6*float字节 偏移为0glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);// 以顶点属性位置值作为参数,启用顶点属性;顶点属性默认是禁用的//读取到0号栏位上glEnableVertexAttribArray(0);// 读取颜色属性 从 1号栏位 开始 将数据每三个为一组 单位为float 每次跳6*float字节 偏移为3个floatglVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3*sizeof(float)));// 读取到1号栏位上 glEnableVertexAttribArray(1);//渲染循环 ,它能在我们让GLFW退出前一直保持运行。下面几行的代码就实现了一个简单的渲染循环://glfwWindowShouldClose 我们每次循环的开始前检查一次GLFW是否被要求退出while (!glfwWindowShouldClose(window)) {//自定义事件 当键盘触发esc 退出processInput(window);glClearColor(0.2, 0.3, 0.3, 1.0);// GL_COLOR_BUFFER_BIT 颜色,GL_DEPTH_BUFFER_BIT 深度 和 GL_STENCIL_BUFFER_BIT 模板// 清除前面的那一帧的颜色glClear(GL_COLOR_BUFFER_BIT);// 绑定 VAO glBindVertexArray(VAO);shaders->use();// 画三角形 从0开始 绘制三个顶点  和VBO的顶点数据(通过VAO间接绑定)来绘制图元//glDrawArrays(GL_TRIANGLES, 0, 6); 这个是不用索引画的glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);//可以不需要这个 绑定VAO的同时也会自动绑定EBO//glDrawElements函数从当前绑定到GL_ELEMENT_ARRAY_BUFFER目标的EBO中获取索引glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);//解绑VAOglBindVertexArray(0);glfwSwapBuffers(window);glfwPollEvents();}// 最后终止 glfwglfwTerminate();return 0;
}

着色器

顶点着色器

#version 330 core                                      
// 0号栏位读取顶点坐标
layout (location = 0) in vec3 aPos;                    
//1号栏位读取颜色颜色
layout (location = 1) in vec3 aColor;  
out vec4 vertexColor;                                  
void main()                                            
{                                                      
//  gl_Position 是固定的名称 用来保存 顶点坐标的gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);   vertexColor = vec4(aColor.x+0.5,aColor.y,aColor.z,1.0);
}                                                      

片段着色器

#version 330 core                          
out vec4 FragColor;                        
//uniform vec4 outColor;                     
in vec4 vertexColor;                       
void main()                                
{                                          FragColor = vertexColor;               
}                                          

未报错效果

在这里插入图片描述

报错的效果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/548062.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《统一沟通-微软-技巧》-20-Lync 2010如何在我的联系人列表中添加非联盟联系人...

Blog:http://dynamic.blog.51cto.com MSN:LiuJinFengmsn.com QQ:316190099如果加:A&#xff0e; 内部Lync用户:输入-英文名输入-中文名输入-中文名/英文名中包括的部分字符B&#xff0e; 联盟Lync用户:输入:邮件地址C&#xff0e; 非 Lync用户:在Outlook新建联系人让Lync与Outl…

texture 纹理(贴图)

纹理 纹理是一个2D图片&#xff08;甚至也有1D和3D的纹理&#xff09;&#xff0c;它可以用来添加物体的细节。 这是两张照片叠加的效果 由下面两张叠加而成 源代码 shaders类在自定义着色器 中有完整的源代码。 下边我们使用stb_image.h来解析图片。 #define GLEW_STATI…

微信开发4——PHP实现PC扫码授权登陆获取用户信息

首先须要申请,必须企业,个体工商户,媒体等&#xff0c;微信开放平台申请地址 https://open.weixin.qq.com/&#xff0c;要交300多的费用才能开通 1&#xff0c;编写入口&#xff1a;微信开放平台的扫码登陆开放的接口可以自动生成PC扫码页面&#xff0c;你得到了官方通过审核的…

计算机组成原理和体系结构----软考(到处copy)

计算机组成原理和体系结构数据的表示n进制转十进制十进制转n进制 使用短除法二进制转八进制和十六进制原码、反码、补码以及移码浮点数运算计算机结构计算机体系结构分类 - FlynnCISC 和 RISC流水线流水线计算流水线时间计算流水线吞吐率计算流水线的加速比计算流水线的效率计算…

Ubuntu16.04安装Hadoop+Spark+pyspark大数据python开发环境

一&#xff0c;安装jdk1.8.0.144 下载地址&#xff1a;www.oracle.com/technetwork/java/javase/downloads/java-archive-javase8-2177648.html Ubuntu配置jdk运行环境 export HADOOP_HOME/usr/local/hadoop export CLASSPATH$($HADOOP_HOME/bin/hadoop classpath):$CLASSPA…

使用IntelliJ IDEA和Maven管理搭建+Web+Tomcat开发环境

使用IntelliJ IDEA和Maven管理搭建WebTomcat开发环境 使用IntelliJ IDEA和Maven管理搭建WebTomcat开发环境 前言&#xff1a;原来一直使用Eclipse&#xff0c;换工作后使用IDEA&#xff0c;初识IDEA发现&#xff0c;哇&#xff0c;它的快捷键可真多啊&#xff0c;但是一路用下…

一起玩Docker之1——Ubuntu配置安装Docker运行环境并安装(Ubuntu、Centos)镜像

Docker 是一个开源的应用容器引擎&#xff0c;基于 Go 语言 并遵从Apache2.0协议开源。 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。 容器是完全使用沙箱机制&am…

SpringBoot执行器端点Actuator Endpoint

比较常用的Endpoint URL作用/actuator/health健康检查/actuator/beans查看容器中所有的Bean/actuator/mapping查看Web的URL映射/actuator/env查看环境信息 默认/actuator/health和/actuator/info是可以通过Web访问&#xff0c;其他的需要解禁 在配置文件中可以设置可以访问哪…

域内禁止不明东西连接DHCP

今天在Windows论坛看到一大牛版主分享的经验&#xff0c;赶紧挺好&#xff0c;就赶紧记下来。 http://bbs.51cto.com/thread-967999-1.html 再补充一点点 域内查看其他pc的 MAC 地址 同一网段的 直接 ping一下 对方 ip地址 然后 arp -a 一下 不通网段的 可以先在 dhc…

SpringBoot中mybatis配置多数据源

首先需要创建多个数据库 简单的user表 CREATE TABLE user (id int NOT NULL AUTO_INCREMENT,name varchar(255) DEFAULT NULL,age int DEFAULT NULL,PRIMARY KEY (id) ) ENGINEInnoDB AUTO_INCREMENT2 DEFAULT CHARSETutf8;导入项目依赖 <dependencies><dependency&g…

玩玩机器学习4——TensorFlow基础之激活函数

激活函数&#xff08;activation function&#xff09;运行时激活神经网络中某一部分神经元&#xff0c;将激活信息向后传入下一层的神经网络。神经网络之所以能解决非线性问题&#xff08;如语音、图像识别&#xff09;&#xff0c;本质上就是激活函数加入了非线性因素&#x…

玩玩机器学习5——构造单层神经网络解决非线性函数(三次函数)的曲线拟合

使用TensorFlow构造了一个隐藏层和输出层的神经网络&#xff0c;做非线性曲线的拟合 import tensorflow as tf import matplotlib.pyplot as plt import numpy as npnp.random.seed(1) x np.linspace(-1, 1, 100)[:, np.newaxis] #创建一个新维度 noise np.random.normal(0,…

HTML网页使用CDN的jquery.qrcode.min.js生成页面二维码(直接可以复制使用)

HTML页面代码 <!DOCTYPE html> <html> <head><title></title><meta http-equiv"Content-Type" content"text/html; charsetutf-8" /><meta name"generator" content"pandoc" /><meta n…

SpringBoot Web 入门

SpringBoot Web 要解决的问题&#xff1a; 导入静态资源首页模板引擎 Thymeleaf装配扩展SpringMVCCRUD拦截器国际化 SpringMVC的自动配置类为WebMvcAutoConfiguration &#xff0c;对应的properties类为WebMvcProperties //WebMvcProperties部分代码 //在application配置文…

handler类型的定时器

2019独角兽企业重金招聘Python工程师标准>>> 一、采用Handle与线程的sleep(long)方法 Handler主要用来处理接受到的消息。这只是最主要的方法&#xff0c;当然Handler里还有其他的方法供实现&#xff0c;有兴趣的可以去查API&#xff0c;这里不过多解释。 1. 定义…

Vue路由基本操作

路由index.js import Vue from vue import VueRouter from vue-router import Home from ../views/Home.vue import Me from ../views/me.vue import About from "../views/About.vue" import Centor from "/views/Center.vue" import _404 from "..…

Windows 10 搭建Python3 安装使用 protobuf

Windows 10 搭建Python3 安装使用 protobuf Protobuf对比XML、Json等其他序列化的优势 protobuf 不管是处理时间上&#xff0c;还是空间占用上都优于现有的其他序列化方式。内存暂用是java 序列化的1/9&#xff0c;时间也是差了一个数量级&#xff0c;一次操作在1us左右。缺点…

Vue + SpringBoot跨域

Vue设置 1、在项目根目录创建文件vue.config.js module.exports {devServer: {proxy: {/api: {target: http://zlf.plus, //对应自己的接口changeOrigin: true,ws: true,pathRewrite: {^/api: }}}}}2、 在main.js中配置 import Vue from vue import App from ./App.vue imp…

Windows10 64位 安装 Postgresql 数据库

Windows10 64位 安装 Postgresql 数据库 1&#xff0c;下载Postgresql 10.7 版本&#xff0c;下载地址 https://www.enterprisedb.com/downloads/postgres-postgresql-downloads 2&#xff0c;打开安装包&#xff0c;傻瓜式默认安装&#xff0c;请谨记 “数据库密码” 和 “…