那就用soil2来解决运行没有纹理图片G:\Demo3\Demo3\textures,container.jpg,wood.png,// Cube18.h
#ifndef CUBE18_H
#define CUBE18_H
#include <string> // ✅ 必须添加!解决 std::string 报错
#include <glad/glad.h>
class Cube18
{
public:
// 构造函数:接收顶点和片段着色器路径
Cube18(const std::string& vertexPath, const std::string& fragmentPath);
// 析构函数
~Cube18();
// 初始化立方体数据(VBO/VAO/EBO)
void init();
// 渲染立方体,传入窗口宽高用于投影矩阵
void render(float width, float height);
// 更新逻辑(可用于动画)
void update(float dt);
private:
unsigned int VAO, VBO, EBO;
unsigned int shaderProgram;
float rotationAngle = 0.0f;
// 私有辅助函数:创建着色器程序
unsigned int createShaderProgram(const std::string& vsPath, const std::string& fsPath);
};
#endif // CUBE18_H
// Cube18.cpp
#include "Cube18.h"
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <iostream>
#include <fstream>
#include <sstream>
#include <glm/gtc/type_ptr.hpp>
#include <string> // 显式包含(虽然通常被其他头文件带入)
// 外部纹理变量(需在 main.cpp 中定义)
extern unsigned int texWood;
extern unsigned int texContainer;
// 辅助函数:读取着色器文件
std::string readShaderFile(const std::string& path) {
std::ifstream file(path);
if (!file.is_open()) {
std::cerr << "无法打开着色器文件: " << path << std::endl;
return "";
}
std::stringstream buffer;
buffer << file.rdbuf();
return buffer.str();
}
// 创建着色器程序(私有方法)
unsigned int Cube18::createShaderProgram(const std::string& vsPath, const std::string& fsPath) {
std::string vsCodeStr = readShaderFile(vsPath);
std::string fsCodeStr = readShaderFile(fsPath);
const char* vertexCode = vsCodeStr.c_str();
const char* fragmentCode = fsCodeStr.c_str();
// 编译顶点着色器
unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexCode, nullptr);
glCompileShader(vertexShader);
int success;
char infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cerr << "顶点着色器编译失败:\n" << infoLog << std::endl;
}
// 编译片段着色器
unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentCode, nullptr);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cerr << "片段着色器编译失败:\n" << infoLog << std::endl;
}
// 链接程序
unsigned int program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(program, 512, NULL, infoLog);
std::cerr << "着色器程序链接失败:\n" << infoLog << std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
return program;
}
// 构造函数
Cube18::Cube18(const std::string& vertexPath, const std::string& fragmentPath)
: shaderProgram(createShaderProgram(vertexPath, fragmentPath)) {}
// 析构函数
Cube18::~Cube18() {
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);
glDeleteProgram(shaderProgram);
}
// 初始化顶点数据
void Cube18::init() {
float vertices[] = {
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f
};
unsigned int indices[] = {
0, 1, 3, 0, 3, 2,
4, 5, 7, 4, 7, 6,
8, 9, 11, 8, 11, 10,
2, 3, 9, 2, 9, 5,
0, 7, 11, 0, 11, 1,
5, 7, 13, 5, 13, 12
};
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
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);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
// 渲染函数
void Cube18::render(float width, float height) {
glUseProgram(shaderProgram);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texWood);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texContainer);
unsigned int modelLoc = glGetUniformLocation(shaderProgram, "model");
unsigned int viewLoc = glGetUniformLocation(shaderProgram, "view");
unsigned int projLoc = glGetUniformLocation(shaderProgram, "projection");
glm::mat4 model = glm::mat4(1.0f);
glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f);
glm::vec3 target = glm::vec3(0.0f, 0.0f, 0.0f);
glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f);
glm::mat4 view = glm::lookAt(cameraPos, target, up);
float aspect = width / height;
glm::mat4 projection = glm::perspective(glm::radians(45.0f), aspect, 0.1f, 100.0f);
float time = glfwGetTime();
model = glm::rotate(model, time * 0.5f, glm::vec3(1.0f, 1.0f, 0.0f));
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
glUniform1i(glGetUniformLocation(shaderProgram, "texture1"), 0);
glUniform1i(glGetUniformLocation(shaderProgram, "texture2"), 1);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}
// 更新函数
void Cube18::update(float dt) {
rotationAngle += dt * 0.5f;
}
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include "Lab3_2.h"
#include "Demo3_2.h"
#include "Demo3_3.h"
#include"Hexagon.h"
#include"ColorTriangle.h"
#include"ColorHexagon.h"
#include "WaveHexagon.h"
#include "Cube18.h" // 👈 新增:包含 Cube18 头文件
using namespace std;
unsigned int texWood;
unsigned int texContainer;
// settings
const unsigned int SCR_WIDTH = 1200;
const unsigned int SCR_HEIGHT = 800;
GLFWwindow* window;
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
void processInput(GLFWwindow* window);
void render();
void init();
void cleanup();
Lab3_2* lab3_2 = nullptr; //指向 Lab3_2 实例的指针,用于管理第一个实验场景(例如带面剔除功能的三角形渲染),初始化为空,防止野指针
Demo3_2* demo3_2 = nullptr;
Demo3_3* demo3_3 = nullptr;
Hexagon* hexagon = nullptr;
ColorTriangle* colorTriangle = nullptr;
ColorHexagon* colorHexagon = nullptr;
WaveHexagon* waveHexagon = nullptr;
Cube18* cube18 = nullptr;
int sceneType = 1; // 当前激活的场景编号:1 -> Lab3_2, 2 -> Demo3_2, 3 -> Demo3_3,可通过键盘按键切换不同场景
bool enableCullFace = false; // 是否启用面剔除(Face Culling)的状态标志,控制是否调用 glEnable(GL_CULL_FACE)
GLenum cullMode = GL_FRONT; //当前面剔除模式:默认剔除正面(GL_FRONT)可选值:GL_BACK(剔除背面)、GL_FRONT_AND_BACK(都剔除)
GLenum frontFace = GL_CCW; //正面判定方式:逆时针方向为正面(Counter-Clockwise),对应 glFrontFace 的参数,影响哪些面被认为是“正面”
int main()
{
//初始化glfw窗口
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);//上下文版本号
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// 创建窗口对象
window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "Demo3", NULL, NULL);
if (window == NULL) //窗口创建失败提示
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window); // 将 OpenGL 上下文设置为当前线程的主上下文,所有 OpenGL 调用都将作用于该窗口
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); //注册帧缓冲大小变化的回调函数.当窗口被缩放或最大化时,会自动调整视口大小
glfwSetKeyCallback(window, key_callback); // 注册键盘按键事件的回调函数,每当有键按下/释放时触发 key_callback初始化glad
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))//glad初始化检查
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
int nrAttributes;
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &nrAttributes); //查询 OpenGL 支持的最大顶点属性数量
std::cout << "Maximum nr of vertex attributes supported: " << nrAttributes << std::endl;
init();
// 窗口消息循环
while (!glfwWindowShouldClose(window))
{
processInput(window); // 输入
render(); // 渲染
glfwSwapBuffers(window); //交换前后缓冲区,实现双缓冲机制,防止画面撕裂
glfwPollEvents();
}
cleanup(); //释放内存
glfwTerminate(); //终止 GLFW,清理所有相关资源
return 0;
}
void cleanup()
{
if (lab3_2)
{
delete lab3_2;
}
if (demo3_2)
{
delete demo3_2;
}
if (demo3_3)
{
delete demo3_3;
}
if (hexagon)
{
delete hexagon;
}
if (colorTriangle)
{
delete colorTriangle;
}
if (colorHexagon)
{
delete colorHexagon;
}
if (waveHexagon)
{
delete waveHexagon;
waveHexagon = nullptr;
}
if (cube18)
{
delete cube18;
}
}
void init()
{
lab3_2 = new Lab3_2();
lab3_2->setRenderParameter(); //设置其初始渲染参数(如面剔除状态)
demo3_2 = new Demo3_2();
demo3_2->setRenderParameter();
demo3_3 = new Demo3_3();
demo3_3->setRenderParameter();
hexagon = new Hexagon();
hexagon->initData(); // 初始化六边形,显式初始化六边形的顶点缓冲区和 VAO/VBO。
colorTriangle = new ColorTriangle();
colorHexagon = new ColorHexagon();
colorHexagon->initData();
// 在 init() 或主函数开始处
waveHexagon = new WaveHexagon();
waveHexagon->init();
cube18 = new Cube18("shaders/Cube.vs", "shaders/Cube.fs");
cube18->init();
glGenTextures(1, &texWood);
glBindTexture(GL_TEXTURE_2D, texWood);
unsigned char white[] = { 255, 255, 255 };
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, white);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glGenTextures(1, &texContainer);
glBindTexture(GL_TEXTURE_2D, texContainer);
unsigned char yellow[] = { 255, 255, 0 };
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, yellow);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
void render()
{
glClearColor(0.2, 0.3, 0.2, 1); //设置清除颜色为深绿色
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // ✅ 加上深度清除 //清除颜色缓冲区,准备新一帧绘制
if (sceneType == 1 && lab3_2) //判断当前应激活的场景是否为 Lab3_2 场景,并确保该场景对象已成功创建
{
lab3_2->render();
}
else if (sceneType == 2 && demo3_2)
{
demo3_2->render();
}
else if (sceneType == 3 && demo3_3)
{
demo3_3->render();
}
else if (sceneType == 4 && hexagon)
{
hexagon->renderObject(); // 渲染六边形
}
else if (sceneType == 5 && colorTriangle)
{
colorTriangle->render();
}
else if (sceneType == 6 && colorHexagon)
{
colorHexagon->renderObject();
}
else if (sceneType == 7 && waveHexagon) {
waveHexagon->render();
}
else if (sceneType == 8 && cube18)
{
std::cout << "[DEBUG] 正在渲染 Cube18 场景!\n";
glEnable(GL_DEPTH_TEST); // ✅ 开启深度测试
cube18->render(SCR_WIDTH, SCR_HEIGHT); // ✅ 传参
glDisable(GL_DEPTH_TEST); // 可选关闭
}
}
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
// 判断按键是否被释放
if (action == GLFW_RELEASE) //GLFW_RELEASE与GLFW_PRESS的区别
{
if (key == GLFW_KEY_1)//释放的是数字键 1,则将当前场景切换为 Lab3_2(编号为 1)
sceneType = 1;
else if (key == GLFW_KEY_2)
sceneType = 2;
else if (key == GLFW_KEY_3)
sceneType = 3;
else if (key == GLFW_KEY_4)
sceneType = 4;
else if (key == GLFW_KEY_5)
sceneType = 5;
else if (key == GLFW_KEY_6)
sceneType = 6;
else if (key == GLFW_KEY_7)
sceneType = 7;
else if (key == GLFW_KEY_E)
{
enableCullFace = !enableCullFace; //切换面剔除开关状态
if (sceneType == 1 && lab3_2)
{
lab3_2->setRenderParameter(enableCullFace, cullMode, frontFace);
}
}
else if (key == GLFW_KEY_C) //按C键切换绕向
{
if (frontFace == GL_CCW) //如果当前为绕向为逆时针
{
frontFace=GL_CW; //切换为顺时针
}
else
{
frontFace = GL_CCW;
}
if (sceneType == 1 && lab3_2)
{
lab3_2->setRenderParameter(enableCullFace, cullMode, frontFace);
}
}
else if (key == GLFW_KEY_F) //按键F切换裁剪面
{
if (cullMode == GL_FRONT) //如果当前正面为裁剪面
{
cullMode = GL_BACK; //切换成背面
}
else
{
cullMode = GL_FRONT;
}
if (sceneType == 1 && lab3_2)
{
lab3_2->setRenderParameter(enableCullFace, cullMode, frontFace);
}
}
else if (key == GLFW_KEY_8)
{
sceneType = 8;
}
}
}
void processInput(GLFWwindow* window) //处理每帧的输入(主要用于连续按键检测)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
}
// 窗口回调函数
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height); //设置 OpenGL 视口与窗口一致,参数:x, y, 宽度, 高度
}
最新发布