You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

引入Utils.h报错:Utils::createShaderProgram未定义引用

编译错误:Undefined Reference Utils::createShaderProgram 解决方法

核心原因

你只提供了Utils.h头文件,但没有对应的实现文件(Utils.cpp)。头文件里仅声明了Utils::createShaderProgram等静态方法的接口,链接器找不到这些方法的具体代码实现,因此报未定义引用错误。

解决步骤

1. 补充Utils类的实现文件(Utils.cpp)

创建Utils.cpp,把Utils.h中所有静态方法的具体逻辑实现写进去。以下是基础实现示例(可按需调整):

#include "Utils.h"

std::string Utils::readShaderFile(const char *filePath) {
    std::ifstream file(filePath);
    if (!file.is_open()) {
        std::cerr << "打开着色器文件失败: " << filePath << std::endl;
        return "";
    }
    std::string content((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
    file.close();
    return content;
}

void Utils::printShaderLog(GLuint 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 << "着色器日志: " << log << std::endl;
        free(log);
    }
}

void Utils::printProgramLog(int prog) {
    int len = 0;
    int chWrittn = 0;
    char* log;
    glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &len);
    if (len > 0) {
        log = (char*)malloc(len);
        glGetProgramInfoLog(prog, len, &chWrittn, log);
        std::cout << "程序日志: " << log << std::endl;
        free(log);
    }
}

GLuint Utils::prepareShader(int shaderTYPE, const char *shaderPath) {
    std::string shaderSource = readShaderFile(shaderPath);
    const char* src = shaderSource.c_str();
    GLuint shader = glCreateShader(shaderTYPE);
    glShaderSource(shader, 1, &src, NULL);
    glCompileShader(shader);
    printShaderLog(shader);
    return shader;
}

int Utils::finalizeShaderProgram(GLuint sprogram) {
    glLinkProgram(sprogram);
    printProgramLog(sprogram);
    int linked;
    glGetProgramiv(sprogram, GL_LINK_STATUS, &linked);
    return linked;
}

Utils::Utils() {}

bool Utils::checkOpenGLError() {
    bool foundError = false;
    int glErr = glGetError();
    while (glErr != GL_NO_ERROR) {
        std::cerr << "OpenGL错误: " << glErr << std::endl;
        foundError = true;
        glErr = glGetError();
    }
    return foundError;
}

GLuint Utils::createShaderProgram(const char *vp, const char *fp) {
    GLuint vShader = prepareShader(GL_VERTEX_SHADER, vp);
    GLuint fShader = prepareShader(GL_FRAGMENT_SHADER, fp);
    GLuint vfProgram = glCreateProgram();
    glAttachShader(vfProgram, vShader);
    glAttachShader(vfProgram, fShader);
    if (!finalizeShaderProgram(vfProgram)) {
        std::cerr << "着色器程序链接失败" << std::endl;
        return 0;
    }
    glDeleteShader(vShader);
    glDeleteShader(fShader);
    return vfProgram;
}

// 其他重载的createShaderProgram方法、纹理加载方法按需实现,暂时用不到可留空提示
GLuint Utils::createShaderProgram(const char *vp, const char *gp, const char *fp) {
    std::cerr << "该重载的createShaderProgram暂未实现" << std::endl;
    return 0;
}

GLuint Utils::createShaderProgram(const char *vp, const char *tCS, const char* tES, const char *fp) {
    std::cerr << "该重载的createShaderProgram暂未实现" << std::endl;
    return 0;
}

GLuint Utils::createShaderProgram(const char *vp, const char *tCS, const char* tES, char *gp, const char *fp) {
    std::cerr << "该重载的createShaderProgram暂未实现" << std::endl;
    return 0;
}

GLuint Utils::loadTexture(const char *texImagePath) {
    std::cerr << "loadTexture暂未实现" << std::endl;
    return 0;
}

GLuint Utils::loadCubeMap(const char *mapDir) {
    std::cerr << "loadCubeMap暂未实现" << std::endl;
    return 0;
}

float* Utils::goldAmbient() {
    static float ambient[] = {0.24725f, 0.1995f, 0.0745f, 1.0f};
    return ambient;
}

float* Utils::goldDiffuse() {
    static float diffuse[] = {0.75164f, 0.60648f, 0.22648f, 1.0f};
    return diffuse;
}

float* Utils::goldSpecular() {
    static float specular[] = {0.628281f, 0.555802f, 0.366065f, 1.0f};
    return specular;
}

float Utils::goldShininess() {
    return 51.2f;
}

float* Utils::silverAmbient() {
    static float ambient[] = {0.19225f, 0.19225f, 0.19225f, 1.0f};
    return ambient;
}

float* Utils::silverDiffuse() {
    static float diffuse[] = {0.50754f, 0.50754f, 0.50754f, 1.0f};
    return diffuse;
}

float* Utils::silverSpecular() {
    static float specular[] = {0.508273f, 0.508273f, 0.508273f, 1.0f};
    return specular;
}

float Utils::silverShininess() {
    return 51.2f;
}

float* Utils::bronzeAmbient() {
    static float ambient[] = {0.2125f, 0.1275f, 0.054f, 1.0f};
    return ambient;
}

float* Utils::bronzeDiffuse() {
    static float diffuse[] = {0.714f, 0.4284f, 0.18144f, 1.0f};
    return diffuse;
}

float* Utils::bronzeSpecular() {
    static float specular[] = {0.393548f, 0.271906f, 0.166721f, 1.0f};
    return specular;
}

float Utils::bronzeShininess() {
    return 25.6f;
}

2. 更新CMakeLists.txt

把Utils.cpp添加到编译目标中,同时确保链接GLM库(代码中用到了GLM但当前配置未链接):

cmake_minimum_required(VERSION 3.17)

project(test LANGUAGES CXX)

# 查找系统中安装的GLM库
find_package(glm REQUIRED)

add_executable(test main.cpp Utils.cpp)
target_link_libraries(test GLEW GL glfw glm::glm)
target_include_directories(test PUBLIC /root/SourceCodes/CPP/include/)

3. 修复顶点着色器拼写错误

vertShader.glsl中gl_position是拼写错误,OpenGL内置变量应为**gl_Position**(大写P),否则着色器编译失败:

#version 330

layout (location=0) in vec3 position;

uniform mat4 mv_matrix;
uniform mat4 proj_matrix;

void main(void) {
    gl_Position = proj_matrix * mv_matrix * vec4(position, 1.0);
}

4. 确认Shader文件路径正确

编译运行时,要保证vertShader.glsl和fragShader.glsl在程序工作目录下,或者在Utils::readShaderFile中使用绝对路径。

额外检查

  • 确认GLEW、GLFW、GLM库已正确安装,CMake能正常找到它们
  • 编译前清理旧构建目录,重新执行cmake和make命令

内容的提问来源于stack exchange,提问作者Freya the Goddess

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 11:48:10