引入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
相关产品推荐
相关产品推荐

