error LNK2005: “public: class std::vector<class std::vector<class std::vector<float>”

本文介绍了在使用Visual Studio 2010时遇到的LNK2005错误,并提供了两种解决方案:一是更换开发环境;二是通过在链接器命令行中加入特定参数来解决版本兼容问题。

VS2010:error LNK2005: "public: class std::vector<class std::vector<class std::vector<class std::vector<float,class std::allocator<float> >,class std::allocator<class std::vector<float,class std::allocator<float> 

如:

     


Reason:

都说这不是版本的问题,这是2010的问题。个人觉得是版本环境导致的STL兼容问题。

Solution:

方法一:不要用vs;

方法二:在link commandline加上一行”  /FORCE:MULTIPLE  “点击” OK “就解决了;简单说就是VS10的STL从import变成static了。


untitled1.pro # Qt项目配置 QT += core gui multimedia widgets greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = untitled1 TEMPLATE = app # C++标准配置 CONFIG += c++17 # 源文件 SOURCES += \ main.cpp \ MainWindow.cpp HEADERS += \ MainWindow.h FORMS += \ MainWindow.ui # OpenPose配置 OPENPOSE_ROOT = C:/openpose-prosperity INCLUDEPATH += $$OPENPOSE_ROOT/include LIBS += -L"C:/openpose-prosperity/build_CPU/src/openpose/Release" LIBS += -L$$OPENPOSE_ROOT/lib -lopenpose # OpenCV配置 OPENCV_ROOT = C:/opencv/build INCLUDEPATH += $$OPENCV_ROOT/include LIBS += -L$$OPENCV_ROOT/x64/vc15/lib \ -lopencv_core455 \ -lopencv_highgui455 \ -lopencv_imgproc455 \ -lopencv_imgcodecs455 \ -lopencv_videoio455 # Windows特定配置 win32 { LIBS += -lws2_32 -lgdi32 QMAKE_CXXFLAGS += -permissive- } # 调试信息 CONFIG += debug_and_release INCLUDEPATH += "C:\Program Files\Microsoft Visual Studio\18\Community\VC\Tools\MSVC\14.44.35207\include" main.cpp #include "MainWindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); } MainWindow.cpp #include "MainWindow.h" #include "ui_MainWindow.h" #include <QFileDialog> #include <QMessageBox> #include <opencv2/imgproc.hpp> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) , m_poseExtractor(nullptr) , m_netWidth(368) , m_netHeight(368) { ui->setupUi(this); initializeOpenPose(); // 连接按钮信号 connect(ui->processButton, &QPushButton::clicked, this, &MainWindow::on_processButton_clicked); connect(ui->closeButton, &QPushButton::clicked, this, &MainWindow::on_closeButton_clicked); } MainWindow::~MainWindow() { if (m_poseExtractor) delete m_poseExtractor; delete ui; } // 初始化OpenPose(兼容旧版本) void MainWindow::initializeOpenPose() { try { const op::PoseModel poseModel = op::PoseModel::COCO_18; const std::string modelFolder = "C:/openpose-prosperity/models/"; // 替换为你的模型路径 const int gpuId = -1; // CPU模式 const std::vector<op::HeatMapType> heatMapTypes; const op::ScaleMode scaleMode = op::ScaleMode::InputResolution; const bool maximizePositives = false; const bool disableBlending = false; const std::string modelProto = ""; const std::string modelWeights = ""; const float renderThreshold = 0.1f; const bool enableGoogleLogging = false; // 严格匹配构造函数参数 m_poseExtractor = new op::PoseExtractorCaffe( poseModel, modelFolder, gpuId, heatMapTypes, scaleMode, maximizePositives, disableBlending, modelProto, modelWeights, renderThreshold, enableGoogleLogging ); } catch (const std::exception& e) { QMessageBox::critical(this, "初始化失败", QString("OpenPose错误:%1").arg(e.what())); close(); } } // 处理图像按钮点击事件 void MainWindow::on_processButton_clicked() { const QString filePath = QFileDialog::getOpenFileName( this, "选择图像", "", "图像文件 (*.jpg *.png *.bmp)" ); if (filePath.isEmpty()) return; cv::Mat frame = cv::imread(filePath.toStdString()); if (frame.empty()) { QMessageBox::warning(this, "错误", "无法读取图像"); return; } const cv::Mat processedFrame = processFrame(frame); displayImage(processedFrame); } // 关闭按钮点击事件 void MainWindow::on_closeButton_clicked() { close(); } // 处理图像帧(核心功能) cv::Mat MainWindow::processFrame(cv::Mat& frame) { try { // 缩放图像至网络输入尺寸 cv::Mat resizedFrame; cv::resize(frame, resizedFrame, cv::Size(m_netWidth, m_netHeight)); // 转换为OpenPose数组格式 op::Array<float> inputArray = matToOpArray(resizedFrame); const std::vector<op::Array<float>> inputVector{inputArray}; // 执行姿态检测 m_poseExtractor->forwardPass( inputVector, op::Point<int>(frame.cols, frame.rows) ); // 获取检测结果并绘制 const op::Array<float> keypoints = m_poseExtractor->getPoseKeypoints(); drawPose(frame, keypoints); return frame; } catch (const std::exception& e) { QMessageBox::warning(this, "处理错误", QString("处理失败:%1").arg(e.what())); return frame; } } // 显示图像 void MainWindow::displayImage(const cv::Mat& image) { const QImage qImg = cvMatToQImage(image); if (qImg.isNull()) { ui->label->setText("无法显示图像"); return; } ui->label->setPixmap(QPixmap::fromImage(qImg).scaled( ui->label->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation )); } // OpenCV图像转Qt图像 QImage MainWindow::cvMatToQImage(const cv::Mat& mat) { if (mat.empty() || mat.type() != CV_8UC3) return QImage(); return QImage(mat.data, mat.cols, mat.rows, mat.step, QImage::Format_BGR888).copy(); } // 修正:不依赖setDimensions的图像转换函数 op::Array<float> MainWindow::matToOpArray(const cv::Mat& mat) { // 计算总元素数量(行×列×3通道) const int totalElements = mat.rows * mat.cols * 3; // 创建一维数组(旧版本兼容方式) op::Array<float> array(totalElements); // 获取可修改的原始数据指针 float* data = array.getPtr(); // 手动填充数据(BGR转RGB) for (int y = 0; y < mat.rows; ++y) { for (int x = 0; x < mat.cols; ++x) { const cv::Vec3b& bgr = mat.at<cv::Vec3b>(y, x); const int index = (y * mat.cols + x) * 3; // 计算一维索引 data[index] = static_cast<float>(bgr[2]); // R通道 data[index + 1] = static_cast<float>(bgr[1]); // G通道 data[index + 2] = static_cast<float>(bgr[0]); // B通道 } } // 移除setDimensions调用,完全适配旧版本 return array; } // 修正:获取const对象的指针 void MainWindow::drawPose(cv::Mat& frame, const op::Array<float>& keypoints) { // COCO模型骨骼连接关系 const std::vector<std::pair<int, int>> skeleton = { {0,1}, {1,2}, {2,3}, {3,4}, // 右臂 {0,5}, {5,6}, {6,7}, {7,8}, // 左臂 {0,9}, {9,10}, {10,11}, {11,12}, // 右腿 {0,13}, {13,14}, {14,15}, {15,16}, // 左腿 {0,17} // 头部 }; const float threshold = 0.1f; // 获取关键点数量信息(兼容旧版本) const int numPersons = keypoints.getSize(0); // 检测到的人数 const int numParts = keypoints.getSize(1); // 每个对象的关键点数量 // 修正:使用const版本的getPtr方法 const float* data = keypoints.getConstPtr(); // 绘制骨骼 for (const auto& pair : skeleton) { const int index1 = pair.first; const int index2 = pair.second; for (int person = 0; person < numPersons; ++person) { // 计算一维索引 const int baseIdx1 = (person * numParts + index1) * 3; const int baseIdx2 = (person * numParts + index2) * 3; // 提取坐标和置信度 const float x1 = data[baseIdx1]; const float y1 = data[baseIdx1 + 1]; const float c1 = data[baseIdx1 + 2]; const float x2 = data[baseIdx2]; const float y2 = data[baseIdx2 + 1]; const float c2 = data[baseIdx2 + 2]; // 绘制骨骼(只绘制置信度高的) if (c1 > threshold && c2 > threshold) { cv::line(frame, cv::Point(static_cast<int>(x1), static_cast<int>(y1)), cv::Point(static_cast<int>(x2), static_cast<int>(y2)), cv::Scalar(0, 255, 0), 2); } } } // 绘制关键点 for (int person = 0; person < numPersons; ++person) { for (int part = 0; part < numParts; ++part) { const int baseIdx = (person * numParts + part) * 3; const float x = data[baseIdx]; const float y = data[baseIdx + 1]; const float c = data[baseIdx + 2]; if (c > threshold) { cv::circle(frame, cv::Point(static_cast<int>(x), static_cast<int>(y)), 5, cv::Scalar(0, 0, 255), -1); } } } } MainWindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <opencv2/opencv.hpp> #include "openpose/pose/poseExtractorCaffe.hpp" #include "openpose/core/array.hpp" QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void on_processButton_clicked(); void on_closeButton_clicked(); private: Ui::MainWindow *ui; op::PoseExtractorCaffe* m_poseExtractor; int m_netWidth; // 网络输入宽度 int m_netHeight; // 网络输入高度 // 工具函数 void initializeOpenPose(); cv::Mat processFrame(cv::Mat& frame); void displayImage(const cv::Mat& image); QImage cvMatToQImage(const cv::Mat& mat); op::Array<float> matToOpArray(const cv::Mat& mat); // 图像转换 void drawPose(cv::Mat& frame, const op::Array<float>& keypoints); // 姿态绘制 }; #endif // MAINWINDOW_H MainWindow.ui <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MainWindow</class> <widget class="QMainWindow" name="MainWindow"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>1327</width> <height>980</height> </rect> </property> <property name="windowTitle"> <string>MainWindow</string> </property> <widget class="QWidget" name="centralwidget"> <widget class="QLabel" name="label"> <property name="geometry"> <rect> <x>40</x> <y>120</y> <width>1280</width> <height>720</height> </rect> </property> <property name="text"> <string>Label</string> </property> <property name="alignment"> <set>Qt::AlignmentFlag::AlignCenter</set> </property> </widget> <widget class="QPushButton" name="processButton"> <property name="geometry"> <rect> <x>290</x> <y>840</y> <width>200</width> <height>40</height> </rect> </property> <property name="text"> <string>处理图像</string> </property> </widget> <widget class="QPushButton" name="closeButton"> <property name="geometry"> <rect> <x>840</x> <y>840</y> <width>200</width> <height>40</height> </rect> </property> <property name="text"> <string>关闭</string> </property> </widget> </widget> <widget class="QMenuBar" name="menubar"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>1327</width> <height>25</height> </rect> </property> </widget> <widget class="QStatusBar" name="statusbar"/> </widget> <resources/> <connections/> </ui> 这是qt6.10.0的工程代码,编译后出现以下问题:cl -c -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -permissive- -Zc:__cplusplus -Zc:externConstexpr -permissive- -Zi -MDd -std:c++17 -utf-8 -W3 -w34100 -w34189 -w44456 -w44457 -w44458 -wd4577 -wd4467 -EHsc /Fddebug\untitled1.vc.pdb -DUNICODE -D_UNICODE -DWIN32 -D_ENABLE_EXTENDED_ALIGNED_STORAGE -DWIN64 -DQT_QML_DEBUG -DQT_MULTIMEDIA_LIB -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -I..\..\..\untitled1 -I. -IC:\openpose-prosperity\include -IC:\opencv\build\include -I"C:\Program Files\Microsoft Visual Studio\18\Community\VC\Tools\MSVC\14.44.35207\include" -IC:\Qt\6.10.0\msvc2022_64\include -IC:\Qt\6.10.0\msvc2022_64\include\QtMultimedia -IC:\Qt\6.10.0\msvc2022_64\include\QtWidgets -IC:\Qt\6.10.0\msvc2022_64\include\QtGui -IC:\Qt\6.10.0\msvc2022_64\include\QtNetwork -IC:\Qt\6.10.0\msvc2022_64\include\QtCore -Idebug -I. -I/include -IC:\Qt\6.10.0\msvc2022_64\mkspecs\win32-msvc -Fodebug\ @C:\Users\admin\AppData\Local\Temp\moc_MainWindow.obj.7132.594.jom moc_MainWindow.cpp link /NOLOGO /DYNAMICBASE /NXCOMPAT /DEBUG /SUBSYSTEM:WINDOWS "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" /MANIFEST:embed /OUT:debug\untitled1.exe @C:\Users\admin\AppData\Local\Temp\untitled1.exe.7132.5438.jom LINK : fatal error LNK1104: 无法打开文件“opencv_core455.lib” jom: C:\Users\admin\Desktop\QT\untitled1\build\Desktop_Qt_6_10_0_MSVC2022_64bit-Debug\Makefile.Debug [debug\untitled1.exe] Error 1104 jom: C:\Users\admin\Desktop\QT\untitled1\build\Desktop_Qt_6_10_0_MSVC2022_64bit-Debug\Makefile [debug] Error 2 02:15:06: The command "C:\Qt\Tools\QtCreator\bin\jom\jom.exe" terminated with exit code 2. 02:15:06: Error while building/deploying project untitled1 (kit: Desktop Qt 6.10.0 MSVC2022 64bit) 02:15:06: The kit Desktop Qt 6.10.0 MSVC2022 64bit has configuration issues which might be the root cause for this problem. 02:15:06: When executing step "Make" 02:15:06: Elapsed time: 00:06.
最新发布
11-23
19:07:07:172 生成开始于 19:07... 19:07:07:255 1>------ 已启动生成: 项目: Project1, 配置: Debug x64 ------ 19:07:07:383 1>FileName.cpp 19:07:08:083 1>D:\Users\dell\Desktop\Project1\FileName.cpp(132,24): warning C4267: “初始化”: 从“size_t”转换到“int”,可能丢失数据 19:07:08:145 1>D:\Users\dell\Desktop\Project1\FileName.cpp(367,13): warning C4244: “初始化”: 从“double”转换到“float”,可能丢失数据 19:07:08:145 1>D:\Users\dell\Desktop\Project1\FileName.cpp(415,35): warning C4267: “初始化”: 从“size_t”转换到“int”,可能丢失数据 19:07:08:145 1>D:\Users\dell\Desktop\Project1\FileName.cpp(415,21): warning C4267: “初始化”: 从“size_t”转换到“const int”,可能丢失数据 19:07:08:145 1>D:\Users\dell\Desktop\Project1\FileName.cpp(572,35): warning C4267: “初始化”: 从“size_t”转换到“int”,可能丢失数据 19:07:08:145 1>D:\Users\dell\Desktop\Project1\FileName.cpp(572,21): warning C4267: “初始化”: 从“size_t”转换到“const int”,可能丢失数据 19:07:08:145 1>D:\Users\dell\Desktop\Project1\FileName.cpp(606,41): warning C4267: “初始化”: 从“size_t”转换到“int”,可能丢失数据 19:07:08:145 1>D:\Users\dell\Desktop\Project1\FileName.cpp(606,21): warning C4267: “初始化”: 从“size_t”转换到“const int”,可能丢失数据 19:07:08:533 1>EasyXw.lib(EasyX.obj) : error LNK2005: "unsigned long __cdecl HSVtoRGB(float,float,float)" (?HSVtoRGB@@YAKMMM@Z) 已经在 FileName.obj 中定义 19:07:08:593 1>D:\Users\dell\Desktop\Project1\x64\Debug\Project1.exe : fatal error LNK1169: 找到一个或多个多重定义的符号 19:07:08:618 1>已完成生成项目“Project1.vcxproj”的操作 - 失败。 19:07:08:623 ========== 生成: 0 成功,1 失败,0 最新,0 已跳过 ========== 19:07:08:623 ========== 生成 于 19:07 完成,耗时 01.538 秒 ==========
07-29
#pragma once #include <string> #include <glad/glad.h> class Shader { public: unsigned int ID; // 构造函数(创建着色器用) Shader(); // 使用这个着色器 void use(); // 设置 uniform 变量的值 void setInt(const std::string& name, int value); void setFloat(const std::string& name, float value); private: // 这两个是字符串,保存你的顶点和片段着色器代码 static std::string vertexSource; static std::string fragmentSource; // 这是一个私有函数,用来编译单个着色器(比如顶点或片段) unsigned int compileShader(unsigned int type, const std::string& source); }; #pragma once #pragma once #include <vector> #include <glm/glm.hpp> class Shape { protected: unsigned int VAO, VBO; std::vector<float> vertices; std::vector<unsigned int> indices; public: virtual void setup() = 0; void draw(); virtual ~Shape(); }; #pragma once // 先包含 GLAD 和 OpenGL #include <glad/glad.h> // 包含 GLM 数学库 #include <glm/glm.hpp> #include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/type_ptr.hpp> // 必须加!否则 value_ptr 找不到 // 包含你自己的类(顺序很重要) #include "Shader.h" // 提供 Shader 类 #include "Texture.h" // 提供 Texture 类 class Sprite { private: unsigned int VAO, VBO; public: Sprite() { float vertices[] = { // 位置 // 纹理坐标 0.5f, 0.5f, 1.0f, 1.0f, // 右上 0.5f, -0.5f, 1.0f, 0.0f, // 右下 -0.5f, -0.5f, 0.0f, 0.0f, // 左下 -0.5f, 0.5f, 0.0f, 1.0f // 左上 }; unsigned int indices[] = { 0, 1, 3, 1, 2, 3 }; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); unsigned int EBO; glGenBuffers(1, &EBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); // 属性 0: 位置 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); // 属性 1: 纹理坐标 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float))); glEnableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); } // 绘制精灵 void draw(float x, float y, float scale, Texture& tex, Shader& shader) { // 激活并绑定纹理 glActiveTexture(GL_TEXTURE0); tex.bind(); // 构建模型矩阵 glm::mat4 model = glm::mat4(1.0f); model = glm::translate(model, glm::vec3(x, y, 0.0f)); model = glm::scale(model, glm::vec3(scale)); // 使用着色器并传入 uniform shader.use(); glUniformMatrix4fv( glGetUniformLocation(shader.ID, "model"), 1, GL_FALSE, glm::value_ptr(model) ); glUniform1i(glGetUniformLocation(shader.ID, "texture1"), 0); // 绘制 glBindVertexArray(VAO); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glBindVertexArray(0); } }; #pragma once #include <string> #include <SOIL2/SOIL2.h> #include <glad/glad.h> class Texture { public: unsigned int ID; std::string path; Texture(const std::string& imagePath, bool alpha = false); void bind(unsigned int unit = 0); // texture unit like GL_TEXTURE0 ~Texture(); }; #define STB_IMAGE_IMPLEMENTATION #include <glad/glad.h> #include <GLFW/glfw3.h> #include <iostream> #include <vector> // 必须添加这两个头文件才能使用 std::this_thread 和 std::chrono #include <thread> #include <chrono> // 包含你自己写的类 #include "Shader.h" #include "Texture.h" int main() { // ======== 初始化 GLFW 和 OpenGL ========== glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); GLFWwindow* window = glfwCreateWindow(800, 600, "Rendering Lab", nullptr, nullptr); if (!window) { std::cerr << "Failed to create GLFW window" << std::endl; glfwTerminate(); return -1; } glfwMakeContextCurrent(window); // 设置视口回调 glfwSetFramebufferSizeCallback(window, [](GLFWwindow*, int w, int h) { glViewport(0, 0, w, h); }); // ======== 初始化 GLAD ========== if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { std::cerr << "Failed to initialize GLAD" << std::endl; return -1; } // ======== SHADER ========== Shader shader; shader.use(); shader.setInt("texture1", 0); // 第一纹理单元 shader.setInt("texture2", 1); // 第二纹理单元(用于叠加) // ✅ 不再需要那一行错误代码! // ======== TEXTURES ========== Texture tex1("resources/image1.jpg"); // 木板纹理 Texture tex2("resources/image2.jpg"); // 双木板 Texture tex3("resources/image3.png", true); // 白亮斑点(带alpha) Texture tex4("resources/image4.png"); // 笑脸纹理 // ======== RECTANGLE VAO/VBO/EBO ========== float rectVertices[] = { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f }; unsigned int rectIndices[] = { 0, 1, 3, 1, 2, 3 }; unsigned int VAO_rect, VBO_rect, EBO_rect; glGenVertexArrays(1, &VAO_rect); glGenBuffers(1, &VBO_rect); glGenBuffers(1, &EBO_rect); glBindVertexArray(VAO_rect); glBindBuffer(GL_ARRAY_BUFFER, VBO_rect); glBufferData(GL_ARRAY_BUFFER, sizeof(rectVertices), rectVertices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO_rect); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(rectIndices), rectIndices, GL_STATIC_DRAW); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float))); glEnableVertexAttribArray(1); // ======== HEXAGON 六边形 ========== const int N = 6; std::vector<float> hexVertices; std::vector<unsigned int> hexIndices; // 中心点 hexVertices.push_back(0.0f); hexVertices.push_back(0.0f); hexVertices.push_back(0.5f); hexVertices.push_back(0.5f); // UV for (int i = 0; i < N; ++i) { float angle = 2.0f * 3.1415926f * i / N; float x = cos(angle), y = sin(angle); hexVertices.push_back(x); hexVertices.push_back(y); hexVertices.push_back((x + 1.0f) / 2.0f); hexVertices.push_back((y + 1.0f) / 2.0f); } for (int i = 1; i <= N; ++i) { hexIndices.push_back(0); hexIndices.push_back(i); hexIndices.push_back(i % N + 1); } unsigned int VAO_hex, VBO_hex, EBO_hex; glGenVertexArrays(1, &VAO_hex); glGenBuffers(1, &VBO_hex); glGenBuffers(1, &EBO_hex); glBindVertexArray(VAO_hex); glBindBuffer(GL_ARRAY_BUFFER, VBO_hex); glBufferData(GL_ARRAY_BUFFER, hexVertices.size() * sizeof(float), hexVertices.data(), GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO_hex); glBufferData(GL_ELEMENT_ARRAY_BUFFER, hexIndices.size() * sizeof(unsigned int), hexIndices.data(), GL_STATIC_DRAW); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float))); glEnableVertexAttribArray(1); // ========== RENDER LOOP ========== while (!glfwWindowShouldClose(window)) { glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); shader.use(); // --- 第一帧:矩形 + image1 --- tex1.bind(0); glBindVertexArray(VAO_rect); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glfwSwapBuffers(window); std::this_thread::sleep_for(std::chrono::seconds(2)); // --- 第二帧:image2 + image3 叠加 --- glClear(GL_COLOR_BUFFER_BIT); tex2.bind(0); // 绑定到纹理单元0 tex3.bind(1); // 绑定到纹理单元1 shader.setFloat("blendAlpha", 0.6f); // 控制叠加强度 glBindVertexArray(VAO_rect); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glfwSwapBuffers(window); std::this_thread::sleep_for(std::chrono::seconds(2)); // --- 第三帧:六边形 + 笑脸 --- glClear(GL_COLOR_BUFFER_BIT); tex4.bind(0); shader.setFloat("blendAlpha", 0.0f); // 关闭叠加 glBindVertexArray(VAO_hex); glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(hexIndices.size()), GL_UNSIGNED_INT, 0); glfwSwapBuffers(window); std::this_thread::sleep_for(std::chrono::seconds(2)); break; // 演示完退出(实际可用按键切换) } // 清理资源(可选) glfwDestroyWindow(window); glfwTerminate(); return 0; } #include "Shader.h" #include <iostream> // 定义静态成员变量(必须在类外定义) std::string Shader::vertexSource = R"( #version 330 core layout(location = 0) in vec2 aPos; layout(location = 1) in vec2 aTexCoord; out vec2 TexCoord; void main() { gl_Position = vec4(aPos, 0.0, 1.0); TexCoord = aTexCoord; } )"; std::string Shader::fragmentSource = R"( #version 330 core in vec2 TexCoord; uniform sampler2D texture1; uniform sampler2D texture2; uniform float blendAlpha; out vec4 FragColor; void main() { vec4 col1 = texture(texture1, TexCoord); vec4 col2 = texture(texture2, TexCoord); if (blendAlpha > 0.0) { FragColor = mix(col1, col2, blendAlpha * col2.a); } else { FragColor = col1; } } )"; // 编译单个着色器 unsigned int Shader::compileShader(unsigned int type, const std::string& source) { unsigned int shader = glCreateShader(type); const char* src = source.c_str(); glShaderSource(shader, 1, &src, nullptr); glCompileShader(shader); int success; char infoLog[512]; glGetShaderiv(shader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(shader, 512, NULL, infoLog); std::cout << "Shader Compile Error:\n" << infoLog << std::endl; } return shader; } // 构造函数 Shader::Shader() { unsigned int vertex = compileShader(GL_VERTEX_SHADER, vertexSource); unsigned int fragment = compileShader(GL_FRAGMENT_SHADER, fragmentSource); ID = glCreateProgram(); glAttachShader(ID, vertex); glAttachShader(ID, fragment); glLinkProgram(ID); int success; char infoLog[512]; glGetProgramiv(ID, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(ID, 512, NULL, infoLog); std::cerr << "Linking Shader Program Failed:\n" << infoLog << std::endl; } glDeleteShader(vertex); glDeleteShader(fragment); } void Shader::use() { glUseProgram(ID); } void Shader::setInt(const std::string& name, int value) { glUniform1i(glGetUniformLocation(ID, name.c_str()), value); } void Shader::setFloat(const std::string& name, float value) { glUniform1f(glGetUniformLocation(ID, name.c_str()), value); } #include "Shape.h" #include <glad/glad.h> void Shape::draw() { glBindVertexArray(VAO); glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(indices.size()), GL_UNSIGNED_INT, 0); } Shape::~Shape() { glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); } #include "Texture.h" #include <iostream> Texture::Texture(const std::string& imagePath, bool alpha) : path(imagePath) { glGenTextures(1, &ID); glBindTexture(GL_TEXTURE_2D, ID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); int width, height, channels; unsigned char* data = SOIL_load_image(path.c_str(), &width, &height, &channels, SOIL_LOAD_AUTO); if (data) { GLenum format = GL_RGB; if (channels == 1) format = GL_RED; else if (channels == 3) format = GL_RGB; else if (channels == 4) format = GL_RGBA; glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data); glGenerateMipmap(GL_TEXTURE_2D); SOIL_free_image_data(data); std::cout << "✅ SOIL2 成功加载: " << path << " (" << width << "x" << height << ")\n"; } else { std::cerr << "❌ SOIL2 无法加载图片: " << path << "\n"; std::cerr << "💡 错误码: " << SOIL_last_result() << "\n"; } glBindTexture(GL_TEXTURE_2D, 0); } void Texture::bind(unsigned int unit) { glActiveTexture(GL_TEXTURE0 + unit); glBindTexture(GL_TEXTURE_2D, ID); } Texture::~Texture() { glDeleteTextures(1, &ID); }
10-11
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值