如何从文件中读取GLSL源码

我们为什么要选择从文件中读取GLSL源代码

  • 当程序变得复杂时,再将GLSL着色器源代码内联存储在字符串中就不合适了。

我们将两个着色器的源代码从主文件中剪切放在对应的文件vertShader.glsl和fragShader.glsl中

image-20231126004130345

代码实现

1.分别在两个.glsl文件中写入对应的代码

 //vertShader.glsl文件
 #version 430 
 void main(void) 
 {
     gl_Position = vec4(0.0, 0.0, 0.0, 1.0); 
 }
 //fragShader.glsl文件
 #version 430   
 out vec4 color;   
 void main(void)   
 { 
     if(gl_FragCoord.x < 255) 
         color = vec4(1.0, 0.0, 0.0, 1.0); 
     else color = vec4(0.0, 0.0, 1.0, 1.0);
 }

2.新增函数ReadShaderSource读取文件

//新增两个头文件
 #include <fstream>
 #include <string>
 std::string ReadShaderSource(const char* filePath)
 {
     std::string content;
     std::ifstream fileStream(filePath, std::ios::in);
     std::string line = "";
     while (!fileStream.eof())
     {
         getline(fileStream, line);
         content.append(line + '\n');
     }
     fileStream.close();
     return content;
 }

3.在CreateShaderProgram函数中对文件进行读取

unsigned int CreateShaderProgram()
 {
     std::string vertShaderStr = readShaderSource("./res/shaders/vertShader.glsl");
     std::string fragShaderStr = readShaderSource("./res/shaders/fragShader.glsl");
     const char* vertShaderSrc = vertShaderStr.c_str();
     const char* fragShaderSrc = fragShaderStr.c_str();
     //捕获编译着色器时的错误
     int vertComplied;
     int fragComplied;
     int linked;
     //创建顶点着色器和片段着色器
     unsigned int vShader = glCreateShader(GL_VERTEX_SHADER);
     unsigned int fShader = glCreateShader(GL_FRAGMENT_SHADER);
 ​
     glShaderSource(vShader, 1, &vertShaderSrc, NULL);
     glShaderSource(fShader, 1, &fragShaderSrc, NULL);
 }

4..cpp完整代码

 #include <GL/glew.h>
 #include <GLFW/glfw3.h>
 #include <iostream>
 #include <fstream>
 #include <string>
 #define numVAOs 1
 unsigned int renderingProgram;
 unsigned int vao[numVAOs];//顶点数组,必须要有
 unsigned int CreateShaderProgram();
 //读取文件中的GLSL的源代码
 std::string ReadShaderSource(const char* filePath)
 {
     std::string content;
     std::ifstream fileStream(filePath, std::ios::in);
     std::string line = "";
     while (!fileStream.eof())
     {
         getline(fileStream, line);
         content.append(line + '\n');
     }
     fileStream.close();
     return content;
 }
 ​
 //捕获GLSL代码编译失败信息函数
 void PrintShaderLog(unsigned int shader)
 {
     int len = 0;
     int chWrittn = 0;
     char* log;
     glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
     if (len > 0)
     {
         log = (char*)malloc(len);
         glGetShaderInfoLog(shader, len, &chWrittn, log);
         std::cout << "Shader Info Log: " << log << std::endl;
         free(log);
     }
 }
 //捕获GLSL链接失败信息函数
 void PrintProgramLog(int prog)
 {
     int len = 0;
     int chWrittn = 0;
     char* log;
     glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &len);
     if (len > 0)
     {
         log = (char*)malloc(len);
         glGetProgramInfoLog(prog, len, &chWrittn, log);
         std::cout << "Program Info Log: " << std::endl;
         free(log);
     }
 }
 //检查OpenGL错误函数
 bool CheckOpenGLError()
 {
     bool foundError = false;
     int glErr = glGetError();
     while (glErr != GL_NO_ERROR)
     {
         std::cout << "glError: " << glErr << std::endl;
         foundError = true;
         glErr = glGetError();
     }
     return foundError;
 }
 ​
 void Init(GLFWwindow* window)
 {
     renderingProgram = CreateShaderProgram();
     glGenVertexArrays(numVAOs, vao);//生成顶点数组对象名称,用numVAOs存储
     glBindVertexArray(vao[0]);//绑定vao[0]
 }
 ​
 void Display(GLFWwindow* window, double currentTime)
 {
     glUseProgram(renderingProgram);//激活程序对象
     glPointSize(430.0f);//设置点的大小
     glDrawArrays(GL_POINTS, 0, 1);//绘制方式,绘制一个点
 }
 unsigned int CreateShaderProgram()
 {
     //从文件读取GLSL代码
     std::string vertShaderStr = ReadShaderSource("./res/shaders/vertShader.glsl");
     std::string fragShaderStr = ReadShaderSource("./res/shaders/fragShader.glsl");
     const char* vertShaderSrc = vertShaderStr.c_str();
     const char* fragShaderSrc = fragShaderStr.c_str();
     //捕获编译着色器时的错误
     int vertComplied;
     int fragComplied;
     int linked;
     //创建顶点着色器和片段着色器
     unsigned int vShader = glCreateShader(GL_VERTEX_SHADER);
     unsigned int fShader = glCreateShader(GL_FRAGMENT_SHADER);
     //替换vShader,fShader中的源代码,使用自定义的编码
     glShaderSource(vShader, 1, &vertShaderSrc, NULL);
     glShaderSource(fShader, 1, &fragShaderSrc, NULL);
     //对着色器对象进行编译
     glCompileShader(vShader);
     CheckOpenGLError();
     glGetShaderiv(vShader, GL_COMPILE_STATUS, &vertComplied);
     if (vertComplied != 1)
     {
         std::cout << "vertex compilation faild" << std::endl;
         PrintShaderLog(vShader);
     }
     glCompileShader(fShader);
     CheckOpenGLError();
     glGetShaderiv(fShader, GL_COMPILE_STATUS, &fragComplied);
     if (fragComplied != 1)
     {
         std::cout << "fragment compilation faild" << std::endl;
         PrintShaderLog(fShader);
     }
     //创建一个Program链接着色器对象,执行的就是链接有着色器对象的程序
     unsigned int vfProgram = glCreateProgram();
     //把之前编译的着色器附加到程序对象上,然后用glLinkProgram链接它们
     glAttachShader(vfProgram, vShader);
     glAttachShader(vfProgram, fShader);
     glLinkProgram(vfProgram);
     CheckOpenGLError();
     glGetProgramiv(vfProgram, GL_LINK_STATUS, &linked);
     if (linked != 1)
     {
         std::cout << "linking faild" << std::endl;
         PrintProgramLog(vfProgram);
     }
     //返回连接好的着色器程序
     return vfProgram;
 }
 int main()
 {
     if (!glfwInit())
         exit(EXIT_FAILURE);
     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
     GLFWwindow* window = glfwCreateWindow(600, 600, "Hello, world", nullptr, nullptr);
     glfwMakeContextCurrent(window);
 ​
     if (glewInit() != GLEW_OK)
         exit(EXIT_FAILURE);
     glfwSwapInterval(1);
 ​
     Init(window);
 ​
     while (!glfwWindowShouldClose(window))
     {
         Display(window, glfwGetTime());
         glfwSwapBuffers(window);
         glfwPollEvents();
     }
 ​
     glfwDestroyWindow(window);
     glfwTerminate();
     exit(EXIT_SUCCESS);
 }

5.运行结果

image-20231126003959625

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值