138 lines
5.3 KiB
C++
138 lines
5.3 KiB
C++
#include "shader_utils.hpp"
|
|
|
|
#include <vector>
|
|
|
|
GLuint LoadShaders(const char * vertex_file_path, const char * fragment_file_path){
|
|
// 创建着色器
|
|
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
|
|
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
|
|
|
|
// 从文件读取顶点着色器代码
|
|
std::string VertexShaderCode;
|
|
std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
|
|
if(VertexShaderStream.is_open()){
|
|
std::stringstream sstr;
|
|
sstr << VertexShaderStream.rdbuf();
|
|
VertexShaderCode = sstr.str();
|
|
VertexShaderStream.close();
|
|
} else {
|
|
std::cerr << "无法打开 " << vertex_file_path << std::endl;
|
|
getchar();
|
|
return 0;
|
|
}
|
|
|
|
// 从文件读取片元着色器代码
|
|
std::string FragmentShaderCode;
|
|
std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
|
|
if(FragmentShaderStream.is_open()){
|
|
std::stringstream sstr;
|
|
sstr << FragmentShaderStream.rdbuf();
|
|
FragmentShaderCode = sstr.str();
|
|
FragmentShaderStream.close();
|
|
} else {
|
|
std::cerr << "无法打开 " << fragment_file_path << std::endl;
|
|
getchar();
|
|
return 0;
|
|
}
|
|
|
|
GLint Result = GL_FALSE;
|
|
int InfoLogLength;
|
|
|
|
// 编译顶点着色器
|
|
std::cout << "编译着色器: " << vertex_file_path << std::endl;
|
|
char const * VertexSourcePointer = VertexShaderCode.c_str();
|
|
glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
|
|
glCompileShader(VertexShaderID);
|
|
|
|
// 检查顶点着色器
|
|
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
|
|
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
|
if ( InfoLogLength > 0 ){
|
|
std::vector<char> VertexShaderErrorMessage(InfoLogLength+1);
|
|
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
|
|
std::cerr << "顶点着色器编译错误:\n" << &VertexShaderErrorMessage[0] << std::endl;
|
|
if (Result == GL_FALSE) {
|
|
std::cerr << "顶点着色器编译失败" << std::endl;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// 编译片元着色器
|
|
std::cout << "编译着色器: " << fragment_file_path << std::endl;
|
|
char const * FragmentSourcePointer = FragmentShaderCode.c_str();
|
|
glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
|
|
glCompileShader(FragmentShaderID);
|
|
|
|
// 检查片元着色器
|
|
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
|
|
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
|
if ( InfoLogLength > 0 ){
|
|
std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1);
|
|
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
|
|
std::cerr << "片元着色器编译错误:\n" << &FragmentShaderErrorMessage[0] << std::endl;
|
|
if (Result == GL_FALSE) {
|
|
std::cerr << "片元着色器编译失败" << std::endl;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// 链接程序
|
|
std::cout << "链接程序" << std::endl;
|
|
GLuint ProgramID = glCreateProgram();
|
|
glAttachShader(ProgramID, VertexShaderID);
|
|
glAttachShader(ProgramID, FragmentShaderID);
|
|
glLinkProgram(ProgramID);
|
|
|
|
// 检查程序
|
|
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
|
|
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
|
if ( InfoLogLength > 0 ){
|
|
std::vector<char> ProgramErrorMessage(InfoLogLength+1);
|
|
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
|
|
std::cerr << "着色器程序链接错误:\n" << &ProgramErrorMessage[0] << std::endl;
|
|
if (Result == GL_FALSE) {
|
|
std::cerr << "着色器程序链接失败" << std::endl;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// 验证程序
|
|
glValidateProgram(ProgramID);
|
|
glGetProgramiv(ProgramID, GL_VALIDATE_STATUS, &Result);
|
|
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
|
if (InfoLogLength > 0) {
|
|
std::vector<char> ProgramErrorMessage(InfoLogLength+1);
|
|
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
|
|
std::cerr << "着色器程序验证错误:\n" << &ProgramErrorMessage[0] << std::endl;
|
|
if (Result == GL_FALSE) {
|
|
std::cerr << "着色器程序验证失败" << std::endl;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// 打印所有uniform变量的位置
|
|
GLint numUniforms;
|
|
glGetProgramiv(ProgramID, GL_ACTIVE_UNIFORMS, &numUniforms);
|
|
std::cout << "活动uniform变量数量: " << numUniforms << std::endl;
|
|
|
|
for (GLint i = 0; i < numUniforms; i++) {
|
|
char uniformName[256];
|
|
GLint uniformSize;
|
|
GLenum uniformType;
|
|
glGetActiveUniform(ProgramID, i, sizeof(uniformName), NULL, &uniformSize, &uniformType, uniformName);
|
|
GLint uniformLocation = glGetUniformLocation(ProgramID, uniformName);
|
|
std::cout << "Uniform变量 " << i << ": " << uniformName
|
|
<< " (类型: " << uniformType
|
|
<< ", 大小: " << uniformSize
|
|
<< ", 位置: " << uniformLocation << ")" << std::endl;
|
|
}
|
|
|
|
glDetachShader(ProgramID, VertexShaderID);
|
|
glDetachShader(ProgramID, FragmentShaderID);
|
|
|
|
glDeleteShader(VertexShaderID);
|
|
glDeleteShader(FragmentShaderID);
|
|
|
|
return ProgramID;
|
|
}
|