使用之前的方法写Shader是一件很痛苦的事情,把Shader代码直接卸载C++文件中,需要使用很多引号来包裹,既不美观也不方便。
我们这节的目的是使用纯文本文件保存Shader。
首先在工程中创建两个文件,分别命名为VertexShaderCode.glsl 和 FragmentShaderCode.glsl,后缀名可以自己随意指定,不一定非要是glsl。
然后把上节的Shader代码拷贝到两个文件中去。
VertexShaderCode.glsl
1 #version 430 2 3 in layout(location=0) vec2 position; 4 in layout(location=1) vec3 vertexColor; 5 6 out vec3 passingColor; 7 8 void main() 9 { 10 gl_Position= vec4(position,0.0,1.0); 11 passingColor= vertexColor; 12 }
FragmentShaderCode.glsl
1 #version 430 2 3 in vec3 passingColor; 4 out vec4 finalColor; 5 6 7 void main() 8 { 9 finalColor = vec4(passingColor,1.0); 10 }
另外在MyGlWindow中添加一个函数用来读取文件
MyGlWindow.h中添加include:
#include <string>
添加成员函数声明:
1 std::string ReadShaderCode(const char* fileName);
MyGlWindow.cpp中添加include:
#include <iostream> #include <fstream>
添加成员函数定义:
1 std::string MyGlWindow::ReadShaderCode(const char* fileName) 2 { 3 std::ifstream myInput(fileName); 4 if (!myInput.good()) 5 { 6 std::cout << "File failed to load..." << fileName; 7 exit(1); 8 } 9 return std::string( 10 std::istreambuf_iterator<char>(myInput), 11 std::istreambuf_iterator<char>()); 12 }
删除掉开头的两个extern声明:
//extern const char* vertexShaderCode; //extern const char* fragmentShaderCode;
修改installShaders()函数:
1 void MyGlWindow::installShaders() 2 { 3 GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER); 4 GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); 5 6 std::string tmp = ReadShaderCode("VertexShaderCode.glsl"); 7 const char* vertexShaderCode = tmp.c_str(); 8 glShaderSource(vertexShaderID, 1, &vertexShaderCode, 0); 9 10 tmp = ReadShaderCode("FragmentShaderCode.glsl"); 11 const char* fragmentShaderCode = tmp.c_str(); 12 glShaderSource(fragmentShaderID, 1, &fragmentShaderCode, 0); 13 14 glCompileShader(vertexShaderID); 15 glCompileShader(fragmentShaderID); 16 17 GLuint programID = glCreateProgram(); 18 glAttachShader(programID, vertexShaderID); 19 glAttachShader(programID, fragmentShaderID); 20 21 glLinkProgram(programID); 22 23 glUseProgram(programID); 24 }
注意第6-7行,先用一个string对象存储读取到的字符串,然后使用.c_str()返回C语言风格字符串 const char*。