复原大唐3d项目测试版

这是一个可以完美复原大唐风土人情的VR项目!!!!!

这里只是最初的测试版本,需要下载多个库,以后会有更多方法

:

// TangDynastyVR_Complete.h

#pragma once

#include <openvr.h>

#include <GL/glew.h>

#include <GLFW/glfw3.h>

#include <glm/glm.hpp>

#include <vector>

#include <memory>

#include <string>

#include <map>

#include <random>

// 情感状态枚举

enum class EmotionalState {

NEUTRAL, JOYFUL, ANGRY, SAD, POETIC, NOSTALGIC, PROUD

};

// 对话消息结构

struct DialogueMessage {

std::string speakerName;

std::string content;

float displayTime;

glm::vec3 speakerPosition;

bool isHistoricalFigure;

};

// 基础场景对象

class SceneObject {

public:

virtual ~SceneObject() = default;

virtual void render(const glm::mat4& view, const glm::mat4& projection) = 0;

virtual void update(float deltaTime) = 0;

};

// 唐朝人物基类

class TangCharacter : public SceneObject {

protected:

glm::vec3 position;

glm::mat4 modelMatrix;

GLuint VAO, VBO;

float animationTime = 0.0f;

public:

TangCharacter(const glm::vec3& pos) : position(pos) {}

virtual ~TangCharacter() = default;

void update(float deltaTime) override {

animationTime += deltaTime;

// 基础动画逻辑

}

void render(const glm::mat4& view, const glm::mat4& projection) override {

// 基础渲染逻辑

}

};

// 人物性格系统

class HistoricalPersonality {

private:

std::map<EmotionalState, std::vector<std::string>> dialogues;

EmotionalState currentState = EmotionalState::NEUTRAL;

public:

void setDialogues(EmotionalState state, const std::vector<std::string>& lines) {

dialogues[state] = lines;

}

std::string speak(EmotionalState state) {

currentState = state;

auto& stateDialogues = dialogues[state];

if (stateDialogues.empty()) return "";

std::random_device rd;

std::mt19937 gen(rd());

std::uniform_int_distribution<> dis(0, stateDialogues.size() - 1);

return stateDialogues[dis(gen)];

}

EmotionalState getCurrentState() const { return currentState; }

};

// 增强的唐朝人物类

class EnhancedTangCharacter : public TangCharacter {

private:

std::string characterName;

std::string characterType;

HistoricalPersonality personality;

EmotionalState currentEmotion;

float emotionChangeTimer = 0;

float speakCooldown = 0;

bool canSpeak = true;

public:

EnhancedTangCharacter(const std::string& name, const std::string& type, const glm::vec3& pos)

: TangCharacter(pos), characterName(name), characterType(type),

currentEmotion(EmotionalState::NEUTRAL) {

initializePersonality();

}

void initializePersonality() {

if (characterType == "libai") {

personality.setDialogues(EmotionalState::POETIC, {

"李白:(举杯邀月)人生得意须尽欢,莫使金樽空对月!这月色如此美好,当浮一大白!",

"李白:我本楚狂人,凤歌笑孔丘。手持绿玉杖,朝别黄鹤楼。哈哈哈!痛快!"

});

personality.setDialogues(EmotionalState::JOYFUL, {

"李白:今日得见知己,当痛饮三百杯!店家,再上酒来!",

"李白:这长安繁华,盛唐气象,能生于此世,实乃我辈之幸!"

});

personality.setDialogues(EmotionalState::SAD, {

"李白:(叹息)大道如青天,我独不得出...这满腹才华,何时才能得遇明主?",

"李白:花间一壶酒,独酌无相亲。举杯邀明月,对影成三人...寂寞啊寂寞。"

});

} else if (characterType == "dufu") {

personality.setDialogues(EmotionalState::SAD, {

"杜甫:(忧心忡忡)朱门酒肉臭,路有冻死骨...这世道,百姓苦啊!",

"杜甫:国破山河在,城春草木深。感时花溅泪,恨别鸟惊心...大唐何时才能重振?"

});

personality.setDialogues(EmotionalState::ANGRY, {

"杜甫:(愤慨)官军收洛阳,家住洛阳里。夫婿与兄弟,目前见伤死!这战乱何时休!"

});

} else if (characterType == "merchant") {

personality.setDialogues(EmotionalState::NEUTRAL, {

"西域商人:(展示货物)来自波斯的琉璃,大食的香料,都是上等货色!",

"西域商人:这丝绸之路真是黄金之路啊!从长安到罗马,处处是商机!"

});

}

}

void update(float deltaTime) override {

TangCharacter::update(deltaTime);

// 情绪状态变化

emotionChangeTimer -= deltaTime;

if (emotionChangeTimer <= 0) {

changeEmotionRandomly();

emotionChangeTimer = 10.0f + (rand() % 20);

}

// 说话冷却

if (!canSpeak) {

speakCooldown -= deltaTime;

if (speakCooldown <= 0) canSpeak = true;

}

}

void changeEmotionRandomly() {

if (characterType == "libai") {

std::vector<EmotionalState> emotions = {

EmotionalState::POETIC, EmotionalState::JOYFUL, EmotionalState::POETIC, EmotionalState::NOSTALGIC

};

currentEmotion = emotions[rand() % emotions.size()];

} else if (characterType == "dufu") {

std::vector<EmotionalState> emotions = {

EmotionalState::SAD, EmotionalState::ANGRY, EmotionalState::NOSTALGIC, EmotionalState::SAD

};

currentEmotion = emotions[rand() % emotions.size()];

}

}

void speak(class DialogueUIManager& dialogueManager) {

if (!canSpeak) return;

std::string dialogue = personality.speak(currentEmotion);

if (!dialogue.empty()) {

dialogueManager.addMessage(characterName, dialogue, position, true);

speakCooldown = 8.0f + (rand() % 7);

canSpeak = false;

}

}

const std::string& getName() const { return characterName; }

};

// 对话UI管理器

class DialogueUIManager {

private:

struct DialogueUI {

GLuint VAO, VBO, EBO;

GLuint texture;

glm::vec2 position = glm::vec2(0.1f, 0.1f);

glm::vec2 size = glm::vec2(0.8f, 0.2f);

bool isVisible = false;

};

DialogueUI dialogueUI;

std::vector<DialogueMessage> messageQueue;

DialogueMessage currentMessage;

float messageTimer = 0;

bool isShowingMessage = false;

GLuint shaderProgram;

public:

DialogueUIManager() = default;

bool initialize() {

createDialogueBackground();

const char* vs = R"(

#version 330 core

layout(location = 0) in vec2 aPos;

uniform vec2 uScreenSize;

void main() {

vec2 normalizedPos = aPos / uScreenSize;

gl_Position = vec4(normalizedPos * 2.0 - 1.0, 0.0, 1.0);

}

)";

const char* fs = R"(

#version 330 core

out vec4 FragColor;

uniform vec4 uColor;

void main() {

FragColor = uColor;

}

)";

// shaderProgram = ShaderManager::compileShaders(vs, fs);

return true; // shaderProgram != 0;

}

void createDialogueBackground() {

float x = dialogueUI.position.x, y = dialogueUI.position.y;

float w = dialogueUI.size.x, h = dialogueUI.size.y;

float vertices[] = { x, y, x+w, y, x+w, y+h, x, y+h };

unsigned int indices[] = { 0, 1, 2, 2, 3, 0 };

glGenVertexArrays(1, &dialogueUI.VAO);

glGenBuffers(1, &dialogueUI.VBO);

glGenBuffers(1, &dialogueUI.EBO);

glBindVertexArray(dialogueUI.VAO);

glBindBuffer(GL_ARRAY_BUFFER, dialogueUI.VBO);

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dialogueUI.EBO);

glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);

glEnableVertexAttribArray(0);

}

void addMessage(const std::string& speaker, const std::string& content,

const glm::vec3& position = glm::vec3(0), bool isHistorical = false) {

DialogueMessage msg{speaker, content, 5.0f, position, isHistorical};

messageQueue.push_back(msg);

}

void update(float deltaTime) {

if (isShowingMessage) {

messageTimer -= deltaTime;

if (messageTimer <= 0) {

isShowingMessage = false;

dialogueUI.isVisible = false;

}

}

if (!isShowingMessage && !messageQueue.empty()) {

currentMessage = messageQueue.front();

messageQueue.erase(messageQueue.begin());

dialogueUI.isVisible = true;

isShowingMessage = true;

messageTimer = currentMessage.displayTime;

}

}

void render() {

if (!dialogueUI.isVisible) return;

glUseProgram(shaderProgram);

glBindVertexArray(dialogueUI.VAO);

// 设置uniform并渲染

GLint screenSizeLoc = glGetUniformLocation(shaderProgram, "uScreenSize");

glUniform2f(screenSizeLoc, 1920.0f, 1080.0f);

glUniform4f(glGetUniformLocation(shaderProgram, "uColor"), 0.0f, 0.0f, 0.0f, 0.7f);

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

// 这里应该渲染文本

// renderText(currentMessage.speakerName + ":" + currentMessage.content, ...);

}

};

// 主VR应用类

class TangDynastyVRApp {

private:

GLFWwindow* window;

vr::IVRSystem* vrSystem;

// 渲染资源

GLuint leftEyeFramebuffer, rightEyeFramebuffer;

GLuint leftEyeTexture, rightEyeTexture;

// 场景管理

std::vector<std::shared_ptr<SceneObject>> sceneObjects;

std::vector<std::shared_ptr<EnhancedTangCharacter>> characters;

DialogueUIManager dialogueManager;

// 着色器

GLuint shaderProgram;

public:

TangDynastyVRApp() : window(nullptr), vrSystem(nullptr), shaderProgram(0) {}

bool initialize() {

if (!initializeOpenGL() || !initializeVR()) return false;

setupVRRenderTargets();

dialogueManager.initialize();

initializeScene();

return true;

}

bool initializeOpenGL() {

if (!glfwInit()) return false;

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);

glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);

window = glfwCreateWindow(800, 600, "唐朝VR体验", nullptr, nullptr);

if (!window) {

glfwTerminate();

return false;

}

glfwMakeContextCurrent(window);

return glewInit() == GLEW_OK;

}

bool initializeVR() {

vr::EVRInitError error = vr::VRInitError_None;

vrSystem = vr::VR_Init(&error, vr::VRApplication_Scene);

return error == vr::VRInitError_None;

}

void initializeScene() {

// 创建历史人物

auto liBai = std::make_shared<EnhancedTangCharacter>("李白", "libai", glm::vec3(2, 0, -3));

auto duFu = std::make_shared<EnhancedTangCharacter>("杜甫", "dufu", glm::vec3(-2, 0, -3));

auto merchant = std::make_shared<EnhancedTangCharacter>("西域商人", "merchant", glm::vec3(0, 0, -4));

characters.push_back(liBai);

characters.push_back(duFu);

characters.push_back(merchant);

// 添加到场景对象

for (auto& character : characters) {

sceneObjects.push_back(character);

}

}

void setupVRRenderTargets() {

// 创建VR渲染目标

glGenFramebuffers(1, &leftEyeFramebuffer);

glGenFramebuffers(1, &rightEyeFramebuffer);

// ... 更多初始化代码

}

void run() {

while (!glfwWindowShouldClose(window)) {

glfwPollEvents();

float deltaTime = 0.016f; // 假设60FPS

// 更新所有对象

for (auto& obj : sceneObjects) {

obj->update(deltaTime);

}

// 随机触发对话

for (auto& character : characters) {

if (rand() % 600 < 1) { // 约每秒有1/600几率触发

character->speak(dialogueManager);

}

}

dialogueManager.update(deltaTime);

// VR渲染

renderVRScene();

glfwSwapBuffers(window);

}

}

void renderVRScene() {

// 渲染左眼

glBindFramebuffer(GL_FRAMEBUFFER, leftEyeFramebuffer);

renderEye(vr::Eye_Left);

// 渲染右眼

glBindFramebuffer(GL_FRAMEBUFFER, rightEyeFramebuffer);

renderEye(vr::Eye_Right);

// 提交到VR合成器

// vr::VRCompositor()->Submit(...);

}

void renderEye(vr::Hmd_Eye eye) {

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// 设置视图和投影矩阵

glm::mat4 view = getEyeViewMatrix(eye);

glm::mat4 projection = getEyeProjectionMatrix(eye);

// 渲染场景对象

for (auto& obj : sceneObjects) {

obj->render(view, projection);

}

// 渲染UI

dialogueManager.render();

}

glm::mat4 getEyeViewMatrix(vr::Hmd_Eye eye) {

// 获取VR眼睛视图矩阵

return glm::mat4(1.0f);

}

glm::mat4 getEyeProjectionMatrix(vr::Hmd_Eye eye) {

// 获取VR眼睛投影矩阵

return glm::mat4(1.0f);

}

~TangDynastyVRApp() {

if (vrSystem) vr::VR_Shutdown();

if (window) glfwDestroyWindow(window);

glfwTerminate();

}

};

// 主函数

int main() {

TangDynastyVRApp app;

if (app.initialize()) {

std::cout << "启动唐朝VR体验..." << std::endl;

app.run();

}

return 0;

}

相关推荐
晨非辰17 小时前
数据结构排序系列指南:从O(n²)到O(n),计数排序如何实现线性时间复杂度
运维·数据结构·c++·人工智能·后端·深度学习·排序算法
RoboWizard18 小时前
高性能电脑热战寒冬 11月DIY配置推荐
linux·运维·服务器·电脑·金士顿
残影飞雪18 小时前
Jetson版本下Pytorch和torchvision
c++
实心儿儿1 天前
C++ —— 模板进阶
开发语言·c++
go_bai1 天前
Linux-线程2
linux·c++·经验分享·笔记·学习方法
j_xxx404_1 天前
C++:继承(概念及定义|作用域|基类与派生类转换|默认成员函数|与友元、静态成员关系|多继承|组合)
数据结构·c++
欧阳x天1 天前
C++入门(二)
开发语言·c++
编程之路,妙趣横生1 天前
STL(五) priority_queue 基本用法 + 模拟实现
c++
一念一花一世界1 天前
Arbess从初级到进阶(9) - 使用Arbess+GitLab实现C++项目自动化部署
c++·ci/cd·gitlab·arbess
永远的超音速1 天前
Docker入门
docker·电脑