| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- #include "Shader.h"
- #include "spdlog/spdlog.h"
- #include <QFile>
- #include <qglobal.h>
- Shader::Shader(const QString vertexPath, const QString fragmentPath)
- {
- /* 获取OpenGL上下文 */
- auto ctx = QOpenGLContext::currentContext();
- if(!ctx)
- {
- SPDLOG_ERROR("获取OpenGL上下文失败");
- return;
- }
- m_glFuncs = ctx->functions();
- SPDLOG_DEBUG("加载着色器代码");
- QByteArray vertexShaderSource;
- QByteArray fragmentShaderSource;
- if(!loadShaderSourceFromFile(vertexPath, vertexShaderSource))
- {
- SPDLOG_ERROR("加载顶点着色器失败: {}", vertexPath.toStdString());
- return;
- }
- if(!loadShaderSourceFromFile(fragmentPath, fragmentShaderSource))
- {
- SPDLOG_ERROR("加载片段着色器失败: {}", fragmentPath.toStdString());
- return;
- }
- /* 编译着色器 */
- SPDLOG_DEBUG("编译着色器...");
- GLuint vertexShader = compileShader(vertexShaderSource, GL_VERTEX_SHADER);
- GLuint fragmentShader = compileShader(fragmentShaderSource, GL_FRAGMENT_SHADER);
- /* 创建着色器程序 */
- m_programID = m_glFuncs->glCreateProgram();
- /* 将顶点着色器和片段着色器附加到着色器程序对象上 */
- m_glFuncs->glAttachShader(m_programID, vertexShader);
- m_glFuncs->glAttachShader(m_programID, fragmentShader);
- /* 链接着色器程序 */
- m_glFuncs->glLinkProgram(m_programID);
- printOpenGLLinkError(m_programID);
- /* 删除着色器对象 */
- m_glFuncs->glDeleteShader(vertexShader);
- m_glFuncs->glDeleteShader(fragmentShader);
- SPDLOG_INFO("着色器创建成功");
- }
- Shader::~Shader()
- {
- }
- void Shader::use()
- {
- m_glFuncs->glUseProgram(m_programID);
- }
- GLuint Shader::getProgramID() const
- {
- return m_programID;
- }
- /* 设置uniform工具 */
- void Shader::setBool(const QString &name, bool value)
- {
- auto location = m_glFuncs->glGetUniformLocation(m_programID, name.toStdString().c_str());
- m_glFuncs->glUniform1i(location, (int)value);
- }
- void Shader::setInt(const QString &name, int value)
- {
- auto location = m_glFuncs->glGetUniformLocation(m_programID, name.toStdString().c_str());
- m_glFuncs->glUniform1i(location, value);
- }
- void Shader::setFloat(const QString &name, float value)
- {
- auto location = m_glFuncs->glGetUniformLocation(m_programID, name.toStdString().c_str());
- m_glFuncs->glUniform1f(location, value);
- }
- /* 打开着色器文件,加载着色器代码 */
- bool Shader::loadShaderSourceFromFile(const QString &filePath, QByteArray &outShaderSource)
- {
- QFile file(filePath);
- if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
- {
- SPDLOG_ERROR("无法打开着色器文件: {}", filePath.toStdString());
- SPDLOG_ERROR("错误信息: {}", file.errorString().toStdString());
- return false;
- }
- outShaderSource = file.readAll();
- file.close();
- return true;
- }
- /* 编译着色器 */
- GLuint Shader::compileShader(const QByteArray &shaderSource, GLenum shaderType)
- {
- const char* sourceCStr = shaderSource.constData();
- /* 创建着色器对象 */
- GLuint shader = m_glFuncs->glCreateShader(shaderType);
- /* 加载着色器源码 */
- m_glFuncs->glShaderSource(shader, 1, &sourceCStr, nullptr);
- /* 编译着色器 */
- m_glFuncs->glCompileShader(shader);
- printOpenGLCompileError(shader);
- return shader;
- }
- /* 打印编译错误 */
- void Shader::printOpenGLCompileError(GLuint errorCode)
- {
- int sucess;
- char infoLog[512];
- m_glFuncs->glGetShaderiv(errorCode, GL_COMPILE_STATUS, &sucess);
- if (!sucess)
- {
- m_glFuncs->glGetShaderInfoLog(errorCode, 512, nullptr, infoLog);
- SPDLOG_ERROR("OpenGL编译错误: {}", infoLog);
- }
- }
- /* 打印着色器链接错误 */
- void Shader::printOpenGLLinkError(GLuint errorCode)
- {
- int sucess;
- char infoLog[512];
- m_glFuncs->glGetProgramiv(errorCode, GL_LINK_STATUS, &sucess);
- if (!sucess)
- {
- m_glFuncs->glGetProgramInfoLog(errorCode, 512, nullptr, infoLog);
- SPDLOG_ERROR("OpenGL链接错误: {}", infoLog);
- }
- }
|