1 /* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef XCOMPONENTDEMO_SHADER_H 17 #define XCOMPONENTDEMO_SHADER_H 18 19 #include <string.h> 20 #include <fstream> 21 #include <sstream> 22 #include <iostream> 23 #include <GLES3/gl3.h> 24 25 #include "algorithm/Vector3.h" 26 #include "algorithm/Matrix4x4.h" 27 #include "log.h" 28 29 class Shader { 30 public: 31 unsigned int ID; 32 // 构造函数动态生成着色器 33 // ------------------------------------------------------------------------ Shader(bool isText,const char * vShaderCode,const char * fShaderCode)34 Shader(bool isText, const char *vShaderCode, const char *fShaderCode) 35 { 36 // 2. 编译着色器 37 unsigned int vertex; 38 unsigned int fragment; 39 // 顶点着色器 40 vertex = glCreateShader(GL_VERTEX_SHADER); 41 glShaderSource(vertex, 1, &vShaderCode, NULL); 42 glCompileShader(vertex); 43 checkCompileErrors(vertex, "VERTEX"); 44 // 片段着色器 45 fragment = glCreateShader(GL_FRAGMENT_SHADER); 46 glShaderSource(fragment, 1, &fShaderCode, NULL); 47 glCompileShader(fragment); 48 checkCompileErrors(fragment, "FRAGMENT"); 49 // 如果给定了几何体着色器,请编译几何体着色器 50 // 着色器程序 51 ID = glCreateProgram(); 52 glAttachShader(ID, vertex); 53 glAttachShader(ID, fragment); 54 glLinkProgram(ID); 55 checkCompileErrors(ID, "PROGRAM"); 56 // 删除着色器,因为它们现在链接到着色器程序中,不再需要了 57 glDeleteShader(vertex); 58 glDeleteShader(fragment); 59 } 60 61 // 选择着色器程序 62 // ------------------------------------------------------------------------ use()63 void use() { glUseProgram(ID); } 64 // uniform的实用函数 65 // ------------------------------------------------------------------------ SetBool(const std::string & name,bool value)66 void SetBool(const std::string &name, bool value) const 67 { 68 glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value); 69 } 70 // ------------------------------------------------------------------------ SetInt(const std::string & name,int value)71 void SetInt(const std::string &name, int value) const 72 { 73 glUniform1i(glGetUniformLocation(ID, name.c_str()), value); 74 } 75 // ------------------------------------------------------------------------ SetFloat(const std::string & name,float value)76 void SetFloat(const std::string &name, float value) const 77 { 78 glUniform1f(glGetUniformLocation(ID, name.c_str()), value); 79 } 80 // ------------------------------------------------------------------------ SetVec2(const std::string & name,float x,float y)81 void SetVec2(const std::string &name, float x, float y) const 82 { 83 glUniform2f(glGetUniformLocation(ID, name.c_str()), x, y); 84 } 85 // ------------------------------------------------------------------------ SetVec3(const std::string & name,float x,float y,float z)86 void SetVec3(const std::string &name, float x, float y, float z) const 87 { 88 glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z); 89 } 90 // ------------------------------------------------------------------------ SetVector3(const std::string & name,Vector3 & value)91 void SetVector3(const std::string &name, Vector3 &value) const 92 { 93 glUniform3f(glGetUniformLocation(ID, name.c_str()), value.GetDataX(), value.GetDataY(), value.GetDataZ()); 94 } SetVec4(const std::string & name,float x,float y,float z,float w)95 void SetVec4(const std::string &name, float x, float y, float z, float w) const 96 { 97 glUniform4f(glGetUniformLocation(ID, name.c_str()), x, y, z, w); 98 } 99 100 // ------------------------------------------------------------------------ SetMatrix4x4(const std::string & name,Matrix4x4 & mat)101 void SetMatrix4x4(const std::string &name, Matrix4x4 &mat) const 102 { 103 glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat.GetValues()[0]); 104 } SetMat4fv(const std::string & name,const GLfloat * mat)105 void SetMat4fv(const std::string &name, const GLfloat *mat) const 106 { 107 GLuint loc = glGetUniformLocation(ID, name.c_str()); 108 glUniformMatrix4fv(loc, 1, GL_FALSE, mat); 109 } 110 111 private: 112 // 用于检查着色器编译/链接错误的实用函数。 113 // ------------------------------------------------------------------------ checkCompileErrors(GLuint shader,std::string type)114 void checkCompileErrors(GLuint shader, std::string type) 115 { 116 GLint success; 117 GLchar infoLog[1024]; 118 if (type != "PROGRAM") { 119 glGetShaderiv(shader, GL_COMPILE_STATUS, &success); 120 if (!success) { 121 glGetShaderInfoLog(shader, 1024, NULL, infoLog); // glGetShaderInfoLog 1024 122 LOGE("ERROR::SHADER_COMPILATION_ERROR of type: %{public}s , %{public}s", type.c_str(), infoLog); 123 } 124 } else { 125 glGetProgramiv(shader, GL_LINK_STATUS, &success); 126 if (!success) { 127 glGetProgramInfoLog(shader, 1024, NULL, infoLog); // glGetShaderInfoLog 1024 128 LOGE("ERROR::PROGRAM_LINKING_ERROR of type: %{public}s , %{public}s", type.c_str(), infoLog); 129 } 130 } 131 } 132 }; 133 134 #endif // XCOMPONENTDEMO_SHADER_H 135